/// <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); } }