public override void EnterXppinlineMethod([NotNull] XP.XppinlineMethodContext context)
        {
            // should do the same as the 'normal' methods in VO Class
            // method init becomes constructor
            // method initClass becomes Class constructor
            Check4ClipperCC(context, context.ParamList?._Params, null, context.Type);
            CheckInitMethods(context);
            var decl = new XppDeclaredMethodInfo()
            {
                Name = context.ShortName, Parent = _currentClass, Visibility = _currentClass.CurrentVisibility, Declaration = context, Entity = context, Inline = true
            };

            context.Info = decl;
            _currentClass.Methods.Add(decl);
        }
 public override void EnterXppdeclareMethod([NotNull] XP.XppdeclareMethodContext context)
 {
     // add method to list of declared methods in the class
     // use the current visibility saved with declMethodVis
     // and include the IsIn property for rerouting methods (should we support that ?)
     if (_currentClass == null)
     {
         // Generate an error
         return;
     }
     foreach (var name in context._Methods)
     {
         var declInfo = new XppDeclaredMethodInfo()
         {
             Name = name.GetText(), Parent = _currentClass, Declaration = context
         };
         declInfo.Visibility = _currentClass.CurrentVisibility;
         _currentClass.Methods.Add(declInfo);
     }
 }
        private PropertyDeclarationSyntax XppCreateProperty(XppDeclaredMethodInfo propDecl)
        {
            var    propctxt = (XP.XpppropertyContext)propDecl.Declaration;
            string propName = propDecl.Name;
            string accName  = propDecl.AccessMethod;
            string assName  = propDecl.AssignMethod;

            if (accName != null && !propDecl.HasVarName)
            {
                accName = accName + XSharpSpecialNames.PropertySuffix;
            }
            if (assName != null && !propDecl.HasVarName)
            {
                assName = assName + XSharpSpecialNames.PropertySuffix;
            }
            var propType = propctxt.Type?.Get <TypeSyntax>();

            if (propType == null)
            {
                propType = _getMissingType();
            }
            var method     = propDecl.Entity as XP.XppmethodContext;
            var accessors  = _pool.Allocate <AccessorDeclarationSyntax>();
            var modifiers  = decodeXppMemberModifiers(propDecl.Visibility, false, method.Modifiers?._Tokens);
            var attributes = EmptyList <AttributeListSyntax>();

            if (method.Attributes != null && propctxt.Attributes == null)
            {
                attributes = method.Attributes.GetList <AttributeListSyntax>();
            }
            else if (method.Attributes == null && propctxt.Attributes != null)
            {
                attributes = propctxt.Attributes.GetList <AttributeListSyntax>();
            }

            #region Accessor
            if (!String.IsNullOrEmpty(accName))
            {
                var methodCall = GenerateMethodCall(accName, true);
                var block      = MakeBlock(GenerateReturn(methodCall));
                block.XGenerated = true;
                var accessor = _syntaxFactory.AccessorDeclaration(SyntaxKind.GetAccessorDeclaration,
                                                                  EmptyList <AttributeListSyntax>(), EmptyList <SyntaxToken>(),
                                                                  SyntaxFactory.MakeToken(SyntaxKind.GetKeyword),
                                                                  block, null, SyntaxFactory.MakeToken(SyntaxKind.SemicolonToken));
                accessor.XNode = method;
                accessors.Add(accessor);
            }
            #endregion
            #region Assign
            if (!String.IsNullOrEmpty(assName))
            {
                method = propDecl.SetEntity as XP.XppmethodContext;
                var args       = MakeArgumentList(MakeArgument(GenerateSimpleName("value")));
                var methodCall = GenerateMethodCall(accName, args, true);
                var stmt       = GenerateExpressionStatement(methodCall);
                var block      = MakeBlock(stmt);
                block.XGenerated = true;
                var accessor = _syntaxFactory.AccessorDeclaration(SyntaxKind.SetAccessorDeclaration,
                                                                  EmptyList <AttributeListSyntax>(), EmptyList <SyntaxToken>(),
                                                                  SyntaxFactory.MakeToken(SyntaxKind.SetKeyword),
                                                                  block, null, SyntaxFactory.MakeToken(SyntaxKind.SemicolonToken));
                accessor.XNode = method;
                accessors.Add(accessor);
            }
            #endregion
            var accessorList = _syntaxFactory.AccessorList(SyntaxFactory.MakeToken(SyntaxKind.OpenBraceToken),
                                                           accessors, SyntaxFactory.MakeToken(SyntaxKind.CloseBraceToken));
            var prop = _syntaxFactory.PropertyDeclaration(
                attributes,
                modifiers: modifiers,
                type: propType,
                explicitInterfaceSpecifier: null,
                identifier: SyntaxFactory.MakeIdentifier(propName),
                accessorList: accessorList,
                expressionBody: null,
                initializer: null,
                semicolonToken: SyntaxFactory.MakeToken(SyntaxKind.SemicolonToken));
            _pool.Free(accessors);
            return(prop);
        }
        public override void EnterXppproperty([NotNull] XP.XpppropertyContext context)
        {
            // When [VAR <VarName>] is missing then this is a declaration of an ACCESS or ASSIGN method.
            // In that case treat implementation like VO Access/assign
            // When VAR is available then the property name = the VAR name and the method names should be called
            // in the getter and setter
            // XPP allows to declare an ACCESS METHOD and then declare the method body without ACCESS prefix !
            // The method is called with an optional parameter (the value from the property)
            // In the method body the user needs to check for the type to see if the getter or setter is called.
            //
            //

            /*
             * // example from XbZLog.prg
             * Class XbZ_LogWriter
             *  Var cLogPath
             *  Var lLogActive
             *  Sync Method Open
             *  Sync Method Stop
             *  Access Assign Method Path
             * EndClass
             * Method XbZ_LogWriter:Path(cPath)
             *      if PCount() == 1 .and. ValType(cPath) == 'C'
             *              ::cLogPath := alltrim(iif(empty(cPath), left(AppName(.t.), RAt('\', AppName(.t.))), cPath))
             *              ::cLogPath += iif(right(::cLogPath, 1) == '\', '', '\')
             *              if ::lLogActive .and. ::Stop(.t.)
             *                      ::Open()
             *              endif
             *      endif
             * return (::cLogPath)
             */
            string name       = context.Id.GetText();
            bool   hasVarName = context.VarName != null;

            if (hasVarName)
            {
                name = context.VarName.GetText();
            }
            _currentClass.AddProperty(name);
            // it is allowed to have a separate line for ACCESS and ASSIGN and map them to different methods
            var declInfo = _currentClass.Methods.Where(x => x.Name == name && x.IsProperty).FirstOrDefault();

            if (declInfo == null)
            {
                declInfo = new XppDeclaredMethodInfo()
                {
                    Name = name, Declaration = context, IsProperty = true, Visibility = _currentClass.CurrentVisibility
                };
                _currentClass.Methods.Add(declInfo);
            }
            declInfo.HasVarName = hasVarName;
            // check to see if we have a declaration
            if (context.Access != null)
            {
                declInfo.AccessMethod = context.Id.GetText();
            }
            if (context.Assign != null)
            {
                declInfo.AssignMethod = context.Id.GetText();
            }
        }