<commit_before>library pana.platform;

import 'dart:collection';
import 'package:source_gen/generators/json_serializable.dart';

import 'pubspec.dart';

part 'platform.g.dart';

class PubspecPlatform {
  final String description;

  static const PubspecPlatform flutter = const PubspecPlatform._('flutter');

  static const PubspecPlatform undefined = const PubspecPlatform._('undefined');

  bool get isFlutter => description == flutter.description;

  const PubspecPlatform._(this.description);

  factory PubspecPlatform.fromJson(String value) {
    switch (value) {
      case 'flutter':
        return flutter;
      case 'undefined':
        return undefined;
      default:
        throw new ArgumentError.value(value, 'value', 'Not a supported value.');
    }
  }

  String toJson() => description;

  String toString() => 'PubspecPlatform: $description';
}

abstract class PlatformFlags {
  /// Denotes a package that references Flutter in `pubspec.yaml`.
  static const String flutter = 'flutter';

  /// Denotes a library that depends on a native extensions via `dart-ext:`
  static const String dartExtension = 'dart-ext';
}

@JsonSerializable()
class PlatformSummary extends Object with _$PlatformSummarySerializerMixin {
  final PubspecPlatform pubspec;
  final Map<String, PlatformInfo> libraries;

  PlatformSummary(this.pubspec, this.libraries);

  factory PlatformSummary.fromJson(Map<String, dynamic> json) =>
      _$PlatformSummaryFromJson(json);

  bool get hasConflict =>
      libraries.values.any((p) => p.hasConflict) || _conflictsFlutter;

  bool get _conflictsFlutter =>
      pubspec.isFlutter && libraries.values.any((p) => !p.worksOnFlutter);
}

@JsonSerializable()
class PlatformInfo extends Object with _$PlatformInfoSerializerMixin {
  final List<String> uses;

  PlatformInfo._(this.uses);

  factory PlatformInfo(Iterable<String> uses) =>
      new PlatformInfo._((uses?.toList() ?? <String>[])..sort());

  factory PlatformInfo.fromJson(Map<String, dynamic> map) =>
      _$PlatformInfoFromJson(map);

  bool get hasConflict =>
      (!worksAnywhere) ||
      (uses.contains(PlatformFlags.flutter) && !worksOnFlutter) ||
      (uses.contains(PlatformFlags.dartExtension) && !worksOnServer);

  bool get worksEverywhere => worksOnWeb && worksOnServer && worksOnFlutter;

  bool get worksAnywhere => worksOnWeb || worksOnServer || worksOnFlutter;

  bool get worksOnWeb =>
      _hasNoUseOf(
          [PlatformFlags.flutter, 'dart:ui', PlatformFlags.dartExtension]) &&
      (_webPackages.any(uses.contains) || _hasNoUseOf(['dart:io']));

  bool get worksOnServer =>
      _hasNoUseOf(_webAnd(['dart:ui', PlatformFlags.flutter]));

  bool get worksOnFlutter => _hasNoUseOf(_webAnd([
        'dart:mirrors',
        PlatformFlags.dartExtension,
      ]));

  String get description {
    if (worksEverywhere) {
      return 'everywhere';
    }

    var items = <String>[];
    if (worksOnFlutter) {
      items.add('flutter');
    }

    if (worksOnServer) {
      items.add('server');
    }

    if (worksOnWeb) {
      items.add('web');
    }

    if (items.isEmpty) {
      assert(hasConflict);
      return 'conflict';
    }

    return items.join(', ');
  }

  @override
  String toString() => 'PlatformInfo: $description';

  bool _hasNoUseOf(Iterable<String> platforms) =>
      !platforms.any((p) => uses.contains(p));
}

PlatformInfo classifyPubspec(Pubspec pubspec) {
  var uses = new Set<String>();
  if (pubspec.hasFlutterKey || pubspec.dependsOnFlutterSdk) {
    uses.add(PlatformFlags.flutter);
  }
  return new PlatformInfo(uses);
}

PlatformSummary classifyPlatforms(
    Pubspec pubspec, Map<String, List<String>> transitiveLibs) {
  var package = classifyPubspec(pubspec);
  return new PlatformSummary(<commit_msg>Start describing packages<commit_after>library pana.platform;

import 'dart:collection';
import 'package:source_gen/generators/json_serializable.dart';

import 'pubspec.dart';

part 'platform.g.dart';

class PubspecPlatform {
  final String description;

  static const PubspecPlatform flutter = const PubspecPlatform._('flutter');

  static const PubspecPlatform undefined = const PubspecPlatform._('undefined');

  bool get isFlutter => description == flutter.description;

  const PubspecPlatform._(this.description);

  factory PubspecPlatform.fromJson(String value) {
    switch (value) {
      case 'flutter':
        return flutter;
      case 'undefined':
        return undefined;
      default:
        throw new ArgumentError.value(value, 'value', 'Not a supported value.');
    }
  }

  String toJson() => description;

  String toString() => 'PubspecPlatform: $description';
}

abstract class PlatformFlags {
  /// Denotes a package that references Flutter in `pubspec.yaml`.
  static const String flutter = 'flutter';

  /// Denotes a library that depends on a native extensions via `dart-ext:`
  static const String dartExtension = 'dart-ext';
}

@JsonSerializable()
class PlatformSummary extends Object with _$PlatformSummarySerializerMixin {
  final PubspecPlatform pubspec;
  final Map<String, PlatformInfo> libraries;

  PlatformSummary(this.pubspec, this.libraries);

  factory PlatformSummary.fromJson(Map<String, dynamic> json) =>
      _$PlatformSummaryFromJson(json);

  bool get hasConflict =>
      libraries.values.any((p) => p.hasConflict) || _conflictsFlutter;

  bool get _conflictsFlutter =>
      pubspec.isFlutter && libraries.values.any((p) => !p.worksOnFlutter);

  String get description {
    if (pubspec.isFlutter) {
      if (libraries.values.every((pi) => pi.worksOnFlutter)) {
        return 'flutter';
      }
      assert(hasConflict);
      return 'conflict';
    }

    assert(pubspec == PubspecPlatform.undefined);

    var items = libraries.values.expand((pi) => pi.descriptionSet).toSet();

    // TODO(kevmoo) – the comma thing is a hack!
    if (items.length == 1) {
      return items.single;
    }

    return "Unclear...";
  }
}

@JsonSerializable()
class PlatformInfo extends Object with _$PlatformInfoSerializerMixin {
  final List<String> uses;

  PlatformInfo._(this.uses);

  factory PlatformInfo(Iterable<String> uses) =>
      new PlatformInfo._((uses?.toList() ?? <String>[])..sort());

  factory PlatformInfo.fromJson(Map<String, dynamic> map) =>
      _$PlatformInfoFromJson(map);

  bool get hasConflict =>
      (!worksAnywhere) ||
      (uses.contains(PlatformFlags.flutter) && !worksOnFlutter) ||
      (uses.contains(PlatformFlags.dartExtension) && !worksOnServer);

  bool get worksEverywhere => worksOnWeb && worksOnServer && worksOnFlutter;

  bool get worksAnywhere => worksOnWeb || worksOnServer || worksOnFlutter;

  bool get worksOnWeb =>
      _hasNoUseOf(
          [PlatformFlags.flutter, 'dart:ui', PlatformFlags.dartExtension]) &&
      (_webPackages.any(uses.contains) || _hasNoUseOf(['dart:io']));

  bool get worksOnServer =>
      _hasNoUseOf(_webAnd(['dart:ui', PlatformFlags.flutter]));

  bool get worksOnFlutter => _hasNoUseOf(_webAnd([
        'dart:mirrors',
        PlatformFlags.dartExtension,
      ]));

  Set<String> get descriptionSet {
    if (worksEverywhere) {
      return new Set.from(['everywhere']);
    }

    var items = <String>[];
    if (worksOnFlutter) {
      items.add('flutter');
    }

    if (worksOnServer) {
      items.add('server');
    }

    if (worksOnWeb) {
      items.add('web');
    }

    if (items.isEmpty) {
      assert(hasConflict);
      return new Set.from(['conflict']);
    }

    assert(!hasConflict);

    return (items..sort()).toSet();
  }

  String get description => descriptionSet.join(', ');

  @override
  String toString() => 'PlatformInfo: $description';

  bool _hasNoUseOf(Iterable<String> platforms) =>
      !platforms.any((p) => uses.contains(p));
}

PubspecPlatform classifyPubspec(Pubspec pubspec) {
  if (pubspec.hasFlutterKey || pubspec.dependsOnFlutterSdk) {
    return PubspecPlatform.flutter;
  }
  return PubspecPlatform.undefined;
}

PlatformSummary classifyPlatforms(
    Pubspec pubspec, Map<String, List<String>> transitiveLibs) {
  var package = classifyPubspec(pubspec);
  return new PlatformSummary(
{'fraction_non_alphanumeric': 0.12519985241667692, 'fraction_numerical': 0.00012298610257040955, 'mean_word_length': 3.881152460984394, 'pattern_counts': {'":': 0, '<': 25, '<?xml version=': 0, '>': 66, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2091800', 'n_tokens_mistral': 2496, 'n_tokens_neox': 2409, 'n_words': 544}