/** * Copyright (C) 2015 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package mujava.op.util; import java.io.*; import java.util.Enumeration; import openjava.ptree.*; import openjava.ptree.util.ParseTreeVisitor; /** * <p>Description: </p> * @author Yu-Seung Ma * @update Lin Deng Add support for AssertStatement * @version 1.0 */ public class LineNumerAnalyzer extends ParseTreeVisitor { public LineNumerAnalyzer() { } protected PrintWriter out; //public static String NEWLINE; public String class_name = null; //public String target_name = null; public int line_num=1; public int mutated_line=-1; /** to write debugging code */ private String tab = " "; private int nest = 0; public void setTab( String str ) { tab = str; } public String getTab() { return tab; } public void setNest( int i ) { nest = i; } public int getNest() { return nest; } public void pushNest() { setNest( getNest() + 1 ); } public void popNest() { setNest( getNest() - 1 ); } public void visit( ClassDeclaration p ) throws ParseTreeException { ModifierList modifs = p.getModifiers(); if (modifs != null) { modifs.accept( this ); } line_num++; MemberDeclarationList classbody = p.getBody(); line_num++; if (classbody.isEmpty()) { classbody.accept( this ); } else { line_num++; classbody.accept( this ); } line_num++; } public void visit( ConstructorDeclaration p ) throws ParseTreeException { TypeName[] tnl = p.getThrows(); if (tnl.length != 0) { line_num++; tnl[0].accept( this ); } ConstructorInvocation sc = p.getConstructorInvocation(); StatementList body = p.getBody(); if (body == null && sc == null) { line_num++; } else { line_num++; line_num++; if (sc != null) sc.accept( this ); if (body != null) body.accept( this ); } line_num++; } public void visit( AllocationExpression p ) throws ParseTreeException { TypeName tn = p.getClassType(); tn.accept( this ); ExpressionList args = p.getArguments(); writeArguments( args ); MemberDeclarationList mdlst = p.getClassBody(); if (mdlst != null) { line_num++; mdlst.accept( this ); } } public void visit( ArrayAccess p ) throws ParseTreeException { Expression expr = p.getReferenceExpr(); if (expr instanceof Leaf || expr instanceof ArrayAccess || expr instanceof FieldAccess || expr instanceof MethodCall || expr instanceof Variable) { expr.accept( this ); } else { writeParenthesis( expr ); } Expression index_expr = p.getIndexExpr(); index_expr.accept( this ); } public void visit( ArrayAllocationExpression p ) throws ParseTreeException { TypeName tn = p.getTypeName(); tn.accept( this ); ExpressionList dl = p.getDimExprList(); for (int i = 0; i < dl.size(); ++i) { Expression expr = dl.get( i ); if (expr != null) { expr.accept( this ); } } ArrayInitializer ainit = p.getInitializer(); if (ainit != null) ainit.accept( this ); } public void visit( ArrayInitializer p ) throws ParseTreeException { writeListWithDelimiter( p, ", " ); } public void visit( AssignmentExpression p ) throws ParseTreeException { Expression lexpr = p.getLeft(); if (lexpr instanceof AssignmentExpression) { writeParenthesis( lexpr ); } else { lexpr.accept( this ); } Expression rexp = p.getRight(); rexp.accept( this ); } public void visit( BinaryExpression p ) throws ParseTreeException { Expression lexpr = p.getLeft(); if (isOperatorNeededLeftPar( p.getOperator(), lexpr )) { writeParenthesis( lexpr ); } else { lexpr.accept( this ); } Expression rexpr = p.getRight(); if (isOperatorNeededRightPar( p.getOperator(), rexpr )) { writeParenthesis( rexpr ); } else { rexpr.accept( this ); } } public void visit( Block p ) throws ParseTreeException { StatementList stmts = p.getStatements(); writeStatementsBlock( stmts ); line_num++; } public void visit( BreakStatement p ) throws ParseTreeException { line_num++; } public void visit( CaseGroup p ) throws ParseTreeException { ExpressionList labels = p.getLabels(); for (int i = 0; i < labels.size(); ++i) { Expression label = labels.get( i ); if (label == null) { } else { label.accept( this ); } line_num++; } StatementList stmts = p.getStatements(); stmts.accept( this ); } public void visit( CaseGroupList p ) throws ParseTreeException { //writeListWithSuffix( p, NEWLINE ); writeListWithSuffixNewline(p); } public void visit( CaseLabel p ) throws ParseTreeException { Expression expr = p.getExpression(); if (expr != null) { expr.accept( this ); } else { } } public void visit( CaseLabelList p ) throws ParseTreeException { //writeListWithSuffix( p, NEWLINE ); writeListWithSuffixNewline( p ); } public void visit( CastExpression p ) throws ParseTreeException { TypeName ts = p.getTypeSpecifier(); ts.accept( this ); Expression expr = p.getExpression(); if(expr instanceof AssignmentExpression || expr instanceof ConditionalExpression || expr instanceof BinaryExpression || expr instanceof InstanceofExpression || expr instanceof UnaryExpression){ writeParenthesis( expr ); } else { expr.accept( this ); } } public void visit( CatchBlock p ) throws ParseTreeException { Parameter param = p.getParameter(); param.accept( this ); StatementList stmts = p.getBody(); writeStatementsBlock( stmts ); } public void visit( CatchList p ) throws ParseTreeException { writeList( p ); } public void visit( ClassDeclarationList p ) throws ParseTreeException { writeListWithDelimiterNewline( p); } public void visit( ClassLiteral p ) throws ParseTreeException { TypeName type = p.getTypeName(); type.accept(this); } public void visit( CompilationUnit p ) throws ParseTreeException { String qn = p.getPackage(); if (qn != null) { line_num++; } /* import statement list */ String[] islst = p.getDeclaredImports(); if (islst.length != 0) { for (int i = 0; i < islst.length; ++i) { line_num++; } line_num++; } /* type declaration list */ ClassDeclarationList tdlst = p.getClassDeclarations(); tdlst.accept( this ); } public void visit( ConditionalExpression p ) throws ParseTreeException { Expression condition = p.getCondition(); if (condition instanceof AssignmentExpression || condition instanceof ConditionalExpression) { writeParenthesis( condition ); } else { condition.accept( this ); } Expression truecase = p.getTrueCase(); if (truecase instanceof AssignmentExpression) { writeParenthesis( truecase ); } else { truecase.accept( this ); } Expression falsecase = p.getFalseCase(); if (falsecase instanceof AssignmentExpression) { writeParenthesis( falsecase ); } else { falsecase.accept( this ); } } public void visit( ConstructorInvocation p ) throws ParseTreeException { if (p.isSelfInvocation()) { } else { Expression enclosing = p.getEnclosing(); if (enclosing != null) { enclosing.accept( this ); } } ExpressionList exprs = p.getArguments(); writeArguments( exprs ); line_num++; } public void visit( ContinueStatement p ) throws ParseTreeException { line_num++; } public void visit( DoWhileStatement p ) throws ParseTreeException { StatementList stmts = p.getStatements(); if (stmts.isEmpty()) { } else { writeStatementsBlock( stmts ); } Expression expr = p.getExpression(); expr.accept( this ); line_num++; } public void visit( EmptyStatement p ) throws ParseTreeException { line_num++; } public void visit(EnumDeclaration p) throws ParseTreeException { // TODO Auto-generated method stub } public void visit(EnumConstant p) throws ParseTreeException { // TODO Auto-generated method stub } public void visit(EnumConstantList p) throws ParseTreeException { // TODO Auto-generated method stub } public void visit( ExpressionList p ) throws ParseTreeException { writeListWithDelimiter( p, ", " ); } public void visit( ExpressionStatement p ) throws ParseTreeException { Expression expr = p.getExpression(); expr.accept( this ); line_num++; } public void visit( FieldAccess p ) throws ParseTreeException { Expression expr = p.getReferenceExpr(); TypeName typename = p.getReferenceType(); if (expr != null) { if (expr instanceof Leaf || expr instanceof ArrayAccess || expr instanceof FieldAccess || expr instanceof MethodCall || expr instanceof Variable) { expr.accept( this ); } else { expr.accept( this ); } } else if (typename != null) { typename.accept( this ); } } public void visit( FieldDeclaration p ) throws ParseTreeException { printComment(p); /*ModifierList*/ ModifierList modifs = p.getModifiers(); if (modifs != null) { modifs.accept( this ); } /*TypeName*/ TypeName ts = p.getTypeSpecifier(); ts.accept(this); /*"=" VariableInitializer*/ VariableInitializer initializer = p.getInitializer(); if (initializer != null) { initializer.accept(this); } line_num++; } public void visit( ForStatement p ) throws ParseTreeException { ExpressionList init = p.getInit(); TypeName tspec = p.getInitDeclType(); VariableDeclarator[] vdecls = p.getInitDecls(); if (init != null && (! init.isEmpty() )) { init.get( 0 ).accept( this ); for (int i = 1; i < init.size(); ++i) { init.get( i ).accept( this ); } } else if (tspec != null && vdecls != null && vdecls.length != 0) { tspec.accept( this ); vdecls[0].accept( this ); for (int i = 1; i < vdecls.length; ++i) { vdecls[i].accept( this ); } } Expression expr = p.getCondition(); if (expr != null) { expr.accept( this ); } ExpressionList incr = p.getIncrement(); if (incr != null && (! incr.isEmpty())) { incr.get( 0 ).accept( this ); for (int i = 1; i < incr.size(); ++i) { incr.get( i ).accept( this ); } } StatementList stmts = p.getStatements(); if (stmts.isEmpty()) { } else { writeStatementsBlock( stmts ); } line_num++; } public void visit( IfStatement p ) throws ParseTreeException { Expression expr = p.getExpression(); expr.accept( this ); /* then part */ StatementList stmts = p.getStatements(); writeStatementsBlock( stmts ); /* else part */ StatementList elsestmts = p.getElseStatements(); if (! elsestmts.isEmpty()) { writeStatementsBlock( elsestmts ); } line_num++; } /* * Update: Aug 23, 2014 * Author: Lin Deng * Add support for AssertStatement */ public void visit(AssertStatement p) throws ParseTreeException { Expression expr = p.getExpression(); expr.accept(this); // if exists a : with second expression Expression expr2 = p.getExpression2(); if (expr2!=null) { expr2.accept(this); } line_num++; } public void visit( InstanceofExpression p ) throws ParseTreeException { /* this is too strict for + or - */ Expression lexpr = p.getExpression(); if (lexpr instanceof AssignmentExpression || lexpr instanceof ConditionalExpression || lexpr instanceof BinaryExpression) { writeParenthesis( lexpr ); } else { lexpr.accept( this ); } TypeName tspec = p.getTypeSpecifier(); tspec.accept( this ); } public void visit( LabeledStatement p ) throws ParseTreeException { line_num++; Statement statement = p.getStatement(); statement.accept( this ); } public void visit( Literal p ) throws ParseTreeException { } public void visit( MemberDeclarationList p ) throws ParseTreeException { writeListWithDelimiterNewline( p ); } public void visit( MemberInitializer p ) throws ParseTreeException { StatementList stmts = p.getBody(); writeStatementsBlock( stmts ); line_num++; } public void visit( MethodCall p ) throws ParseTreeException { Expression expr = p.getReferenceExpr(); TypeName reftype = p.getReferenceType(); if (expr != null) { if (expr instanceof Leaf || expr instanceof ArrayAccess || expr instanceof FieldAccess || expr instanceof MethodCall || expr instanceof Variable) { expr.accept( this ); } else { writeParenthesis( expr ); } } else if (reftype != null) { reftype.accept( this ); } ExpressionList args = p.getArguments(); writeArguments( args ); } public void visit( MethodDeclaration p ) throws ParseTreeException { printComment( p ); TypeName ts = p.getReturnType(); ts.accept( this ); ParameterList params = p.getParameters(); if (! params.isEmpty()) { params.accept( this ); } else { params.accept( this ); } TypeName[] tnl = p.getThrows(); if (tnl.length != 0) { line_num++; tnl[0].accept( this ); for (int i = 1; i < tnl.length; ++i) { tnl[i].accept( this ); } } StatementList bl = p.getBody(); if (bl == null) { } else { line_num++; line_num++; bl.accept( this ); } line_num++; } public void visit( ModifierList p ) throws ParseTreeException { } public void visit( Parameter p ) throws ParseTreeException { ModifierList modifs = p.getModifiers(); modifs.accept( this ); TypeName typespec = p.getTypeSpecifier(); typespec.accept( this ); } public void visit( ParameterList p ) throws ParseTreeException { writeListWithDelimiter( p, ", " ); } public void visit( ReturnStatement p ) throws ParseTreeException { Expression expr = p.getExpression(); if (expr != null) { expr.accept( this ); } line_num++; } public void visit( SelfAccess p ) throws ParseTreeException { } public void visit( StatementList p ) throws ParseTreeException { writeList( p ); } public void visit( SwitchStatement p ) throws ParseTreeException { Expression expr = p.getExpression(); expr.accept( this ); line_num++; CaseGroupList casegrouplist = p.getCaseGroupList(); casegrouplist.accept( this ); line_num++; } public void visit( SynchronizedStatement p ) throws ParseTreeException { Expression expr = p.getExpression(); expr.accept( this ); line_num++; StatementList stmts = p.getStatements(); writeStatementsBlock( stmts ); line_num++; } public void visit( ThrowStatement p ) throws ParseTreeException { Expression expr = p.getExpression(); expr.accept( this ); line_num++; } public void visit( TryStatement p ) throws ParseTreeException { StatementList stmts = p.getBody(); writeStatementsBlock( stmts ); CatchList catchlist = p.getCatchList(); if (! catchlist.isEmpty()) { catchlist.accept( this ); } StatementList finstmts = p.getFinallyBody(); if(! finstmts.isEmpty()){ line_num++; writeStatementsBlock( finstmts ); } line_num++; } /******rough around innerclass********/ public void visit( TypeName p ) throws ParseTreeException { } public void visit( UnaryExpression p ) throws ParseTreeException { Expression expr = p.getExpression(); if (expr instanceof AssignmentExpression || expr instanceof ConditionalExpression || expr instanceof BinaryExpression || expr instanceof InstanceofExpression || expr instanceof CastExpression || expr instanceof UnaryExpression){ writeParenthesis( expr ); } else { expr.accept( this ); } if (p.isPostfix()) { } } public void visit( Variable p ) throws ParseTreeException { } public void visit( VariableDeclaration p ) throws ParseTreeException { ModifierList modifs = p.getModifiers(); modifs.accept( this ); TypeName typespec = p.getTypeSpecifier(); typespec.accept( this ); VariableDeclarator vd = p.getVariableDeclarator(); vd.accept( this ); line_num++; } public void visit( VariableDeclarator p ) throws ParseTreeException { VariableInitializer varinit = p.getInitializer(); if (varinit != null) { varinit.accept( this ); } } public void visit( WhileStatement p ) throws ParseTreeException { Expression expr = p.getExpression(); expr.accept( this ); StatementList stmts = p.getStatements(); if (stmts.isEmpty()) { } else { writeStatementsBlock( stmts ); } line_num++; } protected void printComment( NonLeaf p ) { } protected final void writeListWithDelimiterNewline( List list ) throws ParseTreeException { Enumeration it = list.elements(); if (! it.hasMoreElements()) return; writeAnonymous( it.nextElement() ); while (it.hasMoreElements()) { line_num++; writeAnonymous( it.nextElement() ); } } protected final void writeListWithSuffixNewline( List list ) throws ParseTreeException { Enumeration it = list.elements(); while (it.hasMoreElements()) { writeAnonymous( it.nextElement() ); line_num++; } } protected String removeNewline(String str){ int index; while((index = str.indexOf("\n"))>=0){ if(index>0 && index<str.length()){ str = str.substring(0,index-1)+str.substring(index+1,str.length()); }else if(index==0){ str = str.substring(1,str.length()); }else if(index==str.length()){ str = str.substring(0,index-1); } } return str; } protected final void writeArguments( ExpressionList args ) throws ParseTreeException { } protected final void writeAnonymous( Object obj ) throws ParseTreeException { if (obj == null) { } else if (obj instanceof ParseTree) { ((ParseTree) obj).accept( this ); } else { } } protected final void writeList( List list ) throws ParseTreeException { Enumeration it = list.elements(); while (it.hasMoreElements()) { Object elem = it.nextElement(); writeAnonymous( elem ); } } protected final void writeListWithDelimiter( List list, String delimiter ) throws ParseTreeException { Enumeration it = list.elements(); if (! it.hasMoreElements()) return; writeAnonymous( it.nextElement() ); while (it.hasMoreElements()) { writeAnonymous( it.nextElement() ); } } protected final void writeListWithSuffix( List list, String suffix ) throws ParseTreeException { Enumeration it = list.elements(); while (it.hasMoreElements()) { writeAnonymous( it.nextElement() ); } } protected final void writeParenthesis( Expression expr ) throws ParseTreeException { expr.accept( this ); } protected final void writeStatementsBlock( StatementList stmts ) throws ParseTreeException { line_num++; } protected static final boolean isOperatorNeededLeftPar( int operator, Expression leftexpr ) { if (leftexpr instanceof AssignmentExpression || leftexpr instanceof ConditionalExpression) { return true; } int op = operatorStrength( operator ); if (leftexpr instanceof InstanceofExpression) { return (op > operatorStrength( BinaryExpression.INSTANCEOF )); } if(! (leftexpr instanceof BinaryExpression)) return false; BinaryExpression lbexpr = (BinaryExpression) leftexpr; return (op > operatorStrength( lbexpr.getOperator() )); } protected static final boolean isOperatorNeededRightPar( int operator, Expression rightexpr ) { if (rightexpr instanceof AssignmentExpression || rightexpr instanceof ConditionalExpression) { return true; } int op = operatorStrength( operator ); if (rightexpr instanceof InstanceofExpression) { return (op >= operatorStrength( BinaryExpression.INSTANCEOF )); } if (! (rightexpr instanceof BinaryExpression)) return false; BinaryExpression lbexpr = (BinaryExpression) rightexpr; return (op >= operatorStrength( lbexpr.getOperator() )); } /** * Returns the strength of the union of the operator. * * @param op the id number of operator. * @return the strength of the union. */ protected static final int operatorStrength( int op ) { switch (op) { case BinaryExpression.TIMES : case BinaryExpression.DIVIDE : case BinaryExpression.MOD : return 40; case BinaryExpression.PLUS : case BinaryExpression.MINUS : return 35; case BinaryExpression.SHIFT_L : case BinaryExpression.SHIFT_R : case BinaryExpression.SHIFT_RR : return 30; case BinaryExpression.LESS : case BinaryExpression.GREATER : case BinaryExpression.LESSEQUAL : case BinaryExpression.GREATEREQUAL : case BinaryExpression.INSTANCEOF : return 25; case BinaryExpression.EQUAL : case BinaryExpression.NOTEQUAL : return 20; case BinaryExpression.BITAND : return 16; case BinaryExpression.XOR : return 14; case BinaryExpression.BITOR : return 12; case BinaryExpression.LOGICAL_AND : return 10; case BinaryExpression.LOGICAL_OR : return 8; } return 100; } public String remove(String str,String target) { int index = str.indexOf(target); int length = str.length(); int offset = target.length(); String result = str.substring(0,index); String last = str.substring(index+offset,length); result = result.concat(last); return result; } public String remove(String str,String target,int start_index) { int index = start_index; int length = str.length(); int offset = target.length(); String result = str.substring(0,index); String last = str.substring(index+offset,length); result = result.concat(last); return result; } @Override public void visit(TypeParameter arg0) throws ParseTreeException { // TODO Auto-generated method stub } @Override public void visit(TypeParameterList arg0) throws ParseTreeException { // TODO Auto-generated method stub } }