use of com.google.idea.blaze.android.sync.model.AndroidResourceModuleRegistry in project intellij by bazelbuild.
the class BlazeClassJarProvider method findModuleClassFile.
@Override
@Nullable
public VirtualFile findModuleClassFile(String className, Module module) {
BlazeProjectData blazeProjectData = BlazeProjectDataManager.getInstance(project).getBlazeProjectData();
if (blazeProjectData == null) {
return null;
}
TargetMap targetMap = blazeProjectData.targetMap;
ArtifactLocationDecoder decoder = blazeProjectData.artifactLocationDecoder;
AndroidResourceModuleRegistry registry = AndroidResourceModuleRegistry.getInstance(project);
TargetIdeInfo target = blazeProjectData.targetMap.get(registry.getTargetKey(module));
if (target == null || target.javaIdeInfo == null) {
return null;
}
// As a potential optimization, we could choose an arbitrary android_binary target
// that depends on the library to provide a single complete resource jar,
// instead of having to rely on dynamic class generation.
// TODO: benchmark to see if optimization is worthwhile.
String classNamePath = className.replace('.', File.separatorChar) + SdkConstants.DOT_CLASS;
List<LibraryArtifact> jarsToSearch = Lists.newArrayList(target.javaIdeInfo.jars);
jarsToSearch.addAll(TransitiveDependencyMap.getInstance(project).getTransitiveDependencies(target.key).stream().map(targetMap::get).filter(Objects::nonNull).flatMap(BlazeClassJarProvider::getNonResourceJars).collect(Collectors.toList()));
List<File> missingClassJars = Lists.newArrayList();
for (LibraryArtifact jar : jarsToSearch) {
if (jar.classJar == null || jar.classJar.isSource()) {
continue;
}
File classJarFile = decoder.decode(jar.classJar);
VirtualFile classJarVF = VirtualFileSystemProvider.getInstance().getSystem().findFileByIoFile(classJarFile);
if (classJarVF == null) {
if (classJarFile.exists()) {
missingClassJars.add(classJarFile);
}
continue;
}
VirtualFile classFile = findClassInJar(classJarVF, classNamePath);
if (classFile != null) {
return classFile;
}
}
maybeRefreshJars(missingClassJars, pendingJarsRefresh);
return null;
}
use of com.google.idea.blaze.android.sync.model.AndroidResourceModuleRegistry in project intellij by bazelbuild.
the class BlazeClassJarProvider method getModuleExternalLibraries.
@Override
public List<File> getModuleExternalLibraries(Module module) {
BlazeProjectData blazeProjectData = BlazeProjectDataManager.getInstance(project).getBlazeProjectData();
if (blazeProjectData == null) {
return ImmutableList.of();
}
TargetMap targetMap = blazeProjectData.targetMap;
ArtifactLocationDecoder decoder = blazeProjectData.artifactLocationDecoder;
AndroidResourceModuleRegistry registry = AndroidResourceModuleRegistry.getInstance(project);
TargetIdeInfo target = targetMap.get(registry.getTargetKey(module));
if (target == null) {
return ImmutableList.of();
}
AppResourceRepository repository = AppResourceRepository.getOrCreateInstance(module);
ImmutableList.Builder<File> results = ImmutableList.builder();
for (TargetKey dependencyTargetKey : TransitiveDependencyMap.getInstance(project).getTransitiveDependencies(target.key)) {
TargetIdeInfo dependencyTarget = targetMap.get(dependencyTargetKey);
if (dependencyTarget == null) {
continue;
}
// Add all import jars as external libraries.
JavaIdeInfo javaIdeInfo = dependencyTarget.javaIdeInfo;
if (javaIdeInfo != null) {
for (LibraryArtifact jar : javaIdeInfo.jars) {
if (jar.classJar != null && jar.classJar.isSource()) {
results.add(decoder.decode(jar.classJar));
}
}
}
// Tell ResourceClassRegistry which repository contains our resources and the java packages of
// the resources that we're interested in.
// When the class loader tries to load a custom view, and the view references resource
// classes, layoutlib will ask the class loader for these resource classes.
// If these resource classes are in a separate jar from the target (i.e., in a dependency),
// then offering their jars will lead to a conflict in the resource IDs.
// So instead, the resource class generator will produce dummy resource classes with
// non-conflicting IDs to satisfy the class loader.
// The resource repository remembers the dynamic IDs that it handed out and when the layoutlib
// calls to ask about the name and content of a given resource ID, the repository can just
// answer what it has already stored.
AndroidIdeInfo androidIdeInfo = dependencyTarget.androidIdeInfo;
if (androidIdeInfo != null && !Strings.isNullOrEmpty(androidIdeInfo.resourceJavaPackage) && repository != null) {
ResourceClassRegistry.get(module.getProject()).addLibrary(repository, androidIdeInfo.resourceJavaPackage);
}
}
return results.build();
}
use of com.google.idea.blaze.android.sync.model.AndroidResourceModuleRegistry in project intellij by bazelbuild.
the class BlazeBuildSystemService method addDependency.
@Override
public void addDependency(Module module, String artifact) {
Project project = module.getProject();
BlazeProjectData blazeProjectData = BlazeProjectDataManager.getInstance(project).getBlazeProjectData();
if (blazeProjectData == null) {
return;
}
AndroidResourceModuleRegistry registry = AndroidResourceModuleRegistry.getInstance(project);
TargetIdeInfo targetIdeInfo = blazeProjectData.targetMap.get(registry.getTargetKey(module));
if (targetIdeInfo == null || targetIdeInfo.buildFile == null) {
return;
}
// TODO: automagically edit deps instead of just opening the BUILD file?
// Need to translate Gradle coordinates into blaze targets.
// Will probably need to hardcode for each dependency.
FileEditorManager fileEditorManager = FileEditorManager.getInstance(project);
PsiElement buildTargetPsi = BuildReferenceManager.getInstance(project).resolveLabel(targetIdeInfo.key.label);
if (buildTargetPsi != null) {
// If we can find a PSI for the target,
// then we can jump straight to the target in the build file.
fileEditorManager.openTextEditor(new OpenFileDescriptor(project, buildTargetPsi.getContainingFile().getVirtualFile(), buildTargetPsi.getTextOffset()), true);
} else {
// If not, just the build file is good enough.
File buildIoFile = blazeProjectData.artifactLocationDecoder.decode(targetIdeInfo.buildFile);
VirtualFile buildVirtualFile = VfsUtils.resolveVirtualFile(buildIoFile);
if (buildVirtualFile != null) {
fileEditorManager.openFile(buildVirtualFile, true);
}
}
}
use of com.google.idea.blaze.android.sync.model.AndroidResourceModuleRegistry in project intellij by bazelbuild.
the class BlazeClassJarProviderIntegrationTest method buildTargetMap.
private TargetMap buildTargetMap() {
Label mainResourceLibrary = Label.create("//com/google/example:main");
Label androidDependency = Label.create("//com/google/example:android");
Label resourceDependency = Label.create("//com/google/example:resource");
Label resourceDependency2 = Label.create("//com/google/example:resource2");
Label transitiveResourceDependency = Label.create("//com/google/example/transitive:resource");
Label javaDependency = Label.create("//com/google/example:java");
Label transitiveJavaDependency = Label.create("//com/google/example:transitive");
Label sharedJavaDependency = Label.create("//com/google/example:shared");
Label sharedJavaDependency2 = Label.create("//com/google/example:shared2");
Label importDependency = Label.create("//com/google/example:import");
Label transitiveImportDependency = Label.create("//com/google/example/transitive:import");
Label unrelatedJava = Label.create("//com/google/unrelated:java");
Label unrelatedAndroid = Label.create("//com/google/unrelated:android");
Label unrelatedResource = Label.create("//com/google/unrelated:resource");
AndroidResourceModuleRegistry registry = new AndroidResourceModuleRegistry();
registry.put(module, AndroidResourceModule.builder(TargetKey.forPlainTarget(mainResourceLibrary)).build());
// Not using these, but they should be in the registry.
registry.put(mock(Module.class), AndroidResourceModule.builder(TargetKey.forPlainTarget(resourceDependency)).build());
registry.put(mock(Module.class), AndroidResourceModule.builder(TargetKey.forPlainTarget(resourceDependency2)).build());
registry.put(mock(Module.class), AndroidResourceModule.builder(TargetKey.forPlainTarget(transitiveResourceDependency)).build());
registry.put(mock(Module.class), AndroidResourceModule.builder(TargetKey.forPlainTarget(unrelatedResource)).build());
registerProjectService(AndroidResourceModuleRegistry.class, registry);
return TargetMapBuilder.builder().addTarget(TargetIdeInfo.builder().setLabel(mainResourceLibrary).setKind(Kind.ANDROID_LIBRARY).setJavaInfo(javaInfoWithJars("com/google/example/libmain.jar", "com/google/example/main_resources.jar")).setAndroidInfo(androidInfoWithResourceAndJar("com.google.example.main", "com/google/example/main/res", "com/google/example/main_resources.jar")).addDependency(androidDependency).addDependency(resourceDependency).addDependency(resourceDependency2).addDependency(javaDependency).addDependency(importDependency)).addTarget(TargetIdeInfo.builder().setLabel(androidDependency).setKind(Kind.ANDROID_LIBRARY).setJavaInfo(javaInfoWithJars("com/google/example/libandroid.jar")).addDependency(transitiveResourceDependency)).addTarget(TargetIdeInfo.builder().setLabel(resourceDependency).setKind(Kind.ANDROID_LIBRARY).setJavaInfo(javaInfoWithJars("com/google/example/resource.jar", "com/google/example/resource_resources.jar")).setAndroidInfo(androidInfoWithResourceAndJar("com.google.example.resource", "com/google/example/resource/res", "com/google/example/resource_resources.jar"))).addTarget(TargetIdeInfo.builder().setLabel(resourceDependency2).setKind(Kind.ANDROID_LIBRARY).setJavaInfo(javaInfoWithJars("com/google/example/resource2.jar", "com/google/example/resource2_resources.jar")).setAndroidInfo(androidInfoWithResourceAndJar("com.google.example.resource2", "com/google/example/resource2/res", "com/google/example/resource2_resources.jar"))).addTarget(TargetIdeInfo.builder().setLabel(transitiveResourceDependency).setKind(Kind.ANDROID_LIBRARY).setJavaInfo(javaInfoWithJars("com/google/example/transitive/resource.jar", "com/google/example/transitive/resource_resources.jar")).setAndroidInfo(androidInfoWithResourceAndJar("com.google.example.transitive.resource", "com/google/example/transitive/resource/res", "com/google/example/transitive/resource_resources.jar"))).addTarget(TargetIdeInfo.builder().setLabel(javaDependency).setKind(Kind.JAVA_LIBRARY).setJavaInfo(javaInfoWithJars("com/google/example/libjava.jar")).addDependency(transitiveJavaDependency).addDependency(sharedJavaDependency).addDependency(sharedJavaDependency2).addDependency(transitiveImportDependency)).addTarget(TargetIdeInfo.builder().setLabel(transitiveJavaDependency).setKind(Kind.JAVA_LIBRARY).setJavaInfo(javaInfoWithJars("com/google/example/libtransitive.jar")).addDependency(sharedJavaDependency).addDependency(sharedJavaDependency2)).addTarget(TargetIdeInfo.builder().setLabel(sharedJavaDependency).setKind(Kind.JAVA_LIBRARY).setJavaInfo(javaInfoWithJars("com/google/example/libshared.jar")).addDependency(sharedJavaDependency2)).addTarget(TargetIdeInfo.builder().setLabel(sharedJavaDependency2).setKind(Kind.JAVA_LIBRARY).setJavaInfo(javaInfoWithJars("com/google/example/libshared2.jar"))).addTarget(TargetIdeInfo.builder().setLabel(importDependency).setKind(Kind.JAVA_IMPORT).setJavaInfo(javaInfoWithCheckedInJars("com/google/example/libimport.jar"))).addTarget(TargetIdeInfo.builder().setLabel(transitiveImportDependency).setKind(Kind.JAVA_IMPORT).setJavaInfo(javaInfoWithCheckedInJars("com/google/example/transitive/libimport.jar", "com/google/example/transitive/libimport2.jar"))).addTarget(TargetIdeInfo.builder().setLabel(unrelatedJava).setKind(Kind.JAVA_LIBRARY).setJavaInfo(javaInfoWithJars("com/google/unrelated/libjava.jar"))).addTarget(TargetIdeInfo.builder().setLabel(unrelatedAndroid).setKind(Kind.ANDROID_LIBRARY).setJavaInfo(javaInfoWithJars("com/google/unrelated/libandroid.jar"))).addTarget(TargetIdeInfo.builder().setLabel(unrelatedResource).setKind(Kind.ANDROID_LIBRARY).setJavaInfo(javaInfoWithJars("com/google/unrelated/libresource.jar", "com/google/unrelated/resource_resources.jar")).setAndroidInfo(androidInfoWithResourceAndJar("com.google.unrelated.resource", "com/google/unrelated/resource/res", "com/google/unrelated/resource_resources.jar"))).build();
}
use of com.google.idea.blaze.android.sync.model.AndroidResourceModuleRegistry in project intellij by bazelbuild.
the class BlazeBuildSystemServiceTest method createMocksForAddDependency.
private void createMocksForAddDependency(Container applicationServices, Container projectServices) {
projectServices.register(BlazeProjectDataManager.class, new MockBlazeProjectDataManager(createMockBlazeProjectData()));
projectServices.register(FileEditorManager.class, mock(FileEditorManager.class));
projectServices.register(BuildReferenceManager.class, mock(BuildReferenceManager.class));
projectServices.register(LazyRangeMarkerFactory.class, mock(LazyRangeMarkerFactoryImpl.class));
applicationServices.register(VirtualFileSystemProvider.class, new MockVirtualFileSystemProvider("/foo/BUILD"));
AndroidResourceModuleRegistry moduleRegistry = new AndroidResourceModuleRegistry();
moduleRegistry.put(module, AndroidResourceModule.builder(TargetKey.forPlainTarget(Label.create("//foo:bar"))).build());
projectServices.register(AndroidResourceModuleRegistry.class, moduleRegistry);
}
Aggregations