Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
  /*
   * fb-contrib - Auxiliary detectors for Java programs
   * Copyright (C) 2005-2015 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.Map;
 
 
 
looks for methods that are declared more permissively than the code is using. For instance, declaring a method public, when it could just be declared private.
 
 
 	private static Map<IntegerStringDECLARED_ACCESS = new HashMap<IntegerString>();
 	static {
 		.put(Integer.valueOf(0), "package private");
 	}
 	
 	private OpcodeStack stack;
 	private String callingPackage;
 	private String callingClass;

constructs a OPM detector given the reporter to report bugs on

Parameters:
bugReporter the sync of bug reports
 
 	public OverlyPermissiveMethod(BugReporter bugReporter) {
 		this. = bugReporter;
 	}
 
 	public void visitClassContext(ClassContext classContext) {
 		try {
 			ClassDescriptor cd = classContext.getClassDescriptor();
 			 = new OpcodeStack();
 			super.visitClassContext(classContext);
 		} finally {
 			 = null;
 			 = null;
 		}
 	}
 
 	public void visitCode(Code obj) {
 			super.visitCode(obj);
 		}
 	}
 
 	public void sawOpcode(int seen) {
 		try {
 
 			switch (seen) {
					String calledClass = getClassConstantOperand();
					MethodInfo mi = Statistics.getStatistics().getMethodStatistics(calledClassgetNameConstantOperand(), sig);
					if (mi != null) {
						if (seen == ) {
else {
							String calledPackage;
							int slashPos = calledClass.lastIndexOf('/');
							if (slashPos >= 0) {
								calledPackage = calledClass.substring(0, slashPos);
else {
								calledPackage = "";
							}
							boolean sameClass = calledClass.equals();
							boolean samePackage = calledPackage.equals();
							if (sameClass) {
else if (samePackage) {
else {
								if (seen == ) {
else if (isCallingOnThis(sig)) {
else {
								}
							}
						}
					}
					break;
				default:
					break;
			}
finally {
			.sawOpcode(thisseen);
		}
	}
	private boolean hasRuntimeAnnotations(Method obj) {
		AnnotationEntry[] annotations = obj.getAnnotationEntries();
		if (annotations != null) {
			for (AnnotationEntry entry : annotations) {
				if (entry.isRuntimeVisible()) {
					return true;
				}
			}
		}
		return false;
	}

checks to see if an instance method is called on the 'this' object

Parameters:
sig the signature of the method called to find the called-on object
Returns:
when it is called on this or not
	private boolean isCallingOnThis(String sig) {
		Type[] argTypes = Type.getArgumentTypes(sig);
		if (.getStackDepth() < argTypes.length) {
			return false;
		}
		OpcodeStack.Item item = .getStackItem(argTypes.length);
		return item.getRegisterNumber() == 0;
	}

after collecting all method calls, build a report of all methods that have been called, but in a way that is less permissive then is defined.
	public void report() {
		for (Map.Entry<StatisticsKeyMethodInfoentry : Statistics.getStatistics()) {
			MethodInfo mi = entry.getValue();
			int declaredAccess = mi.getDeclaredAccess();
			if ((declaredAccess & .) != 0) {
				continue;
			}
			if (mi.wasCalledPublicly() || !mi.wasCalled()) {
				continue;
			}
			StatisticsKey key = entry.getKey();
			if (isOverlyPermissive(declaredAccess)) {
				try {
					if (!isDerived(Repository.lookupClass(key.getClassName()), key)) {
										.addMethod(key.getClassName(), key.getMethodName(), key.getSignature(), (declaredAccess & .) != 0);
						String descr = String.format("- Method declared %s but could be declared %s"getDeclaredAccessValue(declaredAccess), getRequiredAccessValue(mi));
						bi.addString(descr);
					}
catch (ClassNotFoundException cnfe) {
				}
			}
		}
	}
	private static boolean isOverlyPermissive(int declaredAccess) {
		if ((declaredAccess & .) != 0) {
			return true;
		}
		return false;
	}

looks to see if this method described by key is derived from a superclass or interface

Parameters:
cls the class that the method is defined in
key the information about the method
Returns:
whether this method derives from something or not
	private boolean isDerived(JavaClass clsStatisticsKey key) {
		try {
			for (JavaClass infCls : cls.getInterfaces()) {
				for (Method infMethod : infCls.getMethods()) {
					if (key.getMethodName().equals(infMethod.getName())) {
						if (infMethod.getGenericSignature() != null) { 
							if (SignatureUtils.compareGenericSignature(infMethod.getGenericSignature(), key.getSignature())) {
								return true;
							}
						}
						else if (infMethod.getSignature().equals(key.getSignature())) {
							return true;
						}
					}
				}
			}
			JavaClass superClass = cls.getSuperClass();
			if ((superClass == null) || "java.lang.Object".equals(superClass.getClassName())) {
				return false;
			}
			for (Method superMethod : superClass.getMethods()) {
				if (key.getMethodName().equals(superMethod.getName())) {
					if (superMethod.getGenericSignature() != null) { 
						if (SignatureUtils.compareGenericSignature(superMethod.getGenericSignature(), key.getSignature())) {
							return true;
						}
					}
					else if (superMethod.getSignature().equals(key.getSignature())) {
						return true;
					}
				}
			}
			return isDerived(superClasskey);
catch (ClassNotFoundException cnfe) {
			return true;
		}
	}
	private static String getDeclaredAccessValue(int declaredAccess) {
	}
	private static Object getRequiredAccessValue(MethodInfo mi) {
			return "protected";
			return "package private";
		return "private";
	}
New to GrepCode? Check out our FAQ X