org.eclipse.jdt.internal.core.dom.rewrite.imports.OnDemandComputer Maven / Gradle / Ivy
/*******************************************************************************
* Copyright (c) 2015 Google Inc and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* John Glassmyer - import group sorting is broken - https://bugs.eclipse.org/430303
*******************************************************************************/
package org.eclipse.jdt.internal.core.dom.rewrite.imports;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
class OnDemandComputer {
private int typeOnDemandThreshold;
private int staticOnDemandThreshold;
OnDemandComputer(int typeOnDemandThreshold, int staticOnDemandThreshold) {
this.typeOnDemandThreshold = typeOnDemandThreshold;
this.staticOnDemandThreshold = staticOnDemandThreshold;
}
/**
* Identifies on-demand reductions (additions of on-demand imports with corresponding removal of
* single imports) satisfying the type and static on-demand import thresholds.
*
* Only the containers imports which have been added or removed as part of the rewrite
* will be considered for on-demand reductions.
*
* @param imports
* the imports in the compilation unit
* @param touchedContainers
* the containers of all imports being added or removed as part of this rewrite,
* which should be considered for on-demand reductions (specified as an on-demand
* ImportName for each container)
* @param typeExplicitSimpleNames
* simple names of non-static single imports which must be preserved as single
* imports and not reduced into on-demand imports
* @param staticExplicitSimpleNames
* simple names of static single imports which must be preserved as single
* imports and not reduced into on-demand imports
*/
Collection identifyPossibleReductions(
Set imports,
Set touchedContainers,
Set typeExplicitSimpleNames,
Set staticExplicitSimpleNames) {
Collection candidates = new ArrayList();
Map> importsByContainer = mapByContainer(imports);
for (Map.Entry> containerAndImports : importsByContainer.entrySet()) {
ImportName containerOnDemand = containerAndImports.getKey();
// Imports from an unnamed package should not be reduced (see bug 461863).
boolean isUnnamedPackage = containerOnDemand.containerName.isEmpty();
if (touchedContainers.contains(containerOnDemand) && !isUnnamedPackage) {
Collection containerImports = containerAndImports.getValue();
Set explicitSimpleNames =
containerOnDemand.isStatic ? staticExplicitSimpleNames : typeExplicitSimpleNames;
int onDemandThreshold =
containerOnDemand.isStatic ? this.staticOnDemandThreshold : this.typeOnDemandThreshold;
OnDemandReduction candidate = maybeReduce(
containerOnDemand, containerImports, onDemandThreshold, explicitSimpleNames);
if (candidate != null) {
candidates.add(candidate);
}
}
}
return candidates;
}
private Map> mapByContainer(Collection imports) {
Map> importsByContainer = new HashMap>();
for (ImportName importName : imports) {
ImportName containerOnDemand = importName.getContainerOnDemand();
Collection containerImports = importsByContainer.get(containerOnDemand);
if (containerImports == null) {
containerImports = new ArrayList();
importsByContainer.put(containerOnDemand, containerImports);
}
containerImports.add(importName);
}
return importsByContainer;
}
private OnDemandReduction maybeReduce(
ImportName containerOnDemand,
Collection containerImports,
int onDemandThreshold,
Set explicitSimpleNames) {
boolean containerHasOnDemand = false;
Collection reducibleImports = new ArrayList();
for (ImportName currentImport : containerImports) {
if (currentImport.isOnDemand()) {
containerHasOnDemand = true;
} else {
if (!explicitSimpleNames.contains(currentImport.simpleName)) {
reducibleImports.add(currentImport);
}
}
}
if (containerHasOnDemand || reducibleImports.size() >= onDemandThreshold) {
return new OnDemandReduction(containerOnDemand, reducibleImports);
}
return null;
}
}