Coder Social home page Coder Social logo

codegeneration.roslyn's Introduction

Roslyn-based Code Generation

Build Status GitHub Actions CI status

๐Ÿ›‘ This project is no longer maintained now that Roslyn offers source generators which offer superior performance, reliability, and IDE integration. See #229 for a discussion leading up to this decision. Existing generators based on this project should be easily portable to Source Generators just by changing the wrapping and keeping all the syntax tree generating code. For an example migration, see refactor: Use .NET 5 Source Generators PR.


Assists in performing Roslyn-based code generation during a build. This includes design-time support, such that code generation can respond to changes made in hand-authored code files by generating new code that shows up to Intellisense as soon as the file is saved to disk.

See who's generating code or consuming it using CodeGeneration.Roslyn.

Instructions on development and using this project's source code are in CONTRIBUTING.md.

Packages

Package Latest Preview Description
CodeGeneration.Roslyn.Tool NuGet package NuGet preview package Tool that loads Plugins and MSBuild targets that run it during build.
CodeGeneration.Roslyn.Templates NuGet package NuGet preview package Templates for dotnet new that help create Plugins items and projects.
CodeGeneration.Roslyn NuGet package NuGet preview package API for generators to build against.
CodeGeneration.Roslyn.Attributes NuGet package NuGet preview package Attributes to annotate plugin attributes with.
CodeGeneration.Roslyn.Engine NuGet package NuGet preview package Engine called by Tool; useful for testing generators.
CodeGeneration.Roslyn.Plugin.Sdk NuGet package NuGet preview package MSBuild project Sdk that facilitates correct Plugin project setup.
CodeGeneration.Roslyn.PluginMetapackage.Sdk NuGet package NuGet preview package MSBuild project Sdk that facilitates correct Plugin metapackage project setup.

Table of Contents

How to write your own code generator

In this walkthrough, we will define a code generator that replicates any class (annotated with our custom attribute) with a suffix (specified in the attribute) appended to its name.

Prerequisites

Use template pack

To install the template pack, run:

dotnet new -i CodeGeneration.Roslyn.Templates

You'll then have our template pack installed and ready for use with dotnet new. For details see templates Readme.

Prepare a directory where you want to create your Plugin projects, e.g. mkdir DemoGeneration. Then, in that directory, create the set of Plugin projects (we add the --sln to create solution as well):

dotnet new cgrplugin -n Duplicator --sln

This will create 3 ready-to-build projects. You can now skip through the next steps of creating and setting up projects, just apply the following changes to have the same content:

  • rename Duplicator.Generators/Generator1.cs to DuplicateWithSuffixGenerator.cs
    • also replace the DuplicateWithSuffixGenerator class with the following:
      public class DuplicateWithSuffixGenerator : ICodeGenerator
      {
          private readonly string suffix;
      
          public DuplicateWithSuffixGenerator(AttributeData attributeData)
          {
              suffix = (string)attributeData.ConstructorArguments[0].Value;
          }
      
          public Task<SyntaxList<MemberDeclarationSyntax>> GenerateAsync(TransformationContext context, IProgress<Diagnostic> progress, CancellationToken cancellationToken)
          {
              // Our generator is applied to any class that our attribute is applied to.
              var applyToClass = (ClassDeclarationSyntax)context.ProcessingNode;
      
              // Apply a suffix to the name of a copy of the class.
              var copy = applyToClass.WithIdentifier(SyntaxFactory.Identifier(applyToClass.Identifier.ValueText + suffix));
      
              // Return our modified copy. It will be added to the user's project for compilation.
              var results = SyntaxFactory.SingletonList<MemberDeclarationSyntax>(copy);
              return Task.FromResult(results);
          }
      }
  • rename Duplicator.Attributes/Generator1Attribute.cs file to DuplicateWithSuffixAttribute.cs
    • also replace DuplicateWithSuffixAttribute class with the following:
      [AttributeUsage(AttributeTargets.Class)]
      [CodeGenerationAttribute("Duplicator.Generators.DuplicateWithSuffixGenerator, Duplicator.Generators")]
      [Conditional("CodeGeneration")]
      public class DuplicateWithSuffixAttribute : Attribute
      {
          public DuplicateWithSuffixAttribute(string suffix)
          {
              Suffix = suffix;
          }
      
          public string Suffix { get; }
      }

Define code generator

Your generator cannot be defined in the same project that will have code generated for it. That's because code generation runs before the consuming project is itself compiled. We'll start by creating the generator. This must be done in a library that targets netcoreapp2.1. Let's create one called Duplicator:

dotnet new classlib -f netcoreapp2.1 -o Duplicator.Generators

Now we'll use an MSBuild project SDK CodeGeneration.Roslyn.Plugin.Sdk to speed up configuring our generator plugin. Edit your project file and add the <Sdk> element:

<!-- Duplicator.Generators/Duplicator.Generators.csproj -->
<Project Sdk="Microsoft.NET.Sdk">
  <!-- Add the following element above any others: -->
  <Sdk Name="CodeGeneration.Roslyn.Plugin.Sdk" Version="{replace with actual version used}" />

  <PropertyGroup>
    <TargetFramework>netcoreapp2.1</TargetFramework>
  </PropertyGroup>

</Project>

This SDK will implicitly add a PackageReference to the corresponding version of CodeGeneration.Roslyn nuget, and set properties to make plugin build correctly. We can now write our generator:

โš  Note: constructor is required to have exactly a single AttributeData parameter.

// Duplicator.Generators/DuplicateWithSuffixGenerator.cs
using System;
using System.Threading;
using System.Threading.Tasks;
using CodeGeneration.Roslyn;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Syntax;

namespace Duplicator.Generators
{
    public class DuplicateWithSuffixGenerator : ICodeGenerator
    {
        private readonly string suffix;

        public DuplicateWithSuffixGenerator(AttributeData attributeData)
        {
            suffix = (string)attributeData.ConstructorArguments[0].Value;
        }

        public Task<SyntaxList<MemberDeclarationSyntax>> GenerateAsync(TransformationContext context, IProgress<Diagnostic> progress, CancellationToken cancellationToken)
        {
            // Our generator is applied to any class that our attribute is applied to.
            var applyToClass = (ClassDeclarationSyntax)context.ProcessingNode;

            // Apply a suffix to the name of a copy of the class.
            var copy = applyToClass.WithIdentifier(SyntaxFactory.Identifier(applyToClass.Identifier.ValueText + suffix));

            // Return our modified copy. It will be added to the user's project for compilation.
            var results = SyntaxFactory.SingletonList<MemberDeclarationSyntax>(copy);
            return Task.FromResult(results);
        }
    }
}

Define attribute

To activate your code generator, you need to define an attribute with which we'll annotate the class to be copied. Let's do that in a new project:

dotnet new classlib -f netstandard2.0 -o Duplicator.Attributes

Install Attributes package:

dotnet add Duplicator.Attributes package CodeGeneration.Roslyn.Attributes

Then, define your attribute class:

// Duplicator.Attributes/DuplicateWithSuffixAttribute.cs
using System;
using System.Diagnostics;
using CodeGeneration.Roslyn;

namespace Duplicator
{
    [AttributeUsage(AttributeTargets.Class)]
    [CodeGenerationAttribute("Duplicator.Generators.DuplicateWithSuffixGenerator, Duplicator.Generators")]
    [Conditional("CodeGeneration")]
    public class DuplicateWithSuffixAttribute : Attribute
    {
        public DuplicateWithSuffixAttribute(string suffix)
        {
            Suffix = suffix;
        }

        public string Suffix { get; }
    }
}

CodeGenerationAttribute is crucial - this tells the CG.R Tool which generator to invoke for a member annotated with our DuplicateWithSuffixAttribute. It's parameter is an assembly-qualified generator type name (incl. namespace): Full.Type.Name, Full.Assembly.Name

The [Conditional("CodeGeneration")] attribute is not necessary, but it will prevent the attribute from persisting in the compiled assembly that consumes it, leaving it instead as just a compile-time hint to code generation, and allowing you to not ship with a dependency on your code generation assembly.

โ„น Of course, the attribute will persist if you define compilation symbol "CodeGeneration"; we assume it won't be defined.

Create consuming console app

We'll consume our generator in a Reflector app:

dotnet new console -o Reflector

dotnet add Reflector reference Duplicator.Attributes

dotnet add Reflector reference Duplicator.Generators

Let's write a simple program that prints all types in its assembly:

// Reflector/Program.cs
using System;

namespace Reflector
{
    class Program
    {
        static void Main(string[] args)
        {
            foreach (var type in typeof(Program).Assembly.GetTypes())
                Console.WriteLine(type.FullName);
        }
    }
}

Now, when we dotnet run -p Reflector we should get:

Reflector.Program

Apply code generation

Applying code generation is incredibly simple. Just add the attribute on any type or member supported by the attribute and generator you wrote. We'll test our Duplicator on a new Test class:

// Reflector/Program.cs
using System;
using System.Diagnostics;
using CodeGeneration.Roslyn;
using Duplicator;

namespace Reflector
{
    [DuplicateWithSuffix("Passed")]
    class Test {}

    class Program
    {
        // ...
    }
}

Let's check our app again:

> dotnet run -p Reflector

Reflector.Program

Reflector.Test

Still nothing except what we wrote. Now all that's left is to plumb the build pipeline with code generation tool; that tool will handle invoking our Duplicator at correct time during build and write generated file, passing it into the compilation.

You'll need to add a reference to CodeGeneration.Roslyn.Tool package:

dotnet add Reflector package CodeGeneration.Roslyn.Tool

Also, you need to add the following metadata to your generator project reference: OutputItemType="CodeGenerationRoslynPlugin". This will add the path to the Duplicator.Generators.dll to the list of plugins the tool runs.

This is how your project file can look like:

<!-- Reflector/Reflector.csproj -->
<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>netcoreapp2.1</TargetFramework>
  </PropertyGroup>
  <ItemGroup>
    <!-- This ProjectReference to the generator needs to have the OutputItemType metadata -->
    <ProjectReference Include="..\Duplicator.Generators\Duplicator.Generators.csproj"
                      OutputItemType="CodeGenerationRoslynPlugin" />
    <PackageReference Include="CodeGeneration.Roslyn.Attributes"
                      Version="{replace with actual version used}" />
    <!--
      This contains the generation tool and MSBuild targets that invoke it,
      and so can be marked with PrivateAssets="all"
    -->
    <PackageReference Include="CodeGeneration.Roslyn.Tool"
                      Version="{replace with actual version used}"
                      PrivateAssets="all" />
  </ItemGroup>
</Project>

And if all steps were done correctly:

> dotnet run -p Reflector

Reflector.Program

Reflector.Test

Reflector.TestPassed

๐Ÿ’ก Notice that there is a TestPassed type in the assembly now.

What's even better is that you should see that new type in IntelliSense as well! Try executing Go to Definition (F12) on it - your IDE (VS/VS Code) should open the generated file for you (it'll be located in IntermediateOutputPath - most commonly obj/).

Advanced scenarios

While the sample worked, it was also unrealistically simple and skipped many complex issues that will inevitably arise when you try to use this project in real world. What follows is a deep dive into more realistic solutions.

Most of the issues are about two things: TargetFramework and dependecies. TargetFramework/TFM/TxM (e.g. netcoreapp2.1) of the generator is restricted to an exact version and there's not a lot of wiggle room there. In contrast, projects consuming generators and their outputs will target any existing TFM. If you will try to add a P2P (project-to-project) reference to a generator (targeting netcoreapp2.1) to a business model project targeting netstandard1.0, you'll get errors.

Customize generator reference

We don't need the generator as a compile reference. However, the magic OutputItemType metadata is important - it adds a path to the generator dll to the list of plugins run by the CodeGeneration.Roslyn.Tool tool. Additionally, we want to specify that there's a build dependency of the consuming project on the generator. So we modify the reference:

<!-- Reflector/Reflector.csproj -->
  <ItemGroup>
    <ProjectReference Include="..\Duplicator\Duplicator.csproj"
      ReferenceOutputAssembly="false"
      SkipGetTargetFrameworkProperties="true"
      OutputItemType="CodeGenerationRoslynPlugin" />
  </ItemGroup>

We add two new metadata attributes:

  • ReferenceOutputAssembly="false" - this causes the compilation to not add a reference to Duplicator.Generators.dll to the ReferencePath - so the source code has no dependency and doesn't know anything about that project.
  • SkipGetTargetFrameworkProperties="true" - this prevents build tasks from checking compatibility of the generator's TFM with this project's TFM.

Now we can retarget our Reflector to any TFM compatible with Attributes package (so netstandard1.0-compatible), e.g. netcoreapp2.0 - and it should run just fine.

Multitargeting generator

It can happen that your generator project will become multi-targeting. You could need to do that to use C#8's Nullable Reference Types feature in the Duplicator; the generator has to target netcoreapp2.1 as this is the framework it'll be run in by the CG.R.Tool - on the other hand, NRT feature is only supported in newer TFMs, starting with netcoreapp3.1. So you'll do:

<!-- Duplicator.Generators/Duplicator.Generators.csproj -->
<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <TargetFrameworks>netcoreapp2.1;netcoreapp3.1</TargetFrameworks>
    <PackAsCodeGenerationRoslynPlugin>$(TargetFramework.Equals('netcoreapp2.1'))</PackAsCodeGenerationRoslynPlugin>
  </PropertyGroup>
  <!-- ... -->
</Project>

โ„น PackAsCodeGenerationRoslynPlugin is necessary to explicitly tell Plugin.Sdk which TargetFramework's build output to pack - there can be only one.

There'll be a build error, because the consumer (Reflector) doesn't know which output to use (and assign to the CodeGenerationRoslynPlugin Item). To fix that we have to use SetTargetFramework metadata. Setting it implies SkipGetTargetFrameworkProperties="true" so we can replace it.

<!-- Reflector/Reflector.csproj -->
<Project Sdk="Microsoft.NET.Sdk">
  <!-- ... -->
  <ItemGroup>
    <ProjectReference Include="..\Duplicator\Duplicator.csproj"
      ReferenceOutputAssembly="false"
      SetTargetFramework="TargetFramework=netcoreapp2.1"
      OutputItemType="CodeGenerationRoslynPlugin" />
    <!-- ... -->
  </ItemGroup>
</Project>

Package your code generator

โ„น If you've used cgrplugin template, you've already got metapackage project ready.

You can also package up your code generator as a NuGet package for others to install and use. A project using CodeGeneration.Roslyn.Plugin.Sdk is automatically configured to produce a correct Plugin nuget package.

Separate out the attribute

โš  This section is deprecated since it's now the default.

The triggering attribute has to be available in consuming code. Your consumers can write it themselves, but it's not a good idea to require them do so. So we'll separate the attribute into another project that has TFM allowing all your consumers to reference it, for example netstandard1.0 - you're constrained only by what CodeGeneration.Roslyn.Attributes targets.

Let's call this new project Duplicator.Attributes.

dotnet new classlib -o Duplicator.Attributes dotnet add Duplicator.Attributes package CodeGeneration.Roslyn.Attributes dotnet add Reflector reference Duplicator.Attributes

Now, move the attribute definition from Reflector to our new project. Dont' forget to change the namespace. The app should work the same, except for not printing DuplicateWithSuffixAttribute type.

If you annotate your triggering attribute with [Conditional("...")], your consumers can make any references to the attribute package non-transient via PrivateAssets="all" and/or exclude from runtime assets via ExcludeAssets="runtime".

Create the metapackage

Your consumers will now have to depend (have PackageReference) on the following:

  • CodeGeneration.Roslyn.Tool tool
  • Duplicator.Attributes (your attributes package)
  • Duplicator.Generators (your generator/plugin package)

An example consuming project file would contain:

<!-- Reflector/Reflector.csproj -->
<ItemGroup>
  <PackageReference Include="Duplicator.Generators" Version="1.0.0" PrivateAssets="all" />
  <PackageReference Include="Duplicator.Attributes" Version="1.0.0" PrivateAssets="all" />
  <PackageReference Include="CodeGeneration.Roslyn.Tool"
                    Version="{CodeGeneration.Roslyn.Tool version}"
                    PrivateAssets="all" />
</ItemGroup>

โœ” There's a much better approach: metapackage.

For this, we'll use CodeGeneration.Roslyn.PluginMetapackage.Sdk MSBuild project SDK in a new project called simply Duplicator, which will reference our attributes:

dotnet new classlib -o Duplicator dotnet add Duplicator reference Duplicator.Attributes

Remove Class1.cs file.

Modify project file:

  • Add <Sdk> element
  • Add NupkgAdditionalDependency in ItemGroup
<!-- Duplicator/Duplicator.csproj -->
<Project Sdk="Microsoft.NET.Sdk">
  <!-- Add the following element above any others: -->
  <Sdk Name="CodeGeneration.Roslyn.PluginMetapackage.Sdk" Version="{replace with actual version used}"/>

  <PropertyGroup>
    <!-- Declare the TargetFramework(s) the same as in your Attributes package -->
    <TargetFramework>netstandard1.0</TargetFramework>
  </PropertyGroup>

  <ItemGroup>
    <!-- Reference your Attributes project normally -->
    <ProjectReference Include="../Duplicator.Attributes/Duplicator.Attributes.csproj" />
    <!--
      Reference your generators package by adding an item to NupkgAdditionalDependency
      with IncludeAssets="all" to flow "build" assets.
      Version used will be the PackageVersion Pack resolves,
      but you can specify Version metadata to override it.

      This is necessary to do like that, because it ensures the dependency is setup
      correctly (e.g. simple transient dependency), and skips validation of TFM (Plugin is a tool,
      it's TFM has no meaning for the consumer).
    -->
    <NupkgAdditionalDependency
        Include="Duplicator.Generators"
        IncludeAssets="all" />
  </ItemGroup>
</Project>

This project will now produce a nupkg that will not contain anything on it's own, but will "pull in" all the other dependecies consumers will need:

  • CodeGeneration.Roslyn.Tool (added implicitly by the Sdk)
  • Duplicator.Attributes
  • Duplicator.Generators

Our metapackage should be versioned in the same manner as it's dependant packages.

โš  Please note that Metapackage project doesn't change how P2P (ProjectReference) setup works - it only works as a NuGet package!

โ„น For a sample metapackage, see MetapackageSample.

Add extra build/ content in Plugin package

CG.R.Plugin.Sdk creates custom build/PackageId.props/targets files. If you want to add custom MSBuild props/targets into NuGet package's build folder (and have it imported when package is referenced), you'll need to use PackageBuildFolderProjectImport ItemGroup, as shown in PackagedGenerator sample.

Accesss MSBuild Properties

You may access MSBuild property values of the project being generated for, by first adding the property name to the PluginRequestedProperty item list. For example, if you want to access the TargetFramework build property, you would do the following in your generator's .csproj file:

<ItemGroup>
  <PluginRequestedProperty Include="ExampleBuildProperty" />
</ItemGroup>

Then, you can access its value like this:

public Task<SyntaxList<MemberDeclarationSyntax>> GenerateAsync(TransformationContext context, IProgress<Diagnostic> progress, CancellationToken cancellationToken)
{
    var targetFramework = context.BuildProperties["TargetFramework"];
    // ...
}

โ„น For a sample generator that accesses MSBuild properties, see BuildPropsGenerator and its consuming project, BuildPropsConsumer

codegeneration.roslyn's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

codegeneration.roslyn's Issues

Intellisense problems when using this library

When using the 0.2.10 nuget package I don't get intellisense for the generated code in VS 2017. (copy/pasted the sample code on the front page in a new console project)

The project compiles but the FooA has no intellisense.

What is also odd is that the DuplicateWithSuffix attribute has no intellisense, even though it is in the referenced code assembly and not in generated code.

Unable to build sample project in Visual Studio

I always get the same error:

6>------ Rebuild All started: Project: CodeGeneration.Roslyn.Tasks, Configuration: Debug Any CPU ------
6>C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\MSBuild\15.0\Bin\Microsoft.Common.CurrentVersion.targets(4825,5): warning MSB3061: Unable to delete file "C:\Users\Alex\Source\Repos\CodeGeneration.Roslyn\bin\CodeGeneration.Roslyn.Tasks\Debug\net46\CodeGeneration.Roslyn.Tasks.dll". Access to the path 'C:\Users\Alex\Source\Repos\CodeGeneration.Roslyn\bin\CodeGeneration.Roslyn.Tasks\Debug\net46\CodeGeneration.Roslyn.Tasks.dll' is denied.
6>C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\MSBuild\15.0\Bin\Microsoft.Common.CurrentVersion.targets(4148,5): warning MSB3026: Could not copy "C:\Users\Alex\Source\Repos\CodeGeneration.Roslyn\bin\CodeGeneration.Roslyn.Tasks.Helper\Debug\net46\CodeGeneration.Roslyn.Tasks.Helper.dll" to "C:\Users\Alex\Source\Repos\CodeGeneration.Roslyn\src\..\bin\CodeGeneration.Roslyn.Tasks\Debug\net46\CodeGeneration.Roslyn.Tasks.Helper.dll". Beginning retry 1 in 1000ms. The process cannot access the file 'C:\Users\Alex\Source\Repos\CodeGeneration.Roslyn\src\..\bin\CodeGeneration.Roslyn.Tasks\Debug\net46\CodeGeneration.Roslyn.Tasks.Helper.dll' because it is being used by another process.
6>C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\MSBuild\15.0\Bin\Microsoft.Common.CurrentVersion.targets(4148,5): warning MSB3026: Could not copy "C:\Users\Alex\Source\Repos\CodeGeneration.Roslyn\bin\CodeGeneration.Roslyn.Tasks.Helper\Debug\net46\CodeGeneration.Roslyn.Tasks.Helper.dll" to "C:\Users\Alex\Source\Repos\CodeGeneration.Roslyn\src\..\bin\CodeGeneration.Roslyn.Tasks\Debug\net46\CodeGeneration.Roslyn.Tasks.Helper.dll". Beginning retry 2 in 1000ms. The process cannot access the file 'C:\Users\Alex\Source\Repos\CodeGeneration.Roslyn\src\..\bin\CodeGeneration.Roslyn.Tasks\Debug\net46\CodeGeneration.Roslyn.Tasks.Helper.dll' because it is being used by another process.
6>C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\MSBuild\15.0\Bin\Microsoft.Common.CurrentVersion.targets(4148,5): warning MSB3026: Could not copy "C:\Users\Alex\Source\Repos\CodeGeneration.Roslyn\bin\CodeGeneration.Roslyn.Tasks.Helper\Debug\net46\CodeGeneration.Roslyn.Tasks.Helper.dll" to "C:\Users\Alex\Source\Repos\CodeGeneration.Roslyn\src\..\bin\CodeGeneration.Roslyn.Tasks\Debug\net46\CodeGeneration.Roslyn.Tasks.Helper.dll". Beginning retry 3 in 1000ms. The process cannot access the file 'C:\Users\Alex\Source\Repos\CodeGeneration.Roslyn\src\..\bin\CodeGeneration.Roslyn.Tasks\Debug\net46\CodeGeneration.Roslyn.Tasks.Helper.dll' because it is being used by another process.
6>C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\MSBuild\15.0\Bin\Microsoft.Common.CurrentVersion.targets(4148,5): warning MSB3026: Could not copy "C:\Users\Alex\Source\Repos\CodeGeneration.Roslyn\bin\CodeGeneration.Roslyn.Tasks.Helper\Debug\net46\CodeGeneration.Roslyn.Tasks.Helper.dll" to "C:\Users\Alex\Source\Repos\CodeGeneration.Roslyn\src\..\bin\CodeGeneration.Roslyn.Tasks\Debug\net46\CodeGeneration.Roslyn.Tasks.Helper.dll". Beginning retry 4 in 1000ms. The process cannot access the file 'C:\Users\Alex\Source\Repos\CodeGeneration.Roslyn\src\..\bin\CodeGeneration.Roslyn.Tasks\Debug\net46\CodeGeneration.Roslyn.Tasks.Helper.dll' because it is being used by another process.
6>C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\MSBuild\15.0\Bin\Microsoft.Common.CurrentVersion.targets(4148,5): warning MSB3026: Could not copy "C:\Users\Alex\Source\Repos\CodeGeneration.Roslyn\bin\CodeGeneration.Roslyn.Tasks.Helper\Debug\net46\CodeGeneration.Roslyn.Tasks.Helper.dll" to "C:\Users\Alex\Source\Repos\CodeGeneration.Roslyn\src\..\bin\CodeGeneration.Roslyn.Tasks\Debug\net46\CodeGeneration.Roslyn.Tasks.Helper.dll". Beginning retry 5 in 1000ms. The process cannot access the file 'C:\Users\Alex\Source\Repos\CodeGeneration.Roslyn\src\..\bin\CodeGeneration.Roslyn.Tasks\Debug\net46\CodeGeneration.Roslyn.Tasks.Helper.dll' because it is being used by another process.
6>C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\MSBuild\15.0\Bin\Microsoft.Common.CurrentVersion.targets(4148,5): warning MSB3026: Could not copy "C:\Users\Alex\Source\Repos\CodeGeneration.Roslyn\bin\CodeGeneration.Roslyn.Tasks.Helper\Debug\net46\CodeGeneration.Roslyn.Tasks.Helper.dll" to "C:\Users\Alex\Source\Repos\CodeGeneration.Roslyn\src\..\bin\CodeGeneration.Roslyn.Tasks\Debug\net46\CodeGeneration.Roslyn.Tasks.Helper.dll". Beginning retry 6 in 1000ms. The process cannot access the file 'C:\Users\Alex\Source\Repos\CodeGeneration.Roslyn\src\..\bin\CodeGeneration.Roslyn.Tasks\Debug\net46\CodeGeneration.Roslyn.Tasks.Helper.dll' because it is being used by another process.
6>C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\MSBuild\15.0\Bin\Microsoft.Common.CurrentVersion.targets(4148,5): warning MSB3026: Could not copy "C:\Users\Alex\Source\Repos\CodeGeneration.Roslyn\bin\CodeGeneration.Roslyn.Tasks.Helper\Debug\net46\CodeGeneration.Roslyn.Tasks.Helper.dll" to "C:\Users\Alex\Source\Repos\CodeGeneration.Roslyn\src\..\bin\CodeGeneration.Roslyn.Tasks\Debug\net46\CodeGeneration.Roslyn.Tasks.Helper.dll". Beginning retry 7 in 1000ms. The process cannot access the file 'C:\Users\Alex\Source\Repos\CodeGeneration.Roslyn\src\..\bin\CodeGeneration.Roslyn.Tasks\Debug\net46\CodeGeneration.Roslyn.Tasks.Helper.dll' because it is being used by another process.
6>C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\MSBuild\15.0\Bin\Microsoft.Common.CurrentVersion.targets(4148,5): warning MSB3026: Could not copy "C:\Users\Alex\Source\Repos\CodeGeneration.Roslyn\bin\CodeGeneration.Roslyn.Tasks.Helper\Debug\net46\CodeGeneration.Roslyn.Tasks.Helper.dll" to "C:\Users\Alex\Source\Repos\CodeGeneration.Roslyn\src\..\bin\CodeGeneration.Roslyn.Tasks\Debug\net46\CodeGeneration.Roslyn.Tasks.Helper.dll". Beginning retry 8 in 1000ms. The process cannot access the file 'C:\Users\Alex\Source\Repos\CodeGeneration.Roslyn\src\..\bin\CodeGeneration.Roslyn.Tasks\Debug\net46\CodeGeneration.Roslyn.Tasks.Helper.dll' because it is being used by another process.
6>C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\MSBuild\15.0\Bin\Microsoft.Common.CurrentVersion.targets(4148,5): warning MSB3026: Could not copy "C:\Users\Alex\Source\Repos\CodeGeneration.Roslyn\bin\CodeGeneration.Roslyn.Tasks.Helper\Debug\net46\CodeGeneration.Roslyn.Tasks.Helper.dll" to "C:\Users\Alex\Source\Repos\CodeGeneration.Roslyn\src\..\bin\CodeGeneration.Roslyn.Tasks\Debug\net46\CodeGeneration.Roslyn.Tasks.Helper.dll". Beginning retry 9 in 1000ms. The process cannot access the file 'C:\Users\Alex\Source\Repos\CodeGeneration.Roslyn\src\..\bin\CodeGeneration.Roslyn.Tasks\Debug\net46\CodeGeneration.Roslyn.Tasks.Helper.dll' because it is being used by another process.
6>C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\MSBuild\15.0\Bin\Microsoft.Common.CurrentVersion.targets(4148,5): warning MSB3026: Could not copy "C:\Users\Alex\Source\Repos\CodeGeneration.Roslyn\bin\CodeGeneration.Roslyn.Tasks.Helper\Debug\net46\CodeGeneration.Roslyn.Tasks.Helper.dll" to "C:\Users\Alex\Source\Repos\CodeGeneration.Roslyn\src\..\bin\CodeGeneration.Roslyn.Tasks\Debug\net46\CodeGeneration.Roslyn.Tasks.Helper.dll". Beginning retry 10 in 1000ms. The process cannot access the file 'C:\Users\Alex\Source\Repos\CodeGeneration.Roslyn\src\..\bin\CodeGeneration.Roslyn.Tasks\Debug\net46\CodeGeneration.Roslyn.Tasks.Helper.dll' because it is being used by another process.
6>C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\MSBuild\15.0\Bin\Microsoft.Common.CurrentVersion.targets(4148,5): error MSB3027: Could not copy "C:\Users\Alex\Source\Repos\CodeGeneration.Roslyn\bin\CodeGeneration.Roslyn.Tasks.Helper\Debug\net46\CodeGeneration.Roslyn.Tasks.Helper.dll" to "C:\Users\Alex\Source\Repos\CodeGeneration.Roslyn\src\..\bin\CodeGeneration.Roslyn.Tasks\Debug\net46\CodeGeneration.Roslyn.Tasks.Helper.dll". Exceeded retry count of 10. Failed.
6>C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\MSBuild\15.0\Bin\Microsoft.Common.CurrentVersion.targets(4148,5): error MSB3021: Unable to copy file "C:\Users\Alex\Source\Repos\CodeGeneration.Roslyn\bin\CodeGeneration.Roslyn.Tasks.Helper\Debug\net46\CodeGeneration.Roslyn.Tasks.Helper.dll" to "C:\Users\Alex\Source\Repos\CodeGeneration.Roslyn\src\..\bin\CodeGeneration.Roslyn.Tasks\Debug\net46\CodeGeneration.Roslyn.Tasks.Helper.dll". The process cannot access the file 'C:\Users\Alex\Source\Repos\CodeGeneration.Roslyn\src\..\bin\CodeGeneration.Roslyn.Tasks\Debug\net46\CodeGeneration.Roslyn.Tasks.Helper.dll' because it is being used by another process.
6>Done building project "CodeGeneration.Roslyn.Tasks.csproj" -- FAILED.

I have just cloned repository, rebooted and only process running is VS so I don't know what's wrong with this I have even resintalled VS :) It didn't work.

Probably it's because of uncommon place for binaries, but I have fresh VS installation and fresh repo so it should be something with repo itself, environment is fine.

Sample app is not working.

Hello.
I was trying to use your library in small test application and failed.
What I was doing:

  1. Created simple ConsoleApplication1.
  2. Added new ClassLibrary1
  3. Installed Nuget package CodeGeneration.Roslyn 0.1.57 to class library.
  4. Added DuplicateWithSuffixAttribute and DuplicateWithSuffixGenerator classes from README.md to my class libraty.
    (4.1.) Fixed a little DuplicateWithSuffixGenerator (IReadonlyCollection changed to SyntaxList).
  5. Added Foo class to my ConsoleApplication1.
  6. Added [DuplicateWithSuffix("A")] attribute to Foo class.
  7. Set Custom Tool property of Foo.cs file to MsBuild:GenerateCodeFromAttributes.
  8. Added var fooA = new FooA(); line to Main method.
  9. Tried to build my test solution.

And unfortunately, ConsoleApplication1 is not building with error error CS0246: The type or namespace name 'FooA' could not be found (are you missing a using directive or an assembly reference?). No other errors or warnings.
My guess is that GenerateCodeFromAttributes task is not launching.
If I can provide any additional information, please let me know.

Thanks.

Problem with #if #endif in using

Hello,

If you have an #endif in end of using section Then you don't set it in the generated code

#if NETSTANDARD1_3
using SomeLib;
#else
using AnotherLib;
#endif

in generated code you get
#if NETSTANDARD1_3
using SomeLib;
#else
using AnotherLib;

so you are stuck

Known workarounds

set an using after #endif

The .NET dlls distributed with CodeGeneration.Roslyn.BuildTime are the wrong version

Create a new .NET Framework 4.6 project (which will become a code generator), add a nuget reference to CodeGeneration.Roslyn.0.3.9. This will add dependent packages to the project including, for example, Microsoft.CodeAnalysis.CSharp.1.3.2.

However, package CodeGeneration.Roslyn.BuildTime.0.3.9 includes several .NET dlls in its build directory, including, for example, build\net46\Microsoft.CodeAnalysis.CSharp.dll with version 1.3.1.60621.

The problem really showed up for me when my generator also referenced Microsoft.CodeAnalysis.CSharp.Workspaces, which, due to the other version 1.3.2 packages in the generator project, must also be version 1.3.2. This situation causes a variety of confusing type system related exceptions at build time, as the build task side of things expects version 1.3.1 (etc) dlls, and the generator is built against and has local copies of version 1.3.2 (etc) dlls.

Replacing the 1.3.1 (etc) dlls in the extracted CodeGeneration.Roslyn.BuildTime.0.3.9 package with 1.3.2 (etc) dlls fixes the problem (all be it temporarily and unmaintainably).

Doesn't work with Microsoft.NET.SDK based project

Repro steps

  1. Load TestRoslynGenerator solution TestRoslynGenerator.zip into VS2017
    1. I've tried with 15.4.1 and 15.5.0 Preview 2 same results
  2. Build the solution (F6)

Expected

successful build

Actual

Error MSB6006 "dotnet" exited with code 1

Additional Details

After enabling full diagnostics in MSBuild I found the call to dotnet.exe and a message that provides some further hint on the problem:

dotnet codegen 
-r C:\Users\USERNAMEXYZ\.nuget\packages\codegeneration.roslyn.attributes\0.4.11\lib\netstandard1.0\CodeGeneration.Roslyn.Attributes.dll 
-r C:\Users\USERNAMEXYZ\.nuget\packages\codegeneration.roslyn\0.4.11\lib\netstandard1.5\CodeGeneration.Roslyn.dll
[ Standard .NET lib references not shown for brevity]
-r "C:\Users\USERNAMEXYZ\Documents\Visual Studio 2017\Projects\TestRoslynGenerator\TestRoslynGenerator\bin\Debug\netstandard1.5\TestRoslynGenerator.dll" 
-r C:\Users\USERNAMEXYZ\.nuget\packages\validation\2.4.13\lib\netstandard1.3\Validation.dll 
--out obj\Debug\netstandard1.5\ 
--generatedFilesList obj\Debug\netstandard1.5\y1sshcfo.ivy 
-- Consumer.cs

No executable found matching command "dotnet-codegen"

I don't pretend to understand the dotnet.exe tooling well enough to know what that means.

Suggestion

Provide complete standalone sample solution(s) that are built and validated as part of CI builds so it is easier for users to try and can catch issues in the builds

Referencing the code generator attribute DLL via output path breaks the compile step

When I reference the code generator by selecting the DLL from its output path then the project can no longer be built. (using a project-to-project reference works but requires the generator project to be loaded into the same solution)

1>------ Build started: Project: Test, Configuration: Debug Any CPU ------
1>C:\Users\...\.nuget\packages\codegeneration.roslyn.buildtime\0.2.10\build\CodeGeneration.Roslyn.BuildTime.targets(20,5): error MSB4018: The "GenerateCodeFromAttributes" task failed unexpectedly.
1>C:\Users\...\.nuget\packages\codegeneration.roslyn.buildtime\0.2.10\build\CodeGeneration.Roslyn.BuildTime.targets(20,5): error MSB4018: System.Reflection.ReflectionTypeLoadException: Mindestens ein Typ in der Assembly kann nicht geladen werden. Rufen Sie die LoaderExceptions-Eigenschaft ab, wenn Sie weitere Informationen benรถtigen.
1>C:\Users\...\.nuget\packages\codegeneration.roslyn.buildtime\0.2.10\build\CodeGeneration.Roslyn.BuildTime.targets(20,5): error MSB4018:    at System.Reflection.RuntimeModule.GetTypes(RuntimeModule module)
1>C:\Users\...\.nuget\packages\codegeneration.roslyn.buildtime\0.2.10\build\CodeGeneration.Roslyn.BuildTime.targets(20,5): error MSB4018:    at System.Reflection.RuntimeAssembly.get_DefinedTypes()
1>C:\Users\...\.nuget\packages\codegeneration.roslyn.buildtime\0.2.10\build\CodeGeneration.Roslyn.BuildTime.targets(20,5): error MSB4018:    at System.Composition.Hosting.ContainerConfiguration.<WithAssemblies>b__0(Assembly a)
1>C:\Users\...\.nuget\packages\codegeneration.roslyn.buildtime\0.2.10\build\CodeGeneration.Roslyn.BuildTime.targets(20,5): error MSB4018:    at System.Linq.Enumerable.<SelectManyIterator>d__16`2.MoveNext()
1>C:\Users\...\.nuget\packages\codegeneration.roslyn.buildtime\0.2.10\build\CodeGeneration.Roslyn.BuildTime.targets(20,5): error MSB4018:    at System.Composition.TypedParts.TypedPartExportDescriptorProvider..ctor(IEnumerable`1 types, AttributedModelProvider attributeContext)
1>C:\Users\...\.nuget\packages\codegeneration.roslyn.buildtime\0.2.10\build\CodeGeneration.Roslyn.BuildTime.targets(20,5): error MSB4018:    at System.Composition.Hosting.ContainerConfiguration.CreateContainer()
1>C:\Users\...\.nuget\packages\codegeneration.roslyn.buildtime\0.2.10\build\CodeGeneration.Roslyn.BuildTime.targets(20,5): error MSB4018:    at Microsoft.CodeAnalysis.Host.Mef.MefHostServices.Create(IEnumerable`1 assemblies)
1>C:\Users\...\.nuget\packages\codegeneration.roslyn.buildtime\0.2.10\build\CodeGeneration.Roslyn.BuildTime.targets(20,5): error MSB4018:    at Microsoft.CodeAnalysis.Host.Mef.MefHostServices.get_DefaultHost()
1>C:\Users\...\.nuget\packages\codegeneration.roslyn.buildtime\0.2.10\build\CodeGeneration.Roslyn.BuildTime.targets(20,5): error MSB4018:    at Microsoft.CodeAnalysis.AdhocWorkspace..ctor()
1>C:\Users\...\.nuget\packages\codegeneration.roslyn.buildtime\0.2.10\build\CodeGeneration.Roslyn.BuildTime.targets(20,5): error MSB4018:    at CodeGeneration.Roslyn.Tasks.Helper.CreateProject()
1>C:\Users\...\.nuget\packages\codegeneration.roslyn.buildtime\0.2.10\build\CodeGeneration.Roslyn.BuildTime.targets(20,5): error MSB4018:    at CodeGeneration.Roslyn.Tasks.Helper.<<Execute>b__37_1>d.MoveNext()
1>C:\Users\...\.nuget\packages\codegeneration.roslyn.buildtime\0.2.10\build\CodeGeneration.Roslyn.BuildTime.targets(20,5): error MSB4018: --- End of stack trace from previous location where exception was thrown ---
1>C:\Users\...\.nuget\packages\codegeneration.roslyn.buildtime\0.2.10\build\CodeGeneration.Roslyn.BuildTime.targets(20,5): error MSB4018:    at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
1>C:\Users\...\.nuget\packages\codegeneration.roslyn.buildtime\0.2.10\build\CodeGeneration.Roslyn.BuildTime.targets(20,5): error MSB4018:    at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
1>C:\Users\...\.nuget\packages\codegeneration.roslyn.buildtime\0.2.10\build\CodeGeneration.Roslyn.BuildTime.targets(20,5): error MSB4018:    at CodeGeneration.Roslyn.Tasks.Helper.Execute()
1>C:\Users\...\.nuget\packages\codegeneration.roslyn.buildtime\0.2.10\build\CodeGeneration.Roslyn.BuildTime.targets(20,5): error MSB4018:    at CodeGeneration.Roslyn.Tasks.Helper.Execute()
1>C:\Users\...\.nuget\packages\codegeneration.roslyn.buildtime\0.2.10\build\CodeGeneration.Roslyn.BuildTime.targets(20,5): error MSB4018:    at CodeGeneration.Roslyn.Tasks.GenerateCodeFromAttributes.Execute()
1>C:\Users\...\.nuget\packages\codegeneration.roslyn.buildtime\0.2.10\build\CodeGeneration.Roslyn.BuildTime.targets(20,5): error MSB4018:    at Microsoft.Build.BackEnd.TaskExecutionHost.Microsoft.Build.BackEnd.ITaskExecutionHost.Execute()
1>C:\Users\...\.nuget\packages\codegeneration.roslyn.buildtime\0.2.10\build\CodeGeneration.Roslyn.BuildTime.targets(20,5): error MSB4018:    at Microsoft.Build.BackEnd.TaskBuilder.<ExecuteInstantiatedTask>d__26.MoveNext()
========== Build: 0 succeeded, 1 failed, 1 up-to-date, 0 skipped ==========

Using VS 2017 RTM and nuget package 0.2.10

Note: I've made sure to set build dependencies manually so the problem is not that VS tries to compile both at the same time and the DLL is temporarily gone. [edit] also the problem happens if the project is not in the solution at all.

Reporting progress and dealing with internal errors

Hi

First off thank you for your efforts on this tool.

I was having an issue where my generator was throwing an exception (my fault :)) and there was a lack of detail coming from Visual Studio.

20170712-dotnet-error

I've prepared a branch with the following changes

  • Progress object is no longer null and reporting of diagnostic to stdout.
  • try\catch around each file
  • addition of a basic diagnostic that reports the exception during transform

This sees the following detail added to Visual Studio

20170712-vserrors

Support multiple source files with same file name

Whether the files with equivalent names are in different folders of the same project, or linked in via Shared Project, we need to support the scenario.
One real use case is dotnet/pinvoke#76 where we have kernel32.cs appearing in both desktop and shared projects, and they are overwriting each other and causing build breaks.

not sure how to replace or add to method contents

Your example shows how to add an additional class. I want to augment my actors project (https://github.com/BrannonKing/Kts.Actors) so that I can perform the actor insertion based on an attribute. To do that, I have to add a class field, rename and privatize the method the code generation attribute was on, and make a new method to call, among other things. By returning a list of generated code, how can I modify existing code? Or what exactly is represented by the GenerateAsync method's return value?

Making it work on Omnisharp

I am able to build .NET Standard 2.0 projects with code generation with the dotnet CLI tool, so I know that this works outside of Visual Studio. Unfortunately the Intellisense provided by the VS Code C# extension (which uses OmniSharp) doesn't seem to pick up on the generated code.

I don't really know whether this is possible, or how much work it would involve, but it would be really useful if this could be made to work with proper Intellisense.

How to debug and log

How does one

  1. Attach a debugger to step through a generator?
  2. Log from the generator, and view those logs?

Allow to add custom usings in generated code.

Hello, I met a problem as i'm trying to generate code for NET3.5 and netstandard for Diagnostics.Tracing but in NET3.5 I have Microsoft.Diagnostics.Tracing and for netstandard it's System.Diagnostics.Tracing.

I don't know if there is a way so that the generator get the targetFramework or if I could add some using to my generated class.

Xml documentation comments from assembly references are not available

All calls to ISymbol.GetXmlDocumentationComment for framework and other direct assembly references (ie, assemblies not being built) returns empty string. From what I can work out, a DocumentationProvider needs to be supplied when calling MetadataReference.CreateFromFile. More recent versions of Microsoft.CodeAnalysis.Workspaces dll expose Microsoft.CodeAnalysis.XmlDocumentationProvider publicly (1.3.2 does not, 2.2.0 does, I'm not sure where the change occurred), which then gives XmlDocumentationProvider.CreateFromFile. I've tried to apply the change myself, but updating the various 1.3.2 packages to 2.2.0 leads to a world of pain. Note that I'm using nuget packages 0.3.9 and the v0.3 branch.

var xmlDocPath = Path.ChangeExtension( p.ItemSpec, ".xml" );
return MetadataReference.CreateFromFile( p.ItemSpec, documentation: File.Exists( xmlDocPath ) ? XmlDocumentationProvider.CreateFromFile( xmlDocPath ) : null );

JIT impact on build perf

We JIT Roslyn, MEF, and other assemblies repeatedly during a long build (e.g. the PInvoke project).

Are we hosting the AppDomain in such a way that the CLR won't load ngen images?

Example code doesn't work when targeting netstandard2.0 or netcoreapp2.0

I'm able to get the example to work as shown (targeting netstandard1.5), but if I retarget it to netstandard2.0 or netcoreapp2.0, it no longer seem to work. Poking around at some of the intermediate files, it looks like the temporary .cs file is still generated, but it only has the using statements in it -- no original or modified code (if that makes sense). As a consequence, the output assembly doesn't have the suffixed type in it.

Code generation not working in some projects

After following the instructions on the front page I could get the dynamic code files generated, but they were not included in the project (i.e. compiler complains that generated methods don't exist) nor were they visible in intellisense.

After restarting VS (2015 Update 3) a few times at some point intellisense started to work and I could see the generated methods, however when compiling it still complains that the generated methods don't exist.

This is a WPF project; if I create a separate desktop-library project everything works, so I suspect WPF (or something contained in my project) is causing issues with the code generation. In the msbuild output I cannot see any difference between the WPF project and the library project (it just says the task starts and then completes). Any idea how to diagnose this further?

Walkthrough appears to be broken, have other issues

I made a repo for this repro: https://github.com/jaredthirsk/CodeGeneration.Roslyn.Walkthrough

Minor issues with the walkthrough instructions:

  • "This must be done in a library that targets netstandard1.3 or net46 (or later)": I created a new NETStandard 1.3 project and added CodeGeneration.Roslyn but it says "Package CodeGeneration.Roslyn 0.4.11 is not compatible with netstandard1.3 (.NETStandard,Version=v1.3). Package CodeGeneration.Roslyn 0.4.11 supports: netstandard1.5 (.NETStandard,Version=v1.5)
    One or more packages are incompatible with .NETStandard,Version=v1.3."

  • "You may need to define this property in your .NET SDK netstandard project to workaround the problem with the Microsoft.Composition NuGet package:" Why would I need to follow this instruction? What is the symptom that would show me I need to do this? (What does the Microsoft.Composition package have to do with anything?)

Breaking problem:

I created a .NETStandard 1.5 library that references my NETStandard 1.5 generator library but I get this build output:

1>------ Build started: Project: Walkthrough.Generators.NETStandard15, Configuration: Debug Any CPU ------
1>Walkthrough.Generators.NETStandard15 -> C:\forks\CodeGeneration.Roslyn.Walkthrough\src\Walkthrough.Generators.NETStandard15\bin\Debug\netstandard1.5\Walkthrough.Generators.NETStandard15.dll
2>------ Build started: Project: Walkthrough.Foo.NETStandard15, Configuration: Debug Any CPU ------
2>C:\Users\ja\.nuget\packages\codegeneration.roslyn.buildtime\0.4.11\build\CodeGeneration.Roslyn.BuildTime.targets(20,5): error MSB6006: "dotnet" exited with code 1.
2>Done building project "Walkthrough.Foo.NETStandard15.csproj" -- FAILED.
========== Build: 1 succeeded or up-to-date, 1 failed, 0 skipped ==========

It's hiding the actual error. If I run msbuild from the developer command prompt, here is the output:
(I tried using bold to highlight errors but it doesn't work inside a code block. So search for ** to see interesting parts.)

Microsoft (R) Build Engine version 15.1.1012.6693
Copyright (C) Microsoft Corporation. All rights reserved.

Building the projects in this solution one at a time. To enable parallel build, please add the "/m" switch.
Build started 2017-07-29 6:40:43 AM.
Project "C:\forks\CodeGeneration.Roslyn.Walkthrough\src\Walkthrough.Generators.sln" on node 1 (default targets).
ValidateSolutionConfiguration:
  Building solution configuration "Debug|Any CPU".
Project "C:\forks\CodeGeneration.Roslyn.Walkthrough\src\Walkthrough.Generators.sln" (1) is building "C:\forks\CodeGeneration.Roslyn.Walkthrough\src\Walkthrough.Generators.NET462\Walkthrough.Generators.NET462.csproj" (2) on node 1 (default targets).
**C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\MSBuild\Microsoft\NuGet\15.0\Microsoft.NuGet.targets(178,5): error : Your project.json doesn't have a runtimes section. You should add '"runtimes": { "win": { } }' to your project.json and then re-run NuGet restore. [C:\forks\CodeGeneration.Roslyn.Walkthrough\src\Walkthrough.Generators.NET462\Walkthrough.Generators.NET462.csproj]**
Done Building Project "C:\forks\CodeGeneration.Roslyn.Walkthrough\src\Walkthrough.Generators.NET462\Walkthrough.Generators.NET462.csproj" (default targets) -- **FAILED**.
Project "C:\forks\CodeGeneration.Roslyn.Walkthrough\src\Walkthrough.Generators.sln" (1) is building "C:\forks\CodeGeneration.Roslyn.Walkthrough\src\Walkthrough.Generators.NETStandard15\Walkthrough.Generators.NETStandard15.csproj" (3) on node 1 (default targets).
GenerateTargetFrameworkMonikerAttribute:
Skipping target "GenerateTargetFrameworkMonikerAttribute" because all output files are up-to-date with respect to the input files.
CoreGenerateAssemblyInfo:
Skipping target "CoreGenerateAssemblyInfo" because all output files are up-to-date with respect to the input files.
CoreCompile:
Skipping target "CoreCompile" because all output files are up-to-date with respect to the input files.
GenerateBuildDependencyFile:
Skipping target "GenerateBuildDependencyFile" because all output files are up-to-date with respect to the input files.
CopyFilesToOutputDirectory:
  Walkthrough.Generators.NETStandard15 -> C:\forks\CodeGeneration.Roslyn.Walkthrough\src\Walkthrough.Generators.NETStandard15\bin\Debug\netstandard1.5\Walkthrough.Generators.NETStandard15.dll
Done Building Project "C:\forks\CodeGeneration.Roslyn.Walkthrough\src\Walkthrough.Generators.NETStandard15\Walkthrough.Generators.NETStandard15.csproj" (default targets).
Project "C:\forks\CodeGeneration.Roslyn.Walkthrough\src\Walkthrough.Generators.sln" (1) is building "C:\forks\CodeGeneration.Roslyn.Walkthrough\src\Walkthrough.Foo.NETStandard15\Walkthrough.Foo.NETStandard15.csproj" (4) on node 1 (default targets).
GenerateCodeFromAttributes:
  dotnet codegen -r C:\Users\ja\.nuget\packages\codegeneration.roslyn.attributes\0.4.11\lib\netstandard1.0\CodeGeneration.Roslyn.Attributes.dll -r C:\Users\ja\.nuget\packages\codegeneration.roslyn\0.4.11\lib\netstandard1.5\CodeGeneration.Roslyn.dll -r C:\Users\ja\.nuget\packages\microsoft.codeanalysis.csharp\2.2.0\lib\netstandard1.3\Microsoft.CodeAnalysis.CSharp.dll -r C:\Users\ja\.nuget\packages\microsoft.codeanalysis.common\2.2.0\lib\netstandard1.3\Microsoft.CodeAnalysis.dll -r C:\Users\ja\.nuget\packages\microsoft.win32.primitives\4.3.0\ref\netstandard1.3\Microsoft.Win32.Primitives.dll -r C:\Users\ja\.nuget\packages\system.appcontext\4.3.0\ref\netstandard1.3\System.AppContext.dll -r C:\Users\ja\.nuget\packages\system.collections.concurrent\4.3.0\ref\netstandard1.3\System.Collections.Concurrent.dll -r C:\Users\ja\.nuget\packages\system.collections\4.3.0\ref\netstandard1.3\System.Collections.dll -r C:\Users\ja\.nuget\packages\system.collections.immutable\1.3.1\lib\netstandard1.0\System.Collections.Immutable.dll -r C:\Users\ja\.nuget\packages\system.console\4.3.0\ref\netstandard1.3\System.Console.dll -r C:\Users\ja\.nuget\packages\system.diagnostics.debug\4.3.0\ref\netstandard1.3\System.Diagnostics.Debug.dll -r C:\Users\ja\.nuget\packages\system.diagnostics.tools\4.3.0\ref\netstandard1.0\System.Diagnostics.Tools.dll -r C:\Users\ja\.nuget\packages\system.diagnostics.tracing\4.3.0\ref\netstandard1.5\System.Diagnostics.Tracing.dll -r C:\Users\ja\.nuget\packages\system.dynamic.runtime\4.3.0\ref\netstandard1.3\System.Dynamic.Runtime.dll -r C:\Users\ja\.nuget\packages\system.globalization.calendars\4.3.0\ref\netstandard1.3\System.Globalization.Calendars.dll -r C:\Users\ja\.nuget\packages\system.globalization\4.3.0\ref\netstandard1.3\System.Globalization.dll -r C:\Users\ja\.nuget\packages\system.io.compression\4.3.0\ref\netstandard1.3\System.IO.Compression.dll -r C:\Users\ja\.nuget\packages\system.io.compression.zipfile\4.3.0\ref\netstandard1.3\System.IO.Compression.ZipFile.dll -r C:\Users\ja\.nuget\packages\system.io\4.3.0\ref\netstandard1.5\System.IO.dll -r C:\Users\ja\.nuget\packages\system.io.filesystem\4.3.0\ref\netstandard1.3\System.IO.FileSystem.dll -r C:\Users\ja\.nuget\packages\system.io.filesystem.primitives\4.3.0\ref\netstandard1.3\System.IO.FileSystem.Primitives.dll -r C:\Users\ja\.nuget\packages\system.linq\4.3.0\ref\netstandard1.0\System.Linq.dll -r C:\Users\ja\.nuget\packages\system.linq.expressions\4.3.0\ref\netstandard1.3\System.Linq.Expressions.dll -r C:\Users\ja\.nuget\packages\system.net.http\4.3.0\ref\netstandard1.3\System.Net.Http.dll -r C:\Users\ja\.nuget\packages\system.net.primitives\4.3.0\ref\netstandard1.3\System.Net.Primitives.dll -r C:\Users\ja\.nuget\packages\system.net.sockets\4.3.0\ref\netstandard1.3\System.Net.Sockets.dll -r C:\Users\ja\.nuget\packages\system.objectmodel\4.3.0\ref\netstandard1.3\System.ObjectModel.dll -r C:\Users\ja\.nuget\packages\system.reflection\4.3.0\ref\netstandard1.5\System.Reflection.dll -r C:\Users\ja\.nuget\packages\system.reflection.extensions\4.3.0\ref\netstandard1.0\System.Reflection.Extensions.dll -r C:\Users\ja\.nuget\packages\system.reflection.metadata\1.4.2\lib\netstandard1.1\System.Reflection.Metadata.dll -r C:\Users\ja\.nuget\packages\system.reflection.primitives\4.3.0\ref\netstandard1.0\System.Reflection.Primitives.dll -r C:\Users\ja\.nuget\packages\system.resources.resourcemanager\4.3.0\ref\netstandard1.0\System.Resources.ResourceManager.dll -r C:\Users\ja\.nuget\packages\system.runtime\4.3.0\ref\netstandard1.5\System.Runtime.dll -r C:\Users\ja\.nuget\packages\system.runtime.extensions\4.3.0\ref\netstandard1.5\System.Runtime.Extensions.dll -r C:\Users\ja\.nuget\packages\system.runtime.handles\4.3.0\ref\netstandard1.3\System.Runtime.Handles.dll -r C:\Users\ja\.nuget\packages\system.runtime.interopservices\4.3.0\ref\netstandard1.5\System.Runtime.InteropServices.dll -r C:\Users\ja\.nuget\packages\system.runtime.interopservices.runtimeinformation\4.3.0\ref\netstandard1.1\System.Runtime.InteropServices.RuntimeInformation.dll -r C:\Users\ja\.nuget\packages\system.runtime.loader\4.3.0\ref\netstandard1.5\System.Runtime.Loader.dll -r C:\Users\ja\.nuget\packages\system.runtime.numerics\4.3.0\ref\netstandard1.1\System.Runtime.Numerics.dll -r C:\Users\ja\.nuget\packages\system.security.cryptography.algorithms\4.3.0\ref\netstandard1.4\System.Security.Cryptography.Algorithms.dll -r C:\Users\ja\.nuget\packages\system.security.cryptography.encoding\4.3.0\ref\netstandard1.3\System.Security.Cryptography.Encoding.dll -r C:\Users\ja\.nuget\packages\system.security.cryptography.primitives\4.3.0\ref\netstandard1.3\System.Security.Cryptography.Primitives.dll -r C:\Users\ja\.nuget\packages\system.security.cryptography.x509certificates\4.3.0\ref\netstandard1.4\System.Security.Cryptography.X509Certificates.dll -r C:\Users\ja\.nuget\packages\system.text.encoding\4.3.0\ref\netstandard1.3\System.Text.Encoding.dll -r C:\Users\ja\.nuget\packages\system.text.encoding.extensions\4.3.0\ref\netstandard1.3\System.Text.Encoding.Extensions.dll -r C:\Users\ja\.nuget\packages\system.text.regularexpressions\4.3.0\ref\netstandard1.3\System.Text.RegularExpressions.dll -r C:\Users\ja\.nuget\packages\system.threading\4.3.0\ref\netstandard1.3\System.Threading.dll -r C:\Users\ja\.nuget\packages\system.threading.tasks\4.3.0\ref\netstandard1.3\System.Threading.Tasks.dll -r C:\Users\ja\.nuget\packages\system.threading.tasks.parallel\4.3.0\ref\netstandard1.1\System.Threading.Tasks.Parallel.dll -r C:\Users\ja\.nuget\packages\system.threading.timer\4.3.0\ref\netstandard1.2\System.Threading.Timer.dll -r C:\Users\ja\.nuget\packages\system.valuetuple\4.3.0\lib\netstandard1.0\System.ValueTuple.dll -r C:\Users\ja\.nuget\packages\system.xml.readerwriter\4.3.0\ref\netstandard1.3\System.Xml.ReaderWriter.dll -r C:\Users\ja\.nuget\packages\system.xml.xdocument\4.3.0\ref\netstandard1.3\System.Xml.XDocument.dll -r C:\Users\ja\.nuget\packages\validation\2.4.13\lib\netstandard1.3\Validation.dll -r C:\forks\CodeGeneration.Roslyn.Walkthrough\src\Walkthrough.Generators.NETStandard15\bin\Debug\netstandard1.5\Walkthrough.Generators.NETStandard15.dll --out obj\Debug\netstandard1.5\ --generatedFilesList obj\Debug\netstandard1.5\rgqkfkhj.41x -- Foo.cs 
  **_No executable found matching command "dotnet-codegen"_**
**C:\Users\ja\.nuget\packages\codegeneration.roslyn.buildtime\0.4.11\build\CodeGeneration.Roslyn.BuildTime.targets(20,5): error MSB6006: "dotnet" exited with code 1.** [C:\forks\CodeGeneration.Roslyn.Walkthrough\src\Walkthrough.Foo.NETStandard15\Walkthrough.Foo.NETStandard15.csproj]
GenerateBuildDependencyFile:
Skipping target "GenerateBuildDependencyFile" because all output files are up-to-date with respect to the input files.
Done Building Project "C:\forks\CodeGeneration.Roslyn.Walkthrough\src\Walkthrough.Foo.NETStandard15\Walkthrough.Foo.NETStandard15.csproj" (default targets) -- FAILED.
Done Building Project "C:\forks\CodeGeneration.Roslyn.Walkthrough\src\Walkthrough.Generators.sln" (default targets) -- **FAILED**.

Build **FAILED**.

"C:\forks\CodeGeneration.Roslyn.Walkthrough\src\Walkthrough.Generators.sln" (default target) (1) ->
"C:\forks\CodeGeneration.Roslyn.Walkthrough\src\Walkthrough.Generators.NET462\Walkthrough.Generators.NET462.csproj" (default target) (2) ->
(ResolveNuGetPackageAssets target) -> 
  C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\MSBuild\Microsoft\NuGet\15.0\Microsoft.NuGet.targets(178,5): error : Your project.json doesn't have a runtimes section. You should add '"runtimes": { "win": { } }' to your project.json and then re-run NuGet restore. [C:\forks\CodeGeneration.Roslyn.Walkthrough\src\Walkthrough.Generators.NET462\Walkthrough.Generators.NET462.csproj]


"C:\forks\CodeGeneration.Roslyn.Walkthrough\src\Walkthrough.Generators.sln" (default target) (1) ->
"C:\forks\CodeGeneration.Roslyn.Walkthrough\src\Walkthrough.Foo.NETStandard15\Walkthrough.Foo.NETStandard15.csproj" (default target) (4) ->
(GenerateCodeFromAttributes target) -> 
  C:\Users\ja\.nuget\packages\codegeneration.roslyn.buildtime\0.4.11\build\CodeGeneration.Roslyn.BuildTime.targets(20,5): error MSB6006: "dotnet" exited with code 1. [C:\forks\CodeGeneration.Roslyn.Walkthrough\src\Walkthrough.Foo.NETStandard15\Walkthrough.Foo.NETStandard15.csproj]

    0 Warning(s)
    2 Error(s)

Time Elapsed 00:00:02.80

Adding more control to output generation

Currently I encountered two problems that are caused by current design:

  1. Generated members always are nested in parent's namespace. Sometimes it's good, sometimes it's not required.
  2. Generated members always are placed in same assembly where attribute is declared. Again, sometimes it's good, sometimes it's not required.

I propose to add more customisation here. I think ICodeGenerator have to provide somehow information if it want inherit ancestor's usings/namespace or it doesn't and information about path where it want to be stored:

Task<GenerationResult> GenerateAsync(TransformationContext context, IProgress<Diagnostic> progress, CancellationToken cancellationToken);

public class GenerationResult
{
   SyntaxList<MemberDeclarationSyntax> GeneratedMembers { get; }
   string DestinationProjectDirectoryFullPath { get; }
   bool IsNestedInAncestor { get; }
}

It's just an idea, I don't really like how it looks now, but we may invent something better.

Use case: I have an attribute in a class in an assembly foo with multiple dependency, for example, ASP.Net. But I obviosly won't use it in my generator, so I don't want these dependencies. I can create assembly foo.generated without any dependency and store generation results there.

I can try to implement it if you agree that we need this feature and we can merge it in master. It's a bit more complicated than other changes and require some API rework, so I don't want to spend several days to get I cannot afford merging it, it completly ruins my design :)

Build cancellation request is ignored by build task

Even though our MSBuild task implements ICancelableTask, we ignore the cts field that is canceled by the Cancel() method. Assuming VS design-time builds are canceled when solution builds are waiting for their completion, this is causing VS to block for an undue length of time.

As observed when building the PInvoke solution.

command line arguments during build are too long

Consider using a response file instead of generating a large command.

Referencing an asp.net core app already breaks the by causing an

C:\Users\martin.ullrich\.nuget\packages\codegeneration.roslyn.buildtime\0.4.11\build\CodeGeneration.Roslyn.BuildTime.targets(20,5): error MSB6003: The specified task executable "dotnet" could not be run. The filename or extension is too long 

The command-line for the "GenerateCodeFromAttributes" task is too long. Command-lines longer than 32000 characters are likely to fail. Try reducing the length of the command-line by breaking down the call to "GenerateCodeFromAttributes" into multiple calls with fewer parameters per call.

Need support for Visual Studio 2017

It seems that the GenerateCodeFromAttributes task does not work in Visual Studio 2017 RC. The error list window shows:

Severity	Code	       Description
Warning	        IDE0006	       Error encountered while loading the project. Some project
                               features, such as full solution analysis for the failed
                               project and projects that depend on it, have been disabled.

I was able to find the following error details by enabling design time logs as described in IDE0006.

Build FAILED.

C:\...\packages\CodeGeneration.Roslyn.BuildTime.0.1.57\build\CodeGeneration.Roslyn.BuildTime.targets(20,5):
error MSB4018: The "GenerateCodeFromAttributes" task failed unexpectedly.
System.ArgumentException: Object type cannot be converted to target type.
   at CodeGeneration.Roslyn.Tasks.GenerateCodeFromAttributes.Helper.set_Compile(ITaskItem[] value)
   at CodeGeneration.Roslyn.Tasks.GenerateCodeFromAttributes.Execute()
   at Microsoft.Build.BackEnd.TaskExecutionHost.Microsoft.Build.BackEnd.ITaskExecutionHost.Execute()
   at Microsoft.Build.BackEnd.TaskBuilder.<ExecuteInstantiatedTask>d__26.MoveNext()

Code from github does not understand project-to-project references

To diagnose issue #8 I tried building my own version of the library so I can debug it. I had to modify the project files in order to build it (see issue #10) so it may be possible I did something wrong.

Anyways, if I build the library on my own the resulting tool no longer understands project-to-project references from the project consuming a code generator and the project implementing a code generator. Referencing the DLL of the code generator implementation works.

The error caused by the project-to-project reference manifests itself in an exception logged during build, complaining that it can't load an assembly. It tried loading the assembly which consumes the code generator, but it tried loading it from the project output path of the code generator implementation project. Somehow it must have mixed up referenced filenames because loading the project it is about to generate makes no sense at all, nor does it make sense to load it from the output folder of the code generator implementation project. (I suspect it wants to load the code generator implementation but picked up the wrong filename, because the other way round it would make no sense.)

Sorry if the explanation above is a bit confusing, I just thought to document it for the case your nuget package is out of sync with github. In that case it may be a new bug introduced. Otherwise its probably just me having made a mistake while building the project.

Add support for assembly target attributes

Would it be possible to add support for code generators defined with validOn = AttributeTargets.Assembly, meaning that they would not be attached to particular class?

For example:

[assembly: GenerateClass("Foo")]

Replacing method at compilation-time

Maybe I got it all wrong, but is it even possible to exclude attribute consumer MemberDeclarationSyntaxs from compilation?
So if I have a code generation-consumer method, I still have it with same identifier, but slightly changed at buildtime

MSBuild Task throws when P2P reference isn't built yet

This breaks the language service of the project in VS if the P2P isn't built.

The method that creates a metadata reference when creating the compilation project throws a FileNotFoundException and is reported in the VS error list. We should gracefully drop the reference when the file is missing.

Document Shared + Platform scenario.

When having Shared + Platform projects combined and want a code generation involving a class defined in both projects (partial class), the following points are not very clear (IMO).

  1. The code generation attributes should be applied only to the files in the shared project (should I say one of the projects?).
  2. The MSBuild:GenerateCodeFromAttributes custom tool must be applied to every file we want to auto generate code from.

So it would be nice to have this documented somehow here for future references.

Document NuGet packaging steps

You refer to the steps of packaging everything up as being tedious. Could you please at least list out the general steps needed?

My goal here is to adjust my NuGet packaging build script to correctly package up everything that is needed so that my code generator can be distributed via NuGet.

Question on performance

Is there anything in place to speed up generation if the source file didn't change from the last build?

Error with dotnet-codegen

Hello,

I try to do a sample following your readme but I can't compile it.

I got an error in
Task "GenerateCodeFromAttributes"
dotnet codegen

Unhandled Exception: System.IO.FileNotFoundException: Could not load file or assembly 'System.CommandLine, Version=0.1.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60'. The system cannot find the file specified.

MEF impact on build perf

MEF composition time. Each project (in the PInvoke project) repeats MEF discovery and composition instead of reusing results at least within the same process across projects. We should consider ways to reuse the work across projects -- possibly by making the AppDomain a static variable.

Although that risks locking DLLs after the build is finished if the nodes don't get unloaded.

problem with #endregion

If I add Methods to an class using this generator, and at the end of the class is an #endregion, this #endregion is also inserted in the generated code. This leads to an compiling error because #region is missing.

partial class Test {
    private bool test;
#region testRegion
[Generate]
void SomeMethod(){}
#endregion
}

Assuming the Generator does nothing this results in following:

partial class Test {
   
#endregion
}

Code from github does not compile in VS 2015

While trying to diagnose issue #8 I tried building my own version of the library so I can debug it, but it does not build cleanly at all in VS 2015 Update 3

  • nuproj files don't load into the IDE (I did install the nuproj extension)
  • the 'CodeGeneration.Roslyn' project references 'CodeGeneration.Roslyn.Attributes' in a way the IDE does not understand (yellow triangle on the item in the references subtree) but this does not seem to prevent it building
  • the 'CodeGeneration.Roslyn' project makes use of the 'Validation' nuget package without referencing it
  • the property pages of the two Attribute projects can't be opened: An error occurred trying to load the page. Additional text found in JSON string after finishing deserializing object. but they do compile

I suspect that this project is meant to be build on "Dev15" ? Anyways even if above issues can't be fixed it'd be great to have some info about building the code in the readme (like required VS version and dependencies on VS extensions)

Cannot get dotnet-codegen

Here is a screencast of my attempt to follow the readme: http://somup.com/cbQUrbVbPx

  1. Started a new project in Visual Studio 2017
  2. Added a second project to the solution ("Your generator cannot be defined in the same project that will have code generated for it")
  3. "Install the CodeGeneration.Roslyn NuGet Package." via Visual Studio's NuGet GUI
  4. "Define the generator class:"
  5. "Define attribute" in the main project (rather than the Generator project) because "define your attribute in another assembly if it must be applied to projects that target older platforms."
  6. "install the CodeGeneration.Roslyn.Attributes package" to the main project
  7. "Define your attribute class." and "specify the assembly-qualified name of the generator type as a string instead"
  8. BUILD FAILS because dotnet-codegen doesn't exist. Skim through issues, discover that the part of the documentation about consuming a redistributed generator is actually required here.
  9. Try installing dotnet-codegen via NeGet GUI - it fails because package type 'DotnetCliTool' that is not supported by project
  10. Try installing dotnet-codegen by adding the given nuget.conf and DotNetCliToolReference XML
  11. "Make sure that the DotNetCliToolReference version matches the version of the CodeGeneration.Roslyn package your package depends on."
  12. Try command-line restore - The imported project "C:\Program Files\dotnet\sdk\1.1.0\Microsoft\Portable\v4.5\Microsoft.Portable.CSharp.targets" was not found.
  13. Try getting the dotnet-codegen by creating a new project that is dotnetcoreapp1.0, still run into DotNetCliToolReference is not supported.

netstandard2.0 breaks Generator

I've targeted netstandard2.0 with my generator in private project and it took some time before I realized that this was the change that broke my builds. I've created separate issue although I see #48 - I think that I generalized the issue since the other one is about the example from this repo. It may very well be closed as duplicate if it's not separate enough.

I've created a repro repo https://github.com/amis92/CodeGenerationBugDemo

Repro steps:

  1. Change CodeGenerationBugDemo.Generator target to netstandard2.0 (as opposed to netstandard1.5 or netstandard1.6).
  2. Observe that:
    a. CodeGenerationBugDemo.Library.DemoClass doesn't compile since the invoked method was not generated.
    b. CodeGenerationBugDemo.GeneratorTests.DemoGeneratorTests.GivenTestClass_CanInvokeGeneratedMethod test fails because the method was not generated.

Expected: netstandard2.0 target for Generator is supported.

Microsoft.Build.Utilities.Core not found

Hi,

I'm getting the following error.

......\packages\CodeGeneration.Roslyn.BuildTime.0.1.57\build\CodeGeneration.Roslyn.BuildTime.targets(20,5): error MSB4018: The "GenerateCodeFromAttributes" task failed unexpectedly.
......\packages\CodeGeneration.Roslyn.BuildTime.0.1.57\build\CodeGeneration.Roslyn.BuildTime.targets(20,5): error MSB4018: System.IO.FileNotFoundException: Could not load file or assembly 'Microsoft.Build.Utilities.Core, Version=14.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' or one of its dependencies. The system cannot find the file specified.
......\packages\CodeGeneration.Roslyn.BuildTime.0.1.57\build\CodeGeneration.Roslyn.BuildTime.targets(20,5): error MSB4018: File name: 'Microsoft.Build.Utilities.Core, Version=14.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'
......\packages\CodeGeneration.Roslyn.BuildTime.0.1.57\build\CodeGeneration.Roslyn.BuildTime.targets(20,5): error MSB4018:    at System.Reflection.RuntimeAssembly.GetType(RuntimeAssembly assembly, String name, Boolean throwOnError, Boolean ignoreCase, ObjectHandleOnStack type)
......\packages\CodeGeneration.Roslyn.BuildTime.0.1.57\build\CodeGeneration.Roslyn.BuildTime.targets(20,5): error MSB4018:    at System.Reflection.RuntimeAssembly.GetType(String name, Boolean throwOnError, Boolean ignoreCase)
......\packages\CodeGeneration.Roslyn.BuildTime.0.1.57\build\CodeGeneration.Roslyn.BuildTime.targets(20,5): error MSB4018:    at System.Activator.CreateInstance(String assemblyString, String typeName, Boolean ignoreCase, BindingFlags bindingAttr, Binder binder, Object[] args, CultureInfo culture, Object[] activationAttributes, Evidence securityInfo, StackCrawlMark& stackMark)
......\packages\CodeGeneration.Roslyn.BuildTime.0.1.57\build\CodeGeneration.Roslyn.BuildTime.targets(20,5): error MSB4018:    at System.Activator.CreateInstance(String assemblyName, String typeName)
......\packages\CodeGeneration.Roslyn.BuildTime.0.1.57\build\CodeGeneration.Roslyn.BuildTime.targets(20,5): error MSB4018:    at System.AppDomain.CreateInstance(String assemblyName, String typeName)
......\packages\CodeGeneration.Roslyn.BuildTime.0.1.57\build\CodeGeneration.Roslyn.BuildTime.targets(20,5): error MSB4018:    at System.AppDomain.CreateInstanceAndUnwrap(String assemblyName, String typeName)
......\packages\CodeGeneration.Roslyn.BuildTime.0.1.57\build\CodeGeneration.Roslyn.BuildTime.targets(20,5): error MSB4018:    at System.AppDomain.CreateInstanceAndUnwrap(String assemblyName, String typeName)
......\packages\CodeGeneration.Roslyn.BuildTime.0.1.57\build\CodeGeneration.Roslyn.BuildTime.targets(20,5): error MSB4018:    at CodeGeneration.Roslyn.Tasks.GenerateCodeFromAttributes.Execute()
......\packages\CodeGeneration.Roslyn.BuildTime.0.1.57\build\CodeGeneration.Roslyn.BuildTime.targets(20,5): error MSB4018:    at Microsoft.Build.BackEnd.TaskExecutionHost.Microsoft.Build.BackEnd.ITaskExecutionHost.Execute()
......\packages\CodeGeneration.Roslyn.BuildTime.0.1.57\build\CodeGeneration.Roslyn.BuildTime.targets(20,5): error MSB4018:    at Microsoft.Build.BackEnd.TaskBuilder.<ExecuteInstantiatedTask>d__26.MoveNext()
......\packages\CodeGeneration.Roslyn.BuildTime.0.1.57\build\CodeGeneration.Roslyn.BuildTime.targets(20,5): error MSB4018: 
......\packages\CodeGeneration.Roslyn.BuildTime.0.1.57\build\CodeGeneration.Roslyn.BuildTime.targets(20,5): error MSB4018: WRN: Assembly binding logging is turned OFF.
......\packages\CodeGeneration.Roslyn.BuildTime.0.1.57\build\CodeGeneration.Roslyn.BuildTime.targets(20,5): error MSB4018: To enable assembly bind failure logging, set the registry value [HKLM\Software\Microsoft\Fusion!EnableLog] (DWORD) to 1.
......\packages\CodeGeneration.Roslyn.BuildTime.0.1.57\build\CodeGeneration.Roslyn.BuildTime.targets(20,5): error MSB4018: Note: There is some performance penalty associated with assembly bind failure logging.
......\packages\CodeGeneration.Roslyn.BuildTime.0.1.57\build\CodeGeneration.Roslyn.BuildTime.targets(20,5): error MSB4018: To turn this feature off, remove the registry value [HKLM\Software\Microsoft\Fusion!EnableLog].
......\packages\CodeGeneration.Roslyn.BuildTime.0.1.57\build\CodeGeneration.Roslyn.BuildTime.targets(20,5): error MSB4018: 

I have only Visual Studio 2017 RC installed, I think I do not have the 'Microsoft.Build.Utilities.Core, Version=14.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' in the GAC registered.
If you could make use of the nuget packges for 'Microsoft.Build.Utilities.Core' it would solve the problem I would guess.

Sample code does not produce new class in VS 2017

I tried the sample in VS 2017. The GenerateAsync method is called (the compilation is failing if exception is thrown) but no new class is created.

The generated class is not available from same project (console application) nor from unit test project.
All project are using .net framework 4.6.2.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.