title: Getting the file path of the .cs file where a type was declared
body: <p>I'm working on a procedural asset generation system and I want it to be able to detect if the source file of a particular asset has changed so that it only has to regenerate assets that will actually be different.</p>
  
  <p>Some googling has told me that there is no way to get the source file of a type using simple reflection, so I'm trying to come up with a workaround. Here's what I'm doing:</p>
  
  <ol>
  <li>Get a list of all .cs files in the project directory using Directory.GetFiles.</li>
  <li>Compile each file into its own assembly using CSharpCodeProvider.CompileAssemblyFromFile.</li>
  <li>If compiledAssembly.GetType(targetType.FullName) exists, then that is the source file of targetType.</li>
  </ol>
  
  <p>The problem is that step 2 is giving compile errors without any sort of description:</p>
  
  <ul>
  <li>(0,0) : error : </li>
  <li>(0,0) : error :   at (wrapper managed-to-native) System.Reflection.Assembly:GetTypes (bool)</li>
  <li>(0,0) : error :   at (wrapper managed-to-native) System.Reflection.Assembly:GetTypes (bool)</li>
  <li>etc.</li>
  </ul>
  
  <p>I think that this may be because the current assembly or app domain or whatever already contains the exact type it's trying to compile, but that's just a guess. Does anyone know what might be causing those errors or how I can avoid them?</p>
  
  <p>Edit: here's the main code for step 2:</p>
  
  <pre><code>private static readonly CSharpCodeProvider CodeProvider = new CSharpCodeProvider();
  private static readonly CompilerParameters CompilerOptions = new CompilerParameters();
  
  static SourceInterpreter()
  {
      // We want a DLL in memory.
      CompilerOptions.GenerateExecutable = false;
      CompilerOptions.GenerateInMemory = true;
  
      // Add references for UnityEngine and UnityEditor DLLs.
      CompilerOptions.ReferencedAssemblies.Add(typeof(Application).Assembly.Location);
      CompilerOptions.ReferencedAssemblies.Add(typeof(EditorApplication).Assembly.Location);
  }
  
  private static Assembly CompileCS(string filePath, out CompilerErrorCollection errors)
  {
      // Compile the assembly from the source script text.
      CompilerResults result = CodeProvider.CompileAssemblyFromFile(CompilerOptions, filePath);
  
      // Store any errors and warnings.
      errors = result.Errors;
  
      foreach (CompilerError e in errors)
      {
          if (!e.IsWarning) Debug.Log(e);
      }
  
      return result.CompiledAssembly;
  }
  </code></pre>