仿真平台内核初版 -tlib库 包含<sparc arm riscv powerPC>

This commit is contained in:
liuwb
2026-02-07 20:43:43 +08:00
parent de61f9e2b0
commit b3117648be
9748 changed files with 4309137 additions and 0 deletions

View File

@@ -0,0 +1,13 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>netstandard2.0</TargetFrameworks>
<IsPackable>false</IsPackable>
<EnforceExtendedAnalyzerRules>true</EnforceExtendedAnalyzerRules>
<RunAnalyzersDuringBuild>false</RunAnalyzersDuringBuild>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.CodeAnalysis.Analyzers" Version="3.3.4" />
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="3.9.0" />
<PackageReference Include="Microsoft.CodeAnalysis.CSharp.Workspaces" Version="3.9.0" />
</ItemGroup>
</Project>

View File

@@ -0,0 +1,22 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.0.31903.59
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Analyzers", "Analyzers.csproj", "{3BD152FA-6A0A-45E1-A570-0E9B8488030A}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{3BD152FA-6A0A-45E1-A570-0E9B8488030A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{3BD152FA-6A0A-45E1-A570-0E9B8488030A}.Debug|Any CPU.Build.0 = Debug|Any CPU
{3BD152FA-6A0A-45E1-A570-0E9B8488030A}.Release|Any CPU.ActiveCfg = Release|Any CPU
{3BD152FA-6A0A-45E1-A570-0E9B8488030A}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
EndGlobal

View File

@@ -0,0 +1,4 @@
<Project>
<!-- Empty default so that the upper level Directory.Build.targets is not used. -->
<!-- https://github.com/MicrosoftDocs/visualstudio-docs/blob/705d3b200e68e87d1070696cb6f483462c7be3e2/docs/msbuild/customize-your-build.md?plain=1#L42 -->
</Project>

View File

@@ -0,0 +1,247 @@
//
// Copyright (c) 2010-2025 Antmicro
//
// This file is licensed under the MIT License.
// Full license text is available in 'licenses/MIT.txt'.
//
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Linq;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.Diagnostics;
namespace Antmicro.Renode.CustomAnalyzers
{
[DiagnosticAnalyzer(LanguageNames.CSharp)]
public class RenodeClassMembersOrderAnalyzer : DiagnosticAnalyzer
{
public override ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics =>
ImmutableArray.Create(ClassMembersOrderRule);
public override void Initialize(AnalysisContext context)
{
context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.None);
context.EnableConcurrentExecution();
context.RegisterSyntaxTreeAction(CheckClassMembersOrder);
}
public const string DiagnosticId = "renode_class_members_order";
private void CheckClassMembersOrder(SyntaxTreeAnalysisContext context)
{
var classes = context
.Tree
.GetRoot()
.DescendantNodes()
.Where(node => node.IsKind(SyntaxKind.ClassDeclaration));
foreach(var cls in classes)
{
var declarations = cls
.ChildNodes()
.OfType<MemberDeclarationSyntax>();
var currentMember = ClassMemberOrder.StaticConstructor;
foreach(var declaration in declarations)
{
if(TryGetClassMemberOrder(declaration, out var nextMember))
{
if(nextMember < currentMember)
{
var diagnostic = Diagnostic.Create(
ClassMembersOrderRule,
declaration.GetLocation(),
new object[] {currentMember, nextMember}
);
context.ReportDiagnostic(diagnostic);
}
currentMember = nextMember;
}
}
}
}
public static bool TryGetClassMemberOrder(MemberDeclarationSyntax node, out ClassMemberOrder classMemberOrder)
{
var ignoredModifiers = ImmutableHashSet.Create
(
"async",
"extern",
"internal",
"override",
"partial",
"sealed",
"unsafe",
"virtual",
"volatile"
);
var modifiersOrder = new Dictionary<string, int>
{
{"public", 0},
{"protected", 0},
{"private", 0},
{"static", 1},
{"abstract", 2},
{"readonly", 3},
{"const", 3},
}.ToImmutableDictionary();
var modifiers = node
.Modifiers
.OrderBy(mod => modifiersOrder.GetValueOrDefault(mod.ToString(), -1))
.Aggregate("", (acc, val) => ignoredModifiers.Contains(val.ToString()) ? acc : $"{acc}_{val}");
var id = $"{modifiers}_{node.Kind()}";
if(ClassMembersOrderMap.TryGetValue(id, out classMemberOrder))
{
return true;
}
return false;
}
#pragma warning disable SA1509
// SA1509 - No space before opening braces
public static readonly Dictionary<string, ClassMemberOrder> ClassMembersOrderMap = new Dictionary<string, ClassMemberOrder>
{
{"_static_ConstructorDeclaration", ClassMemberOrder.StaticConstructor},
{"_public_static_MethodDeclaration", ClassMemberOrder.PublicStaticMethod},
{"_public_static_PropertyDeclaration", ClassMemberOrder.PublicStaticProperty},
{"_public_static_explicit_OperatorDeclaration", ClassMemberOrder.PublicStaticExplicitOperator},
{"_public_static_implicit_OperatorDeclaration", ClassMemberOrder.PublicStaticImplicitOperator},
{"_public_static_FieldDeclaration", ClassMemberOrder.PublicStaticField},
{"_public_ConstructorDeclaration", ClassMemberOrder.PublicConstructor},
{"_public_MethodDeclaration", ClassMemberOrder.PublicMethod},
{"_public_abstract_MethodDeclaration", ClassMemberOrder.PublicAbstractMethod},
{"_public_PropertyDeclaration", ClassMemberOrder.PublicProperty},
{"_public_abstract_PropertyDeclaration", ClassMemberOrder.PublicAbstractProperty},
{"_public_abstract_readonly_PropertyDeclaration", ClassMemberOrder.PublicAbstractProperty},
{"_public_EventFieldDeclaration", ClassMemberOrder.PublicEvent},
{"_public_FieldDeclaration", ClassMemberOrder.PublicField},
{"_public_readonly_FieldDeclaration", ClassMemberOrder.PublicReadonlyField},
{"_public_const_FieldDeclaration", ClassMemberOrder.PublicConst},
{"_protected_static_MethodDeclaration", ClassMemberOrder.ProtectedStaticMethod},
{"_protected_static_PropertyDeclaration", ClassMemberOrder.ProtectedStaticProperty},
{"_protected_static_explicit_OperatorDeclaration", ClassMemberOrder.ProtectedStaticExplicitOperator},
{"_protected_static_implicit_OperatorDeclaration", ClassMemberOrder.ProtectedStaticImplicitOperator},
{"_protected_static_FieldDeclaration", ClassMemberOrder.ProtectedStaticField},
{"_protected_ConstructorDeclaration", ClassMemberOrder.ProtectedConstructor},
{"_protected_MethodDeclaration", ClassMemberOrder.ProtectedMethod},
{"_protected_abstract_MethodDeclaration", ClassMemberOrder.ProtectedAbstractMethod},
{"_protected_PropertyDeclaration", ClassMemberOrder.ProtectedProperty},
{"_protected_abstract_PropertyDeclaration", ClassMemberOrder.ProtectedAbstractProperty},
{"_protected_abstract_readonly_PropertyDeclaration", ClassMemberOrder.ProtectedAbstractProperty},
{"_protected_EventFieldDeclaration", ClassMemberOrder.ProtectedEvent},
{"_protected_FieldDeclaration", ClassMemberOrder.ProtectedField},
{"_protected_readonly_FieldDeclaration", ClassMemberOrder.ProtectedReadonlyField},
{"_protected_const_FieldDeclaration", ClassMemberOrder.ProtectedConst},
{"_private_static_MethodDeclaration", ClassMemberOrder.PrivateStaticMethod},
{"_private_static_FieldDeclaration", ClassMemberOrder.PrivateStaticField},
{"_private_ConstructorDeclaration", ClassMemberOrder.PrivateConstructor},
{"_private_MethodDeclaration", ClassMemberOrder.PrivateMethod},
{"_private_abstract_MethodDeclaration", ClassMemberOrder.PrivateAbstractMethod},
{"_private_PropertyDeclaration", ClassMemberOrder.PrivateProperty},
{"_private_abstract_PropertyDeclaration", ClassMemberOrder.PrivateAbstractProperty},
{"_private_abstract_readonly_PropertyDeclaration", ClassMemberOrder.PrivateAbstractProperty},
{"_private_FieldDeclaration", ClassMemberOrder.PrivateField},
{"_private_readonly_FieldDeclaration", ClassMemberOrder.PrivateReadonlyField},
{"_private_const_FieldDeclaration", ClassMemberOrder.PrivateConst},
{"_public_ClassDeclaration", ClassMemberOrder.PublicClass},
{"_public_abstract_ClassDeclaration", ClassMemberOrder.PublicAbstractClass},
{"_public_StructDeclaration", ClassMemberOrder.PublicStruct},
{"_public_DelegateDeclaration", ClassMemberOrder.PublicDelegate},
{"_public_EnumDeclaration", ClassMemberOrder.PublicEnum},
{"_protected_ClassDeclaration", ClassMemberOrder.ProtectedClass},
{"_protected_abstract_ClassDeclaration", ClassMemberOrder.ProtectedAbstractClass},
{"_protected_StructDeclaration", ClassMemberOrder.ProtectedStruct},
{"_protected_DelegateDeclaration", ClassMemberOrder.ProtectedDelegate},
{"_protected_EnumDeclaration", ClassMemberOrder.ProtectedEnum},
{"_private_ClassDeclaration", ClassMemberOrder.PrivateClass},
{"_private_abstract_ClassDeclaration", ClassMemberOrder.PrivateAbstractClass},
{"_private_StructDeclaration", ClassMemberOrder.PrivateStruct},
{"_private_DelegateDeclaration", ClassMemberOrder.PrivateDelegate},
{"_private_EnumDeclaration", ClassMemberOrder.PrivateEnum},
};
#pragma warning restore SA1509
private static readonly DiagnosticDescriptor ClassMembersOrderRule = new DiagnosticDescriptor(
DiagnosticId,
"Class Members Order",
"Wrong Class Members Order: {1} should be placed before {0}",
"Design",
DiagnosticSeverity.Warning,
isEnabledByDefault: false,
description: "Checks if class members order is preserved."
);
// Order of fields in this Enum is important.
// It specifies allowed order of class members.
public enum ClassMemberOrder
{
StaticConstructor,
PublicStaticMethod,
PublicStaticProperty,
PublicStaticExplicitOperator,
PublicStaticImplicitOperator,
PublicStaticField,
PublicConstructor,
PublicMethod,
PublicAbstractMethod,
PublicProperty,
PublicAbstractProperty,
PublicEvent,
PublicField,
PublicReadonlyField,
PublicConst,
ProtectedStaticMethod,
ProtectedStaticProperty,
ProtectedStaticExplicitOperator,
ProtectedStaticImplicitOperator,
ProtectedStaticField,
ProtectedConstructor,
ProtectedMethod,
ProtectedAbstractMethod,
ProtectedProperty,
ProtectedAbstractProperty,
ProtectedEvent,
ProtectedField,
ProtectedReadonlyField,
ProtectedConst,
PrivateStaticMethod,
PrivateStaticField,
PrivateConstructor,
PrivateMethod,
PrivateAbstractMethod,
PrivateProperty,
PrivateAbstractProperty,
PrivateField,
PrivateReadonlyField,
PrivateConst,
PublicClass,
PublicAbstractClass,
PublicStruct,
PublicDelegate,
PublicEnum,
ProtectedClass,
ProtectedAbstractClass,
ProtectedStruct,
ProtectedDelegate,
ProtectedEnum,
PrivateClass,
PrivateAbstractClass,
PrivateStruct,
PrivateDelegate,
PrivateEnum,
}
}
}

View File

@@ -0,0 +1,217 @@
//
// Copyright (c) 2010-2025 Antmicro
//
// This file is licensed under the MIT License.
// Full license text is available in 'licenses/MIT.txt'.
//
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Composition;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CodeActions;
using Microsoft.CodeAnalysis.CodeFixes;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.Editing;
namespace Antmicro.Renode.CustomAnalyzers
{
[ExportCodeFixProvider(LanguageNames.CSharp, Name = nameof(RenodeClassMembersOrderFixProvider)), Shared]
public class RenodeClassMembersOrderFixProvider : CodeFixProvider
{
public sealed override ImmutableArray<string> FixableDiagnosticIds =>
ImmutableArray.Create(RenodeClassMembersOrderAnalyzer.DiagnosticId);
public override FixAllProvider GetFixAllProvider() =>
FixAllProvider.Create(async (context, document, _) =>
await FixDocumentClassMembersOrder(document, context.CancellationToken).ConfigureAwait(false));
public override Task RegisterCodeFixesAsync(CodeFixContext context)
{
var document = context.Document;
// We have only one entry in FixableDiagnosticIds,
// so there should be just one entry on the list.
var diagnostic = context.Diagnostics.First();
var codeAction = CodeAction.Create(
title: "Fix Renode class member order",
createChangedDocument: c => FixSingleClassMemberOrder(document, diagnostic, c),
equivalenceKey: "RenodeClassMemberOrder"
);
context.RegisterCodeFix(codeAction, diagnostic);
return Task.CompletedTask;
}
private async Task<Document> FixDocumentClassMembersOrder(
Document document,
CancellationToken cancellationToken
)
{
var editor = await DocumentEditor.CreateAsync(document, cancellationToken);
// This fix provider is capable of fixing members order also within nested calsses, on arbitrary level.
// In order to do so, it must handle nested classes first. Since we list members recursively
// in document prefix order, we just have to reverse list to start with nested classes.
var classes = editor
.OriginalRoot
.DescendantNodes()
.Where(node => node.IsKind(SyntaxKind.ClassDeclaration))
.Reverse();
foreach(var cls in classes)
{
var currentRoot = editor.GetChangedRoot();
var declarations = cls
.ChildNodes()
.OfType<MemberDeclarationSyntax>();
// We first find all misplaced members and remove them from tree.
// When we reinsert removed nodes to tree, they are treated as new nodes, so we cannot reference them
// in tree operations (i.e. we cannot use them as reference when inserting new nodes).
// We also remember all well ordered nodes to use them as references when we reinsert misplaced nodes.
var wellOrderedMembers = new List<MemberDeclarationSyntax>();
var misplacedMembers = new List<MemberDeclarationSyntax>();
var currentMember = RenodeClassMembersOrderAnalyzer.ClassMemberOrder.StaticConstructor;
foreach(var declaration in declarations)
{
if(RenodeClassMembersOrderAnalyzer.TryGetClassMemberOrder(declaration, out var nextMember))
{
if(nextMember < currentMember)
{
misplacedMembers.Add(declaration);
editor.RemoveNode(declaration, SyntaxRemoveOptions.KeepNoTrivia);
}
else
{
wellOrderedMembers.Add(declaration);
currentMember = nextMember;
}
}
}
// This class already satisfies Renode class members order rule
if(misplacedMembers.Count == 0)
{
continue;
}
// We know that this class content will be modified, so we want to track this class
// in case we need to move it later
editor.TrackNode(cls);
// At this point all members stored in wellOrderedMembers and misplacedMembers
// have corresponding ClassMemberOrder, so we no longer need to check every call
// to RenodeClassMembersOrderAnalyzer.TryGetClassMemberOrder.
misplacedMembers.Sort((lhs, rhs) =>
{
RenodeClassMembersOrderAnalyzer.TryGetClassMemberOrder(lhs, out var lhsOrder);
RenodeClassMembersOrderAnalyzer.TryGetClassMemberOrder(rhs, out var rhsOrder);
return lhsOrder.CompareTo(rhsOrder);
});
// If we are here, we know that there is at least one correct memeber and at least one misplaced member.
// So calling MoveNext on Enumerator is safe.
var correctMemberEnumerator = wellOrderedMembers.GetEnumerator();
correctMemberEnumerator.MoveNext();
var correctMember = correctMemberEnumerator.Current;
RenodeClassMembersOrderAnalyzer.TryGetClassMemberOrder(correctMember, out var correctOrder);
// We keep last valid order to easily break loop
RenodeClassMembersOrderAnalyzer.TryGetClassMemberOrder(wellOrderedMembers.Last(), out var lastCorrectOrder);
foreach(var misplacedMember in misplacedMembers)
{
RenodeClassMembersOrderAnalyzer.TryGetClassMemberOrder(misplacedMember, out var misplacedOrder);
if(misplacedOrder > lastCorrectOrder)
{
break;
}
while(misplacedOrder > correctOrder)
{
correctMemberEnumerator.MoveNext();
correctMember = correctMemberEnumerator.Current;
RenodeClassMembersOrderAnalyzer.TryGetClassMemberOrder(correctMember, out correctOrder);
}
var upToDateMember = currentRoot.GetCurrentNode(misplacedMember) ?? misplacedMember;
editor.InsertBefore(correctMember, upToDateMember);
}
// correctMember now points to the last valid member.
// We have to perform InsertAfter on remaining misplaced nodes
// in reverse order to keep valid members order.
misplacedMembers.Reverse();
foreach(var misplacedMember in misplacedMembers)
{
RenodeClassMembersOrderAnalyzer.TryGetClassMemberOrder(misplacedMember, out var misplacedOrder);
if(misplacedOrder <= lastCorrectOrder)
{
break;
}
var upToDateMember = currentRoot.GetCurrentNode(misplacedMember) ?? misplacedMember;
editor.InsertAfter(correctMember, upToDateMember);
}
}
return editor.GetChangedDocument();
}
private async Task<Document> FixSingleClassMemberOrder(
Document document,
Diagnostic diagnostic,
CancellationToken cancellationToken
)
{
var editor = await DocumentEditor.CreateAsync(document, cancellationToken);
var root = editor.OriginalRoot;
var misplacedDeclaration = root
.FindToken(diagnostic.Location.SourceSpan.Start)
.Parent
.AncestorsAndSelf()
.OfType<MemberDeclarationSyntax>()
.First();
if(!RenodeClassMembersOrderAnalyzer.TryGetClassMemberOrder(misplacedDeclaration, out var misplacedOrder))
{
return document;
}
var classMembers = misplacedDeclaration
.Parent
.ChildNodes()
.OfType<MemberDeclarationSyntax>();
editor.RemoveNode(misplacedDeclaration, SyntaxRemoveOptions.KeepNoTrivia);
var successor = classMembers
.FirstOrDefault(
node => RenodeClassMembersOrderAnalyzer.TryGetClassMemberOrder(node, out var correctOrder) && misplacedOrder <= correctOrder);
// If there isn't any member, that is greater or equal than misplaced declaration,
// then it must be last declaration.
if(successor == null)
{
editor.InsertAfter(classMembers.Last(), misplacedDeclaration);
}
else
{
editor.InsertBefore(successor, misplacedDeclaration);
}
return editor.GetChangedDocument();
}
}
}

View File

@@ -0,0 +1,156 @@
//
// Copyright (c) 2010-2025 Antmicro
//
// This file is licensed under the MIT License.
// Full license text is available in 'licenses/MIT.txt'.
//
using System;
using System.Collections.Immutable;
using System.Linq;
using System.Text.RegularExpressions;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.Diagnostics;
namespace Antmicro.Renode.CustomAnalyzers
{
[DiagnosticAnalyzer(LanguageNames.CSharp)]
public class RenodeCopyrightAnalyzer : DiagnosticAnalyzer
{
public override ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics =>
ImmutableArray.Create(CopyrightDateRule, CopyrightFormatRule);
public override void Initialize(AnalysisContext context)
{
context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.None);
context.EnableConcurrentExecution();
context.RegisterSyntaxTreeAction(CheckCopyrights);
}
private void CheckCopyrights(SyntaxTreeAnalysisContext context)
{
var comments = context
.Tree
.GetRoot()
.DescendantTrivia()
.Where(node => node.IsKind(SyntaxKind.SingleLineCommentTrivia))
.ToArray();
var commentIdx = 0;
for(var templateIdx = 0; templateIdx < CopyrightTemplate.Length; ++templateIdx)
{
// We don't have any more comments to check
if(commentIdx >= comments.Length)
{
context.ReportDiagnostic(Diagnostic.Create(CopyrightFormatRule, location: null));
return;
}
var comment = comments[commentIdx];
var content = comment.ToString();
var commentLine = comment
.GetLocation()
.GetLineSpan()
.StartLinePosition
.Line;
// copyright line might be correct, but it's on wrong line
if(commentLine != commentIdx)
{
context.ReportDiagnostic(Diagnostic.Create(CopyrightFormatRule, location: null));
}
switch(templateIdx)
{
case AntmicroCopyrightLine:
CheckAntmicroCopyrights(context, comment);
break;
case AdditionalCopyrightLine:
if(CheckAdditionalCopyrights(comment))
{
// We found additional copyright, but we adjust templateIdx
// because we don't know how many there will be.
templateIdx--;
}
else
{
// We end up pointing to the line after additional copyrights.
// Let's adjust pointer to not skip any line.
commentIdx--;
}
break;
default:
if(content != CopyrightTemplate[templateIdx])
{
context.ReportDiagnostic(Diagnostic.Create(CopyrightFormatRule, comment.GetLocation()));
}
break;
}
commentIdx++;
}
}
private void CheckAntmicroCopyrights(SyntaxTreeAnalysisContext context, SyntaxTrivia commentNode)
{
var content = commentNode.ToString();
var regex = new Regex(CopyrightTemplate[AntmicroCopyrightLine]);
var match = regex.Match(content);
if(match.Success)
{
var copyrightYear = match.Groups[1].Value;
var currentYear = DateTime.Today.Year.ToString();
if(copyrightYear != currentYear)
{
context.ReportDiagnostic(Diagnostic.Create(CopyrightDateRule, commentNode.GetLocation()));
}
}
else
{
context.ReportDiagnostic(Diagnostic.Create(CopyrightFormatRule, commentNode.GetLocation()));
}
}
private bool CheckAdditionalCopyrights(SyntaxTrivia commentNode)
{
var content = commentNode.ToString();
var regex = new Regex(CopyrightTemplate[AdditionalCopyrightLine]);
var match = regex.Match(content);
return match.Success;
}
private static readonly DiagnosticDescriptor CopyrightDateRule = new DiagnosticDescriptor(
"renode_copyright",
"Copyright Date",
"Copyright is not up to date",
"License",
DiagnosticSeverity.Warning,
isEnabledByDefault: false,
description: "Ensure that copyrights are up to date."
);
private static readonly DiagnosticDescriptor CopyrightFormatRule = new DiagnosticDescriptor(
"renode_copyright",
"Copyright Format",
"Wrong copyright format",
"License",
DiagnosticSeverity.Warning,
isEnabledByDefault: false,
description: "Ensure that copyrights are in correct format."
);
private static readonly string[] CopyrightTemplate = {
"//",
@"// Copyright \(c\) 2010-(\d+) Antmicro",
@"// Copyright \(c\) .*",
"//",
"// This file is licensed under the MIT License.",
"// Full license text is available in 'licenses/MIT.txt'.",
"//"
};
private const int AntmicroCopyrightLine = 1;
private const int AdditionalCopyrightLine = 2;
}
}