ParseHelper { public static synchronized TranslationUnit parse(File file) throws IOException, ParseTimeoutException, InterruptedException, GlslParserException { return parseInputStream(new ByteArrayInputStream(FileUtils.readFileToByteArray(file)), ShaderKind.fromExtension(FilenameUtils.getExtension(file.getName()))); }  static Optional<TranslationUnit> maybeParseShader(File shader); static synchronized TranslationUnit parse(File file); static synchronized TranslationUnit parse(String string, ShaderKind shaderKind); static synchronized TranslationUnit parse(String string); static final String END_OF_GRAPHICSFUZZ_DEFINES; }
@Test public void testParseFromString() throws Exception { TranslationUnit tu = ParseHelper.parse(TEST_PROGRAM); checkTranslationUnit(tu); }
@Test public void testParseFromFile() throws Exception { File tempFile = testFolder.newFile("shader.frag"); BufferedWriter bw = new BufferedWriter(new FileWriter(tempFile)); bw.write(TEST_PROGRAM); bw.close(); TranslationUnit tu = ParseHelper.parse(tempFile); checkTranslationUnit(tu); }
@Test public void testParseFromFileWithHeader() throws Exception { File tempFile = testFolder.newFile("shader.frag"); BufferedWriter bw = new BufferedWriter(new FileWriter(tempFile)); bw.write("arbitrary\nstuff\n" + ParseHelper.END_OF_GRAPHICSFUZZ_DEFINES + "\n" + TEST_PROGRAM); bw.close(); TranslationUnit tu = ParseHelper.parse(tempFile); checkTranslationUnit(tu); }
@Test public void testParseCurrentHeaderNoMacros() throws Exception { File tempFile = testFolder.newFile("shader.frag"); PrintStream ps = new PrintStream(new FileOutputStream(tempFile)); PrettyPrinterVisitor.emitGraphicsFuzzDefines(ps, ShadingLanguageVersion.ESSL_320); ps.println(TEST_PROGRAM); ps.close(); TranslationUnit tu = ParseHelper.parse(tempFile); assertEquals(3, tu.getTopLevelDeclarations().size()); }
@Test public void testParseCurrentHeaderWithMacros() throws Exception { File tempFile = testFolder.newFile("shader.frag"); PrintStream ps = new PrintStream(new FileOutputStream(tempFile)); PrettyPrinterVisitor.emitGraphicsFuzzDefines(ps, ShadingLanguageVersion.ESSL_310); ps.println(TEST_PROGRAM); ps.close(); TranslationUnit tu = ParseHelper.parse(tempFile); assertEquals(3, tu.getTopLevelDeclarations().size()); }
@Test public void testQualifiers() throws Exception { final String prog = "in vec3 blah; out vec3 bloo; void foo(in float x, out float y);"; final TranslationUnit tu = ParseHelper.parse(prog); assertEquals(3, tu.getTopLevelDeclarations().size()); { final Declaration decl = tu.getTopLevelDeclarations().get(0); final VariablesDeclaration variablesDeclaration = (VariablesDeclaration) decl; assertTrue(variablesDeclaration.getBaseType().hasQualifier(TypeQualifier.SHADER_INPUT)); assertFalse(variablesDeclaration.getBaseType().hasQualifier(TypeQualifier.IN_PARAM)); } { final Declaration decl = tu.getTopLevelDeclarations().get(1); final VariablesDeclaration variablesDeclaration = (VariablesDeclaration) decl; assertTrue(variablesDeclaration.getBaseType().hasQualifier(TypeQualifier.SHADER_OUTPUT)); assertFalse(variablesDeclaration.getBaseType().hasQualifier(TypeQualifier.OUT_PARAM)); } { final Declaration decl = tu.getTopLevelDeclarations().get(2); FunctionPrototype proto = (FunctionPrototype) decl; assertTrue(proto.getParameters().get(0).getType().hasQualifier(TypeQualifier.IN_PARAM)); assertFalse(proto.getParameters().get(0).getType().hasQualifier(TypeQualifier.SHADER_INPUT)); assertTrue(proto.getParameters().get(1).getType().hasQualifier(TypeQualifier.OUT_PARAM)); assertFalse(proto.getParameters().get(1).getType().hasQualifier(TypeQualifier.SHADER_OUTPUT)); } }
@Test public void testParseOctalIntLiteral() throws Exception { final String shader = "#version 300 es\n" + "void main() {" + " int x = 031;" + "}"; final TranslationUnit tu = ParseHelper.parse(shader); assertTrue(new CheckPredicateVisitor() { @Override public void visitInitializer(Initializer initializer) { super.visitInitializer(initializer); if (initializer.getExpr() instanceof IntConstantExpr && ((IntConstantExpr) initializer.getExpr()).getValue().equals("031")) { predicateHolds(); } } }.test(tu)); }
@Test public void testParseHexIntLiteral() throws Exception { final String shader = "#version 300 es\n" + "void main() {" + " int x = 0xa03b;" + "}"; final TranslationUnit tu = ParseHelper.parse(shader); assertTrue( new CheckPredicateVisitor() { @Override public void visitInitializer(Initializer initializer) { super.visitInitializer(initializer); if (initializer.getExpr() instanceof IntConstantExpr && ((IntConstantExpr) initializer.getExpr()).getValue().equals("0xa03b")) { predicateHolds(); } } }.test(tu)); }
@Test public void testParseOctalUnsignedIntLiteral() throws Exception { final String shader = "#version 300 es\n" + "void main() {" + " int x = 031u;" + "}"; final TranslationUnit tu = ParseHelper.parse(shader); assertTrue( new CheckPredicateVisitor() { @Override public void visitInitializer(Initializer initializer) { super.visitInitializer(initializer); if (initializer.getExpr() instanceof UIntConstantExpr && ((UIntConstantExpr) initializer.getExpr()).getValue().equals("031u")) { predicateHolds(); } } }.test(tu)); }
@Test public void testParseHexUnsignedIntLiteral() throws Exception { final String shader = "#version 300 es\n" + "void main() {" + " int x = 0xA03Bu;" + "}"; final TranslationUnit tu = ParseHelper.parse(shader); assertTrue( new CheckPredicateVisitor() { @Override public void visitInitializer(Initializer initializer) { super.visitInitializer(initializer); if (initializer.getExpr() instanceof UIntConstantExpr && ((UIntConstantExpr) initializer.getExpr()).getValue().equals("0xA03Bu")) { predicateHolds(); } } }.test(tu)); }
@Test public void testParseUnsignedZero() throws Exception { final String program = "uint foo() { return 0u; }"; assertTrue( new CheckPredicateVisitor() { @Override public void visitReturnStmt(ReturnStmt returnStmt) { super.visitReturnStmt(returnStmt); if (returnStmt.getExpr() instanceof UIntConstantExpr && ((UIntConstantExpr) returnStmt.getExpr()).getValue().equals("0u")) { predicateHolds(); } } }.test(ParseHelper.parse(program))); }
@Test(expected = GlslParserException.class) public void testDoNotParseBadSignedConstant() throws Exception { ParseHelper.parse("int foo() { return 0x120x12; }"); }
@Test(expected = GlslParserException.class) public void testDoNotParseBadUnsignedConstant() throws Exception { ParseHelper.parse("uint foo() { return 0x120x12u; }"); }
@Test public void testParseEssl320() throws Exception { TranslationUnit tu = ParseHelper.parse("#version 320 es\n" + "void main() { }"); assertSame(ShadingLanguageVersion.ESSL_320, tu.getShadingLanguageVersion()); }
@Test public void testParseWebGl1() throws Exception { TranslationUnit tu = ParseHelper.parse("#version 100\n" + " + "void main() { }"); assertSame(ShadingLanguageVersion.WEBGL_SL, tu.getShadingLanguageVersion()); }
@Test public void testParseWebGl2() throws Exception { TranslationUnit tu = ParseHelper.parse("#version 300 es\n" + " + "void main() { }"); assertSame(ShadingLanguageVersion.WEBGL2_SL, tu.getShadingLanguageVersion()); }
@Test public void testParseInPlacePrecisionAndFloatSuffix() throws Exception { final String shader = "#version 310 es\n" + "\n" + "void main() {\n" + " mediump vec3 color = 1.00f;\n" + "}\n"; final TranslationUnit tu = ParseHelper.parse(shader); final VariablesDeclaration variablesDeclaration = ((DeclarationStmt) ((FunctionDefinition) tu.getTopLevelDeclarations().get(0)).getBody() .getStmt(0)).getVariablesDeclaration(); final Type baseType = variablesDeclaration.getBaseType(); assertTrue(baseType.hasQualifier(TypeQualifier.MEDIUMP)); assertEquals("1.00f", ((FloatConstantExpr) variablesDeclaration.getDeclInfo(0) .getInitializer().getExpr()).getValue()); }
@Test public void testParseSharedKeyword() throws Exception { final String program = "#version 310 es\n" + "layout(std430, binding = 0) buffer theSSBO {\n" + " bool b;\n" + "};\n" + "\n" + "layout(local_size_x=20, local_size_y=1, local_size_z=1) in;\n" + "\n" + "shared float result[10];\n" + "\n" + "void main() { }\n"; final TranslationUnit tu = ParseHelper.parse(program, ShaderKind.COMPUTE); assertTrue(new CheckPredicateVisitor() { @Override public void visitVariablesDeclaration(VariablesDeclaration variablesDeclaration) { super.visitVariablesDeclaration(variablesDeclaration); if (variablesDeclaration.getBaseType().hasQualifier(TypeQualifier.SHARED)) { predicateHolds(); } } }.test(tu)); }
@Test public void testParseError() throws Exception { try { ParseHelper.parse("void foo("); fail("Expected GlslParserException to be thrown."); } catch (GlslParserException exception) { } }
@Test public void testParsingComma1() throws Exception { final TranslationUnit tu = ParseHelper.parse("" + "void main() {\n" + " bool b, c;\n" + " int x, y;\n" + " b, c ? x : y;\n" + " b ? c, x : y;\n" + " b ? x : y, c;\n" + "}\n"); final BlockStmt block = tu.getMainFunction().getBody(); assertTrue(block.getStmt(0) instanceof DeclarationStmt); assertTrue(block.getStmt(1) instanceof DeclarationStmt); { final ExprStmt exprStmt = (ExprStmt) block.getStmt(2); assertTrue(exprStmt.getExpr() instanceof BinaryExpr); final BinaryExpr binaryExpr = (BinaryExpr) exprStmt.getExpr(); assertEquals(BinOp.COMMA, binaryExpr.getOp()); assertTrue(binaryExpr.getLhs() instanceof VariableIdentifierExpr); assertTrue(binaryExpr.getRhs() instanceof TernaryExpr); } { final ExprStmt exprStmt = (ExprStmt) block.getStmt(3); assertTrue(exprStmt.getExpr() instanceof TernaryExpr); final TernaryExpr ternaryExpr = (TernaryExpr) exprStmt.getExpr(); assertTrue(ternaryExpr.getTest() instanceof VariableIdentifierExpr); assertTrue(ternaryExpr.getThenExpr() instanceof BinaryExpr); assertEquals(BinOp.COMMA, ((BinaryExpr) ternaryExpr.getThenExpr()).getOp()); assertTrue(ternaryExpr.getElseExpr() instanceof VariableIdentifierExpr); } { final ExprStmt exprStmt = (ExprStmt) block.getStmt(4); assertTrue(exprStmt.getExpr() instanceof BinaryExpr); final BinaryExpr binaryExpr = (BinaryExpr) exprStmt.getExpr(); assertEquals(BinOp.COMMA, binaryExpr.getOp()); assertTrue(binaryExpr.getLhs() instanceof TernaryExpr); assertTrue(binaryExpr.getRhs() instanceof VariableIdentifierExpr); } }
@Test public void testUnsupportedMultiDimensionalArrays() throws Exception { try { ParseHelper.parse("void main() {\n" + " int A[3][4];\n" + "}\n"); fail("Exception was expected"); } catch (UnsupportedLanguageFeatureException exception) { assertTrue(exception.getMessage().contains("Not yet supporting multi-dimensional arrays")); } }
@Test public void testUnsupportedArrayInBaseType() throws Exception { try { ParseHelper.parse("void main() {\n" + " int[2] A, B[3];\n" + " B[2][1] = 3;\n" + "}\n"); fail("Exception was expected"); } catch (UnsupportedLanguageFeatureException exception) { assertTrue(exception.getMessage().contains("Array information specified at the base type")); } }
@Test public void testUnsupportedDeclarationInCondition() throws Exception { try { ParseHelper.parse("void main() {\n" + " while(bool b = true) {\n" + " if(b) {\n" + " break;\n" + " }\n" + " }\n" + "}\n"); fail("Exception was expected"); } catch (UnsupportedLanguageFeatureException exception) { assertTrue(exception.getMessage().contains("We do not yet support the case where the " + "condition of a 'for' or 'while' introduces a new variable")); } }
@Test public void testUnsupportedInitializerList() throws Exception { try { ParseHelper.parse("#version 440\n" + "\n" + "void main() {\n" + "\n" + " int A[4] = { 1, 2, 3, 4 };\n" + "\n" + "}\n"); fail("Exception was expected"); } catch (UnsupportedLanguageFeatureException exception) { assertTrue(exception.getMessage().contains("Initializer lists are not currently supported")); } }
@Test public void testUnsupportedMethodCall1() throws Exception { try { ParseHelper.parse("#version 310 es\n" + "\n" + "void main() {\n" + "\n" + " int A[4];\n" + " A.length();\n" + "\n" + "}\n"); fail("Exception was expected"); } catch (UnsupportedLanguageFeatureException exception) { assertTrue(exception.getMessage().contains("Method calls are not currently supported")); } }
@Test public void testUnsupportedMethodCall2() throws Exception { try { ParseHelper.parse("#version 310 es\n" + "\n" + "void main() {\n" + "\n" + " int A[4];\n" + " A.length(void);\n" + "\n" + "}\n"); fail("Exception was expected"); } catch (UnsupportedLanguageFeatureException exception) { assertTrue(exception.getMessage().contains("Method calls are not currently supported")); } }
@Test public void testUnsupportedMethodCall3() throws Exception { try { ParseHelper.parse("#version 320 es\n" + "\n" + "precision highp float;\n" + "\n" + "struct S { int A[4]; };\n" + "\n" + "void main() {\n" + "\n" + " S s = S(int[4](1,2,3,4));\n" + " s.A.length();\n" + "\n" + "}\n"); fail("Exception was expected"); } catch (UnsupportedLanguageFeatureException exception) { assertTrue(exception.getMessage().contains("Method calls are not currently supported")); } }
@Test public void testUnsupportedNamedInterfaceBlock() throws Exception { try { ParseHelper.parse("#version 320 es\n" + "\n" + "layout(std430, binding = 0) buffer doesNotMatter {\n" + " int x;\n" + " int data[];\n" + "} block_name_not_currently_supported;\n" + "void main() {\nprecision highp float;\n" + "}\n"); fail("Exception was expected"); } catch (UnsupportedLanguageFeatureException exception) { assertTrue(exception.getMessage().contains("Named interface blocks are not currently " + "supported")); } }