コード例 #1
0
        public override void ExitFoxmethod([NotNull] XP.FoxmethodContext context)
        {
            context.SetSequencePoint(context.T.Start, context.end.Stop);
            var idName     = context.Id.Get <SyntaxToken>();
            var mods       = context.Modifiers?.GetList <SyntaxToken>() ?? DefaultMethodModifiers(false, false, context.TypeParameters != null);
            var isExtern   = mods.Any((int)SyntaxKind.ExternKeyword);
            var isAbstract = mods.Any((int)SyntaxKind.AbstractKeyword);
            var hasNoBody  = isExtern || isAbstract;
            var mName      = idName.Text;

            if (mName.EndsWith("_ACCESS", StringComparison.OrdinalIgnoreCase))
            {
                mName = mName.Substring(0, mName.Length - "_ACCESS".Length);
            }
            else if (mName.EndsWith("_ASSIGN", StringComparison.OrdinalIgnoreCase))
            {
                mName = mName.Substring(0, mName.Length - "_ASSIGN".Length);
            }
            idName = SyntaxFactory.MakeIdentifier(mName);
            bool isAccessAssign        = this.isAccessAssign(context.RealType);
            var  attributes            = context.Attributes?.GetList <AttributeListSyntax>() ?? EmptyList <AttributeListSyntax>();
            bool hasExtensionAttribute = false;

            if (isAccessAssign)
            {
                var vomods = _pool.Allocate();
                vomods.Add(SyntaxFactory.MakeToken(SyntaxKind.PrivateKeyword));
                if (mods.Any((int)SyntaxKind.StaticKeyword))
                {
                    vomods.Add(SyntaxFactory.MakeToken(SyntaxKind.StaticKeyword));
                }
                if (mods.Any((int)SyntaxKind.UnsafeKeyword))
                {
                    vomods.Add(SyntaxFactory.MakeToken(SyntaxKind.UnsafeKeyword));
                }
                mods = vomods.ToList <SyntaxToken>();
                _pool.Free(vomods);
            }

            if (!isExtern)
            {
                isExtern  = hasDllImport(attributes);
                hasNoBody = hasNoBody || isExtern;
            }
            if (isExtern && !mods.Any((int)SyntaxKind.ExternKeyword))
            {
                // Add Extern Keyword to modifiers
                var m1 = _pool.Allocate();
                m1.AddRange(mods);
                if (!m1.Any((int)SyntaxKind.ExternKeyword))
                {
                    m1.Add(SyntaxFactory.MakeToken(SyntaxKind.ExternKeyword));
                }
                mods = m1.ToList <SyntaxToken>();
                _pool.Free(m1);
            }
            var parameters = context.ParamList?.Get <ParameterListSyntax>() ?? EmptyParameterList();
            var body       = hasNoBody ? null : context.StmtBlk.Get <BlockSyntax>();
            var returntype = context.Type?.Get <TypeSyntax>();

            if (returntype == null)
            {
                if (context.RealType == XP.ASSIGN)
                {
                    returntype = VoidType();
                }
                else  // method and access
                {
                    returntype       = _getMissingType();
                    returntype.XNode = context;
                }
            }
            else
            {
                returntype.XVoDecl = true;
            }
            var oldbody = body;

            ImplementClipperAndPSZ(context, ref attributes, ref parameters, ref body, ref returntype);
            if (body != oldbody)
            {
                context.StmtBlk.Put(body);
            }
            if (context.RealType == XP.ASSIGN)
            {
                // Assign does not need a return.
                // So do not add missing returns
                returntype = VoidType();
            }
            else if (context.StmtBlk != null && !hasNoBody)
            {
                body = AddMissingReturnStatement(body, context.StmtBlk, returntype);
            }
            MemberDeclarationSyntax m = _syntaxFactory.MethodDeclaration(
                attributeLists: attributes,
                modifiers: mods,
                returnType: returntype,
                explicitInterfaceSpecifier: null,
                identifier: idName,
                typeParameterList: context.TypeParameters?.Get <TypeParameterListSyntax>(),
                parameterList: parameters,
                constraintClauses: MakeList <TypeParameterConstraintClauseSyntax>(context._ConstraintsClauses),
                body: body,
                expressionBody: null, // TODO: (grammar) expressionBody methods
                semicolonToken: (!hasNoBody && context.StmtBlk != null) ? null : SyntaxFactory.MakeToken(SyntaxKind.SemicolonToken));

            if (hasExtensionAttribute)
            {
                m = m.WithAdditionalDiagnostics(new SyntaxDiagnosticInfo(ErrorCode.ERR_ExplicitExtension));
            }
            bool separateMethod = false;

            context.Put(m);
            if (isAccessAssign && !separateMethod)
            {
                if (context.Data.HasClipperCallingConvention && context.CallingConvention != null)
                {
                    m = m.WithAdditionalDiagnostics(new SyntaxDiagnosticInfo(
                                                        ErrorCode.ERR_NoClipperCallingConventionForAccessAssign));
                }
                context.Put(m);
                ClassEntities.Peek().AddVoPropertyAccessor(context, context.RealType, idName);
            }
        }
コード例 #2
0
        public override void ExitXppclassvars([NotNull] XP.XppclassvarsContext context)
        {
            // add class vars to current class
            // use the current visibility saved with declMethodVis
            // IS and IN are not supported, so produce warning
            // include [SHARED], [READONLY] [ASSIGNMENT HIDDEN | PROTECTED | EXPORTED]  and [NOSAVE] modifiers
            // on top of the visibility modifier
            // The [Readonly] clause and [Assignment] clause are not supported yet
            // In as future build we will create a private backing Ivar and
            // Create a property with Getter and Setter with property visibility
            // to emulate the possible combinations of [ReadOnly] and Assignment and Visibility
            // The following table lists what should be done
            // ========================================================================.
            //               | Visibility                                              |
            // Assignment    | Hidden           |  Protected        | Exported         |
            // ========================================================================.
            // Hidden        | pri Get/pri Set  |  pro Get pri Set  | pub Get pri Set  |
            // Protected     |                  |  pro Get pro Set  | pub Get pro Set  |
            // Exported      |    -             |                   | pub Get pub Set  |
            // ========================================================================.
            // // The Readonly clause does something similar as the ASSIGNMENT.
            // For the following visibilities this results in:
            // Private         Readonly is useless
            // Protected       Readonly creates a Protected Getter and a hidden/Private Setter
            // Exported/Public ReadOnly creates a Public Getter and a Protected Setter
            //
            var varList = _pool.AllocateSeparated <VariableDeclaratorSyntax>();
            // Check to see if the variables have not been also declared as property
            // when they are we do not generate variables
            var varType = context.DataType?.Get <TypeSyntax>() ?? _getMissingType();

            varType.XVoDecl = true;
            var fieldList      = new List <FieldDeclarationSyntax>();
            var attributeLists = _pool.Allocate <AttributeListSyntax>();

            if (context.Nosave != null)
            {
                GenerateAttributeList(attributeLists, SystemQualifiedNames.NonSerialized);
            }
            foreach (var id in context._Vars)
            {
                varList.Clear();
                var name     = id.GetText();
                var variable = GenerateVariable(id.Get <SyntaxToken>());
                varList.Add(variable);
                // calculate modifiers
                // each field is added separately so we can later decide which field to keep and which one to delete when they are duplicated by a
                var modifiers = decodeXppMemberModifiers(context.Visibility, false, context.Modifiers?._Tokens);
                if (varList.Count > 0)
                {
                    var decl = _syntaxFactory.VariableDeclaration(
                        type: varType,
                        variables: varList);

                    var fdecl = _syntaxFactory.FieldDeclaration(
                        attributeLists: attributeLists,
                        modifiers: modifiers,
                        declaration: decl,
                        semicolonToken: SyntaxFactory.MakeToken(SyntaxKind.SemicolonToken));

                    ClassEntities.Peek().Members.Add(fdecl);
                    fieldList.Add(fdecl);
                }
            }
            context.PutList(MakeList <FieldDeclarationSyntax>(fieldList));
            _pool.Free(varList);
            _pool.Free(attributeLists);
        }