Exemplo n.º 1
0
  private boolean isInDistanceInternal(
      int distance, NetworkNode from, NetworkNode to, TwoNetworkNodes cachePairKey) {
    if (from.equals(to)) return true;

    if (distance == 0) return false;

    if (SimpleNetwork.areNodesConnecting(from, to)) return true;

    // Breadth-first search of the network
    Set<NetworkNode> visitedNodes = Sets.newHashSet();
    visitedNodes.add(from);

    Set<NetworkNode> networkingNodesToTest = Sets.newHashSet();
    listConnectedNotVisitedNetworkingNodes(visitedNodes, from, networkingNodesToTest);
    int distanceSearched = 1;
    while (distanceSearched < distance) {
      distanceSearched++;

      for (NetworkNode nodeToTest : networkingNodesToTest) {
        if (SimpleNetwork.areNodesConnecting(nodeToTest, to)) {
          distanceCache.put(cachePairKey, distanceSearched);
          return true;
        }
        visitedNodes.add(nodeToTest);
      }

      Set<NetworkNode> nextNetworkingNodesToTest = Sets.newHashSet();
      for (NetworkNode nodeToTest : networkingNodesToTest)
        listConnectedNotVisitedNetworkingNodes(visitedNodes, nodeToTest, nextNetworkingNodesToTest);

      networkingNodesToTest = nextNetworkingNodesToTest;
    }

    return false;
  }
Exemplo n.º 2
0
 /**
  * get types annotated with a given annotation, both classes and annotations, including annotation
  * member values matching
  *
  * <p>{@link Inherited} is honored according to given honorInherited
  *
  * <p>depends on TypeAnnotationsScanner configured
  */
 public Set<Class<?>> getTypesAnnotatedWith(final Annotation annotation, boolean honorInherited) {
   Iterable<String> annotated =
       store.get(index(TypeAnnotationsScanner.class), annotation.annotationType().getName());
   Iterable<Class<?>> filter = filter(forNames(annotated, loaders()), withAnnotation(annotation));
   Iterable<String> classes =
       getAllAnnotated(
           names(filter),
           annotation.annotationType().isAnnotationPresent(Inherited.class),
           honorInherited);
   return Sets.newHashSet(
       concat(filter, forNames(filter(classes, not(in(Sets.newHashSet(annotated)))), loaders())));
 }
 public static TileEntity getTileEntity(IBlockAccess blockaccess, int x, int y, int z) {
   HashSet<ChunkCoordinates> visited = Sets.newHashSet();
   Block block = blockaccess.getBlock(x, y, z);
   while (block != NailedBlocks.portalController) {
     if (isValidLinkPortalBlock(block) == 0) {
       return null;
     }
     ChunkCoordinates pos = new ChunkCoordinates(x, y, z);
     if (!visited.add(pos)) {
       return null;
     }
     int meta = blockaccess.getBlockMetadata(x, y, z);
     if (meta == 0) {
       return null;
     }
     if (meta == 1) {
       y--;
     } else if (meta == 2) {
       y++;
     } else if (meta == 3) {
       z--;
     } else if (meta == 4) {
       z++;
     } else if (meta == 5) {
       x--;
     } else if (meta == 6) {
       x++;
     } else {
       return null;
     }
     block = blockaccess.getBlock(x, y, z);
   }
   return blockaccess.getTileEntity(x, y, z);
 }
Exemplo n.º 4
0
 @NonNull
 public IAndroidTarget[] getMissingTargets() {
   synchronized (mLocalPackages) {
     if (mCachedMissingTargets == null) {
       Map<MissingTarget, MissingTarget> result = Maps.newHashMap();
       Set<ISystemImage> seen = Sets.newHashSet();
       for (IAndroidTarget target : getTargets()) {
         Collections.addAll(seen, target.getSystemImages());
       }
       for (LocalPkgInfo local : getPkgsInfos(PkgType.PKG_ADDON_SYS_IMAGE)) {
         LocalAddonSysImgPkgInfo info = (LocalAddonSysImgPkgInfo) local;
         ISystemImage image = info.getSystemImage();
         if (!seen.contains(image)) {
           addOrphanedSystemImage(image, info.getDesc(), result);
         }
       }
       for (LocalPkgInfo local : getPkgsInfos(PkgType.PKG_SYS_IMAGE)) {
         LocalSysImgPkgInfo info = (LocalSysImgPkgInfo) local;
         ISystemImage image = info.getSystemImage();
         if (!seen.contains(image)) {
           addOrphanedSystemImage(image, info.getDesc(), result);
         }
       }
       mCachedMissingTargets = result.keySet();
     }
     return mCachedMissingTargets.toArray(new IAndroidTarget[mCachedMissingTargets.size()]);
   }
 }
Exemplo n.º 5
0
  /**
   * Assigns sequential identifiers to the provided <code>clusters</code> (and their sub-clusters).
   * If a cluster already has an identifier, the identifier will not be changed.
   *
   * @param clusters Clusters to assign identifiers to.
   * @throws IllegalArgumentException if the provided clusters contain non-unique identifiers
   */
  public static void assignClusterIds(Collection<Cluster> clusters) {
    final ArrayList<Cluster> flattened = Lists.newArrayListWithExpectedSize(clusters.size());

    flatten(flattened, clusters);

    synchronized (clusters) {
      final HashSet<Integer> ids = Sets.newHashSet();

      // First, find the start value for the id and check uniqueness of the ids
      // already provided.
      int maxId = Integer.MIN_VALUE;
      for (final Cluster cluster : flattened) {
        if (cluster.id != null) {
          if (!ids.add(cluster.id)) {
            throw new IllegalArgumentException("Non-unique cluster id found: " + cluster.id);
          }
          maxId = Math.max(maxId, cluster.id);
        }
      }

      // We'd rather start with 0
      maxId = Math.max(maxId, -1);

      // Assign missing ids
      for (final Cluster c : flattened) {
        if (c.id == null) {
          c.id = ++maxId;
        }
      }
    }
  }
Exemplo n.º 6
0
 // Loop through all changed classes, adding their parents (and their
 // parents)
 // to another set of changed classes
 public Set<JavaClass> findChangedParents(Set<JavaClass> classes) {
   Set<JavaClass> changedParents = Sets.newHashSet(classes);
   for (JavaClass jclass : classes) {
     findParents(jclass, changedParents);
   }
   return changedParents;
 }
Exemplo n.º 7
0
 /**
  * get all fields annotated with a given annotation
  *
  * <p>depends on FieldAnnotationsScanner configured
  */
 public Set<Field> getFieldsAnnotatedWith(final Class<? extends Annotation> annotation) {
   final Set<Field> result = Sets.newHashSet();
   for (String annotated : store.get(index(FieldAnnotationsScanner.class), annotation.getName())) {
     result.add(getFieldFromString(annotated, loaders()));
   }
   return result;
 }
Exemplo n.º 8
0
 /**
  * get types annotated with a given annotation, both classes and annotations
  *
  * <p>{@link Inherited} is honored according to given honorInherited.
  *
  * <p>when honoring @Inherited, meta-annotation should only effect annotated super classes and
  * it's sub types
  *
  * <p>when not honoring @Inherited, meta annotation effects all subtypes, including annotations
  * interfaces and classes
  *
  * <p><i>Note that this (@Inherited) meta-annotation type has no effect if the annotated type is
  * used for anything other then a class. Also, this meta-annotation causes annotations to be
  * inherited only from superclasses; annotations on implemented interfaces have no effect.</i>
  *
  * <p>depends on TypeAnnotationsScanner and SubTypesScanner configured
  */
 public Set<Class<?>> getTypesAnnotatedWith(
     final Class<? extends Annotation> annotation, boolean honorInherited) {
   Iterable<String> annotated =
       store.get(index(TypeAnnotationsScanner.class), annotation.getName());
   Iterable<String> classes =
       getAllAnnotated(annotated, annotation.isAnnotationPresent(Inherited.class), honorInherited);
   return Sets.newHashSet(concat(forNames(annotated, loaders()), forNames(classes, loaders())));
 }
Exemplo n.º 9
0
 /**
  * get all types scanned. this is effectively similar to getting all subtypes of Object.
  *
  * <p>depends on SubTypesScanner configured with {@code SubTypesScanner(false)}, otherwise {@code
  * ReflectionsException} is thrown
  *
  * <p><i>note using this might be a bad practice. it is better to get types matching some
  * criteria, such as {@link #getSubTypesOf(Class)} or {@link #getTypesAnnotatedWith(Class)}</i>
  *
  * @return Set of String, and not of Class, in order to avoid definition of all types in PermGen
  */
 public Set<String> getAllTypes() {
   Set<String> allTypes =
       Sets.newHashSet(store.getAll(index(SubTypesScanner.class), Object.class.getName()));
   if (allTypes.isEmpty()) {
     throw new ReflectionsException(
         "Couldn't find subtypes of Object. "
             + "Make sure SubTypesScanner initialized to include Object class - new SubTypesScanner(false)");
   }
   return allTypes;
 }
 Set<Object> getPartitions(List<Document> documents) {
   final HashSet<Object> partitions = Sets.newHashSet();
   for (Document document : documents) {
     final Collection<Object> documentPartitions =
         document.<Collection<Object>>getField(partitionIdFieldName);
     if (documentPartitions != null) {
       partitions.addAll(documentPartitions);
     }
   }
   return partitions;
 }
Exemplo n.º 11
0
 private void markDeadInstructions() {
   Set<Instruction> instructionSet = Sets.newHashSet(instructions);
   for (Instruction instruction : mutableInstructionList) {
     if (!instructionSet.contains(instruction)) {
       ((InstructionImpl) instruction).setMarkedAsDead(true);
       for (Instruction nextInstruction : instruction.getNextInstructions()) {
         nextInstruction.getPreviousInstructions().remove(instruction);
       }
     }
   }
 }
Exemplo n.º 12
0
 /**
  * expand super types after scanning, for super types that were not scanned. this is helpful in
  * finding the transitive closure without scanning all 3rd party dependencies. it uses {@link
  * ReflectionUtils#getSuperTypes(Class)}.
  *
  * <p>for example, for classes A,B,C where A supertype of B, B supertype of C:
  *
  * <ul>
  *   <li>if scanning C resulted in B (B->C in store), but A was not scanned (although A supertype
  *       of B) - then getSubTypes(A) will not return C
  *   <li>if expanding supertypes, B will be expanded with A (A->B in store) - then getSubTypes(A)
  *       will return C
  * </ul>
  */
 public void expandSuperTypes() {
   if (store.keySet().contains(index(SubTypesScanner.class))) {
     Multimap<String, String> mmap = store.get(index(SubTypesScanner.class));
     Sets.SetView<String> keys = Sets.difference(mmap.keySet(), Sets.newHashSet(mmap.values()));
     Multimap<String, String> expand = HashMultimap.create();
     for (String key : keys) {
       expandSupertypes(expand, key, forName(key));
     }
     mmap.putAll(expand);
   }
 }
Exemplo n.º 13
0
  @Override
  public int getDistance(NetworkNode from, NetworkNode to) {
    TwoNetworkNodes nodePair = new TwoNetworkNodes(from, to);
    final Integer cachedDistance = distanceCache.get(nodePair);
    if (cachedDistance != null) return cachedDistance;

    if ((!hasNetworkingNode(from) && !hasLeafNode(from))
        || (!hasNetworkingNode(to) && !hasLeafNode(to)))
      throw new IllegalArgumentException("Cannot test nodes not in network");

    if (from.equals(to)) return 0;

    if (SimpleNetwork.areNodesConnecting(from, to)) return 1;

    // Breadth-first search of the network
    Set<NetworkNode> visitedNodes = Sets.newHashSet();
    visitedNodes.add(from);

    Set<NetworkNode> networkingNodesToTest = Sets.newHashSet();
    listConnectedNotVisitedNetworkingNodes(visitedNodes, from, networkingNodesToTest);
    int distanceSearched = 1;
    while (networkingNodesToTest.size() > 0) {
      distanceSearched++;

      for (NetworkNode nodeToTest : networkingNodesToTest) {
        if (SimpleNetwork.areNodesConnecting(nodeToTest, to)) {
          distanceCache.put(new TwoNetworkNodes(from, to), distanceSearched);
          return distanceSearched;
        }
        visitedNodes.add(nodeToTest);
      }

      Set<NetworkNode> nextNetworkingNodesToTest = Sets.newHashSet();
      for (NetworkNode nodeToTest : networkingNodesToTest)
        listConnectedNotVisitedNetworkingNodes(visitedNodes, nodeToTest, nextNetworkingNodesToTest);

      networkingNodesToTest = nextNetworkingNodesToTest;
    }
    return -1;
  }
Exemplo n.º 14
0
 private Set<Instruction> collectReachableInstructions() {
   Set<Instruction> visited = Sets.newHashSet();
   PseudocodeTraverserKt.traverseFollowingInstructions(
       getEnterInstruction(), visited, FORWARD, null);
   if (!visited.contains(getExitInstruction())) {
     visited.add(getExitInstruction());
   }
   if (!visited.contains(errorInstruction)) {
     visited.add(errorInstruction);
   }
   if (!visited.contains(getSinkInstruction())) {
     visited.add(getSinkInstruction());
   }
   return visited;
 }
Exemplo n.º 15
0
  /**
   * Builds an "Other Topics" cluster that groups those documents from <code>allDocument</code> that
   * were not referenced in any cluster in <code>clusters</code>.
   *
   * @param allDocuments all documents to check against
   * @param clusters list of clusters with assigned documents
   * @param label label for the "Other Topics" group
   * @return the "Other Topics" cluster
   */
  public static Cluster buildOtherTopics(
      List<Document> allDocuments, List<Cluster> clusters, String label) {
    final Set<Document> unclusteredDocuments = Sets.newLinkedHashSet(allDocuments);
    final Set<Document> assignedDocuments = Sets.newHashSet();

    for (Cluster cluster : clusters) {
      collectAllDocuments(cluster, assignedDocuments);
    }

    unclusteredDocuments.removeAll(assignedDocuments);

    final Cluster otherTopics = new Cluster(label);
    otherTopics.addDocuments(unclusteredDocuments);
    otherTopics.setOtherTopics(true);

    return otherTopics;
  }
Exemplo n.º 16
0
 /**
  * Returns all the fields that match the given pattern. If the pattern is prefixed with a type
  * then the fields will be returned with a type prefix.
  */
 public Set<String> simpleMatchToIndexNames(String pattern) {
   if (!Regex.isSimpleMatchPattern(pattern)) {
     return ImmutableSet.of(pattern);
   }
   int dotIndex = pattern.indexOf('.');
   if (dotIndex != -1) {
     String possibleType = pattern.substring(0, dotIndex);
     DocumentMapper possibleDocMapper = mappers.get(possibleType);
     if (possibleDocMapper != null) {
       Set<String> typedFields = Sets.newHashSet();
       for (String indexName : possibleDocMapper.mappers().simpleMatchToIndexNames(pattern)) {
         typedFields.add(possibleType + "." + indexName);
       }
       return typedFields;
     }
   }
   return fieldMappers.simpleMatchToIndexNames(pattern);
 }
Exemplo n.º 17
0
  private void checkRedeclarationsInPackages(@NotNull TopDownAnalysisContext c) {
    for (MutablePackageFragmentDescriptor packageFragment :
        Sets.newHashSet(c.getPackageFragments().values())) {
      PackageViewDescriptor packageView =
          packageFragment.getContainingDeclaration().getPackage(packageFragment.getFqName());
      JetScope packageViewScope = packageView.getMemberScope();
      Multimap<Name, DeclarationDescriptor> simpleNameDescriptors =
          packageFragment.getMemberScope().getDeclaredDescriptorsAccessibleBySimpleName();
      for (Name name : simpleNameDescriptors.keySet()) {
        // Keep only properties with no receiver
        Collection<DeclarationDescriptor> descriptors =
            Collections2.filter(
                simpleNameDescriptors.get(name),
                new Predicate<DeclarationDescriptor>() {
                  @Override
                  public boolean apply(@Nullable DeclarationDescriptor descriptor) {
                    if (descriptor instanceof PropertyDescriptor) {
                      PropertyDescriptor propertyDescriptor = (PropertyDescriptor) descriptor;
                      return propertyDescriptor.getReceiverParameter() == null;
                    }
                    return true;
                  }
                });
        ContainerUtil.addIfNotNull(descriptors, packageViewScope.getPackage(name));

        if (descriptors.size() > 1) {
          for (DeclarationDescriptor declarationDescriptor : descriptors) {
            for (PsiElement declaration : getDeclarationsByDescriptor(declarationDescriptor)) {
              assert declaration != null
                  : "Null declaration for descriptor: "
                      + declarationDescriptor
                      + " "
                      + (declarationDescriptor != null
                          ? DescriptorRenderer.FQ_NAMES_IN_TYPES.render(declarationDescriptor)
                          : "");
              trace.report(
                  REDECLARATION.on(declaration, declarationDescriptor.getName().asString()));
            }
          }
        }
      }
    }
  }
  /**
   * @param gcBefore
   * @return
   */
  private List<SSTableReader> getNextBackgroundSSTables(final int gcBefore) {
    if (!isEnabled() || cfs.getSSTables().isEmpty()) return Collections.emptyList();

    Set<SSTableReader> uncompacting = Sets.intersection(sstables, cfs.getUncompactingSSTables());

    // Find fully expired SSTables. Those will be included no matter what.
    Set<SSTableReader> expired =
        CompactionController.getFullyExpiredSSTables(
            cfs, uncompacting, cfs.getOverlappingSSTables(uncompacting), gcBefore);
    Set<SSTableReader> candidates = Sets.newHashSet(filterSuspectSSTables(uncompacting));

    List<SSTableReader> compactionCandidates =
        new ArrayList<>(getNextNonExpiredSSTables(Sets.difference(candidates, expired), gcBefore));
    if (!expired.isEmpty()) {
      logger.debug("Including expired sstables: {}", expired);
      compactionCandidates.addAll(expired);
    }
    return compactionCandidates;
  }
Exemplo n.º 19
0
 /**
  * Returns all the fields that match the given pattern, with an optional narrowing based on a list
  * of types.
  */
 public Set<String> simpleMatchToIndexNames(String pattern, @Nullable String[] types) {
   if (types == null || types.length == 0) {
     return simpleMatchToIndexNames(pattern);
   }
   if (types.length == 1 && types[0].equals("_all")) {
     return simpleMatchToIndexNames(pattern);
   }
   if (!Regex.isSimpleMatchPattern(pattern)) {
     return ImmutableSet.of(pattern);
   }
   Set<String> fields = Sets.newHashSet();
   for (String type : types) {
     DocumentMapper possibleDocMapper = mappers.get(type);
     if (possibleDocMapper != null) {
       for (String indexName : possibleDocMapper.mappers().simpleMatchToIndexNames(pattern)) {
         fields.add(indexName);
       }
     }
   }
   return fields;
 }
Exemplo n.º 20
0
  private void writeGetters(ClassVisitor visitor, Type generatedType, ModelProperty<?> property) {
    Class<?> propertyClass = property.getType().getConcreteClass();
    Type propertyType = Type.getType(propertyClass);
    Set<String> processedNames = Sets.newHashSet();
    for (WeaklyTypeReferencingMethod<?, ?> weakGetter : property.getGetters()) {
      Method getter = weakGetter.getMethod();
      if (!processedNames.add(getter.getName())) {
        continue;
      }
      MethodVisitor methodVisitor =
          declareMethod(
              visitor,
              getter.getName(),
              Type.getMethodDescriptor(propertyType),
              AsmClassGeneratorUtils.signature(getter));

      putStateFieldValueOnStack(methodVisitor, generatedType);
      putConstantOnStack(methodVisitor, property.getName());
      invokeStateGetMethod(methodVisitor);
      castFirstStackElement(methodVisitor, propertyClass);
      finishVisitingMethod(methodVisitor, returnCode(propertyType));
    }
  }
Exemplo n.º 21
0
  private void reportRedeclarations(@NotNull Multimap<Name, DeclarationDescriptor> descriptorMap) {
    Set<Pair<PsiElement, Name>> redeclarations = Sets.newHashSet();
    for (Name name : descriptorMap.keySet()) {
      Collection<DeclarationDescriptor> descriptors = descriptorMap.get(name);
      if (descriptors.size() > 1) {
        // We mustn't compare PropertyDescriptor with PropertyDescriptor because we do this at
        // OverloadResolver
        for (DeclarationDescriptor descriptor : descriptors) {
          if (descriptor instanceof ClassDescriptor) {
            for (DeclarationDescriptor descriptor2 : descriptors) {
              if (descriptor == descriptor2) {
                continue;
              }

              redeclarations.add(
                  Pair.create(
                      BindingContextUtils.classDescriptorToDeclaration(
                          trace.getBindingContext(), (ClassDescriptor) descriptor),
                      descriptor.getName()));
              if (descriptor2 instanceof PropertyDescriptor) {
                redeclarations.add(
                    Pair.create(
                        BindingContextUtils.descriptorToDeclaration(
                            trace.getBindingContext(), descriptor2),
                        descriptor2.getName()));
              }
            }
          }
        }
      }
    }
    for (Pair<PsiElement, Name> redeclaration : redeclarations) {
      trace.report(
          REDECLARATION.on(redeclaration.getFirst(), redeclaration.getSecond().asString()));
    }
  }
Exemplo n.º 22
0
 /**
  * gets all sub types in hierarchy of a given type
  *
  * <p>depends on SubTypesScanner configured
  */
 public <T> Set<Class<? extends T>> getSubTypesOf(final Class<T> type) {
   return Sets.newHashSet(
       ReflectionUtils.<T>forNames(
           store.getAll(index(SubTypesScanner.class), Arrays.asList(type.getName())), loaders()));
 }
Exemplo n.º 23
0
 /**
  * get resources relative paths where simple name (key) matches given namePredicate
  *
  * <p>depends on ResourcesScanner configured
  */
 public Set<String> getResources(final Predicate<String> namePredicate) {
   Iterable<String> resources =
       Iterables.filter(store.get(index(ResourcesScanner.class)).keySet(), namePredicate);
   return Sets.newHashSet(store.get(index(ResourcesScanner.class), resources));
 }
Exemplo n.º 24
0
public class PseudocodeImpl implements Pseudocode {

  public class PseudocodeLabel implements Label {
    private final String name;
    private final String comment;
    private Integer targetInstructionIndex;

    private PseudocodeLabel(@NotNull String name, @Nullable String comment) {
      this.name = name;
      this.comment = comment;
    }

    @NotNull
    @Override
    public String getName() {
      return name;
    }

    @Override
    public String toString() {
      return comment == null ? name : (name + " [" + comment + "]");
    }

    public Integer getTargetInstructionIndex() {
      return targetInstructionIndex;
    }

    public void setTargetInstructionIndex(int targetInstructionIndex) {
      this.targetInstructionIndex = targetInstructionIndex;
    }

    @Nullable
    private List<Instruction> resolve() {
      assert targetInstructionIndex != null;
      return mutableInstructionList.subList(
          getTargetInstructionIndex(), mutableInstructionList.size());
    }

    public Instruction resolveToInstruction() {
      assert targetInstructionIndex != null;
      return mutableInstructionList.get(targetInstructionIndex);
    }

    public PseudocodeLabel copy(int newLabelIndex) {
      return new PseudocodeLabel("L" + newLabelIndex, "copy of " + name + ", " + comment);
    }

    public PseudocodeImpl getPseudocode() {
      return PseudocodeImpl.this;
    }
  }

  private final List<Instruction> mutableInstructionList = new ArrayList<Instruction>();
  private final List<Instruction> instructions = new ArrayList<Instruction>();

  private final BidirectionalMap<KtElement, PseudoValue> elementsToValues =
      new BidirectionalMap<KtElement, PseudoValue>();

  private final Map<PseudoValue, List<Instruction>> valueUsages = Maps.newHashMap();
  private final Map<PseudoValue, Set<PseudoValue>> mergedValues = Maps.newHashMap();
  private final Set<Instruction> sideEffectFree = Sets.newHashSet();

  private Pseudocode parent = null;
  private Set<LocalFunctionDeclarationInstruction> localDeclarations = null;
  // todo getters
  private final Map<KtElement, Instruction> representativeInstructions =
      new HashMap<KtElement, Instruction>();

  private final List<PseudocodeLabel> labels = new ArrayList<PseudocodeLabel>();

  private final KtElement correspondingElement;
  private SubroutineExitInstruction exitInstruction;
  private SubroutineSinkInstruction sinkInstruction;
  private SubroutineExitInstruction errorInstruction;
  private boolean postPrecessed = false;

  public PseudocodeImpl(KtElement correspondingElement) {
    this.correspondingElement = correspondingElement;
  }

  @NotNull
  @Override
  public KtElement getCorrespondingElement() {
    return correspondingElement;
  }

  @NotNull
  @Override
  public Set<LocalFunctionDeclarationInstruction> getLocalDeclarations() {
    if (localDeclarations == null) {
      localDeclarations = getLocalDeclarations(this);
    }
    return localDeclarations;
  }

  @NotNull
  private static Set<LocalFunctionDeclarationInstruction> getLocalDeclarations(
      @NotNull Pseudocode pseudocode) {
    Set<LocalFunctionDeclarationInstruction> localDeclarations = Sets.newLinkedHashSet();
    for (Instruction instruction : ((PseudocodeImpl) pseudocode).mutableInstructionList) {
      if (instruction instanceof LocalFunctionDeclarationInstruction) {
        localDeclarations.add((LocalFunctionDeclarationInstruction) instruction);
        localDeclarations.addAll(
            getLocalDeclarations(((LocalFunctionDeclarationInstruction) instruction).getBody()));
      }
    }
    return localDeclarations;
  }

  @Override
  @Nullable
  public Pseudocode getParent() {
    return parent;
  }

  private void setParent(Pseudocode parent) {
    this.parent = parent;
  }

  @NotNull
  public Pseudocode getRootPseudocode() {
    Pseudocode parent = getParent();
    while (parent != null) {
      if (parent.getParent() == null) return parent;
      parent = parent.getParent();
    }
    return this;
  }

  /*package*/ PseudocodeLabel createLabel(@NotNull String name, @Nullable String comment) {
    PseudocodeLabel label = new PseudocodeLabel(name, comment);
    labels.add(label);
    return label;
  }

  @Override
  @NotNull
  public List<Instruction> getInstructions() {
    return instructions;
  }

  @NotNull
  @Override
  public List<Instruction> getReversedInstructions() {
    LinkedHashSet<Instruction> traversedInstructions = Sets.newLinkedHashSet();
    PseudocodeTraverserKt.traverseFollowingInstructions(
        sinkInstruction, traversedInstructions, BACKWARD, null);
    if (traversedInstructions.size() < instructions.size()) {
      List<Instruction> simplyReversedInstructions = Lists.newArrayList(instructions);
      Collections.reverse(simplyReversedInstructions);
      for (Instruction instruction : simplyReversedInstructions) {
        if (!traversedInstructions.contains(instruction)) {
          PseudocodeTraverserKt.traverseFollowingInstructions(
              instruction, traversedInstructions, BACKWARD, null);
        }
      }
    }
    return Lists.newArrayList(traversedInstructions);
  }

  @Override
  @NotNull
  public List<Instruction> getInstructionsIncludingDeadCode() {
    return mutableInstructionList;
  }

  // for tests only
  @NotNull
  public List<PseudocodeLabel> getLabels() {
    return labels;
  }

  /*package*/ void addExitInstruction(SubroutineExitInstruction exitInstruction) {
    addInstruction(exitInstruction);
    assert this.exitInstruction == null;
    this.exitInstruction = exitInstruction;
  }

  /*package*/ void addSinkInstruction(SubroutineSinkInstruction sinkInstruction) {
    addInstruction(sinkInstruction);
    assert this.sinkInstruction == null;
    this.sinkInstruction = sinkInstruction;
  }

  /*package*/ void addErrorInstruction(SubroutineExitInstruction errorInstruction) {
    addInstruction(errorInstruction);
    assert this.errorInstruction == null;
    this.errorInstruction = errorInstruction;
  }

  /*package*/ void addInstruction(Instruction instruction) {
    mutableInstructionList.add(instruction);
    instruction.setOwner(this);

    if (instruction instanceof KtElementInstruction) {
      KtElementInstruction elementInstruction = (KtElementInstruction) instruction;
      representativeInstructions.put(elementInstruction.getElement(), instruction);
    }

    if (instruction instanceof MergeInstruction) {
      addMergedValues((MergeInstruction) instruction);
    }

    for (PseudoValue inputValue : instruction.getInputValues()) {
      addValueUsage(inputValue, instruction);
      for (PseudoValue mergedValue : getMergedValues(inputValue)) {
        addValueUsage(mergedValue, instruction);
      }
    }
    if (PseudocodeUtilsKt.calcSideEffectFree(instruction)) {
      sideEffectFree.add(instruction);
    }
  }

  @Override
  @NotNull
  public SubroutineExitInstruction getExitInstruction() {
    return exitInstruction;
  }

  @Override
  @NotNull
  public SubroutineSinkInstruction getSinkInstruction() {
    return sinkInstruction;
  }

  @Override
  @NotNull
  public SubroutineEnterInstruction getEnterInstruction() {
    return (SubroutineEnterInstruction) mutableInstructionList.get(0);
  }

  @Nullable
  @Override
  public PseudoValue getElementValue(@Nullable KtElement element) {
    return elementsToValues.get(element);
  }

  @NotNull
  @Override
  public List<? extends KtElement> getValueElements(@Nullable PseudoValue value) {
    List<? extends KtElement> result = elementsToValues.getKeysByValue(value);
    return result != null ? result : Collections.<KtElement>emptyList();
  }

  @NotNull
  @Override
  public List<? extends Instruction> getUsages(@Nullable PseudoValue value) {
    List<? extends Instruction> result = valueUsages.get(value);
    return result != null ? result : Collections.<Instruction>emptyList();
  }

  @Override
  public boolean isSideEffectFree(@NotNull Instruction instruction) {
    return sideEffectFree.contains(instruction);
  }

  /*package*/ void bindElementToValue(@NotNull KtElement element, @NotNull PseudoValue value) {
    elementsToValues.put(element, value);
  }

  /*package*/ void bindLabel(Label label) {
    ((PseudocodeLabel) label).setTargetInstructionIndex(mutableInstructionList.size());
  }

  private Set<PseudoValue> getMergedValues(@NotNull PseudoValue value) {
    Set<PseudoValue> result = mergedValues.get(value);
    return result != null ? result : Collections.<PseudoValue>emptySet();
  }

  private void addMergedValues(@NotNull MergeInstruction instruction) {
    Set<PseudoValue> result = new LinkedHashSet<PseudoValue>();
    for (PseudoValue value : instruction.getInputValues()) {
      result.addAll(getMergedValues(value));
      result.add(value);
    }
    mergedValues.put(instruction.getOutputValue(), result);
  }

  private void addValueUsage(PseudoValue value, Instruction usage) {
    if (usage instanceof MergeInstruction) return;
    MapsKt.getOrPut(
            valueUsages,
            value,
            new Function0<List<Instruction>>() {
              @Override
              public List<Instruction> invoke() {
                return Lists.newArrayList();
              }
            })
        .add(usage);
  }

  public void postProcess() {
    if (postPrecessed) return;
    postPrecessed = true;
    errorInstruction.setSink(getSinkInstruction());
    exitInstruction.setSink(getSinkInstruction());
    int index = 0;
    for (Instruction instruction : mutableInstructionList) {
      // recursively invokes 'postProcess' for local declarations
      processInstruction(instruction, index);
      index++;
    }
    if (getParent() != null) return;

    // Collecting reachable instructions should be done after processing all instructions
    // (including instructions in local declarations) to avoid being in incomplete state.
    collectAndCacheReachableInstructions();
    for (LocalFunctionDeclarationInstruction localFunctionDeclarationInstruction :
        getLocalDeclarations()) {
      ((PseudocodeImpl) localFunctionDeclarationInstruction.getBody())
          .collectAndCacheReachableInstructions();
    }
  }

  private void collectAndCacheReachableInstructions() {
    Set<Instruction> reachableInstructions = collectReachableInstructions();
    for (Instruction instruction : mutableInstructionList) {
      if (reachableInstructions.contains(instruction)) {
        instructions.add(instruction);
      }
    }
    markDeadInstructions();
  }

  private void processInstruction(Instruction instruction, final int currentPosition) {
    instruction.accept(
        new InstructionVisitor() {
          @Override
          public void visitInstructionWithNext(@NotNull InstructionWithNext instruction) {
            instruction.setNext(getNextPosition(currentPosition));
          }

          @Override
          public void visitJump(@NotNull AbstractJumpInstruction instruction) {
            instruction.setResolvedTarget(getJumpTarget(instruction.getTargetLabel()));
          }

          @Override
          public void visitNondeterministicJump(
              @NotNull NondeterministicJumpInstruction instruction) {
            instruction.setNext(getNextPosition(currentPosition));
            List<Label> targetLabels = instruction.getTargetLabels();
            for (Label targetLabel : targetLabels) {
              instruction.setResolvedTarget(targetLabel, getJumpTarget(targetLabel));
            }
          }

          @Override
          public void visitConditionalJump(@NotNull ConditionalJumpInstruction instruction) {
            Instruction nextInstruction = getNextPosition(currentPosition);
            Instruction jumpTarget = getJumpTarget(instruction.getTargetLabel());
            if (instruction.getOnTrue()) {
              instruction.setNextOnFalse(nextInstruction);
              instruction.setNextOnTrue(jumpTarget);
            } else {
              instruction.setNextOnFalse(jumpTarget);
              instruction.setNextOnTrue(nextInstruction);
            }
            visitJump(instruction);
          }

          @Override
          public void visitLocalFunctionDeclarationInstruction(
              @NotNull LocalFunctionDeclarationInstruction instruction) {
            PseudocodeImpl body = (PseudocodeImpl) instruction.getBody();
            body.setParent(PseudocodeImpl.this);
            body.postProcess();
            instruction.setNext(getSinkInstruction());
          }

          @Override
          public void visitSubroutineExit(@NotNull SubroutineExitInstruction instruction) {
            // Nothing
          }

          @Override
          public void visitSubroutineSink(@NotNull SubroutineSinkInstruction instruction) {
            // Nothing
          }

          @Override
          public void visitInstruction(@NotNull Instruction instruction) {
            throw new UnsupportedOperationException(instruction.toString());
          }
        });
  }

  private Set<Instruction> collectReachableInstructions() {
    Set<Instruction> visited = Sets.newHashSet();
    PseudocodeTraverserKt.traverseFollowingInstructions(
        getEnterInstruction(), visited, FORWARD, null);
    if (!visited.contains(getExitInstruction())) {
      visited.add(getExitInstruction());
    }
    if (!visited.contains(errorInstruction)) {
      visited.add(errorInstruction);
    }
    if (!visited.contains(getSinkInstruction())) {
      visited.add(getSinkInstruction());
    }
    return visited;
  }

  private void markDeadInstructions() {
    Set<Instruction> instructionSet = Sets.newHashSet(instructions);
    for (Instruction instruction : mutableInstructionList) {
      if (!instructionSet.contains(instruction)) {
        ((InstructionImpl) instruction).setMarkedAsDead(true);
        for (Instruction nextInstruction : instruction.getNextInstructions()) {
          nextInstruction.getPreviousInstructions().remove(instruction);
        }
      }
    }
  }

  @NotNull
  private Instruction getJumpTarget(@NotNull Label targetLabel) {
    return ((PseudocodeLabel) targetLabel).resolveToInstruction();
  }

  @NotNull
  private Instruction getNextPosition(int currentPosition) {
    int targetPosition = currentPosition + 1;
    assert targetPosition < mutableInstructionList.size() : currentPosition;
    return mutableInstructionList.get(targetPosition);
  }

  @Override
  public PseudocodeImpl copy() {
    PseudocodeImpl result = new PseudocodeImpl(correspondingElement);
    result.repeatWhole(this);
    return result;
  }

  private void repeatWhole(@NotNull PseudocodeImpl originalPseudocode) {
    repeatInternal(originalPseudocode, null, null, 0);
    parent = originalPseudocode.parent;
  }

  public int repeatPart(@NotNull Label startLabel, @NotNull Label finishLabel, int labelCount) {
    return repeatInternal(
        ((PseudocodeLabel) startLabel).getPseudocode(), startLabel, finishLabel, labelCount);
  }

  private int repeatInternal(
      @NotNull PseudocodeImpl originalPseudocode,
      @Nullable Label startLabel,
      @Nullable Label finishLabel,
      int labelCount) {
    Integer startIndex =
        startLabel != null
            ? ((PseudocodeLabel) startLabel).getTargetInstructionIndex()
            : Integer.valueOf(0);
    assert startIndex != null;
    Integer finishIndex =
        finishLabel != null
            ? ((PseudocodeLabel) finishLabel).getTargetInstructionIndex()
            : Integer.valueOf(originalPseudocode.mutableInstructionList.size());
    assert finishIndex != null;

    Map<Label, Label> originalToCopy = Maps.newLinkedHashMap();
    Multimap<Instruction, Label> originalLabelsForInstruction = HashMultimap.create();
    for (PseudocodeLabel label : originalPseudocode.labels) {
      Integer index = label.getTargetInstructionIndex();
      if (index == null) continue; // label is not bounded yet
      if (label == startLabel || label == finishLabel) continue;

      if (startIndex <= index && index <= finishIndex) {
        originalToCopy.put(label, label.copy(labelCount++));
        originalLabelsForInstruction.put(getJumpTarget(label), label);
      }
    }
    for (Label label : originalToCopy.values()) {
      labels.add((PseudocodeLabel) label);
    }
    for (int index = startIndex; index < finishIndex; index++) {
      Instruction originalInstruction = originalPseudocode.mutableInstructionList.get(index);
      repeatLabelsBindingForInstruction(
          originalInstruction, originalToCopy, originalLabelsForInstruction);
      Instruction copy = copyInstruction(originalInstruction, originalToCopy);
      addInstruction(copy);
      if (originalInstruction == originalPseudocode.errorInstruction
          && copy instanceof SubroutineExitInstruction) {
        errorInstruction = (SubroutineExitInstruction) copy;
      }
      if (originalInstruction == originalPseudocode.exitInstruction
          && copy instanceof SubroutineExitInstruction) {
        exitInstruction = (SubroutineExitInstruction) copy;
      }
      if (originalInstruction == originalPseudocode.sinkInstruction
          && copy instanceof SubroutineSinkInstruction) {
        sinkInstruction = (SubroutineSinkInstruction) copy;
      }
    }
    if (finishIndex < mutableInstructionList.size()) {
      repeatLabelsBindingForInstruction(
          originalPseudocode.mutableInstructionList.get(finishIndex),
          originalToCopy,
          originalLabelsForInstruction);
    }
    return labelCount;
  }

  private void repeatLabelsBindingForInstruction(
      @NotNull Instruction originalInstruction,
      @NotNull Map<Label, Label> originalToCopy,
      @NotNull Multimap<Instruction, Label> originalLabelsForInstruction) {
    for (Label originalLabel : originalLabelsForInstruction.get(originalInstruction)) {
      bindLabel(originalToCopy.get(originalLabel));
    }
  }

  private static Instruction copyInstruction(
      @NotNull Instruction instruction, @NotNull Map<Label, Label> originalToCopy) {
    if (instruction instanceof AbstractJumpInstruction) {
      Label originalTarget = ((AbstractJumpInstruction) instruction).getTargetLabel();
      if (originalToCopy.containsKey(originalTarget)) {
        return ((AbstractJumpInstruction) instruction).copy(originalToCopy.get(originalTarget));
      }
    }
    if (instruction instanceof NondeterministicJumpInstruction) {
      List<Label> originalTargets =
          ((NondeterministicJumpInstruction) instruction).getTargetLabels();
      List<Label> copyTargets = copyLabels(originalTargets, originalToCopy);
      return ((NondeterministicJumpInstruction) instruction).copy(copyTargets);
    }
    return ((InstructionImpl) instruction).copy();
  }

  @NotNull
  private static List<Label> copyLabels(
      Collection<Label> labels, Map<Label, Label> originalToCopy) {
    List<Label> newLabels = Lists.newArrayList();
    for (Label label : labels) {
      Label newLabel = originalToCopy.get(label);
      newLabels.add(newLabel != null ? newLabel : label);
    }
    return newLabels;
  }
}
Exemplo n.º 25
0
        @Override
        public Iterator<TitanElement> getNew(final StandardElementQuery query) {
          Preconditions.checkArgument(
              query.getType() == StandardElementQuery.Type.VERTEX
                  || query.getType() == StandardElementQuery.Type.EDGE);
          if (query.getType() == StandardElementQuery.Type.VERTEX && hasModifications()) {
            // Collect all keys from the query - ASSUMPTION: query is an AND of KeyAtom
            final Set<TitanKey> keys = Sets.newHashSet();
            KeyAtom<TitanKey> standardIndexKey = null;
            for (KeyCondition<TitanKey> cond : query.getCondition().getChildren()) {
              KeyAtom<TitanKey> atom = (KeyAtom<TitanKey>) cond;
              if (atom.getRelation() == Cmp.EQUAL && isVertexIndexProperty(atom.getKey()))
                standardIndexKey = atom;
              keys.add(atom.getKey());
            }
            Iterator<TitanVertex> vertices;
            if (standardIndexKey == null) {
              Set<TitanVertex> vertexSet = Sets.newHashSet();
              for (TitanRelation r :
                  addedRelations.getView(
                      new Predicate<InternalRelation>() {
                        @Override
                        public boolean apply(@Nullable InternalRelation relation) {
                          return keys.contains(relation.getType());
                        }
                      })) {
                vertexSet.add(((TitanProperty) r).getVertex());
              }
              for (TitanRelation r : deletedRelations.values()) {
                if (keys.contains(r.getType())) {
                  TitanVertex v = ((TitanProperty) r).getVertex();
                  if (!v.isRemoved()) vertexSet.add(v);
                }
              }
              vertices = vertexSet.iterator();
            } else {
              vertices =
                  Iterators.transform(
                      newVertexIndexEntries
                          .get(standardIndexKey.getCondition(), standardIndexKey.getKey())
                          .iterator(),
                      new Function<TitanProperty, TitanVertex>() {
                        @Nullable
                        @Override
                        public TitanVertex apply(@Nullable TitanProperty o) {
                          return o.getVertex();
                        }
                      });
            }

            return (Iterator)
                Iterators.filter(
                    vertices,
                    new Predicate<TitanVertex>() {
                      @Override
                      public boolean apply(@Nullable TitanVertex vertex) {
                        return query.matches(vertex);
                      }
                    });
          } else if (query.getType() == StandardElementQuery.Type.EDGE
              && !addedRelations.isEmpty()) {
            return (Iterator)
                addedRelations
                    .getView(
                        new Predicate<InternalRelation>() {
                          @Override
                          public boolean apply(@Nullable InternalRelation relation) {
                            return (relation instanceof TitanEdge)
                                && !relation.isHidden()
                                && query.matches(relation);
                          }
                        })
                    .iterator();
          } else throw new IllegalArgumentException("Unexpected type: " + query.getType());
        }