예제 #1
0
 public void Visit(MethodDeclaration methodDeclaration)
 {
     methodDeclaration.Qualifiers.Values.Remove(ParadoxStorageQualifier.Override);
     methodDeclaration.Qualifiers.Values.Remove(ParadoxStorageQualifier.Clone);
     methodDeclaration.Qualifiers.Values.Remove(ParadoxStorageQualifier.Stage);
     Visit((Node)methodDeclaration);
 }
예제 #2
0
        /// <summary>
        /// Replace the method occurence with its last definition
        /// </summary>
        /// <param name="methodDeclaration">the overriding method</param>
        /// <param name="errorLogger"></param>
        public void ReplaceVirtualMethod(MethodDeclaration methodDeclaration, LoggerResult errorLogger)
        {
            var baseDeclarationMixin = (string)methodDeclaration.GetTag(XenkoTags.BaseDeclarationMixin);
            foreach (var dict in VirtualTableGroup.Select(x => x.Value))
            {
                for (int i = 0; i < dict.Length; ++i)
                {
                    var method = dict[i];
                    var originalDecl = (string)method.GetTag(XenkoTags.BaseDeclarationMixin);

                    // TODO: take typedefs into account...
                    if (originalDecl == baseDeclarationMixin && method.IsSameSignature(methodDeclaration))
                    {
                        if (method.Qualifiers.Contains(XenkoStorageQualifier.Stage) && !methodDeclaration.Qualifiers.Contains(XenkoStorageQualifier.Stage))
                        {
                            errorLogger.Warning(XenkoMessageCode.WarningMissingStageKeyword, methodDeclaration.Span, methodDeclaration, (methodDeclaration.GetTag(XenkoTags.ShaderScope) as ModuleMixin).MixinName);
                            methodDeclaration.Qualifiers |= XenkoStorageQualifier.Stage;
                        }
                        else if (!method.Qualifiers.Contains(XenkoStorageQualifier.Stage) && methodDeclaration.Qualifiers.Contains(XenkoStorageQualifier.Stage))
                        {
                            errorLogger.Error(XenkoMessageCode.ErrorExtraStageKeyword, methodDeclaration.Span, methodDeclaration, method, (methodDeclaration.GetTag(XenkoTags.ShaderScope) as ModuleMixin).MixinName);
                            methodDeclaration.Qualifiers.Values.Remove(XenkoStorageQualifier.Stage);
                        }

                        dict[i] = methodDeclaration;
                    }
                }
            }
        }
예제 #3
0
        /// <summary>
        /// Adds the methods defined in the final mixin
        /// </summary>
        /// <param name="methodDeclarations">a list of MethodDeclaration</param>
        /// <param name="className">the name of the class</param>
        /// <param name="errorLogger">the logger for errors and warnings</param>
        public void AddFinalDeclarations(List<MethodDeclaration> methodDeclarations, string className, LoggerResult errorLogger)
        {
            var finalDict = new MethodDeclaration[methodDeclarations.Count];
            foreach (var methodDecl in methodDeclarations)
            {
                var vtableReference = (VTableReference)methodDecl.GetTag(XenkoTags.VirtualTableReference);
                finalDict[vtableReference.Slot] = methodDecl;

                // TODO: override/abstract behavior
                //if (methodDecl.Qualifiers.Contains(XenkoStorageQualifier.Override))
                    LookForBaseDeclarationMixin(methodDecl, errorLogger);
            }

            VirtualTableGroup.Add(className, finalDict);
        }
예제 #4
0
 /// <summary>
 /// rename the input/ouput of a method
 /// </summary>
 /// <param name="methodDeclaration">the method</param>
 /// <param name="inputName">the type replacement for Input</param>
 /// <param name="input2Name">the type replacement for Input2</param>
 /// <param name="outputName">the type replacement for Output</param>
 /// <param name="constantsName">the type replacement for Constants</param>
 private void RenameInputOutput(MethodDeclaration methodDeclaration, TypeName inputName, TypeName input2Name, TypeName outputName, TypeName constantsName)
 {
     if (inputName != null)
     {
         var replacor = new ParadoxReplaceVisitor(StreamsType.Input, inputName);
         replacor.Run(methodDeclaration);
     }
     if (input2Name != null)
     {
         var replacor = new ParadoxReplaceVisitor(StreamsType.Input2, input2Name);
         replacor.Run(methodDeclaration);
     }
     if (outputName != null)
     {
         var replacor = new ParadoxReplaceVisitor(StreamsType.Output, outputName);
         replacor.Run(methodDeclaration);
     }
     if (constantsName != null)
     {
         var replacor = new ParadoxReplaceVisitor(StreamsType.Constants, constantsName);
         replacor.Run(methodDeclaration);
     }
 }
        /// <summary>
        /// Analyse the method definition and store it in the correct lists (based on storage and stream usage)
        /// </summary>
        /// <param name="methodDefinition">the MethodDefinition</param>
        /// <returns>the input method definition</returns>
        public override Node Visit(MethodDefinition methodDefinition)
        {
            currentVisitedMethod = methodDefinition;
            
            if (methodDefinition.Qualifiers.Contains(XenkoStorageQualifier.Abstract))
                Error(XenkoMessageCode.ErrorUnnecessaryAbstract, methodDefinition.Span, methodDefinition, analyzedModuleMixin.MixinName);

            var ret = base.Visit(methodDefinition);

            PostMethodDeclarationVisit(methodDefinition);

            return ret;
        }
예제 #6
0
 /// <summary>
 /// Initializes a new instance of the <see cref="MethodDefinition"/> class.
 /// </summary>
 /// <param name="returntype">The returntype.</param>
 /// <param name="name">The name.</param>
 public MethodDefinition(TypeBase returntype, string name) : this()
 {
     ReturnType  = returntype;
     Name        = new Identifier(name);
     declaration = this;
 }
예제 #7
0
 /// <summary>
 /// Initializes a new instance of the <see cref="MethodDefinition"/> class.
 /// </summary>
 public MethodDefinition()
 {
     Body = new StatementList();
     declaration = this;
 }
 /// <summary>
 /// Store the method in the correct list
 /// </summary>
 /// <param name="methodDeclaration"></param>
 private void StoreMethod(MethodDeclaration methodDeclaration)
 {
     if (!parsingInfo.ClassReferences.MethodsReferences.ContainsKey(methodDeclaration))
         parsingInfo.ClassReferences.MethodsReferences.Add(methodDeclaration, new HashSet<MethodInvocationExpression>());
 }
예제 #9
0
 /// <summary>
 /// Copies declartion to another instance.
 /// </summary>
 /// <param name="target">The target instance.</param>
 public void CopyTo(MethodDeclaration target)
 {
     target.Attributes = Attributes;
     target.Name = Name;
     target.Parameters = Parameters;
     target.Qualifiers = Qualifiers;
     target.ReturnType = ReturnType;
 }
예제 #10
0
파일: ShaderWriter.cs 프로젝트: cg123/xenko
 public virtual void Visit(MethodDeclaration methodDeclaration)
 {
     WriteLinkLine(methodDeclaration);
     WriteMethodDeclaration(methodDeclaration).WriteLine(";");
 }
예제 #11
0
        /// <summary>
        /// Get all the calls from the current method
        /// </summary>
        /// <param name="currentMethod">the current method</param>
        /// <param name="calledMethods">list of method called</param>
        /// <returns>true if calls were found</returns>
        //private bool TryGetMethodCalls(MethodDeclaration currentMethod, out List<MethodInvocationExpression> calledMethods)
        private bool TryGetMethodCalls(MethodDeclaration currentMethod, out List<MethodDeclaration> calledMethods)
        {
            List<StreamUsageInfo> streamUsageInfos;
            if (streamsUsages.TryGetValue(currentMethod, out streamUsageInfos))
            {
                //calledMethods = streamUsageInfos.Where(x => x.CallType == StreamCallType.Method).Select(x => x.MethodReference).ToList();
                calledMethods = streamUsageInfos.Where(x => x.CallType == StreamCallType.Method).Select(x => x.MethodDeclaration).ToList();
                return true;
            }

            calledMethods = null;
            return false;
        }
예제 #12
0
        protected void Visit(MethodDeclaration methodDeclaration)
        {
            currentVisitedMethod = methodDeclaration;
            
            if (!methodDeclaration.Qualifiers.Contains(ParadoxStorageQualifier.Abstract))
                Error(ParadoxMessageCode.ErrorMissingAbstract, methodDeclaration.Span, methodDeclaration, analyzedModuleMixin.MixinName);
            if (methodDeclaration.Qualifiers.Contains(ParadoxStorageQualifier.Override))
                Error(ParadoxMessageCode.ErrorUnnecessaryOverride, methodDeclaration.Span, methodDeclaration, analyzedModuleMixin.MixinName);

            Visit((Node)methodDeclaration);
            PostMethodDeclarationVisit(methodDeclaration);
        }
예제 #13
0
        /// <summary>
        /// Recursively rename the input/output types
        /// </summary>
        /// <param name="methodDeclaration">the method to explore</param>
        /// <param name="inputName">the TypeName for Input</param>
        /// <param name="input2Name">the TypeName for Input2</param>
        /// <param name="outputName">the TypeName for Output</param>
        /// <param name="constantsName">the TypeName for Constants</param>
        /// <param name="visitedMethods">the already visited methods</param>
        private void RecursiveRename(MethodDeclaration methodDeclaration, TypeName inputName, TypeName input2Name, TypeName outputName, TypeName constantsName, Stack<MethodDeclaration> visitedMethods)
        {
            if (methodDeclaration == null || visitedMethods.Contains(methodDeclaration))
                return;

            RenameInputOutput(methodDeclaration, inputName, input2Name, outputName, constantsName);
            visitedMethods.Push(methodDeclaration);

            List<MethodDeclaration> calls;
            if (TryGetMethodCalls(methodDeclaration, out calls))
            {
                foreach (var calledmethod in calls)
                    RecursiveRename(calledmethod, inputName, input2Name, outputName, constantsName, visitedMethods);
            }
        }
예제 #14
0
        /// <summary>
        /// Finds the usage of the streams
        /// </summary>
        /// <param name="currentMethod">the current method</param>
        /// <param name="inStreamList">list of in-streams</param>
        /// <param name="outStreamList">list of out-streams</param>
        /// <param name="visitedMethods">list of already visited methods</param>
        private void FindStreamsUsage(MethodDeclaration currentMethod, List<IDeclaration> inStreamList, List<IDeclaration> outStreamList, List<MethodDeclaration> visitedMethods)
        {
            if (visitedMethods.Contains(currentMethod))
            {
                errorWarningLog.Error(ParadoxMessageCode.ErrorRecursiveCall, currentMethod.Span, currentMethod);
                return;
            }

            if (currentMethod != null)
            {
                var newListVisitedMethods = new List<MethodDeclaration>();
                newListVisitedMethods.AddRange(visitedMethods);
                newListVisitedMethods.Add(currentMethod);

                List<StreamUsageInfo> streamUsageList;
                if (streamsUsages.TryGetValue(currentMethod, out streamUsageList))
                {
                    // look for stream usage inside the function
                    foreach (var streamUsage in streamUsageList)
                    {
                        if (streamUsage.CallType == StreamCallType.Member)
                        {
                            var isOutStream = outStreamList.Contains(streamUsage.Variable);
                            var isInStream = inStreamList.Contains(streamUsage.Variable);

                            if (streamUsage.Usage.IsWrite() && !isOutStream)
                            {
                                outStreamList.Add(streamUsage.Variable);
                                if (streamUsage.Usage.IsPartial() && !isInStream) // force variable to be passed from previous stages when affectation is only partial.
                                    inStreamList.Add(streamUsage.Variable);
                            }
                            else if (streamUsage.Usage.IsRead() && !isOutStream && !isInStream) // first read
                                inStreamList.Add(streamUsage.Variable);
                        }
                        else if (streamUsage.CallType == StreamCallType.Method)
                        {
                            if (streamUsage.MethodDeclaration != null) // way to check the built-in functions (could be improved?)
                                FindStreamsUsage(streamUsage.MethodDeclaration, inStreamList, outStreamList, newListVisitedMethods);
                        }
                        else if (streamUsage.CallType != StreamCallType.Direct) // should not happen
                            errorWarningLog.Error(ParadoxMessageCode.ErrorStreamUsageInitialization, streamUsage.Expression.Span, streamUsage.Expression);
                    }
                }
            }
        }
예제 #15
0
        /// <summary>
        /// Get the streams usage for this entrypoint
        /// </summary>
        /// <param name="moduleMixin">the current module mixin</param>
        /// <param name="entryPoint">the entrypoint method</param>
        /// <returns>a StreamStageUsage containing the streams usages</returns>
        private StreamStageUsage StreamAnalysisPerShader(ModuleMixin moduleMixin, MethodDeclaration entryPoint, PdxShaderStage shaderStage)
        {
            var visitedMethods = new List<MethodDeclaration>();
            var streamStageUsage = new StreamStageUsage { ShaderStage = shaderStage };
            FindStreamsUsage(entryPoint, streamStageUsage.InStreamList, streamStageUsage.OutStreamList, visitedMethods);
            visitedMethods.Clear();

            return streamStageUsage;
        }
예제 #16
0
 /// <summary>
 /// Insert a method reference
 /// </summary>
 /// <param name="methodDeclaration">the method</param>
 /// <param name="expression">the reference</param>
 public void InsertMethod(MethodDeclaration methodDeclaration, MethodInvocationExpression expression)
 {
     if (!MethodsReferences.ContainsKey(methodDeclaration))
         MethodsReferences.Add(methodDeclaration, new HashSet<MethodInvocationExpression>());
     MethodsReferences[methodDeclaration].Add(expression);
 }
예제 #17
0
 /// <summary>
 /// Get the overloaded method from one of its base declaration
 /// </summary>
 /// <param name="methodDeclaration">the MethodDeclaration</param>
 /// <returns>the overloaded MethodDeclaration</returns>
 public MethodDeclaration GetMethodFromDeclaration(MethodDeclaration methodDeclaration)
 {
     var info = (VTableReference)methodDeclaration.GetTag(ParadoxTags.VirtualTableReference);
     return VirtualTable.GetMethod(info.Shader, info.Slot);
 }
예제 #18
0
        /// <summary>
        /// Test if a method declaration has the same signature.
        /// </summary>
        /// <param name="methodDeclaration">The method declaration.</param>
        /// <returns>True if the method passed has the same signature</returns>
        public bool IsSameSignature(MethodDeclaration methodDeclaration)
        {
            if (methodDeclaration == null)
                return false;

            if (Name != methodDeclaration.Name)
                return false;
            if (Parameters.Count != methodDeclaration.Parameters.Count)
                return false;
            for (int i = 0; i < Parameters.Count; i++)
            {
                var parameter = Parameters[i];
                var parameterAgainst = methodDeclaration.Parameters[i];
                var parameterType = parameter.Type.ResolveType();
                var parameterAgainstType = parameterAgainst.Type.ResolveType();
                if (parameterType != parameterAgainstType)
                {
                    return false;
                }
            }
            return true;
        }
예제 #19
0
        protected static void InitializeBuiltins()
        {
            foreach (var function in Function.Functions)
            {
                foreach (var p in EnumerateParameters(function.Parameters[0]))
                {
                    var returnType = function.Return(function, new[] { p });
                    var parameterTypes = function.ParamList(function, new[] { p });

                    var methodDeclaration = new MethodDeclaration();
                    methodDeclaration.IsBuiltin = true;
                    methodDeclaration.Name = new Identifier(function.Name);
                    methodDeclaration.ReturnType = returnType;

                    foreach (var parameterType in parameterTypes)
                        methodDeclaration.Parameters.Add( new Ast.Parameter { DeclaringMethod = methodDeclaration, Type = parameterType } );

                    defaultDeclarations.Add(methodDeclaration);
                }
            }

            defaultDeclarations.AddRange(declaredMethods);

            foreach (var methodDeclaration in declaredMethods)
            {
                var newMethodDeclaration = new MethodDeclaration();
                newMethodDeclaration.IsBuiltin = true;
                newMethodDeclaration.Name = new Identifier(methodDeclaration.Name);
                newMethodDeclaration.ReturnType = methodDeclaration.ReturnType;

                foreach (var parameter in methodDeclaration.Parameters)
                {
                    var parameterType = parameter.Type;
                    if (parameterType is SamplerType)
                    {
                        parameterType = SamplerType.Sampler;
                    }

                    newMethodDeclaration.Parameters.Add(new Ast.Parameter { DeclaringMethod = newMethodDeclaration, Type = parameterType });
                }
                defaultDeclarations.Add(newMethodDeclaration);
            }

            // adding remaining functions that doesn't have multiple versions
            defaultDeclarations.Add(GenericMethod("AllMemoryBarrier", TypeBase.Void));
            defaultDeclarations.Add(GenericMethod("AllMemoryBarrierWithGroupSync", TypeBase.Void));
            defaultDeclarations.Add(GenericMethod("D3DCOLORtoUBYTE4", VectorType.Int4, GenericParam("x", VectorType.Float4)));
            defaultDeclarations.Add(GenericMethod("DeviceMemoryBarrier", TypeBase.Void));
            defaultDeclarations.Add(GenericMethod("DeviceMemoryBarrierWithGroupSync", TypeBase.Void));
            defaultDeclarations.Add(GenericMethod("GetRenderTargetSampleCount", ScalarType.UInt));
            defaultDeclarations.Add(GenericMethod("GetRenderTargetSamplePosition", ScalarType.UInt, GenericParam("x", ScalarType.Int)));
            defaultDeclarations.Add(GenericMethod("GroupMemoryBarrier", TypeBase.Void));
        }
예제 #20
0
 /// <inheritdoc />
 public override void Visit(MethodDeclaration methodDeclaration)
 {
     WriteLinkLine(methodDeclaration);
     WriteMethodDeclaration(methodDeclaration).WriteLine(";");
 }
예제 #21
0
 private static MethodDeclaration GenericMethod(string methodName, TypeBase returnType, List<GenericParameterConstraint> constraints, params Ast.Parameter[] parameters)
 {
     var methodDeclaration = new MethodDeclaration() { Name = new Identifier(methodName), ReturnType = returnType };
     methodDeclaration.IsBuiltin = true;
     if (constraints != null)
         methodDeclaration.ParameterConstraints = constraints;
     methodDeclaration.Parameters.AddRange(parameters);
     return methodDeclaration;
 }
예제 #22
0
파일: ShaderWriter.cs 프로젝트: cg123/xenko
        /// <summary>
        /// Writes the specified method declaration.
        /// </summary>
        /// <param name="methodDeclaration">
        /// The method declaration.
        /// </param>
        /// <returns>
        /// This instance
        /// </returns>
        protected virtual ShaderWriter WriteMethodDeclaration(MethodDeclaration methodDeclaration)
        {
            isVisitingVariableInlines = true;

            // Pre Attributes
            Write(methodDeclaration.Attributes, true);

            // Pre Qualifiers
            Write(methodDeclaration.Qualifiers, true);

            VisitDynamic(methodDeclaration.ReturnType);

            Write(" ");
            Write(methodDeclaration.Name);

            Write("(");

            for (int i = 0; i < methodDeclaration.Parameters.Count; i++)
            {
                var parameter = methodDeclaration.Parameters[i];
                if (i > 0) Write(",").WriteSpace();

                VisitDynamic(parameter);
            }

            Write(")");

            // Post Qualifiers
            Write(methodDeclaration.Qualifiers, false);

            // Post Attributes
            Write(methodDeclaration.Attributes, false);

            isVisitingVariableInlines = false;
            return this;
        }
예제 #23
0
 public MethodDeclarationShaderCouple(MethodDeclaration method, ShaderClassType shader)
 {
     Method = method;
     Shader = shader;
 }
예제 #24
0
 /// <summary>
 /// Initializes a new instance of the <see cref="MethodDefinition"/> class.
 /// </summary>
 /// <param name="returntype">The returntype.</param>
 /// <param name="name">The name.</param>
 public MethodDefinition(TypeBase returntype, string name) : this()
 {
     ReturnType = returntype;
     Name = new Identifier(name);
     declaration = this;
 }
예제 #25
0
 /// <summary>
 /// Finds the location of the method in the virtual table of its definition mixin
 /// </summary>
 /// <param name="methodDeclaration"></param>
 /// <returns></returns>
 public VTableReference GetBaseDeclaration(MethodDeclaration methodDeclaration)
 {
     var baseMethodDeclMixin = methodDeclaration.GetTag(XenkoTags.BaseDeclarationMixin) as string;
     var slot = -1;
     var vt = VirtualTableGroup[baseMethodDeclMixin];
     for (int i = 0; i < vt.Length; ++i)
     {
         if (methodDeclaration.IsSameSignature(vt[i]))
         {
             slot = i;
             break;
         }
     }
     return new VTableReference { Shader = baseMethodDeclMixin, Slot = slot };
 }
        /// <summary>
        /// Checks that the method does not have mixin as parameter or return type
        /// </summary>
        /// <param name="methodDeclaration">the method.</param>
        private void CheckParamatersAndReturnType(MethodDeclaration methodDeclaration)
        {
            foreach (var parameter in methodDeclaration.Parameters)
            {
                if (parameter.Type.TypeInference.Declaration is ShaderClassType)
                    Error(XenkoMessageCode.ErrorShaderClassTypeParameter, methodDeclaration.Span, methodDeclaration, parameter, analyzedModuleMixin.MixinName);
            }

            if (methodDeclaration.ReturnType.TypeInference.Declaration is ShaderClassType)
                Error(XenkoMessageCode.ErrorShaderClassReturnType, methodDeclaration.Span, methodDeclaration, analyzedModuleMixin.MixinName);
        }
예제 #27
0
        /// <summary>
        /// Find the base definition of the method and override its occurence
        /// </summary>
        /// <param name="methodDeclaration"></param>
        /// <param name="errorLogger"></param>
        private void LookForBaseDeclarationMixin(MethodDeclaration methodDeclaration, LoggerResult errorLogger)
        {
            foreach (var dict in VirtualTableGroup.Select(x => x.Value))
            {
                for (int i = 0; i < dict.Length; ++i)
                {
                    var method = dict[i];
                    var baseDeclarationMixin = (string)method.GetTag(XenkoTags.BaseDeclarationMixin);

                    // TODO: take typedefs into account...
                    if (method.IsSameSignature(methodDeclaration))
                    {
                        var sourceShader = ((ModuleMixin)methodDeclaration.GetTag(XenkoTags.ShaderScope)).MixinName;

                        // test override
                        if (methodDeclaration is MethodDefinition && method is MethodDefinition && !methodDeclaration.Qualifiers.Contains(XenkoStorageQualifier.Override))
                            errorLogger.Error(XenkoMessageCode.ErrorMissingOverride, method.Span, methodDeclaration, sourceShader);
                        if (!(methodDeclaration is MethodDefinition))
                            errorLogger.Error(XenkoMessageCode.ErrorOverrindingDeclaration, method.Span, methodDeclaration, sourceShader);

                        if (method.Qualifiers.Contains(XenkoStorageQualifier.Stage) && !methodDeclaration.Qualifiers.Contains(XenkoStorageQualifier.Stage))
                        {
                            errorLogger.Warning(XenkoMessageCode.WarningMissingStageKeyword, methodDeclaration.Span, methodDeclaration, (methodDeclaration.GetTag(XenkoTags.ShaderScope) as ModuleMixin).MixinName);
                            methodDeclaration.Qualifiers |= XenkoStorageQualifier.Stage;
                        }
                        else if (!method.Qualifiers.Contains(XenkoStorageQualifier.Stage) && methodDeclaration.Qualifiers.Contains(XenkoStorageQualifier.Stage))
                        {
                            errorLogger.Error(XenkoMessageCode.ErrorExtraStageKeyword, methodDeclaration.Span, methodDeclaration, method, (methodDeclaration.GetTag(XenkoTags.ShaderScope) as ModuleMixin).MixinName);
                            methodDeclaration.Qualifiers.Values.Remove(XenkoStorageQualifier.Stage);
                        }

                        dict[i] = methodDeclaration;
                        methodDeclaration.SetTag(XenkoTags.BaseDeclarationMixin, baseDeclarationMixin);
                    }
                }
            }
        }
 /// <summary>
 /// Performs operations applicable for MethodDefinition & MethodDeclaration nodes
 /// </summary>
 /// <param name="methodDeclaration">the method declaration or definition</param>
 private void PostMethodDeclarationVisit(MethodDeclaration methodDeclaration)
 {
     currentVisitedMethod = null;
     StoreMethod(methodDeclaration);
     CheckParamatersAndReturnType(methodDeclaration);
 }
예제 #29
0
 /// <summary>
 /// Initializes a new instance of the <see cref="MethodDefinition"/> class.
 /// </summary>
 public MethodDefinition()
 {
     Body        = new StatementList();
     declaration = this;
 }