Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
  /*
   * fb-contrib - Auxiliary detectors for Java programs
   * Copyright (C) 2005-2013 Dave Brosius
   *
   * This library is free software; you can redistribute it and/or
   * modify it under the terms of the GNU Lesser General Public
   * License as published by the Free Software Foundation; either
   * version 2.1 of the License, or (at your option) any later version.
   *
  * This library is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
  * License along with this library; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 package com.mebigfatguy.fbcontrib.detect;
 
 import java.util.List;
 
 import  org.apache.bcel.Constants;
 import  org.apache.bcel.Repository;
 import  org.apache.bcel.classfile.Code;
 import  org.apache.bcel.classfile.JavaClass;
 import  org.apache.bcel.classfile.LineNumberTable;
 import  org.apache.bcel.classfile.Method;
 import  org.apache.bcel.generic.Type;
 
 import  edu.umd.cs.findbugs.BugInstance;
 import  edu.umd.cs.findbugs.BugReporter;
 import  edu.umd.cs.findbugs.BytecodeScanningDetector;
 import  edu.umd.cs.findbugs.OpcodeStack;
 import  edu.umd.cs.findbugs.ba.ClassContext;

looks for methods that make static method calls using an instance reference. For documentation purposes, it is better to call the method using the class name. This may represent a change in definition that should be noticed.
 
 public class StaticMethodInstanceInvocation extends BytecodeScanningDetector {
 	private final BugReporter bugReporter;
 	private OpcodeStack stack;
 	private List<PopInfopopStack;
 	private LineNumberTable lineNumberTable;

constructs a SMII detector given the reporter to report bugs on

Parameters:
bugReporter the sync of bug reports
 
 	public StaticMethodInstanceInvocation(BugReporter bugReporter) {
 		this. = bugReporter;
 	}
 
 	public void visitClassContext(ClassContext classContext) {
 		try {
 			 = new OpcodeStack();
 			 = new ArrayList<PopInfo>();
 			super.visitClassContext(classContext);
 		} finally {
 			 = null;
 			 = null;
 			 = null;
 		}
 	}
looks for methods that contain a INVOKESTATIC opcodes

Parameters:
method the context object of the current method
Returns:
if the class uses synchronization
 
 	public boolean prescreen(Method method) {
 		BitSet bytecodeSet = getClassContext().getBytecodeSet(method);
 		return (bytecodeSet != null) && (bytecodeSet.get(Constants.INVOKESTATIC));
 	}

implement the visitor to reset the stack

Parameters:
obj the context object of the currently parsed method
 
 	public void visitCode(Code obj) {
 		Method m = getMethod();
 		if (prescreen(m)) {
 			.resetForMethodEntry(this);
 			 = obj.getLineNumberTable();
 			super.visitCode(obj);
 		}
 	}

implements the visitor to look for static method calls from instance variables

Parameters:
seen the opcode of the currently visited instruction
	public void sawOpcode(int seen) {
		try {
			.mergeJumps(this);
			int sDepth = .getStackDepth();
			while (it.hasNext()) {
				if (sDepth < it.next().)
                {
                    it.remove();
                }
			}
			if ((seen == INVOKESTATIC) && (.size() > 0)) {
                String method = getNameConstantOperand();
                if (method.indexOf('$') < 0) {
    				PopInfo pInfo = .get(0);
    				Type[] args = Type.getArgumentTypes(getSigConstantOperand());
    				if ((args.length > 0) || (pInfo.popPC == (getPC() - 1))) {
    					if (args.length == (.getStackDepth() - pInfo.popDepth)) {
    						if (classDefinesStaticMethod(pInfo.popSignature.substring(1, pInfo.popSignature.length() - 1))) {
    						    int lineNumber = -1;
    						    if ( != null) {
    						        lineNumber = .getSourceLine(getPC());
    						    }
    						    if (pInfo.popLineNum == lineNumber) {
        							.reportBug(new BugInstance(this"SMII_STATIC_METHOD_INSTANCE_INVOCATION", NORMAL_PRIORITY)
        								.addClass(this)
        								.addMethod(this)
        								.addSourceLine(this));
    						    }
    							.clear();
    						}
    					}
    				}
                }
			}
			if ((seen == ASTORE)
			||  ((seen >= ASTORE_0) && (seen <= ASTORE_3))
			||  (seen == PUTFIELD)
			||  (seen == ATHROW)
			||  (seen == GOTO)
			||  (seen == GOTO_W)
			||  (seen >= IFEQ) && (seen <= IF_ACMPNE)) {
else if ((seen == INVOKESPECIAL)
		      ||       (seen == INVOKEINTERFACE)
			  ||       (seen == INVOKEVIRTUAL)
			  ||       (seen == INVOKESTATIC)) {
				Type result = Type.getReturnType(getSigConstantOperand());
				if ("V".equals(result.getSignature()))
                {
                    .clear();
                }
			}
			if (seen == POP) {
				if (.getStackDepth() > 0) {
					OpcodeStack.Item itm = .getStackItem(0);
					String popSig = itm.getSignature();
					if (popSig.charAt(0) == 'L')
                    {
					    int lineNumber = -1;
					    if ( != null) {
					        lineNumber = .getSourceLine(getPC());
					    }
                        .add(new PopInfo(getPC(), lineNumberpopSigsDepth - 1));
                    }
				}
			}
catch (ClassNotFoundException cnfe) {
			.reportMissingClass(cnfe);
finally {
			.sawOpcode(thisseen);
		}
	}
	boolean classDefinesStaticMethod(String popSignaturethrows ClassNotFoundException {
		popSignature = popSignature.replace('/''.');
		if ("java.lang.Object".equals(popSignature) || "java.lang.Class".equals(popSignature))
        {
            return false;
        }
		JavaClass cls = Repository.lookupClass(popSignature);
		Method[] methods = cls.getMethods();
		for (Method m : methods) {
			if (m.isStatic()) {
				if (m.getName().equals(getNameConstantOperand())
				&&  m.getSignature().equals(getSigConstantOperand()))
                {
                    return true;
                }
			}
		}
		return classDefinesStaticMethod(cls.getSuperclassName());
	}
	static class PopInfo {
		int popPC;
		public PopInfo(int pcint lineNumString signatureint depth) {
			 = pc;
			 = lineNum;
			 = signature;
			 = depth;
		}
	}
New to GrepCode? Check out our FAQ X