function applyContextToBuilder(builder, context) {
  // define one uniform per variable
  for (const varName in context.variables) {
    const variable = context.variables[varName];
    const uniformName = uniformNameForVariable(variable.name);
    let glslType = getGlslTypeFromType(variable.type);
    if (variable.type === ColorType) {
      // we're not packing colors when they're passed as uniforms
      glslType = 'vec4';
    }
    builder.addUniform(uniformName, glslType);
  }

  // for each feature attribute used in the fragment shader, define a varying that will be used to pass data
  // from the vertex to the fragment shader, as well as an attribute in the vertex shader (if not already present)
  for (const propName in context.properties) {
    const property = context.properties[propName];
    const glslType = getGlslTypeFromType(property.type);
    const attributeName = `a_prop_${property.name}`;
    if (property.type === ColorType) {
      builder.addAttribute(
        attributeName,
        glslType,
        `unpackColor(${attributeName})`,
        'vec4',
      );
      builder.addVertexShaderFunction(UNPACK_COLOR_FN);
    } else {
      builder.addAttribute(attributeName, glslType);
    }
  }

  // add functions that were collected in the compilation contexts
  for (const functionName in context.functions) {
    builder.addVertexShaderFunction(context.functions[functionName]);
    builder.addFragmentShaderFunction(context.functions[functionName]);
  }
}
Applies the properties and variables collected in a compilation context to a ShaderBuilder instance:
properties will show up as attributes in shaders, and variables will show up as uniforms.
@param {import("./ShaderBuilder.js").ShaderBuilder} builder Shader builder
@param {import("../../expr/gpu.js").CompilationContext} context Compilation context