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