Roslyn: Effect of CSharpCompilerOptions WithUsings - c#

My question is about CSharpCompilerOptions and using statements passed to an instance of CSharpCompilation.
I have a syntax tree parsed from some text:
SyntaxTree syntaxTree = CSharpSyntaxTree.ParseText(#"
namespace RoslynCodeAnalysis
{
using System;
using System.Net; // Commenting this out causes errors
public class Writer
{
public void Write(string message)
{
WebClient client = new WebClient();
Console.WriteLine(message);
}
}
}");
The CSharpCompilation instance is created as below. I did not include the references for simplicity but it does add a reference to System.Net and few other common assemblies.
CSharpCompilation compilation = CSharpCompilation.Create(
assemblyName,
syntaxTrees: new[] { syntaxTree },
references: references,
options: new CSharpCompilationOptions(
OutputKind.DynamicallyLinkedLibrary,
usings: new List<string> { "System", "System.Net" }));
The issue is that, if I comment out using System.Net, I get errors saying that:
CS0246: The type or namespace name 'WebClient' could not be found (are
you missing a using directive or an assembly reference?)
What could cause this? The options passed to CSharpCompilation has the usings property set to System and System.Net. Is this the normal behavior or am I missing something? Even though the usings property is specified, source text still needs to have the using statement? I am pretty sure I am missing something!

This is used for scripting, not normal file compilations.
If you trace usages of that property through Roslyn source, you'll end up here, which is used in the interactive pipeline (that's what a Submission is).

Related

Build.cs not working even after being restores to it's previous version

I'm trying to compile a project I'm working on and this error mesages pops out:
Invalidating makefile for SpaceShooterEditor (SpaceShooter.Build.cs modified)
While compiling E:\ue projects\SpaceShooter\Intermediate\Build\BuildRules\SpaceShooterModuleRules.dll:
e:\ue projects\SpaceShooter\Source\SpaceShooter\SpaceShooter.Build.cs(3,29) : error CS0246: The type or namespace name 'ModuleRules' could not be found (are you missing a using directive or an assembly reference?)
e:\ue projects\SpaceShooter\Source\SpaceShooter\SpaceShooter.Build.cs(5,25) : error CS0246: The type or namespace name 'ReadOnlyTargetRules' could not be found (are you missing a using directive or an assembly reference?)
ERROR: Unable to compile source files.
Any idea why this might happen? Last night i was trying to code a widget, modified the build.cs, then replaced the modified version (which chrashed the game) with a build.cs that worked previously, and still nothing? Is there any hope to make it work or should i start over? Moreover, how can this be avoided?
I already did the restarts and refreshes. I went to even delete the binaries and some cashed files and it didn't work.
Below you'll find the content of the Build.cs:
public class SpaceShooter : ModuleRules
{
public SpaceShooter(ReadOnlyTargetRules Target) : base(Target)
{
PCHUsage = PCHUsageMode.UseExplicitOrSharedPCHs;
PublicDependencyModuleNames.AddRange(new string[] { "Core", "CoreUObject", "Engine", "InputCore" });
PrivateDependencyModuleNames.AddRange(new string[] { });
// Uncomment if you are using Slate UI
// PrivateDependencyModuleNames.AddRange(new string[] { "Slate", "SlateCore" });
// Uncomment if you are using online features
// PrivateDependencyModuleNames.Add("OnlineSubsystem");
// To include OnlineSubsystemSteam, add it to the plugins section in your uproject file with the Enabled attribute set to true
}
}
When i try to input specify the using UnrealBuildTool;, Visual Studio, for some reason, deletes it when i hit compile or save.
After some digging, i found out that wrapping the content in a namespace UnrealBuidTool.Rules{} solves this. In the end, the build file looks like this:
namespace UnrealBuildTool.Rules
{
public class SpaceShooter : ModuleRules
{
public SpaceShooter(ReadOnlyTargetRules Target) : base(Target)
{
PCHUsage = PCHUsageMode.UseExplicitOrSharedPCHs;
PublicDependencyModuleNames.AddRange(new string[] { "Core", "CoreUObject", "Engine", "InputCore" });
PrivateDependencyModuleNames.AddRange(new string[] { });
// Uncomment if you are using Slate UI
// PrivateDependencyModuleNames.AddRange(new string[] { "Slate", "SlateCore" });
// Uncomment if you are using online features
// PrivateDependencyModuleNames.Add("OnlineSubsystem");
// To include OnlineSubsystemSteam, add it to the plugins section in your uproject file with the Enabled attribute set to true
}
}
}
As you do not share what is included in your Build.cs file I will just explain what the error is and how you could fix it. The error basically says that it couldn't compile the Build.cs file based on the lines 29 and 25, and that the types that are used there called 'ModuleRules' and 'ReadOnlyTargetRules' could not be found in any of the namespaces that were included by the using statements at the top of Build.cs. These types are both stored in the UnrealBuildTool namespace and can thus be included in your file by typing:
using UnrealBuildTool;
This however seems like a trivial solution to your problem, but as you do not share a lot of info this is the best solution I can give you for now.

The namespace name 'SyntaxTree' could not be found

I have am developing in Unity 2019.2.3f1. I am trying to write a script that can Customize project files created by VSTU. In case the link ever gets removed, I have included a script very similar to the one from the link.
#if ENABLE_VSTU
using System.IO;
using System.Text;
using System.Xml.Linq;
using UnityEditor;
using SyntaxTree.VisualStudio.Unity.Bridge;
[InitializeOnLoad]
public class ProjectFileHook
{
private class Utf8StringWriter : StringWriter
{
public override Encoding Encoding => Encoding.UTF8;
}
static ProjectFileHook()
{
ProjectFilesGenerator.ProjectFileGeneration += (string name, string content) =>
{
// parse the document and make some changes
XDocument document = XDocument.Parse(content);
document.Root?.Add(new XComment("FIX ME"));
// save the changes using the Utf8StringWriter
Utf8StringWriter str = new Utf8StringWriter();
document.Save(str);
return str.ToString();
};
}
}
#endif
The issue is, using SyntaxTree.VisualStudio.Unity.Bridge; fails to compile due to the error error CS0246: The type or namespace name 'SyntaxTree' could not be found (are you missing a using directive or an assembly reference?).
I have checked both Unity and Visual Studio that the Visual Studio Tools for Unity are installed and enabled.
Why is the code failing to compile? Am I missing something that is preventing it from compiling?
Just incase anyone else has this issue.
This issue was being caused by the scripts position. The script has to be under the Editor folder, otherwise the script won't work as expected.
Credits to therealjohn for pointing it out here.

Why does my IDE (Visual Studio Code) mark "using xy" directives as unneccessary even though i require them for compiling?

I want to compile and run some c# code, but it's not working due to the methods/classes not being found by referenced libraries. Even though i included the needed namespaces e.g. "using System.Collections.Generic;", they will be grey'd out and marked with "Using directive is unneccessary", even though my code requires it. As a result, compiling fails. What am I doing wrong?
using System.Collections.Generic;
namespace NetCoreExamples
{
class Program
{
static void Main(string[] args)
{
##some code##
}
private static async Task MainAsync(string[] args)
{
var type = Type.GetType(args[0]);
await (Task)type.GetMethod("RunAsync", BindingFlags.NonPublic | BindingFlags.Static)
.Invoke(null, new object[] {args.TakeLast(args.Length - 1).ToArray() });
}
}
}
On phrase "args.TakeLast(args.Length - 1)", "TakeLast" is underlined saying "string[] has no definition for TakeLast and no extension method was found that accepts the first argument as string[]. (Maybe missing using directive or assembly reference)".
To use System.Collections.Generic.IEnumerable, I discovered it's location:
Namespace:
System.Collections.Generic
Assemblies:
System.Runtime.dll, mscorlib.dll, netstandard.dll
But the "using System.Collections.Generic;" keeps being grey'd out, referencing the assemblies for the project did not change anything.
I am sure this is trivial, but I cannot seem to find out what I am doing wrong.

USQL - Custom Outputter failed to find NewtonSoft

I have a USQL Job which reads json from Azure Blob and after some data manipulation writes a single line JSON file to ADLS.
I have written a Custom Ouputter to write JSON File.
This is how my CustomOutputter files look like:
using Microsoft.Analytics.Interfaces;
using Microsoft.Analytics.Types.Sql;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using Newtonsoft.Json;
namespace demo{
[SqlUserDefinedOutputter(AtomicFileProcessing = true)]
public class JSONOutputter : IOutputter
{
//Actual Code Here
public static class Factory
{
public static JSONOutputter JSONOutputter(bool isHeader = true, Encoding encoding = null)
{
return new JSONOutputter(isHeader, encoding);
}
}
}
I am using this Ouputter in my USQL Job like this:
OUTPUT #final_output
TO "/output/json/final.json"
USING demo.Factory.JSONOutputter(isHeader: true);
When I compile my USQL Script using
ADL: Compile Script
I get this error:
[Info] Start compiling code behind: /users/kumar.pratik/documents/usql/second.usql.cs ...
[Error] Command failed: mono /Users/kumar.pratik/.vscode/extensions/usqlextpublisher.usql-vscode-ext-0.2.11/compilehost/compilehost.exe /users/kumar.pratik/documents/usql/second.usql.cs /Users/kumar.pratik/Documents/usql/usqlCodeBehindReference /Users/kumar.pratik/Documents/usql/second.usql.dll __codeBehind__tRYGlFBeSWcl
[Error] Compile failed
error: "The type or namespace name 'Newtonsoft' could not be found (are you missing a using directive or an assembly reference?)" at line: 8, column 6
error: "The type or namespace name 'JsonTextWriter' could not be found (are you missing a using directive or an assembly reference?)" at line: 17, column 12
error: "The type or namespace name 'JsonTextWriter' could not be found (are you missing a using directive or an assembly reference?)" at line: 44, column 34
Could someone please let me know how can I get this fixed?
I am working on Visual Studio Code on Mac OS
Thanks
Can you please share how your script looks like? In particular, are you
Using Visual Studio's code behind for your Outputter code?
If the answer to 1 is no: Did you register your Outputter and Newtonsoft lib in the U-SQL catalog with CREATE ASSEMBLY or via the Visual Studio Assembly registration feature? And did you reference the U-SQL assemblies (both your own code and Newtonsoft) in your script with REFERENCE ASSEMBLY?
More details: https://blogs.msdn.microsoft.com/azuredatalake/2016/08/26/how-to-register-u-sql-assemblies-in-your-u-sql-catalog/

using namespace in C# from CLI/C++ class

This might be a C#-noob question...
Assume I have the following CLI/C++ header:
namespace DotNet {
namespace V1 {
namespace X {
public ref class AClass {
public:
AClass() {}
void foo() {}
static void bar() {}
};
}
}
}
Then from C# I do the following:
using DotNet;
V1.X.AClass a = new V1.X.AClass();
I get:
Program.cs(18,7): error CS0246: The type or namespace name 'V1' could
not be found (are you missing a using directive or an assembly
reference?)
Same with:
using DotNet.V1;
X.AClass a = new X.AClass();
Program.cs(18,7): error CS0246: The type or namespace name 'X' could
not be found (are you missing a using directive or an assembly
reference?)
What works is:
DotNet.V1.X.AClass a = new DotNet.V1.X.AClass();
Or
using DotNet.V1.X;
AClass a = new AClass();
So either I have to use the full namespace path, or I have to open all of the path to access the class. Is there anything I can do about this?
I would like to be able to open only a part of it.
So either I have to use the full namespace path, or I have to open all of the path to access the class.
Yes.
Is there anything I can do about this?
Not that I'm aware of. Why would you not just want a using directive for the whole namespace? Isn't that the simplest approach?
Note that this has nothing to do with C++/CLI. The same is true whatever the source language is - so you can see it with C# as well:
namespace DotNet.V1.X
{
public class AClass {}
}
As Jon Skeet stated you have to include the full namespace in either the using statement or each time you reference it in code. I recommend just placing the full namespace in the using statement.
You can, however, achieve that syntax with a using alias, but it does not add anything of value outside of syntax.
using V1 = DotNet.V1;
...
V1.X.AClass a = new V1.X.AClass();
Also if you are using C# version 3.0 or higher the var keyword will only require you type out the full namespace on the right side of the assignment.
var a = new DotNet.V1.X.AClass();

Categories