public void TestNamespaceGenerationWithNoTypes() { // arrange var csharpNamespace = new CSharpNamespace { Name = "SuperBlogger" }; var output = new StringWriter(); var expectedOutput = "namespace SuperBlogger" + Environment.NewLine + "{" + Environment.NewLine + "}" + Environment.NewLine; // act csharpNamespace.Generate(output); // assert Assert.Equal(expectedOutput, output.ToString()); }
public void CSharpNamespaceCloneTest() { var parentPackage = new CSharpNamespace("parent"); var childPackage = new CSharpNamespace("child"); var classType1 = new CSharpClass("class1"); var classType2 = new CSharpClass("class2"); childPackage.AddNestedChild(classType1); childPackage.AddNestedChild(classType2); parentPackage.AddNestedChild(childPackage); var otherParent = parentPackage.Clone(true); var otherChild = (CSharpNamespace)parentPackage.NestedChilds.First(); otherParent.NestedChilds.Count().ShouldBe(1); otherParent.Name.ShouldBe(parentPackage.Name); otherChild.NestedChilds.Count().ShouldBe(2); otherChild.Name.ShouldBe(childPackage.Name); otherChild.NestedChilds.First().Name.ShouldBe(classType1.Name); otherChild.NestedChilds.Last().Name.ShouldBe(classType2.Name); }
public bool TryGetNamespaceReference(CSharpNamespace semanticNamespace, IAssemblyReference cciAssembly, out IUnitNamespaceReference cciNamespace) { Contract.Ensures(!Contract.Result <bool>() || (Contract.ValueAtReturn(out cciNamespace) != null)); cciNamespace = null; #region Check input if (semanticNamespace == null || cciAssembly == null) { return(false); } #endregion #region If root try { if (semanticNamespace.IsRoot) { cciNamespace = new Microsoft.Cci.MutableCodeModel.RootUnitNamespaceReference() { Unit = cciAssembly }; goto ReturnTrue; } } catch (InvalidOperationException e) { //For some reason, an InvalidOperationException may get thrown. if (e.Message.Contains(ContractsPackageAccessor.InvalidOperationExceptionMessage_TheSnapshotIsOutOfDate)) { goto ReturnFalse; } else { throw e; } } #endregion #region If nested if (semanticNamespace.ContainingNamespace != null) { IUnitNamespaceReference parentNs; if (!TryGetNamespaceReference(semanticNamespace.ContainingNamespace, cciAssembly, out parentNs)) { goto ReturnFalse; } if (semanticNamespace.Name == null) { goto ReturnFalse; } cciNamespace = new Microsoft.Cci.Immutable.NestedUnitNamespaceReference(parentNs, Host.NameTable.GetNameFor(semanticNamespace.Name.Text)); goto ReturnTrue; } #endregion Contract.Assert(cciNamespace == null); goto ReturnFalse; #region ReturnTrue: ReturnTrue: return(true); #endregion #region ReturnFalse: ReturnFalse: return(false); #endregion }
private static void GenerateDwarfAttributes(CSharpNamespace ns) { var alreadyDone = new HashSet <string>(); var csHelper = new CSharpClass("DwarfHelper") { Modifiers = CSharpModifiers.Static | CSharpModifiers.Partial, Visibility = CSharpVisibility.Public }; ns.Members.Add(csHelper); var csField = new CSharpField("AttributeToEncoding") { Modifiers = CSharpModifiers.Static | CSharpModifiers.ReadOnly, Visibility = CSharpVisibility.Private, FieldType = new CSharpArrayType(new CSharpFreeType("DwarfAttributeEncoding")) }; csHelper.Members.Add(csField); var fieldArrayBuilder = new StringBuilder(); fieldArrayBuilder.AppendLine("new DwarfAttributeEncoding[] {"); int currentAttributeIndex = 0; foreach (var attrEncoding in MapAttributeToEncoding) { var attrEncodingParts = attrEncoding.Split(' ', StringSplitOptions.RemoveEmptyEntries); var attributeName = attrEncodingParts[0]; var attributeIndex = int.Parse(attrEncodingParts[1].Substring(2), System.Globalization.NumberStyles.HexNumber); var rawName = attributeName.Substring("DW_AT_".Length); //var csharpName = CSharpifyName(rawName); string attrType = "object"; var kind = AttributeKind.Managed; if (attributeName == "DW_AT_accessibility") { attrType = "DwarfAccessibility"; kind = AttributeKind.ValueType; } else if (attributeName == "DW_AT_visibility") { attrType = "DwarfVisibility"; kind = AttributeKind.ValueType; } else if (attributeName == "DW_AT_virtuality") { attrType = "DwarfVirtuality"; kind = AttributeKind.ValueType; } else if (attributeName == "DW_AT_language") { attrType = "DwarfLanguageKind"; kind = AttributeKind.ValueType; } else if (attributeName == "DW_AT_identifier_case") { attrType = "DwarfIdentifierCaseKind"; kind = AttributeKind.ValueType; } else if (attributeName == "DW_AT_calling_convention") { attrType = "DwarfCallingConvention"; kind = AttributeKind.ValueType; } else if (attributeName == "DW_AT_inline") { attrType = "DwarfInlineKind"; kind = AttributeKind.ValueType; } else if (attributeName == "DW_AT_ordering") { attrType = "DwarfArrayOrderingKind"; kind = AttributeKind.ValueType; } else if (attributeName == "DW_AT_discr_list") { attrType = "DwarfDiscriminantListKind"; kind = AttributeKind.ValueType; } else if (attrEncodingParts.Length == 3) { switch (attrEncodingParts[2]) { case "string": attrType = "string"; break; case "flag": attrType = "bool"; kind = AttributeKind.ValueType; break; case "reference": attrType = "DwarfDIE"; break; case "address": attrType = "ulong"; kind = AttributeKind.ValueType; break; case "constant": attrType = "DwarfConstant"; kind = AttributeKind.ValueType; break; case "lineptr": attrType = "DwarfLineProgramTable"; break; case "exprloc": attrType = "DwarfExpression"; break; case "loclist": case "loclistptr": attrType = "DwarfLocation"; break; case "addrptr": case "macptr": case "rnglist": case "rangelistptr": case "rnglistsptr": case "stroffsetsptr": attrType = "ulong"; kind = AttributeKind.ValueType; break; } } else if (attrEncodingParts.Length > 3) { var key = string.Join(" ", attrEncodingParts.Skip(2).ToArray()); alreadyDone.Add(key); Console.WriteLine(attrEncoding); bool hasConstant = false; for (int i = 2; i < attrEncodingParts.Length; i++) { switch (attrEncodingParts[i]) { case "loclist": case "loclistptr": attrType = "DwarfLocation"; kind = AttributeKind.ValueType; goto next; case "constant": hasConstant = true; break; } } if (hasConstant) { attrType = "DwarfConstant"; kind = AttributeKind.ValueType; } } next: MapAttributeCompactNameToType.Add(attributeName.Replace("_", string.Empty), new AttributeMapping(rawName, attrType, kind)); const int PaddingEncodingName = 50; for (; currentAttributeIndex < attributeIndex; currentAttributeIndex++) { fieldArrayBuilder.AppendLine($" {"DwarfAttributeEncoding.None",-PaddingEncodingName}, // 0x{currentAttributeIndex:x2} (undefined)"); } for (int i = 2; i < attrEncodingParts.Length; i++) { string name; switch (attrEncodingParts[i]) { case "string": name = "String"; break; case "flag": name = "Flag"; break; case "block": name = "Block"; break; case "reference": name = "Reference"; break; case "address": name = "Address"; break; case "constant": name = "Constant"; break; case "lineptr": name = "LinePointer"; break; case "exprloc": name = "ExpressionLocation"; break; case "loclist": name = "LocationList"; break; case "loclistptr": name = "LocationListPointer"; break; case "loclistsptr": name = "LocationListsPointer"; break; case "addrptr": name = "AddressPointer"; break; case "macptr": name = "MacroPointer"; break; case "rnglist": name = "RangeList"; break; case "rangelistptr": name = "RangeListPointer"; break; case "rnglistsptr": name = "RangeListsPointer"; break; case "stroffsetsptr": name = "StringOffsetPointer"; break; default: throw new InvalidOperationException($"Unknown encoding {attrEncodingParts[i]}"); } bool isLast = i + 1 == attrEncodingParts.Length; fieldArrayBuilder.Append($" {"DwarfAttributeEncoding." + name + (isLast ? "" : " | "),-PaddingEncodingName}"); if (isLast) { fieldArrayBuilder.Append($", // 0x{currentAttributeIndex:x2} {attributeName} "); } fieldArrayBuilder.AppendLine(); } currentAttributeIndex++; } fieldArrayBuilder.Append(" }"); csField.InitValue = fieldArrayBuilder.ToString(); Console.WriteLine(); foreach (var key in alreadyDone.ToArray().OrderBy(x => x)) { Console.WriteLine(key); } }
private static void GenerateDwarfDIE(CSharpNamespace ns) { var file = File.ReadAllLines(@"C:\code\LibObjectFile\ext\dwarf-specs\attributesbytag.tex"); var regexDWTag = new Regex(@"^\\(DWTAG\w+)"); var regexDWAT = new Regex(@"^&\\(DWAT\w+)"); int state = 0; string currentCompactTagName = null; CSharpClass currentDIE = null; var dieClasses = new List <CSharpClass>(); var dieTags = new List <string>(); foreach (var line in file) { if (state == 0) { if (line.StartsWith(@"\begin{longtable}")) { continue; } else { state = 1; } } var match = regexDWTag.Match(line); if (match.Success) { var compactTagName = match.Groups[1].Value; if (compactTagName == currentCompactTagName) { continue; } currentCompactTagName = compactTagName; var fullTagName = MapTagCompactNameToFullName[compactTagName]; dieTags.Add(fullTagName); var csDIEName = fullTagName.Substring("DW_TAG_".Length); csDIEName = CSharpifyName(csDIEName); currentDIE = new CSharpClass($"DwarfDIE{csDIEName}"); currentDIE.BaseTypes.Add(new CSharpFreeType("DwarfDIE")); ns.Members.Add(currentDIE); var csConstructor = new CSharpMethod(); csConstructor.IsConstructor = true; csConstructor.Body = (writer, element) => writer.WriteLine($"this.Tag = (DwarfTag)DwarfNative.{fullTagName};"); currentDIE.Members.Add(csConstructor); dieClasses.Add(currentDIE); } else { match = regexDWAT.Match(line); if (match.Success) { var compactAttrName = match.Groups[1].Value; var csProperty = CreatePropertyFromDwarfAttributeName(compactAttrName); currentDIE.Members.Add(csProperty); // The DW_AT_description attribute can be used on any debugging information // entry that may have a DW_AT_name attribute. For simplicity, this attribute is // not explicitly shown. if (compactAttrName == "DWATname") { csProperty = CreatePropertyFromDwarfAttributeName("DWATdescription"); currentDIE.Members.Add(csProperty); } } else if (currentDIE != null && line.Contains("{DECL}")) { currentDIE.BaseTypes[0] = new CSharpFreeType("DwarfDIEDeclaration"); } } } // Generate the DIEHelper class var dieHelperClass = new CSharpClass("DIEHelper") { Modifiers = CSharpModifiers.Partial | CSharpModifiers.Static, Visibility = CSharpVisibility.Internal }; ns.Members.Add(dieHelperClass); var dieHelperMethod = new CSharpMethod() { Name = "ConvertTagToDwarfDIE", Modifiers = CSharpModifiers.Static, Visibility = CSharpVisibility.Public }; dieHelperClass.Members.Add(dieHelperMethod); dieHelperMethod.Parameters.Add(new CSharpParameter("tag") { ParameterType = CSharpPrimitiveType.UShort }); dieHelperMethod.ReturnType = new CSharpFreeType("DwarfDIE"); dieHelperMethod.Body = (writer, element) => { writer.WriteLine("switch (tag)"); writer.OpenBraceBlock(); for (var i = 0; i < dieClasses.Count; i++) { var dieCls = dieClasses[i]; var dieTag = dieTags[i]; writer.WriteLine($"case DwarfNative.{dieTag}:"); writer.Indent(); writer.WriteLine($"return new {dieCls.Name}();"); writer.UnIndent(); } writer.CloseBraceBlock(); writer.WriteLine("return new DwarfDIE();"); }; }
public bool TryGetNamespaceReference(CSharpNamespace semanticNamespace, IAssemblyReference cciAssembly, out IUnitNamespaceReference cciNamespace) { Contract.Ensures(!Contract.Result<bool>() || (Contract.ValueAtReturn(out cciNamespace) != null)); cciNamespace = null; #region Check input if (semanticNamespace == null || cciAssembly == null) { return false; } #endregion #region If root try { if (semanticNamespace.IsRoot) { cciNamespace = new Microsoft.Cci.MutableCodeModel.RootUnitNamespaceReference() { Unit = cciAssembly }; goto ReturnTrue; } } catch (InvalidOperationException e) { //For some reason, an InvalidOperationException may get thrown. if (e.Message.Contains(VSServiceProvider.InvalidOperationExceptionMessage_TheSnapshotIsOutOfDate)) goto ReturnFalse; else throw e; } #endregion #region If nested if (semanticNamespace.ContainingNamespace != null) { IUnitNamespaceReference parentNs; if (!TryGetNamespaceReference(semanticNamespace.ContainingNamespace, cciAssembly, out parentNs)) goto ReturnFalse; if (semanticNamespace.Name == null) goto ReturnFalse; cciNamespace = new Microsoft.Cci.Immutable.NestedUnitNamespaceReference(parentNs, Host.NameTable.GetNameFor(semanticNamespace.Name.Text)); goto ReturnTrue; } #endregion Contract.Assert(cciNamespace == null); goto ReturnFalse; #region ReturnTrue: ReturnTrue: return true; #endregion #region ReturnFalse: ReturnFalse: return false; #endregion }