<commit_before>﻿// Copyright 2020 <NAME>.
//
// 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.

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Reflection.Metadata;
using System.Reflection.PortableExecutable;
using System.Xml;

namespace Xcst.Compiler.Reflection;

partial class MetadataManifestReader {

   const string
   _prefix = "xcst";

   const string
   _ns = XmlNamespaces.XcstGrammar;

   const string
   _packageModelNs = "Xcst.Runtime";

   static readonly ICustomAttributeTypeProvider<TypeSpec>
   _attrTypeProvider = new TypeSpecTypeProvider();

   static readonly ISignatureTypeProvider<TypeSpec, object?>
   _signatureTypeProvider = new TypeSpecSignatureTypeProvider();

   readonly MetadataReader
   _reader;

   readonly XmlWriter
   _writer;

   public static void
   ReadAssembly(Stream assemblySource, Func<string, XmlWriter> writerFn) {

      using var peReader = new PEReader(assemblySource);

      var reader = peReader.GetMetadataReader();

      foreach (var typeDef in reader.TypeDefinitions.Select(reader.GetTypeDefinition)) {

         if (!typeDef.Attributes.HasFlag(TypeAttributes.Public)) {
            continue;
         }

         if (typeDef.Attributes.HasFlag(TypeAttributes.ClassSemanticsMask)) {
            // is interface
            continue;
         }

         var isPkg =
            (from ih in typeDef.GetInterfaceImplementations()
             let i = reader.GetInterfaceImplementation(ih)
             where i.Interface.Kind == HandleKind.TypeReference
             let t = reader.GetTypeReference(((TypeReferenceHandle)i.Interface))
             select t).Any(t => reader.GetString(t.Name) == "IXcstPackage"
                && reader.GetString(t.Namespace) == "Xcst");

         if (isPkg) {

            var pkgName = reader.GetString(typeDef.Name);

            if (!typeDef.Namespace.IsNil) {
               pkgName = reader.GetString(typeDef.Namespace) + "." + pkgName;
            }

            using var writer = writerFn(pkgName);

            new MetadataManifestReader(reader, writer)
               .WritePackage(typeDef);
         }
      }
   }

   public
   MetadataManifestReader(MetadataReader reader, XmlWriter writer) {
      _reader = reader;
      _writer = writer;
   }

   void
   WritePackage(TypeDefinition typeDef) {

      _writer.WriteStartElement(_prefix, "package-manifest", _ns);
      _writer.WriteAttributeString("qualified-types", "true");
      _writer.WriteAttributeString("xmlns", "code", null, XmlNamespaces.XcstCode);
<commit_msg>fixed metadata reflection of v1 packages<commit_after>﻿// Copyright 2020 <NAME>.
//
// 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.

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Reflection.Metadata;
using System.Reflection.PortableExecutable;
using System.Xml;

namespace Xcst.Compiler.Reflection;

partial class MetadataManifestReader {

   const string
   _prefix = "xcst";

   const string
   _ns = XmlNamespaces.XcstGrammar;

   const string
   _v1PackageModelNs = "Xcst.PackageModel";

   const string
   _v2PackageModelNs = "Xcst.Runtime";

   static readonly ICustomAttributeTypeProvider<TypeSpec>
   _attrTypeProvider = new TypeSpecTypeProvider();

   static readonly ISignatureTypeProvider<TypeSpec, object?>
   _signatureTypeProvider = new TypeSpecSignatureTypeProvider();

   readonly MetadataReader
   _reader;

   readonly XmlWriter
   _writer;

   readonly string
   _packageModelNs;

   public static void
   ReadAssembly(Stream assemblySource, Func<string, XmlWriter> writerFn) {

      using var peReader = new PEReader(assemblySource);

      var reader = peReader.GetMetadataReader();

      foreach (var typeDef in reader.TypeDefinitions.Select(reader.GetTypeDefinition)) {

         if (!typeDef.Attributes.HasFlag(TypeAttributes.Public)) {
            continue;
         }

         if (typeDef.Attributes.HasFlag(TypeAttributes.ClassSemanticsMask)) {
            // is interface
            continue;
         }

         var pkgInterface =
            (from ih in typeDef.GetInterfaceImplementations()
             let i = reader.GetInterfaceImplementation(ih)
             where i.Interface.Kind == HandleKind.TypeReference
             let t = reader.GetTypeReference((TypeReferenceHandle)i.Interface)
             where reader.GetString(t.Name) == "IXcstPackage"
               && t.ResolutionScope.Kind == HandleKind.AssemblyReference
             let ar = reader.GetAssemblyReference((AssemblyReferenceHandle)t.ResolutionScope)
             where reader.GetString(ar.Name) == "Xcst.Runtime"
             let v1rt = !(ar.Version.Major >= 2)
             where reader.GetString(t.Namespace) == (v1rt ? _v1PackageModelNs : "Xcst")
             select new { v1rt }
            ).FirstOrDefault();

         if (pkgInterface != null) {

            var pkgName = reader.GetString(typeDef.Name);

            if (!typeDef.Namespace.IsNil) {
               pkgName = reader.GetString(typeDef.Namespace) + "." + pkgName;
            }

            using var writer = writerFn(pkgName);

            new MetadataManifestReader(reader, writer, pkgInterface.v1rt)
               .WritePackage(typeDef);
         }
      }
   }

   public
   MetadataManifestReader(MetadataReader reader, XmlWriter writer, bool v1rt) {

      _reader = reader;
      _writer = writer;
      _packageModelNs = (v1rt) ? _v1PackageModelNs : _v2PackageModelNs;
   }

   void
   WritePackage(TypeDefinition typeDef) {

      _writer.WriteStartElement(_prefix, "package-manifest", _ns);
      _writer.WriteAttributeString("qualified-types", "true");
      _writer.WriteAttributeString("xmlns", "code", null, XmlNamespaces.XcstCode);

{'fraction_non_alphanumeric': 0.09076456135279665, 'fraction_numerical': 0.004191357132533603, 'mean_word_length': 2.9747271682940837, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 13, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 2}, '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': '7585726', 'n_tokens_mistral': 1898, 'n_tokens_neox': 1829, 'n_words': 492}