Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion include/CppSharp.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
//
// Licensed under the MIT license
// ------------------------------------------------------------------------------------------- //
// clang-format off
#pragma once

#if defined(__cplusplus_cli)
Expand Down Expand Up @@ -293,7 +294,7 @@ namespace clix {
/// <param name="string">String to be marshalled to the other side</param>
/// <returns>The marshaled representation of the string</returns>
template<Encoding encoding, typename SourceType, class ResultType =
typename detail::IfManaged<SourceType>::Select::Either<
typename detail::IfManaged<SourceType>::Select::template Either<
typename detail::StringTypeSelector<encoding>::Type,
System::String^>::Type
>
Expand Down
19 changes: 17 additions & 2 deletions src/Core/Diagnostics.cs
Original file line number Diff line number Diff line change
Expand Up @@ -112,13 +112,25 @@ public ConsoleDiagnostics()
Level = DiagnosticKind.Message;
}

private string GetColorForDiagKind(DiagnosticKind kind) =>
kind switch
{
DiagnosticKind.Debug => null,
DiagnosticKind.Message => null,
DiagnosticKind.Warning => "\u001b[33m", // yellow
DiagnosticKind.Error => "\u001b[91m", // red
_ => null
};

public void Emit(DiagnosticInfo info)
{
if (info.Kind < Level)
return;

var currentIndentation = Indents.Sum();
var message = new string(' ', currentIndentation) + info.Message;
var colorString = GetColorForDiagKind(info.Kind);
var colorReset = colorString == null ? null : "\u001b[0m";
var message = $"{new string(' ', currentIndentation)}{colorString}{info.Message}{colorReset}";

if (info.Kind == DiagnosticKind.Error)
{
Expand All @@ -128,7 +140,10 @@ public void Emit(DiagnosticInfo info)
{
Console.WriteLine(message);
}
Debug.WriteLine(message);

// Don't output debug messages to VS output window. This is extremely slow.
if (info.Kind > DiagnosticKind.Debug)
Debug.WriteLine(message);
}

public void PushIndent(int level)
Expand Down
2 changes: 1 addition & 1 deletion src/CppParser/Bootstrap/StmtCodeGenerators.cs
Original file line number Diff line number Diff line change
Expand Up @@ -344,7 +344,7 @@ public override bool VisitProperty(Property property)
{
var expr = $"_S->{fieldName} = static_cast<AST::{typeName}>(WalkExpression(S->{methodName}()));";

if (fieldName == "base" && typeName is "CXXDependentScopeMemberExpr")
if (fieldName == "base" && @class.Name == "CXXDependentScopeMemberExpr")
{
// Clang asserts that 'getBase()' is not called when 'isImplicitAccess()' returns true
WriteLine("if (!S->isImplicitAccess())");
Expand Down
170 changes: 76 additions & 94 deletions src/Generator/Passes/RenamePass.cs
Original file line number Diff line number Diff line change
Expand Up @@ -43,27 +43,33 @@ protected RenamePass(RenameTargets targets)

public virtual bool Rename(Declaration decl, out string newName)
{
if (decl is Method method && !method.IsStatic)
switch (decl)
{
Method rootBaseMethod;
if (method.OriginalNamespace is Class @class && @class.IsInterface)
rootBaseMethod = (Method)method.OriginalFunction;
else
rootBaseMethod = method.GetRootBaseMethod();
if (rootBaseMethod != null && rootBaseMethod != method)
case Method { IsStatic: false } method:
{
newName = rootBaseMethod.Name;
return true;
}
}
Method rootBaseMethod;
if (method.OriginalNamespace is Class { IsInterface: true })
rootBaseMethod = (Method)method.OriginalFunction;
else
rootBaseMethod = method.GetRootBaseMethod();
if (rootBaseMethod != null && rootBaseMethod != method)
{
newName = rootBaseMethod.Name;
return true;
}

if (decl is Property property && !property.IsStatic)
{
var rootBaseProperty = ((Class)property.Namespace).GetBasePropertyByName(property);
if (rootBaseProperty != null && rootBaseProperty != property)
break;
}
case Property { IsStatic: false } property:
{
newName = rootBaseProperty.Name;
return true;
var rootBaseProperty = ((Class)property.Namespace).GetBasePropertyByName(property);
if (rootBaseProperty != null && rootBaseProperty != property)
{
newName = rootBaseProperty.Name;
return true;
}

break;
}
}

Expand All @@ -73,62 +79,46 @@ public virtual bool Rename(Declaration decl, out string newName)

public bool IsRenameableDecl(Declaration decl)
{
if (decl is Class)
return Targets.HasFlag(RenameTargets.Class);

var method = decl as Method;
if (method != null)
switch (decl)
{
return Targets.HasFlag(RenameTargets.Method) &&
method.Kind == CXXMethodKind.Normal &&
method.Name != "dispose";
}

var function = decl as Function;
if (function != null)
{
// Special case the IDisposable.Dispose method.
return Targets.HasFlag(RenameTargets.Function) &&
(!function.IsOperator && function.Name != "dispose");
}

if (decl is Parameter)
return Targets.HasFlag(RenameTargets.Parameter);

if (decl is Enumeration.Item)
return Targets.HasFlag(RenameTargets.EnumItem);

if (decl is Enumeration)
return Targets.HasFlag(RenameTargets.Enum);

var property = decl as Property;
if (property != null)
return Targets.HasFlag(RenameTargets.Property) && !property.IsIndexer;

if (decl is Event)
return Targets.HasFlag(RenameTargets.Event);

if (decl is TypedefDecl)
return Targets.HasFlag(RenameTargets.Delegate);

if (decl is Namespace && !(decl is TranslationUnit))
return Targets.HasFlag(RenameTargets.Namespace);

if (decl is Variable)
return Targets.HasFlag(RenameTargets.Variable);

var field = decl as Field;
if (field != null)
{
if (!Targets.HasFlag(RenameTargets.Field))
case Class:
return Targets.HasFlag(RenameTargets.Class);
case Method method:
return Targets.HasFlag(RenameTargets.Method) &&
method.Kind == CXXMethodKind.Normal &&
method.Name != "dispose";
case Function function:
// Special case the IDisposable.Dispose method.
return Targets.HasFlag(RenameTargets.Function) &&
(!function.IsOperator && function.Name != "dispose");
case Parameter:
return Targets.HasFlag(RenameTargets.Parameter);
case Enumeration.Item:
return Targets.HasFlag(RenameTargets.EnumItem);
case Enumeration:
return Targets.HasFlag(RenameTargets.Enum);
case Property property:
return Targets.HasFlag(RenameTargets.Property) && !property.IsIndexer;
case Event:
return Targets.HasFlag(RenameTargets.Event);
case TypedefDecl:
return Targets.HasFlag(RenameTargets.Delegate);
case Namespace when !(decl is TranslationUnit):
return Targets.HasFlag(RenameTargets.Namespace);
case Variable:
return Targets.HasFlag(RenameTargets.Variable);
case Field when !Targets.HasFlag(RenameTargets.Field):
return false;
case Field field:
{
var fieldProperty = ((Class)field.Namespace).Properties.FirstOrDefault(
p => p.Field == field);
return (fieldProperty != null &&
fieldProperty.IsInRefTypeAndBackedByValueClassField());
}
default:
return false;
var fieldProperty = ((Class)field.Namespace).Properties.FirstOrDefault(
p => p.Field == field);
return (fieldProperty != null &&
fieldProperty.IsInRefTypeAndBackedByValueClassField());
}

return false;
}

public override bool VisitDeclaration(Declaration decl)
Expand All @@ -148,8 +138,7 @@ public override bool VisitDeclaration(Declaration decl)

private bool Rename(Declaration decl)
{
string newName;
if (!Rename(decl, out newName) || AreThereConflicts(decl, newName))
if (!Rename(decl, out var newName) || AreThereConflicts(decl, newName))
return false;

decl.Name = newName;
Expand All @@ -167,8 +156,7 @@ private static bool AreThereConflicts(Declaration decl, string newName)
declarations.AddRange(decl.Namespace.Events);
declarations.Add(decl.Namespace);

var function = decl as Function;
if (function != null)
if (decl is Function function)
// account for overloads
declarations.AddRange(GetFunctionsWithTheSameParams(function));
else
Expand All @@ -177,11 +165,10 @@ private static bool AreThereConflicts(Declaration decl, string newName)
declarations.AddRange(decl.Namespace.Variables);
declarations.AddRange(from typedefDecl in decl.Namespace.Typedefs
let pointerType = typedefDecl.Type.Desugar() as PointerType
where pointerType != null && pointerType.GetFinalPointee() is FunctionType
where pointerType?.GetFinalPointee() is FunctionType
select typedefDecl);

var specialization = decl as ClassTemplateSpecialization;
if (specialization != null)
if (decl is ClassTemplateSpecialization specialization)
declarations.RemoveAll(d => specialization.TemplatedDecl.TemplatedDecl == d);

var @class = decl.Namespace as Class;
Expand All @@ -201,8 +188,7 @@ where typedefDecl.Type.Desugar() is FunctionType
if (decl is Method && decl.IsGenerated)
return @class.GetPropertyByName(newName) != null;

var property = decl as Property;
if (property != null)
if (decl is Property property)
{
Property existingProperty = @class.Properties.Find(
p => p != decl && p.Name == newName);
Expand All @@ -216,8 +202,7 @@ where typedefDecl.Type.Desugar() is FunctionType
}
}

var enumItem = decl as Enumeration.Item;
if (enumItem != null)
if (decl is Enumeration.Item enumItem)
return ((Enumeration)enumItem.Namespace).Items.Any(
i => i != decl && i.Name == newName);

Expand All @@ -226,8 +211,7 @@ where typedefDecl.Type.Desugar() is FunctionType

private static IEnumerable<Function> GetFunctionsWithTheSameParams(Function function)
{
var method = function as Method;
if (method != null)
if (function is Method method)
{
return ((Class)method.Namespace).Methods.Where(
m => !m.Ignore && m.Parameters.SequenceEqual(function.Parameters, new ParameterComparer()));
Expand Down Expand Up @@ -391,14 +375,12 @@ public static string ConvertCaseString(Declaration decl, RenameCasePattern patte
if (decl.Name.All(c => !char.IsLetter(c)))
return decl.Name;

var typedef = decl as TypedefDecl;
if (typedef != null && typedef.IsSynthetized)
return decl.Name;

var property = decl as Property;
if (property != null && property.GetMethod != null &&
property.GetMethod.SynthKind == FunctionSynthKind.InterfaceInstance)
return decl.Name;
switch (decl)
{
case TypedefDecl { IsSynthetized: true }:
case Property { GetMethod.SynthKind: FunctionSynthKind.InterfaceInstance }:
return decl.Name;
}

var sb = new StringBuilder(decl.Name);
// check if it's been renamed to avoid a keyword
Expand All @@ -412,14 +394,14 @@ public static string ConvertCaseString(Declaration decl, RenameCasePattern patte
{
case RenameCasePattern.UpperCamelCase:
// ensure separation in enum items by not ending up with more capitals in a row than before
if (sb.Length == 1 || !char.IsUpper(sb[1]) || !(decl is Enumeration.Item))
if (sb.Length == 1 || !char.IsUpper(sb[1]) || decl is not Enumeration.Item)
sb[0] = char.ToUpperInvariant(sb[0]);
if (@class != null && @class.Type == ClassType.Interface)
if (@class is { Type: ClassType.Interface })
sb[1] = char.ToUpperInvariant(sb[1]);
break;
case RenameCasePattern.LowerCamelCase:
sb[0] = char.ToLowerInvariant(sb[0]);
if (@class != null && @class.Type == ClassType.Interface)
if (@class is { Type: ClassType.Interface })
sb[1] = char.ToLowerInvariant(sb[1]);
break;
}
Expand Down
3 changes: 3 additions & 0 deletions src/Generator/Types/Std/Stdlib.CSharp.cs
Original file line number Diff line number Diff line change
Expand Up @@ -307,10 +307,13 @@ public override Type SignatureType(TypePrinterContext ctx)
{
if (ctx.Kind == TypePrinterContextKind.Managed)
return new CILType(typeof(string));

var typePrinter = new CSharpTypePrinter(null);
typePrinter.PushContext(TypePrinterContextKind.Native);

if (ctx.Type.Desugar().IsAddress())
return new CustomType(typePrinter.IntPtrType);

ClassTemplateSpecialization basicString = GetBasicString(ctx.Type);
return new CustomType(basicString.Visit(typePrinter).Type);
}
Expand Down
3 changes: 2 additions & 1 deletion tests/dotnet/Common/Common.h
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#include "../Tests.h"
#pragma once
#include "../Tests.h"
#include "AnotherUnit.h"

#ifdef _WIN32
Expand Down