use of org.codehaus.groovy.ast.expr.StaticMethodCallExpression in project groovy by apache.
the class StaticTypeCheckingVisitor method visitStaticMethodCallExpression.
@Override
public void visitStaticMethodCallExpression(final StaticMethodCallExpression call) {
String name = call.getMethod();
if (name == null) {
addStaticTypeError("cannot resolve dynamic method name at compile time.", call);
return;
}
if (extension.beforeMethodCall(call)) {
extension.afterMethodCall(call);
return;
}
Expression callArguments = call.getArguments();
ArgumentListExpression argumentList = InvocationWriter.makeArgumentList(callArguments);
checkForbiddenSpreadArgument(argumentList);
ClassNode receiver = call.getOwnerType();
visitMethodCallArguments(receiver, argumentList, false, null);
ClassNode[] args = getArgumentTypes(argumentList);
try {
// method call receivers are :
// - possible "with" receivers
// - the actual receiver as found in the method call expression
// - any of the potential receivers found in the instanceof temporary table
// in that order
List<Receiver<String>> receivers = new LinkedList<>();
addReceivers(receivers, makeOwnerList(new ClassExpression(receiver)), false);
List<MethodNode> mn = null;
Receiver<String> chosenReceiver = null;
for (Receiver<String> currentReceiver : receivers) {
mn = findMethod(currentReceiver.getType(), name, args);
if (!mn.isEmpty()) {
if (mn.size() == 1) {
// GROOVY-8909, GROOVY-8961, GROOVY-9734, GROOVY-9844, GROOVY-9915, et al.
resolvePlaceholdersFromImplicitTypeHints(args, argumentList, mn.get(0).getParameters());
typeCheckMethodsWithGenericsOrFail(currentReceiver.getType(), args, mn.get(0), call);
}
chosenReceiver = currentReceiver;
break;
}
}
if (mn == null) {
throw new GroovyBugError("Invalid state finding valid method: receivers should never be empty and findMethod should never return null");
}
if (mn.isEmpty()) {
mn = extension.handleMissingMethod(receiver, name, argumentList, args, call);
}
boolean callArgsVisited = false;
if (mn.isEmpty()) {
addNoMatchingMethodError(receiver, name, args, call);
} else {
mn = disambiguateMethods(mn, receiver, args, call);
if (mn.size() == 1) {
MethodNode directMethodCallCandidate = mn.get(0);
ClassNode returnType = getType(directMethodCallCandidate);
if (returnType.isUsingGenerics() && !returnType.isEnum()) {
visitMethodCallArguments(receiver, argumentList, true, directMethodCallCandidate);
ClassNode irtg = inferReturnTypeGenerics(chosenReceiver.getType(), directMethodCallCandidate, callArguments);
returnType = irtg != null && implementsInterfaceOrIsSubclassOf(irtg, returnType) ? irtg : returnType;
callArgsVisited = true;
}
storeType(call, returnType);
storeTargetMethod(call, directMethodCallCandidate);
} else {
addAmbiguousErrorMessage(mn, name, args, call);
}
if (!callArgsVisited) {
visitMethodCallArguments(receiver, argumentList, true, call.getNodeMetaData(DIRECT_METHOD_CALL_TARGET));
}
}
} finally {
extension.afterMethodCall(call);
}
}
use of org.codehaus.groovy.ast.expr.StaticMethodCallExpression in project groovy by apache.
the class RecursivenessTester method isRecursive.
public boolean isRecursive(Map<String, ASTNode> params) {
ASTNode method = params.get("method");
assert MethodNode.class.equals(method.getClass());
ASTNode call = params.get("call");
Class<? extends ASTNode> callClass = call.getClass();
assert MethodCallExpression.class.equals(callClass) || StaticMethodCallExpression.class.equals(callClass);
if (callClass == MethodCallExpression.class) {
return isRecursive((MethodNode) method, (MethodCallExpression) call);
}
return isRecursive((MethodNode) method, (StaticMethodCallExpression) call);
}
use of org.codehaus.groovy.ast.expr.StaticMethodCallExpression in project groovy by apache.
the class TailRecursiveASTTransformation method replaceRecursiveReturnsInsideClosures.
@SuppressWarnings("Instanceof")
private void replaceRecursiveReturnsInsideClosures(final MethodNode method, final Map<Integer, Map<String, Object>> positionMapping) {
Closure<Boolean> whenRecursiveReturn = new Closure<Boolean>(this, this) {
public Boolean doCall(Statement statement, boolean inClosure) {
if (!inClosure)
return false;
if (!(statement instanceof ReturnStatement)) {
return false;
}
Expression inner = ((ReturnStatement) statement).getExpression();
if (!(inner instanceof MethodCallExpression) && !(inner instanceof StaticMethodCallExpression)) {
return false;
}
return isRecursiveIn(inner, method);
}
};
Closure<Statement> replaceWithThrowLoopException = new Closure<Statement>(this, this) {
public Statement doCall(ReturnStatement statement) {
return new ReturnStatementToIterationConverter(AstHelper.recurByThrowStatement()).convert(statement, positionMapping);
}
};
StatementReplacer replacer = new StatementReplacer(whenRecursiveReturn, replaceWithThrowLoopException);
replacer.replaceIn(method.getCode());
}
use of org.codehaus.groovy.ast.expr.StaticMethodCallExpression in project groovy by apache.
the class TailRecursiveASTTransformation method replaceRecursiveReturnsOutsideClosures.
@SuppressWarnings("Instanceof")
private void replaceRecursiveReturnsOutsideClosures(final MethodNode method, final Map<Integer, Map<String, Object>> positionMapping) {
Closure<Boolean> whenRecursiveReturn = new Closure<Boolean>(this, this) {
public Boolean doCall(Statement statement, boolean inClosure) {
if (inClosure)
return false;
if (!(statement instanceof ReturnStatement)) {
return false;
}
Expression inner = ((ReturnStatement) statement).getExpression();
if (!(inner instanceof MethodCallExpression) && !(inner instanceof StaticMethodCallExpression)) {
return false;
}
return isRecursiveIn(inner, method);
}
};
Closure<Statement> replaceWithContinueBlock = new Closure<Statement>(this, this) {
public Statement doCall(ReturnStatement statement) {
return new ReturnStatementToIterationConverter().convert(statement, positionMapping);
}
};
StatementReplacer replacer = new StatementReplacer(whenRecursiveReturn, replaceWithContinueBlock);
replacer.replaceIn(method.getCode());
}
use of org.codehaus.groovy.ast.expr.StaticMethodCallExpression in project groovy by apache.
the class GrabAnnotationTransformation method callGrabAsStaticInitIfNeeded.
private void callGrabAsStaticInitIfNeeded(ClassNode classNode, ClassNode grapeClassNode, Collection<Map<String, Object>> grabMapsInit, Collection<Map<String, Object>> grabExcludeMaps) {
List<Statement> grabInitializers = new ArrayList<Statement>();
MapExpression basicArgs = new MapExpression();
if (autoDownload != null) {
basicArgs.addMapEntryExpression(constX(AUTO_DOWNLOAD_SETTING), constX(autoDownload));
}
if (disableChecksums != null) {
basicArgs.addMapEntryExpression(constX(DISABLE_CHECKSUMS_SETTING), constX(disableChecksums));
}
if (systemProperties != null && !systemProperties.isEmpty()) {
BlockStatement block = new BlockStatement();
for (Map.Entry<String, String> e : systemProperties.entrySet()) {
block.addStatement(stmt(callX(SYSTEM_CLASSNODE, "setProperty", args(constX(e.getKey()), constX(e.getValue())))));
}
StaticMethodCallExpression enabled = callX(SYSTEM_CLASSNODE, "getProperty", args(constX("groovy.grape.enable"), constX("true")));
grabInitializers.add(ifS(eqX(enabled, constX("true")), block));
}
if (!grabExcludeMaps.isEmpty()) {
ListExpression list = new ListExpression();
for (Map<String, Object> map : grabExcludeMaps) {
Set<Map.Entry<String, Object>> entries = map.entrySet();
MapExpression inner = new MapExpression();
for (Map.Entry<String, Object> entry : entries) {
inner.addMapEntryExpression(constX(entry.getKey()), constX(entry.getValue()));
}
list.addExpression(inner);
}
basicArgs.addMapEntryExpression(constX("excludes"), list);
}
List<Expression> argList = new ArrayList<Expression>();
argList.add(basicArgs);
if (grabMapsInit.isEmpty())
return;
for (Map<String, Object> grabMap : grabMapsInit) {
// add Grape.grab(excludeArgs, [group:group, module:module, version:version, classifier:classifier])
// or Grape.grab([group:group, module:module, version:version, classifier:classifier])
MapExpression dependencyArg = new MapExpression();
for (String s : GRAB_REQUIRED) {
dependencyArg.addMapEntryExpression(constX(s), constX(grabMap.get(s)));
}
for (String s : GRAB_OPTIONAL) {
if (grabMap.containsKey(s))
dependencyArg.addMapEntryExpression(constX(s), constX(grabMap.get(s)));
}
argList.add(dependencyArg);
}
grabInitializers.add(stmt(callX(grapeClassNode, "grab", args(argList))));
// insert at beginning so we have the classloader set up before the class is called
classNode.addStaticInitializerStatements(grabInitializers, true);
}
Aggregations