示例#1
0
        public FunctionDecl(SourceUnit /*!*/ sourceUnit,
                            Position position, Position entireDeclarationPosition, ShortPosition headingEndPosition, ShortPosition declarationBodyPosition,
                            bool isConditional, Scope scope, PhpMemberAttributes memberAttributes, string /*!*/ name, NamespaceDecl ns,
                            bool aliasReturn, List <FormalParam> /*!*/ formalParams, List <FormalTypeParam> /*!*/ genericParams,
                            List <Statement> /*!*/ body, List <CustomAttribute> attributes)
            : base(position)
        {
            Debug.Assert(genericParams != null && name != null && formalParams != null && body != null);

            this.name                      = new Name(name);
            this.ns                        = ns;
            this.signature                 = new Signature(aliasReturn, formalParams);
            this.typeSignature             = new TypeSignature(genericParams);
            this.attributes                = new CustomAttributes(attributes);
            this.body                      = body;
            this.entireDeclarationPosition = entireDeclarationPosition;
            this.headingEndPosition        = headingEndPosition;
            this.declarationBodyPosition   = declarationBodyPosition;

            QualifiedName qn = (ns != null) ? new QualifiedName(this.name, ns.QualifiedName) : new QualifiedName(this.name);

            function = new PhpFunction(qn, memberAttributes, signature, typeSignature, isConditional, scope, sourceUnit, position);
            function.WriteUp(typeSignature.ToPhpRoutineSignature(function));

            function.Declaration.Node = this;
        }
示例#2
0
            public FunctionDeclCompiler(FunctionDecl /*!*/ node)
            {
                this.node = node;

                QualifiedName qn = (node.Namespace != null)
                    ? new QualifiedName(node.Name, node.Namespace.QualifiedName)
                    : new QualifiedName(node.Name);

                function = new PhpFunction(
                    qn, node.MemberAttributes, node.Signature, node.TypeSignature,
                    node.IsConditional, node.Scope, (CompilationSourceUnit)node.SourceUnit, node.Span);

                function.WriteUp(node.TypeSignature.ToPhpRoutineSignature(function));
                function.Declaration.Node = this;
            }
示例#3
0
        /// <summary>
        /// Emit publically accessible stub that just calls argfull of <paramref name="function"/>.
        /// </summary>
        /// <returns><see cref="MethodInfo"/> of newly created function stub.</returns>
        private MethodInfo /*!*/ EmitPhpFunctionPublicStub(ref TypeBuilder publicsContainer, PhpFunction /*!*/ function)
        {
            Debug.Assert(function != null);
            Debug.Assert(function.ArgFullInfo != null, "!function.ArgFullInfo");

            if (publicsContainer == null)
            {
                publicsContainer = PureAssemblyBuilder.RealModuleBuilder.DefineType(
                    string.Format("{1}<{0}>",
                                  StringUtils.ToClsCompliantIdentifier(Path.ChangeExtension(PureAssemblyBuilder.FileName, "")),
                                  QualifiedName.Global.ToString()),
                    TypeAttributes.Public | TypeAttributes.Sealed | TypeAttributes.Class | TypeAttributes.SpecialName);
            }

            Type returnType;
            var  parameterTypes = function.Signature.ToArgfullSignature(1, out returnType);

            parameterTypes[0] = Types.ScriptContext[0];

            var mi = publicsContainer.DefineMethod(function.GetFullName(), MethodAttributes.Public | MethodAttributes.Static, returnType, parameterTypes);
            var il = new ILEmitter(mi);

            // load arguments
            for (int i = 0; i < parameterTypes.Length; i++)
            {
                if (function.Builder != null)
                {
                    mi.DefineParameter(i + 1, ParameterAttributes.None, function.Builder.ParameterBuilders[i].Name);
                }

                il.Ldarg(i);
            }

            // call function.ArgFullInfo
            il.Emit(OpCodes.Call, function.ArgFullInfo);

            // .ret
            il.Emit(OpCodes.Ret);

            //
            return(mi);
        }
示例#4
0
 /// <summary>
 /// Initializes a new instance of the <see cref="FunctionCouplingVisitor" /> class.
 /// </summary>
 /// <param name="function">Function whose sub-tree is traversed for function references.</param>
 public FunctionCouplingVisitor(PhpFunction function)
 {
     currentFunction = function;
 }
示例#5
0
        private void Bake()
        {
            if (types != null)
            {
                bakedTypes = new KeyValuePair <string, PhpTypeDesc> [types.Count];

                int i = 0;
                foreach (Declaration declaration in types.Values)
                {
                    PhpType type = (PhpType)declaration.Declaree;

                    // store full name before calling Bake() as it nulls the PhpType:
                    string      full_name = type.FullName;
                    PhpTypeDesc baked     = type.Bake();

                    // baked is null if the type is indefinite
                    // (its base class may be evaluated when the module's main method is executed):
                    if (baked != null && !declaration.IsConditional)
                    {
                        bakedTypes[i++] = new KeyValuePair <string, PhpTypeDesc>(full_name, baked);
                    }
                }

                // trim:
                Array.Resize(ref bakedTypes, i);

                types = null;
            }

            if (functions != null)
            {
                bakedFunctions = new KeyValuePair <string, PhpRoutineDesc> [functions.Count];

                int i = 0;
                foreach (Declaration declaration in functions.Values)
                {
                    PhpFunction function = (PhpFunction)declaration.Declaree;

                    string         full_name = function.FullName;
                    PhpRoutineDesc baked     = function.Bake();

                    if (!declaration.IsConditional)
                    {
                        bakedFunctions[i++] = new KeyValuePair <string, PhpRoutineDesc>(full_name, baked);
                    }
                }

                // trim:
                Array.Resize(ref bakedFunctions, i);

                functions = null;
            }

            if (constants != null)
            {
                bakedConstants = new KeyValuePair <string, DConstantDesc> [constants.Count];

                int i = 0;
                foreach (Declaration declaration in constants.Values)
                {
                    GlobalConstant constant = (GlobalConstant)declaration.Declaree;

                    string        full_name = constant.FullName;
                    DConstantDesc baked     = constant.Bake();

                    if (!declaration.IsConditional)
                    {
                        bakedConstants[i++] = new KeyValuePair <string, DConstantDesc>(full_name, baked);
                    }
                }

                // trim:
                Array.Resize(ref bakedConstants, i);

                constants = null;
            }
        }
示例#6
0
        /// <summary>
        ///	reflect global functions in &lt;Script&gt; class
        /// TODO: consider merging with PhpTypeDesc.FullReflectMethods
        /// </summary>
        /// <param name="functions">Dictionary for functions</param>
        /// <param name="scriptType">The type to reflect from.</param>
        private static void ReflectScriptTypeFunctions(Type scriptType, Dictionary <string, DRoutineDesc> functions)
        {
            MethodInfo[] real_methods = scriptType.GetMethods(DTypeDesc.MembersReflectionBindingFlags);
            Dictionary <string, MethodInfo> argless_stubs = new Dictionary <string, MethodInfo>(real_methods.Length / 3);

            // first pass - fill argless_stubs
            for (int i = 0; i < real_methods.Length; i++)
            {
                MethodInfo info = real_methods[i];
                if ((info.Attributes & MethodAttributes.MemberAccessMask) != MethodAttributes.PrivateScope)
                {
                    if (PhpFunctionUtils.IsArglessStub(info, null))
                    {
                        argless_stubs.Add(info.Name, info);
                        real_methods[i] = null;
                    }
                }
                else
                {
                    real_methods[i] = null;                  // expunge private scope methods
                }
            }

            // second pass - match argfulls
            foreach (MethodInfo info in real_methods)
            {
                // argfull detection:
                if (info == null || !PhpFunctionUtils.IsArgfullOverload(info, null))
                {
                    continue;
                }

                // TODO: namespaces!!

                if (functions.ContainsKey(info.Name))
                {
                    throw new InvalidOperationException("Function '" + info.Name + "' redeclaration.");   // compilation unit contains more functions with the same name
                }
                // find the argless:
                MethodInfo argless_info = null;
                if (!argless_stubs.TryGetValue(info.Name, out argless_info))
                {
                    // argless has to be generated on-the-fly
                    throw new NotImplementedException("Generating argless stubs for imported PHP types is not yet implemented");
                }

                if (!PhpFunctionUtils.IsRealConditionalDefinition(info.Name))
                {
                    Name                name = new Name(info.Name);
                    DRoutineDesc        func_desc;
                    PhpMemberAttributes attrs = Enums.GetMemberAttributes(info);

                    // this method has not been populated -> create a new PhpRoutineDesc
                    func_desc = new PhpRoutineDesc(attrs, (RoutineDelegate)Delegate.CreateDelegate(Types.RoutineDelegate, argless_info), true);
                    functions.Add(info.Name, func_desc);

                    //
                    if (func_desc.Member == null)
                    {
                        PhpFunction func = new PhpFunction(new QualifiedName(name), (PhpRoutineDesc)func_desc, info, argless_info);
                        func.WriteUp(PhpRoutineSignature.FromArgfullInfo(func, info));
                        func_desc.Member = func;
                    }
                }
            }
        }