@@ -116,6 +116,8 @@ const DEPRECATED_LINT_TYPE: [&str; 3] = ["clippy_lints", "deprecated_lints", "Cl
116116const APPLICABILITY_NAME_INDEX : usize = 2 ;
117117/// This applicability will be set for unresolved applicability values.
118118const APPLICABILITY_UNRESOLVED_STR : & str = "Unresolved" ;
119+ /// The version that will be displayed if none has been defined
120+ const VERION_DEFAULT_STR : & str = "Unknown" ;
119121
120122declare_clippy_lint ! {
121123 /// ### What it does
@@ -144,6 +146,7 @@ declare_clippy_lint! {
144146 /// "docs": " ### What it does\nCollects metadata about clippy lints for the website. [...] "
145147 /// }
146148 /// ```
149+ #[ clippy:: version = "0.1.56" ]
147150 pub INTERNAL_METADATA_COLLECTOR ,
148151 internal_warn,
149152 "A busy bee collection metadata about lints"
@@ -215,18 +218,27 @@ struct LintMetadata {
215218 group : String ,
216219 level : String ,
217220 docs : String ,
221+ version : String ,
218222 /// This field is only used in the output and will only be
219223 /// mapped shortly before the actual output.
220224 applicability : Option < ApplicabilityInfo > ,
221225}
222226
223227impl LintMetadata {
224- fn new ( id : String , id_span : SerializableSpan , group : String , level : & ' static str , docs : String ) -> Self {
228+ fn new (
229+ id : String ,
230+ id_span : SerializableSpan ,
231+ group : String ,
232+ level : & ' static str ,
233+ version : String ,
234+ docs : String ,
235+ ) -> Self {
225236 Self {
226237 id,
227238 id_span,
228239 group,
229240 level : level. to_string ( ) ,
241+ version,
230242 docs,
231243 applicability : None ,
232244 }
@@ -410,12 +422,14 @@ impl<'hir> LateLintPass<'hir> for MetadataCollector {
410422 if let Some ( configuration_section) = self . get_lint_configs( & lint_name) {
411423 docs. push_str( & configuration_section) ;
412424 }
425+ let version = get_lint_version( cx, item) ;
413426
414427 self . lints. push( LintMetadata :: new(
415428 lint_name,
416429 SerializableSpan :: from_item( cx, item) ,
417430 group,
418431 level,
432+ version,
419433 docs,
420434 ) ) ;
421435 }
@@ -429,11 +443,14 @@ impl<'hir> LateLintPass<'hir> for MetadataCollector {
429443 // Metadata the little we can get from a deprecated lint
430444 if let Some ( docs) = extract_attr_docs_or_lint( cx, item) ;
431445 then {
446+ let version = get_lint_version( cx, item) ;
447+
432448 self . lints. push( LintMetadata :: new(
433449 lint_name,
434450 SerializableSpan :: from_item( cx, item) ,
435451 DEPRECATED_LINT_GROUP_STR . to_string( ) ,
436452 DEPRECATED_LINT_LEVEL ,
453+ version,
437454 docs,
438455 ) ) ;
439456 }
@@ -541,6 +558,28 @@ fn extract_attr_docs(cx: &LateContext<'_>, item: &Item<'_>) -> Option<String> {
541558 Some ( docs)
542559}
543560
561+ fn get_lint_version ( cx : & LateContext < ' _ > , item : & Item < ' _ > ) -> String {
562+ let attrs = cx. tcx . hir ( ) . attrs ( item. hir_id ( ) ) ;
563+ attrs
564+ . iter ( )
565+ . find_map ( |attr| {
566+ if_chain ! {
567+ // Identify attribute
568+ if let ast:: AttrKind :: Normal ( ref attr_kind, _) = & attr. kind;
569+ if let [ tool_name, attr_name] = & attr_kind. path. segments[ ..] ;
570+ if tool_name. ident. name == sym:: clippy;
571+ if attr_name. ident. name == sym:: version;
572+ if let Some ( version) = attr. value_str( ) ;
573+ then {
574+ Some ( version. as_str( ) . to_string( ) )
575+ } else {
576+ None
577+ }
578+ }
579+ } )
580+ . unwrap_or_else ( || VERION_DEFAULT_STR . to_string ( ) )
581+ }
582+
544583fn get_lint_group_and_level_or_lint (
545584 cx : & LateContext < ' _ > ,
546585 lint_name : & str ,
@@ -652,7 +691,6 @@ fn extract_emission_info<'hir>(
652691 applicability = resolve_applicability ( cx, arg) ;
653692 } else if arg_ty. is_closure ( ) {
654693 multi_part |= check_is_multi_part ( cx, arg) ;
655- // TODO xFrednet 2021-03-01: don't use or_else but rather a comparison
656694 applicability = applicability. or_else ( || resolve_applicability ( cx, arg) ) ;
657695 }
658696 }
0 commit comments