blob: 5da8a3b73f4b8784c8f591c5e5b7cdea8a62a24b [file] [log] [blame]
/*
* Copyright 2012-present Facebook, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License. You may obtain
* a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*/
package com.facebook.buck.dalvik.firstorder;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Maps;
import org.objectweb.asm.Type;
import org.objectweb.asm.tree.ClassNode;
import java.util.Map;
public class FirstOrderHelper {
private final Iterable<Type> scenarioTypes;
private final ImmutableSet.Builder<String> resultBuilder;
private final Map<Type, FirstOrderTypeInfo> knownTypes;
private FirstOrderHelper(
Iterable<Type> scenarioTypes,
ImmutableSet.Builder<String> resultBuilder) {
this.scenarioTypes = scenarioTypes;
this.resultBuilder = resultBuilder;
this.knownTypes = Maps.newHashMap();
}
public static void addTypesAndDependencies(
Iterable<Type> scenarioTypes,
Iterable<ClassNode> allClasses,
ImmutableSet.Builder<String> classNamesBuilder) {
FirstOrderHelper helper = new FirstOrderHelper(scenarioTypes, classNamesBuilder);
helper.addDependencies(allClasses);
}
private ImmutableSet<String> addDependencies(Iterable<ClassNode> allClasses) {
for (ClassNode classNode : allClasses) {
FirstOrderVisitorContext context = new FirstOrderVisitorContext();
classNode.accept(context.classVisitor);
FirstOrderTypeInfo info = context.builder.build();
knownTypes.put(info.type, info);
}
// TODO(user): consider adding events here that allow developers to track
// how many non android.* and java.* classes went unrecognized over time.
//
// Not all types will be known. This includes types from Android, java
// runtime libraries, and any types that have been removed from the application
// since the scenario ran.
for (Type type : scenarioTypes) {
addFirstOrderTypes(type);
}
return resultBuilder.build();
}
private void addFirstOrderTypes(Type type) {
addTypeAndSupers(type);
FirstOrderTypeInfo info = knownTypes.get(type);
if (info != null) {
for (Type dependency : info.observedDependencies) {
addTypeAndSupers(dependency);
}
}
}
private void addTypeAndSupers(Type type) {
addType(type);
FirstOrderTypeInfo info = knownTypes.get(type);
if (info != null) {
addTypeAndSupers(info.superType);
for (Type interfaceType : info.interfaceTypes) {
addTypeAndSupers(interfaceType);
}
}
}
private void addType(Type type) {
resultBuilder.add(type.getInternalName());
}
}