Ejemplo n.º 1
0
		/// <summary>
		/// Checks whether specified method has parameters suitable for being event handler.
		/// </summary>
		private static bool CheckEventHandlerParameters(Method method)
		{
			if (method.Parameters.Count != 2)
				return false;

			Parameter sender = method.Parameters[0];
			if (sender.Name != "sender")
				return false;

			if (sender.Type.Text != "object")
				return false;

			Parameter args = method.Parameters[1];
			if (args.Name != "e")
				return false;

			if (!ExtractPureName(args.Type.Text, true).EndsWith("EventArgs"))
				return false;

			return true;
		}
Ejemplo n.º 2
0
        /// <summary>
        /// Parses and returns a method.
        /// </summary>
        /// <param name="parent">
        /// The parent of the element.
        /// </param>
        /// <param name="elementReference">
        /// A reference to the element being created.
        /// </param>
        /// <param name="unsafeCode">
        /// Indicates whether the code is marked as unsafe.
        /// </param>
        /// <param name="generated">
        /// Indicates whether the code is marked as generated code.
        /// </param>
        /// <param name="xmlHeader">
        /// The element's documentation header.
        /// </param>
        /// <param name="attributes">
        /// The attributes on the element.
        /// </param>
        /// <returns>
        /// Returns the element.
        /// </returns>
        private Method ParseMethod(
            CsElement parent, Reference<ICodePart> elementReference, bool unsafeCode, bool generated, XmlHeader xmlHeader, ICollection<Attribute> attributes)
        {
            Param.AssertNotNull(parent, "parent");
            Param.AssertNotNull(elementReference, "elementReference");
            Param.Ignore(unsafeCode);
            Param.Ignore(generated);
            Param.Ignore(xmlHeader);
            Param.Ignore(attributes);

            Node<CsToken> previousTokenNode = this.tokens.Last;

            // Get the modifiers and access.
            AccessModifierType accessModifier = AccessModifierType.Private;

            // Get the declared modifiers for the method.
            Dictionary<CsTokenType, CsToken> modifiers = this.GetElementModifiers(elementReference, ref accessModifier, MethodModifiers);

            // Methods within interfaces always have the access of the parent interface.
            Interface parentInterface = parent as Interface;
            if (parentInterface != null)
            {
                accessModifier = parentInterface.AccessModifier;
            }

            unsafeCode |= modifiers.ContainsKey(CsTokenType.Unsafe);

            TypeToken returnType = null;
            if (!modifiers.ContainsKey(CsTokenType.Implicit) && !modifiers.ContainsKey(CsTokenType.Explicit))
            {
                // Get the return type.
                returnType = this.GetTypeToken(elementReference, unsafeCode, true);
                this.tokens.Add(returnType);
            }

            // Get the name of the method.
            string methodName = null;

            Symbol symbol = this.GetNextSymbol(elementReference);
            if (symbol.SymbolType == SymbolType.Operator)
            {
                this.tokens.Add(this.GetToken(CsTokenType.Operator, SymbolType.Operator, elementReference));

                // Advance up to the next symbol.
                this.AdvanceToNextCodeSymbol(elementReference);

                // The overloaded item will either be a type or a symbol.
                int endIndex = -1;
                CsToken operatorType = null;

                if (this.HasTypeSignature(1, unsafeCode, out endIndex))
                {
                    // The overloaded item is a type.
                    operatorType = this.GetTypeToken(elementReference, unsafeCode, true);
                }
                else
                {
                    // The overloaded item is a symbol.
                    operatorType = this.ConvertOperatorOverloadSymbol(elementReference);
                }

                this.tokens.Add(operatorType);
                methodName = "operator " + operatorType.Text;
            }
            else
            {
                CsToken name = this.GetElementNameToken(elementReference, unsafeCode);
                methodName = name.Text;
                this.tokens.Add(name);
            }

            // Get the parameter list.
            IList<Parameter> parameters = this.ParseParameterList(elementReference, unsafeCode, SymbolType.OpenParenthesis, modifiers.ContainsKey(CsTokenType.Static));

            // Check whether there are any type constraint clauses.
            ICollection<TypeParameterConstraintClause> typeConstraints = null;
            symbol = this.GetNextSymbol(elementReference);
            if (symbol.Text == "where")
            {
                typeConstraints = this.ParseTypeConstraintClauses(elementReference, unsafeCode);
            }

            // Create the declaration.
            Node<CsToken> firstTokenNode = previousTokenNode == null ? this.tokens.First : previousTokenNode.Next;
            CsTokenList declarationTokens = new CsTokenList(this.tokens, firstTokenNode, this.tokens.Last);
            Declaration declaration = new Declaration(declarationTokens, methodName, ElementType.Method, accessModifier, modifiers);

            Method method = new Method(this.document, parent, xmlHeader, attributes, declaration, returnType, parameters, typeConstraints, unsafeCode, generated);
            elementReference.Target = method;

            // If the element is extern, abstract, or containing within an interface, it will not have a body.
             if (modifiers.ContainsKey(CsTokenType.Abstract) || modifiers.ContainsKey(CsTokenType.Extern) || parent.ElementType == ElementType.Interface)
            {
                // Get the closing semicolon.
                this.tokens.Add(this.GetToken(CsTokenType.Semicolon, SymbolType.Semicolon, elementReference));
            }
            else
            {
                // Get the method body or bodied expression C# 6.
                this.ParseStatementContainer(method, true, unsafeCode);
            }

            return method;
        }
        /// <summary>
        /// The save.
        /// </summary>
        /// <param name="methodDeclaration">
        /// The method declaration.
        /// </param>
        private void Save(Method methodDeclaration)
        {
            this.CurrentParameters = methodDeclaration.Parameters;

            var methodName = methodDeclaration.Declaration.Name;

            var lastDot = methodName.LastIndexOf('.');
            var nameWithoutNamespace = lastDot != -1
                                           ? methodName.Substring(lastDot + 1, methodName.Length - lastDot - 1)
                                           : methodName;
            var methodInterfaceNamespace = lastDot != -1 ? methodName.Substring(0, lastDot) : string.Empty;

            var isGenericMethod = nameWithoutNamespace.Contains('<') && nameWithoutNamespace.Contains('>');
            var isOperator = methodName.StartsWith("operator ");
            if (isOperator)
            {
                methodName = methodName.Substring("operator ".Length);

                switch (methodName)
                {
                    case "==":
                        methodName = RelationalExpression.Operator.EqualTo.ToString();
                        break;
                    case "!=":
                        methodName = RelationalExpression.Operator.NotEqualTo.ToString();
                        break;
                    case ">":
                        methodName = RelationalExpression.Operator.GreaterThan.ToString();
                        break;
                    case ">=":
                        methodName = RelationalExpression.Operator.GreaterThanOrEqualTo.ToString();
                        break;
                    case "<":
                        methodName = RelationalExpression.Operator.LessThan.ToString();
                        break;
                    case "<=":
                        methodName = RelationalExpression.Operator.LessThanOrEqualTo.ToString();
                        break;
                    case "+":
                        methodName = "Add";
                        break;
                    case "-":
                        methodName = "Remove";
                        break;
                    default:
                        break;
                }

                methodName = string.Concat("op_", methodName);
                nameWithoutNamespace = methodName;
            }

            // decide which mode 1/2 files to use;
            var restoreStateIsCppInHeader = this.IsCPPInHeader;
            if (!this.IsCPPInHeader)
            {
                this.IsCPPInHeader = isGenericMethod;
            }

            if (this.ClassContext.IsInterface)
            {
                this.IsCPPInHeader = true;
            }

            // 1 to destHeader
            this.Save(methodDeclaration.AccessModifier);
            this.headerWriter.Write(": ");

            var isImplicit = false;
            var isExplicit = false;

            // if generic, write template here
            if (isGenericMethod)
            {
                this.BuildDeclaretionTemplatePart(methodName);
                this.headerWriter.Write(this.BuildDeclaretionTemplatePart(methodName));
            }

            methodDeclaration.SaveDeclatationsAfterModifiers(this.headerWriter);

            // ASD: HACK
            if (methodDeclaration.ReturnType != null)
            {
                // 1 to destHeader
                this.Save(methodDeclaration.ReturnType);

                if (!this.IsCPPInHeader)
                {
                    // 2 to Source
                    this.Save(methodDeclaration.ReturnType, this.cppWriter, SavingOptions.None);
                }
            }
            else
            {
                // check if it is implicit or explicit operators
                isImplicit = methodDeclaration.Declaration.ContainsModifier(CsTokenType.Implicit);
                isExplicit = methodDeclaration.Declaration.ContainsModifier(CsTokenType.Explicit);
                if (isImplicit || isExplicit)
                {
                    // var returnType = new ResolvedTypeReference(typeConvertTypeName, this);
                    // this.Save(returnType, this.destHeader, false);
                    if (!this.IsCPPInHeader)
                    {
                        // 2 to Source
                        // this.Save(returnType, this.destCPP, false);
                    }
                }
            }

            var cppName = nameWithoutNamespace;
            cppName = isGenericMethod ? cppName.Split('<')[0] : cppName;

            // add namespace of interface if any
            if (!string.IsNullOrEmpty(methodInterfaceNamespace))
            {
                // var typeResolverReference = new ResolvedTypeReference(methodInterfaceNamespace, this);

                // cppName = String.Concat(typeResolverReference.CNameFullyQualifiedName, "::", cppName);
            }

            if (isImplicit)
            {
                cppName = "op_Implicit";
            }
            else if (isExplicit)
            {
                cppName = "op_Explicit";
            }

            // 1 to destHeader
            this.headerWriter.Write(' ');
            this.headerWriter.Write(cppName);

            // 2 to Source
            if (!this.IsCPPInHeader)
            {
                this.cppWriter.Write(' ');
                this.cppWriter.Write(this.currentClassNamespace);
                this.cppWriter.Write("::");
                this.cppWriter.Write(cppName);
            }

            this.SaveParametersAndBody(methodDeclaration);

            if (!this.IsCPPInHeader)
            {
                this.cppWriter.WriteLine();
            }

            this.CurrentParameters = null;

            this.IsCPPInHeader = restoreStateIsCppInHeader;
        }