@Override protected Object visitLambdaExpression(LambdaExpression node, Object context) { if (optimize) { // TODO: enable optimization related to lambda expression // A mechanism to convert function type back into lambda expression need to exist to enable optimization return node; } Expression body = node.getBody(); List<String> argumentNames = node.getArguments().stream() .map(LambdaArgumentDeclaration::getName) .map(Identifier::getValue) .collect(toImmutableList()); FunctionType functionType = (FunctionType) expressionTypes.get(NodeRef.<Expression>of(node)); checkArgument(argumentNames.size() == functionType.getArgumentTypes().size()); return generateVarArgsToMapAdapter( Primitives.wrap(functionType.getReturnType().getJavaType()), functionType.getArgumentTypes().stream() .map(Type::getJavaType) .map(Primitives::wrap) .collect(toImmutableList()), argumentNames, map -> process(body, new LambdaSymbolResolver(map))); }
@Override protected Type visitBindExpression(BindExpression node, StackableAstVisitorContext<Context> context) { verify(context.getContext().isExpectingLambda(), "bind expression found when lambda is not expected"); StackableAstVisitorContext<Context> innerContext = new StackableAstVisitorContext<>(context.getContext().notExpectingLambda()); ImmutableList.Builder<Type> functionInputTypesBuilder = ImmutableList.builder(); for (Expression value : node.getValues()) { functionInputTypesBuilder.add(process(value, innerContext)); } functionInputTypesBuilder.addAll(context.getContext().getFunctionInputTypes()); List<Type> functionInputTypes = functionInputTypesBuilder.build(); FunctionType functionType = (FunctionType) process(node.getFunction(), new StackableAstVisitorContext<>(context.getContext().expectingLambda(functionInputTypes))); List<Type> argumentTypes = functionType.getArgumentTypes(); int numCapturedValues = node.getValues().size(); verify(argumentTypes.size() == functionInputTypes.size()); for (int i = 0; i < numCapturedValues; i++) { verify(functionInputTypes.get(i).equals(argumentTypes.get(i))); } FunctionType result = new FunctionType(argumentTypes.subList(numCapturedValues, argumentTypes.size()), functionType.getReturnType()); return setExpressionType(node, result); }
verify(lambdaExpression.getArguments().size() == functionType.getArgumentTypes().size()); Map<NodeRef<Expression>, Type> lambdaArgumentExpressionTypes = new HashMap<>(); Map<Symbol, Type> lambdaArgumentSymbolTypes = new HashMap<>(); for (int j = 0; j < lambdaExpression.getArguments().size(); j++) { LambdaArgumentDeclaration argument = lambdaExpression.getArguments().get(j); Type type = functionType.getArgumentTypes().get(j); lambdaArgumentExpressionTypes.put(NodeRef.of(argument), type); lambdaArgumentSymbolTypes.put(new Symbol(argument.getName().getValue()), type);
process(expression, new StackableAstVisitorContext<>(context.getContext().expectingLambda(expectedFunctionType.getArgumentTypes())));