diff --git a/tools/external_crates/Cargo.toml b/tools/external_crates/Cargo.toml index 4ee0bfd765c..4e4c64413bf 100644 --- a/tools/external_crates/Cargo.toml +++ b/tools/external_crates/Cargo.toml @@ -6,7 +6,6 @@ members = [ "google_metadata", "license_checker", "name_and_version", - "name_and_version_proc_macros", "repo_config", "rooted_path", "test_mapping", diff --git a/tools/external_crates/cargo_embargo.json b/tools/external_crates/cargo_embargo.json index b515b5f64c7..ccaf13c5f26 100644 --- a/tools/external_crates/cargo_embargo.json +++ b/tools/external_crates/cargo_embargo.json @@ -17,9 +17,6 @@ "name_and_version": { "device_supported": false }, - "name_and_version_proc_macros": { - "device_supported": false - }, "repo_config": { "device_supported": false } diff --git a/tools/external_crates/crate_tool/Cargo.toml b/tools/external_crates/crate_tool/Cargo.toml index d49dfd080fb..5f27d907553 100644 --- a/tools/external_crates/crate_tool/Cargo.toml +++ b/tools/external_crates/crate_tool/Cargo.toml @@ -29,7 +29,6 @@ crate_config = { path = "../crate_config" } google_metadata = { path = "../google_metadata"} license_checker = { path = "../license_checker", features = ["fuzzy_content_match"] } name_and_version = { path = "../name_and_version" } -name_and_version_proc_macros = { path = "../name_and_version_proc_macros" } repo_config = { path = "../repo_config" } rooted_path = { path = "../rooted_path" } test_mapping = { path = "../test_mapping" } diff --git a/tools/external_crates/crate_tool/src/crate_collection.rs b/tools/external_crates/crate_tool/src/crate_collection.rs index f1255f33130..50fb29ad698 100644 --- a/tools/external_crates/crate_tool/src/crate_collection.rs +++ b/tools/external_crates/crate_tool/src/crate_collection.rs @@ -13,23 +13,18 @@ // limitations under the License. use name_and_version::{NameAndVersion, NameAndVersionMap, NamedAndVersioned}; -use name_and_version_proc_macros::NameAndVersionMap; use rooted_path::RootedPath; -use std::{ - collections::HashSet, - path::{Path, PathBuf}, -}; +use std::path::{Path, PathBuf}; use anyhow::{anyhow, Result}; -use semver::Version; use walkdir::WalkDir; use crate::{crate_type::Crate, CrateError}; use std::collections::BTreeMap; -#[derive(NameAndVersionMap, Debug)] +#[derive(Debug)] pub struct CrateCollection { crates: BTreeMap, repo_root: PathBuf, @@ -64,4 +59,22 @@ impl CrateCollection { } Ok(()) } + pub fn len(&self) -> usize { + self.crates.len() + } + pub fn get(&self, nv: &dyn NamedAndVersioned) -> Option<&Crate> { + self.crates.get(nv) + } + pub fn values(&self) -> impl Iterator { + self.crates.values() + } + pub fn get_versions( + &self, + crate_name: impl AsRef, + ) -> Box + '_> { + self.crates.get_versions(crate_name.as_ref()) + } + pub fn contains_crate(&self, crate_name: impl AsRef) -> bool { + self.crates.contains_name(crate_name.as_ref()) + } } diff --git a/tools/external_crates/crate_tool/src/managed_repo.rs b/tools/external_crates/crate_tool/src/managed_repo.rs index d0c9e0bbfcc..7b259c5312e 100644 --- a/tools/external_crates/crate_tool/src/managed_repo.rs +++ b/tools/external_crates/crate_tool/src/managed_repo.rs @@ -106,7 +106,6 @@ impl ManagedRepo { let cc = self.legacy_crates_for(crate_name)?; let nv = NameAndVersionRef::new(crate_name, v); Ok(cc - .map_field() .get(&nv as &dyn NamedAndVersioned) .ok_or(anyhow!("Failed to find crate {} v{}", crate_name, v))? .path() @@ -165,7 +164,7 @@ impl ManagedRepo { let krate = match version { Some(v) => { let nv = NameAndVersionRef::new(crate_name, v); - match cc.map_field().get(&nv as &dyn NamedAndVersioned) { + match cc.get(&nv as &dyn NamedAndVersioned) { Some(k) => k, None => { return Err(anyhow!("Did not find crate {} v{}", crate_name, v)); @@ -173,7 +172,7 @@ impl ManagedRepo { } } None => { - if cc.map_field().len() != 1 { + if cc.len() != 1 { return Err(anyhow!( "Expected a single crate version for {}, but found {}. Specify a version with --versions={}=", crate_name, @@ -181,7 +180,7 @@ impl ManagedRepo { crate_name )); } - cc.map_field().values().next().unwrap() + cc.values().next().unwrap() } }; println!("Found {} v{} in {}", krate.name(), krate.version(), krate.path()); @@ -428,12 +427,12 @@ impl ManagedRepo { let mut found_problems = false; for (dep, req) in version.android_deps_with_version_reqs() { println!("Found dep {}", dep.crate_name()); - let cc = if managed_crates.contains_name(dep.crate_name()) { + let cc = if managed_crates.contains_crate(dep.crate_name()) { &managed_crates } else { &legacy_crates }; - if !cc.contains_name(dep.crate_name()) { + if !cc.contains_crate(dep.crate_name()) { found_problems = true; println!( " Dep {} {} has not been imported to Android", @@ -701,7 +700,7 @@ impl ManagedRepo { let mut cc = self.new_cc(); cc.add_from(self.managed_dir().rel())?; - for krate in cc.map_field().values() { + for krate in cc.values() { let cio_crate = self.crates_io.get_crate(krate.name())?; let upgrades = cio_crate.versions_gt(krate.version()).map(|v| v.version()).collect::>(); @@ -776,12 +775,12 @@ impl ManagedRepo { // * If a dep is missing, but the same dep exists for the current version of the crate, it's probably not actually necessary. // * Use relaxed version requirements, treating 0.x and 0.y as compatible, even though they aren't according to semver rules. for (dep, req) in version.android_deps_with_version_reqs() { - let cc = if managed_crates.contains_name(dep.crate_name()) { + let cc = if managed_crates.contains_crate(dep.crate_name()) { &managed_crates } else { &legacy_crates }; - if !cc.contains_name(dep.crate_name()) { + if !cc.contains_crate(dep.crate_name()) { found_problems = true; println!( " Dep {} {} has not been imported to Android", @@ -831,7 +830,7 @@ impl ManagedRepo { managed_crates.add_from(self.managed_dir().rel())?; let legacy_crates = self.legacy_crates()?; - for krate in managed_crates.map_field().values() { + for krate in managed_crates.values() { let cio_crate = self.crates_io.get_crate(krate.name())?; let base_version = cio_crate.get_version(krate.version()); @@ -869,7 +868,7 @@ impl ManagedRepo { if !dep.is_changed_dep(&base_deps) { return false; } - let cc = if managed_crates.contains_name(dep.crate_name()) { + let cc = if managed_crates.contains_crate(dep.crate_name()) { &managed_crates } else { &legacy_crates diff --git a/tools/external_crates/name_and_version_proc_macros/Android.bp b/tools/external_crates/name_and_version_proc_macros/Android.bp deleted file mode 100644 index aadadaebd60..00000000000 --- a/tools/external_crates/name_and_version_proc_macros/Android.bp +++ /dev/null @@ -1,23 +0,0 @@ -// This file is generated by cargo_embargo. -// Do not modify this file after the first "rust_*" or "genrule" module -// because the changes will be overridden on upgrade. -// Content before the first "rust_*" or "genrule" module is preserved. - -package { - default_team: "trendy_team_android_rust", - default_applicable_licenses: ["Android-Apache-2.0"], -} - -rust_proc_macro { - name: "libname_and_version_proc_macros", - crate_name: "name_and_version_proc_macros", - cargo_env_compat: true, - cargo_pkg_version: "0.1.0", - crate_root: "src/lib.rs", - edition: "2021", - rustlibs: [ - "libproc_macro2", - "libquote", - "libsyn", - ], -} diff --git a/tools/external_crates/name_and_version_proc_macros/Cargo.toml b/tools/external_crates/name_and_version_proc_macros/Cargo.toml deleted file mode 100644 index 1f728362bd3..00000000000 --- a/tools/external_crates/name_and_version_proc_macros/Cargo.toml +++ /dev/null @@ -1,12 +0,0 @@ -[package] -name = "name_and_version_proc_macros" -version = "0.1.0" -edition = "2021" - -[lib] -proc-macro = true - -[dependencies] -proc-macro2 = "1" -syn = "2.0" -quote = "1.0" diff --git a/tools/external_crates/name_and_version_proc_macros/src/lib.rs b/tools/external_crates/name_and_version_proc_macros/src/lib.rs deleted file mode 100644 index 832b2c1874e..00000000000 --- a/tools/external_crates/name_and_version_proc_macros/src/lib.rs +++ /dev/null @@ -1,124 +0,0 @@ -// Copyright (C) 2023 The Android Open Source Project -// -// 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. - -//! Derive the NameAndVersionMap trait for a struct with a suitable map field. - -use syn::{parse_macro_input, DeriveInput, Error}; - -/// Derive the NameAndVersionMap trait for a struct with a suitable map field. -#[proc_macro_derive(NameAndVersionMap)] -pub fn derive_name_and_version_map(input: proc_macro::TokenStream) -> proc_macro::TokenStream { - let input = parse_macro_input!(input as DeriveInput); - name_and_version_map::expand(input).unwrap_or_else(Error::into_compile_error).into() -} - -mod name_and_version_map { - use proc_macro2::TokenStream; - use quote::quote; - use syn::{ - Data, DataStruct, DeriveInput, Error, Field, GenericArgument, PathArguments, Result, Type, - }; - - pub(crate) fn expand(input: DeriveInput) -> Result { - let name = &input.ident; - let (impl_generics, ty_generics, where_clause) = input.generics.split_for_impl(); - - let mapfield = get_map_field(get_struct(&input)?)?; - let mapfield_name = mapfield - .ident - .as_ref() - .ok_or(Error::new_spanned(mapfield, "mapfield ident is none"))?; - let (_, value_type) = get_map_type(&mapfield.ty)?; - - let expanded = quote! { - #[automatically_derived] - impl #impl_generics NameAndVersionMap for #name #ty_generics #where_clause { - type Value = #value_type; - - fn map_field(&self) -> &BTreeMap { - self.#mapfield_name.map_field() - } - - fn map_field_mut(&mut self) -> &mut BTreeMap { - self.#mapfield_name.map_field_mut() - } - - fn insert_or_error(&mut self, key: NameAndVersion, val: Self::Value) -> Result<(), name_and_version::Error> { - self.#mapfield_name.insert_or_error(key, val) - } - - fn num_crates(&self) -> usize { - self.#mapfield_name.num_crates() - } - - fn get_versions<'a, 'b>(&'a self, name: &'b str) -> Box + 'a> { - self.#mapfield_name.get_versions(name) - } - - fn get_versions_mut<'a, 'b>(&'a mut self, name: &'b str) -> Box + 'a> { - self.#mapfield_name.get_versions_mut(name) - } - - fn filter_versions<'a: 'b, 'b, F: Fn(&mut dyn Iterator, - ) -> HashSet + 'a>( - &'a self, - f: F, - ) -> Box + 'a> { - self.#mapfield_name.filter_versions(f) - } - } - }; - - Ok(expanded) - } - - fn get_struct(input: &DeriveInput) -> Result<&DataStruct> { - match &input.data { - Data::Struct(strukt) => Ok(strukt), - _ => Err(Error::new_spanned(input, "Not a struct")), - } - } - - fn get_map_field(strukt: &DataStruct) -> Result<&Field> { - for field in &strukt.fields { - if let Ok((syn::Type::Path(path), _value_type)) = get_map_type(&field.ty) { - if path.path.segments.len() == 1 && path.path.segments[0].ident == "NameAndVersion" - { - return Ok(field); - } - } - } - Err(Error::new_spanned(strukt.struct_token, "No field of type NameAndVersionMap")) - } - - fn get_map_type(typ: &Type) -> Result<(&Type, &Type)> { - if let syn::Type::Path(path) = &typ { - if path.path.segments.len() == 1 && path.path.segments[0].ident == "BTreeMap" { - if let PathArguments::AngleBracketed(args) = &path.path.segments[0].arguments { - if args.args.len() == 2 { - return Ok((get_type(&args.args[0])?, get_type(&args.args[1])?)); - } - } - } - } - Err(Error::new_spanned(typ, "Must be BTreeMap")) - } - - fn get_type(arg: &GenericArgument) -> Result<&Type> { - if let GenericArgument::Type(typ) = arg { - return Ok(typ); - } - Err(Error::new_spanned(arg, "Could not extract argument type")) - } -}