예제 #1
0
        public override void EnterFoxmethod([NotNull] XP.FoxmethodContext context)
        {
            Check4ClipperCC(context, context.Sig.ParamList?._Params, context.Sig.CallingConvention?.Convention, context.Sig.Type);
            var name = context.Id.GetText().ToUpper();

            if (name == "INIT" && (context.Params == null || context.Params._Params.Count == 0))
            {
                context.Data.HasClipperCallingConvention = true;
            }
            else if (name.EndsWith("_ASSIGN"))
            {
                context.Data.HasClipperCallingConvention = false;
                context.Data.HasTypedParameter           = true; // this will set all missing types to USUAL
                context.Data.MustBeVoid = true;
                context.RealType        = XP.ASSIGN;
            }
            else if (name.EndsWith("_ACCESS"))
            {
                context.Data.HasClipperCallingConvention = false;
                context.Data.HasTypedParameter           = true; // this will set all missing types to USUAL
                context.RealType = XP.ACCESS;
            }
            else
            {
                context.RealType = XP.METHOD;
            }
        }
예제 #2
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);
            }
        }