Browse Source

Now somewhat compiling control catalog, PEVerify complains about assigning null to Nullable<T>

xamlil-debug-info
Nikita Tsukanov 7 years ago
parent
commit
cd93624f3e
  1. 7
      packages/Avalonia/AvaloniaBuildTasks.targets
  2. 2
      samples/ControlCatalog/SideBar.xaml
  3. 13
      src/Avalonia.Build.Tasks/CompileAvaloniaXamlTask.cs
  4. 4
      src/Avalonia.Build.Tasks/Program.cs
  5. 79
      src/Avalonia.Build.Tasks/XamlCompilerTaskExecutor.cs
  6. 1
      src/Avalonia.Themes.Default/Avalonia.Themes.Default.csproj
  7. 2
      src/Markup/Avalonia.Markup.Xaml/XamlIl/xamlil.github

7
packages/Avalonia/AvaloniaBuildTasks.targets

@ -37,14 +37,14 @@
EmbeddedResources="@(EmbeddedResources)"/>
<Exec
Condition="'$(_AvaloniaUseExternalMSBuild)' == 'true'"
Command="dotnet msbuild /nodereuse:false $(MSBuildProjectFile) /t:GenerateAvaloniaResources /p:_AvaloniaForceInternalMSBuild=true /p:Configuration=$(Configuration)"/>
Command="dotnet msbuild /nodereuse:false $(MSBuildProjectFile) /t:GenerateAvaloniaResources /p:_AvaloniaForceInternalMSBuild=true /p:Configuration=$(Configuration) /p:BuildProjectReferences=false"/>
</Target>
<Target
Name="CompileAvaloniaXaml"
AfterTargets="AfterCompile"
Condition="Exists('@(IntermediateAssembly)') And $(DesignTimeBuild) != true And $(EnableAvaloniaXamlCompilation) == true"
Condition="Exists('@(IntermediateAssembly)') And $(DesignTimeBuild) != true And $(EnableAvaloniaXamlCompilation) != false"
Inputs="@(IntermediateAssembly);"
Outputs="$(IntermediateOutputPath)$(MSBuildProjectFile).Fody.CopyLocal.cache">
<PropertyGroup>
@ -61,10 +61,11 @@
AssemblyFile="@(IntermediateAssembly)"
ReferencesFilePath="$(AvaloniaXamlReferencesTemporaryFilePath)"
OriginalCopyPath="$(AvaloniaXamlOriginalCopyFilePath)"
ProjectDirectory="$(MSBuildProjectDirectory)"
/>
<Exec
Condition="'$(_AvaloniaUseExternalMSBuild)' == 'true'"
Command="dotnet msbuild /nodereuse:false $(MSBuildProjectFile) /t:CompileAvaloniaXaml /p:_AvaloniaForceInternalMSBuild=true /p:Configuration=$(Configuration)"/>
Command="dotnet msbuild /nodereuse:false $(MSBuildProjectFile) /t:CompileAvaloniaXaml /p:_AvaloniaForceInternalMSBuild=true /p:Configuration=$(Configuration) /p:BuildProjectReferences=false"/>
</Target>

2
samples/ControlCatalog/SideBar.xaml

@ -1,6 +1,6 @@
<Styles xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="ControlCatalog.SideBar">
>
<Design.PreviewWith>
<Border Padding="20">
<TabControl Classes="sidebar">

13
src/Avalonia.Build.Tasks/CompileAvaloniaXamlTask.cs

@ -21,12 +21,15 @@ namespace Avalonia.Build.Tasks
File.Delete(AssemblyFile);
}
var data = XamlCompilerTaskExecutor.Compile(BuildEngine, input,
File.ReadAllLines(ReferencesFilePath).Where(l => !string.IsNullOrWhiteSpace(l)).ToArray());
if(data == null)
var res = XamlCompilerTaskExecutor.Compile(BuildEngine, input,
File.ReadAllLines(ReferencesFilePath).Where(l => !string.IsNullOrWhiteSpace(l)).ToArray(),
ProjectDirectory);
if (!res.Success)
return false;
if (res.Data == null)
File.Copy(input, OutputPath);
else
File.WriteAllBytes(OutputPath, data);
File.WriteAllBytes(OutputPath, res.Data);
return true;
}
@ -39,6 +42,8 @@ namespace Avalonia.Build.Tasks
public string ReferencesFilePath { get; set; }
[Required]
public string OriginalCopyPath { get; set; }
[Required]
public string ProjectDirectory { get; set; }
public string OutputPath { get; set; }

4
src/Avalonia.Build.Tasks/Program.cs

@ -1,5 +1,6 @@
using System;
using System.Collections;
using System.IO;
using Microsoft.Build.Framework;
namespace Avalonia.Build.Tasks
@ -19,7 +20,8 @@ namespace Avalonia.Build.Tasks
AssemblyFile = args[0],
ReferencesFilePath = args[1],
OutputPath = args[2],
BuildEngine = new ConsoleBuildEngine()
BuildEngine = new ConsoleBuildEngine(),
ProjectDirectory = Directory.GetCurrentDirectory()
}.Execute() ?
0 :
2;

79
src/Avalonia.Build.Tasks/XamlCompilerTaskExecutor.cs

@ -10,6 +10,8 @@ using Mono.Cecil;
using XamlIl.TypeSystem;
using Avalonia.Utilities;
using Mono.Cecil.Rocks;
using XamlIl;
using XamlIl.Ast;
using XamlIl.Parsers;
using XamlIl.Transform;
using TypeAttributes = Mono.Cecil.TypeAttributes;
@ -47,7 +49,19 @@ namespace Avalonia.Build.Tasks
return rv;
}
public static byte[] Compile(IBuildEngine engine, string input, string[] references)
public class CompileResult
{
public bool Success { get; set; }
public byte[] Data { get; set; }
public CompileResult(bool success, byte[] data = null)
{
Success = success;
Data = data;
}
}
public static CompileResult Compile(IBuildEngine engine, string input, string[] references, string projectDirectory)
{
var typeSystem = new CecilTypeSystem(references.Concat(new[] {input}), input);
var asm = typeSystem.TargetAssemblyDefinition;
@ -55,7 +69,7 @@ namespace Avalonia.Build.Tasks
var avares = ReadAvaloniaXamlResources(asm);
if (avares.Count == 0 && emres.Count == 0)
// Nothing to do
return null;
return new CompileResult(true);
var xamlLanguage = AvaloniaXamlIlLanguage.Configure(typeSystem);
var compilerConfig = new XamlIlTransformerConfiguration(typeSystem,
typeSystem.TargetAssembly,
@ -80,7 +94,8 @@ namespace Avalonia.Build.Tasks
asm.MainModule.ImportReference(editorBrowsableAttribute.GetConstructors()
.First(c => c.Parameters.Count == 1));
void CompileGroup(Dictionary<string, byte[]> resources, string name, Func<string, string> uriTransform)
bool CompileGroup(Dictionary<string, byte[]> resources, string name, Func<string, string> uriTransform,
Func<string, string> pathTransform)
{
var typeDef = new TypeDefinition("CompiledAvaloniaXaml", name,
TypeAttributes.Class, asm.MainModule.TypeSystem.Object);
@ -94,23 +109,63 @@ namespace Avalonia.Build.Tasks
var builder = typeSystem.CreateTypeBuilder(typeDef);
foreach (var res in resources)
{
var xaml = Encoding.UTF8.GetString(res.Value);
var parsed = XDocumentXamlIlParser.Parse(xaml);
compiler.Transform(parsed);
compiler.Compile(parsed, builder, contextClass,
"Populate:" + res.Key, "Build:" + res.Key,
"NamespaceInfo:" + res.Key, uriTransform(res.Key));
try
{
// StreamReader is needed here to handle BOM
var xaml = new StreamReader(new MemoryStream(res.Value)).ReadToEnd();
var parsed = XDocumentXamlIlParser.Parse(xaml);
var initialRoot = (XamlIlAstObjectNode)parsed.Root;
var classDirective = initialRoot.Children.OfType<XamlIlAstXmlDirective>()
.FirstOrDefault(d => d.Namespace == XamlNamespaces.Xaml2006 && d.Name == "Class");
if (classDirective != null)
{
if (classDirective.Values.Count != 1 || !(classDirective.Values[0] is XamlIlAstTextNode tn))
throw new XamlIlParseException("x:Class should have a string value", classDirective);
var classType = typeSystem.TargetAssembly.FindType(tn.Text);
if (classType == null)
throw new XamlIlParseException($"Unable to find type `{tn.Text}`", classDirective);
initialRoot.Type = new XamlIlAstClrTypeReference(classDirective, classType);
}
compiler.Transform(parsed);
compiler.Compile(parsed, builder, contextClass,
"Populate:" + res.Key, "Build:" + res.Key,
"NamespaceInfo:" + res.Key, uriTransform(res.Key));
}
catch (Exception e)
{
int lineNumber = 0, linePosition = 0;
if (e is XamlIlParseException xe)
{
lineNumber = xe.Line;
linePosition = xe.Position;
}
engine.LogErrorEvent(new BuildErrorEventArgs("Avalonia", "XAMLIL", pathTransform(res.Key),
lineNumber, linePosition, lineNumber, linePosition,
e.Message, "", "Avalonia"));
return false;
}
}
return true;
}
if (emres.Count != 0)
CompileGroup(emres, "EmbeddedResource", name => $"resm:{name}?assembly={asm.Name}");
if (!CompileGroup(emres, "EmbeddedResource",
name => $"resm:{name}?assembly={asm.Name}", name => name))
return new CompileResult(false);
if (avares.Count != 0)
CompileGroup(avares, "AvaloniaResource", name => $"avares://{asm.Name}/{name}");
if (!CompileGroup(avares, "AvaloniaResource",
name => $"avares://{asm.Name}/{name}",
name => Path.Combine(projectDirectory, name.TrimStart('/'))))
return new CompileResult(false);
var ms = new MemoryStream();
asm.Write(ms);
return ms.ToArray();
return new CompileResult(true, ms.ToArray());
}
}

1
src/Avalonia.Themes.Default/Avalonia.Themes.Default.csproj

@ -1,7 +1,6 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<EnableAvaloniaXamlCompilation>true</EnableAvaloniaXamlCompilation>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\Markup\Avalonia.Markup.Xaml\Avalonia.Markup.Xaml.csproj" />

2
src/Markup/Avalonia.Markup.Xaml/XamlIl/xamlil.github

@ -1 +1 @@
Subproject commit ddc2490b8f0437c42c9bc4662b25c2f693255278
Subproject commit 570fa4d67ed0da7fc5b6e36c3100f0ccbba5aa5a
Loading…
Cancel
Save