Skip to content

Commit

Permalink
Added Flo's Optimized PrettyPrinter
Browse files Browse the repository at this point in the history
  • Loading branch information
aJanker committed Mar 8, 2013
1 parent 050eb5a commit dd40def
Show file tree
Hide file tree
Showing 11 changed files with 66 additions and 40 deletions.
Expand Up @@ -2,6 +2,7 @@ package de.fosd.typechef.parser.c

import de.fosd.typechef.conditional._
import de.fosd.typechef.featureexpr.{FeatureExprFactory, FeatureExpr}
import java.io.Writer

object PrettyPrinter {

Expand Down Expand Up @@ -51,6 +52,26 @@ object PrettyPrinter {

def print(ast: AST): String = layout(prettyPrint(ast))

def layoutW(d: Doc, p: Writer): Unit = d match {
case Empty => p.write("")
case Line => p.write("\n")
case Text(s) => p.write(s)
case Cons(l, r) =>
layoutW(l, p)
layoutW(r, p)
case Nest(n, Empty) => layoutW(Empty, p)
case Nest(n, Line) => p.write("\n" + (" " * n))
case Nest(n, Text(s)) => layoutW(Text(s), p)
case Nest(n, Cons(l, r)) => layoutW(Cons(Nest(n, l), Nest(n, r)), p)
case Nest(i, Nest(j, x)) => layoutW(Nest(i + j, x), p)
case _ =>
}

def printW(ast: AST, writer: Writer): Writer = {
layoutW(prettyPrint(ast), writer)
writer
}


def ppConditional(e: Conditional[_], list_feature_expr: List[FeatureExpr]): Doc = e match {
case One(c: AST) => prettyPrint(c, list_feature_expr)
Expand Down
@@ -1,6 +1,5 @@
package de.fosd.typechef.crefactor;

import de.fosd.typechef.crefactor.backend.Cache;
import de.fosd.typechef.crefactor.frontend.Editor;
import de.fosd.typechef.crefactor.frontend.loader.Loader;
import de.fosd.typechef.crefactor.util.Configuration;
Expand Down Expand Up @@ -71,10 +70,10 @@ public void run() {
}

// parse file
if (Cache.parse(typeChefConfig) == null) {
System.err.println("Something really bad happend");
System.exit(-1);
}
/**if (Cache.parse(typeChefConfig) == null) {
System.err.println("Something really bad happend");
System.exit(-1);
} */

// show editor window
final Editor editor = new Editor(new Morpheus(ast, loadingWindow.getFileToAnalyse()));
Expand Down
Expand Up @@ -13,6 +13,7 @@
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.StringWriter;
import java.lang.management.ManagementFactory;
import java.lang.management.ThreadMXBean;
import java.util.Observable;
Expand Down Expand Up @@ -112,7 +113,7 @@ public final Morpheus getMorpheus() {
public void update(final Observable observable, final Object o) {
final ThreadMXBean tb = ManagementFactory.getThreadMXBean();
final long time = tb.getCurrentThreadCpuTime();
this.textArea.setText(PrettyPrinter.print(this.morpheus.getAST()));
this.textArea.setText(PrettyPrinter.printW(this.morpheus.getAST(), new StringWriter()).toString());
System.out.println("PrettyPrinting duration: " + (tb.getCurrentThreadCpuTime() - time) / 1000000);
}
}
Expand Up @@ -55,7 +55,7 @@ public void menuSelected(MenuEvent menuEvent) {
/**
* Refactor Renaming
*/
final List<Id> availableIds = RenameIdentifier.getAvailableIdentifiers(morpheus.getAST(), morpheus.getASTEnv(), selection);
final List<Id> availableIds = RenameIdentifier.getAvailableIdentifiers(morpheus, selection);
if (!availableIds.isEmpty()) {
final JMenu rename = new JMenu(Configuration.getInstance().getConfig("refactor.rename.name"));
this.menu.add(rename);
Expand All @@ -79,15 +79,15 @@ public void menuSelected(MenuEvent menuEvent) {
this.menu.add(extract);
extract.setEnabled(eligable);*/

final List<AST> extractSelection = ExtractMethod.getSelectedElements(morpheus.getAST(), morpheus.getASTEnv(), selection);
final List<AST> extractSelection = ExtractMethod.getSelectedElements(morpheus, selection);
final JMenuItem extract = new JMenuItem(RefactorAction.getExtractFunction(morpheus, extractSelection));
this.menu.add(extract);
extract.setEnabled(ExtractMethod.isAvailable(morpheus.getAST(), morpheus.getASTEnv(), selection));
extract.setEnabled(ExtractMethod.isAvailable(morpheus, selection));

/**
* Inline Function
*/
final List<Id> availableFuncIDs = InlineFunction.getAvailableIdentifiers(morpheus.getAST(), morpheus.getASTEnv(), selection);
final List<Id> availableFuncIDs = InlineFunction.getAvailableIdentifiers(morpheus, selection);
if (!availableFuncIDs.isEmpty()) {
final JMenu inline = new JMenu(Configuration.getInstance().getConfig("refactor.inline.name"));
this.menu.add(inline);
Expand Down
@@ -1,21 +1,21 @@
package de.fosd.typechef.crefactor.backend

import de.fosd.typechef.crewrite.ASTEnv
import de.fosd.typechef.parser.c.{Id, AST}
import de.fosd.typechef.crefactor.frontend.util.Selection
import de.fosd.typechef.crefactor.Morpheus

trait ASTSelection {

def getSelectedElements(ast: AST, astEnv: ASTEnv, selection: Selection): List[AST]
def getSelectedElements(morpheus: Morpheus, selection: Selection): List[AST]

def getAvailableIdentifiers(ast: AST, astEnv: ASTEnv, selection: Selection): List[Id]
def getAvailableIdentifiers(morpheus: Morpheus, selection: Selection): List[Id]

protected def isInSelectionRange(value: AST, selection: Selection): Boolean = {
/**
* Annotated ast elements have often the same starting line. As workaround we only identify the element by its end value.
*/
(isInRange(value.getPositionTo.getLine, selection.getLineStart, selection.getLineEnd))
// TODO ROW!
(isInRange(value.getPositionTo.getLine, selection.getLineStart + 1, (selection.getLineEnd - 1)))
// TODO FIX IT -> Broken!
// && ((selection.getRowEnd <= value.getPositionTo.getColumn) || (selection.getRowEnd <= value.getPositionTo.getColumn)))
}

Expand Down
Expand Up @@ -2,7 +2,6 @@ package de.fosd.typechef.crefactor.backend.refactor

import de.fosd.typechef.crefactor.backend.ASTSelection
import de.fosd.typechef.parser.c._
import de.fosd.typechef.crewrite.ASTEnv
import de.fosd.typechef.crefactor.frontend.util.Selection
import de.fosd.typechef.parser.c.PostfixExpr
import de.fosd.typechef.parser.c.Id
Expand Down Expand Up @@ -38,12 +37,12 @@ import de.fosd.typechef.crefactor.Morpheus
*/
// TODO Replace original ExtractFunction -> Delete and Refactor
object ExtractMethod extends ASTSelection with Refactor {
def getSelectedElements(ast: AST, astEnv: ASTEnv, selection: Selection): List[AST] = {
def getSelectedElements(morpheus: Morpheus, selection: Selection): List[AST] = {

val ids = filterASTElementsForFile[Id](filterASTElems[Id](ast).par.filter(x => isInSelectionRange(x, selection)).toList, selection.getFilePath)
val ids = filterASTElementsForFile[Id](filterASTElems[Id](morpheus.getAST).par.filter(x => isInSelectionRange(x, selection)).toList, selection.getFilePath)

def findMostUpwardExpr(element: Expr): Expr = {
parentAST(element, astEnv) match {
parentAST(element, morpheus.getASTEnv) match {
case e: Id => findMostUpwardExpr(e)
case e: Constant => findMostUpwardExpr(e)
case e: StringLit => findMostUpwardExpr(e)
Expand All @@ -64,7 +63,7 @@ object ExtractMethod extends ASTSelection with Refactor {
}

def findParent(id: Id): Some[AST] = {
val priorElement = findPriorASTElem[Statement](id, astEnv)
val priorElement = findPriorASTElem[Statement](id, morpheus.getASTEnv)
priorElement match {
case None => null
case _ => priorElement.get match {
Expand All @@ -85,7 +84,7 @@ object ExtractMethod extends ASTSelection with Refactor {
def exploitStatements(statement: Statement): Statement = {
try {
// val parentStatement = parentAST(statement, astEnv) // debug purpose only
parentAST(statement, astEnv) match {
parentAST(statement, morpheus.getASTEnv) match {
case null =>
assert(false, "An error during determine the preconditions occured.")
statement
Expand Down Expand Up @@ -125,14 +124,19 @@ object ExtractMethod extends ASTSelection with Refactor {
parents.sortWith(comparePosition)
}

def getAvailableIdentifiers(ast: AST, astEnv: ASTEnv, selection: Selection): List[Id] = getSelectedElements(ast, astEnv, selection).isEmpty match {
def getAvailableIdentifiers(morpheus: Morpheus, selection: Selection): List[Id] = getSelectedElements(morpheus, selection).isEmpty match {
case true => null
case false => List[Id]() // returns a empty list to signalize a valid selection was found
}

def isAvailable(ast: AST, astEnv: ASTEnv, selection: Selection): Boolean = !getSelectedElements(ast, astEnv, selection).isEmpty // TODO Check if selection is valid for extraction
def isAvailable(morpheus: Morpheus, selection: Selection): Boolean = {
if (getSelectedElements(morpheus, selection).isEmpty) return false

true
}

def extract(morph: Morpheus, selection: List[AST]): AST = {
null
}

}
Expand Up @@ -48,18 +48,18 @@ import de.fosd.typechef.parser.c.ParameterDeclarationD
*/
object InlineFunction extends ASTSelection with Refactor {

def getSelectedElements(ast: AST, astEnv: ASTEnv, selection: Selection): List[AST] = {
val functions = (filterASTElems[FunctionDef](ast) ::: filterASTElems[FunctionCall](ast)
::: filterAllASTElems[NestedFunctionDef](ast)).filter(x => isSelected(x, astEnv, selection))
def getSelectedElements(morpheus: Morpheus, selection: Selection): List[AST] = {
val functions = (filterASTElems[FunctionDef](morpheus.getAST) ::: filterASTElems[FunctionCall](morpheus.getAST)
::: filterAllASTElems[NestedFunctionDef](morpheus.getAST)).filter(x => isSelected(x, morpheus.getASTEnv, selection))
filterASTElementsForFile(functions, selection.getFilePath).sortWith(comparePosition)
}

def getAvailableIdentifiers(ast: AST, astEnv: ASTEnv, selection: Selection): List[Id] = {
val ids = getSelectedElements(ast, astEnv, selection).map(x => getFunctionIdentifier(x, astEnv))
def getAvailableIdentifiers(morpheus: Morpheus, selection: Selection): List[Id] = {
val ids = getSelectedElements(morpheus, selection).map(x => getFunctionIdentifier(x, morpheus.getASTEnv))
ids.sortWith(comparePosition)
}

def isAvailable(ast: AST, astEnv: ASTEnv, selection: Selection): Boolean = !getAvailableIdentifiers(ast, astEnv, selection).isEmpty
def isAvailable(morpheus: Morpheus, selection: Selection): Boolean = !getAvailableIdentifiers(morpheus, selection).isEmpty

def isFunctionCall(morpheus: Morpheus, id: Id): Boolean = {
parentAST(id, morpheus.getASTEnv) match {
Expand Down
Expand Up @@ -6,7 +6,7 @@ import de.fosd.typechef.typesystem.CEnvCache
import de.fosd.typechef.crefactor.Morpheus
import org.kiama.rewriting.Rewriter._
import de.fosd.typechef.parser.c._
import de.fosd.typechef.crewrite.{ASTEnv, ConditionalNavigation, ASTNavigation}
import de.fosd.typechef.crewrite.{ConditionalNavigation, ASTNavigation}
import de.fosd.typechef.crefactor.frontend.util.Selection
import de.fosd.typechef.parser.c.Id
import scala.Some
Expand Down Expand Up @@ -67,7 +67,7 @@ trait Refactor extends CEnvCache with ASTNavigation with ConditionalNavigation {
"_Thread_local"
)

def isAvailable(ast: AST, astEnv: ASTEnv, selection: Selection): Boolean
def isAvailable(morpheus: Morpheus, selection: Selection): Boolean

/**
* Checks if the name of a variable is compatible to the iso c standard. See 6.4.2 of the iso standard
Expand Down
Expand Up @@ -2,7 +2,6 @@ package de.fosd.typechef.crefactor.backend.refactor

import de.fosd.typechef.crefactor.backend.ASTSelection
import de.fosd.typechef.parser.c.{Id, AST}
import de.fosd.typechef.crewrite.ASTEnv
import de.fosd.typechef.crefactor.frontend.util.Selection
import de.fosd.typechef.crefactor.Morpheus
import de.fosd.typechef.crefactor.util.Configuration
Expand All @@ -12,16 +11,16 @@ import de.fosd.typechef.crefactor.util.Configuration
*/
object RenameIdentifier extends ASTSelection with Refactor {

def getSelectedElements(ast: AST, astEnv: ASTEnv, selection: Selection): List[AST] = getAvailableIdentifiers(ast, astEnv, selection)
def getSelectedElements(morpheus: Morpheus, selection: Selection): List[AST] = getAvailableIdentifiers(morpheus, selection)

def getAvailableIdentifiers(ast: AST, astEnv: ASTEnv, selection: Selection): List[Id] = {
filterASTElems[Id](ast).par.filter(x => isInSelectionRange(x, selection)).toList.flatMap(x => {
def getAvailableIdentifiers(morpheus: Morpheus, selection: Selection): List[Id] = {
filterASTElems[Id](morpheus.getAST).par.filter(x => isInSelectionRange(x, selection)).toList.flatMap(x => {
if (isElementOfFile(x, selection.getFilePath)) Some(x)
else None
})
}

def isAvailable(ast: AST, astEnv: ASTEnv, selection: Selection): Boolean = !getAvailableIdentifiers(ast, astEnv, selection).isEmpty
def isAvailable(morpheus: Morpheus, selection: Selection): Boolean = !getAvailableIdentifiers(morpheus, selection).isEmpty

def rename(id: Id, newName: String, morpheus: Morpheus): AST = {
assert(isValidName(newName), Configuration.getInstance().getConfig("default.error.invalidName"))
Expand Down
Expand Up @@ -2,12 +2,14 @@ package de.fosd.typechef.crefactor

import backend.refactor.RenameIdentifier
import org.junit.Test
import java.io.{InputStream, FileInputStream, FilenameFilter, File}
import java.io._
import de.fosd.typechef.parser.c._
import de.fosd.typechef.parser.c.TranslationUnit
import de.fosd.typechef.parser.c.CTypeContext
import java.util.IdentityHashMap
import de.fosd.typechef.crewrite.{ConditionalNavigation, ASTNavigation}
import de.fosd.typechef.parser.c.Id
import de.fosd.typechef.parser.c.GnuAsmExpr
import de.fosd.typechef.parser.c.CTypeContext
import de.fosd.typechef.parser.c.TranslationUnit


/**
Expand Down Expand Up @@ -80,7 +82,7 @@ class RenamingTest extends ASTNavigation with ConditionalNavigation {


val prettyPrint = tb.getCurrentThreadCpuTime
val prettyPrinter = PrettyPrinter.print(refactored)
val prettyPrinter = PrettyPrinter.printW(refactored, new StringWriter()).toString
resultBuilder.append("++Pretty printing (size:" + prettyPrinter.length + ") time: " + (tb.getCurrentThreadCpuTime - prettyPrint) / nsToMs + "ms ++\n")
val file = new File(prettyPrint_Output + piFile.getName + "_" + i)
file.createNewFile()
Expand Down
File renamed without changes.

0 comments on commit dd40def

Please sign in to comment.