function makeShader(inputsInfo, outputShape, program) {
    const prefixSnippets = [];
    inputsInfo.forEach((x)=>{
        const size = (0, _tfjsCore.util).sizeFromShape(x.shapeInfo.logicalShape);
        // Snippet when we decided to upload the values as uniform.
        if (x.shapeInfo.isUniform) prefixSnippets.push(`uniform float ${x.name}${size > 1 ? `[${size}]` : ""};`);
        else {
            prefixSnippets.push(`uniform sampler2D ${x.name};`);
            prefixSnippets.push(`uniform int offset${x.name};`);
        }
        if (program.enableShapeUniforms) {
            const { uniformShape } = getUniformInfoFromShape(program.packedInputs, x.shapeInfo.logicalShape, x.shapeInfo.texShape);
            switch(uniformShape.length){
                case 1:
                    prefixSnippets.push(`uniform int ${x.name}Shape;`);
                    break;
                case 2:
                    prefixSnippets.push(`uniform ivec2 ${x.name}Shape;`);
                    break;
                case 3:
                    prefixSnippets.push(`uniform ivec3 ${x.name}Shape;`);
                    break;
                case 4:
                    prefixSnippets.push(`uniform ivec4 ${x.name}Shape;`);
                    break;
                default:
                    break;
            }
            prefixSnippets.push(`uniform ivec2 ${x.name}TexShape;`);
        }
    });
    if (program.enableShapeUniforms) {
        switch(outputShape.logicalShape.length){
            case 1:
                prefixSnippets.push(`uniform int outShape;`);
                break;
            case 2:
                prefixSnippets.push(`uniform ivec2 outShape;`);
                prefixSnippets.push(`uniform int outShapeStrides;`);
                break;
            case 3:
                prefixSnippets.push(`uniform ivec3 outShape;`);
                prefixSnippets.push(`uniform ivec2 outShapeStrides;`);
                break;
            case 4:
                prefixSnippets.push(`uniform ivec4 outShape;`);
                prefixSnippets.push(`uniform ivec3 outShapeStrides;`);
                break;
            default:
                break;
        }
        prefixSnippets.push(`uniform ivec2 outTexShape;`);
    }
    if (program.customUniforms) program.customUniforms.forEach((d)=>{
        prefixSnippets.push(`uniform ${d.type} ${d.name}${d.arrayIndex ? `[${d.arrayIndex}]` : ""};`);
    });
    const inputPrefixSnippet = prefixSnippets.join("\n");
    const inputSamplingSnippet = inputsInfo.map((x)=>getInputSamplingSnippet(x, outputShape, program.packedInputs, program.enableShapeUniforms)).join("\n");
    const outTexShape = outputShape.texShape;
    const glsl = (0, _glslVersion.getGlslDifferences)();
    const floatTextureSampleSnippet = getFloatTextureSampleSnippet(glsl);
    let outputSamplingSnippet;
    let floatTextureSetOutputSnippet;
    let shaderPrefix = getShaderPrefix(glsl);
    if (outputShape.isPacked) {
        outputSamplingSnippet = getPackedOutputSamplingSnippet(outputShape.logicalShape, outTexShape, program.enableShapeUniforms);
        floatTextureSetOutputSnippet = getFloatTextureSetRGBASnippet(glsl);
    } else {
        outputSamplingSnippet = getOutputSamplingSnippet(outputShape.logicalShape, outTexShape, program.enableShapeUniforms);
        floatTextureSetOutputSnippet = getFloatTextureSetRSnippet(glsl);
    }
    if (program.packedInputs) shaderPrefix += SHADER_PACKED_PREFIX;
    const source = [
        shaderPrefix,
        floatTextureSampleSnippet,
        floatTextureSetOutputSnippet,
        inputPrefixSnippet,
        outputSamplingSnippet,
        inputSamplingSnippet,
        program.userCode
    ].join("\n");
    return source;
}
Returns a new input info (a copy) that has a squeezed logical shape.