@Test public void apply5() throws Exception { ExprStmt toOutline = new ExprStmt(new BinaryExpr( new VariableIdentifierExpr(OpenGlConstants.GL_POINT_SIZE), new BinaryExpr(new VariableIdentifierExpr("x"), new VariableIdentifierExpr("x"), BinOp.ADD), BinOp.ASSIGN)); Scope fakeScope = new Scope(); fakeScope.add("x", BasicType.FLOAT, Optional.empty()); new OutlineStatementMutation(toOutline, fakeScope, tu, fakeFunction, new IdGenerator()).apply(); final String expectedDecl = "float " + Constants.OUTLINED_FUNCTION_PREFIX + "0(float x)\n" + "{\n" + PrettyPrinterVisitor.defaultIndent(1) + "return x + x;\n" + "}\n"; assertEquals(expectedDecl, tu.getTopLevelDeclarations().get(0).getText()); assertEquals(OpenGlConstants.GL_POINT_SIZE + " = " + Constants.OUTLINED_FUNCTION_PREFIX + "0" + "(x);\n", toOutline.getText()); }
@Override public void apply() { BinaryExpr binaryExpr = (BinaryExpr) toOutline.getExpr(); assert binaryExpr.getOp() == BinOp.ASSIGN; final List<String> referencedVariables = getReferencedVariables(binaryExpr.getRhs()); final String newFunctionName = Constants.OUTLINED_FUNCTION_PREFIX + idGenerator.freshId(); toOutline.setExpr(new BinaryExpr( binaryExpr.getLhs().clone(), new FunctionCallExpr(newFunctionName, referencedVariables.stream().map(VariableIdentifierExpr::new) .collect(Collectors.toList())), BinOp.ASSIGN)); final List<ParameterDecl> params = new ArrayList<>(); for (String v : referencedVariables) { final Type type = scopeOfStmt.lookupType(v); assert type != null; final Type varType = type.clone().getWithoutQualifiers(); assert !(varType.getWithoutQualifiers() instanceof ArrayType); params.add(new ParameterDecl(v, maybeGetStructNameType(varType), null)); } Type returnType = scopeOfStmt.lookupType( ((VariableIdentifierExpr) binaryExpr.getLhs()).getName()); if (returnType == null) { final Optional<Type> maybeTypeOfBuiltin = Typer.maybeGetTypeOfBuiltinVariable(((VariableIdentifierExpr) binaryExpr.getLhs()) .getName()); if (maybeTypeOfBuiltin.isPresent()) { returnType = maybeTypeOfBuiltin.get(); } else { throw new RuntimeException("No type for " + ((VariableIdentifierExpr) binaryExpr.getLhs()).getName()); } } returnType = maybeGetStructNameType(returnType.getWithoutQualifiers()); tu.addDeclarationBefore(new FunctionDefinition(new FunctionPrototype( newFunctionName, returnType, params), new BlockStmt(Collections.singletonList( new ReturnStmt(binaryExpr.getRhs().clone())), false)), enclosingFunction); }
OutlineStatementMutation implements Mutation { @Override public void apply() { BinaryExpr binaryExpr = (BinaryExpr) toOutline.getExpr(); assert binaryExpr.getOp() == BinOp.ASSIGN; final List<String> referencedVariables = getReferencedVariables(binaryExpr.getRhs()); final String newFunctionName = Constants.OUTLINED_FUNCTION_PREFIX + idGenerator.freshId(); toOutline.setExpr(new BinaryExpr( binaryExpr.getLhs().clone(), new FunctionCallExpr(newFunctionName, referencedVariables.stream().map(VariableIdentifierExpr::new) .collect(Collectors.toList())), BinOp.ASSIGN)); final List<ParameterDecl> params = new ArrayList<>(); for (String v : referencedVariables) { final Type type = scopeOfStmt.lookupType(v); assert type != null; final Type varType = type.clone().getWithoutQualifiers(); assert !(varType.getWithoutQualifiers() instanceof ArrayType); params.add(new ParameterDecl(v, maybeGetStructNameType(varType), null)); } Type returnType = scopeOfStmt.lookupType( ((VariableIdentifierExpr) binaryExpr.getLhs()).getName()); if (returnType == null) { final Optional<Type> maybeTypeOfBuiltin = Typer.maybeGetTypeOfBuiltinVariable(((VariableIdentifierExpr) binaryExpr.getLhs()) .getName()); if (maybeTypeOfBuiltin.isPresent()) { returnType = maybeTypeOfBuiltin.get(); } else { throw new RuntimeException("No type for " + ((VariableIdentifierExpr) binaryExpr.getLhs()).getName()); } } returnType = maybeGetStructNameType(returnType.getWithoutQualifiers()); tu.addDeclarationBefore(new FunctionDefinition(new FunctionPrototype( newFunctionName, returnType, params), new BlockStmt(Collections.singletonList( new ReturnStmt(binaryExpr.getRhs().clone())), false)), enclosingFunction); } }
OutlineStatementMutation implements Mutation { @Override public void apply() { BinaryExpr binaryExpr = (BinaryExpr) toOutline.getExpr(); assert binaryExpr.getOp() == BinOp.ASSIGN; final List<String> referencedVariables = getReferencedVariables(binaryExpr.getRhs()); final String newFunctionName = Constants.OUTLINED_FUNCTION_PREFIX + idGenerator.freshId(); toOutline.setExpr(new BinaryExpr( binaryExpr.getLhs().clone(), new FunctionCallExpr(newFunctionName, referencedVariables.stream().map(VariableIdentifierExpr::new) .collect(Collectors.toList())), BinOp.ASSIGN)); final List<ParameterDecl> params = new ArrayList<>(); for (String v : referencedVariables) { final Type type = scopeOfStmt.lookupType(v); assert type != null; final Type varType = type.clone().getWithoutQualifiers(); assert !(varType.getWithoutQualifiers() instanceof ArrayType); params.add(new ParameterDecl(v, maybeGetStructNameType(varType), null)); } Type returnType = scopeOfStmt.lookupType( ((VariableIdentifierExpr) binaryExpr.getLhs()).getName()); if (returnType == null) { final Optional<Type> maybeTypeOfBuiltin = Typer.maybeGetTypeOfBuiltinVariable(((VariableIdentifierExpr) binaryExpr.getLhs()) .getName()); if (maybeTypeOfBuiltin.isPresent()) { returnType = maybeTypeOfBuiltin.get(); } else { throw new RuntimeException("No type for " + ((VariableIdentifierExpr) binaryExpr.getLhs()).getName()); } } returnType = maybeGetStructNameType(returnType.getWithoutQualifiers()); tu.addDeclarationBefore(new FunctionDefinition(new FunctionPrototype( newFunctionName, returnType, params), new BlockStmt(Collections.singletonList( new ReturnStmt(binaryExpr.getRhs().clone())), false)), enclosingFunction); } OutlineStatementMutation(ExprStmt toOutline, Scope scopeOfStmt, TranslationUnit tu,
                                  FunctionDefinition enclosingFunction,
                                  IdGenerator idGenerator); }
OutlineStatementMutation implements Mutation { @Override public void apply() { BinaryExpr binaryExpr = (BinaryExpr) toOutline.getExpr(); assert binaryExpr.getOp() == BinOp.ASSIGN; final List<String> referencedVariables = getReferencedVariables(binaryExpr.getRhs()); final String newFunctionName = Constants.OUTLINED_FUNCTION_PREFIX + idGenerator.freshId(); toOutline.setExpr(new BinaryExpr( binaryExpr.getLhs().clone(), new FunctionCallExpr(newFunctionName, referencedVariables.stream().map(VariableIdentifierExpr::new) .collect(Collectors.toList())), BinOp.ASSIGN)); final List<ParameterDecl> params = new ArrayList<>(); for (String v : referencedVariables) { final Type type = scopeOfStmt.lookupType(v); assert type != null; final Type varType = type.clone().getWithoutQualifiers(); assert !(varType.getWithoutQualifiers() instanceof ArrayType); params.add(new ParameterDecl(v, maybeGetStructNameType(varType), null)); } Type returnType = scopeOfStmt.lookupType( ((VariableIdentifierExpr) binaryExpr.getLhs()).getName()); if (returnType == null) { final Optional<Type> maybeTypeOfBuiltin = Typer.maybeGetTypeOfBuiltinVariable(((VariableIdentifierExpr) binaryExpr.getLhs()) .getName()); if (maybeTypeOfBuiltin.isPresent()) { returnType = maybeTypeOfBuiltin.get(); } else { throw new RuntimeException("No type for " + ((VariableIdentifierExpr) binaryExpr.getLhs()).getName()); } } returnType = maybeGetStructNameType(returnType.getWithoutQualifiers()); tu.addDeclarationBefore(new FunctionDefinition(new FunctionPrototype( newFunctionName, returnType, params), new BlockStmt(Collections.singletonList( new ReturnStmt(binaryExpr.getRhs().clone())), false)), enclosingFunction); } OutlineStatementMutation(ExprStmt toOutline, Scope scopeOfStmt, TranslationUnit tu,
                                  FunctionDefinition enclosingFunction,
                                  IdGenerator idGenerator); @Override void apply(); }
OutlineStatementMutation implements Mutation { @Override public void apply() { BinaryExpr binaryExpr = (BinaryExpr) toOutline.getExpr(); assert binaryExpr.getOp() == BinOp.ASSIGN; final List<String> referencedVariables = getReferencedVariables(binaryExpr.getRhs()); final String newFunctionName = Constants.OUTLINED_FUNCTION_PREFIX + idGenerator.freshId(); toOutline.setExpr(new BinaryExpr( binaryExpr.getLhs().clone(), new FunctionCallExpr(newFunctionName, referencedVariables.stream().map(VariableIdentifierExpr::new) .collect(Collectors.toList())), BinOp.ASSIGN)); final List<ParameterDecl> params = new ArrayList<>(); for (String v : referencedVariables) { final Type type = scopeOfStmt.lookupType(v); assert type != null; final Type varType = type.clone().getWithoutQualifiers(); assert !(varType.getWithoutQualifiers() instanceof ArrayType); params.add(new ParameterDecl(v, maybeGetStructNameType(varType), null)); } Type returnType = scopeOfStmt.lookupType( ((VariableIdentifierExpr) binaryExpr.getLhs()).getName()); if (returnType == null) { final Optional<Type> maybeTypeOfBuiltin = Typer.maybeGetTypeOfBuiltinVariable(((VariableIdentifierExpr) binaryExpr.getLhs()) .getName()); if (maybeTypeOfBuiltin.isPresent()) { returnType = maybeTypeOfBuiltin.get(); } else { throw new RuntimeException("No type for " + ((VariableIdentifierExpr) binaryExpr.getLhs()).getName()); } } returnType = maybeGetStructNameType(returnType.getWithoutQualifiers()); tu.addDeclarationBefore(new FunctionDefinition(new FunctionPrototype( newFunctionName, returnType, params), new BlockStmt(Collections.singletonList( new ReturnStmt(binaryExpr.getRhs().clone())), false)), enclosingFunction); } OutlineStatementMutation(ExprStmt toOutline, Scope scopeOfStmt, TranslationUnit tu,
                                  FunctionDefinition enclosingFunction,
                                  IdGenerator idGenerator); @Override void apply();  }