Enable nullable annotations, round 2 of x

This commit is contained in:
Jason Nelson
2021-03-09 16:55:13 -08:00
parent 640196a18f
commit 39c05f34d1
42 changed files with 278 additions and 206 deletions

View File

@@ -2,6 +2,8 @@
// This file is licensed under the BSD-Clause 2 license.
// See the license.txt file in the project root for more information.
#nullable enable
using System;
using System.Collections.Generic;
using Markdig.Helpers;
@@ -41,7 +43,7 @@ namespace Markdig.Extensions.Abbreviations
return BlockState.None;
}
if (!LinkHelper.TryParseLabel(ref slice, out string label, out SourceSpan labelSpan))
if (!LinkHelper.TryParseLabel(ref slice, out string? label, out SourceSpan labelSpan))
{
return BlockState.None;
}
@@ -89,10 +91,10 @@ namespace Markdig.Extensions.Abbreviations
inlineProcessor.LiteralInlineParser.PostMatch += (InlineProcessor processor, ref StringSlice slice) =>
{
var literal = (LiteralInline)processor.Inline;
var literal = (LiteralInline)processor.Inline!;
var originalLiteral = literal;
ContainerInline container = null;
ContainerInline? container = null;
// This is slow, but we don't have much the choice
var content = literal.Content;

View File

@@ -2,9 +2,12 @@
// This file is licensed under the BSD-Clause 2 license.
// See the license.txt file in the project root for more information.
#nullable enable
using Markdig.Helpers;
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
namespace Markdig.Extensions.MediaLinks
@@ -13,12 +16,23 @@ namespace Markdig.Extensions.MediaLinks
{
private sealed class DelegateProvider : IHostProvider
{
public string HostPrefix { get; set; }
public Func<Uri, string> Delegate { get; set; }
public bool AllowFullScreen { get; set; } = true;
public string Class { get; set; }
public DelegateProvider(string hostPrefix, Func<Uri, string?> handler, bool allowFullscreen = true, string? className = null)
{
HostPrefix = hostPrefix;
Delegate = handler;
AllowFullScreen = allowFullscreen;
Class = className;
}
public bool TryHandle(Uri mediaUri, bool isSchemaRelative, out string iframeUrl)
public string HostPrefix { get; }
public Func<Uri, string?> Delegate { get; }
public bool AllowFullScreen { get; }
public string? Class { get; }
public bool TryHandle(Uri mediaUri, bool isSchemaRelative, [NotNullWhen(true)] out string? iframeUrl)
{
if (!mediaUri.Host.StartsWith(HostPrefix, StringComparison.OrdinalIgnoreCase))
{
@@ -38,14 +52,14 @@ namespace Markdig.Extensions.MediaLinks
/// <param name="allowFullScreen">Should the generated iframe has allowfullscreen attribute.</param>
/// <param name="iframeClass">"class" attribute of generated iframe.</param>
/// <returns>A <see cref="IHostProvider"/> with delegate handler.</returns>
public static IHostProvider Create(string hostPrefix, Func<Uri, string> handler, bool allowFullScreen = true, string iframeClass = null)
public static IHostProvider Create(string hostPrefix, Func<Uri, string?> handler, bool allowFullScreen = true, string? iframeClass = null)
{
if (string.IsNullOrEmpty(hostPrefix))
ThrowHelper.ArgumentException("hostPrefix is null or empty.", nameof(hostPrefix));
if (handler == null)
ThrowHelper.ArgumentNullException(nameof(handler));
return new DelegateProvider { HostPrefix = hostPrefix, Delegate = handler, AllowFullScreen = allowFullScreen, Class = iframeClass };
return new DelegateProvider(hostPrefix, handler, allowFullScreen, iframeClass);
}
internal static Dictionary<string, IHostProvider> KnownHosts { get; }
@@ -67,7 +81,7 @@ namespace Markdig.Extensions.MediaLinks
return query.Split(SplitAnd, StringSplitOptions.RemoveEmptyEntries);
}
private static string YouTube(Uri uri)
private static string? YouTube(Uri uri)
{
string uriPath = uri.AbsolutePath;
if (string.Equals(uriPath, "/embed", StringComparison.OrdinalIgnoreCase) || uriPath.StartsWith("/embed/", StringComparison.OrdinalIgnoreCase))
@@ -85,7 +99,7 @@ namespace Markdig.Extensions.MediaLinks
);
}
private static string YouTubeShortened(Uri uri)
private static string? YouTubeShortened(Uri uri)
{
return BuildYouTubeIframeUrl(
uri.AbsolutePath.Substring(1),
@@ -93,7 +107,7 @@ namespace Markdig.Extensions.MediaLinks
);
}
private static string BuildYouTubeIframeUrl(string videoId, string startTime)
private static string? BuildYouTubeIframeUrl(string? videoId, string? startTime)
{
if (string.IsNullOrEmpty(videoId))
{
@@ -103,29 +117,25 @@ namespace Markdig.Extensions.MediaLinks
return string.IsNullOrEmpty(startTime) ? url : $"{url}?start={startTime}";
}
private static string Vimeo(Uri uri)
private static string? Vimeo(Uri uri)
{
var items = uri.GetComponents(UriComponents.Path, UriFormat.Unescaped).Split('/');
return items.Length > 0 ? $"https://player.vimeo.com/video/{ items[items.Length - 1] }" : null;
}
private static string Odnoklassniki(Uri uri)
private static string? Odnoklassniki(Uri uri)
{
var items = uri.GetComponents(UriComponents.Path, UriFormat.Unescaped).Split('/');
return items.Length > 0 ? $"https://ok.ru/videoembed/{ items[items.Length - 1] }" : null;
}
private static string Yandex(Uri uri)
private static string? Yandex(Uri uri)
{
var items = uri.GetComponents(UriComponents.Path, UriFormat.Unescaped).Split('/');
var albumKeyword
= items.Skip(0).FirstOrDefault();
var albumId
= items.Skip(1).FirstOrDefault();
var trackKeyword
= items.Skip(2).FirstOrDefault();
var trackId
= items.Skip(3).FirstOrDefault();
string[] items = uri.GetComponents(UriComponents.Path, UriFormat.Unescaped).Split('/');
string? albumKeyword = items.Skip(0).FirstOrDefault();
string? albumId = items.Skip(1).FirstOrDefault();
string? trackKeyword = items.Skip(2).FirstOrDefault();
string? trackId = items.Skip(3).FirstOrDefault();
if (albumKeyword != "album" || albumId == null || trackKeyword != "track" || trackId == null)
{

View File

@@ -2,7 +2,10 @@
// This file is licensed under the BSD-Clause 2 license.
// See the license.txt file in the project root for more information.
#nullable enable
using System;
using System.Diagnostics.CodeAnalysis;
namespace Markdig.Extensions.MediaLinks
{
@@ -14,7 +17,7 @@ namespace Markdig.Extensions.MediaLinks
/// <summary>
/// "class" attribute of generated iframe.
/// </summary>
string Class { get; }
string? Class { get; }
/// <summary>
/// Generate url for iframe.
@@ -23,7 +26,7 @@ namespace Markdig.Extensions.MediaLinks
/// <param name="isSchemaRelative"><see langword="true"/> if <paramref name="mediaUri"/> is a schema relative uri, i.e. uri starts with "//".</param>
/// <param name="iframeUrl">Generated url for iframe.</param>
/// <seealso href="https://tools.ietf.org/html/rfc3986#section-4.2"/>
bool TryHandle(Uri mediaUri, bool isSchemaRelative, out string iframeUrl);
bool TryHandle(Uri mediaUri, bool isSchemaRelative, [NotNullWhen(true)] out string? iframeUrl);
/// <summary>
/// Should the generated iframe has allowfullscreen attribute.

View File

@@ -2,12 +2,12 @@
// This file is licensed under the BSD-Clause 2 license.
// See the license.txt file in the project root for more information.
using Markdig.Renderers;
using Markdig.Renderers.Html.Inlines;
using System;
#nullable enable
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Markdig.Renderers;
using Markdig.Renderers.Html.Inlines;
namespace Markdig.Extensions.ReferralLinks
{
@@ -18,7 +18,7 @@ namespace Markdig.Extensions.ReferralLinks
Rels = rels?.ToList();
}
public List<string> Rels { get; }
public List<string>? Rels { get; }
public void Setup(MarkdownPipelineBuilder pipeline)
{
@@ -26,7 +26,7 @@ namespace Markdig.Extensions.ReferralLinks
public void Setup(MarkdownPipeline pipeline, IMarkdownRenderer renderer)
{
string relString = Rels == null? null :
string? relString = Rels is null ? null :
string.Join(" ", Rels.Where(r => !string.IsNullOrEmpty(r)));
var linkRenderer = renderer.ObjectRenderers.Find<LinkInlineRenderer>();

View File

@@ -2,6 +2,8 @@
// This file is licensed under the BSD-Clause 2 license.
// See the license.txt file in the project root for more information.
#nullable enable
using System;
using Markdig.Helpers;
using Markdig.Renderers;
@@ -24,7 +26,7 @@ namespace Markdig.Extensions.SelfPipeline
/// <param name="tag">The matching start tag.</param>
/// <param name="defaultExtensions">The default extensions.</param>
/// <exception cref="ArgumentException">Tag cannot contain angle brackets</exception>
public SelfPipelineExtension(string tag = null, string defaultExtensions = null)
public SelfPipelineExtension(string? tag = null, string? defaultExtensions = null)
{
tag = tag?.Trim();
tag = string.IsNullOrEmpty(tag) ? DefaultTag : tag;
@@ -46,7 +48,7 @@ namespace Markdig.Extensions.SelfPipeline
/// <summary>
/// Gets the default pipeline to configure if no tag was found in the input text. Default is <c>null</c> (core pipeline).
/// </summary>
public string DefaultExtensions { get; }
public string? DefaultExtensions { get; }
/// <summary>
/// Gets the self pipeline hint tag start that will be matched.
@@ -78,7 +80,7 @@ namespace Markdig.Extensions.SelfPipeline
if (inputText == null) ThrowHelper.ArgumentNullException(nameof(inputText));
var builder = new MarkdownPipelineBuilder();
string defaultConfig = DefaultExtensions;
string? defaultConfig = DefaultExtensions;
var indexOfSelfPipeline = inputText.IndexOf(SelfPipelineHintTagStart, StringComparison.OrdinalIgnoreCase);
if (indexOfSelfPipeline >= 0)
{
@@ -90,7 +92,7 @@ namespace Markdig.Extensions.SelfPipeline
}
}
if (!string.IsNullOrEmpty(defaultConfig))
if (defaultConfig is { Length: > 0 })
{
builder.Configure(defaultConfig);
}

View File

@@ -1,6 +1,9 @@
// Copyright (c) Alexandre Mutel. All rights reserved.
// This file is licensed under the BSD-Clause 2 license.
// See the license.txt file in the project root for more information.
#nullable enable
using System;
using Markdig.Renderers;
using Markdig.Renderers.Html;
@@ -22,14 +25,14 @@ namespace Markdig.Extensions.SmartyPants
/// </summary>
/// <param name="options">The options.</param>
/// <exception cref="ArgumentNullException"></exception>
public HtmlSmartyPantRenderer(SmartyPantOptions options)
public HtmlSmartyPantRenderer(SmartyPantOptions? options)
{
this.options = options ?? throw new ArgumentNullException(nameof(options));
}
protected override void Write(HtmlRenderer renderer, SmartyPant obj)
{
if (!options.Mapping.TryGetValue(obj.Type, out string text))
if (!options.Mapping.TryGetValue(obj.Type, out string? text))
{
DefaultOptions.Mapping.TryGetValue(obj.Type, out text);
}

View File

@@ -2,6 +2,8 @@
// This file is licensed under the BSD-Clause 2 license.
// See the license.txt file in the project root for more information.
#nullable enable
using System.Collections.Generic;
namespace Markdig.Extensions.SmartyPants

View File

@@ -2,6 +2,8 @@
// This file is licensed under the BSD-Clause 2 license.
// See the license.txt file in the project root for more information.
#nullable enable
using Markdig.Parsers.Inlines;
using Markdig.Renderers;
@@ -16,7 +18,7 @@ namespace Markdig.Extensions.SmartyPants
/// Initializes a new instance of the <see cref="SmartyPantsExtension"/> class.
/// </summary>
/// <param name="options">The options.</param>
public SmartyPantsExtension(SmartyPantOptions options)
public SmartyPantsExtension(SmartyPantOptions? options)
{
Options = options ?? new SmartyPantOptions();
}

View File

@@ -2,6 +2,8 @@
// This file is licensed under the BSD-Clause 2 license.
// See the license.txt file in the project root for more information.
#nullable enable
using System;
using System.Collections.Generic;
using System.Diagnostics;
@@ -28,7 +30,7 @@ namespace Markdig.Extensions.Tables
/// </summary>
/// <param name="lineBreakParser">The linebreak parser to use</param>
/// <param name="options">The options.</param>
public PipeTableParser(LineBreakInlineParser lineBreakParser, PipeTableOptions options = null)
public PipeTableParser(LineBreakInlineParser lineBreakParser, PipeTableOptions? options = null)
{
this.lineBreakParser = lineBreakParser ?? throw new ArgumentNullException(nameof(lineBreakParser));
OpeningCharacters = new[] { '|', '\n', '\r' };
@@ -59,7 +61,7 @@ namespace Markdig.Extensions.Tables
var position = processor.GetSourcePosition(slice.Start, out int globalLineIndex, out int column);
var localLineIndex = globalLineIndex - processor.LineIndex;
if (tableState == null)
if (tableState is null)
{
// A table could be preceded by an empty line or a line containing an inline
@@ -92,8 +94,8 @@ namespace Markdig.Extensions.Tables
tableState.LineIndex++;
if (!isFirstLineEmpty)
{
tableState.ColumnAndLineDelimiters.Add(processor.Inline);
tableState.EndOfLines.Add(processor.Inline);
tableState.ColumnAndLineDelimiters.Add(processor.Inline!);
tableState.EndOfLines.Add(processor.Inline!);
}
}
else
@@ -117,11 +119,10 @@ namespace Markdig.Extensions.Tables
tableState.ColumnAndLineDelimiters.Add(processor.Inline);
}
return true;
}
public bool PostProcess(InlineProcessor state, Inline root, Inline lastChild, int postInlineProcessorIndex, bool isFinalProcessing)
public bool PostProcess(InlineProcessor state, Inline root, Inline? lastChild, int postInlineProcessorIndex, bool isFinalProcessing)
{
var container = root as ContainerInline;
var tableState = state.ParserStates[Index] as TableState;
@@ -135,17 +136,14 @@ namespace Markdig.Extensions.Tables
}
var child = container.LastChild;
List<PipeTableDelimiterInline> delimitersToRemove = null;
List<PipeTableDelimiterInline>? delimitersToRemove = null;
while (child != null)
{
var pipeDelimiter = child as PipeTableDelimiterInline;
if (pipeDelimiter != null)
if (child is PipeTableDelimiterInline pipeDelimiter)
{
if (delimitersToRemove == null)
{
delimitersToRemove = new List<PipeTableDelimiterInline>();
}
delimitersToRemove ??= new List<PipeTableDelimiterInline>();
delimitersToRemove.Add(pipeDelimiter);
}
@@ -258,9 +256,9 @@ namespace Markdig.Extensions.Tables
{
while (true)
{
if (lastElement is ContainerInline)
if (lastElement is ContainerInline lastElementContainer)
{
var nextElement = ((ContainerInline) lastElement).LastChild;
var nextElement = lastElementContainer.LastChild;
if (nextElement != null)
{
lastElement = nextElement;
@@ -287,8 +285,8 @@ namespace Markdig.Extensions.Tables
// Cell loop
// Reconstruct the table from the delimiters
TableRow row = null;
TableRow firstRow = null;
TableRow? row = null;
TableRow? firstRow = null;
for (int i = 0; i < delimiters.Count; i++)
{
var delimiter = delimiters[i];
@@ -298,10 +296,8 @@ namespace Markdig.Extensions.Tables
if (row == null)
{
row = new TableRow();
if (firstRow == null)
{
firstRow = row;
}
firstRow ??= row;
// If the first delimiter is a pipe and doesn't have any parent or previous sibling, for cases like:
// 0) | a | b | \n
@@ -318,8 +314,8 @@ namespace Markdig.Extensions.Tables
// x
// 1) | a | b \n
// 2) a | b \n
Inline endOfCell = null;
Inline beginOfCell = null;
Inline? endOfCell = null;
Inline? beginOfCell = null;
var cellContentIt = delimiter;
while (true)
{
@@ -331,7 +327,7 @@ namespace Markdig.Extensions.Tables
}
// The cell begins at the first effective child after a | or the top ContainerInline (which is not necessary to bring into the tree + it contains an invalid span calculation)
if (cellContentIt is PipeTableDelimiterInline || (cellContentIt.GetType() == typeof(ContainerInline) && cellContentIt.Parent == null ))
if (cellContentIt is PipeTableDelimiterInline || (cellContentIt.GetType() == typeof(ContainerInline) && cellContentIt.Parent is null ))
{
beginOfCell = ((ContainerInline)cellContentIt).FirstChild;
if (endOfCell == null)
@@ -348,14 +344,13 @@ namespace Markdig.Extensions.Tables
}
}
// If the current deilimiter is a pipe `|` OR
// the beginOfCell/endOfCell are not null and
// either they are :
// - different
// - they contain a single element, but it is not a line break (\n) or an empty/whitespace Literal.
// Then we can add a cell to the current row
if (!isLine || (beginOfCell != null && endOfCell != null && ( beginOfCell != endOfCell || !(beginOfCell is LineBreakInline || (beginOfCell is LiteralInline && ((LiteralInline)beginOfCell).Content.IsEmptyOrWhitespace())))))
if (!isLine || (beginOfCell != null && endOfCell != null && ( beginOfCell != endOfCell || !(beginOfCell is LineBreakInline || (beginOfCell is LiteralInline beingOfCellLiteral && beingOfCellLiteral.Content.IsEmptyOrWhitespace())))))
{
if (!isLine)
{
@@ -420,7 +415,7 @@ namespace Markdig.Extensions.Tables
Debug.Assert(row != null);
if (table.Span.IsEmpty)
{
table.Span = row.Span;
table.Span = row!.Span;
table.Line = row.Line;
table.Column = row.Column;
}
@@ -470,7 +465,7 @@ namespace Markdig.Extensions.Tables
return false;
}
private static bool ParseHeaderString(Inline inline, out TableColumnAlign? align)
private static bool ParseHeaderString(Inline? inline, out TableColumnAlign? align)
{
align = 0;
var literal = inline as LiteralInline;
@@ -493,10 +488,10 @@ namespace Markdig.Extensions.Tables
return false;
}
private List<TableColumnDefinition> FindHeaderRow(List<Inline> delimiters)
private List<TableColumnDefinition>? FindHeaderRow(List<Inline> delimiters)
{
bool isValidRow = false;
List<TableColumnDefinition> aligns = null;
List<TableColumnDefinition>? aligns = null;
for (int i = 0; i < delimiters.Count; i++)
{
if (!IsLine(delimiters[i]))
@@ -524,10 +519,9 @@ namespace Markdig.Extensions.Tables
}
// Create aligns until we may have a header row
if (aligns == null)
{
aligns = new List<TableColumnDefinition>();
}
aligns ??= new List<TableColumnDefinition>();
aligns.Add(new TableColumnDefinition() { Alignment = align });
// If this is the last delimiter, we need to check the right side of the `|` delimiter
@@ -572,20 +566,20 @@ namespace Markdig.Extensions.Tables
return inline is LineBreakInline;
}
private static bool IsStartOfLineColumnDelimiter(Inline inline)
private static bool IsStartOfLineColumnDelimiter(Inline? inline)
{
if (inline == null)
if (inline is null)
{
return false;
}
var previous = inline.PreviousSibling;
if (previous == null)
if (previous is null)
{
return true;
}
var literal = previous as LiteralInline;
if (literal != null)
if (previous is LiteralInline literal)
{
if (!literal.Content.IsEmptyOrWhitespace())
{
@@ -596,43 +590,42 @@ namespace Markdig.Extensions.Tables
return previous == null || IsLine(previous);
}
private static void TrimStart(Inline inline)
private static void TrimStart(Inline? inline)
{
while (inline is ContainerInline && !(inline is DelimiterInline))
{
inline = ((ContainerInline)inline).FirstChild;
}
var literal = inline as LiteralInline;
if (literal != null)
if (inline is LiteralInline literal)
{
literal.Content.TrimStart();
}
}
private static void TrimEnd(Inline inline)
private static void TrimEnd(Inline? inline)
{
var literal = inline as LiteralInline;
if (literal != null)
if (inline is LiteralInline literal)
{
literal.Content.TrimEnd();
}
}
private static bool IsNullOrSpace(Inline inline)
private static bool IsNullOrSpace(Inline? inline)
{
if (inline == null)
if (inline is null)
{
return true;
}
var literal = inline as LiteralInline;
if (literal != null)
if (inline is LiteralInline literal)
{
return literal.Content.IsEmptyOrWhitespace();
}
return false;
}
private class TableState
private sealed class TableState
{
public TableState()
{

View File

@@ -2,6 +2,8 @@
// This file is licensed under the BSD-Clause 2 license.
// See the license.txt file in the project root for more information.
#nullable enable
using Markdig.Helpers;
using Markdig.Parsers;
using Markdig.Syntax;

View File

@@ -2,6 +2,8 @@
// This file is licensed under the BSD-Clause 2 license.
// See the license.txt file in the project root for more information.
#nullable enable
using System;
using System.Globalization;
using System.Collections.Generic;

View File

@@ -419,7 +419,7 @@ namespace Markdig.Helpers
public static bool TryParseInlineLinkTrivia(
ref StringSlice text,
out string? link,
[NotNullWhen(true)] out string? link,
out SourceSpan unescapedLink,
out string? title,
out SourceSpan unescapedTitle,

View File

@@ -2,7 +2,10 @@
// This file is licensed under the BSD-Clause 2 license.
// See the license.txt file in the project root for more information.
#nullable enable
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
namespace Markdig.Helpers
{
@@ -12,7 +15,7 @@ namespace Markdig.Helpers
/// <typeparam name="T">Type of the list item</typeparam>
/// <seealso cref="List{T}" />
/// <remarks>We use a typed list and don't use extension methods because it would pollute all list implements and the top level namespace.</remarks>
public class OrderedList<T> : List<T>
public class OrderedList<T> : List<T> where T: notnull
{
public OrderedList()
{
@@ -36,7 +39,7 @@ namespace Markdig.Helpers
return false;
}
public TItem Find<TItem>() where TItem : T
public TItem? Find<TItem>() where TItem : T
{
for (int i = 0; i < Count; i++)
{
@@ -48,13 +51,13 @@ namespace Markdig.Helpers
return default;
}
public bool TryFind<TItem>(out TItem item) where TItem : T
public bool TryFind<TItem>([NotNullWhen(true)] out TItem? item) where TItem : T
{
item = Find<TItem>();
return item != null;
}
public TItem FindExact<TItem>() where TItem : T
public TItem? FindExact<TItem>() where TItem : T
{
for (int i = 0; i < Count; i++)
{

View File

@@ -95,9 +95,9 @@ namespace Markdig
/// <param name="pipeline">The pipeline used for the conversion.</param>
/// <returns>The result of the conversion</returns>
/// <exception cref="ArgumentNullException">if markdown document variable is null</exception>
public static string ToHtml(this MarkdownDocument document, MarkdownPipeline pipeline = null)
public static string ToHtml(this MarkdownDocument document, MarkdownPipeline? pipeline = null)
{
if (document == null) ThrowHelper.ArgumentNullException(nameof(document));
if (document is null) ThrowHelper.ArgumentNullException(nameof(document));
pipeline ??= new MarkdownPipelineBuilder().Build();
var renderer = pipeline.GetCacheableHtmlRenderer();
@@ -105,7 +105,7 @@ namespace Markdig
renderer.Render(document);
renderer.Writer.Flush();
string html = renderer.Writer.ToString();
string html = renderer.Writer.ToString()!;
pipeline.ReleaseCacheableHtmlRenderer(renderer);
return html;
}

View File

@@ -538,9 +538,9 @@ namespace Markdig
/// <param name="pipeline">The pipeline (e.g: advanced for <see cref="UseAdvancedExtensions"/>, pipetables+gridtables for <see cref="UsePipeTables"/> and <see cref="UseGridTables"/></param>
/// <param name="extensions">The extensions to activate as a string</param>
/// <returns>The modified pipeline</returns>
public static MarkdownPipelineBuilder Configure(this MarkdownPipelineBuilder pipeline, string extensions)
public static MarkdownPipelineBuilder Configure(this MarkdownPipelineBuilder pipeline, string? extensions)
{
if (extensions == null)
if (extensions is null)
{
return pipeline;
}

View File

@@ -2,6 +2,8 @@
// This file is licensed under the BSD-Clause 2 license.
// See the license.txt file in the project root for more information.
#nullable enable
using Markdig.Syntax;
namespace Markdig.Parsers
@@ -38,9 +40,9 @@ namespace Markdig.Parsers
}
// TODO: Add comment
public event ProcessBlockDelegate Closed;
public event ProcessBlockDelegate? Closed;
internal ProcessBlockDelegate GetClosedEvent => Closed;
internal ProcessBlockDelegate? GetClosedEvent => Closed;
/// <summary>
/// Determines whether this instance can interrupt the specified block being processed.

View File

@@ -2,6 +2,8 @@
// This file is licensed under the BSD-Clause 2 license.
// See the license.txt file in the project root for more information.
#nullable enable
using System;
using System.Collections.Generic;
using System.Diagnostics;
@@ -16,7 +18,7 @@ namespace Markdig.Parsers
/// </summary>
public class BlockProcessor
{
private BlockProcessor root;
private readonly BlockProcessor? root;
private int currentStackIndex;
private readonly BlockParserStateCache parserStateCache;
private int originalLineStart = 0;
@@ -44,7 +46,7 @@ namespace Markdig.Parsers
/// <param name="trackTrivia">Whether to parse trivia such as whitespace, extra heading characters and unescaped string values.</param>
/// <exception cref="ArgumentNullException">
/// </exception>
public BlockProcessor(MarkdownDocument document, BlockParserList parsers, MarkdownParserContext context, bool trackTrivia = false)
public BlockProcessor(MarkdownDocument document, BlockParserList parsers, MarkdownParserContext? context, bool trackTrivia = false)
{
if (document == null) ThrowHelper.ArgumentNullException(nameof(document));
if (parsers == null) ThrowHelper.ArgumentNullException(nameof(parsers));
@@ -75,27 +77,27 @@ namespace Markdig.Parsers
/// <summary>
/// Gets the parser context or <c>null</c> if none is available.
/// </summary>
public MarkdownParserContext Context { get; }
public MarkdownParserContext? Context { get; }
/// <summary>
/// Gets the current active container.
/// </summary>
public ContainerBlock CurrentContainer { get; private set; }
public ContainerBlock? CurrentContainer { get; private set; }
/// <summary>
/// Gets the last block that is opened.
/// </summary>
public Block CurrentBlock { get; private set; }
public Block? CurrentBlock { get; private set; }
/// <summary>
/// Gets the last block that is created.
/// </summary>
public Block LastBlock { get; private set; }
public Block? LastBlock { get; private set; }
/// <summary>
/// Gets the next block in a <see cref="BlockParser.TryContinue"/>.
/// </summary>
public Block NextContinue => currentStackIndex + 1 < OpenedBlocks.Count ? OpenedBlocks[currentStackIndex + 1] : null;
public Block? NextContinue => currentStackIndex + 1 < OpenedBlocks.Count ? OpenedBlocks[currentStackIndex + 1] : null;
/// <summary>
/// Gets the root document.
@@ -197,7 +199,7 @@ namespace Markdig.Parsers
{
var linesBefore = LinesBefore;
LinesBefore = null;
return linesBefore;
return linesBefore!;
}
/// <summary>
@@ -206,7 +208,7 @@ namespace Markdig.Parsers
/// <see cref="StringSlice.NewLine"/> is relevant. Otherwise, the <see cref="StringSlice"/>
/// entry will contain trivia.
/// </summary>
public List<StringSlice> LinesBefore { get; set; }
public List<StringSlice>? LinesBefore { get; set; }
/// <summary>
/// True to parse trivia such as whitespace, extra heading characters and unescaped
@@ -226,7 +228,7 @@ namespace Markdig.Parsers
container = container.Parent;
}
return container;
return container!;
}
/// <summary>
@@ -835,7 +837,7 @@ namespace Markdig.Parsers
// If a block parser cannot interrupt a paragraph, and the last block is a paragraph
// we can skip this parser
var lastBlock = CurrentBlock;
var lastBlock = CurrentBlock!;
if (!blockParser.CanInterrupt(this, lastBlock))
{
continue;
@@ -960,10 +962,10 @@ namespace Markdig.Parsers
}
// If previous block is a container, add the new block as a children of the previous block
if (block.Parent == null)
if (block.Parent is null)
{
UpdateLastBlockAndContainer();
CurrentContainer.Add(block);
CurrentContainer!.Add(block);
}
block.IsOpen = result.IsContinue();

View File

@@ -2,6 +2,10 @@
// This file is licensed under the BSD-Clause 2 license.
// See the license.txt file in the project root for more information.
#nullable enable
using System;
using Markdig.Helpers;
using Markdig.Renderers.Html;
using Markdig.Syntax;
@@ -24,12 +28,12 @@ namespace Markdig.Parsers
/// <summary>
/// Gets or sets the information parser.
/// </summary>
public InfoParserDelegate InfoParser { get; set; }
public InfoParserDelegate? InfoParser { get; set; }
/// <summary>
/// A delegates that allows to process attached attributes
/// </summary>
public TryParseAttributesDelegate TryParseAttributes { get; set; }
public TryParseAttributesDelegate? TryParseAttributes { get; set; }
}
/// <summary>
@@ -38,7 +42,6 @@ namespace Markdig.Parsers
/// <seealso cref="BlockParser" />
public abstract class FencedBlockParserBase<T> : FencedBlockParserBase where T : Block, IFencedBlock
{
/// <summary>
/// Initializes a new instance of the <see cref="FencedBlockParserBase{T}"/> class.
/// </summary>
@@ -52,7 +55,7 @@ namespace Markdig.Parsers
/// <summary>
/// Gets or sets the language prefix (default is "language-")
/// </summary>
public string InfoPrefix { get; set; }
public string? InfoPrefix { get; set; }
public int MinimumMatchCount { get; set; }
@@ -79,11 +82,11 @@ namespace Markdig.Parsers
{
var start = line.Start;
var end = start - 1;
StringSlice afterFence = new StringSlice(line.Text, start, end);
StringSlice info = new StringSlice(line.Text, start, end);
StringSlice afterInfo = new StringSlice(line.Text, start, end);
StringSlice arg = new StringSlice(line.Text, start, end);
StringSlice afterArg = new StringSlice(line.Text, start, end);
var afterFence = new StringSlice(line.Text, start, end);
var info = new StringSlice(line.Text, start, end);
var afterInfo = new StringSlice(line.Text, start, end);
var arg = new StringSlice(line.Text, start, end);
var afterArg = new StringSlice(line.Text, start, end);
ParseState state = ParseState.AfterFence;
for (int i = line.Start; i <= line.End; i++)
@@ -182,7 +185,7 @@ namespace Markdig.Parsers
public static bool DefaultInfoParser(BlockProcessor state, ref StringSlice line, IFencedBlock fenced, char openingCharacter)
{
string infoString;
string argString = null;
string? argString = null;
// An info string cannot contain any backticks (unless it is a tilde block)
int firstSpace = -1;
@@ -216,7 +219,7 @@ namespace Markdig.Parsers
if (firstSpace > 0)
{
infoString = line.Text.Substring(line.Start, firstSpace - line.Start).Trim();
infoString = line.Text.AsSpan(line.Start, firstSpace - line.Start).Trim().ToString();
// Skip any spaces after info string
firstSpace++;
@@ -329,7 +332,7 @@ namespace Markdig.Parsers
{
block.UpdateSpanEnd(startBeforeTrim - 1);
var fencedBlock = block as IFencedBlock;
var fencedBlock = (IFencedBlock)block;
fencedBlock.ClosingFencedCharCount = closingCount;
fencedBlock.NewLine = processor.Line.NewLine;
fencedBlock.TriviaBeforeClosingFence = processor.UseTrivia(sourcePosition - 1);

View File

@@ -2,9 +2,10 @@
// This file is licensed under the BSD-Clause 2 license.
// See the license.txt file in the project root for more information.
#nullable enable
using Markdig.Helpers;
using Markdig.Syntax;
using System.ComponentModel;
namespace Markdig.Parsers
{

View File

@@ -2,6 +2,8 @@
// This file is licensed under the BSD-Clause 2 license.
// See the license.txt file in the project root for more information.
#nullable enable
using System.Diagnostics;
using Markdig.Helpers;
using Markdig.Syntax;
@@ -31,7 +33,7 @@ namespace Markdig.Parsers
/// <summary>
/// A delegates that allows to process attached attributes after #
/// </summary>
public TryParseAttributesDelegate TryParseAttributes { get; set; }
public TryParseAttributesDelegate? TryParseAttributes { get; set; }
public override BlockState TryOpen(BlockProcessor processor)
{

View File

@@ -2,6 +2,8 @@
// This file is licensed under the BSD-Clause 2 license.
// See the license.txt file in the project root for more information.
#nullable enable
using System;
using Markdig.Helpers;
using Markdig.Syntax;
@@ -176,7 +178,6 @@ namespace Markdig.Parsers
private const string EndOfCDATA = "]]>";
private const string EndOfProcessingInstruction = "?>";
private BlockState MatchEnd(BlockProcessor state, HtmlBlock htmlBlock)
{
state.GoToColumn(state.ColumnBeforeIndent);

View File

@@ -2,6 +2,8 @@
// This file is licensed under the BSD-Clause 2 license.
// See the license.txt file in the project root for more information.
#nullable enable
using Markdig.Helpers;
using Markdig.Syntax;
@@ -25,6 +27,6 @@ namespace Markdig.Parsers
/// <summary>
/// A delegates that allows to process attached attributes
/// </summary>
TryParseAttributesDelegate TryParseAttributes { get; set; }
TryParseAttributesDelegate? TryParseAttributes { get; set; }
}
}

View File

@@ -2,6 +2,8 @@
// This file is licensed under the BSD-Clause 2 license.
// See the license.txt file in the project root for more information.
#nullable enable
using Markdig.Syntax.Inlines;
namespace Markdig.Parsers
@@ -21,6 +23,6 @@ namespace Markdig.Parsers
/// <param name="isFinalProcessing"></param>
/// <returns><c>true</c> to continue to the next delimiter processor;
/// <c>false</c> to stop the process (in case a processor is performing sub-sequent processor itself)</returns>
bool PostProcess(InlineProcessor state, Inline root, Inline lastChild, int postInlineProcessorIndex, bool isFinalProcessing);
bool PostProcess(InlineProcessor state, Inline root, Inline? lastChild, int postInlineProcessorIndex, bool isFinalProcessing);
}
}

View File

@@ -2,6 +2,8 @@
// This file is licensed under the BSD-Clause 2 license.
// See the license.txt file in the project root for more information.
#nullable enable
using Markdig.Helpers;
using Markdig.Syntax;
using System.Collections.Generic;
@@ -52,7 +54,7 @@ namespace Markdig.Parsers
return result;
}
public override BlockState TryContinue(BlockProcessor processor, Block block)
public override BlockState TryContinue(BlockProcessor processor, Block? block)
{
if (!processor.IsCodeIndent || processor.IsBlankLine)
{

View File

@@ -2,6 +2,8 @@
// This file is licensed under the BSD-Clause 2 license.
// See the license.txt file in the project root for more information.
#nullable enable
using Markdig.Helpers;
namespace Markdig.Parsers

View File

@@ -2,6 +2,8 @@
// This file is licensed under the BSD-Clause 2 license.
// See the license.txt file in the project root for more information.
#nullable enable
using System;
using System.Collections.Generic;
using System.IO;
@@ -38,10 +40,10 @@ namespace Markdig.Parsers
/// <param name="trackTrivia">Whether to parse trivia such as whitespace, extra heading characters and unescaped string values.</param>
/// <exception cref="ArgumentNullException">
/// </exception>
public InlineProcessor(MarkdownDocument document, InlineParserList parsers, bool preciseSourcelocation, MarkdownParserContext context, bool trackTrivia = false)
public InlineProcessor(MarkdownDocument document, InlineParserList parsers, bool preciseSourcelocation, MarkdownParserContext? context, bool trackTrivia = false)
{
if (document == null) ThrowHelper.ArgumentNullException(nameof(document));
if (parsers == null) ThrowHelper.ArgumentNullException(nameof(parsers));
if (document is null) ThrowHelper.ArgumentNullException(nameof(document));
if (parsers is null) ThrowHelper.ArgumentNullException(nameof(parsers));
Document = document;
Parsers = parsers;
Context = context;
@@ -55,7 +57,7 @@ namespace Markdig.Parsers
/// <summary>
/// Gets the current block being processed.
/// </summary>
public LeafBlock Block { get; private set; }
public LeafBlock? Block { get; private set; }
/// <summary>
/// Gets a value indicating whether to provide precise source location.
@@ -65,17 +67,17 @@ namespace Markdig.Parsers
/// <summary>
/// Gets or sets the new block to replace the block being processed.
/// </summary>
public Block BlockNew { get; set; }
public Block? BlockNew { get; set; }
/// <summary>
/// Gets or sets the current inline. Used by <see cref="InlineParser"/> to return a new inline if match was successfull
/// </summary>
public Inline Inline { get; set; }
public Inline? Inline { get; set; }
/// <summary>
/// Gets the root container of the current <see cref="Block"/>.
/// </summary>
public ContainerInline Root { get; internal set; }
public ContainerInline? Root { get; internal set; }
/// <summary>
/// Gets the list of inline parsers.
@@ -85,7 +87,7 @@ namespace Markdig.Parsers
/// <summary>
/// Gets the parser context or <c>null</c> if none is available.
/// </summary>
public MarkdownParserContext Context { get; }
public MarkdownParserContext? Context { get; }
/// <summary>
/// Gets the root document.
@@ -100,12 +102,12 @@ namespace Markdig.Parsers
/// <summary>
/// Gets the parser states that can be used by <see cref="InlineParser"/> using their <see cref="ParserBase{Inline}.Index"/> property.
/// </summary>
public object[] ParserStates { get; }
public object?[] ParserStates { get; }
/// <summary>
/// Gets or sets the debug log writer. No log if null.
/// </summary>
public TextWriter DebugLog { get; set; }
public TextWriter? DebugLog { get; set; }
/// <summary>
/// True to parse trivia such as whitespace, extra heading characters and unescaped
@@ -118,7 +120,6 @@ namespace Markdig.Parsers
/// </summary>
public LiteralInlineParser LiteralInlineParser { get; }
public int GetSourcePosition(int sliceOffset)
{
return GetSourcePosition(sliceOffset, out int lineIndex, out int column);
@@ -308,7 +309,7 @@ namespace Markdig.Parsers
//}
}
public void PostProcessInlines(int startingIndex, Inline root, Inline lastChild, bool isFinalProcessing)
public void PostProcessInlines(int startingIndex, Inline root, Inline? lastChild, bool isFinalProcessing)
{
for (int i = startingIndex; i < Parsers.PostInlineProcessors.Length; i++)
{
@@ -322,7 +323,7 @@ namespace Markdig.Parsers
private ContainerInline FindLastContainer()
{
var container = Block.Inline;
var container = Block!.Inline;
for (int depth = 0; ; depth++)
{
if (container.LastChild is ContainerInline nextContainer && !nextContainer.IsClosed)

View File

@@ -2,6 +2,8 @@
// This file is licensed under the BSD-Clause 2 license.
// See the license.txt file in the project root for more information.
#nullable enable
using Markdig.Helpers;
using Markdig.Syntax;
using Markdig.Syntax.Inlines;

View File

@@ -9,7 +9,7 @@ namespace Markdig.Parsers.Inlines
/// <summary>
/// Descriptor for an emphasis.
/// </summary>
public class EmphasisDescriptor
public sealed class EmphasisDescriptor
{
/// <summary>
/// Initializes a new instance of the <see cref="EmphasisDescriptor"/> class.
@@ -33,21 +33,21 @@ namespace Markdig.Parsers.Inlines
/// <summary>
/// The character of this emphasis.
/// </summary>
public readonly char Character;
public char Character { get; }
/// <summary>
/// The minimum number of character this emphasis is expected to have (must be >=1)
/// </summary>
public readonly int MinimumCount;
public int MinimumCount { get; }
/// <summary>
/// The maximum number of character this emphasis is expected to have (must be >=1 and >= minimumCount)
/// </summary>
public readonly int MaximumCount;
public int MaximumCount { get; }
/// <summary>
/// This emphasis can be used within a word.
/// </summary>
public readonly bool EnableWithinWord;
public bool EnableWithinWord { get; }
}
}

View File

@@ -2,6 +2,8 @@
// This file is licensed under the BSD-Clause 2 license.
// See the license.txt file in the project root for more information.
#nullable enable
using System;
using System.Collections.Generic;
using System.Diagnostics;
@@ -19,7 +21,7 @@ namespace Markdig.Parsers.Inlines
/// <seealso cref="IPostInlineProcessor" />
public class EmphasisInlineParser : InlineParser, IPostInlineProcessor
{
private CharacterMap<EmphasisDescriptor> emphasisMap;
private CharacterMap<EmphasisDescriptor>? emphasisMap;
private readonly DelimitersObjectCache inlinesCache = new DelimitersObjectCache();
[Obsolete("Use TryCreateEmphasisInlineDelegate instead", error: false)]
@@ -64,7 +66,7 @@ namespace Markdig.Parsers.Inlines
/// Gets or sets the create emphasis inline delegate (allowing to create a different emphasis inline class)
/// </summary>
[Obsolete("Use TryCreateEmphasisInlineList instead", error: false)]
public CreateEmphasisInlineDelegate CreateEmphasisInline { get; set; }
public CreateEmphasisInlineDelegate? CreateEmphasisInline { get; set; }
public readonly List<TryCreateEmphasisInlineDelegate> TryCreateEmphasisInlineList = new List<TryCreateEmphasisInlineDelegate>();
public override void Initialize()
@@ -89,14 +91,14 @@ namespace Markdig.Parsers.Inlines
emphasisMap = new CharacterMap<EmphasisDescriptor>(tempMap);
}
public bool PostProcess(InlineProcessor state, Inline root, Inline lastChild, int postInlineProcessorIndex, bool isFinalProcessing)
public bool PostProcess(InlineProcessor state, Inline root, Inline? lastChild, int postInlineProcessorIndex, bool isFinalProcessing)
{
if (!(root is ContainerInline container))
{
return true;
}
List<EmphasisDelimiterInline> delimiters = null;
List<EmphasisDelimiterInline>? delimiters = null;
if (container is EmphasisDelimiterInline emphasisDelimiter)
{
delimiters = inlinesCache.Get();
@@ -139,7 +141,7 @@ namespace Markdig.Parsers.Inlines
// The amount of delimiter characters in the delimiter run may exceed emphasisDesc.MaximumCount, as that is handeled in `ProcessEmphasis`
var delimiterChar = slice.CurrentChar;
var emphasisDesc = emphasisMap[delimiterChar];
var emphasisDesc = emphasisMap![delimiterChar];
char pc = (char)0;
if (processor.Inline is HtmlEntityInline htmlEntityInline)
@@ -173,7 +175,7 @@ namespace Markdig.Parsers.Inlines
char c = slice.CurrentChar;
// The following character is actually an entity, we need to decode it
if (HtmlEntityParser.TryParse(ref slice, out string htmlString, out int htmlLength))
if (HtmlEntityParser.TryParse(ref slice, out string? htmlString, out int htmlLength))
{
c = htmlString[0];
}
@@ -218,7 +220,7 @@ namespace Markdig.Parsers.Inlines
{
var closeDelimiter = delimiters[i];
// Skip delimiters not supported by this instance
EmphasisDescriptor emphasisDesc = emphasisMap[closeDelimiter.DelimiterChar];
EmphasisDescriptor emphasisDesc = emphasisMap![closeDelimiter.DelimiterChar];
if (emphasisDesc == null)
{
continue;
@@ -230,7 +232,7 @@ namespace Markdig.Parsers.Inlines
{
// Now, look back in the stack (staying above stack_bottom and the openers_bottom for this delimiter type)
// for the first matching potential opener (“matching” means same delimiter).
EmphasisDelimiterInline openDelimiter = null;
EmphasisDelimiterInline? openDelimiter = null;
int openDelimiterIndex = -1;
for (int j = i - 1; j >= 0; j--)
{
@@ -260,7 +262,7 @@ namespace Markdig.Parsers.Inlines
int delimiterDelta = Math.Min(Math.Min(openDelimiter.DelimiterCount, closeDelimiter.DelimiterCount), emphasisDesc.MaximumCount);
// Insert an emph or strong emph node accordingly, after the text node corresponding to the opener.
EmphasisInline emphasis = null;
EmphasisInline? emphasis = null;
{
if (delimiterDelta <= 2) // We can try using the legacy delegate
{
@@ -293,7 +295,7 @@ namespace Markdig.Parsers.Inlines
var openDelimitercount = openDelimiter.DelimiterCount;
var closeDelimitercount = closeDelimiter.DelimiterCount;
emphasis.Span.Start = openDelimiter.Span.Start;
emphasis!.Span.Start = openDelimiter.Span.Start;
emphasis.Line = openDelimiter.Line;
emphasis.Column = openDelimiter.Column;
emphasis.Span.End = closeDelimiter.Span.End - closeDelimitercount + delimiterDelta;

View File

@@ -2,7 +2,11 @@
// This file is licensed under the BSD-Clause 2 license.
// See the license.txt file in the project root for more information.
#nullable enable
using System;
using System.Diagnostics.CodeAnalysis;
using Markdig.Helpers;
using Markdig.Syntax;
using Markdig.Syntax.Inlines;
@@ -24,7 +28,7 @@ namespace Markdig.Parsers.Inlines
}
public static bool TryParse(ref StringSlice slice, out string literal, out int match)
public static bool TryParse(ref StringSlice slice, [NotNullWhen(true)] out string? literal, out int match)
{
literal = null;
match = HtmlHelper.ScanEntity(slice, out int entityValue, out int entityNameStart, out int entityNameLength);
@@ -46,7 +50,7 @@ namespace Markdig.Parsers.Inlines
public override bool Match(InlineProcessor processor, ref StringSlice slice)
{
if (!TryParse(ref slice, out string literal, out int match))
if (!TryParse(ref slice, out string? literal, out int match))
{
return false;
}

View File

@@ -2,6 +2,8 @@
// This file is licensed under the BSD-Clause 2 license.
// See the license.txt file in the project root for more information.
#nullable enable
using Markdig.Helpers;
using Markdig.Syntax;
using Markdig.Syntax.Inlines;

View File

@@ -2,6 +2,8 @@
// This file is licensed under the BSD-Clause 2 license.
// See the license.txt file in the project root for more information.
#nullable enable
using Markdig.Helpers;
using Markdig.Syntax;
using Markdig.Syntax.Inlines;
@@ -41,7 +43,7 @@ namespace Markdig.Parsers.Inlines
return false;
}
}
string label;
string? label;
SourceSpan labelWithTriviaSpan = SourceSpan.Empty;
switch (c)
{
@@ -114,7 +116,7 @@ namespace Markdig.Parsers.Inlines
private bool ProcessLinkReference(
InlineProcessor state,
StringSlice text,
string label,
string? label,
SourceSpan labelWithriviaSpan,
bool isShortcut,
SourceSpan labelSpan,
@@ -127,7 +129,7 @@ namespace Markdig.Parsers.Inlines
return false;
}
Inline link = null;
Inline? link = null;
// Try to use a callback directly defined on the LinkReferenceDefinition
if (linkRef.CreateLinkInline != null)
{
@@ -200,7 +202,7 @@ namespace Markdig.Parsers.Inlines
private bool TryProcessLinkOrImage(InlineProcessor inlineState, ref StringSlice text)
{
LinkDelimiterInline openParent = inlineState.Inline.FirstParentOfType<LinkDelimiterInline>();
LinkDelimiterInline? openParent = inlineState.Inline!.FirstParentOfType<LinkDelimiterInline>();
if (openParent is null)
{
@@ -237,9 +239,9 @@ namespace Markdig.Parsers.Inlines
{
if (LinkHelper.TryParseInlineLinkTrivia(
ref text,
out string url,
out string? url,
out SourceSpan unescapedUrlSpan,
out string title,
out string? title,
out SourceSpan unescapedTitleSpan,
out char titleEnclosingCharacter,
out SourceSpan linkSpan,
@@ -297,7 +299,7 @@ namespace Markdig.Parsers.Inlines
}
else
{
if (LinkHelper.TryParseInlineLink(ref text, out string url, out string title, out SourceSpan linkSpan, out SourceSpan titleSpan))
if (LinkHelper.TryParseInlineLink(ref text, out string? url, out string? title, out SourceSpan linkSpan, out SourceSpan titleSpan))
{
// Inline Link
var link = new LinkInline()
@@ -338,7 +340,7 @@ namespace Markdig.Parsers.Inlines
}
var labelSpan = SourceSpan.Empty;
string label = null;
string? label = null;
SourceSpan labelWithTrivia = SourceSpan.Empty;
bool isLabelSpanLocal = true;
@@ -401,7 +403,7 @@ namespace Markdig.Parsers.Inlines
return false;
}
private void MarkParentAsInactive(Inline inline)
private void MarkParentAsInactive(Inline? inline)
{
while (inline != null)
{

View File

@@ -2,6 +2,8 @@
// This file is licensed under the BSD-Clause 2 license.
// See the license.txt file in the project root for more information.
#nullable enable
using System.Collections.Generic;
using Markdig.Helpers;
using Markdig.Syntax;
@@ -14,7 +16,7 @@ namespace Markdig.Parsers
/// <seealso cref="BlockParser" />
public class ListBlockParser : BlockParser
{
private CharacterMap<ListItemParser> mapItemParsers;
private CharacterMap<ListItemParser>? mapItemParsers;
/// <summary>
/// Initializes a new instance of the <see cref="ListBlockParser"/> class.
@@ -179,10 +181,10 @@ namespace Markdig.Parsers
return BlockState.None;
}
private BlockState TryParseListItem(BlockProcessor state, Block block)
private BlockState TryParseListItem(BlockProcessor state, Block? block)
{
var currentListItem = block as ListItemBlock;
var currentParent = block as ListBlock ?? (ListBlock)currentListItem?.Parent;
var currentParent = block as ListBlock ?? (ListBlock)currentListItem?.Parent!;
// We can early exit if we have a code indent and we are either (1) not in a ListItem, (2) preceded by a blank line, (3) in an unordered list
if (state.IsCodeIndent && (currentListItem is null || currentListItem.LastChild is BlankLineBlock || !currentParent.IsOrdered))
@@ -196,7 +198,7 @@ namespace Markdig.Parsers
var sourceEndPosition = state.Line.End;
var c = state.CurrentChar;
var itemParser = mapItemParsers[c];
var itemParser = mapItemParsers![c];
if (itemParser == null)
{
return BlockState.None;

View File

@@ -2,6 +2,8 @@
// This file is licensed under the BSD-Clause 2 license.
// See the license.txt file in the project root for more information.
#nullable enable
using System;
using System.Collections.Generic;
using Markdig.Helpers;
@@ -39,10 +41,10 @@ namespace Markdig.Parsers
/// <param name="context">A parser context used for the parsing.</param>
/// <exception cref="ArgumentNullException">
/// </exception>
private MarkdownParser(string text, MarkdownPipeline pipeline, MarkdownParserContext context)
private MarkdownParser(string text, MarkdownPipeline pipeline, MarkdownParserContext? context)
{
if (text == null) ThrowHelper.ArgumentNullException_text();
if (pipeline == null) ThrowHelper.ArgumentNullException(nameof(pipeline));
if (text is null) ThrowHelper.ArgumentNullException_text();
if (pipeline is null) ThrowHelper.ArgumentNullException(nameof(pipeline));
trackTrivia = pipeline.TrackTrivia;
roughLineCountEstimate = text.Length / 40;
@@ -73,7 +75,7 @@ namespace Markdig.Parsers
/// <param name="context">A parser context used for the parsing.</param>
/// <returns>An AST Markdown document</returns>
/// <exception cref="ArgumentNullException">if reader variable is null</exception>
public static MarkdownDocument Parse(string text, MarkdownPipeline pipeline = null, MarkdownParserContext context = null)
public static MarkdownDocument Parse(string text, MarkdownPipeline? pipeline = null, MarkdownParserContext? context = null)
{
if (text == null) ThrowHelper.ArgumentNullException_text();
pipeline ??= new MarkdownPipelineBuilder().Build();
@@ -118,8 +120,8 @@ namespace Markdig.Parsers
{
if (trackTrivia)
{
Block lastBlock = blockProcessor.LastBlock;
if (lastBlock == null && document.Count == 0)
Block? lastBlock = blockProcessor.LastBlock;
if (lastBlock is null && document.Count == 0)
{
// this means we have unassigned characters
var noBlocksFoundBlock = new EmptyBlock (null);
@@ -177,7 +179,7 @@ namespace Markdig.Parsers
{
process_new_block:
var item = blocks.Peek();
var container = item.Container;
var container = item.Container!;
for (; item.Index < container.Count; item.Index++)
{
@@ -222,14 +224,14 @@ namespace Markdig.Parsers
}
}
item = blocks.Pop();
container = item.Container;
container = item.Container!;
container.OnProcessInlinesEnd(inlineProcessor);
cache.Release(item);
}
}
private class ContainerItem
private sealed class ContainerItem
{
public ContainerItem()
{
@@ -240,9 +242,9 @@ namespace Markdig.Parsers
Container = container;
}
public ContainerBlock Container;
public ContainerBlock? Container { get; set; }
public int Index;
public int Index { get; set; }
}
}
}

View File

@@ -2,8 +2,9 @@
// This file is licensed under the BSD-Clause 2 license.
// See the license.txt file in the project root for more information.
#nullable enable
using Markdig.Helpers;
using System.Text;
namespace Markdig.Parsers
{

View File

@@ -2,9 +2,10 @@
// This file is licensed under the BSD-Clause 2 license.
// See the license.txt file in the project root for more information.
#nullable enable
using Markdig.Helpers;
using Markdig.Syntax;
using System.Diagnostics;
namespace Markdig.Parsers
{

View File

@@ -2,6 +2,8 @@
// This file is licensed under the BSD-Clause 2 license.
// See the license.txt file in the project root for more information.
#nullable enable
namespace Markdig.Parsers
{
/// <summary>
@@ -14,7 +16,7 @@ namespace Markdig.Parsers
/// <summary>
/// Gets the opening characters this parser will be triggered if the character is found.
/// </summary>
public char[] OpeningCharacters { get; set; }
public char[]? OpeningCharacters { get; set; }
/// <summary>
/// Initializes this parser with the specified parser processor.

View File

@@ -2,7 +2,8 @@
// This file is licensed under the BSD-Clause 2 license.
// See the license.txt file in the project root for more information.
using System;
#nullable enable
using System.Collections.Generic;
using System.Runtime.CompilerServices;
using Markdig.Helpers;
@@ -15,10 +16,10 @@ namespace Markdig.Parsers
/// <typeparam name="T">Type of the parser</typeparam>
/// <typeparam name="TState">The type of the parser state.</typeparam>
/// <seealso cref="OrderedList{T}" />
public abstract class ParserList<T, TState> : OrderedList<T> where T : ParserBase<TState>
public abstract class ParserList<T, TState> : OrderedList<T> where T : notnull, ParserBase<TState>
{
private readonly CharacterMap<T[]> charMap;
private readonly T[] globalParsers;
private readonly T[]? globalParsers;
protected ParserList(IEnumerable<T> parsersArg) : base(parsersArg)
{
@@ -28,7 +29,7 @@ namespace Markdig.Parsers
for (int i = 0; i < Count; i++)
{
var parser = this[i];
if (parser == null)
if (parser is null)
{
ThrowHelper.InvalidOperationException("Unexpected null parser found");
}
@@ -60,11 +61,11 @@ namespace Markdig.Parsers
var tempCharMap = new Dictionary<char, T[]>();
foreach (var parser in this)
{
if (parser.OpeningCharacters != null && parser.OpeningCharacters.Length != 0)
if (parser.OpeningCharacters is { Length: > 0 })
{
foreach (var openingChar in parser.OpeningCharacters)
{
if (!tempCharMap.TryGetValue(openingChar, out T[] parsers))
if (!tempCharMap.TryGetValue(openingChar, out T[]? parsers))
{
parsers = new T[charCounter[openingChar]];
tempCharMap[openingChar] = parsers;
@@ -77,7 +78,7 @@ namespace Markdig.Parsers
}
else
{
globalParsers[globalParsers.Length - globalCounter] = parser;
globalParsers![globalParsers.Length - globalCounter] = parser;
globalCounter--;
}
}
@@ -88,7 +89,7 @@ namespace Markdig.Parsers
/// <summary>
/// Gets the list of global parsers (that don't have any opening characters defined)
/// </summary>
public T[] GlobalParsers => globalParsers;
public T[]? GlobalParsers => globalParsers;
/// <summary>
/// Gets all the opening characters defined.

View File

@@ -2,9 +2,10 @@
// This file is licensed under the BSD-Clause 2 license.
// See the license.txt file in the project root for more information.
#nullable enable
using Markdig.Helpers;
using Markdig.Syntax;
using System.Diagnostics;
namespace Markdig.Parsers
{

View File

@@ -2,6 +2,8 @@
// This file is licensed under the BSD-Clause 2 license.
// See the license.txt file in the project root for more information.
#nullable enable
using Markdig.Helpers;
using Markdig.Syntax;

View File

@@ -2,6 +2,8 @@
// This file is licensed under the BSD-Clause 2 license.
// See the license.txt file in the project root for more information.
#nullable enable
using System;
using System.Collections.Generic;
using System.IO;
@@ -18,17 +20,17 @@ namespace Markdig.Syntax.Inlines
/// <summary>
/// Gets the parent container of this inline.
/// </summary>
public ContainerInline Parent { get; internal set; }
public ContainerInline? Parent { get; internal set; }
/// <summary>
/// Gets the previous inline.
/// </summary>
public Inline PreviousSibling { get; private set; }
public Inline? PreviousSibling { get; private set; }
/// <summary>
/// Gets the next sibling inline.
/// </summary>
public Inline NextSibling { get; internal set; }
public Inline? NextSibling { get; internal set; }
/// <summary>
/// Gets or sets a value indicating whether this instance is closed.
@@ -224,7 +226,7 @@ namespace Markdig.Syntax.Inlines
}
}
public T FirstParentOfType<T>() where T : Inline
public T? FirstParentOfType<T>() where T : notnull, Inline
{
var inline = this;
while (inline != null)
@@ -250,7 +252,7 @@ namespace Markdig.Syntax.Inlines
continue;
}
current = current.PreviousSibling;
current = current.PreviousSibling!;
}
return current;

View File

@@ -2,6 +2,8 @@
// This file is licensed under the BSD-Clause 2 license.
// See the license.txt file in the project root for more information.
#nullable enable
using Markdig.Helpers;
using System;
@@ -113,7 +115,7 @@ namespace Markdig.Syntax
/// <param name="key">The key.</param>
/// <returns>The associated data or null if none</returns>
/// <exception cref="ArgumentNullException">if key is null</exception>
public object GetData(object key)
public object? GetData(object key)
{
if (key == null) ThrowHelper.ArgumentNullException_key();
if (attachedDatas == null)
@@ -138,7 +140,7 @@ namespace Markdig.Syntax
/// <exception cref="ArgumentNullException"></exception>
public bool RemoveData(object key)
{
if (key == null) ThrowHelper.ArgumentNullException_key();
if (key is null) ThrowHelper.ArgumentNullException_key();
if (attachedDatas == null)
{
return true;