Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import java.io.BufferedReader
- import java.io.File
- import java.io.FileReader
- import java.io.IOException
- import java.nio.file.Files
- import java.nio.file.Paths
- import java.util._
- import java.io._
- import java.nio.charset._
- import org.apache.commons.io._
- import org.eclipse.jdt.core.dom.MethodDeclaration
- import org.eclipse.jdt.core.JavaCore
- import org.eclipse.jdt.core.dom._
- import org.eclipse.jdt.core.dom.rewrite.ASTRewrite
- import org.eclipse.jdt.core.dom.rewrite.ITrackedNodePosition
- import org.eclipse.jdt.core.dom.rewrite.ListRewrite
- import org.eclipse.jface.text.BadLocationException
- import org.eclipse.jface.text.Document
- import scala.collection.mutable.HashSet
- import org.eclipse.text.edits.TextEdit
- import org.eclipse.text.edits.UndoEdit
- import org.apache.commons.io.FileUtils.readFileToString
- import org.slf4j.{Logger, LoggerFactory}
- import scala.collection.mutable
- object MainScala {
- @throws[IOException]
- @throws[BadLocationException]
- def main(args: Array[String]): Unit = {
- val config = System.getProperty("user.dir") + "/src/config.properties"
- val input = new FileInputStream(config)
- val prop = new Properties
- prop.load(input)
- val is = new FileInputStream(prop.getProperty("file"))
- val buf = new BufferedReader(new InputStreamReader(is))
- var line = buf.readLine
- val sb = new StringBuilder
- while ( {
- line != null
- }) {
- sb.append(line).append("\n")
- line = buf.readLine
- }
- val fileName = sb.toString.toCharArray
- val document = new Document(sb.toString)
- val parser = ASTParser.newParser(AST.JLS3)
- parser.setKind(ASTParser.K_COMPILATION_UNIT)
- parser.setResolveBindings(true)
- val options = JavaCore.getOptions
- val unitName = "Test.java"
- parser.setUnitName(unitName)
- parser.setCompilerOptions(options)
- parser.setSource(document.get.toCharArray)
- val sources = Array("/Users/Abdel/Documents/Fall2019/CS474/Final_Proj_474/src")
- val classpath = Array("")
- parser setEnvironment(classpath, sources, Array[String]("UTF-8"), true)
- parser.setBindingsRecovery(true)
- parser.setResolveBindings(true)
- parser.setCompilerOptions(options)
- parser.setStatementsRecovery(true)
- //parser.setSource(fileName);
- val cu = parser.createAST(null).asInstanceOf[CompilationUnit]
- //----------------------------------------------------------------------------------------------------------------------
- val root = cu.getRoot
- //Creating logger to log statements
- def log : Logger = LoggerFactory.getLogger(MainScala.getClass)
- //Creating Abstract Syntax Tree from compilation unit
- val ast = cu.getAST
- //ASTRewriter to allow modifications in the code
- val rewriter = ASTRewrite.create(ast)
- cu.recordModifications()
- val typeDec:TypeDeclaration = cu.types().get(0).asInstanceOf[TypeDeclaration]//typeDec is the class
- var className:String = typeDec.getName.toString
- //Traversing AST using AST Parser
- cu.accept(new ASTVisitor() {
- var names: HashSet[String] = HashSet(" ")
- //When visiting a variable declaration fragment
- override def visit(node: VariableDeclarationFragment): Boolean = {
- //Gathering basic information of the node
- //Name of the node
- val name = node.getName
- //Adding it to the hashset of variables
- this.names.add(name.getIdentifier)
- val id = ast.newImportDeclaration
- id.setName(ast.newName(Array[String]("java", "util", "Set")))
- val lrw = rewriter.getListRewrite(cu, CompilationUnit.IMPORTS_PROPERTY)
- //Empty list of statements
- val s = new ArrayList[Statement]
- //Creating empty block to be inserted into the node if necessary
- val block = ast.newBlock
- //if node is only a variable declaration fragment and NOT a variable delcaration statement withing a function
- if (node.getParent.getNodeType == 23) {
- //Log name, type, and line number
- log.info("Global Declaration of : " + node.getName + " with Type: " + node.resolveBinding.getType.getQualifiedName + " at Line " + cu.getLineNumber(node.getStartPosition) )
- val type1 = node.resolveBinding.getType.getQualifiedName.toString
- val name = node.getName.toString
- //Will check the variable to see if it's Initialized or not
- //If it's not, it must be instrum in a different way
- if(node.getInitializer!= null) {//if initialized
- //Getting value of variable
- val value = node.getInitializer.toString
- //Getting variable declaration string
- val declaration = (name + "=" + value).toString
- //Create instrumentation statement and rewrite to document
- val placeHolder = rewriter.createStringPlaceholder("Template.instrum(" + "\""+ type1 + "\"" +"," + "\""+ declaration + "\"" + ");", 20).asInstanceOf[Statement]
- //Adding new statment to list of statements
- s.add(placeHolder)
- }
- else{//if not initialized
- //Creating empty value of variable
- val value= ""
- val declaration= (name)
- //Create instrumentation statement and rewrite to document
- val placeHolder = rewriter.createStringPlaceholder("Template.instrum(" + "\""+ type1 + "\"" +"," + "\""+ declaration + "\"" + ");", 20).asInstanceOf[Statement]
- //Adding new statment to list of statements
- s.add(placeHolder)
- }
- }
- lrw.replace(node, id, null)
- val name1 = "var " + node.getName.toString
- val varDecFrag = ast.newVariableDeclarationFragment
- true // do not continue to avoid usage info
- }
- // override def visit(node: SimpleName): Boolean = {
- // if (this.names.contains(node.getIdentifier)) {
- // //System.out.println("Usage of '" + node + "' at line " + cu.getLineNumber(node.getStartPosition()));
- // }
- // true
- // }
- //When visiting a method declaration
- override def visit(node: MethodDeclaration): Boolean = { //CREATE NEW BLOCK
- //Creating empty block to be inserted into the node
- val block = ast.newBlock
- //Old block with statements
- val block1 = node.getBody
- //Empty list of statements
- val s = new ArrayList[Statement]
- //Getting statements from body of function
- val lstStmt = node.getBody.statements()
- val placeHolder: Statement = rewriter.createStringPlaceholder("//Declaration of Method: "+ node.getName()+ " with parameters: "+ node.parameters() + " returning: "+ node.getReturnType2() + " at Line: "+cu.getLineNumber(node.getStartPosition) , 20).asInstanceOf[Statement]
- s.add(placeHolder)
- log.info("Method Declaration: "+ node.getName()+ " with parameters: "+ node.parameters() + " returning: "+ node.getReturnType2() + " at Line: "+cu.getLineNumber(node.getStartPosition) )
- //Retrieveing strings method info
- val name = node.getName.toString
- val rType = node.getReturnType2.toString
- val param = node.parameters.toString
- //creating and adding new instrumenatation statement to statement list
- val placeHolder3 = rewriter.createStringPlaceholder(
- "Template.instrum(" + "\""+ rType + "\"" +"," + "\""+ name + "\"" + "," + "\""+ param + "\"" + ");", 20).asInstanceOf[Statement]
- s.add(placeHolder3)
- //Traversing statements from body of method, checking each type of statement to be instrumented
- //This is where the bulk of the logging will take place, accessing different types of statements (ex. Methods, While loops, variable Declarations)
- var x = 0
- while ( {
- x < block1.statements.size
- }) {
- //Adding statement to array of new statements to be instrumented
- s.add(block1.statements.get(x).asInstanceOf[Statement])
- //If variable declaration statement
- if (block1.statements.get(x).isInstanceOf[VariableDeclarationStatement]) {
- val node1 = block1.statements.get(x).asInstanceOf[VariableDeclarationStatement]
- //Debug logger
- log.info("Local Declaration of : " + node1.fragments + " with Type: " + node1.getType + " at Line " +cu.getLineNumber(node1.getStartPosition))
- //Break fragements of statement
- val fragments= node1.fragments()
- //Gather name and type from fragments
- val name = fragments.get(0)
- val type1 = node1.getType.toString
- //Create and rewrite with new instrumentation statement
- val placeHolder3 = rewriter.createStringPlaceholder(
- "Template.instrum(" + "\""+ type1 + "\"" +"," + "\""+ name + "\"" + ");", 20).asInstanceOf[Statement]
- //Add instrumentation statement to list of statements
- s.add(placeHolder3)
- }
- //Will check for instances of While Loop statements
- else if(block1.statements().get(x).isInstanceOf[WhileStatement]){
- //Store the While Statement into a node
- val node1 = block1.statements.get(x).asInstanceOf[WhileStatement]
- log.info("While Statement Expression: '" + node1.getExpression +"' at Line " +cu.getLineNumber(node1.getStartPosition))
- //Will store the WhileExpresssion, will identify the name of the instrum case as 'While Loop' and then add to the Template class
- val whileExpression= node1.getExpression.toString
- val name = "While Loop"
- //Create and rewrite with new instrumentation statement
- val placeHolder4= rewriter.createStringPlaceholder(
- "Template.instrum(" + "\""+ name + "\"" +"," + "\""+ whileExpression + "\"" + ");", 20).asInstanceOf[Statement]
- //Add instrumentation statement to list of statements
- s.add(placeHolder4)
- }
- //Will check for all instances of For Loop Statements
- else if(block1.statements().get(x).isInstanceOf[ForStatement]){
- //Stores the For Loop Statement into a node
- val node1 = block1.statements.get(x).asInstanceOf[ForStatement]
- log.info("For Statement Statement: '" + node1.getExpression+ "' at Line " +cu.getLineNumber(node1.getStartPosition))
- //Will store the forExpresssion, will identify the name of the instrum case as 'For Loop' and then adds to the Template class
- val forExpression= node1.getExpression.toString
- val name = "For Loop"
- //Create and rewrite with new instrumentation statement
- val placeHolder5= rewriter.createStringPlaceholder(
- "Template.instrum(" + "\""+ name + "\"" +"," + "\""+ forExpression + "\"" + ");", 20).asInstanceOf[Statement]
- //Add instrumentation statement to list of statements
- s.add(placeHolder5)
- }
- //If it's a do while loop
- else if(block1.statements().get(x).isInstanceOf[DoStatement]) {
- //Get do while node
- val node1 = block1.statements.get(x).asInstanceOf[DoStatement]
- //Debug Logger
- log.info("Do-While Statement: '" + node1.getExpression + "' at Line " + cu.getLineNumber(node1.getStartPosition))
- //Gather info from do while
- val doWhileExpression = node1.getExpression.toString
- val name = "Do-While Loop"
- //Create and rewrite with new instrumentation statement
- val placeHolder6 = rewriter.createStringPlaceholder(
- "Template.instrum(" + "\"" + name + "\"" + "," + "\"" + doWhileExpression + "\"" + ");", 20).asInstanceOf[Statement]
- //Add instrumentation statement to list of statements
- s.add(placeHolder6)
- }
- //ToDo: Will not work if the If and Else is at the very end of the method (Receive an 'unused statement' error)
- else if(block1.statements().get(x).isInstanceOf[IfStatement]) {
- //Will store the If-Else statement into a node
- val node1 = block1.statements.get(x).asInstanceOf[IfStatement]
- log.info("If-Else Statement: '" + node1.getExpression + "' at Line " + cu.getLineNumber(node1.getStartPosition))
- //Will store the Expression for the If-Else statement into ifElseExpression as a string, it's instance type, and updates to the Template class
- val ifElseExpression = node1.getExpression.toString
- val name = "If-Else Statement"
- var elseStatement=""
- //In case the use only write the 'if' statement without 'else'
- if(node1.getElseStatement != null) {
- var elseStatement = node1.getElseStatement.toString
- }
- //Removes the semicolon that automatically creates a new line
- //Thus preventing an error to the NewJava File
- if (elseStatement.contains(";")){
- val parts = elseStatement.split(";")
- elseStatement = parts(0)
- }
- //ToDo: It will log it but not create an instrum due to the unused statement error
- /*
- val placeHolder7 = rewriter.createStringPlaceholder(
- "Template.instrum(" + "\"" + name + "\"" + "," + "\"" + elseStatement + "\"" + ");", 20).asInstanceOf[Statement]
- s.add(placeHolder7)
- */
- }
- {
- //Increments
- x += 1; x - 1
- }
- }
- //Will store all the block statements into list rewrite, and will Insert Last
- val listRewrite = rewriter.getListRewrite(block, Block.STATEMENTS_PROPERTY)
- var i = 0
- while ( {
- i < s.size
- }) {
- listRewrite.insertLast(s.get(i), null)
- {
- i += 1; i - 1
- }
- }
- val methodDeclaration = ast.newMethodDeclaration
- methodDeclaration.setBody(block)
- rewriter.set(node, MethodDeclaration.BODY_PROPERTY, block, null)
- true
- }
- })
- //Writing/modifying the file
- val edits = rewriter.rewriteAST(document, null)
- //Applying the writes the document
- edits.apply(document)
- var docString = document.get
- /*
- -Replaces the name of the new file so that it is not the same as the input Java Program
- This ensures that the file can run without any issues of having multiple files with
- the same name
- */
- val newClass= "new_" + className
- docString = docString.replaceAll(className,newClass)
- //Variables for writing to a new file
- val writer = new BufferedWriter( new FileWriter( "src/main/Java/"+newClass+".java"));
- //Writing into the new file
- writer.write( docString );
- //Close writer
- writer.close();
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement