/// <inheritdoc /> protected override void OnDocumentStructureCreated( RazorCodeDocument codeDocument, NamespaceDeclarationIntermediateNode @namespace, ClassDeclarationIntermediateNode @class, MethodDeclarationIntermediateNode method) { if (!codeDocument.TryComputeNamespace(fallbackToRootNamespace: true, out var computedNamespace) || !TryComputeClassName(codeDocument, out var computedClass)) { // If we can't compute a nice namespace (no relative path) then just generate something // mangled. computedNamespace = FallbackRootNamespace; var checksum = Checksum.BytesToString(codeDocument.Source.GetChecksum()); computedClass = $"AspNetCore_{checksum}"; } var documentNode = codeDocument.GetDocumentIntermediateNode(); if (char.IsLower(computedClass, 0)) { // We don't allow component names to start with a lowercase character. documentNode.Diagnostics.Add( ComponentDiagnosticFactory.Create_ComponentNamesCannotStartWithLowerCase(computedClass, documentNode.Source)); } if (MangleClassNames) { computedClass = ComponentMetadata.MangleClassName(computedClass); } @namespace.Content = computedNamespace; @class.ClassName = computedClass; @class.Modifiers.Clear(); @class.Modifiers.Add("public"); @class.Modifiers.Add("partial"); if (FileKinds.IsComponentImport(codeDocument.GetFileKind())) { // We don't want component imports to be considered as real component. // But we still want to generate code for it so we can get diagnostics. @class.BaseType = typeof(object).FullName; method.ReturnType = "void"; method.MethodName = "Execute"; method.Modifiers.Clear(); method.Modifiers.Add("protected"); method.Parameters.Clear(); } else { @class.BaseType = ComponentsApi.ComponentBase.FullTypeName; var typeParamReferences = documentNode.FindDirectiveReferences(ComponentTypeParamDirective.Directive); for (var i = 0; i < typeParamReferences.Count; i++) { var typeParamNode = (DirectiveIntermediateNode)typeParamReferences[i].Node; if (typeParamNode.HasDiagnostics) { continue; } @class.TypeParameters.Add(new TypeParameter() { ParameterName = typeParamNode.Tokens.First().Content, Constraints = typeParamNode.Tokens.Skip(1).FirstOrDefault()?.Content }); } method.ReturnType = "void"; method.MethodName = ComponentsApi.ComponentBase.BuildRenderTree; method.Modifiers.Clear(); method.Modifiers.Add("protected"); method.Modifiers.Add("override"); method.Parameters.Clear(); method.Parameters.Add(new MethodParameter() { ParameterName = ComponentsApi.RenderTreeBuilder.BuilderParameter, TypeName = ComponentsApi.RenderTreeBuilder.FullTypeName, }); } }