コード例 #1
0
        public override void Visit(VariableReferenceExpression variableReferenceExpression)
        {
            base.Visit(variableReferenceExpression);

            if (sourceManager.IsClassExists(variableReferenceExpression.Name.Text))
                FoundClasses.Add(variableReferenceExpression.Name.Text);
        }
コード例 #2
0
        private void Visit(VariableReferenceExpression variableReferenceExpression)
        {
            Visit((Node)variableReferenceExpression);

            if (sourceManager.IsClassExists(variableReferenceExpression.Name.Text))
                FoundClasses.Add(variableReferenceExpression.Name.Text);
        }
コード例 #3
0
 public XenkoReplaceAppend(HashSet<MethodInvocationExpression> appendList, List<Statement> output, VariableReferenceExpression vre)
     : base(false, false)
 {
     appendMethodsList = appendList;
     outputStatements = output;
     outputVre = vre;
 }
コード例 #4
0
        public override Node Visit(VariableReferenceExpression expression)
        {
            base.Visit(expression);
            if (expression.Name.Text == VariableToReplace.Name.Text)
                return IndexerReplacement;

            return expression;
        }
コード例 #5
0
        protected Node Visit(VariableReferenceExpression expression)
        {
            Visit((Node)expression);
            if (expression.Name.Text == VariableToReplace.Name.Text)
                return IndexerReplacement;

            return expression;
        }
コード例 #6
0
ファイル: GlobalUniformVisitor.cs プロジェクト: cg123/xenko
        protected void Visit(VariableReferenceExpression variableRef)
        {
            var variable = GetUniform(variableRef);

            // If the variable is a global uniform, non static/const and is not already in the list used then
            if (variable != null && !uniformReadList.Contains(variable))
            {
                uniformReadList.Add(variable);
            }
        }
コード例 #7
0
        public override Node Visit(VariableReferenceExpression variableRef)
        {
            var variable = GetUniform(variableRef);

            // If the variable is a global uniform, non static/const and is not already in the list used then
            if (variable != null && !uniformReadList.Contains(variable))
            {
                uniformReadList.Add(variable);
            }
            return variableRef;
        }
コード例 #8
0
 /// <summary>
 /// Replace a MemberReferenceExpression by a VariableReferenceExpression in the AST
 /// </summary>
 /// <param name="memberReferenceExpression">the member reference expression.</param>
 /// <param name="variableReferenceExpression">the variable reference expression.</param>
 /// <param name="parentNode">the parent node.</param>
 private static void ReplaceMemberReferenceExpressionByVariableReferenceExpression(MemberReferenceExpression memberReferenceExpression, VariableReferenceExpression variableReferenceExpression, Node parentNode)
 {
     var replacor = new XenkoReplaceVisitor(memberReferenceExpression, variableReferenceExpression);
     replacor.Run(parentNode);
 }
コード例 #9
0
        /// <summary>
        /// Creates a ForStatement with the same behavior
        /// </summary>
        /// <param name="forEachStatement">the ForEachStatement</param>
        /// <returns>the ForStatement</returns>
        private static ForStatement ExpandForEachStatement(ForEachStatement forEachStatement)
        {
            if (forEachStatement != null)
            {
                var collec = forEachStatement.Collection.TypeInference.Declaration as Variable;
                LiteralExpression dimLit = null;
                if (collec.Type is ArrayType)
                {
                    if ((collec.Type as ArrayType).Dimensions.Count == 1)
                    {
                        dimLit = (collec.Type as ArrayType).Dimensions[0] as LiteralExpression;
                    }
                }

                if (dimLit != null)
                {
                    var initializer = new Variable(ScalarType.Int, forEachStatement.Variable.Name.Text + "Iter", new LiteralExpression(0));
                    var vre = new VariableReferenceExpression(initializer.Name);
                    var condition = new BinaryExpression(BinaryOperator.Less, vre, dimLit);
                    var next = new UnaryExpression(UnaryOperator.PreIncrement, vre);
                    ForStatement forStatement = new ForStatement(new DeclarationStatement(initializer), condition, next);
                    var body = new BlockStatement();

                    var variable = forEachStatement.Variable;
                    variable.InitialValue = new IndexerExpression(forEachStatement.Collection, new VariableReferenceExpression(initializer));
                    body.Statements.Add(new DeclarationStatement(variable));

                    if (forEachStatement.Body is BlockStatement)
                        body.Statements.AddRange((forEachStatement.Body as BlockStatement).Statements);
                    else
                        body.Statements.Add(forEachStatement.Body);

                    forStatement.Body = body;

                    return forStatement;
                }

                // TODO: multidimension-array?
                // TODO: unroll?
                // TODO: multiple foreach?
            }
            return null;
        }
コード例 #10
0
        /// <summary>
        /// Rename the methods and their references
        /// </summary>
        /// <param name="references">the pool to rename</param>
        /// <param name="id">the id used to build the new name</param>
        private void RenameAllMethods(ReferencesPool references, HashSet<MethodDefinition> renameFreeMethods, ref int id)
        {
            foreach (var method in references.MethodsReferences)
            {
                if (renameFreeMethods.Contains(method.Key) || !(method.Key is MethodDefinition))
                    continue;

                foreach (var methodRef in method.Value)
                {
                    var targetMre = methodRef.Target as MemberReferenceExpression;
                    if (targetMre != null)
                    {
                        var vre = new VariableReferenceExpression();
                        methodRef.Target = vre;
                        vre.TypeInference.Declaration = targetMre.TypeInference.Declaration;
                        vre.TypeInference.TargetType = targetMre.TypeInference.TargetType;
                    }

                    var targetVre = methodRef.Target as VariableReferenceExpression;
                    targetVre.Name = method.Key.Name;
                }
                
                method.Key.Name.Text += "_id" + id;
                ++id;
            }
            references.RegenKeys();
        }
コード例 #11
0
        /// <summary>
        /// Rename all the variables and their references based on the id
        /// </summary>
        /// <param name="references">the pool to rename</param>
        /// <param name="id">the id used to build the new name</param>
        private void RenameAllVariables(ReferencesPool references, ref int id)
        {
            foreach (var variable in references.VariablesReferences)
            {
                if (variable.Key.Name.Text == FlipRendertargetVariableName) // DO NOT RENAME THIS SPECIFIC VARIABLE
                    continue;

                foreach (var varRef in variable.Value)
                {
                    if (varRef.Expression is MemberReferenceExpression)
                    {
                        if (variable.Key.Qualifiers.Contains(XenkoStorageQualifier.Stream)) // TODO: change test
                        {
                            (varRef.Expression as MemberReferenceExpression).Member = variable.Key.Name;

                            var type = (varRef.Expression as MemberReferenceExpression).Target.TypeInference.TargetType as StreamsType;
                            if (type == null || !type.IsInputOutput)
                                (varRef.Expression as MemberReferenceExpression).Target = new VariableReferenceExpression(StreamsType.ThisStreams);
                        }
                        else if (variable.Key.Qualifiers.Contains(XenkoStorageQualifier.PatchStream))
                        {
                            (varRef.Expression as MemberReferenceExpression).Member = variable.Key.Name;
                        }
                        else
                        {
                            var vre = new VariableReferenceExpression(variable.Key.Name);
                            vre.TypeInference.Declaration = variable.Key;
                            vre.TypeInference.TargetType = variable.Key.Type.ResolveType();
                            ReplaceMemberReferenceExpressionByVariableReferenceExpression(varRef.Expression as MemberReferenceExpression, vre, varRef.Node);
                            varRef.Expression = vre;
                        }
                    }
                    else
                        (varRef.Expression as VariableReferenceExpression).Name = variable.Key.Name;
                }

                variable.Key.Name.Text += "_id" + id;
                ++id;
            }
        }
コード例 #12
0
        /// <summary>
        /// Checks if a function needs to have a stream strucutre added in its declaration
        /// </summary>
        /// <param name="methodDefinition">the method definition</param>
        /// <param name="inputStream">The stage input structure stream.</param>
        /// <param name="intermediateStream">the stream structure</param>
        /// <param name="outputStream">The stage output stream structure.</param>
        /// <param name="visitedMethods">the list of already visited methods</param>
        /// <param name="methodsWithStreams">The list of methods that have a streams argument.</param>
        /// <returns>true if needed, false otherwise</returns>
        private bool PropagateStreamsParameter(MethodDefinition methodDefinition, StructType inputStream, StructType intermediateStream, StructType outputStream, HashSet<MethodDeclaration> visitedMethods, List<MethodDeclaration> methodsWithStreams)
        {
            var needStream = false;

            if (methodDefinition != null)
            {
                if (visitedMethods.Contains(methodDefinition))
                    return methodDefinition.Parameters.Count > 0 && methodDefinition.Parameters[0].Type == intermediateStream;

                List<StreamUsageInfo> streamUsageInfos;
                if (streamsUsages.TryGetValue(methodDefinition, out streamUsageInfos))
                {
                    needStream = streamUsageInfos.Any(x => x.CallType == StreamCallType.Member || x.CallType == StreamCallType.Direct);
                    visitedMethods.Add(methodDefinition);

                    List<MethodDeclaration> calls;
                    if (TryGetMethodCalls(methodDefinition, out calls))
                        needStream = calls.Aggregate(needStream, (res, calledmethod) => res | PropagateStreamsParameter(calledmethod as MethodDefinition, inputStream, intermediateStream, outputStream, visitedMethods, methodsWithStreams));

                    if (needStream && !entryPointMethods.Contains(methodDefinition))
                    {
                        var param = new Parameter(new TypeName(intermediateStream.Name), "streams");

                        foreach (var methodRef in mainModuleMixin.ClassReferences.MethodsReferences[methodDefinition])
                        {
                            var vre = new VariableReferenceExpression(param.Name) { TypeInference = { Declaration = param, TargetType = param.Type } };
                            methodRef.Arguments.Insert(0, vre);
                        }

                        param.Qualifiers |= ParameterQualifier.InOut;
                        methodDefinition.Parameters.Insert(0, param);

                        // If any parameters in the method are streams, then replace by using the intermediate stream
                        foreach (var parameter in methodDefinition.Parameters)
                        {
                            if (parameter.Type == StreamsType.Streams)
                            {
                                parameter.Type = new TypeName(intermediateStream.Name);
                            }
                        }

                        methodsWithStreams.Add(methodDefinition);
                    }
                }

                TransformStreamsAssignments(methodDefinition, inputStream, intermediateStream, outputStream);
            }
            return needStream;
        }
コード例 #13
0
 protected void Visit(VariableReferenceExpression variableRef)
 {
     ((ScopeDeclarationWithRef)ScopeStack.Peek()).VariableReferences.Add(variableRef);
 }
コード例 #14
0
 private static VariableReferenceExpression Clone(VariableReferenceExpression expression)
 {
     var vre = new VariableReferenceExpression(expression.Name);
     if (expression.TypeInference.TargetType is StreamsType)
         vre.TypeInference.TargetType = expression.TypeInference.TargetType;
     return vre;
 }
コード例 #15
0
        /// <summary>
        /// Checks that the name does not bear many meanings
        /// </summary>
        /// <param name="variableReferenceExpression">the variable reference expression to check to check</param>
        private void CheckNameConflict(VariableReferenceExpression variableReferenceExpression)
        {
            var name = variableReferenceExpression.Name.Text;
            // NOTE: a VariableReferenceExpression means that we are in the context of the currently analyzed mixin
            // we need to check that a variable does not appear twice
            var varCount = analyzedModuleMixin.VirtualTable.Variables.Count(x => x.Variable.Name.Text == name);

            if (varCount > 1)
                Error(XenkoMessageCode.ErrorVariableNameAmbiguity, variableReferenceExpression.Span, variableReferenceExpression, analyzedModuleMixin.MixinName);
        }
コード例 #16
0
ファイル: StripVisitor.cs プロジェクト: h78hy78yhoi8j/xenko
 public void Visit(VariableReferenceExpression variableReferenceExpression)
 {
     Visit((Node)variableReferenceExpression);
     AddReference(GetDeclarationContainer(), (Node)variableReferenceExpression.TypeInference.Declaration);
 }
コード例 #17
0
 public override void Visit(VariableReferenceExpression variableReferenceExpression)
 {
     base.Visit(variableReferenceExpression);
     AddReference(GetDeclarationContainer(), (Node)variableReferenceExpression.TypeInference.Declaration);
 }
コード例 #18
0
        private void ExtractGenericParameters(Expression expression, out Expression mixinName, List<Expression> genericParametersOut)
        {
            if (genericParametersOut == null)
            {
                throw new ArgumentNullException("genericParametersOut");
            }

            mixinName = expression;
            genericParametersOut.Clear();

            var varExp = expression as VariableReferenceExpression;
            if (varExp != null)
            {
                Identifier identifier = varExp.Name;
                var identifierGeneric = identifier as IdentifierGeneric;
                if (identifierGeneric != null)
                {
                    mixinName = new VariableReferenceExpression(identifierGeneric.Text);

                    foreach (Identifier subIdentifier in identifierGeneric.Identifiers)
                    {
                        var identifierDot = subIdentifier as IdentifierDot;
                        if (identifierDot != null)
                        {
                            if (identifierDot.Identifiers.Count == 2)
                            {
                                genericParametersOut.Add(new MemberReferenceExpression(new VariableReferenceExpression(identifierDot.Identifiers[0]), identifierDot.Identifiers[1]));
                            }
                            else
                            {
                                logging.Error("Unsupported identifier in generic used for mixin", identifierDot.Span);
                            }
                        }
                        else if (subIdentifier is LiteralIdentifier)
                        {
                            var literalIdentifier = (LiteralIdentifier)subIdentifier;

                            genericParametersOut.Add(new LiteralExpression(literalIdentifier.Value));
                        }
                        else if (subIdentifier.GetType() == typeof(Identifier))
                        {
                            genericParametersOut.Add(new VariableReferenceExpression(subIdentifier));
                        }
                        else
                        {
                            logging.Error("Unsupported identifier in generic used for mixin", subIdentifier.Span);
                        }
                    }
                }
            }
        }
コード例 #19
0
        /// <inheritdoc/>
        public override void Visit(VariableReferenceExpression variableReferenceExpression)
        {
            base.Visit(variableReferenceExpression);

            var variableDeclaration = variableReferenceExpression.TypeInference.Declaration as Variable;
            if (variableDeclaration == null)
            {
                result.Error("Unable to find variable [{0}]", variableReferenceExpression.Span, variableReferenceExpression);
            }
            else if (variableDeclaration.InitialValue == null || !variableDeclaration.Qualifiers.Contains(StorageQualifier.Const))
            {
                result.Error("Variable [{0}] used in expression is not constant", variableReferenceExpression.Span, variableDeclaration);
            }
            else
            {
                var evaluator = new ExpressionEvaluator();
                var subResult = evaluator.Evaluate(variableDeclaration.InitialValue);
                subResult.CopyTo(result);

                if (subResult.HasErrors)
                {
                    values.Push(0.0);
                }
                else
                {
                    values.Push(subResult.Value);
                }
            }
        }
コード例 #20
0
ファイル: SemanticAnalysis.cs プロジェクト: cg123/xenko
        protected virtual void Visit(VariableReferenceExpression variableReferenceExpression)
        {
            Visit((Node)variableReferenceExpression);

            var typeReference = variableReferenceExpression.TypeInference;
            typeReference.Declaration = FindDeclaration(variableReferenceExpression.Name);
            typeReference.TargetType = ResolveTypeFromDeclaration(typeReference.Declaration);
        }
コード例 #21
0
        /// <summary>
        /// Rename all the variables and their references based on the id
        /// </summary>
        /// <param name="references">the pool to rename</param>
        /// <param name="id">the id used to build the new name</param>
        private void RenameAllVariables(ReferencesPool references, ref int id)
        {
            foreach (var variable in references.VariablesReferences)
            {
                foreach (var varRef in variable.Value)
                {
                    var memberReferenceExpression = varRef.Expression as MemberReferenceExpression;
                    if (memberReferenceExpression != null)
                    {
                        if (variable.Key.Qualifiers.Contains(XenkoStorageQualifier.Stream)) // TODO: change test
                        {
                            memberReferenceExpression.Member = variable.Key.Name;

                            var type = memberReferenceExpression.Target.TypeInference.TargetType;
                            if (type == null || !type.IsStreamsType() || !type.IsStreamsMutable())
                                memberReferenceExpression.Target = new VariableReferenceExpression(StreamsType.ThisStreams);
                        }
                        else if (variable.Key.Qualifiers.Contains(XenkoStorageQualifier.PatchStream))
                        {
                            memberReferenceExpression.Member = variable.Key.Name;
                        }
                        else
                        {
                            var vre = new VariableReferenceExpression(variable.Key.Name);
                            vre.TypeInference.Declaration = variable.Key;
                            vre.TypeInference.TargetType = variable.Key.Type.ResolveType();
                            ReplaceMemberReferenceExpressionByVariableReferenceExpression(memberReferenceExpression, vre, varRef.Node);
                            varRef.Expression = vre;
                        }
                    }
                    else
                        ((VariableReferenceExpression)varRef.Expression).Name = variable.Key.Name;
                }

                variable.Key.Name.Text += "_id" + id;
                ++id;
            }
        }
コード例 #22
0
 public override Node Visit(VariableReferenceExpression variableRef)
 {
     ((ScopeDeclarationWithRef)ScopeStack.Peek()).VariableReferences.Add(variableRef);
     return variableRef;
 }
コード例 #23
0
        /// <summary>
        /// Visits the specified variable reference expression.
        /// </summary>
        /// <param name="variableReferenceExpression">The variable reference expression.</param>
        public override Node Visit(VariableReferenceExpression variableReferenceExpression)
        {
            base.Visit(variableReferenceExpression);

            var typeReference = variableReferenceExpression.TypeInference;
            typeReference.Declaration = FindDeclaration(variableReferenceExpression.Name);
            typeReference.TargetType = ResolveTypeFromDeclaration(typeReference.Declaration);
            return variableReferenceExpression;
        }
コード例 #24
0
 /// <summary>
 /// Analyse the VariableReferenceExpression, detects streams, propagate type inference, get stored in the correct list for later analysis
 /// </summary>
 /// <param name="variableReferenceExpression">the VariableReferenceExpression</param>
 public override void Visit(VariableReferenceExpression variableReferenceExpression)
 {
     base.Visit(variableReferenceExpression);
     // HACK: force types on base, this and stream keyword to eliminate errors in the log an use the standard type inference
     if (variableReferenceExpression.Name == StreamsType.ThisStreams.Name)
     {
         if (!(ParentNode is MemberReferenceExpression)) // streams is alone
             currentStreamUsageList.Add(new StreamUsageInfo { CallType = StreamCallType.Direct, Variable = StreamsType.ThisStreams, Expression = variableReferenceExpression, Usage = currentStreamUsage });
     }
 }
コード例 #25
0
        protected override void  ProcessMethodInvocation(MethodInvocationExpression invoke, MethodDefinition method)
        {
            var textureParameters = new List<Parameter>();
            var parameterValues = new List<Expression>();
            var parameterGlobalValues = new List<Variable>();

            var samplerTypes = new List<int>();

            for (int i = 0; i < method.Parameters.Count; i++)
            {
                var parameter = method.Parameters[i];
                if (parameter.Type is TextureType || parameter.Type is StateType)
                {
                    textureParameters.Add(parameter);

                    // Find global variable
                    var parameterValue = this.FindGlobalVariable(invoke.Arguments[i]);

                    // Set the tag ScopeValue for the current parameter
                    parameter.SetTag(ScopeValueKey, parameterValue);

                    // Add only new variable
                    if (!parameterGlobalValues.Contains(parameterValue))
                        parameterGlobalValues.Add(parameterValue);
                }
                else if ( i < invoke.Arguments.Count)
                {
                    parameterValues.Add(invoke.Arguments[i]);
                    if (parameter.Type is SamplerType)
                    {
                        samplerTypes.Add(i);
                    }
                }
            }

            // We have texture/sampler parameters. We need to generate a new specialized method
            if (textureParameters.Count > 0)
            {
                // Order parameter values by name
                parameterGlobalValues.Sort((left, right) => left.Name.Text.CompareTo(right.Name.Text));

                var methodKey = new TextureSamplerMethodKey(method);

                int indexOf = textureSamplerMethods.IndexOf(methodKey);

                if (indexOf < 0)
                {
                    methodKey.Initialize(cloneContext);
                    textureSamplerMethods.Add(methodKey);
                }
                else
                {
                    // If a key is found again, add it as it was reused in order to keep usage in order
                    methodKey = textureSamplerMethods[indexOf];
                    textureSamplerMethods.RemoveAt(indexOf);
                    textureSamplerMethods.Add(methodKey);
                }

                methodKey.Invokers.Add(invoke);

                var newTarget = new VariableReferenceExpression(methodKey.NewMethod.Name) { TypeInference = { Declaration = methodKey.NewMethod, TargetType = invoke.TypeInference.TargetType } };
                invoke.Target = newTarget;
                invoke.Arguments = parameterValues;
                invoke.TypeInference.Declaration = methodKey.NewMethod;
                invoke.TypeInference.TargetType = invoke.TypeInference.TargetType;

                this.VisitDynamic(methodKey.NewMethod);
            }
            else
            {
                // Visit the method callstack
                this.VisitDynamic(method);

                // There is an anonymous sampler type
                // We need to resolve its types after the method definition was processed
                if (samplerTypes.Count > 0)
                {
                    foreach (var samplerTypeIndex in samplerTypes)
                    {
                        var samplerRef = invoke.Arguments[samplerTypeIndex] as VariableReferenceExpression;
                        if (samplerRef != null)
                        {
                            var samplerDecl = samplerRef.TypeInference.Declaration as Variable;
                            ChangeVariableType(samplerDecl, method.Parameters[samplerTypeIndex].Type);
                        }
                    }
                }
            }

            // Remove temporary parameters
            if (textureParameters.Count > 0)
            {
                foreach (var textureParameter in textureParameters)
                {
                    textureParameter.RemoveTag(ScopeValueKey);
                }
            }
        }
コード例 #26
0
 public override Node Visit(VariableReferenceExpression variableReferenceExpression)
 {
     var expression = (Expression)base.Visit(variableReferenceExpression);
     return ProcessExpression(expression);
 }
コード例 #27
0
        /// <summary>
        /// Analyse the MethodInvocationExpression, link to the base calls, remove "this" from virtual calls, store in the correct list for later analysis
        /// </summary>
        /// <param name="expression">the method expression</param>
        /// <param name="methodName">the method name</param>
        /// <param name="declarations">the special declarations</param>
        protected override void ProcessMethodInvocation(MethodInvocationExpression expression, string methodName, List<IDeclaration> declarations)
        {
            bool callBaseProcessMethodInvocation = true;
            bool isNotBaseCall = true;

            // check if it is a base/this invocation
            var memberReferenceExpression = expression.Target as MemberReferenceExpression;
            if (memberReferenceExpression != null)
            {
                var variableReferenceExpression = memberReferenceExpression.Target as VariableReferenceExpression;
                if (variableReferenceExpression != null)
                {
                    switch (variableReferenceExpression.Name.Text)
                    {
                        case "base":
                            {
                                parsingInfo.BaseMethodCalls.Add(expression);
                                isNotBaseCall = false;
                                callBaseProcessMethodInvocation = false;

                                // get a base method declaration
                                MethodDeclaration baseMethod = null;
                                foreach (var mixin in analyzedModuleMixin.InheritanceList)
                                {
                                    baseMethod = mixin.LocalVirtualTable.Methods.Select(x => x.Method).FirstOrDefault(x => x.IsSameSignature(expression));
                                    if (baseMethod != null)
                                        break;
                                }
                                if (baseMethod == null)
                                    baseMethod = analyzedModuleMixin.LocalVirtualTable.Methods.Select(x => x.Method).FirstOrDefault(x => x.IsSameSignature(expression));
                                
                                if (baseMethod != null)
                                {
                                    expression.TypeInference.TargetType = baseMethod.ReturnType.ResolveType();
                                    expression.Target.TypeInference.Declaration = baseMethod;
                                }
                                else
                                    Error(XenkoMessageCode.ErrorImpossibleBaseCall, memberReferenceExpression.Span, expression, analyzedModuleMixin.MixinName);
                                break;
                            }
                        case "this":
                            {
                                // remove "this" keyword
                                var vre = new VariableReferenceExpression(memberReferenceExpression.Member);
                                expression.Target = vre;
                                
                                callBaseProcessMethodInvocation = false;
                                
                                // get top method declaration
                                var topMethod = analyzedModuleMixin.VirtualTable.Methods.Select(x => x.Method).FirstOrDefault(x => x.IsSameSignature(expression));
                                if (topMethod != null)
                                {
                                    expression.TypeInference.TargetType = topMethod.ReturnType.ResolveType();
                                    expression.Target.TypeInference.Declaration = topMethod;
                                }
                                else
                                    Error(XenkoMessageCode.ErrorImpossibleVirtualCall, memberReferenceExpression.Span, expression, analyzedModuleMixin.MixinName, analyzedModuleMixin.MixinName);

                                memberReferenceExpression = null;

                                break;
                            }
                    }
                    
                }

                if (expression.Target is MemberReferenceExpression)
                {
                    var typeCall = (expression.Target as MemberReferenceExpression).Target.TypeInference.TargetType;
                    if (typeCall is ShaderClassType)
                        declarations.AddRange(FindDeclarationsFromObject(typeCall, memberReferenceExpression.Member));
                }
            }

            // call base
            if (callBaseProcessMethodInvocation)
                base.ProcessMethodInvocation(expression, methodName, declarations);

            var methodDecl = expression.Target.TypeInference.Declaration as MethodDeclaration;
            var isBuiltIn = true;

            if (methodDecl != null)
            {
                // check if it is a recursive call
                if (ReferenceEquals(currentVisitedMethod, expression.Target.TypeInference.Declaration)) // How to handle "this" keyword?
                    Error(XenkoMessageCode.ErrorCyclicMethod, currentVisitedMethod.Span, currentVisitedMethod, analyzedModuleMixin.MixinName);

                // check if it is a build-in method
                isBuiltIn = !methodDecl.ContainsTag(XenkoTags.ShaderScope);

                if (memberReferenceExpression != null)
                {
                    var varDecl = memberReferenceExpression.Target.TypeInference.Declaration as Variable;
                    if (memberReferenceExpression.Target is IndexerExpression)
                        varDecl = (memberReferenceExpression.Target as IndexerExpression).Target.TypeInference.Declaration as Variable;

                    if (varDecl != null && varDecl.Qualifiers.Contains(StorageQualifier.Extern))
                    {
                        if (IsStageInitMember(memberReferenceExpression))
                            expression.SetTag(XenkoTags.StageInitRef, null);
                        else
                            expression.SetTag(XenkoTags.ExternRef, null);
                    }

                    var shaderDecl = memberReferenceExpression.Target.TypeInference.Declaration as ShaderClassType;
                    if (shaderDecl != null && shaderDecl != analyzedModuleMixin.Shader && analyzedModuleMixin.InheritanceList.All(x => x.Shader != shaderDecl))
                        expression.SetTag(XenkoTags.StaticRef, null);
                }

                if (!isBuiltIn)
                {
                    // store if not a base call
                    if (isNotBaseCall && !expression.ContainsTag(XenkoTags.ExternRef) && !expression.ContainsTag(XenkoTags.StageInitRef) && !expression.ContainsTag(XenkoTags.StaticRef))
                        parsingInfo.ThisMethodCalls.Add(expression);

                    if (methodDecl.Qualifiers.Contains(XenkoStorageQualifier.Stage))
                        parsingInfo.StageMethodCalls.Add(expression);
                }
            }
        }
コード例 #28
0
        /// <summary>
        /// Generates a stream structure and add them to the Ast - for the geometry shader
        /// </summary>
        /// <param name="entryPoint">the entrypoint function</param>
        /// <param name="streamStageUsage">the stream usage in this stage</param>
        /// <param name="stageName">the name of the stage</param>
        /// <param name="prevOuputStructure">the output structutre from the previous stage</param>
        /// <returns>the new output structure</returns>
        private StructType GenerateStreamsWithSpecialDataInput(MethodDefinition entryPoint, StreamStageUsage streamStageUsage, string stageName, StructType prevOuputStructure)
        {
            if (entryPoint != null)
            {
                var inStreamStruct = prevOuputStructure ?? CreateStreamStructure(streamStageUsage.InStreamList, stageName + "_INPUT");
                var outStreamStruct = CreateStreamStructure(streamStageUsage.OutStreamList, stageName + "_OUTPUT");

                var mixin = entryPoint.GetTag(ParadoxTags.ShaderScope) as ModuleMixin;

                var intermediateStreamStruct = CreateIntermediateStructType(streamStageUsage, stageName);

                // put the streams declaration at the beginning of the method body
                var streamsDeclaration = new DeclarationStatement(new Variable(new TypeName(intermediateStreamStruct.Name), "streams") { InitialValue = new CastExpression { From = new LiteralExpression(0), Target = new TypeName(intermediateStreamStruct.Name) } });
                entryPoint.Body.Insert(0, streamsDeclaration);

                // add the declaration statements to the entrypoint and fill with the values
                var outputStatements = CreateOutputFromStream(outStreamStruct, "output", intermediateStreamStruct, "streams").ToList();
                var outputVre = new VariableReferenceExpression(((outputStatements.First() as DeclarationStatement).Content as Variable).Name);

                var replacor = new ParadoxReplaceAppend(streamAnalyzer.AppendMethodCalls, outputStatements, outputVre);
                ReplaceAppendMethod(entryPoint, replacor);
                
                var visitedMethods = new Stack<MethodDeclaration>();
                var inStructType = new TypeName(inStreamStruct.Name);
                var outStructType = new TypeName(outStreamStruct.Name);
                RecursiveRename(entryPoint, inStructType, null, outStructType, null, visitedMethods);

                // explore all the called functions
                var streamsVisitedMethods = new HashSet<MethodDeclaration>();
                var methodsWithStreams = new List<MethodDeclaration>();
                PropagateStreamsParameter(entryPoint, inStreamStruct, intermediateStreamStruct, outStreamStruct, streamsVisitedMethods, methodsWithStreams);

                CheckCrossStageMethodCall(streamStageUsage.ShaderStage, methodsWithStreams);

                if (prevOuputStructure == null)
                    shader.Members.Insert(0, inStreamStruct);
                shader.Members.Insert(0, outStreamStruct);
                shader.Members.Insert(0, intermediateStreamStruct);

                return outStreamStruct;
            }

            return prevOuputStructure;
        }
コード例 #29
0
        /// <summary>
        /// Analyse the VariableReferenceExpression, detects streams, propagate type inference, get stored in the correct list for later analysis
        /// </summary>
        /// <param name="variableReferenceExpression">the VariableReferenceExpression</param>
        public override Node Visit(VariableReferenceExpression variableReferenceExpression)
        {
            // HACK: force types on base, this and stream keyword to eliminate errors in the log and use the standard type inference
            var name = variableReferenceExpression.Name.Text;
            if (name == "base")
            {
                variableReferenceExpression.TypeInference.Declaration = analyzedModuleMixin.Shader;
                variableReferenceExpression.TypeInference.TargetType = analyzedModuleMixin.Shader;
                return variableReferenceExpression;
            }
            if (name == "this")
            {
                variableReferenceExpression.TypeInference.Declaration = analyzedModuleMixin.Shader;
                variableReferenceExpression.TypeInference.TargetType = analyzedModuleMixin.Shader;
                return variableReferenceExpression;
            }
            if (name == "stage")
            {
                if (!(ParentNode is Variable && (ParentNode as Variable).InitialValue == variableReferenceExpression))
                    Error(XenkoMessageCode.ErrorStageOutsideVariable, ParentNode.Span, ParentNode, analyzedModuleMixin.MixinName);

                return variableReferenceExpression;
            }
            if (name == StreamsType.ThisStreams.Name.Text)
            {
                variableReferenceExpression.TypeInference.Declaration = StreamsType.ThisStreams;
                variableReferenceExpression.TypeInference.TargetType = StreamsType.ThisStreams.Type;
            }
            
            // check if the variable is double-defined
            if (!XenkoKeywords.Contains(variableReferenceExpression.Name.Text))
                CheckNameConflict(variableReferenceExpression);

            base.Visit(variableReferenceExpression);

            var varDecl = variableReferenceExpression.TypeInference.Declaration as Variable;

            if (varDecl != null)
            {
                // because the parent classes do not do this all the time
                if (variableReferenceExpression.TypeInference.TargetType == null)
                    variableReferenceExpression.TypeInference.TargetType = (variableReferenceExpression.TypeInference.Declaration as Variable).Type.ResolveType();

                if (varDecl.ContainsTag(XenkoTags.ShaderScope))
                {
                    // stream variable should be called within the streams scope
                    if (varDecl.Qualifiers.Contains(XenkoStorageQualifier.Stream) || varDecl.Qualifiers.Contains(XenkoStorageQualifier.PatchStream))
                        Error(XenkoMessageCode.ErrorMissingStreamsStruct, variableReferenceExpression.Span, variableReferenceExpression, analyzedModuleMixin.MixinName);
                }
            }

            var isMethodName = defaultDeclarations.Any(x => x.Name.Text == variableReferenceExpression.Name.Text);

            if (!XenkoKeywords.Contains(variableReferenceExpression.Name.Text) && variableReferenceExpression.TypeInference.Declaration == null && !inSampler && !isMethodName)
                Error(XenkoMessageCode.ErrorMissingVariable, variableReferenceExpression.Span, variableReferenceExpression, analyzedModuleMixin.MixinName);

            // update function static status
            if (!inSampler && !isMethodName && variableReferenceExpression.TypeInference.Declaration == null)
                Error(XenkoMessageCode.ErrorNoTypeInference, variableReferenceExpression.Span, variableReferenceExpression, analyzedModuleMixin.MixinName);

            if (currentVisitedMethod != null && currentVisitedMethod.Qualifiers.Contains(StorageQualifier.Static) && varDecl != null && varDecl.GetTag(XenkoTags.BaseDeclarationMixin) != null)
                Error(XenkoMessageCode.ErrorNonStaticReferenceInStaticMethod, variableReferenceExpression.Span, currentVisitedMethod, varDecl, analyzedModuleMixin.MixinName);

            // Add to the variables references list
            AddToVariablesReference(variableReferenceExpression);

            return variableReferenceExpression;
        }
コード例 #30
0
 private void Visit(VariableReferenceExpression variableReferenceExpression)
 {
     Visit((Node)variableReferenceExpression);
     CheckUsage(variableReferenceExpression.TypeInference.Declaration as Variable);
 }