mirror of https://github.com/mono/CppSharp.git
c-sharpdotnetmonobindingsbridgecclangcpluspluscppsharpglueinteropparserparsingpinvokeswigsyntax-treevisitorsxamarinxamarin-bindings
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
308 lines
13 KiB
308 lines
13 KiB
using System.Linq; |
|
using CppSharp.Passes; |
|
using CppSharp.AST; |
|
using CppSharp.AST.Extensions; |
|
using NUnit.Framework; |
|
|
|
namespace CppSharp.Generator.Tests.AST |
|
{ |
|
[TestFixture] |
|
public class TestAST : ASTTestFixture |
|
{ |
|
[TestFixtureSetUp] |
|
public void Init() |
|
{ |
|
} |
|
|
|
[SetUp] |
|
public void Setup() |
|
{ |
|
ParseLibrary("AST.h", "ASTExtensions.h"); |
|
} |
|
|
|
[Test] |
|
public void TestASTParameter() |
|
{ |
|
var func = AstContext.FindFunction("TestParameterProperties").FirstOrDefault(); |
|
Assert.IsNotNull(func); |
|
|
|
var paramNames = new [] { "a", "b", "c" }; |
|
var paramTypes = new [] |
|
{ |
|
new QualifiedType(new BuiltinType(PrimitiveType.Bool)), |
|
new QualifiedType( |
|
new PointerType() |
|
{ |
|
Modifier = PointerType.TypeModifier.LVReference, |
|
QualifiedPointee = new QualifiedType( |
|
new BuiltinType(PrimitiveType.Short), |
|
new TypeQualifiers() { IsConst = true }) |
|
}), |
|
new QualifiedType( |
|
new PointerType() |
|
{ |
|
Modifier = PointerType.TypeModifier.Pointer, |
|
QualifiedPointee = new QualifiedType(new BuiltinType(PrimitiveType.Int)) |
|
}) |
|
}; |
|
for (int i = 0; i < func.Parameters.Count; i++) |
|
{ |
|
var param = func.Parameters[i]; |
|
Assert.AreEqual(paramNames[i], param.Name, "Parameter.Name"); |
|
Assert.AreEqual(paramTypes[i], param.QualifiedType, "Parameter.QualifiedType"); |
|
Assert.AreEqual(i, param.Index, "Parameter.Index"); |
|
} |
|
Assert.IsTrue(func.Parameters[2].HasDefaultValue, "Parameter.HasDefaultValue"); |
|
} |
|
|
|
[Test] |
|
public void TestASTHelperMethods() |
|
{ |
|
var @class = AstContext.FindClass("Math::Complex").FirstOrDefault(); |
|
Assert.IsNotNull(@class, "Couldn't find Math::Complex class."); |
|
var plusOperator = @class.FindOperator(CXXOperatorKind.Plus).FirstOrDefault(); |
|
Assert.IsNotNull(plusOperator, "Couldn't find operator+ in Math::Complex class."); |
|
var typedef = AstContext.FindTypedef("Math::Single").FirstOrDefault(); |
|
Assert.IsNotNull(typedef); |
|
} |
|
|
|
#region TestVisitor |
|
class TestVisitor : IDeclVisitor<bool> |
|
{ |
|
public bool VisitDeclaration(Declaration decl) |
|
{ |
|
throw new System.NotImplementedException(); |
|
} |
|
|
|
public bool VisitClassDecl(Class @class) |
|
{ |
|
throw new System.NotImplementedException(); |
|
} |
|
|
|
public bool VisitFieldDecl(Field field) |
|
{ |
|
throw new System.NotImplementedException(); |
|
} |
|
|
|
public bool VisitFunctionDecl(Function function) |
|
{ |
|
throw new System.NotImplementedException(); |
|
} |
|
|
|
public bool VisitMethodDecl(Method method) |
|
{ |
|
return true; |
|
} |
|
|
|
public bool VisitParameterDecl(Parameter parameter) |
|
{ |
|
throw new System.NotImplementedException(); |
|
} |
|
|
|
public bool VisitTypedefDecl(TypedefDecl typedef) |
|
{ |
|
throw new System.NotImplementedException(); |
|
} |
|
|
|
public bool VisitEnumDecl(Enumeration @enum) |
|
{ |
|
throw new System.NotImplementedException(); |
|
} |
|
|
|
public bool VisitVariableDecl(Variable variable) |
|
{ |
|
throw new System.NotImplementedException(); |
|
} |
|
|
|
public bool VisitClassTemplateDecl(ClassTemplate template) |
|
{ |
|
throw new System.NotImplementedException(); |
|
} |
|
|
|
public bool VisitFunctionTemplateDecl(FunctionTemplate template) |
|
{ |
|
throw new System.NotImplementedException(); |
|
} |
|
|
|
public bool VisitMacroDefinition(MacroDefinition macro) |
|
{ |
|
throw new System.NotImplementedException(); |
|
} |
|
|
|
public bool VisitNamespace(Namespace @namespace) |
|
{ |
|
throw new System.NotImplementedException(); |
|
} |
|
|
|
public bool VisitEvent(Event @event) |
|
{ |
|
throw new System.NotImplementedException(); |
|
} |
|
|
|
public bool VisitProperty(Property property) |
|
{ |
|
throw new System.NotImplementedException(); |
|
} |
|
|
|
public bool VisitFriend(Friend friend) |
|
{ |
|
throw new System.NotImplementedException(); |
|
} |
|
} |
|
#endregion |
|
|
|
[Test] |
|
public void TestASTVisitor() |
|
{ |
|
var testVisitor = new TestVisitor(); |
|
var plusOperator = AstContext.TranslationUnits |
|
.SelectMany(u => u.Namespaces.Where(n => n.Name == "Math")) |
|
.SelectMany(n => n.Classes.Where(c => c.Name == "Complex")) |
|
.SelectMany(c => c.Methods.Where(m => m.OperatorKind == CXXOperatorKind.Plus)) |
|
.First(); |
|
Assert.IsTrue(plusOperator.Visit(testVisitor)); |
|
} |
|
|
|
[Test] |
|
public void TestASTEnumItemByName() |
|
{ |
|
var @enum = AstContext.FindEnum("TestASTEnumItemByName").Single(); |
|
Assert.NotNull(@enum); |
|
Assert.IsTrue(@enum.ItemsByName.ContainsKey("TestItemByName")); |
|
} |
|
|
|
[Test] |
|
public void TestASTFunctionTemplates() |
|
{ |
|
var @class = AstContext.FindClass("TestTemplateFunctions").FirstOrDefault(); |
|
Assert.IsNotNull(@class, "Couldn't find TestTemplateFunctions class."); |
|
Assert.AreEqual(6, @class.Templates.Count); |
|
var twoParamMethodTemplate = @class.Templates.OfType<FunctionTemplate>() |
|
.FirstOrDefault(t => t.Name == "MethodTemplateWithTwoTypeParameter"); |
|
Assert.IsNotNull(twoParamMethodTemplate); |
|
Assert.AreEqual(2, twoParamMethodTemplate.Parameters.Count); |
|
Assert.AreEqual("T", twoParamMethodTemplate.Parameters[0].Name); |
|
Assert.AreEqual("S", twoParamMethodTemplate.Parameters[1].Name); |
|
Assert.IsTrue(twoParamMethodTemplate.Parameters[0].IsTypeParameter); |
|
Assert.IsTrue(twoParamMethodTemplate.Parameters[1].IsTypeParameter); |
|
var twoParamMethod = twoParamMethodTemplate.TemplatedFunction as Method; |
|
Assert.IsNotNull(twoParamMethod); |
|
Assert.IsInstanceOf<TemplateParameterType>(twoParamMethod.Parameters[0].Type); |
|
Assert.IsInstanceOf<TemplateParameterType>(twoParamMethod.Parameters[1].Type); |
|
Assert.AreEqual(twoParamMethodTemplate.Parameters[0], |
|
((TemplateParameterType)twoParamMethod.Parameters[0].Type).Parameter); |
|
Assert.AreEqual(twoParamMethodTemplate.Parameters[1], |
|
((TemplateParameterType)twoParamMethod.Parameters[1].Type).Parameter); |
|
Assert.AreEqual(0, ((TemplateParameterType)twoParamMethod.Parameters[0].Type).Index); |
|
Assert.AreEqual(1, ((TemplateParameterType)twoParamMethod.Parameters[1].Type).Index); |
|
} |
|
|
|
[Test] |
|
public void TestASTClassTemplates() |
|
{ |
|
var template = AstContext.TranslationUnits |
|
.SelectMany(u => u.Templates.OfType<ClassTemplate>()) |
|
.FirstOrDefault(t => t.Name == "TestTemplateClass"); |
|
Assert.IsNotNull(template, "Couldn't find TestTemplateClass class."); |
|
Assert.AreEqual(1, template.Parameters.Count); |
|
var templateTypeParameter = template.Parameters[0]; |
|
Assert.AreEqual("T", templateTypeParameter.Name); |
|
var ctor = template.TemplatedClass.Constructors |
|
.FirstOrDefault(c => c.Parameters.Count == 1 && c.Parameters[0].Name == "v"); |
|
Assert.IsNotNull(ctor); |
|
var paramType = ctor.Parameters[0].Type as TemplateParameterType; |
|
Assert.IsNotNull(paramType); |
|
Assert.AreEqual(templateTypeParameter, paramType.Parameter); |
|
Assert.AreEqual(3, template.Specializations.Count); |
|
Assert.AreEqual(TemplateSpecializationKind.ExplicitInstantiationDefinition, template.Specializations[0].SpecializationKind); |
|
Assert.AreEqual(TemplateSpecializationKind.ExplicitInstantiationDefinition, template.Specializations[1].SpecializationKind); |
|
Assert.AreEqual(TemplateSpecializationKind.Undeclared, template.Specializations[2].SpecializationKind); |
|
var typeDef = AstContext.FindTypedef("TestTemplateClassInt").FirstOrDefault(); |
|
Assert.IsNotNull(typeDef, "Couldn't find TestTemplateClassInt typedef."); |
|
var integerInst = typeDef.Type as TemplateSpecializationType; |
|
Assert.AreEqual(1, integerInst.Arguments.Count); |
|
var intArgument = integerInst.Arguments[0]; |
|
Assert.AreEqual(new BuiltinType(PrimitiveType.Int), intArgument.Type.Type); |
|
Class classTemplate; |
|
Assert.IsTrue(typeDef.Type.TryGetClass(out classTemplate)); |
|
Assert.AreEqual(classTemplate, template.TemplatedClass); |
|
} |
|
|
|
[Test] |
|
public void TestFindClassInNamespace() |
|
{ |
|
Assert.IsNotNull(AstContext.FindClass("HiddenInNamespace").FirstOrDefault()); |
|
} |
|
|
|
[Test] |
|
public void TestLineNumber() |
|
{ |
|
Assert.AreEqual(65, AstContext.FindClass("HiddenInNamespace").First().LineNumberStart); |
|
} |
|
|
|
[Test] |
|
public void TestLineNumberOfFriend() |
|
{ |
|
Assert.AreEqual(88, AstContext.FindFunction("operator+").First().LineNumberStart); |
|
} |
|
|
|
[Test] |
|
public void TestSignature() |
|
{ |
|
Assert.AreEqual("void testSignature()", AstContext.FindFunction("testSignature").Single().Signature); |
|
Assert.AreEqual("void testImpl()", AstContext.FindFunction("testImpl").Single().Signature); |
|
Assert.AreEqual("void testConstSignature() const", |
|
AstContext.FindClass("HasConstFunction").Single().FindMethod("testConstSignature").Signature); |
|
Assert.AreEqual("void testConstSignatureWithTrailingMacro() const", |
|
AstContext.FindClass("HasConstFunction").Single().FindMethod("testConstSignatureWithTrailingMacro").Signature); |
|
// TODO: restore when the const of a return type is fixed properly |
|
//Assert.AreEqual("const int& testConstRefSignature()", AstContext.FindClass("HasConstFunction").Single().FindMethod("testConstRefSignature").Signature); |
|
//Assert.AreEqual("const int& testStaticConstRefSignature()", AstContext.FindClass("HasConstFunction").Single().FindMethod("testStaticConstRefSignature").Signature); |
|
} |
|
|
|
[Test] |
|
public void TestAmbiguity() |
|
{ |
|
new CheckAmbiguousFunctions { Driver = new Driver(new DriverOptions(), new TextDiagnosticPrinter()) } |
|
.VisitLibrary(AstContext); |
|
Assert.IsTrue(AstContext.FindClass("HasAmbiguousFunctions").Single().FindMethod("ambiguous").IsAmbiguous); |
|
} |
|
|
|
[Test] |
|
public void TestAtomics() |
|
{ |
|
var type = AstContext.FindClass("Atomics").Single().Fields |
|
.Find(f => f.Name == "AtomicInt").Type as BuiltinType; |
|
Assert.IsTrue(type != null && type.IsPrimitiveType(PrimitiveType.Int)); |
|
} |
|
|
|
[Test] |
|
public void TestMacroLineNumber() |
|
{ |
|
Assert.AreEqual(98, AstContext.FindClass("HasAmbiguousFunctions").First().Specifiers.Last().LineNumberStart); |
|
} |
|
|
|
[Test] |
|
public void TestImplicitDeclaration() |
|
{ |
|
Assert.IsTrue(AstContext.FindClass("ImplicitCtor").First().Constructors.First( |
|
c => c.Parameters.Count == 0).IsImplicit); |
|
} |
|
|
|
[Test] |
|
public void TestSpecializationArguments() |
|
{ |
|
var classTemplate = AstContext.FindDecl<ClassTemplate>("TestSpecializationArguments").FirstOrDefault(); |
|
Assert.IsTrue(classTemplate.Specializations[0].Arguments[0].Type.Type.IsPrimitiveType(PrimitiveType.Int)); |
|
} |
|
|
|
[Test] |
|
public void TestFunctionInstantiatedFrom() |
|
{ |
|
var classTemplate = AstContext.FindDecl<ClassTemplate>("TestSpecializationArguments").FirstOrDefault(); |
|
Assert.AreEqual(classTemplate.Specializations[0].Constructors.First( |
|
c => !c.IsCopyConstructor && !c.IsMoveConstructor).InstantiatedFrom, |
|
classTemplate.TemplatedClass.Constructors.First(c => !c.IsCopyConstructor && !c.IsMoveConstructor)); |
|
} |
|
} |
|
}
|
|
|