Beispiel #1
0
        /// <summary>
        /// Get the base MethodDeclaration from its call and the mixin where the call is performed
        /// </summary>
        /// <param name="expression">the calling expression</param>
        /// <param name="mixin">the mixin where the call is performed</param>
        /// <returns>the base MethodDeclaration</returns>
        public MethodDeclaration GetBaseMethodFromExpression(Expression expression, ModuleMixin mixin)
        {
            var info       = (VTableReference)expression.GetTag(XenkoTags.VirtualTableReference);
            var thisMethod = VirtualTable.GetMethod(info.Shader, info.Slot);

            if (thisMethod == null)
            {
                return(null);
            }

            var startIndex = mixin == this ? InheritanceList.Count : InheritanceList.IndexOf(mixin);

            for (int i = startIndex - 1; i >= 0; --i)
            {
                var dep   = InheritanceList[i];
                var array = VirtualTable.VirtualTableGroup[dep.MixinName];
                for (int j = 0; j < array.Length; ++j)
                {
                    var method = array[j];
                    if (method == thisMethod)
                    {
                        return(dep.VirtualTable.VirtualTableGroup[dep.MixinName][j]);
                    }
                }
            }
            return(null);
        }
 /// <summary>
 /// Check if the class is stage
 /// </summary>
 /// <param name="mixin">the ModuleMixin to check</param>
 private void CheckStageClass(ModuleMixin mixin)
 {
     mixin.StageOnlyClass = mixin.VirtualTable.Variables.All(x => x.Variable.Qualifiers.Contains(XenkoStorageQualifier.Stage) &&
                                                             !x.Variable.Qualifiers.Contains(XenkoStorageQualifier.Compose)) &&   // composition variable can be stage but the classes behind may not be.
                            mixin.VirtualTable.Methods.All(x => x.Method.Qualifiers.Contains(XenkoStorageQualifier.Stage) &&
                                                           !x.Method.Qualifiers.Contains(XenkoStorageQualifier.Clone));
 }
        /// <summary>
        /// Check that the stage function calls are possible and that the stage declared variable have a correct type
        /// </summary>
        /// <param name="externMixin">the mixin to look into</param>
        /// <param name="contextMixin">the root mixin</param>
        private void CheckReferencesFromExternMixin(ModuleMixin externMixin, ModuleMixin contextMixin)
        {
            // test that the root mixin has the correct type
            foreach (var variable in externMixin.ParsingInfo.StageInitializedVariables)
            {
                if (variable.Type.Name.Text != contextMixin.MixinName && contextMixin.InheritanceList.All(x => x.MixinName == variable.Type.Name.Text)) // since it is the same AST, compare the object?
                {
                    ErrorWarningLog.Error(XenkoMessageCode.ErrorExternStageVariableNotFound, variable.Span, variable, externMixin.MixinName);
                }
            }

            foreach (var stageCall in externMixin.ParsingInfo.StageMethodCalls)
            {
                var decl = contextMixin.FindTopThisFunction(stageCall).FirstOrDefault();
                if (decl == null)
                {
                    ErrorWarningLog.Error(XenkoMessageCode.ErrorExternStageFunctionNotFound, stageCall.Span, stageCall, externMixin.MixinName, contextMixin.MixinName);
                }
            }

            // recursive calls
            foreach (var mixin in externMixin.InheritanceList)
            {
                CheckReferencesFromExternMixin(mixin, contextMixin);

                foreach (var externModule in mixin.VariableDependencies)
                {
                    CheckReferencesFromExternMixin(externModule.Value, contextMixin);
                }
            }

            foreach (var externModule in externMixin.VariableDependencies)
            {
                CheckReferencesFromExternMixin(externModule.Value, contextMixin);
            }
        }