3

I am working on some T4 code generation, for this I need the CodeClass of the type that is passed inside the constructor of BarAttribute.

class Baz { }
class Bar : Attribute { public Bar (Type type) {    } }

[Bar(typeof(Baz))]
public class Foo
{
}

This is what I have so far inside my T4 Template, I just give the CodeAttribute '[Bar(typeof(Baz))]' to the function:

private CodeClass GetType(CodeElement codeElement)
{
    CodeAttribute attribute = (CodeAttribute)codeElement;
    if (attribute.Name == "Bar")
    {
        foreach (CodeElement child in attribute.Children)
        {
            EnvDTE80.CodeAttributeArgument attributeArg = (EnvDTE80.CodeAttributeArgument)child;
            WriteLine(attributeArg.Value);
        }
    }

    return null;
}

The function now will just write: typeof(Baz), how can I get the CodeClass of Baz (which can be inside another assembly within the solution) without iterating thru all Projects, ProjectItems, CodeElements, etc?

Peter Kiers
  • 602
  • 4
  • 16
  • I don't know if what you are trying to do is possible, as to do so would require System.Reflection, which is performed at runtime (not design-time). Your best bet (which seems like your only option at this point) is to enumerate through all your Projects. All your CodeModels, and all your ProjectItems. Also, using this method, you still might end up with inconsistent data if there is more than one NameSpace that contains a Baz class (as, AFAIK, EnvDTE doesn't see what's in the Attribute, just the string literal of arguments passed to the attribute). – William Apr 19 '13 at 22:37
  • Here's a related thread: http://stackoverflow.com/questions/9520802/accessing-attribute-info-from-dte – Erti-Chris Eelmaa Jan 01 '15 at 13:15

1 Answers1

2

As per William's reply, you are limited to the design-time information, which will be the unparsed text passed to the attribute. If you are interested in finding the CodeClass referenced in the typeof keyword without resorting to recursion, you can use the VisualStudioAutomationHelper class found in tangible's T4 Editor template gallery. You use it like this:

var project = VisualStudioHelper.CurrentProject;

var allClasses = VisualStudioHelper.GetAllCodeElementsOfType(project.CodeModel.CodeElements, EnvDTE.vsCMElement.vsCMElementClass, false);

allClasses.Cast<EnvDTE.CodeClass>().Single(x => x.Name == searchedClassName);
Community
  • 1
  • 1
Pedro Pombeiro
  • 1,654
  • 13
  • 14