docfx icon indicating copy to clipboard operation
docfx copied to clipboard

DefineConstants / MSBuild Properties not working with non-csproj configurations.

Open Lachee opened this issue 3 years ago • 4 comments

Operating System: (Windows or Linux or MacOS) Windows

DocFX Version Used:

  • docfx 2.44.0.0
  • docfx 2.59.2.0

Template used: (default or statictoc or contain custom template) default

Steps to Reproduce: Via Example

  1. git clone https://github.com/Lachee/docfx-define-constants-issue.git - Repository highlighting issue
  2. cd docfx-define-constants-issue
  3. docfx Documentation/docfx.json

Expected Behavior: The DefineConstants property gets applied to the MSBuild and classes within a #if condition have their documentation generated

Actual Behavior: Anything within a #if gets ignored.

Other:

I have generated a sample project that experiences the issue here: https://github.com/Lachee/docfx-define-constants-issue but the main project that has an issue is my Unity Utilities. It is a Unity Package so doesnt directly have .csproj itself.

Here is the metadata i used

    "metadata": [
        {
            "src": [
                {
                    "src": "..",
                    "files": [ "Scripts/**/*.cs" ]
                }
            ],
            "globalNamespaceId": "Global",
            "dest": "api",
            "properties": {
                "DefineConstants": "SOME_DEFINE=1"
            }
        }
    ],

Lachee avatar May 24 '22 07:05 Lachee

SOME_DEFINE=1 is odd because C# conditional compilation defines cannot have values.

That said, the DocFX implementation looks like it uses Roslyn directly, rather than MSBuild, if you specify *.cs files rather than *.csproj. If you don't have a project, then there's no SDK that would translate the MSBuild property to CSharpParseOptions.PreprocessorSymbolNames. Perhaps DocFX could be changed to recognize the DefineConstants name, construct a CSharpParseOptions instance with the corresponding settings, and pass that to SyntaxFactory.ParseSyntaxTree via CompilationUtility.CreateCompilationFromCsharpCode:

https://github.com/dotnet/docfx/blob/9a3c8aa16adec1be4ee2e62ef45a9a0c78ccef14/src/Microsoft.DocAsCode.Metadata.ManagedReference/ExtractMetadataWorker.cs#L309

https://github.com/dotnet/docfx/blob/9a3c8aa16adec1be4ee2e62ef45a9a0c78ccef14/src/Microsoft.DocAsCode.Metadata.ManagedReference/ExtractMetadata/CompilationUtility.cs#L27

KalleOlaviNiemitalo avatar May 24 '22 09:05 KalleOlaviNiemitalo

If DocFX translated the DefineConstants property in this way, then I expect users would also ask for similar support for the Nullable property. Are there any other MSBuild properties that affect metadata?

KalleOlaviNiemitalo avatar May 24 '22 09:05 KalleOlaviNiemitalo

CodePage might affect metadata, if you have non-ASCII characters in identifiers or string literals. AllowUnsafeBlocks and LangVersion might also be needed, depending on what the defaults are in Roslyn (as opposed to the .NET SDK).

If one needs item types like Reference, I think one should just set up a C# project file that configures those for DocFX, even if that project won't ever be built for other purposes. I don't think DocFX itself should configure references for Roslyn.

KalleOlaviNiemitalo avatar May 24 '22 13:05 KalleOlaviNiemitalo

Is there any update with this? This is a breaking issue for my documentation as it literally stops be from generating half the documentation.

Lachee avatar Jul 05 '22 09:07 Lachee

Is it a unity specific problem? It seems most ordinary .NET projects uses csproj , what is the equivalence in the unity world? In another word, how do you specify SOME_DEFINE=1 in a unity project?

yufeih avatar Feb 01 '23 08:02 yufeih

Also assembly name #4597

yufeih avatar Feb 05 '23 07:02 yufeih

Is it a unity specific problem? It seems most ordinary .NET projects uses csproj , what is the equivalence in the unity world? In another word, how do you specify SOME_DEFINE=1 in a unity project?

Unity defines the scripting symbols itself when compiling.

Newer versions of Unity uses Roslyn to compile.

Unity generates the csproj in the root level of the project, per assembly definition, so packages don't actually contain their own csproj. It cannot be expected for Packages to maintain a csproj themselves or to include the root level ones generated by unity.

Lachee avatar Feb 17 '23 03:02 Lachee

For anyone here in the future, to set a symbol (for instance: #if TIMELINE_PRESENT), you can just use add

      "properties": {
        "DefineConstants": "TIMELINE_PRESENT"
      }

into src under your docfx configuration metadata. After adding, it finally found and documented all my code which used this symbol!

GasimoCodes avatar Dec 25 '23 22:12 GasimoCodes

For anyone here in the future, to set a symbol (for instance: #if TIMELINE_PRESENT), you can just use add

      "properties": {
        "DefineConstants": "TIMELINE_PRESENT"
      }

into src under your docfx configuration metadata. After adding, it finally found and documented all my code which used this symbol!

so this issue has been fixed? This only worked if there was a included csproj as per the original issue.

Lachee avatar Dec 26 '23 04:12 Lachee

For anyone here in the future, to set a symbol (for instance: #if TIMELINE_PRESENT), you can just use add

      "properties": {
        "DefineConstants": "TIMELINE_PRESENT"
      }

into src under your docfx configuration metadata. After adding, it finally found and documented all my code which used this symbol!

so this issue has been fixed? This only worked if there was a included csproj as per the original issue.

Not this isn't supported yet for building .cs files directly.

yufeih avatar Jan 01 '24 02:01 yufeih