зеркало из https://github.com/DeGsoft/maui-linux.git
[X] RegisterSourceInfo for XamlC (#8579)
When compiling in DEBUG, Register sourceInfo even for compiled code
This commit is contained in:
Родитель
5bee239756
Коммит
7573226b58
|
@ -506,7 +506,7 @@ namespace Xamarin.Forms.Build.Tasks
|
|||
}
|
||||
break;
|
||||
case "System.Uri":
|
||||
if (hasValue && Uri.TryCreate(valueString, UriKind.RelativeOrAbsolute, out Uri outuri)) {
|
||||
if (hasValue && Uri.TryCreate(valueString, UriKind.RelativeOrAbsolute, out _)) {
|
||||
var vardef = new VariableDefinition(module.ImportReference(("System", "System", "Uri")));
|
||||
Context.Body.Variables.Add(vardef);
|
||||
//Use an extra temp var so we can push the value to the stack, just like other cases
|
||||
|
|
|
@ -39,5 +39,7 @@ namespace Xamarin.Forms.Build.Tasks
|
|||
public MethodBody Body { get; private set; }
|
||||
|
||||
public ModuleDefinition Module { get; private set; }
|
||||
public bool DefineDebug { get; internal set; }
|
||||
public string XamlFilePath { get; internal set; }
|
||||
}
|
||||
}
|
|
@ -6,7 +6,7 @@ namespace Xamarin.Forms.Build.Tasks
|
|||
{
|
||||
class ILRootNode : RootNode
|
||||
{
|
||||
public ILRootNode(XmlType xmlType, TypeReference typeReference, IXmlNamespaceResolver nsResolver) : base(xmlType, nsResolver)
|
||||
public ILRootNode(XmlType xmlType, TypeReference typeReference, IXmlNamespaceResolver nsResolver, int linenumber = -1, int lineposition = -1) : base(xmlType, nsResolver, linenumber: linenumber, lineposition: lineposition)
|
||||
{
|
||||
TypeReference = typeReference;
|
||||
}
|
||||
|
|
|
@ -858,18 +858,18 @@ namespace Xamarin.Forms.Build.Tasks
|
|||
// IL_008e: newobj instance void class [mscorlib]System.Tuple`2<class [mscorlib]System.Func`2<class ViewModel, object>, string>::'.ctor'(!0, !1)
|
||||
// IL_0093: stelem.ref
|
||||
|
||||
yield return Instruction.Create(OpCodes.Ldc_I4, properties.Count);
|
||||
yield return Instruction.Create(OpCodes.Newarr, tupleRef);
|
||||
yield return Create(Ldc_I4, properties.Count);
|
||||
yield return Create(Newarr, tupleRef);
|
||||
|
||||
for (var i = 0; i < properties.Count; i++) {
|
||||
yield return Instruction.Create(OpCodes.Dup);
|
||||
yield return Instruction.Create(OpCodes.Ldc_I4, i);
|
||||
yield return Instruction.Create(OpCodes.Ldnull);
|
||||
yield return Instruction.Create(OpCodes.Ldftn, partGetters [i]);
|
||||
yield return Instruction.Create(OpCodes.Newobj, module.ImportReference(funcCtor));
|
||||
yield return Instruction.Create(OpCodes.Ldstr, properties [i].Item1.Name);
|
||||
yield return Instruction.Create(OpCodes.Newobj, module.ImportReference(tupleCtor));
|
||||
yield return Instruction.Create(OpCodes.Stelem_Ref);
|
||||
yield return Create(Dup);
|
||||
yield return Create(Ldc_I4, i);
|
||||
yield return Create(Ldnull);
|
||||
yield return Create(Ldftn, partGetters [i]);
|
||||
yield return Create(Newobj, module.ImportReference(funcCtor));
|
||||
yield return Create(Ldstr, properties [i].Item1.Name);
|
||||
yield return Create(Newobj, module.ImportReference(tupleCtor));
|
||||
yield return Create(Stelem_Ref);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -892,19 +892,55 @@ namespace Xamarin.Forms.Build.Tasks
|
|||
|
||||
//If it's a BP, SetValue ()
|
||||
if (CanSetValue(bpRef, attached, valueNode, iXmlLineInfo, context))
|
||||
return SetValue(parent, bpRef, valueNode, iXmlLineInfo, context);
|
||||
return SetValue(parent, bpRef, valueNode, iXmlLineInfo, context).Concat(RegisterSourceInfo(context, valueNode));
|
||||
|
||||
//If it's a property, set it
|
||||
if (CanSet(parent, localName, valueNode, context))
|
||||
return Set(parent, localName, valueNode, iXmlLineInfo, context);
|
||||
return Set(parent, localName, valueNode, iXmlLineInfo, context).Concat(RegisterSourceInfo(context, valueNode));
|
||||
|
||||
//If it's an already initialized property, add to it
|
||||
if (CanAdd(parent, propertyName, valueNode, iXmlLineInfo, context))
|
||||
return Add(parent, propertyName, valueNode, iXmlLineInfo, context);
|
||||
return Add(parent, propertyName, valueNode, iXmlLineInfo, context).Concat(RegisterSourceInfo(context, valueNode));
|
||||
|
||||
throw new XamlParseException($"No property, bindable property, or event found for '{localName}', or mismatching type between value and property.", iXmlLineInfo);
|
||||
}
|
||||
|
||||
internal static IEnumerable<Instruction> RegisterSourceInfo(ILContext context, INode valueNode)
|
||||
{
|
||||
if (!context.DefineDebug)
|
||||
yield break;
|
||||
if (!(valueNode is IXmlLineInfo lineInfo))
|
||||
yield break;
|
||||
if (!(valueNode is IElementNode elementNode))
|
||||
yield break;
|
||||
if (context.Variables[elementNode].VariableType.IsValueType)
|
||||
yield break;
|
||||
|
||||
var module = context.Body.Method.Module;
|
||||
|
||||
yield return Create(Ldloc, context.Variables[elementNode]); //target
|
||||
|
||||
yield return Create(Ldstr, context.XamlFilePath);
|
||||
yield return Create(Ldc_I4, (int)UriKind.RelativeOrAbsolute);
|
||||
yield return Create(Newobj, module.ImportCtorReference(("System", "System", "Uri"),
|
||||
parameterTypes: new[] {
|
||||
("mscorlib", "System", "String"),
|
||||
("System", "System", "UriKind"),
|
||||
})); //uri
|
||||
|
||||
yield return Create(Ldc_I4, lineInfo.LineNumber); //lineNumber
|
||||
yield return Create(Ldc_I4, lineInfo.LinePosition); //linePosition
|
||||
|
||||
yield return Create(Call, module.ImportMethodReference(("Xamarin.Forms.Xaml", "Xamarin.Forms.Xaml.Diagnostics", "VisualDiagnostics"),
|
||||
methodName: "RegisterSourceInfo",
|
||||
parameterTypes: new[] {
|
||||
("mscorlib", "System", "Object"),
|
||||
("System", "System", "Uri"),
|
||||
("mscorlib", "System", "Int32"),
|
||||
("mscorlib", "System", "Int32")},
|
||||
isStatic: true));
|
||||
}
|
||||
|
||||
public static IEnumerable<Instruction> GetPropertyValue(VariableDefinition parent, XmlName propertyName, ILContext context, IXmlLineInfo lineInfo, out TypeReference propertyType)
|
||||
{
|
||||
var module = context.Body.Method.Module;
|
||||
|
@ -1492,7 +1528,9 @@ namespace Xamarin.Forms.Build.Tasks
|
|||
templateIl.Emit(OpCodes.Nop);
|
||||
var templateContext = new ILContext(templateIl, loadTemplate.Body, module, parentValues)
|
||||
{
|
||||
Root = root
|
||||
Root = root,
|
||||
DefineDebug = parentContext.DefineDebug,
|
||||
XamlFilePath = parentContext.XamlFilePath,
|
||||
};
|
||||
node.Accept(new CreateObjectVisitor(templateContext), null);
|
||||
node.Accept(new SetNamescopesAndRegisterNamesVisitor(templateContext), null);
|
||||
|
|
|
@ -189,7 +189,7 @@ namespace Xamarin.Forms.Build.Tasks
|
|||
|
||||
LoggingHelper.LogMessage(Low, $"{new string(' ', 6)}Replacing {0}.InitializeComponent ()");
|
||||
Exception e;
|
||||
if (!TryCoreCompile(initComp, initCompRuntime, rootnode, out e)) {
|
||||
if (!TryCoreCompile(initComp, initCompRuntime, rootnode, xamlFilePath, out e)) {
|
||||
success = false;
|
||||
LoggingHelper.LogMessage(Low, $"{new string(' ', 8)}failed.");
|
||||
(thrownExceptions = thrownExceptions ?? new List<Exception>()).Add(e);
|
||||
|
@ -263,7 +263,7 @@ namespace Xamarin.Forms.Build.Tasks
|
|||
return success;
|
||||
}
|
||||
|
||||
bool TryCoreCompile(MethodDefinition initComp, MethodDefinition initCompRuntime, ILRootNode rootnode, out Exception exception)
|
||||
bool TryCoreCompile(MethodDefinition initComp, MethodDefinition initCompRuntime, ILRootNode rootnode, string xamlFilePath, out Exception exception)
|
||||
{
|
||||
try {
|
||||
var body = new MethodBody(initComp);
|
||||
|
@ -328,7 +328,11 @@ namespace Xamarin.Forms.Build.Tasks
|
|||
il.Append(nop);
|
||||
}
|
||||
|
||||
var visitorContext = new ILContext(il, body, module);
|
||||
var visitorContext = new ILContext(il, body, module) {
|
||||
DefineDebug = DebugSymbols || (!string.IsNullOrEmpty(DebugType) && DebugType.ToLowerInvariant() != "none"),
|
||||
XamlFilePath = xamlFilePath
|
||||
};
|
||||
|
||||
|
||||
rootnode.Accept(new XamlNodeVisitor((node, parent) => node.Parent = parent), null);
|
||||
rootnode.Accept(new ExpandMarkupsVisitor(visitorContext), null);
|
||||
|
@ -339,6 +343,8 @@ namespace Xamarin.Forms.Build.Tasks
|
|||
rootnode.Accept(new SetResourcesVisitor(visitorContext), null);
|
||||
rootnode.Accept(new SetPropertiesVisitor(visitorContext, true), null);
|
||||
|
||||
il.Append(SetPropertiesVisitor.RegisterSourceInfo(visitorContext, rootnode));
|
||||
|
||||
il.Emit(Ret);
|
||||
initComp.Body = body;
|
||||
exception = null;
|
||||
|
|
|
@ -62,7 +62,7 @@ namespace Xamarin.Forms.Build.Tasks
|
|||
}
|
||||
|
||||
XamlParser.ParseXaml(
|
||||
rootnode = new ILRootNode(new XmlType(reader.NamespaceURI, reader.Name, null), typeReference, reader as IXmlNamespaceResolver), reader);
|
||||
rootnode = new ILRootNode(new XmlType(reader.NamespaceURI, reader.Name, null), typeReference, reader as IXmlNamespaceResolver, ((IXmlLineInfo)reader).LineNumber, ((IXmlLineInfo)reader).LinePosition), reader);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,21 +1,23 @@
|
|||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT License.
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.ComponentModel;
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
namespace Xamarin.Forms.Xaml.Diagnostics
|
||||
{
|
||||
class VisualDiagnostics
|
||||
public class VisualDiagnostics
|
||||
{
|
||||
static ConditionalWeakTable<object, XamlSourceInfo> sourceInfos = new ConditionalWeakTable<object, XamlSourceInfo>();
|
||||
internal static void RegisterSourceInfo(object target, Uri uri, int lineNumber, int linePosition)
|
||||
|
||||
[EditorBrowsable(EditorBrowsableState.Never)]
|
||||
public static void RegisterSourceInfo(object target, Uri uri, int lineNumber, int linePosition)
|
||||
{
|
||||
if (DebuggerHelper.DebuggerIsAttached && !sourceInfos.TryGetValue(target, out _))
|
||||
if (target != null && DebuggerHelper.DebuggerIsAttached && !sourceInfos.TryGetValue(target, out _))
|
||||
sourceInfos.Add(target, new XamlSourceInfo(uri, lineNumber, linePosition));
|
||||
}
|
||||
|
||||
[EditorBrowsable(EditorBrowsableState.Never)]
|
||||
internal static void SendVisualTreeChanged(object parent, object child)
|
||||
{
|
||||
if (DebuggerHelper.DebuggerIsAttached)
|
||||
|
@ -26,7 +28,7 @@ namespace Xamarin.Forms.Xaml.Diagnostics
|
|||
public static XamlSourceInfo GetXamlSourceInfo(object obj) => sourceInfos.TryGetValue(obj, out var sourceinfo) ? sourceinfo : null;
|
||||
}
|
||||
|
||||
class XamlSourceInfo
|
||||
public class XamlSourceInfo
|
||||
{
|
||||
public XamlSourceInfo(Uri sourceUri, int lineNumber, int linePosition)
|
||||
{
|
||||
|
@ -47,7 +49,7 @@ namespace Xamarin.Forms.Xaml.Diagnostics
|
|||
}
|
||||
}
|
||||
|
||||
class VisualTreeChangeEventArgs : EventArgs
|
||||
public class VisualTreeChangeEventArgs : EventArgs
|
||||
{
|
||||
public VisualTreeChangeEventArgs(object parent, object child, int childIndex, VisualTreeChangeType changeType)
|
||||
{
|
||||
|
@ -63,7 +65,7 @@ namespace Xamarin.Forms.Xaml.Diagnostics
|
|||
public VisualTreeChangeType ChangeType { get; }
|
||||
}
|
||||
|
||||
enum VisualTreeChangeType
|
||||
public enum VisualTreeChangeType
|
||||
{
|
||||
Add = 0,
|
||||
Remove = 1
|
||||
|
|
|
@ -190,7 +190,7 @@ namespace Xamarin.Forms.Xaml
|
|||
|
||||
abstract class RootNode : ElementNode
|
||||
{
|
||||
protected RootNode(XmlType xmlType, IXmlNamespaceResolver nsResolver) : base(xmlType, xmlType.NamespaceUri, nsResolver)
|
||||
protected RootNode(XmlType xmlType, IXmlNamespaceResolver nsResolver, int linenumber = -1, int lineposition = -1) : base(xmlType, xmlType.NamespaceUri, nsResolver, linenumber: linenumber, lineposition: lineposition)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче