Skip to content

Commit

Permalink
Update the Groovy plug-in to 2.5.6
Browse files Browse the repository at this point in the history
  • Loading branch information
eric-milles committed Feb 4, 2019
1 parent c1f518b commit 34412d7
Show file tree
Hide file tree
Showing 58 changed files with 770 additions and 257 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ protected String[] getDefaultClassPaths() {
System.arraycopy(cps, 0, newcps, 0, cps.length);

String[] ivyVersions = {"2.5.0", "2.4.0"};
String[] groovyVersions = {"3.0.0-indy", "2.5.5-indy", "2.4.16"};
String[] groovyVersions = {"3.0.0-indy", "2.5.6-indy", "2.4.16"};
try {
URL groovyJar = null;
for (String groovyVer : groovyVersions) {
Expand Down
2 changes: 2 additions & 0 deletions base/org.codehaus.groovy24/.checkstyle
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
<file-match-pattern match-pattern="groovy/ast/CodeVisitorSupport.java" include-pattern="false" />
<file-match-pattern match-pattern="groovy/ast/CompileUnit.java" include-pattern="false" />
<file-match-pattern match-pattern="groovy/ast/ConstructorNode.java" include-pattern="false" />
<file-match-pattern match-pattern="groovy/ast/FieldNode.java" include-pattern="false" />
<file-match-pattern match-pattern="groovy/ast/GenericsType.java" include-pattern="false" />
<file-match-pattern match-pattern="groovy/ast/GroovyCodeVisitor.java" include-pattern="false" />
<file-match-pattern match-pattern="groovy/ast/ImportNode.java" include-pattern="false" />
Expand Down Expand Up @@ -71,6 +72,7 @@
<file-match-pattern match-pattern="groovy/transform/sc/transformers/MethodCallExpressionTransformer.java" include-pattern="false" />
<file-match-pattern match-pattern="groovy/transform/stc/StaticTypeCheckingSupport.java" include-pattern="false" />
<file-match-pattern match-pattern="groovy/transform/stc/StaticTypeCheckingVisitor.java" include-pattern="false" />
<file-match-pattern match-pattern="groovy/transform/stc/TraitTypeCheckingExtension.java" include-pattern="false" />
<file-match-pattern match-pattern="groovy/transform/trait/TraitASTTransformation.java" include-pattern="false" />
<file-match-pattern match-pattern="groovy/transform/trait/TraitComposer.java" include-pattern="false" />
<file-match-pattern match-pattern="groovy/vmplugin/v5/Java5.java" include-pattern="false" />
Expand Down
197 changes: 197 additions & 0 deletions base/org.codehaus.groovy24/src/org/codehaus/groovy/ast/FieldNode.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,197 @@
/*
* 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;

import org.codehaus.groovy.ast.expr.Expression;
import groovyjarjarasm.asm.Opcodes;

import java.lang.reflect.Field;

/**
* Represents a field (member variable)
*
* @author <a href="mailto:james@coredevelopers.net">James Strachan</a>
*/
public class FieldNode extends AnnotatedNode implements Opcodes, Variable {

private String name;
private int modifiers;
private ClassNode type;
private ClassNode owner;
private Expression initialValueExpression;
private ClassNode originType;
private boolean dynamicTyped;
private boolean holder;

public static FieldNode newStatic(Class theClass, String name) throws SecurityException, NoSuchFieldException {
Field field = theClass.getField(name);
ClassNode fldType = ClassHelper.make(field.getType());
return new FieldNode(name, ACC_PUBLIC | ACC_STATIC, fldType, ClassHelper.make(theClass), null);
}

public FieldNode(String name, int modifiers, ClassNode type, ClassNode owner, Expression initialValueExpression) {
this.name = name;
this.modifiers = modifiers;
/* GRECLIPSE edit -- https://issues.apache.org/jira/browse/GROOVY-8535
this.type = type;
if (this.type == ClassHelper.DYNAMIC_TYPE && initialValueExpression != null)
this.setType(initialValueExpression.getType());
this.setType(type);
this.originType = type;
*/
this.setType(type);
// GRECLIPSE end
this.owner = owner;
this.initialValueExpression = initialValueExpression;
}

public Expression getInitialExpression() {
return initialValueExpression;
}

public int getModifiers() {
return modifiers;
}

public String getName() {
return name;
}

public ClassNode getType() {
return type;
}

public void setType(ClassNode type) {
this.type = type;
this.originType = type;
dynamicTyped |= type == ClassHelper.DYNAMIC_TYPE;
}

public ClassNode getOwner() {
return owner;
}

public boolean isHolder() {
return holder;
}

public void setHolder(boolean holder) {
this.holder = holder;
}

public boolean isDynamicTyped() {
return dynamicTyped;
}

public void setModifiers(int modifiers) {
this.modifiers = modifiers;
}

/**
* @return true if the field is static
*/
public boolean isStatic() {
return (modifiers & ACC_STATIC) != 0;
}

/**
* @return true if the field is an enum
*/
public boolean isEnum() {
return (modifiers & ACC_ENUM) != 0;
}

/**
* @return true if the field is final
*/
public boolean isFinal() {
return (modifiers & ACC_FINAL) != 0;
}

/**
* @return true if the field is volatile
*/
public boolean isVolatile() {
return (modifiers & ACC_VOLATILE) != 0;
}

/**
* @return true if the field is public
*/
public boolean isPublic() {
return (modifiers & ACC_PUBLIC) != 0;
}

/**
* @return true if the field is protected
*/
public boolean isProtected() {
return (modifiers & ACC_PROTECTED) != 0;
}

/**
* @param owner The owner to set.
*/
public void setOwner(ClassNode owner) {
this.owner = owner;
}

public boolean hasInitialExpression() {
return initialValueExpression != null;
}

public boolean isInStaticContext() {
return isStatic();
}

public Expression getInitialValueExpression() {
return initialValueExpression;
}

public void setInitialValueExpression(Expression initialValueExpression) {
this.initialValueExpression = initialValueExpression;
}

/**
* @deprecated
*/
@Deprecated
public boolean isClosureSharedVariable() {
return false;
}
/**
* @deprecated
*/
@Deprecated
public void setClosureSharedVariable(boolean inClosure) {
}

public ClassNode getOriginType() {
return originType;
}

public void setOriginType(ClassNode cn) {
originType = cn;
}

public void rename(String name) {
declaringClass.renameField(this.name, name);
this.name = name;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,161 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.codehaus.groovy.transform.stc;

import org.codehaus.groovy.ast.ClassHelper;
import org.codehaus.groovy.ast.ClassNode;
import org.codehaus.groovy.ast.MethodNode;
import org.codehaus.groovy.ast.Parameter;
import org.codehaus.groovy.ast.expr.ArgumentListExpression;
import org.codehaus.groovy.ast.expr.MethodCall;
import org.codehaus.groovy.ast.expr.MethodCallExpression;
import org.codehaus.groovy.ast.expr.VariableExpression;
import org.codehaus.groovy.transform.trait.TraitASTTransformation;
import org.codehaus.groovy.transform.trait.Traits;

import java.util.Arrays;
import java.util.Collections;
import java.util.LinkedHashSet;
import java.util.LinkedList;
import java.util.List;

import static org.codehaus.groovy.transform.stc.StaticTypeCheckingSupport.isClassClassNodeWrappingConcreteType;

/**
* A type checking extension that will take care of handling errors which are specific to traits. In particular, it will
* handle the "super" method calls within a trait.
*
* @since 2.3.0
*/
public class TraitTypeCheckingExtension extends AbstractTypeCheckingExtension {
private static final List<MethodNode> NOTFOUND = Collections.emptyList();

/**
* Builds a type checking extension relying on a Groovy script (type checking DSL).
*
* @param typeCheckingVisitor the type checking visitor
*/
public TraitTypeCheckingExtension(final StaticTypeCheckingVisitor typeCheckingVisitor) {
super(typeCheckingVisitor);
}

@Override
public void setup() {
}

@Override
public List<MethodNode> handleMissingMethod(final ClassNode receiver, final String name, final ArgumentListExpression argumentList, final ClassNode[] argumentTypes, final MethodCall call) {
String[] decomposed = Traits.decomposeSuperCallName(name);
if (decomposed != null) {
return convertToDynamicCall(call, receiver, decomposed, argumentTypes);
}
if (call instanceof MethodCallExpression) {
MethodCallExpression mce = (MethodCallExpression) call;
if (mce.getReceiver() instanceof VariableExpression) {
VariableExpression var = (VariableExpression) mce.getReceiver();

// GROOVY-7322
// static method call in trait?
ClassNode type = null;
if (isStaticTraitReceiver(receiver, var)) {
type = receiver.getGenericsTypes()[0].getType();
} else if (isThisTraitReceiver(var)) {
type = receiver;
}
if (type != null && Traits.isTrait(type) && !(type instanceof UnionTypeClassNode)) {
/* GRECLIPSE edit -- GROOVY-8272: https://github.com/apache/groovy/pull/865
ClassNode helper = Traits.findHelper(type);
Parameter[] params = new Parameter[argumentTypes.length + 1];
params[0] = new Parameter(ClassHelper.CLASS_Type.getPlainNodeReference(), "staticSelf");
for (int i = 1; i < params.length; i++) {
params[i] = new Parameter(argumentTypes[i-1], "p" + i);
}
MethodNode method = helper.getDeclaredMethod(name, params);
if (method != null) {
return Collections.singletonList(makeDynamic(call, method.getReturnType()));
}
*/
LinkedList<ClassNode> candidates = new LinkedList<>();
candidates.add(type);
while (!candidates.isEmpty()) {
ClassNode next = candidates.removeFirst();
ClassNode helper = Traits.findHelper(next);
Parameter[] params = new Parameter[argumentTypes.length + 1];
params[0] = new Parameter(ClassHelper.CLASS_Type.getPlainNodeReference(), "staticSelf");
for (int i = 1, n = params.length; i < n; i += 1) {
params[i] = new Parameter(argumentTypes[i - 1], "p" + i);
}
MethodNode method = helper.getDeclaredMethod(name, params);
if (method != null) {
return Collections.singletonList(makeDynamic(call, method.getReturnType()));
}
// GROOVY-8272: support inherited static methods
candidates.addAll(Arrays.asList(next.getInterfaces()));
}
// GRECLIPSE end
}
}

ClassNode dynamic = mce.getNodeMetaData(TraitASTTransformation.DO_DYNAMIC);
if (dynamic!=null) {
return Collections.singletonList(makeDynamic(call, dynamic));
}
}
return NOTFOUND;
}

private static boolean isStaticTraitReceiver(final ClassNode receiver, final VariableExpression var) {
return Traits.STATIC_THIS_OBJECT.equals(var.getName()) && isClassClassNodeWrappingConcreteType(receiver);
}

private static boolean isThisTraitReceiver(final VariableExpression var) {
return Traits.THIS_OBJECT.equals(var.getName());
}

private List<MethodNode> convertToDynamicCall(MethodCall call, ClassNode receiver, String[] decomposed, ClassNode[] argumentTypes) {
String traitName = decomposed[0];
String name = decomposed[1];
LinkedHashSet<ClassNode> traitsAsList = Traits.collectAllInterfacesReverseOrder(receiver, new LinkedHashSet<ClassNode>());
ClassNode[] implementedTraits = traitsAsList.toArray(new ClassNode[traitsAsList.size()]);
ClassNode nextTrait = null;
for (int i = 0; i < implementedTraits.length - 1; i++) {
ClassNode implementedTrait = implementedTraits[i];
if (implementedTrait.getName().equals(traitName)) {
nextTrait = implementedTraits[i + 1];
}
}
ClassNode[] newArgs = new ClassNode[argumentTypes.length];
System.arraycopy(argumentTypes, 0, newArgs, 0, newArgs.length);
ClassNode inferredReturnType = inferTraitMethodReturnType(nextTrait, name, newArgs);

return Arrays.asList(makeDynamic(call, inferredReturnType));
}

private ClassNode inferTraitMethodReturnType(ClassNode nextTrait, String methodName, ClassNode[] paramTypes) {
ClassNode result = ClassHelper.OBJECT_TYPE;
if (nextTrait != null) {
List<MethodNode> candidates = typeCheckingVisitor.findMethod(nextTrait, methodName, paramTypes);
if (candidates.size() == 1) {
result = candidates.get(0).getReturnType();
}
}
return result;
}

}
Loading

0 comments on commit 34412d7

Please sign in to comment.