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;
 import java.util.Set;
 
 
 
looks for private collection members, either static or instance, that are only initialized in the clinit or init, but are synchronized. This is not necessary as the constructor or static initializer are guaranteed to be thread safe.
 
 	private static JavaClass collectionClass;
 	static {
 		try {
 			 = Repository.lookupClass("java/util/Collection");
 		} catch (ClassNotFoundException cnfe) {
 			 = null;
 		}
 	}
 	private static JavaClass mapClass;
 	static {
 		try {
 			 = Repository.lookupClass("java/util/Map");
 		} catch (ClassNotFoundException cnfe) {
 			 = null;
 		}
 	}
 	private static Set<StringsyncCollections = new HashSet<String>();
 	static {
 		.add("java/util/Vector");
 		.add("java/util/Hashtable");
 	}
 	private static Set<StringmodifyingMethods = new HashSet<String>();
 	static {
 		.add("addAll");
 		.add("addFirst");
 		.add("addElement");
 		.add("addLast");
 		.add("clear");
 		.add("insertElementAt");
 		.add("remove");
 		.add("removeAll");
 		.add("removeAllElements");
 		.add("removeElement");
 		.add("removeElementAt");
 		.add("removeFirst");
 		.add("removeLast");
 		.add("removeRange");
 		.add("retainAll");
 		.add("setElementAt");
 		.add("setSize");
 	}
 	
 	private enum State {IN_METHOD, IN_CLINIT, IN_INIT};
 	
	private Map<IntegerStringaliases;
	private OpcodeStack stack;
	private State state;
	private String className;

constructs a NMCS detector given the reporter to report bugs on

Parameters:
bugReporter the sync of bug reports
		this. = bugReporter;
	}

implements the visitor to clear the collectionFields and stack and to report collections that remain unmodified out of clinit or init

Parameters:
classContext the context object of the currently parsed class
	public void visitClassContext(ClassContext classContext) {
		try {
			if (( != null) && ( != null)) {
				 = new OpcodeStack();
				JavaClass cls = classContext.getJavaClass();
				super.visitClassContext(classContext);
				for (FieldInfo fi : .values()) {
					if (fi.isSynchronized()) {
									.addClass(this)
					}
				}
			}
finally {
			 = null;
			 = null;
		}
	}

implements the visitor to find collection fields

Parameters:
obj the context object of the currently parse field
	public void visitField(Field obj) {
		if (obj.isPrivate()) {
			String signature = obj.getSignature();
			if (signature.charAt(0) == 'L') {
				try {
					JavaClass cls = Repository.lookupClass(signature.substring(1, signature.length() - 1));
						FieldAnnotation fa = FieldAnnotation.fromVisitedField(this);
					}
catch (ClassNotFoundException cnfe) {
				}
			}
		}
	}

implements the visitor to set the state based on the type of method being parsed

Parameters:
obj the context object of the currently parsed code block
	public void visitCode(Code obj) {
		if (.size() > 0) {
			String methodName = getMethodName();
			else if (..equals(methodName))
			else
			super.visitCode(obj);
		}
	}

implements the visitor to call the approriate visitor based on state

Parameters:
seen the opcode of the currently parsed instruction
	public void sawOpcode(int seen) {
		switch () {
			case :
			break;
			case :
			break;
			case :
			break;
		}
	}

handle <clinit> blocks by looking for putstatic calls referencing synchronized collections

Parameters:
seen the opcode of the currently parsed instruction
	private void sawCLInitOpcode(int seen) {
		boolean isSyncCollection = false;
		try {
	        .precomputation(this);
	        
			isSyncCollection = isSyncCollectionCreation(seen);
			if (seen == )
finally {
			.sawOpcode(thisseen);
			if (isSyncCollection) {
				if (.getStackDepth() > 0) {
				}
			}
		}
	}

handle <init> blocks by looking for putfield calls referencing synchronized collections

Parameters:
seen the opcode of the currently parsed instruction
	private void sawInitOpcode(int seen) {
		boolean isSyncCollection = false;
		try {
			isSyncCollection = isSyncCollectionCreation(seen);
			if (seen == )
finally {
			.sawOpcode(thisseen);
			if (isSyncCollection) {
				if (.getStackDepth() > 0) {
				}
			}
		}
	}

handles regular methods by looking for methods on collections that are modifying and removes those collections from the ones under review

Parameters:
seen the opcode of the currently parsed instruction
	private void sawMethodOpcode(int seen) {
		boolean isSyncCollection = false;
		try {
			isSyncCollection = isSyncCollectionCreation(seen);
			switch (seen) {
					String methodName = getNameConstantOperand();
					if (.contains(methodName)) {
						String signature = getSigConstantOperand();
						int parmCount = Type.getArgumentTypes(signature).length;
						if (.getStackDepth() > parmCount) {
							OpcodeStack.Item item = .getStackItem(parmCount);
							XField field = item.getXField();
							if (field != null) {
else {
								int reg = item.getRegisterNumber();
								if (reg >= 0) {
									Integer register = Integer.valueOf(reg);
									String fName = .get(register);
									if (fName != null) {
										.remove(register);
									}
								}
							}
						}
					}
                    removeCollectionParameters();
				break;
                
                case :
                    removeCollectionParameters();
                break;
				case :
					if (.getStackDepth() > 0) {
						XField field = item.getXField();
						if (field != null) {
						}
					}
				break;
				case :
				case :
				break;
				case :
				case :
					if (.getStackDepth() > 0) {
						XField field = item.getXField();
						if (field != null) {
						}
					}
				break;
				default:
					break;
			}
finally {
			TernaryPatcher.pre(seen);
			.sawOpcode(thisseen);
			TernaryPatcher.post(seen);
			if (isSyncCollection) {
				if (.getStackDepth() > 0) {
				}
			}
		}
	}

returns whether this instruction is creating a synchronized collection

Parameters:
seen the opcode of the currently parsed instruction
Returns:
whether a synchronized collection has just been created
	private boolean isSyncCollectionCreation(int seen) {
		if (seen == ) {
			}
else if (seen == ) {
			if ("java/util/Collections".equals(getClassConstantOperand())) {
				String methodName = getNameConstantOperand();
				return ("synchronizedMap".equals(methodName) || "synchronizedSet".equals(methodName));
			}
		}
		return false;
	}

sets the source line annotation of a store to a collection if that collection is synchronized.
	private void processCollectionStore() {
		if (fieldClassName.equals()) {
			if (.getStackDepth() > 0) {
				if (item.getUserValue() != null) {
					if (fieldName != null) {
						FieldInfo fi = .get(fieldName);
						if (fi != null) {
						}
					}
				}
			}
		}
	}
    
    
removes collection fields that are passed to other methods as arguments
    private void removeCollectionParameters() {
        int parmCount = Type.getArgumentTypes(getSigConstantOperand()).length;
        if (.getStackDepth() >= parmCount) {
            for (int i = 0; i < parmCounti++) {
                OpcodeStack.Item item = .getStackItem(i);
                XField field = item.getXField();
                if (field != null) {
                    .remove(field.getName());
                }
            }
        }
    }

holds information about a field, namely the annotation and whether the collection is synchronized.
	static class FieldInfo {
		private boolean isSynchronized;
		public FieldInfo(FieldAnnotation fa) {
			 = false;
		}
		public void setSynchronized() {
		}
		}
		public boolean isSynchronized() {
		}
	}
New to GrepCode? Check out our FAQ X