public void GetAttributeNameValuePairs_ParsesPairsCorrectly(
            string documentContent,
            IEnumerable<KeyValuePair<string, string>> expectedPairs)
        {
            // Arrange
            var errorSink = new ErrorSink();
            var parseResult = ParseDocument(documentContent, errorSink);
            var document = parseResult.Document;
            var rewriters = RazorParser.GetDefaultRewriters(new HtmlMarkupParser());
            var rewritingContext = new RewritingContext(document, errorSink);
            foreach (var rewriter in rewriters)
            {
                rewriter.Rewrite(rewritingContext);
            }
            var block = rewritingContext.SyntaxTree.Children.First();
            var parseTreeRewriter = new TagHelperParseTreeRewriter(provider: null);

            // Assert - Guard
            var tagBlock = Assert.IsType<Block>(block);
            Assert.Equal(BlockType.Tag, tagBlock.Type);
            Assert.Empty(errorSink.Errors);

            // Act
            var pairs = parseTreeRewriter.GetAttributeNameValuePairs(tagBlock);

            // Assert
            Assert.Equal(expectedPairs, pairs);
        }
示例#2
0
        /// <summary>
        /// Instantiates a new <see cref="ParserResults"/> instance.
        /// </summary>
        /// <param name="success"><c>true</c> if parsing was successful, <c>false</c> otherwise.</param>
        /// <param name="document">The <see cref="Block"/> for the syntax tree.</param>
        /// <param name="tagHelperDescriptors">
        /// The <see cref="TagHelperDescriptor"/>s that apply to the current Razor document.
        /// </param>
        /// <param name="errorSink">
        /// The <see cref="ErrorSink"/> used to collect <see cref="RazorError"/>s encountered when parsing the
        /// current Razor document.
        /// </param>
        protected ParserResults(bool success,
            Block document,
            IEnumerable<TagHelperDescriptor> tagHelperDescriptors,
            ErrorSink errorSink)
        {
            if (document == null)
            {
                throw new ArgumentNullException(nameof(document));
            }

            if (tagHelperDescriptors == null)
            {
                throw new ArgumentNullException(nameof(tagHelperDescriptors));
            }

            if (errorSink == null)
            {
                throw new ArgumentNullException(nameof(errorSink));
            }

            Success = success;
            Document = document;
            TagHelperDescriptors = tagHelperDescriptors;
            ErrorSink = errorSink;
            ParserErrors = errorSink.Errors;
            Prefix = tagHelperDescriptors.FirstOrDefault()?.Prefix;
        }
示例#3
0
        /// <summary>
        /// Instantiates a new <see cref="RewritingContext"/>.
        /// </summary>
        public RewritingContext(Block syntaxTree, ErrorSink errorSink)
        {
            _errors = new List<RazorError>();
            SyntaxTree = syntaxTree;

            ErrorSink = errorSink;
        }
        /// <summary>
        /// Creates a <see cref="TagHelperDescriptor"/> from the given <paramref name="typeInfo"/>.
        /// </summary>
        /// <param name="assemblyName">The assembly name that contains <paramref name="type"/>.</param>
        /// <param name="typeInfo">The <see cref="ITypeInfo"/> to create a <see cref="TagHelperDescriptor"/> from.
        /// </param>
        /// <param name="errorSink">The <see cref="ErrorSink"/> used to collect <see cref="RazorError"/>s encountered
        /// when creating <see cref="TagHelperDescriptor"/>s for the given <paramref name="typeInfo"/>.</param>
        /// <returns>
        /// A collection of <see cref="TagHelperDescriptor"/>s that describe the given <paramref name="typeInfo"/>.
        /// </returns>
        public virtual IEnumerable<TagHelperDescriptor> CreateDescriptors(
            string assemblyName,
            ITypeInfo typeInfo,
            ErrorSink errorSink)
        {
            if (typeInfo == null)
            {
                throw new ArgumentNullException(nameof(typeInfo));
            }

            if (errorSink == null)
            {
                throw new ArgumentNullException(nameof(errorSink));
            }

            if (ShouldSkipDescriptorCreation(typeInfo))
            {
                return Enumerable.Empty<TagHelperDescriptor>();
            }

            var attributeDescriptors = GetAttributeDescriptors(typeInfo, errorSink);
            var targetElementAttributes = GetValidHtmlTargetElementAttributes(typeInfo, errorSink);
            var allowedChildren = GetAllowedChildren(typeInfo, errorSink);

            var tagHelperDescriptors =
                BuildTagHelperDescriptors(
                    typeInfo,
                    assemblyName,
                    attributeDescriptors,
                    targetElementAttributes,
                    allowedChildren);

            return tagHelperDescriptors.Distinct(TagHelperDescriptorComparer.Default);
        }
        public void CreateDescriptors_WithPrefixes_ReturnsExpectedAttributeDescriptors(
            Type tagHelperType,
            IEnumerable<TagHelperAttributeDescriptor> expectedAttributeDescriptors,
            string[] expectedErrorMessages)
        {
            // Arrange
            var errorSink = new ErrorSink();
            var factory = new TagHelperDescriptorFactory(designTime: false);

            // Act
            var descriptors = factory.CreateDescriptors(
                AssemblyName,
                GetTypeInfo(tagHelperType),
                errorSink: errorSink);

            // Assert
            var errors = errorSink.Errors.ToArray();
            Assert.Equal(expectedErrorMessages.Length, errors.Length);

            for (var i = 0; i < errors.Length; i++)
            {
                Assert.Equal(0, errors[i].Length);
                Assert.Equal(SourceLocation.Zero, errors[i].Location);
                Assert.Equal(expectedErrorMessages[i], errors[i].Message, StringComparer.Ordinal);
            }

            var descriptor = Assert.Single(descriptors);
            Assert.Equal(
                expectedAttributeDescriptors,
                descriptor.Attributes,
                TagHelperAttributeDescriptorComparer.Default);
        }
        public void Resolve_CalculatesAssemblyLocationInLookupText(string lookupText, int assemblyLocation)
        {
            // Arrange
            var errorSink = new ErrorSink();
            var tagHelperDescriptorResolver = new InspectableTagHelperDescriptorResolver();
            var directiveType = TagHelperDirectiveType.AddTagHelper;
            var resolutionContext = new TagHelperDescriptorResolutionContext(
                new[]
                {
                    new TagHelperDirectiveDescriptor
                    {
                        DirectiveText = lookupText,
                        Location = SourceLocation.Zero,
                        DirectiveType = directiveType
                    }
                },
                errorSink);
            var expectedSourceLocation = new SourceLocation(assemblyLocation, 0, assemblyLocation);

            // Act
            tagHelperDescriptorResolver.Resolve(resolutionContext);

            // Assert
            Assert.Empty(errorSink.Errors);
            Assert.Equal(expectedSourceLocation, tagHelperDescriptorResolver.DocumentLocation);
        }
 public TagHelperDirectiveSpanVisitor(
     [NotNull] ITagHelperDescriptorResolver descriptorResolver,
     [NotNull] ErrorSink errorSink)
 {
     _descriptorResolver = descriptorResolver;
     _errorSink = errorSink;
 }
        private static IEnumerable<TargetElementAttribute> GetValidTargetElementAttributes(
            TypeInfo typeInfo,
            ErrorSink errorSink)
        {
            var targetElementAttributes = typeInfo.GetCustomAttributes<TargetElementAttribute>(inherit: false);

            return targetElementAttributes.Where(attribute => ValidTargetElementAttributeNames(attribute, errorSink));
        }
 public override ParserContext CreateParserContext(
     ITextDocument input,
     ParserBase codeParser,
     ParserBase markupParser,
     ErrorSink errorSink)
 {
     return base.CreateParserContext(input, codeParser, markupParser, errorSink);
 }
示例#10
0
        public CompilerContext(SourceUnit sourceUnit, CompilerOptions options, ErrorSink errorSink, ParserSink parserSink)
        {
            Contract.RequiresNotNull(sourceUnit, "sourceUnit");

            _sourceUnit = sourceUnit;
            _options = options ?? sourceUnit.Engine.GetDefaultCompilerOptions();
            _errors = errorSink ?? sourceUnit.Engine.GetCompilerErrorSink();
            _parserSink = parserSink ?? ParserSink.Null;
        }
示例#11
0
 public void ConstructorAcceptsActiveParserIfIsSameAsEitherCodeOrMarkupParser()
 {
     var codeParser = new CSharpCodeParser();
     var markupParser = new HtmlMarkupParser();
     var errorSink = new ErrorSink();
     new ParserContext(
         new SeekableTextReader(TextReader.Null), codeParser, markupParser, codeParser, errorSink);
     new ParserContext(
         new SeekableTextReader(TextReader.Null), codeParser, markupParser, markupParser, errorSink);
 }
示例#12
0
 public virtual ParserContext CreateParserContext(ITextDocument input,
                                                  ParserBase codeParser,
                                                  ParserBase markupParser,
                                                  ErrorSink errorSink)
 {
     return new ParserContext(input,
                              codeParser,
                              markupParser,
                              SelectActiveParser(codeParser, markupParser),
                              errorSink);
 }
示例#13
0
        public CompilerContext(SourceUnit sourceUnit, CompilerOptions options, ErrorSink errorSink, ParserSink parserSink) {
            ContractUtils.RequiresNotNull(sourceUnit, "sourceUnit");
            ContractUtils.RequiresNotNull(errorSink, "errorSink");
            ContractUtils.RequiresNotNull(parserSink, "parserSink");
            ContractUtils.RequiresNotNull(options, "options");

            _sourceUnit = sourceUnit;
            _options = options;
            _errors = errorSink;
            _parserSink = parserSink;
        }
示例#14
0
 // Internal for testing.
 internal CodeBuilderContext(RazorEngineHost host,
                             string className,
                             string rootNamespace,
                             string sourceFile,
                             bool shouldGenerateLinePragmas,
                             ErrorSink errorSink)
     : base(host, className, rootNamespace, sourceFile, shouldGenerateLinePragmas)
 {
     ErrorSink = errorSink;
     ExpressionRenderingMode = ExpressionRenderingMode.WriteToOutput;
 }
        public static TagHelperBlockBuilder Rewrite(
            string tagName,
            bool validStructure,
            Block tag,
            IEnumerable<TagHelperDescriptor> descriptors,
            ErrorSink errorSink)
        {
            // There will always be at least one child for the '<'.
            var start = tag.Children.First().Start;
            var attributes = GetTagAttributes(tagName, validStructure, tag, descriptors, errorSink);
            var tagMode = GetTagMode(tagName, tag, descriptors, errorSink);

            return new TagHelperBlockBuilder(tagName, tagMode, start, attributes, descriptors);
        }
        public void VisitCallsOnCompleteWhenAllNodesHaveBeenVisited()
        {
            // Arrange
            Mock<ParserVisitor> targetMock = new Mock<ParserVisitor>();
            var root = new BlockBuilder() { Type = BlockType.Comment }.Build();
            var errorSink = new ErrorSink();
            errorSink.OnError(new RazorError("Foo", new SourceLocation(1, 0, 1), length: 3));
            errorSink.OnError(new RazorError("Bar", new SourceLocation(2, 0, 2), length: 3));
            var results = new ParserResults(root, Enumerable.Empty<TagHelperDescriptor>(), errorSink);

            // Act
            targetMock.Object.Visit(results);

            // Assert
            targetMock.Verify(v => v.OnComplete());
        }
示例#17
0
		internal bool Merge(ErrorSink/*!*/ errors, FormalTypeParam/*!*/ other)
		{
			if (this.name != other.Name)
			{
				PhpType declaring_type = (PhpType)parameter.DeclaringMember;

				errors.Add(Errors.PartialDeclarationsDifferInTypeParameter, declaring_type.Declaration.SourceUnit,
					position, declaring_type.FullName);

				return false;
			}

			attributes.Merge(other.Attributes);

			return true;
		}
        public void VisitSendsDocumentToVisitor()
        {
            // Arrange
            Mock<ParserVisitor> targetMock = new Mock<ParserVisitor>();
            var root = new BlockBuilder() { Type = BlockType.Comment }.Build();
            var errorSink = new ErrorSink();
            var results = new ParserResults(root,
                                            Enumerable.Empty<TagHelperDescriptor>(),
                                            errorSink);

            // Act
            targetMock.Object.Visit(results);

            // Assert
            targetMock.Verify(v => v.VisitBlock(root));
        }
        // Allows MVC a chance to override the TagHelperDescriptorResolutionContext
        protected virtual TagHelperDescriptorResolutionContext GetTagHelperDescriptorResolutionContext(
            IEnumerable<TagHelperDirectiveDescriptor> descriptors,
            ErrorSink errorSink)
        {
            if (descriptors == null)
            {
                throw new ArgumentNullException(nameof(descriptors));
            }

            if (errorSink == null)
            {
                throw new ArgumentNullException(nameof(errorSink));
            }

            return new TagHelperDescriptorResolutionContext(descriptors, errorSink);
        }
        public void EvaluateData(
            TagHelperDescriptorProvider provider,
            string documentContent,
            MarkupBlock expectedOutput,
            IEnumerable<RazorError> expectedErrors)
        {
            var errorSink = new ErrorSink();
            var results = ParseDocument(documentContent, errorSink);
            var rewritingContext = new RewritingContext(results.Document, errorSink);
            new TagHelperParseTreeRewriter(provider).Rewrite(rewritingContext);
            var rewritten = rewritingContext.SyntaxTree;
            var actualErrors = errorSink.Errors.OrderBy(error => error.Location.AbsoluteIndex)
                                               .ToList();

            EvaluateRazorErrors(actualErrors, expectedErrors.ToList());
            EvaluateParseTree(rewritten, expectedOutput);
        }
        /// <summary>
        /// Instantiates a new instance of <see cref="TagHelperDescriptorResolutionContext"/>.
        /// </summary>
        /// <param name="directiveDescriptors"><see cref="TagHelperDirectiveDescriptor"/>s used to resolve
        /// <see cref="TagHelperDescriptor"/>s.</param>
        /// <param name="errorSink">Used to aggregate <see cref="RazorError"/>s.</param>
        public TagHelperDescriptorResolutionContext(
            IEnumerable<TagHelperDirectiveDescriptor> directiveDescriptors,
            ErrorSink errorSink)
        {
            if (directiveDescriptors == null)
            {
                throw new ArgumentNullException(nameof(directiveDescriptors));
            }

            if (errorSink == null)
            {
                throw new ArgumentNullException(nameof(errorSink));
            }

            DirectiveDescriptors = new List<TagHelperDirectiveDescriptor>(directiveDescriptors);
            ErrorSink = errorSink;
        }
        public void CreateDescriptors_WithPrefixes_ReturnsExpectedAttributeDescriptors(
            Type tagHelperType,
            IEnumerable<TagHelperAttributeDescriptor> expectedAttributeDescriptors,
            string[] expectedErrorMessages)
        {
            // Arrange
            var errorSink = new ErrorSink();

            // Act
            var descriptors = TagHelperDescriptorFactory.CreateDescriptors(
                AssemblyName,
                GetTypeInfo(tagHelperType),
                designTime: false,
                errorSink: errorSink);

            // Assert
            var errors = errorSink.Errors.ToArray();
            Assert.Equal(expectedErrorMessages.Length, errors.Length);

            for (var i = 0; i < errors.Length; i++)
            {
                Assert.Equal(0, errors[i].Length);
                Assert.Equal(SourceLocation.Zero, errors[i].Location);
                Assert.Equal(expectedErrorMessages[i], errors[i].Message, StringComparer.Ordinal);
            }

            var descriptor = Assert.Single(descriptors);
#if DNXCORE50
            // In CoreCLR type forwarding of System.Runtime types causes issues with comparing FullNames for generic types.
            // We'll work around this by sanitizing the type names so that the assembly qualification is removed.
            foreach (var attributeDescriptor in expectedAttributeDescriptors)
            {
                attributeDescriptor.TypeName = RuntimeTypeInfo.SanitizeFullName(attributeDescriptor.TypeName);
            }

            foreach (var attributeDescriptor in descriptor.Attributes)
            {
                attributeDescriptor.TypeName = RuntimeTypeInfo.SanitizeFullName(attributeDescriptor.TypeName);
            }
#endif

            Assert.Equal(
                expectedAttributeDescriptors,
                descriptor.Attributes,
                TagHelperAttributeDescriptorComparer.Default);
        }
        public TagHelperDirectiveSpanVisitor(
            ITagHelperDescriptorResolver descriptorResolver,
            ErrorSink errorSink)
        {
            if (descriptorResolver == null)
            {
                throw new ArgumentNullException(nameof(descriptorResolver));
            }

            if (errorSink == null)
            {
                throw new ArgumentNullException(nameof(errorSink));
            }

            _descriptorResolver = descriptorResolver;
            _errorSink = errorSink;
        }
示例#24
0
        public ParserContext(ITextDocument source,
                             ParserBase codeParser,
                             ParserBase markupParser,
                             ParserBase activeParser,
                             ErrorSink errorSink)
        {
            if (source == null)
            {
                throw new ArgumentNullException(nameof(source));
            }

            if (codeParser == null)
            {
                throw new ArgumentNullException(nameof(codeParser));
            }

            if (markupParser == null)
            {
                throw new ArgumentNullException(nameof(markupParser));
            }

            if (activeParser == null)
            {
                throw new ArgumentNullException(nameof(activeParser));
            }

            if (errorSink == null)
            {
                throw new ArgumentNullException(nameof(errorSink));
            }

            if (activeParser != codeParser && activeParser != markupParser)
            {
                throw new ArgumentException(RazorResources.ActiveParser_Must_Be_Code_Or_Markup_Parser, nameof(activeParser));
            }

            CaptureOwnerTask();

            Source = new TextDocumentReader(source);
            CodeParser = codeParser;
            MarkupParser = markupParser;
            ActiveParser = activeParser;
            _errorSink = errorSink;
        }
示例#25
0
        /// <inheritdoc />
        public IEnumerable<Type> Resolve(
            string name,
            SourceLocation documentLocation,
            ErrorSink errorSink)
        {
            if (errorSink == null)
            {
                throw new ArgumentNullException(nameof(errorSink));
            }

            if (string.IsNullOrEmpty(name))
            {
                var errorLength = name == null ? 1 : Math.Max(name.Length, 1);
                errorSink.OnError(
                    documentLocation,
                    Resources.TagHelperTypeResolver_TagHelperAssemblyNameCannotBeEmptyOrNull,
                    errorLength);

                return Type.EmptyTypes;
            }

            var assemblyName = new AssemblyName(name);

            IEnumerable<TypeInfo> libraryTypes;
            try
            {
                libraryTypes = GetExportedTypes(assemblyName);
            }
            catch (Exception ex)
            {
                errorSink.OnError(
                    documentLocation,
                    Resources.FormatTagHelperTypeResolver_CannotResolveTagHelperAssembly(
                        assemblyName.Name,
                        ex.Message),
                    name.Length);

                return Type.EmptyTypes;
            }

            return libraryTypes.Where(IsTagHelper).Select(t => t.AsType());
        }
示例#26
0
        /// <summary>
        /// Instantiates a new <see cref="ParserResults"/> instance.
        /// </summary>
        /// <param name="document">The <see cref="Block"/> for the syntax tree.</param>
        /// <param name="tagHelperDescriptors">
        /// The <see cref="TagHelperDescriptor"/>s that apply to the current Razor document.
        /// </param>
        /// <param name="errorSink">
        /// The <see cref="ErrorSink"/> used to collect <see cref="RazorError"/>s encountered when parsing the
        /// current Razor document.
        /// </param>
        public ParserResults(Block document,
            IEnumerable<TagHelperDescriptor> tagHelperDescriptors,
            ErrorSink errorSink)
            : this(!errorSink.Errors.Any(), document, tagHelperDescriptors, errorSink)
        {
            if (document == null)
            {
                throw new ArgumentNullException(nameof(document));
            }

            if (tagHelperDescriptors == null)
            {
                throw new ArgumentNullException(nameof(tagHelperDescriptors));
            }

            if (errorSink == null)
            {
                throw new ArgumentNullException(nameof(errorSink));
            }
        }
        public void CreateDescriptors_BuildsDescriptorsFromSimpleTypes()
        {
            // Arrange
            var errorSink = new ErrorSink();
            var objectAssemblyName = typeof(object).GetTypeInfo().Assembly.GetName().Name;
            var expectedDescriptor =
                CreateTagHelperDescriptor("object", "System.Object", objectAssemblyName);
            var factory = new TagHelperDescriptorFactory(designTime: false);

            // Act
            var descriptors = factory.CreateDescriptors(
                objectAssemblyName,
                GetTypeInfo(typeof(object)),
                errorSink: errorSink);

            // Assert
            Assert.Empty(errorSink.Errors);
            var descriptor = Assert.Single(descriptors);
            Assert.Equal(expectedDescriptor, descriptor, CaseSensitiveTagHelperDescriptorComparer.Default);
        }
示例#28
0
		internal static object[]/*!!*/ ToStaticTypeRefs(List<TypeRef>/*!*/ typeRefs, ErrorSink errors, SourceUnit sourceUnit)
		{
            if (typeRefs == null || typeRefs.Count == 0)
                return ArrayUtils.EmptyObjects;

			object[] result = new object[typeRefs.Count];

			for (int i = 0; i < typeRefs.Count; i++)
			{
                if ((result[i] = typeRefs[i].ToStaticTypeRef(errors, sourceUnit)) == null)
				{
					if (errors != null)
                        errors.Add(Errors.GenericParameterMustBeType, sourceUnit, typeRefs[i].Span);

					result[i] = new PrimitiveTypeName(QualifiedName.Object);
				}
			}

			return result;
		}
        public void RenderAttributeValue_RendersModelExpressionsCorrectly(
            string modelExpressionType,
            string propertyType,
            string expectedValue)
        {
            // Arrange
            var renderer = new MvcTagHelperAttributeValueCodeRenderer(
                new GeneratedTagHelperAttributeContext
                {
                    ModelExpressionTypeName = modelExpressionType,
                    CreateModelExpressionMethodName = "SomeMethod",
                    ModelExpressionProviderPropertyName = "Provider",
                    ViewDataPropertyName = "ViewData"
                });
            var attributeDescriptor = new TagHelperAttributeDescriptor
            {
                Name = "MyAttribute",
                PropertyName = "SomeProperty",
                TypeName = propertyType,
            };
            var writer = new CSharpCodeWriter();
            var generatorContext = new ChunkGeneratorContext(
                host: null,
                className: string.Empty,
                rootNamespace: string.Empty,
                sourceFile: string.Empty,
                shouldGenerateLinePragmas: true);
            var errorSink = new ErrorSink();
            var context = new CodeGeneratorContext(generatorContext, errorSink);

            // Act
            renderer.RenderAttributeValue(attributeDescriptor, writer, context,
            (codeWriter) =>
            {
                codeWriter.Write("MyValue");
            },
            complexValue: false);

            // Assert
            Assert.Equal(expectedValue, writer.GenerateCode());
        }
示例#30
0
        public void RemoteCompile(ref ErrorSink /*!*/ errorSink, CompilationParameters /*!*/ ps)
        {
            lock (buildMutex)             // TODO: do we need thread-safety (if yes, there is a better way)?
            {
                //if (++buildCounter % 10 == 0) // TODO: is it possible to estimate size of memory allocated by the domain?
                //{
                //  // if a referenced assembly gets updated then we should reload the domain as well
                //  AppDomain.Unload(remoteCompiler.Domain);
                //  remoteCompiler = null;
                //}

                if (remoteCompiler != null)
                {
                    AppDomain.Unload(remoteCompiler.Domain);
                }

                remoteCompiler = ApplicationCompiler.CreateRemoteCompiler();

                remoteCompiler.RemoteCompile(ref errorSink, ps);
            }
        }
        public void Resolve_ResolvesTagHelperDescriptors()
        {
            // Arrange
            var assemblyNameLookups = new Dictionary <string, IEnumerable <Type> >
            {
                { CustomTagHelperAssembly, new[] { typeof(CustomTagHelper) } }
            };
            var descriptorResolver = new TestAssemblyTagHelperDescriptorResolver(assemblyNameLookups);
            var errorSink          = new ErrorSink();

            // Act
            var descriptors = descriptorResolver.Resolve(CustomTagHelperAssembly, errorSink);

            // Assert
            Assert.NotNull(descriptors);
            var descriptor = Assert.Single(descriptors);

            Assert.Equal(CustomTagHelperAssembly, descriptor.AssemblyName, StringComparer.Ordinal);
            Assert.Equal(CustomTagHelperDescriptor, descriptor, CaseSensitiveTagHelperDescriptorComparer.Default);
            Assert.Empty(errorSink.Errors);
        }
示例#32
0
        /// <inheritdoc />
        protected override IEnumerable <TagHelperDescriptor> GetTagHelperDescriptors(
            Block documentRoot,
            ErrorSink errorSink)
        {
            if (documentRoot == null)
            {
                throw new ArgumentNullException(nameof(documentRoot));
            }

            if (errorSink == null)
            {
                throw new ArgumentNullException(nameof(errorSink));
            }

            var visitor = new ViewImportsTagHelperDirectiveSpanVisitor(
                TagHelperDescriptorResolver,
                _viewImportsDirectiveDescriptors,
                errorSink);

            return(visitor.GetDescriptors(documentRoot));
        }
        private void ValidateParentAllowsPlainTag(Block tagBlock, ErrorSink errorSink)
        {
            var tagName = GetTagName(tagBlock);

            // Treat partial tags such as '</' which have no tag names as content.
            if (string.IsNullOrEmpty(tagName))
            {
                Debug.Assert(tagBlock.Children.First() is Span);

                ValidateParentAllowsContent((Span)tagBlock.Children.First(), errorSink);
                return;
            }

            var currentTracker = _trackerStack.Count > 0 ? _trackerStack.Peek() : null;

            if (HasAllowedChildren() &&
                !_currentTagHelperTracker.AllowedChildren.Contains(tagName, StringComparer.OrdinalIgnoreCase))
            {
                OnAllowedChildrenTagError(_currentTagHelperTracker, tagName, tagBlock, errorSink);
            }
        }
示例#34
0
        protected virtual ParserResults RunParse(string document,
                                                 Func <ParserBase, Action> parserActionSelector,
                                                 bool designTimeParser,
                                                 Func <ParserContext, ParserBase> parserSelector = null,
                                                 ErrorSink errorSink = null)
        {
            parserSelector = parserSelector ?? (c => c.ActiveParser);
            errorSink      = errorSink ?? new ErrorSink();

            // Create the source
            ParserResults results = null;

            using (var reader = new SeekableTextReader(document))
            {
                try
                {
                    var codeParser   = CreateCodeParser();
                    var markupParser = CreateMarkupParser();
                    var context      = CreateParserContext(reader, codeParser, markupParser, errorSink);
                    context.DesignTimeMode = designTimeParser;

                    codeParser.Context   = context;
                    markupParser.Context = context;

                    // Run the parser
                    parserActionSelector(parserSelector(context))();
                    results = context.CompleteParse();
                }
                finally
                {
                    if (results != null && results.Document != null)
                    {
                        WriteTraceLine(string.Empty);
                        WriteTraceLine("Actual Parse Tree:");
                        WriteNode(0, results.Document);
                    }
                }
            }
            return(results);
        }
        private static bool ValidateName(
            string name,
            bool targetingAttributes,
            ErrorSink errorSink)
        {
            if (!targetingAttributes &&
                string.Equals(
                    name,
                    TagHelperDescriptorProvider.ElementCatchAllTarget,
                    StringComparison.OrdinalIgnoreCase))
            {
                // '*' as the entire name is OK in the HtmlTargetElement catch-all case.
                return(true);
            }
            else if (targetingAttributes &&
                     name.EndsWith(
                         TagHelperDescriptorProvider.RequiredAttributeWildcardSuffix,
                         StringComparison.OrdinalIgnoreCase))
            {
                // A single '*' at the end of a required attribute is valid; everywhere else is invalid. Strip it from
                // the end so we can validate the rest of the name.
                name = name.Substring(0, name.Length - 1);
            }

            var targetName = targetingAttributes ?
                             Resources.TagHelperDescriptorFactory_Attribute :
                             Resources.TagHelperDescriptorFactory_Tag;

            var validName = TryValidateName(
                name,
                whitespaceError: Resources.FormatHtmlTargetElementAttribute_NameCannotBeNullOrWhitespace(targetName),
                characterErrorBuilder: (invalidCharacter) =>
                Resources.FormatHtmlTargetElementAttribute_InvalidName(
                    targetName.ToLower(),
                    name,
                    invalidCharacter),
                errorSink: errorSink);

            return(validName);
        }
        public IEnumerable <Type> Resolve(
            string name,
            SourceLocation documentLocation,
            ErrorSink errorSink)
        {
            if (errorSink == null)
            {
                throw new ArgumentNullException(nameof(errorSink));
            }

            if (string.IsNullOrEmpty(name))
            {
                var errorLength = name == null ? 1 : Math.Max(name.Length, 1);
                errorSink.OnError(
                    documentLocation,
                    "Tag Helper Assembly Name Cannot Be Empty Or Null",
                    errorLength);

                return(Type.EmptyTypes);
            }


            IEnumerable <TypeInfo> libraryTypes;

            try
            {
                libraryTypes = GetExportedTypes(name);
            }
            catch (Exception ex)
            {
                errorSink.OnError(
                    documentLocation,
                    $"Cannot Resolve Tag Helper Assembly: {name}, {ex.Message}",
                    name.Length);

                return(Type.EmptyTypes);
            }

            return(libraryTypes.Select(a => a.AsType()));
        }
        protected override int OnExecute()
        {
            int protocol;

            if (ProtocolOption.HasValue())
            {
                var protocolOptionValue = ProtocolOption.Value();
                if (!int.TryParse(protocolOptionValue, out protocol))
                {
                    ReportError(
                        string.Format(
                            CultureInfo.CurrentCulture,
                            Resources.CouldNotParseProvidedProtocol,
                            protocolOptionValue));
                    return(0);
                }
            }
            else
            {
                protocol = AssemblyTagHelperDescriptorResolver.DefaultProtocolVersion;
            }

            var descriptorResolver = CreateDescriptorResolver();

            descriptorResolver.ProtocolVersion = protocol;

            var errorSink           = new ErrorSink();
            var resolvedDescriptors = new List <TagHelperDescriptor>();

            for (var i = 0; i < AssemblyNamesArgument.Values.Count; i++)
            {
                var assemblyName = AssemblyNamesArgument.Values[i];
                var descriptors  = descriptorResolver.Resolve(assemblyName, errorSink);
                resolvedDescriptors.AddRange(descriptors);
            }

            ReportResults(resolvedDescriptors, errorSink.Errors);

            return(0);
        }
 private void ValidateParentAllowsContent(Span child, ErrorSink errorSink)
 {
     if (HasAllowedChildren())
     {
         var content = child.Content;
         if (!string.IsNullOrWhiteSpace(content))
         {
             var trimmedStart          = content.TrimStart();
             var whitespace            = content.Substring(0, content.Length - trimmedStart.Length);
             var errorStart            = SourceLocation.Advance(child.Start, whitespace);
             var length                = trimmedStart.TrimEnd().Length;
             var allowedChildren       = _currentTagHelperTracker.AllowedChildren;
             var allowedChildrenString = string.Join(", ", allowedChildren);
             errorSink.OnError(
                 errorStart,
                 RazorResources.FormatTagHelperParseTreeRewriter_CannotHaveNonTagContent(
                     _currentTagHelperTracker.TagName,
                     allowedChildrenString),
                 length);
         }
     }
 }
示例#39
0
    public void SimpleRecordTest()
    {
        var code      = @"
record Person =
    FirstName: String;
";
        var errorSink = new ErrorSink();
        var result    = new Lexer(errorSink).Lex(code).ToList();
        var nodes     = new Parser(result, errorSink).Parse().ToList();
        var node      = nodes[0];
        var foo       = (RecordNode)node;

        Assert.Single(nodes);
        Assert.Empty(errorSink.Errors);
        Assert.IsType <RecordNode>(node);
        Assert.Equal("Person", foo.Id);

        var firstNameField = foo.Fields[0];

        Assert.Equal("FirstName", firstNameField.Id);
        Assert.Equal("String", firstNameField.Type.ToString());
    }
        public void RenderAttributeValue_RendersModelExpressionsCorrectly(
            string modelExpressionType,
            string propertyType,
            string expectedValue)
        {
            // Arrange
            var renderer = new MvcTagHelperAttributeValueCodeRenderer(
                new GeneratedTagHelperAttributeContext
            {
                ModelExpressionTypeName         = modelExpressionType,
                CreateModelExpressionMethodName = "SomeMethod"
            });
            var attributeDescriptor = new TagHelperAttributeDescriptor
            {
                Name         = "MyAttribute",
                PropertyName = "SomeProperty",
                TypeName     = propertyType,
            };
            var writer           = new CSharpCodeWriter();
            var generatorContext = new ChunkGeneratorContext(
                host: null,
                className: string.Empty,
                rootNamespace: string.Empty,
                sourceFile: string.Empty,
                shouldGenerateLinePragmas: true);
            var errorSink = new ErrorSink();
            var context   = new CodeGeneratorContext(generatorContext, errorSink);

            // Act
            renderer.RenderAttributeValue(attributeDescriptor, writer, context,
                                          (codeWriter) =>
            {
                codeWriter.Write("MyValue");
            },
                                          complexValue: false);

            // Assert
            Assert.Equal(expectedValue, writer.GenerateCode());
        }
示例#41
0
        private static IEnumerable <string> GetAllowedChildren(Type type, ErrorSink errorSink)
        {
            var restrictChildrenAttribute = type.GetTypeInfo().GetCustomAttribute <RestrictChildrenAttribute>(inherit: false);

            if (restrictChildrenAttribute == null)
            {
                return(null);
            }

            var allowedChildren      = restrictChildrenAttribute.ChildTags;
            var validAllowedChildren = GetValidAllowedChildren(allowedChildren, type.FullName, errorSink);

            if (validAllowedChildren.Any())
            {
                return(validAllowedChildren);
            }
            else
            {
                // All allowed children were invalid, return null to indicate that any child is acceptable.
                return(null);
            }
        }
示例#42
0
            private TagHelperRequiredAttributeDescriptor ParsePlainSelector(ErrorSink errorSink)
            {
                var    nameEndIndex = _requiredAttributes.IndexOfAny(InvalidPlainAttributeNameCharacters, _index);
                string attributeName;

                var nameComparison = TagHelperRequiredAttributeNameComparison.FullMatch;

                if (nameEndIndex == -1)
                {
                    attributeName = _requiredAttributes.Substring(_index);
                    _index        = _requiredAttributes.Length;
                }
                else
                {
                    attributeName = _requiredAttributes.Substring(_index, nameEndIndex - _index);
                    _index        = nameEndIndex;

                    if (_requiredAttributes[nameEndIndex] == RequiredAttributeWildcardSuffix)
                    {
                        nameComparison = TagHelperRequiredAttributeNameComparison.PrefixMatch;

                        // Move past wild card
                        _index++;
                    }
                }

                TagHelperRequiredAttributeDescriptor descriptor = null;

                if (ValidateName(attributeName, targetingAttributes: true, errorSink: errorSink))
                {
                    descriptor = new TagHelperRequiredAttributeDescriptor
                    {
                        Name           = attributeName,
                        NameComparison = nameComparison
                    };
                }

                return(descriptor);
            }
示例#43
0
        public new virtual void Error(int lookaheadIndex, string format, params object[] args)
        {
            int       index = InputPosition + lookaheadIndex;
            SourcePos pos;

            if (SourceFile == null)
            {
                pos = new SourcePos(FileName, LineNumber, index - LineStartAt + 1);
            }
            else
            {
                pos = SourceFile.IndexToLine(index);
            }

            if (ErrorSink != null)
            {
                if (args != null)
                {
                    ErrorSink.Write(Severity.Error, pos, format, args);
                }
                else
                {
                    ErrorSink.Write(Severity.Error, pos, format);
                }
            }
            else
            {
                string msg;
                if (args != null)
                {
                    msg = Localize.From(format, args);
                }
                else
                {
                    msg = Localize.From(format);
                }
                throw new FormatException(pos + ": " + msg);
            }
        }
示例#44
0
 object ParseLiteral2(UString typeMarker, UString parsedText, bool isNumericLiteral)
 {
     if (SkipValueParsing)
     {
         return(null);
     }
     if (PreferCustomLiterals)
     {
         return(new CustomLiteral(parsedText.ToString(), (Symbol)typeMarker.ToString()));
     }
     else
     {
         string syntaxError;
         var    result = ParseLiteral(typeMarker, parsedText, isNumericLiteral, out syntaxError);
         if (syntaxError != null)
         {
             var pos = new SourceRange(SourceFile, _startPosition, InputPosition - _startPosition);
             ErrorSink.Write(Severity.Error, pos, syntaxError);
         }
         return(result);
     }
 }
示例#45
0
        public bool Verify(Dafny.Program dafnyProgram, ResolverTagger resolver, string uniqueIdPrefix, string requestId, ErrorReporterDelegate er)
        {
            Dafny.Translator translator = new Dafny.Translator(dafnyProgram.reporter);
            var translatorFlags         = new Dafny.Translator.TranslatorFlags()
            {
                InsertChecksums = true, UniqueIdPrefix = uniqueIdPrefix
            };


            var boogiePrograms = Dafny.Translator.Translate(dafnyProgram, dafnyProgram.reporter, translatorFlags);

            var impls = boogiePrograms.SelectMany(p => p.Item2.Implementations);

            resolver.ReInitializeVerificationErrors(requestId, impls);

            bool success   = false;
            var  errorSink = new ErrorSink(this);

            foreach (var kv in boogiePrograms)
            {
                var boogieProgram = kv.Item2;

                // TODO(wuestholz): Maybe we should use a fixed program ID to limit the memory overhead due to the program cache in Boogie.
                PipelineOutcome oc = BoogiePipeline(boogieProgram, 1 < Dafny.DafnyOptions.Clo.VerifySnapshots ? uniqueIdPrefix : null, requestId, errorSink, er);
                switch (oc)
                {
                case PipelineOutcome.Done:
                case PipelineOutcome.VerificationCompleted:
                    // TODO:  This would be the place to proceed to compile the program, if desired
                    success = true;
                    break;

                case PipelineOutcome.FatalError:
                default:
                    return(false);
                }
            }
            return(success);
        }
示例#46
0
            private string ParseCssValue(ErrorSink errorSink)
            {
                int valueStart;
                int valueEnd;

                if (At('\'') || At('"'))
                {
                    var quote = Current;

                    // Move past the quote
                    _index++;

                    valueStart = _index;
                    valueEnd   = _requiredAttributes.IndexOf(quote, _index);
                    if (valueEnd == -1)
                    {
                        errorSink.OnError(
                            SourceLocation.Zero,
                            Resources.FormatTagHelperDescriptorFactory_InvalidRequiredAttributeMismatchedQuotes(
                                _requiredAttributes,
                                quote),
                            length: 0);
                        return(null);
                    }
                    _index = valueEnd + 1;
                }
                else
                {
                    valueStart = _index;
                    var valueEndIndex = _requiredAttributes.IndexOfAny(InvalidCssQuotelessValueCharacters, _index);
                    valueEnd = valueEndIndex == -1 ? _requiredAttributes.Length : valueEndIndex;
                    _index   = valueEnd;
                }

                var value = _requiredAttributes.Substring(valueStart, valueEnd - valueStart);

                return(value);
            }
        public void CreateDescriptors_CreatesDesignTimeDescriptorsWithOutputElementHint(
            Type tagHelperType,
            TagHelperDescriptor[] expectedDescriptors)
        {
            // Arrange
            var errorSink = new ErrorSink();

            // Act
            var descriptors = TagHelperDescriptorFactory.CreateDescriptors(
                AssemblyName,
                GetTypeInfo(tagHelperType),
                designTime: true,
                errorSink: errorSink);

            // Assert
            Assert.Empty(errorSink.Errors);

            // We don't care about order. Mono returns reflected attributes differently so we need to ensure order
            // doesn't matter by sorting.
            descriptors = descriptors.OrderBy(descriptor => descriptor.TagName);

            Assert.Equal(expectedDescriptors, descriptors, CaseSensitiveTagHelperDescriptorComparer.Default);
        }
示例#48
0
        public void TagHelperResolution(bool designTime)
        {
            var descriptorResolver    = new TagHelperDescriptorResolver(designTime);
            var errorSink             = new ErrorSink();
            var addTagHelperDirective = new TagHelperDirectiveDescriptor
            {
                DirectiveText = "*, Microsoft.AspNetCore.Mvc.TagHelpers",
                DirectiveType = TagHelperDirectiveType.AddTagHelper,
                Location      = SourceLocation.Zero
            };
            var resolutionContext = new TagHelperDescriptorResolutionContext(
                new[] { addTagHelperDirective },
                errorSink);
            IEnumerable <TagHelperDescriptor> descriptors;

            using (Collector.StartCollection())
            {
                descriptors = descriptorResolver.Resolve(resolutionContext);
            }

            Assert.NotEmpty(descriptors);
            Assert.Empty(errorSink.Errors);
        }
示例#49
0
文件: Parser.cs 项目: Thourum/zLisp
        public static SourceDocument Parse(string sourceCode)
        {
            var errorSink = new ErrorSink();
            var lexer     = new Lexer.Lexer(errorSink);
            var parser    = new Parser(errorSink);
            var src       = new SourceCode(sourceCode);

            var tokens = lexer.LexFile(src).ToArray();

            if (errorSink.HasErrors)
            {
                errorSink.ConsolePrint(); return(null);
            }

            var sourceDoc = parser.ParseFile(src, tokens);

            if (errorSink.HasErrors)
            {
                errorSink.ConsolePrint(); return(null);
            }

            return(sourceDoc);
        }
示例#50
0
    public void CanInstatiateLexer()
    {
        var code = @"
# Chapter One

This is a Paragraph, here we can write all the 
documentation that we'll ever want.

@ This is an annotation
record Person =
    FirstName: String;

Some extra documentation

view MyView =
    Controller
    Model
    View

@ An annotation
@ Another annotation
component Controller =
    @ The Title 
    @ Of the Controller component
    Title: This is the Controller
component Model
component View

";


        var errorSink = new ErrorSink();
        var result    = new Lexer(errorSink).Lex(code).ToList();

        Assert.NotNull(result);
        Assert.Equal(149, result.Count);
    }
示例#51
0
        public void Compile_ReturnsFailedResultIfParseFails()
        {
            // Arrange
            var errorSink = new ErrorSink();
            errorSink.OnError(new RazorError("some message", 1, 1, 1, 1));
            var generatorResult = new GeneratorResults(
                    new Block(new BlockBuilder { Type = BlockType.Comment }),
                    Enumerable.Empty<TagHelperDescriptor>(),
                    errorSink,
                    new CodeGeneratorResult("", new LineMapping[0]),
                    new ChunkTree());
            var host = new Mock<IMvcRazorHost>();
            host.Setup(h => h.GenerateCode(It.IsAny<string>(), It.IsAny<Stream>()))
                .Returns(generatorResult)
                .Verifiable();

            var fileInfo = new Mock<IFileInfo>();
            fileInfo.Setup(f => f.CreateReadStream())
                    .Returns(Stream.Null);

            var compiler = new Mock<ICompilationService>(MockBehavior.Strict);
            var relativeFileInfo = new RelativeFileInfo(fileInfo.Object, @"Views\index\home.cshtml");
            var razorService = new RazorCompilationService(compiler.Object, host.Object, GetFileProviderAccessor(), NullLoggerFactory.Instance);

            // Act
            var result = razorService.Compile(relativeFileInfo);

            // Assert
            Assert.NotNull(result.CompilationFailures);
            Assert.Collection(result.CompilationFailures,
                failure =>
                {
                    var message = Assert.Single(failure.Messages);
                    Assert.Equal("some message", message.Message);
                });
            host.Verify();
        }
示例#52
0
        // This is all that's needed to run code on behalf of language-independent
        // DLR hosting.  Sympl defines its own subtype of ScriptCode.
        //
        public override ScriptCode CompileSourceCode(
            SourceUnit sourceUnit, CompilerOptions options, ErrorSink errorSink)
        {
            using (var reader = sourceUnit.GetReader()) {
                try {
                    switch (sourceUnit.Kind)
                    {
                    case SourceCodeKind.SingleStatement:
                    case SourceCodeKind.Expression:
                    case SourceCodeKind.AutoDetect:
                    case SourceCodeKind.InteractiveCode:
                        return(new SymplScriptCode(
                                   _sympl, _sympl.ParseExprToLambda(reader),
                                   sourceUnit));

                    case SourceCodeKind.Statements:
                    case SourceCodeKind.File:
                        return(new SymplScriptCode(
                                   _sympl,
                                   _sympl.ParseFileToLambda(sourceUnit.Path, reader),
                                   sourceUnit));

                    default:
                        throw Assert.Unreachable;
                    }
                }
                catch (Exception e) {
                    // Real language implementation would have a specific type
                    // of exception.  Also, they would pass errorSink down into
                    // the parser and add messages while doing tighter error
                    // recovery and continuing to parse.
                    errorSink.Add(sourceUnit, e.Message, SourceSpan.None, 0,
                                  Severity.FatalError);
                    return(null);
                }
            }
        }
示例#53
0
    internal override ComponentNode? Parse()
    {
        var keyWordComponent = Take(TokenType.KwComponent);
        var id = ParserIdentifier();
        if (id is null) return null;
        var fields = new List<ArchitectureField>();
        
        var equals = TakeWithoutSpace(TokenType.Equals);
        if (equals is null) return new ComponentNode(id, fields);

        while (_hasField())
        {
            Take(TokenType.NewLine);
            Take(TokenType.Indent);
            var fieldId = Take(TokenType.Identifier);
            if (fieldId is null)
            {
                ErrorSink.AddError(Current ?? Token.Default, ErrorType.InvalidIdentifier,
                    $"A field should have an Identifier.");
                continue;
            }
            
            TakeWithoutSpace(TokenType.Colon);

            var root = Take() ?? Token.Default;
            while (_stillInFieldDefinition())
            {
                if (Current == TokenType.Indent) Take();
                else root = root.Append(Take());
            }
            
            fields.Add(new ArchitectureField(fieldId, root));
        }

        return new ComponentNode(id, fields);
    }
示例#54
0
 private bool?Evaluate(LNode expr)
 {
     if (expr.IsId)
     {
         return(DefinedSymbols.Contains(expr.Name));
     }
     else if (expr.IsLiteral && expr.Value is bool)
     {
         return((bool)expr.Value);
     }
     else if (expr.Calls(S.And, 2))
     {
         return(Evaluate(expr.Args[0]) & Evaluate(expr.Args[1]));
     }
     else if (expr.Calls(S.Or, 2))
     {
         return(Evaluate(expr.Args[0]) | Evaluate(expr.Args[1]));
     }
     else if (expr.Calls(S.Not, 1))
     {
         return(!Evaluate(expr.Args[0]));
     }
     else if (expr.Calls(S.Eq, 2))
     {
         return(Evaluate(expr.Args[0]) == Evaluate(expr.Args[1]));
     }
     else if (expr.Calls(S.Neq, 2))
     {
         return(Evaluate(expr.Args[0]) != Evaluate(expr.Args[1]));
     }
     else
     {
         ErrorSink.Write(Severity.Error, expr.Range, "Only simple boolean expressions with &&, ||, !, ==, !=, are supported in #if and #elif");
         return(null);
     }
 }
        /// <summary>
        /// Creates a <see cref="TagHelperDescriptor"/> from the given <paramref name="typeInfo"/>.
        /// </summary>
        /// <param name="assemblyName">The assembly name that contains <paramref name="type"/>.</param>
        /// <param name="typeInfo">The <see cref="ITypeInfo"/> to create a <see cref="TagHelperDescriptor"/> from.
        /// </param>
        /// <param name="designTime">Indicates if the returned <see cref="TagHelperDescriptor"/>s should include
        /// design time specific information.</param>
        /// <param name="errorSink">The <see cref="ErrorSink"/> used to collect <see cref="RazorError"/>s encountered
        /// when creating <see cref="TagHelperDescriptor"/>s for the given <paramref name="typeInfo"/>.</param>
        /// <returns>
        /// A collection of <see cref="TagHelperDescriptor"/>s that describe the given <paramref name="typeInfo"/>.
        /// </returns>
        public static IEnumerable <TagHelperDescriptor> CreateDescriptors(
            string assemblyName,
            ITypeInfo typeInfo,
            bool designTime,
            ErrorSink errorSink)
        {
            if (typeInfo == null)
            {
                throw new ArgumentNullException(nameof(typeInfo));
            }

            if (errorSink == null)
            {
                throw new ArgumentNullException(nameof(errorSink));
            }

            if (ShouldSkipDescriptorCreation(designTime, typeInfo))
            {
                return(Enumerable.Empty <TagHelperDescriptor>());
            }

            var attributeDescriptors    = GetAttributeDescriptors(typeInfo, designTime, errorSink);
            var targetElementAttributes = GetValidHtmlTargetElementAttributes(typeInfo, errorSink);
            var allowedChildren         = GetAllowedChildren(typeInfo, errorSink);

            var tagHelperDescriptors =
                BuildTagHelperDescriptors(
                    typeInfo,
                    assemblyName,
                    attributeDescriptors,
                    targetElementAttributes,
                    allowedChildren,
                    designTime);

            return(tagHelperDescriptors.Distinct(TagHelperDescriptorComparer.Default));
        }
示例#56
0
        /// <summary>
        /// Loads an <see cref="Assembly"/> using the given <paramref name="name"/> and resolves
        /// all valid <see cref="ITagHelper"/> <see cref="Type"/>s.
        /// </summary>
        /// <param name="name">The name of an <see cref="Assembly"/> to search.</param>
        /// <param name="documentLocation">The <see cref="SourceLocation"/> of the associated
        /// <see cref="Parser.SyntaxTree.SyntaxTreeNode"/> responsible for the current <see cref="Resolve"/> call.
        /// </param>
        /// <param name="errorSink">The <see cref="ErrorSink"/> used to record errors found when resolving
        /// <see cref="ITagHelper"/> <see cref="Type"/>s.</param>
        /// <returns>An <see cref="IEnumerable{Type}"/> of valid <see cref="ITagHelper"/> <see cref="Type"/>s.
        /// </returns>
        public IEnumerable <Type> Resolve(string name,
                                          SourceLocation documentLocation,
                                          [NotNull] ErrorSink errorSink)
        {
            if (string.IsNullOrEmpty(name))
            {
                errorSink.OnError(documentLocation,
                                  Resources.TagHelperTypeResolver_TagHelperAssemblyNameCannotBeEmptyOrNull);

                return(Type.EmptyTypes);
            }

            var assemblyName = new AssemblyName(name);

            IEnumerable <TypeInfo> libraryTypes;

            try
            {
                libraryTypes = GetExportedTypes(assemblyName);
            }
            catch (Exception ex)
            {
                errorSink.OnError(
                    documentLocation,
                    Resources.FormatTagHelperTypeResolver_CannotResolveTagHelperAssembly(
                        assemblyName.Name,
                        ex.Message));

                return(Type.EmptyTypes);
            }

            var validTagHelpers = libraryTypes.Where(IsTagHelper);

            // Convert from TypeInfo[] to Type[]
            return(validTagHelpers.Select(type => type.AsType()));
        }
        /// <summary>
        /// Instantiates a new <see cref="GeneratorResults"/> instance.
        /// </summary>
        /// <param name="document">The <see cref="Block"/> for the syntax tree.</param>
        /// <param name="tagHelperDescriptors">
        /// The <see cref="TagHelperDescriptor"/>s that apply to the current Razor document.
        /// </param>
        /// <param name="errorSink">
        /// The <see cref="ErrorSink"/> used to collect <see cref="RazorError"/>s encountered when parsing the
        /// current Razor document.
        /// </param>
        /// <param name="codeGeneratorResult">The results of generating code for the document.</param>
        /// <param name="chunkTree">A <see cref="ChunkTree"/> for the document.</param>
        public GeneratorResults(Block document,
                                IEnumerable <TagHelperDescriptor> tagHelperDescriptors,
                                ErrorSink errorSink,
                                CodeGeneratorResult codeGeneratorResult,
                                ChunkTree chunkTree)
            : base(document, tagHelperDescriptors, errorSink)
        {
            if (document == null)
            {
                throw new ArgumentNullException(nameof(document));
            }

            if (tagHelperDescriptors == null)
            {
                throw new ArgumentNullException(nameof(tagHelperDescriptors));
            }

            if (errorSink == null)
            {
                throw new ArgumentNullException(nameof(errorSink));
            }

            if (codeGeneratorResult == null)
            {
                throw new ArgumentNullException(nameof(codeGeneratorResult));
            }

            if (chunkTree == null)
            {
                throw new ArgumentNullException(nameof(chunkTree));
            }

            GeneratedCode          = codeGeneratorResult.Code;
            DesignTimeLineMappings = codeGeneratorResult.DesignTimeLineMappings;
            ChunkTree = chunkTree;
        }
    public static RazorSyntaxTree Rewrite(RazorSyntaxTree syntaxTree, string tagHelperPrefix, IEnumerable <TagHelperDescriptor> descriptors)
    {
        var errorSink = new ErrorSink();

        var rewriter = new Rewriter(
            syntaxTree.Source,
            tagHelperPrefix,
            descriptors,
            syntaxTree.Options.FeatureFlags,
            errorSink);

        var rewritten = rewriter.Visit(syntaxTree.Root);

        var errorList = new List <RazorDiagnostic>();

        errorList.AddRange(errorSink.Errors);
        errorList.AddRange(descriptors.SelectMany(d => d.GetAllDiagnostics()));

        var diagnostics = CombineErrors(syntaxTree.Diagnostics, errorList).OrderBy(error => error.Span.AbsoluteIndex);

        var newSyntaxTree = RazorSyntaxTree.Create(rewritten, syntaxTree.Source, diagnostics, syntaxTree.Options);

        return(newSyntaxTree);
    }
示例#59
0
        private static bool EnsureValidPrefix(
            string prefix,
            SourceLocation directiveLocation,
            ErrorSink errorSink)
        {
            foreach (var character in prefix)
            {
                // Prefixes are correlated with tag names, tag names cannot have whitespace.
                if (char.IsWhiteSpace(character) ||
                    TagHelperDescriptorFactory.InvalidNonWhitespaceNameCharacters.Contains(character))
                {
                    errorSink.OnError(
                        directiveLocation,
                        Resources.FormatTagHelperDescriptorResolver_InvalidTagHelperPrefixValue(
                            SyntaxConstants.CSharp.TagHelperPrefixKeyword,
                            character,
                            prefix));

                    return(false);
                }
            }

            return(true);
        }
示例#60
0
        public void Resolve_CreatesErrors()
        {
            // Arrange
            var assemblyNameLookups = new Dictionary <string, IEnumerable <Type> >
            {
                { CustomTagHelperAssembly, new[] { typeof(InvalidTagHelper) } }
            };
            var descriptorResolver = new TestAssemblyTagHelperDescriptorResolver(assemblyNameLookups);
            var errorSink          = new ErrorSink();

            // Act
            var descriptors = descriptorResolver.Resolve(CustomTagHelperAssembly, errorSink);

            // Assert
            Assert.NotEmpty(descriptors);
            var error = Assert.Single(errorSink.Errors);

            Assert.Equal(
                "Tag helpers cannot target tag name 'inv@lid' because it contains a '@' character.",
                error.Message,
                StringComparer.Ordinal);
            Assert.Equal(SourceLocation.Zero, error.Location);
            Assert.Equal(0, error.Length);
        }