public override void AddSourceMappingFor(IntermediateNode node)
        {
            if (node == null)
            {
                throw new ArgumentNullException(nameof(node));
            }

            if (node.Source == null)
            {
                return;
            }

            if (SourceDocument.FilePath != null &&
                !string.Equals(SourceDocument.FilePath, node.Source.Value.FilePath, StringComparison.OrdinalIgnoreCase))
            {
                // We don't want to generate line mappings for imports.
                return;
            }

            var source            = node.Source.Value;
            var generatedLocation = new SourceSpan(CodeWriter.Location, source.Length);
            var sourceMapping     = new SourceMapping(source, generatedLocation);

            SourceMappings.Add(sourceMapping);
        }
        public void WriteUsingDirective_WithSource_WritesContentWithLinePragmaAndMapping()
        {
            // Arrange
            var writer         = new DesignTimeNodeWriter();
            var sourceDocument = TestRazorSourceDocument.Create("@using System;");
            var context        = TestCodeRenderingContext.CreateDesignTime();

            var originalSpan          = new SourceSpan("test.cshtml", 0, 0, 0, 6);
            var generatedSpan         = new SourceSpan(null, 21 + Environment.NewLine.Length, 1, 0, 6);
            var expectedSourceMapping = new SourceMapping(originalSpan, generatedSpan);
            var node = new UsingDirectiveIntermediateNode()
            {
                Content = "System",
                Source  = originalSpan,
            };

            // Act
            writer.WriteUsingDirective(context, node);

            // Assert
            var mapping = Assert.Single(((DefaultCodeRenderingContext)context).SourceMappings);

            Assert.Equal(expectedSourceMapping, mapping);
            var csharp = context.CodeWriter.GenerateCode();

            Assert.Equal(
                @"#line 1 ""test.cshtml""
using System;

#line default
#line hidden
",
                csharp,
                ignoreLineEndingDifferences: true);
        }
Esempio n. 3
0
        public void SourceMapCache_HandlesDuplicateNames()
        {
            var cache = new SourceMapCache(new SourceMap()
            {
                version    = 3,
                file       = "foo.js",
                sources    = new string[] { "source.js" },
                names      = new string[] { "name1", "name1", "name3" },
                mappings   = ";EAACA;;IAEEA;;MAEEE",
                sourceRoot = "http://example.com"
            });

            {
                var expected = new SourceMapping(1, 1, 2, 2, "source.js", "name1");
                var actual   = cache.SourceMappingFor(2, 2);
                Assert.AreEqual(expected, actual);
            }

            {
                var expected = new SourceMapping(3, 3, 4, 4, "source.js", "name1");
                var actual   = cache.SourceMappingFor(4, 4);
                Assert.AreEqual(expected, actual);
            }

            {
                var expected = new SourceMapping(5, 5, 6, 6, "source.js", "name3");
                var actual   = cache.SourceMappingFor(6, 6);
                Assert.AreEqual(expected, actual);
            }
        }
Esempio n. 4
0
 private void AssertNotEqual(SourceMapping left, SourceMapping right)
 {
     Assert.False(left == right);
     Assert.False(left.Equals(right));
     Assert.False(right.Equals(left));
     Assert.False(Equals(left, right));
 }
            static Range ConvertMapping(RazorSourceDocument sourceDocument, SourceMapping mapping)
            {
                var startLocation  = sourceDocument.Lines.GetLocation(mapping.OriginalSpan.AbsoluteIndex);
                var endLocation    = sourceDocument.Lines.GetLocation(mapping.OriginalSpan.AbsoluteIndex + mapping.OriginalSpan.Length);
                var convertedRange = new Range(
                    new Position(startLocation.LineIndex, startLocation.CharacterIndex),
                    new Position(endLocation.LineIndex, endLocation.CharacterIndex));

                return(convertedRange);
            }
Esempio n. 6
0
    public void GeneratedCodeMappingsAreNotEqualIfAbsoluteIndexIsNotEqual()
    {
        // Arrange
        var left = new SourceMapping(
            new SourceSpan(new SourceLocation(1, 2, 3), 4),
            new SourceSpan(new SourceLocation(4, 6, 7), 8));

        var right = new SourceMapping(
            new SourceSpan(new SourceLocation(1, 2, 3), 4),
            new SourceSpan(new SourceLocation(5, 6, 7), 9));

        // Assert
        AssertNotEqual(left, right);
    }
Esempio n. 7
0
    public void GeneratedCodeMappingsAreNotEqualIfStartLineIsNotEqual()
    {
        // Arrange
        var left = new SourceMapping(
            new SourceSpan(new SourceLocation(1, 2, 3), 4),
            new SourceSpan(new SourceLocation(5, 5, 7), 8));

        var right = new SourceMapping(
            new SourceSpan(new SourceLocation(1, 1, 3), 4),
            new SourceSpan(new SourceLocation(5, 6, 7), 8));

        // Assert
        AssertNotEqual(left, right);
    }
Esempio n. 8
0
    public void GeneratedCodeMappingsAreEqualIfDataIsEqual()
    {
        // Arrange
        var left = new SourceMapping(
            new SourceSpan(new SourceLocation(1, 2, 3), 4),
            new SourceSpan(new SourceLocation(5, 6, 7), 8));

        var right = new SourceMapping(
            new SourceSpan(new SourceLocation(1, 2, 3), 4),
            new SourceSpan(new SourceLocation(5, 6, 7), 8));

        // Assert
        Assert.True(left.Equals(right));
        Assert.True(right.Equals(left));
        Assert.True(Equals(left, right));
    }
        private void FindPendingReferenceIncludes(NavigationTreeNode node, SourceMapping sourceMapping)
        {
            if (node.Navigation != null && node.Navigation.IsCollection())
            {
                return;
            }

            if (node.Included == NavigationTreeNodeIncludeMode.ReferencePending && node.ExpansionMode != NavigationTreeNodeExpansionMode.ReferenceComplete)
            {
                PendingIncludes[node] = sourceMapping;
            }

            foreach (var child in node.Children)
            {
                FindPendingReferenceIncludes(child, sourceMapping);
            }
        }
Esempio n. 10
0
        public void SourceMapCache_ParsesSimpleSourceMap()
        {
            var cache = new SourceMapCache(new SourceMap()
            {
                version    = 3,
                file       = "foo.js",
                sourceRoot = "http://example.com/",
                sources    = new string[] { "/a" },
                names      = new string[] { },
                mappings   = "AACA"
            });

            var expected = new SourceMapping(2, 0, 1, 0, "/a", "");
            var actual   = cache.SourceMappingFor(1, 0);

            Assert.AreEqual(expected, actual);
        }
        public static Expression CreateCollectionNavigationExpression(
            NavigationTreeNode navigationTreeNode, ParameterExpression rootParameter, SourceMapping sourceMapping)
        {
            var collectionEntityType = navigationTreeNode.Navigation.ForeignKey.DeclaringEntityType;
            var entityQueryable      = (Expression)NullAsyncQueryProvider.Instance.CreateEntityQueryableExpression(collectionEntityType.ClrType);

            var outerBinding = new NavigationBindingExpression(
                rootParameter,
                navigationTreeNode.Parent,
                navigationTreeNode.Navigation.DeclaringEntityType,
                sourceMapping,
                navigationTreeNode.Navigation.DeclaringEntityType.ClrType);

            var outerKeyAccess = NavigationExpansionHelpers.CreateKeyAccessExpression(
                outerBinding,
                navigationTreeNode.Navigation.ForeignKey.PrincipalKey.Properties,
                addNullCheck: outerBinding.NavigationTreeNode.Optional);

            var collectionCurrentParameter = Expression.Parameter(collectionEntityType.ClrType, collectionEntityType.ClrType.GenerateParameterName());

            var innerKeyAccess = NavigationExpansionHelpers.CreateKeyAccessExpression(
                collectionCurrentParameter,
                navigationTreeNode.Navigation.ForeignKey.Properties);

            var predicate = Expression.Lambda(
                CreateKeyComparisonExpressionForCollectionNavigationSubquery(
                    outerKeyAccess,
                    innerKeyAccess,
                    outerBinding),
                collectionCurrentParameter);

            var operand = Expression.Call(
                LinqMethodHelpers.QueryableWhereMethodInfo.MakeGenericMethod(collectionEntityType.ClrType),
                entityQueryable,
                predicate);

            var result = NavigationExpansionHelpers.CreateNavigationExpansionRoot(operand, collectionEntityType, navigationTreeNode.Navigation);

            // this is needed for cases like: root.Include(r => r.Collection).ThenInclude(c => c.Reference).Select(r => r.Collection)
            // result should be elements of the collection navigation with their 'Reference' included
            var newSourceMapping = result.State.SourceMappings.Single();

            IncludeHelpers.CopyIncludeInformation(navigationTreeNode, newSourceMapping.NavigationTree, newSourceMapping);

            return(result);
        }
Esempio n. 12
0
        private IncludeExpression CreateIncludeReferenceCall(Expression caller, NavigationTreeNode node, ParameterExpression rootParameter, SourceMapping sourceMapping)
        {
            var entityType = node.Navigation.GetTargetType();
            var included   = (Expression) new NavigationBindingExpression(rootParameter, node, entityType, sourceMapping, entityType.ClrType);

            foreach (var child in node.Children.Where(n => n.Included == NavigationTreeNodeIncludeMode.ReferencePending || n.Included == NavigationTreeNodeIncludeMode.Collection))
            {
                included = CreateIncludeCall(included, child, rootParameter, sourceMapping);
            }

            return(new IncludeExpression(caller, included, node.Navigation));
        }
Esempio n. 13
0
 private IncludeExpression CreateIncludeCall(Expression caller, NavigationTreeNode node, ParameterExpression rootParameter, SourceMapping sourceMapping)
 => node.Navigation.IsCollection()
     ? CreateIncludeCollectionCall(caller, node, rootParameter, sourceMapping)
     : CreateIncludeReferenceCall(caller, node, rootParameter, sourceMapping);
Esempio n. 14
0
        private IncludeExpression CreateIncludeCollectionCall(Expression caller, NavigationTreeNode node, ParameterExpression rootParameter, SourceMapping sourceMapping)
        {
            var included = CollectionNavigationRewritingVisitor.CreateCollectionNavigationExpression(node, rootParameter, sourceMapping);

            return(new IncludeExpression(caller, included, node.Navigation));
        }