From e05f34fec166319893c4bda391359a12c2cf0e0f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Standa=20Luke=C5=A1?= Date: Thu, 25 Jan 2024 10:04:09 +0100 Subject: [PATCH] Allow internal-only namespaces in `@import` directive --- .../Compilation/CompiledAssemblyCache.cs | 5 ++- .../ImportDirectiveTests.cs | 45 +++++++++++++++++++ 2 files changed, 48 insertions(+), 2 deletions(-) diff --git a/src/Framework/Framework/Compilation/CompiledAssemblyCache.cs b/src/Framework/Framework/Compilation/CompiledAssemblyCache.cs index b8a990dce4..8aea8818ed 100644 --- a/src/Framework/Framework/Compilation/CompiledAssemblyCache.cs +++ b/src/Framework/Framework/Compilation/CompiledAssemblyCache.cs @@ -172,12 +172,13 @@ private HashSet GetAllNamespaces() foreach (var a in GetAllAssemblies()) { string? lastNs = null; // namespaces come in batches, usually, so no need to hash it everytime when a quick compare says it's the same as last time - foreach (var type in a.ExportedTypes) + foreach (var type in a.GetLoadableTypes()) { var ns = type.Namespace; if (ns is null || lastNs == ns) continue; - result.Add(ns); + result.Add(ns); + lastNs = ns; } } return result; diff --git a/src/Tests/Runtime/ControlTree/DefaultControlTreeResolver/ImportDirectiveTests.cs b/src/Tests/Runtime/ControlTree/DefaultControlTreeResolver/ImportDirectiveTests.cs index acd28c81bf..d53853e6ac 100644 --- a/src/Tests/Runtime/ControlTree/DefaultControlTreeResolver/ImportDirectiveTests.cs +++ b/src/Tests/Runtime/ControlTree/DefaultControlTreeResolver/ImportDirectiveTests.cs @@ -5,6 +5,11 @@ using System; using System.Collections.Generic; +namespace DotVVM.Framework.Tests.Runtime.ControlTree.TestInternalOnlyNamespace +{ + class InternalClass { } +} + namespace DotVVM.Framework.Tests.Runtime.ControlTree { [TestClass] @@ -70,6 +75,46 @@ @viewModel object Assert.AreEqual(typeof(List).FullName, importDirective.Type.FullName); } + [TestMethod] + public void ResolvedTree_ImportDirective_NamespaceDoesNotExist() + { + var root = ParseSource(@" +@viewModel object +@import This.Namespace.Does.Not.Exist +"); + var importDirective = EnsureSingleResolvedImportDirective(root); + + Assert.IsTrue(importDirective.HasError); + Assert.AreEqual("This.Namespace.Does.Not.Exist is unknown type or namespace.", importDirective.DothtmlNode.NodeErrors.Single()); + } + [TestMethod] + public void ResolvedTree_ImportDirective_NamespaceDoesNotExist_Alias() + { + var root = ParseSource(@" +@viewModel object +@import testns = This.Namespace.Does.Not.Exist +"); + var importDirective = EnsureSingleResolvedImportDirective(root); + + Assert.IsTrue(importDirective.HasError); + Assert.AreEqual("This.Namespace.Does.Not.Exist is unknown type or namespace.", importDirective.DothtmlNode.NodeErrors.Single()); + } + + [TestMethod] + public void ResolvedTree_ImportDirective_InternalNamespace() + { + var root = ParseSource(@" +@viewModel object +@import DotVVM.Framework.Tests.Runtime.ControlTree.TestInternalOnlyNamespace +"); + var importDirective = EnsureSingleResolvedImportDirective(root); + + Assert.IsFalse(importDirective.HasError, message: importDirective.DothtmlNode.NodeErrors.SingleOrDefault()); + Assert.IsNull(importDirective.Type); + Assert.IsTrue(importDirective.IsNamespace); + } + + private static ResolvedImportDirective EnsureSingleResolvedImportDirective(ResolvedTreeRoot root) => root.Directives["import"] .Single()