public void CheckNonVirtualInheritedFunctions(Class @class, Class originalClass = null) { if (originalClass == null) originalClass = @class; foreach (BaseClassSpecifier baseSpecifier in @class.Bases) { var @base = baseSpecifier.Class; if (@base.IsInterface) continue; var nonVirtualOffset = ComputeNonVirtualBaseClassOffset(originalClass, @base); if (nonVirtualOffset == 0) continue; foreach (var method in @base.Methods.Where(method => !method.IsVirtual && (method.Kind == CXXMethodKind.Normal))) { Console.WriteLine(method); var adjustedMethod = new Method(method) { SynthKind = FunctionSynthKind.AdjustedMethod, AdjustedOffset = nonVirtualOffset, }; originalClass.Methods.Add(adjustedMethod); } CheckNonVirtualInheritedFunctions(@base, originalClass); } }
public override bool VisitFunctionDecl(Function function) { if (function.Ignore || !function.IsOperator) return false; var param = function.Parameters[0]; Class @class; if (!FunctionToInstanceMethodPass.GetClassParameter(param, out @class)) return false; // Create a new fake method so it acts as a static method. var method = new Method(function) { Namespace = @class, Kind = CXXMethodKind.Operator, OperatorKind = function.OperatorKind, SynthKind = FunctionSynthKind.NonMemberOperator, OriginalFunction = null, IsStatic = true }; function.ExplicityIgnored = true; @class.Methods.Add(method); Driver.Diagnostics.Debug("Function converted to operator: {0}::{1}", @class.Name, function.Name); return true; }
public override bool VisitMethodDecl(Method method) { if (!method.IsConstructor && !method.IsDestructor && !method.IsOperator && method.IsGenerated && !method.IsSynthetized) DistributeMethod(method); return base.VisitMethodDecl(method); }
public static bool CanOverride(this Method @override, Method method) { return (method.OriginalName == @override.OriginalName && method.ReturnType == @override.ReturnType && method.Parameters.SequenceEqual(@override.Parameters, ParameterTypeComparer.Instance)) || (@override.IsDestructor && method.IsDestructor && method.IsVirtual); }
static bool CanOverride(Method method, Method @override) { return method.OriginalName == @override.OriginalName && method.ReturnType == @override.ReturnType && method.Parameters.SequenceEqual(@override.Parameters, new ParameterTypeComparer()); }
public override bool VisitMethodDecl(Method method) { if (!method.IsConstructor && (method.Name.EndsWith("Event") || method.Name == "event") && method.Parameters.Count == 1 && method.Parameters[0].Type.ToString().EndsWith("Event") && method.OriginalName != "widgetEvent") { Event @event = new Event(); if (method.Name.StartsWith("on")) { @event.Name = method.Name.Substring(2); } else { @event.Name = method.Name; } @event.OriginalDeclaration = method; @event.Namespace = method.Namespace; @event.Parameters.AddRange(method.Parameters); method.Namespace.Events.Add(@event); this.events.Add(@event); if (!method.Name.StartsWith("on")) method.Name = "on" + char.ToUpperInvariant(method.Name[0]) + method.Name.Substring(1); } return base.VisitMethodDecl(method); }
public override bool VisitMethodDecl(Method method) { if (!base.VisitMethodDecl(method)) { return false; } if (!method.IsConstructor && (method.Name.EndsWith("Event", StringComparison.Ordinal) || method.Name == "event") && method.Parameters.Count == 1) { var type = method.Parameters[0].Type; type = type.GetFinalPointee() ?? type; Class @class; if (type.TryGetClass(out @class) && @class.Name.EndsWith("Event", StringComparison.Ordinal)) { var name = char.ToUpperInvariant(method.Name[0]) + method.Name.Substring(1); method.Name = "on" + name; Method baseMethod; if (!method.IsOverride || (baseMethod = ((Class) method.Namespace).GetBaseMethod(method, true, true)) == null || baseMethod.IsPure) { this.events.Add(method); this.Context.Options.ExplicitlyPatchedVirtualFunctions.Add(method.QualifiedOriginalName); } } } return true; }
void GenerateToString(Class @class, Block block, Method method) { needsStreamInclude = true; block.WriteLine("std::ostringstream os;"); block.WriteLine("os << *NativePtr;"); block.Write("return clix::marshalString<clix::E_UTF8>(os.str());"); }
public override bool VisitMethodDecl(Method method) { if (!method.IsConstructor && !method.IsDestructor && !method.IsOperator && !method.Ignore) DistributeMethod(method); return base.VisitMethodDecl(method); }
public override bool VisitMethodDecl(Method decl) { if (ASTUtils.CheckIgnoreMethod(decl)) return false; if (!AlreadyVisited(decl) && decl.ExplicitInterfaceImpl == null) CheckDuplicate(decl); return false; }
public override bool VisitMethodDecl(Method method) { if (!base.VisitMethodDecl(method)) return false; if (method.IsPure && method.IsOperator) method.ExplicitlyIgnore(); return true; }
public override bool VisitFunctionDecl(Function function) { if (!function.IsGenerated) return false; // Check if this function can be converted. if (function.Parameters.Count == 0) return false; var classParam = function.Parameters[0]; Class @class; if (!GetClassParameter(classParam, out @class)) return false; // If we reach here, it means the first parameter is of class type. // This means we can change the function to be an instance method. // Clean up the name of the function now that it will be an instance method. if (!function.Name.StartsWith(@class.Name)) return false; function.Name = function.Name.Substring(@class.Name.Length); function.ExplicitlyIgnore(); // Create a new fake method so it acts as an instance method. var method = new Method { Namespace = @class, OriginalNamespace = function.Namespace, Name = function.Name, OriginalName = function.OriginalName, Mangled = function.Mangled, Access = AccessSpecifier.Public, Kind = CXXMethodKind.Normal, ReturnType = function.ReturnType, Parameters = function.Parameters, CallingConvention = function.CallingConvention, IsVariadic = function.IsVariadic, IsInline = function.IsInline, Conversion = MethodConversionKind.FunctionToInstanceMethod }; if (Options.GeneratorKind == GeneratorKind.CSharp) method.Parameters = method.Parameters.Skip(1).ToList(); @class.Methods.Add(method); Diagnostics.Debug("Function converted to instance method: {0}::{1}", @class.Name, function.Name); return true; }
public override bool VisitMethodDecl(Method method) { if (method.IsOverride && !method.IsSynthetized) { Method rootBaseMethod = ((Class) method.Namespace).GetBaseMethod(method); for (int i = 0; i < method.Parameters.Count; i++) { method.Parameters[i].DefaultArgument = rootBaseMethod.Parameters[i].DefaultArgument; } } return base.VisitMethodDecl(method); }
public override bool VisitMethodDecl(Method method) { if (!VisitDeclaration(method)) return false; if (ASTUtils.CheckIgnoreMethod(method, Driver.Options)) return false; var @class = method.Namespace as Class; if (@class == null || @class.IsIncomplete) return false; if (method.IsConstructor) return false; if (method.IsSynthetized) return false; if (IsGetter(method)) { var name = method.Name.Substring("get".Length); var prop = GetOrCreateProperty(@class, name, method.ReturnType); prop.GetMethod = method; prop.Access = method.Access; // Do not generate the original method now that we know it is a getter. method.GenerationKind = GenerationKind.Internal; Driver.Diagnostics.Debug("Getter created: {0}::{1}", @class.Name, name); return false; } if (IsSetter(method) && IsValidSetter(method)) { var name = method.Name.Substring("set".Length); var type = method.Parameters[0].QualifiedType; var prop = GetOrCreateProperty(@class, name, type); prop.SetMethod = method; prop.Access = method.Access; // Ignore the original method now that we know it is a setter. method.GenerationKind = GenerationKind.Internal; Driver.Diagnostics.Debug("Setter created: {0}::{1}", @class.Name, name); return false; } return false; }
public override bool VisitMethodDecl(Method decl) { if (!VisitDeclaration(decl)) return false; if (ASTUtils.CheckIgnoreMethod(decl, Driver.Options)) return false; if (decl.ExplicitInterfaceImpl == null) CheckDuplicate(decl); return false; }
void GenerateEquals(Class @class, Block block, Method method) { var cliTypePrinter = new CLITypePrinter(Driver); var classCliType = @class.Visit(cliTypePrinter); block.WriteLine("if (!object) return false;"); block.WriteLine("auto obj = dynamic_cast<{0}>({1});", classCliType, method.Parameters[0].Name); block.NewLine(); block.WriteLine("if (!obj) return false;"); block.Write("return __Instance == obj->__Instance;"); }
public static int GetVTableIndex(Method method, Class @class) { switch (@class.Layout.ABI) { case CppAbi.Microsoft: return (from table in @class.Layout.VFTables let j = table.Layout.Components.FindIndex(m => CanOverride(m.Method, method)) where j >= 0 select j).First(); default: // ignore offset to top and RTTI return @class.Layout.Layout.Components.FindIndex(m => m.Method == method) - 2; } }
public override bool VisitMethodDecl(Method method) { if (!method.IsConstructor) return false; if (method.IsCopyConstructor) return false; if (method.Parameters.Count != 1) return false; var parameter = method.Parameters[0]; // TODO: disable implicit operators for C++/CLI because they seem not to be support parameters if (!Driver.Options.IsCSharpGenerator) { var pointerType = parameter.Type as PointerType; if (pointerType != null && !pointerType.IsReference) return false; } var qualifiedPointee = parameter.Type.SkipPointerRefs(); Class castFromClass; if (qualifiedPointee.TryGetClass(out castFromClass)) { var castToClass = method.OriginalNamespace as Class; if (castToClass == null) return false; if (castFromClass == castToClass) return false; } var operatorKind = method.IsExplicit ? CXXOperatorKind.ExplicitConversion : CXXOperatorKind.Conversion; var qualifiedCastToType = new QualifiedType(new TagType(method.Namespace)); var conversionOperator = new Method { Name = Operators.GetOperatorIdentifier(operatorKind), Namespace = method.Namespace, Kind = CXXMethodKind.Conversion, SynthKind = FunctionSynthKind.ComplementOperator, ConversionType = qualifiedCastToType, ReturnType = qualifiedCastToType, OperatorKind = operatorKind }; var p = new Parameter(parameter); Class @class; if (p.Type.SkipPointerRefs().TryGetClass(out @class)) p.QualifiedType = new QualifiedType(new TagType(@class), parameter.QualifiedType.Qualifiers); p.DefaultArgument = null; conversionOperator.Parameters.Add(p); ((Class) method.Namespace).Methods.Add(conversionOperator); return true; }
public override bool VisitClassDecl(Class @class) { // FIXME: Add a better way to hook the event if (!isHooked) { Driver.Generator.OnUnitGenerated += OnUnitGenerated; isHooked = true; } if (!VisitDeclaration(@class)) return false; if (AlreadyVisited(@class)) return true; if (@class.IsValueType) return false; var methodEqualsParam = new Parameter { Name = "object", QualifiedType = new QualifiedType(new CILType(typeof(Object))), }; var methodEquals = new Method { Name = "Equals", Namespace = @class, ReturnType = new QualifiedType(new BuiltinType(PrimitiveType.Bool)), Parameters = new List<Parameter> { methodEqualsParam }, IsSynthetized = true, IsOverride = true, IsProxy = true }; @class.Methods.Add(methodEquals); var methodHashCode = new Method { Name = "GetHashCode", Namespace = @class, ReturnType = new QualifiedType(new BuiltinType(PrimitiveType.Int32)), IsSynthetized = true, IsOverride = true, IsProxy = true }; @class.Methods.Add(methodHashCode); return true; }
public override bool VisitFunctionDecl(Function function) { if (!function.IsGenerated) return false; var types = StringHelpers.SplitCamelCase(function.Name); if (types.Length == 0) return false; var @class = ASTContext.FindCompleteClass(types[0]); if (@class == null) return false; // TODO: If the translation units of the declarations are different, // and we apply the pass, we might need additional includes in the // generated translation unit of the class. if (@class.TranslationUnit != function.TranslationUnit) return false; // Clean up the name of the function now that it will be a static method. var name = function.Name.Substring(@class.Name.Length); function.ExplicitlyIgnore(); // Create a new fake method so it acts as a static method. var method = new Method { Namespace = @class, OriginalNamespace = function.Namespace, Name = name, OriginalName = function.OriginalName, Mangled = function.Mangled, Access = AccessSpecifier.Public, Kind = CXXMethodKind.Normal, ReturnType = function.ReturnType, Parameters = function.Parameters, CallingConvention = function.CallingConvention, IsVariadic = function.IsVariadic, IsInline = function.IsInline, IsStatic = true, Conversion = MethodConversionKind.FunctionToStaticMethod }; @class.Methods.Add(method); Diagnostics.Debug("Function converted to static method: {0}::{1}", @class.Name, function.Name); return true; }
private static void CreateIndexer(Class @class, Method @operator) { Property property = new Property { Name = "Item", QualifiedType = @operator.ReturnType, Access = @operator.Access, Namespace = @class, GetMethod = @operator }; property.Parameters.AddRange(@operator.Parameters); if ([email protected] && @operator.ReturnType.Type.IsAddress()) property.SetMethod = @operator; @class.Properties.Add(property); @operator.IsGenerated = false; }
private void VisitMethod(Method method, Block block) { if (!method.IsSynthetized) return; var @class = (Class)method.Namespace; if (method.Name == "GetHashCode" && method.Parameters.Count == 0) GenerateGetHashCode(block); if (method.Name == "Equals" && method.Parameters.Count == 1) GenerateEquals(@class, block, method); if (method.Name == "ToString" && method.Parameters.Count == 0) GenerateToString(@class, block, method); }
public override bool VisitMethodDecl(Method method) { if (AlreadyVisited(method) || !method.IsGenerated || !method.IsConstructor || method.IsCopyConstructor || method.Parameters.Count != 1) return false; var parameter = method.Parameters[0]; // TODO: disable implicit operators for C++/CLI because they seem not to be support parameters if (!Driver.Options.IsCSharpGenerator) { var pointerType = parameter.Type as PointerType; if (pointerType != null && !pointerType.IsReference) return false; } var qualifiedPointee = parameter.Type.GetFinalPointee() ?? parameter.Type; Class castFromClass; var castToClass = method.OriginalNamespace as Class; if (qualifiedPointee.TryGetClass(out castFromClass)) { if (castToClass == null || castToClass.IsAbstract) return false; if (ConvertsBetweenDerivedTypes(castToClass, castFromClass)) return false; } if (castToClass != null && castToClass.IsAbstract) return false; var operatorKind = method.IsExplicit ? CXXOperatorKind.ExplicitConversion : CXXOperatorKind.Conversion; var qualifiedCastToType = new QualifiedType(new TagType(method.Namespace)); var conversionOperator = new Method { Name = Operators.GetOperatorIdentifier(operatorKind), Namespace = method.Namespace, Kind = CXXMethodKind.Conversion, SynthKind = FunctionSynthKind.ComplementOperator, ConversionType = qualifiedCastToType, ReturnType = qualifiedCastToType, OperatorKind = operatorKind, IsExplicit = method.IsExplicit }; conversionOperator.Parameters.Add(new Parameter(parameter) { DefaultArgument = null }); ((Class) method.Namespace).Methods.Add(conversionOperator); return true; }
public static bool CheckIgnoreMethod(Method method, DriverOptions options) { if (!method.IsGenerated) return true; var isEmptyCtor = method.IsConstructor && method.Parameters.Count == 0; var @class = method.Namespace as Class; if (@class != null && @class.IsValueType && isEmptyCtor) return true; if (method.IsMoveConstructor) return true; if (method.IsDestructor) return true; if (method.OperatorKind == CXXOperatorKind.Equal) return true; if (method.Access == AccessSpecifier.Private && !method.IsOverride && !method.IsExplicitlyGenerated) return true; // Ignore copy constructor if a base class don't has or has a private copy constructor if (method.IsCopyConstructor) { if (!options.GenerateCopyConstructors) return true; var baseClass = @class; while (baseClass != null && baseClass.HasBaseClass) { baseClass = baseClass.BaseClass; if (!baseClass.IsInterface) { var copyConstructor = baseClass.Methods.FirstOrDefault(m => m.IsCopyConstructor); if (copyConstructor == null || copyConstructor.Access == AccessSpecifier.Private || !copyConstructor.IsDeclared) return true; } } } return false; }
private static void GenerateProperty(DeclarationContext context, Method getter, Method setter = null) { Class type = (Class) context; if (type.Properties.All(p => getter.Name != p.Name || p.ExplicitInterfaceImpl != getter.ExplicitInterfaceImpl)) { Property property = new Property(); property.Name = GetPropertyName(getter.Name); property.Namespace = type; property.QualifiedType = getter.OriginalReturnType; if (getter.IsOverride || (setter != null && setter.IsOverride)) { Property baseVirtualProperty = type.GetRootBaseProperty(property); if (baseVirtualProperty.SetMethod == null) setter = null; } property.GetMethod = getter; property.SetMethod = setter; property.ExplicitInterfaceImpl = getter.ExplicitInterfaceImpl; if (property.ExplicitInterfaceImpl == null && setter != null) { property.ExplicitInterfaceImpl = setter.ExplicitInterfaceImpl; } if (getter.Comment != null) { var comment = new RawComment(); comment.Kind = getter.Comment.Kind; comment.BriefText = getter.Comment.BriefText; comment.Text = getter.Comment.Text; comment.FullComment = new FullComment(); comment.FullComment.Blocks.AddRange(getter.Comment.FullComment.Blocks); if (setter != null && setter.Comment != null) { comment.BriefText += Environment.NewLine + setter.Comment.BriefText; comment.Text += Environment.NewLine + setter.Comment.Text; comment.FullComment.Blocks.AddRange(setter.Comment.FullComment.Blocks); } property.Comment = comment; } type.Properties.Add(property); getter.IsGenerated = false; if (setter != null) setter.IsGenerated = false; } }
private static void ImplementInterfaceMethods(Class @class, Class @interface) { foreach (var method in @interface.Methods) { var impl = new Method(method) { Namespace = @class, IsVirtual = false, IsOverride = false }; var rootBaseMethod = @class.GetRootBaseMethod(method, true); if (rootBaseMethod != null && !rootBaseMethod.Ignore) impl.ExplicitInterfaceImpl = @interface; @class.Methods.Add(impl); } foreach (var @base in @interface.Bases) ImplementInterfaceMethods(@class, @base.Class); }
public override bool VisitFunctionDecl(Function function) { if (function.Ignore) return false; var types = StringHelpers.SplitCamelCase(function.Name); if (types.Length == 0) return false; var @class = AstContext.FindCompleteClass(types[0]); if (@class == null) return false; // Clean up the name of the function now that it will be a static method. var name = function.Name.Substring(@class.Name.Length); function.ExplicityIgnored = true; // Create a new fake method so it acts as a static method. var method = new Method() { Namespace = @class, OriginalNamespace = function.Namespace, Name = name, OriginalName = function.OriginalName, Mangled = function.Mangled, Access = AccessSpecifier.Public, Kind = CXXMethodKind.Normal, ReturnType = function.ReturnType, Parameters = function.Parameters, CallingConvention = function.CallingConvention, IsVariadic = function.IsVariadic, IsInline = function.IsInline, IsStatic = true, Conversion = MethodConversionKind.FunctionToStaticMethod }; @class.Methods.Add(method); Log.EmitMessage("Static method: {0}::{1}", @class.Name, function.Name); return true; }
public override bool VisitMethodDecl(Method method) { if (!method.IsConstructor) return false; if (method.IsCopyConstructor) return false; if (method.Parameters.Count != 1) return false; var parameter = method.Parameters[0]; var parameterType = parameter.Type as PointerType; if (parameterType == null) return false; if (!parameterType.IsReference) return false; var qualifiedPointee = parameterType.QualifiedPointee; Class castFromClass; if (!qualifiedPointee.Type.TryGetClass(out castFromClass)) return false; var castToClass = method.OriginalNamespace as Class; if (castToClass == null) return false; if (castFromClass == castToClass) return false; var operatorKind = method.IsExplicit ? CXXOperatorKind.ExplicitConversion : CXXOperatorKind.Conversion; var castToType = new TagType(castToClass); var qualifiedCastToType = new QualifiedType(castToType); var conversionOperator = new Method() { Name = Operators.GetOperatorIdentifier(operatorKind), Namespace = castFromClass, Kind = CXXMethodKind.Conversion, IsSynthetized = true, ConversionType = qualifiedCastToType, ReturnType = qualifiedCastToType }; conversionOperator.OperatorKind = operatorKind; castFromClass.Methods.Add(conversionOperator); return true; }
public override bool VisitMethodDecl(Method method) { if (!base.VisitMethodDecl(method) || !method.IsVirtual || method.Ignore) return false; var @params = method.GatherInternalParams(Driver.Options.IsItaniumLikeAbi, true).ToList(); var delegateName = GenerateDelegateSignature(@params, method.ReturnType); var @delegate = new TypedefDecl { Name = delegateName, QualifiedType = new QualifiedType( new PointerType( new QualifiedType( new FunctionType { CallingConvention = method.CallingConvention, IsDependent = method.IsDependent, Parameters = @params, ReturnType = method.ReturnType }))), Namespace = namespaceDelegates }; var delegateString = @delegate.Visit(TypePrinter).Type; var existingDelegate = GetExistingDelegate(delegateString); if (existingDelegate != null) { Driver.Delegates.Add(method, existingDelegate); return true; } existingDelegate = new DelegateDefinition(Driver.Options.OutputNamespace, delegateString); Driver.Delegates.Add(method, existingDelegate); foreach (var library in Driver.Options.Libraries) libsDelegates[library].Add(delegateString, existingDelegate); namespaceDelegates.Declarations.Add(@delegate); return true; }
public override bool VisitMethodDecl(Method method) { if (method.IsOverride && !method.IsSynthetized) { Method rootBaseMethod = ((Class) method.Namespace).GetBaseMethod(method); for (int i = 0; i < method.Parameters.Count; i++) { var rootBaseParameter = rootBaseMethod.Parameters[i]; var parameter = method.Parameters[i]; if (rootBaseParameter.DefaultArgument == null) { parameter.DefaultArgument = null; } else { parameter.DefaultArgument = rootBaseParameter.DefaultArgument.Clone(); } } } return base.VisitMethodDecl(method); }
public override AST.Declaration VisitMethod(Method decl) { var _method = new AST.Method(); VisitFunction(decl, _method); _method.AccessDecl = Visit(decl.AccessDecl) as AST.AccessSpecifierDecl; _method.IsVirtual = decl.IsVirtual; _method.IsStatic = decl.IsStatic; _method.IsConst = decl.IsConst; _method.IsImplicit = decl.IsImplicit; _method.IsOverride = decl.IsOverride; _method.Kind = VisitCXXMethodKind(decl.MethodKind); _method.IsDefaultConstructor = decl.IsDefaultConstructor; _method.IsCopyConstructor = decl.IsCopyConstructor; _method.IsMoveConstructor = decl.IsMoveConstructor; _method.ConversionType = typeConverter.VisitQualified(decl.ConversionType); return(_method); }
public virtual string VisitMethodDecl(Method method) { return(VisitDeclaration(method)); }
public static bool CheckIgnoreMethod(Method method, DriverOptions options) { if (!method.IsGenerated) { return(true); } var isEmptyCtor = method.IsConstructor && method.Parameters.Count == 0; var @class = method.Namespace as Class; if (@class != null && @class.IsValueType && isEmptyCtor) { return(true); } if (method.IsMoveConstructor) { return(true); } if (method.IsDestructor) { return(true); } if (method.OperatorKind == CXXOperatorKind.Equal) { return(true); } if (method.Access == AccessSpecifier.Private && !method.IsOverride && !method.IsExplicitlyGenerated) { return(true); } // Ignore copy constructor if a base class don't has or has a private copy constructor if (method.IsCopyConstructor) { if (!options.GenerateCopyConstructors) { return(true); } var baseClass = @class; while (baseClass != null && baseClass.HasBaseClass) { baseClass = baseClass.BaseClass; if (!baseClass.IsInterface) { var copyConstructor = baseClass.Methods.FirstOrDefault(m => m.IsCopyConstructor); if (copyConstructor == null || copyConstructor.Access == AccessSpecifier.Private || !copyConstructor.IsDeclared) { return(true); } } } } return(false); }
public virtual bool VisitMethodDecl(Method method) { return(VisitFunctionDecl(method)); }