Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
  /*
   * fb-contrib - Auxiliary detectors for Java programs
   * Copyright (C) 2005-2014 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.collect;
 
 import java.util.Set;
 
 import  org.apache.bcel.classfile.Code;
 import  org.apache.bcel.classfile.Method;
 import  org.apache.bcel.generic.Type;
 
 
collects methods that return a collection that could be created thru an immutable method such as Arrays.aslist, etc.
 
 public class CollectMethodsReturningImmutableCollections extends BytecodeScanningDetector implements NonReportingDetector {
 
     private static Set<StringIMMUTABLE_PRODUCING_METHODS = new HashSet<String>();
     static {
         .add("com/google/common/Collect/Maps.immutableEnumMap");
         .add("com/google/common/Collect/Maps.unmodifiableMap");
         .add("com/google/common/Collect/Sets.immutableEnumSet");
         .add("com/google/common/Collect/Sets.immutableCopy");
         .add("java/util/Arrays.asList");
         .add("java/util/Collections.unmodifiableCollection");
         .add("java/util/Collections.unmodifiableSet");
         .add("java/util/Collections.unmodifiableSortedSet");
         .add("java/util/Collections.unmodifiableMap");
         .add("java/util/Collections.unmodifiableList");        
         .add("edu/emory/mathcs/backport/java/util/Arrays.asList");
         .add("edu/emory/mathcs/backport/java/util/Collections.unmodifiableCollection");
         .add("edu/emory/mathcs/backport/java/util/Collections.unmodifiableSet");
         .add("edu/emory/mathcs/backport/java/util/Collections.unmodifiableSortedSet");
         .add("edu/emory/mathcs/backport/java/util/Collections.unmodifiableMap");
         .add("edu/emory/mathcs/backport/java/util/Collections.unmodifiableList");
     }
     
     private BugReporter bugReporter;
     private OpcodeStack stack;
     private String clsName;
     private ImmutabilityType imType;
    
    
constructs a CMRIC detector given the reporter to report bugs on

Parameters:
bugReporter the sync of bug reports
 
          = reporter;
     }
     
     public void visitClassContext(ClassContext context) {
         try {
              = new OpcodeStack();
              = context.getJavaClass().getClassName();
             super.visitClassContext(context);
         } finally {
              = null;
         }
     }
    
    
overrides the visitor to reset the stack for the new method, then checks if the immutability field is set to immutable and if so reports it

Parameters:
obj the context object of the currently parsed method
 
     public void visitCode(Code obj) {
         try {
             String signature = Type.getReturnType(getMethod().getSignature()).getSignature();
             if (signature.startsWith("L") && CollectionUtils.isListSetMap(signature.substring(1, signature.length() - 1))) {
                 .resetForMethodEntry(this);
                 = .;
                super.visitCode(obj);
                
                if (( == .) || ( == .)) {
                    Method m = getMethod();
                    Statistics.getStatistics().addImmutabilityStatus(m.getName(), m.getSignature(), );
                }
            }
        } catch (ClassNotFoundException cnfe) {
            .reportMissingClass(cnfe);
        }
    }
    
    
overrides the visitor to look for calls to static methods that are known to return immutable collections It records those variabls, and documents if what the method returns is one of those objects.
    public void sawOpcode(int seen) {
        ImmutabilityType seenImmutable = null;
        try {
            .precomputation(this);
            
            switch (seen) {
                case INVOKESTATIC: {
                    String className = getClassConstantOperand();
                    String methodName = getNameConstantOperand();
                    
                    if (.contains(className + '.' + methodName)) {
                        seenImmutable = .;
                        break;
                    }
                }
                //$FALL-THROUGH$   
                case INVOKEINTERFACE:
                case INVOKESPECIAL:
                case INVOKEVIRTUAL: {
                    String className = getClassConstantOperand();
                    String methodName = getNameConstantOperand();
                    String signature = getSigConstantOperand();
                    
                    MethodInfo mi = Statistics.getStatistics().getMethodStatistics(classNamemethodNamesignature);
                    seenImmutable = mi.getImmutabilityType();
                    if (seenImmutable == .)
                        seenImmutable = null;
                }
                break;
                    
                case ARETURN: {
                    if (.getStackDepth() > 0) {
                        OpcodeStack.Item item = .getStackItem(0);
                        ImmutabilityType type = (ImmutabilityTypeitem.getUserValue();
                        if (type == null)
                            type = .;
                        
                        switch () {
                            case :
                                switch (type) {
                                    case :
                                         = .;
                                    break;
                                    case :
                                         = .;
                                    break;
                                    default:
                                         = .;
                                    break;
                                }
                                break;
                                
                            case :
                                if (type != .) {
                                     = .;
                                }
                                break;
                                
                            case :
                                break;
                                
                            case :
                                if (type == .) {
                                     = .;
                                }
                                break;
                        }
                    }
                    break;
                }
            }
            
        } finally {
            .sawOpcode(this,  seen);
            if (seenImmutable != null) {
                if (.getStackDepth() > 0) {
                    OpcodeStack.Item item = .getStackItem(0);
                    item.setUserValue(seenImmutable);
                }
            }
        }
    }
New to GrepCode? Check out our FAQ X