blob: 71d8f1f76f24363b887016a263ec3e2df617adbf [file] [log] [blame]
/*******************************************************************************
* 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 <jogl@google.com> - 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.
* <p>
* 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<OnDemandReduction> identifyPossibleReductions(
Set<ImportName> imports,
Set<ImportName> touchedContainers,
Set<String> typeExplicitSimpleNames,
Set<String> staticExplicitSimpleNames) {
Collection<OnDemandReduction> candidates = new ArrayList<OnDemandReduction>();
Map<ImportName, Collection<ImportName>> importsByContainer = mapByContainer(imports);
for (Map.Entry<ImportName, Collection<ImportName>> containerAndImports : importsByContainer.entrySet()) {
ImportName containerOnDemand = containerAndImports.getKey();
Collection<ImportName> containerImports = containerAndImports.getValue();
Set<String> explicitSimpleNames =
containerOnDemand.isStatic ? staticExplicitSimpleNames : typeExplicitSimpleNames;
int onDemandThreshold =
containerOnDemand.isStatic ? this.staticOnDemandThreshold : this.typeOnDemandThreshold;
if (touchedContainers.contains(containerOnDemand)) {
OnDemandReduction candidate = maybeReduce(
containerOnDemand, containerImports, onDemandThreshold, explicitSimpleNames);
if (candidate != null) {
candidates.add(candidate);
}
}
}
return candidates;
}
private Map<ImportName, Collection<ImportName>> mapByContainer(Collection<ImportName> imports) {
Map<ImportName, Collection<ImportName>> importsByContainer = new HashMap<ImportName, Collection<ImportName>>();
for (ImportName importName : imports) {
ImportName containerOnDemand = importName.getContainerOnDemand();
Collection<ImportName> containerImports = importsByContainer.get(containerOnDemand);
if (containerImports == null) {
containerImports = new ArrayList<ImportName>();
importsByContainer.put(containerOnDemand, containerImports);
}
containerImports.add(importName);
}
return importsByContainer;
}
private OnDemandReduction maybeReduce(
ImportName containerOnDemand,
Collection<ImportName> containerImports,
int onDemandThreshold,
Set<String> explicitSimpleNames) {
boolean containerHasOnDemand = false;
Collection<ImportName> reducibleImports = new ArrayList<ImportName>();
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;
}
}