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());
        }
Beispiel #2
0
        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);
        }
Beispiel #3
0
        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
        }
Beispiel #4
0
        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);
            }
        }
Beispiel #5
0
        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
    }