TerminalOperation (@NotNull String name, PsiExpression @NotNull [] args, @NotNull PsiType elementType, @NotNull PsiType resultType, boolean isVoid) { if(isVoid) { if ((name.equals("forEach") || name.equals("forEachOrdered")) && args.length == 1) { FunctionHelper fn = FunctionHelper.create(args[0], 1, true); return fn == null ? null : new ForEachTerminalOperation(fn); } return null; } if(name.equals("count") && args.length == 0) { return TemplateBasedOperation.counting(); } if(name.equals("sum") && args.length == 0) { return TemplateBasedOperation.summing(resultType); } if(name.equals("average") && args.length == 0) { if(elementType.equals(PsiTypes.doubleType())) { return new AverageTerminalOperation(true, true); } else if(elementType.equals(PsiTypes.intType()) || elementType.equals(PsiTypes.longType())) { return new AverageTerminalOperation(false, true); } } if(name.equals("summaryStatistics") && args.length == 0) { return TemplateBasedOperation.summarizing(resultType); } if((name.equals("findFirst") || name.equals("findAny")) && args.length == 0) { PsiType optionalElementType = OptionalUtil.getOptionalElementType(resultType); return optionalElementType == null ? null : new FindTerminalOperation(optionalElementType); } if(name.equals("toList") && args.length == 0) { return ToCollectionTerminalOperation.toList(resultType); } if(name.equals("toSet") && args.length == 0) { return ToCollectionTerminalOperation.toSet(resultType); } if(name.equals("toImmutableList") && args.length == 0) { return new WrappedCollectionTerminalOperation(ToCollectionTerminalOperation.toList(resultType), "unmodifiableList", resultType); } if(name.equals("toImmutableSet") && args.length == 0) { return new WrappedCollectionTerminalOperation(ToCollectionTerminalOperation.toSet(resultType), "unmodifiableSet", resultType); } if((name.equals("anyMatch") || name.equals("allMatch") || name.equals("noneMatch")) && args.length == 1) { FunctionHelper fn = FunctionHelper.create(args[0], 1); return fn == null ? null : new MatchTerminalOperation(fn, name); } if(name.equals("reduce")) { if(args.length == 2 || args.length == 3) { FunctionHelper fn = FunctionHelper.create(args[1], 2); if(fn != null) { return new ReduceTerminalOperation(args[0], fn, resultType); } } if(args.length == 1) { return ReduceToOptionalTerminalOperation.create(args[0], resultType); } } if(name.equals("toArray") && args.length < 2) { if(!(resultType instanceof PsiArrayType)) return null; PsiType componentType = ((PsiArrayType)resultType).getComponentType(); if (componentType instanceof PsiPrimitiveType) { if (args.length == 0) return new ToPrimitiveArrayTerminalOperation(componentType); } else { FunctionHelper fn = null; if(args.length == 1) { fn = FunctionHelper.create(args[0], 1); if(fn == null) return null; } return new ToArrayTerminalOperation(elementType, fn); } } if ((name.equals("max") || name.equals("min")) && args.length < 2) { return MinMaxTerminalOperation.create(args.length == 1 ? args[0] : null, elementType, name.equals("max")); } if (name.equals("collect")) { if (args.length == 3) { FunctionHelper supplier = FunctionHelper.create(args[0], 0); if (supplier == null) return null; FunctionHelper accumulator = FunctionHelper.create(args[1], 2); if (accumulator == null) return null; return new ExplicitCollectTerminalOperation(supplier, accumulator); } if (args.length == 1) { return fromCollector(elementType, resultType, PsiUtil.skipParenthesizedExprDown(args[0])); } } return null; }