static NameAndIndex[] ReadNames(ref DataReader reader, IPEImage peImage, int numNames, uint offsetOfNames, uint offsetOfNameIndexes) { var names = new NameAndIndex[numNames]; reader.Position = offsetOfNameIndexes; for (int i = 0; i < names.Length; i++) { names[i].Index = reader.ReadUInt16(); } var currentOffset = offsetOfNames; for (int i = 0; i < names.Length; i++, currentOffset += 4) { reader.Position = currentOffset; uint offsetOfName = (uint)peImage.ToFileOffset((RVA)reader.ReadUInt32()); names[i].Name = ReadMethodNameASCIIZ(ref reader, offsetOfName); } return(names); }
internal AnonymousTypeTemplateSymbol(AnonymousTypeManager manager, AnonymousTypeDescriptor typeDescr) { this.Manager = manager; this.TypeDescriptorKey = typeDescr.Key; _smallestLocation = typeDescr.Location; // Will be set when the type's metadata is ready to be emitted, // <anonymous-type>.Name will throw exception if requested // before that moment. _nameAndIndex = null; int fieldsCount = typeDescr.Fields.Length; // members Symbol[] members = new Symbol[fieldsCount * 3 + 1]; int memberIndex = 0; // The array storing property symbols to be used in // generation of constructor and other methods if (fieldsCount > 0) { AnonymousTypePropertySymbol[] propertiesArray = new AnonymousTypePropertySymbol[fieldsCount]; TypeParameterSymbol[] typeParametersArray = new TypeParameterSymbol[fieldsCount]; // Process fields for (int fieldIndex = 0; fieldIndex < fieldsCount; fieldIndex++) { AnonymousTypeField field = typeDescr.Fields[fieldIndex]; // Add a type parameter AnonymousTypeParameterSymbol typeParameter = new AnonymousTypeParameterSymbol(this, fieldIndex, GeneratedNames.MakeAnonymousTypeParameterName(field.Name)); typeParametersArray[fieldIndex] = typeParameter; // Add a property AnonymousTypePropertySymbol property = new AnonymousTypePropertySymbol(this, field, TypeSymbolWithAnnotations.Create(typeParameter)); propertiesArray[fieldIndex] = property; // Property related symbols members[memberIndex++] = property; members[memberIndex++] = property.BackingField; members[memberIndex++] = property.GetMethod; } _typeParameters = typeParametersArray.AsImmutable(); this.Properties = propertiesArray.AsImmutable(); } else { _typeParameters = ImmutableArray <TypeParameterSymbol> .Empty; this.Properties = ImmutableArray <AnonymousTypePropertySymbol> .Empty; } // Add a constructor members[memberIndex++] = new AnonymousTypeConstructorSymbol(this, this.Properties); _members = members.AsImmutable(); Debug.Assert(memberIndex == _members.Length); // fill nameToSymbols map foreach (var symbol in _members) { _nameToSymbols.Add(symbol.Name, symbol); } // special members: Equals, GetHashCode, ToString MethodSymbol[] specialMembers = new MethodSymbol[3]; specialMembers[0] = new AnonymousTypeEqualsMethodSymbol(this); specialMembers[1] = new AnonymousTypeGetHashCodeMethodSymbol(this); specialMembers[2] = new AnonymousTypeToStringMethodSymbol(this); this.SpecialMembers = specialMembers.AsImmutable(); }
internal AnonymousTypeTemplateSymbol(AnonymousTypeManager manager, AnonymousTypeDescriptor typeDescr) { this.Manager = manager; this.TypeDescriptorKey = typeDescr.Key; _smallestLocation = typeDescr.Location; // Will be set when the type's metadata is ready to be emitted, // <anonymous-type>.Name will throw exception if requested // before that moment. _nameAndIndex = null; int fieldsCount = typeDescr.Fields.Length; // members Symbol[] members = new Symbol[fieldsCount * 3 + 1]; int memberIndex = 0; // The array storing property symbols to be used in // generation of constructor and other methods if (fieldsCount > 0) { AnonymousTypePropertySymbol[] propertiesArray = new AnonymousTypePropertySymbol[fieldsCount]; TypeParameterSymbol[] typeParametersArray = new TypeParameterSymbol[fieldsCount]; // Process fields for (int fieldIndex = 0; fieldIndex < fieldsCount; fieldIndex++) { AnonymousTypeField field = typeDescr.Fields[fieldIndex]; // Add a type parameter AnonymousTypeParameterSymbol typeParameter = new AnonymousTypeParameterSymbol(this, fieldIndex, GeneratedNames.MakeAnonymousTypeParameterName(field.Name)); typeParametersArray[fieldIndex] = typeParameter; // Add a property AnonymousTypePropertySymbol property = new AnonymousTypePropertySymbol(this, field, typeParameter); propertiesArray[fieldIndex] = property; // Property related symbols members[memberIndex++] = property; members[memberIndex++] = property.BackingField; members[memberIndex++] = property.GetMethod; } _typeParameters = typeParametersArray.AsImmutable(); this.Properties = propertiesArray.AsImmutable(); } else { _typeParameters = ImmutableArray<TypeParameterSymbol>.Empty; this.Properties = ImmutableArray<AnonymousTypePropertySymbol>.Empty; } // Add a constructor members[memberIndex++] = new AnonymousTypeConstructorSymbol(this, this.Properties); _members = members.AsImmutable(); Debug.Assert(memberIndex == _members.Length); // fill nameToSymbols map foreach (var symbol in _members) { _nameToSymbols.Add(symbol.Name, symbol); } // special members: Equals, GetHashCode, ToString MethodSymbol[] specialMembers = new MethodSymbol[3]; specialMembers[0] = new AnonymousTypeEqualsMethodSymbol(this); specialMembers[1] = new AnonymousTypeGetHashCodeMethodSymbol(this); specialMembers[2] = new AnonymousTypeToStringMethodSymbol(this); this.SpecialMembers = specialMembers.AsImmutable(); }
internal AnonymousTypeTemplateSymbol(AnonymousTypeManager manager, AnonymousTypeDescriptor typeDescr) { this.Manager = manager; this.TypeDescriptorKey = typeDescr.Key; _smallestLocation = typeDescr.Location; // Will be set when the type's metadata is ready to be emitted, // <anonymous-type>.Name will throw exception if requested // before that moment. _nameAndIndex = null; #if XSHARP IsCodeblock = typeDescr.Fields.Length > 0 && typeDescr.Fields[0].Name.StartsWith("Cb$Param$"); _baseType = IsCodeblock ? manager.CodeblockType : manager.System_Object; if (IsCodeblock) { _baseType = manager.CodeblockType; int cbParamCount = typeDescr.Fields.Length; NamedTypeSymbol[] cbParameters = new NamedTypeSymbol[cbParamCount]; for (int i = 0; i < cbParamCount; i++) { cbParameters[i] = manager.UsualType; } var cbDelegate = manager.SynthesizeDelegate(typeDescr.Fields.Length - 1, default(BitVector), false, 0).Construct(cbParameters); Symbol[] cbMembers = new Symbol[7]; int cbMemberIndex = 0; var eval = new AnonymousTypePropertySymbol(this, new AnonymousTypeField("Cb$Eval$", typeDescr.Location, cbDelegate), cbDelegate); var source = new AnonymousTypePropertySymbol(this, new AnonymousTypeField("Cb$Src$", typeDescr.Location, manager.System_String), manager.System_String); this.Properties = new[] { source }.ToImmutableArray(); // Property related symbols cbMembers[cbMemberIndex++] = eval; cbMembers[cbMemberIndex++] = eval.BackingField; cbMembers[cbMemberIndex++] = eval.GetMethod; cbMembers[cbMemberIndex++] = source; cbMembers[cbMemberIndex++] = source.BackingField; cbMembers[cbMemberIndex++] = source.GetMethod; cbMembers[cbMemberIndex++] = new AnonymousTypeConstructorSymbol(this, new[] { eval, source }.ToImmutableArray()); _typeParameters = ImmutableArray <TypeParameterSymbol> .Empty; _members = cbMembers.AsImmutable(); Debug.Assert(cbMemberIndex == _members.Length); // fill nameToSymbols map foreach (var symbol in _members) { _nameToSymbols.Add(symbol.Name, symbol); } MethodSymbol[] cbSpecialMembers = new MethodSymbol[2]; cbSpecialMembers[0] = new CodeblockEvalMethod(this); cbSpecialMembers[1] = new AnonymousTypeToStringMethodSymbol(this); this.SpecialMembers = cbSpecialMembers.AsImmutable(); return; } _baseType = manager.System_Object; #endif int fieldsCount = typeDescr.Fields.Length; // members Symbol[] members = new Symbol[fieldsCount * 3 + 1]; int memberIndex = 0; // The array storing property symbols to be used in // generation of constructor and other methods if (fieldsCount > 0) { AnonymousTypePropertySymbol[] propertiesArray = new AnonymousTypePropertySymbol[fieldsCount]; TypeParameterSymbol[] typeParametersArray = new TypeParameterSymbol[fieldsCount]; // Process fields for (int fieldIndex = 0; fieldIndex < fieldsCount; fieldIndex++) { AnonymousTypeField field = typeDescr.Fields[fieldIndex]; // Add a type parameter AnonymousTypeParameterSymbol typeParameter = new AnonymousTypeParameterSymbol(this, fieldIndex, GeneratedNames.MakeAnonymousTypeParameterName(field.Name)); typeParametersArray[fieldIndex] = typeParameter; // Add a property AnonymousTypePropertySymbol property = new AnonymousTypePropertySymbol(this, field, typeParameter); propertiesArray[fieldIndex] = property; // Property related symbols members[memberIndex++] = property; members[memberIndex++] = property.BackingField; members[memberIndex++] = property.GetMethod; } _typeParameters = typeParametersArray.AsImmutable(); this.Properties = propertiesArray.AsImmutable(); } else { _typeParameters = ImmutableArray <TypeParameterSymbol> .Empty; this.Properties = ImmutableArray <AnonymousTypePropertySymbol> .Empty; } // Add a constructor members[memberIndex++] = new AnonymousTypeConstructorSymbol(this, this.Properties); _members = members.AsImmutable(); Debug.Assert(memberIndex == _members.Length); // fill nameToSymbols map foreach (var symbol in _members) { _nameToSymbols.Add(symbol.Name, symbol); } // special members: Equals, GetHashCode, ToString MethodSymbol[] specialMembers = new MethodSymbol[3]; specialMembers[0] = new AnonymousTypeEqualsMethodSymbol(this); specialMembers[1] = new AnonymousTypeGetHashCodeMethodSymbol(this); specialMembers[2] = new AnonymousTypeToStringMethodSymbol(this); this.SpecialMembers = specialMembers.AsImmutable(); }
internal AnonymousTypeTemplateSymbol(AnonymousTypeManager manager, AnonymousTypeDescriptor typeDescr) { this.Manager = manager; this.TypeDescriptorKey = typeDescr.Key; _smallestLocation = typeDescr.Location; // Will be set when the type's metadata is ready to be emitted, // <anonymous-type>.Name will throw exception if requested // before that moment. _nameAndIndex = null; int fieldsCount = typeDescr.Fields.Length; int membersCount = fieldsCount * 3 + 1; // members var membersBuilder = ArrayBuilder <Symbol> .GetInstance(membersCount); var propertiesBuilder = ArrayBuilder <AnonymousTypePropertySymbol> .GetInstance(fieldsCount); var typeParametersBuilder = ArrayBuilder <TypeParameterSymbol> .GetInstance(fieldsCount); // Process fields for (int fieldIndex = 0; fieldIndex < fieldsCount; fieldIndex++) { AnonymousTypeField field = typeDescr.Fields[fieldIndex]; // Add a type parameter AnonymousTypeParameterSymbol typeParameter = new AnonymousTypeParameterSymbol(this, fieldIndex, GeneratedNames.MakeAnonymousTypeParameterName(field.Name)); typeParametersBuilder.Add(typeParameter); // Add a property AnonymousTypePropertySymbol property = new AnonymousTypePropertySymbol(this, field, TypeWithAnnotations.Create(typeParameter), fieldIndex); propertiesBuilder.Add(property); // Property related symbols membersBuilder.Add(property); membersBuilder.Add(property.BackingField); membersBuilder.Add(property.GetMethod); } _typeParameters = typeParametersBuilder.ToImmutableAndFree(); this.Properties = propertiesBuilder.ToImmutableAndFree(); // Add a constructor membersBuilder.Add(new AnonymousTypeConstructorSymbol(this, this.Properties)); _members = membersBuilder.ToImmutableAndFree(); Debug.Assert(membersCount == _members.Length); // fill nameToSymbols map foreach (var symbol in _members) { _nameToSymbols.Add(symbol.Name, symbol); } // special members: Equals, GetHashCode, ToString this.SpecialMembers = ImmutableArray.Create <MethodSymbol>( new AnonymousTypeEqualsMethodSymbol(this), new AnonymousTypeGetHashCodeMethodSymbol(this), new AnonymousTypeToStringMethodSymbol(this)); }
// An html file might have other files it references, so do a recursive search through the archive to find // them all, and extract only the required files to the cache. That way we keep the disk footprint way down. private static void ExtractHTMLRefFiles(string fmArchivePath, string fmCachePath) { var htmlRefFiles = new List <NameAndIndex>(); using var archive = new ZipArchive(new FileStream(fmArchivePath, FileMode.Open, FileAccess.Read), ZipArchiveMode.Read, leaveOpen: false); foreach (string f in Directory.GetFiles(fmCachePath, "*", SearchOption.AllDirectories)) { if (!f.ExtIsHtml()) { continue; } string html = File.ReadAllText(f); for (int i = 0; i < archive.Entries.Count; i++) { var e = archive.Entries[i]; if (e.Name.IsEmpty() || !e.Name.Contains('.') || HTMLRefExcludes.Any(e.Name.EndsWithI)) { continue; } // We just do a dumb string-match search through the whole file. While it's true that HTML // files have their links in specific structures (href tags etc.), we don't attempt to // narrow it down to these because a) we want to future-proof against any new ways to link // that might come about, and b) HTML files can link out to other formats like CSS and // who knows what else, and we don't want to write parsers for every format under the sun. if (html.ContainsI(e.Name) && htmlRefFiles.All(x => x.Index != i)) { htmlRefFiles.Add(new NameAndIndex { Index = i, Name = e.FullName }); } } } if (htmlRefFiles.Count > 0) { for (int ri = 0; ri < htmlRefFiles.Count; ri++) { NameAndIndex f = htmlRefFiles[ri]; if (HTMLRefExcludes.Any(f.Name.EndsWithI) || ImageFileExtensions.Any(f.Name.EndsWithI)) { continue; } var re = archive.Entries[f.Index]; // 128k is generous. Any text or markup sort of file should be WELL under that. if (re.Length > 131_072) { continue; } string content; using (var es = re.Open()) { using var sr = new StreamReader(es); content = sr.ReadToEnd(); } for (int ei = 0; ei < archive.Entries.Count; ei++) { var e = archive.Entries[ei]; if (e.Name.IsEmpty() || !e.Name.Contains('.') || HTMLRefExcludes.Any(e.Name.EndsWithI)) { continue; } if (content.ContainsI(e.Name) && htmlRefFiles.All(x => x.Index != ei)) { htmlRefFiles.Add(new NameAndIndex { Index = ei, Name = e.FullName }); } } } } if (htmlRefFiles.Count > 0) { foreach (NameAndIndex f in htmlRefFiles) { string path = Path.GetDirectoryName(f.Name); if (!path.IsEmpty()) { Directory.CreateDirectory(Path.Combine(fmCachePath, path)); } archive.Entries[f.Index].ExtractToFile(Path.Combine(fmCachePath, f.Name), overwrite: true); } } }