GlslShaderJob implements ShaderJob { @Override public void removeUniformBindings() { for (String uniformName : getPipelineInfo().getUniformNames()) { assert getPipelineInfo().hasBindingOrIsPushConstant(uniformName); getPipelineInfo().removeUniformBinding(uniformName); } for (TranslationUnit tu : shaders) { final List<Declaration> newTopLevelDeclarations = new ArrayList<>(); for (Declaration decl : tu.getTopLevelDeclarations()) { if (decl instanceof VariablesDeclaration && ((VariablesDeclaration) decl).getBaseType() .hasQualifier(TypeQualifier.UNIFORM)) { final VariablesDeclaration variablesDeclaration = (VariablesDeclaration) decl; final Type targetType = variablesDeclaration.getBaseType().getWithoutQualifiers(); assert targetType instanceof SamplerType : "Only samplers may exist as top-level " + "uniforms with bindings."; assert variablesDeclaration.getNumDecls() == 1 : "A bound sampler must appear on its " + "own."; final VariableDeclInfo declInfo = variablesDeclaration.getDeclInfos().get(0); newTopLevelDeclarations.add( new VariablesDeclaration( new QualifiedType(targetType, Collections.singletonList( TypeQualifier.UNIFORM )), declInfo)); } else if (decl instanceof InterfaceBlock && ((InterfaceBlock) decl).getInterfaceQualifier() .equals(TypeQualifier.UNIFORM)) { final InterfaceBlock interfaceBlock = (InterfaceBlock) decl; assert interfaceBlock.getMemberNames().size() == 1 : "We assume that each uniform block" + " wraps precisely one uniform."; final ImmutablePair<Type, ArrayInfo> baseTypeAndArrayInfo = Typer.getBaseTypeArrayInfo(interfaceBlock.getMemberTypes().get(0)); final List<TypeQualifier> qualifiers = new ArrayList<>(); qualifiers.add(TypeQualifier.UNIFORM); if (baseTypeAndArrayInfo.left instanceof QualifiedType) { qualifiers.addAll(((QualifiedType) baseTypeAndArrayInfo.left).getQualifiers()); } newTopLevelDeclarations.add(new VariablesDeclaration( new QualifiedType(baseTypeAndArrayInfo.left.getWithoutQualifiers(), qualifiers), new VariableDeclInfo(interfaceBlock.getMemberNames().get(0), baseTypeAndArrayInfo.right, null))); } else { newTopLevelDeclarations.add(decl); } } tu.setTopLevelDeclarations(newTopLevelDeclarations); } } GlslShaderJob(Optional<String> license,
                       PipelineInfo pipelineInfo,
                       List<TranslationUnit> shaders);  GlslShaderJob(Optional<String> license,
                       PipelineInfo pipelineInfo,
                       TranslationUnit... shaders); @Override PipelineInfo getPipelineInfo(); @Override Optional<String> getLicense(); @Override void makeUniformBindings(Optional<String> pushConstant); @Override void removeUniformBindings(); @Override boolean hasUniformBindings(); @Override Optional<String> getPushConstant(); @Override List<TranslationUnit> getShaders(); @Override Optional<TranslationUnit> getVertexShader(); @Override Optional<TranslationUnit> getFragmentShader(); @Override Optional<TranslationUnit> getComputeShader(); @Override GlslShaderJob clone();  }
@Test public void testRemoveUniformBindings() throws Exception { final GlslShaderJob job = new GlslShaderJob( Optional.empty(), new PipelineInfo(JSON_WITH_BINDINGS), ParseHelper.parse(getShaderFile("vert", VERT_SHADER_WITH_BINDINGS)), ParseHelper.parse(getShaderFile("frag", FRAG_SHADER_WITH_BINDINGS))); job.removeUniformBindings(); CompareAsts.assertEqualAsts(VERT_SHADER_NO_BINDINGS, job.getVertexShader().get()); CompareAsts.assertEqualAsts(FRAG_SHADER_NO_BINDINGS, job.getFragmentShader().get()); assertEquals(new PipelineInfo(JSON_NO_BINDINGS).toString(), job.getPipelineInfo().toString()); }