From 36f779085bf9d9327202f1916273b79cac0f6e7a Mon Sep 17 00:00:00 2001 From: Robert Holt Date: Fri, 31 Aug 2018 15:57:17 +1000 Subject: [PATCH 1/4] Cache the reflection call done for completions --- .../Language/AstOperations.cs | 40 ++++++++++++------- 1 file changed, 26 insertions(+), 14 deletions(-) diff --git a/src/PowerShellEditorServices/Language/AstOperations.cs b/src/PowerShellEditorServices/Language/AstOperations.cs index c28416280..700d3b89b 100644 --- a/src/PowerShellEditorServices/Language/AstOperations.cs +++ b/src/PowerShellEditorServices/Language/AstOperations.cs @@ -23,6 +23,8 @@ namespace Microsoft.PowerShell.EditorServices /// internal static class AstOperations { + private static MethodInfo s_extentCloneWithNewOffset; + /// /// Gets completions for the symbol found in the Ast at /// the given file offset. @@ -55,22 +57,9 @@ static public async Task GetCompletions( ILogger logger, CancellationToken cancellationToken) { - var type = scriptAst.Extent.StartScriptPosition.GetType(); - var method = -#if CoreCLR - type.GetMethod( - "CloneWithNewOffset", - BindingFlags.Instance | BindingFlags.NonPublic); -#else - type.GetMethod( - "CloneWithNewOffset", - BindingFlags.Instance | BindingFlags.NonPublic, - null, - new[] { typeof(int) }, null); -#endif IScriptPosition cursorPosition = - (IScriptPosition)method.Invoke( + (IScriptPosition)GetExtentCloneMethod(scriptAst).Invoke( scriptAst.Extent.StartScriptPosition, new object[] { fileOffset }); @@ -337,5 +326,28 @@ static public string[] FindDotSourcedIncludes(Ast scriptAst) return dotSourcedVisitor.DotSourcedFiles.ToArray(); } + + private static MethodInfo GetExtentCloneMethod(Ast scriptAst) + { + if (s_extentCloneWithNewOffset == null) + { + Type type = scriptAst.Extent.StartScriptPosition.GetType(); + s_extentCloneWithNewOffset = +#if CoreCLR + type.GetMethod( + "CloneWithNewOffset", + BindingFlags.Instance | BindingFlags.NonPublic); +#else + type.GetMethod( + "CloneWithNewOffset", + BindingFlags.Instance | BindingFlags.NonPublic, + null, + new[] { typeof(int) }, null); +#endif + } + + return s_extentCloneWithNewOffset; + } + } } From 52bd38f23f670410acf0620b515f72c7f186731c Mon Sep 17 00:00:00 2001 From: Robert Holt Date: Mon, 3 Sep 2018 12:48:39 +1000 Subject: [PATCH 2/4] Find InternalScriptPositionType directly --- .../Language/AstOperations.cs | 54 +++++++++---------- 1 file changed, 26 insertions(+), 28 deletions(-) diff --git a/src/PowerShellEditorServices/Language/AstOperations.cs b/src/PowerShellEditorServices/Language/AstOperations.cs index 700d3b89b..12eec173f 100644 --- a/src/PowerShellEditorServices/Language/AstOperations.cs +++ b/src/PowerShellEditorServices/Language/AstOperations.cs @@ -14,6 +14,7 @@ namespace Microsoft.PowerShell.EditorServices { using System.Diagnostics; + using System.Linq.Expressions; using System.Management.Automation; using System.Management.Automation.Language; using System.Management.Automation.Runspaces; @@ -23,7 +24,28 @@ namespace Microsoft.PowerShell.EditorServices /// internal static class AstOperations { - private static MethodInfo s_extentCloneWithNewOffset; + private static readonly MethodInfo s_extentCloneWithNewOffset; + + static AstOperations() + { + // TODO: When netstandard is upgraded to 2.0, see if + // Delegate.CreateDelegate can be used here instead + s_extentCloneWithNewOffset = +#if CoreCLR + typeof(PSObject).GetTypeInfo().Assembly + .GetType("System.Management.Automation.Language.InternalScriptPosition") + .GetMethod("CloneWithNewOffset", BindingFlags.Instance | BindingFlags.NonPublic); +#else + typeof(PSObject).GetType().Assembly + .GetType("System.Management.Automation.Language.InternalScriptPosition") + .GetMethod( + "CloneWithNewOffset", + BindingFlags.Instance | BindingFlags.NonPublic, + binder: null, + types: new [] { typeof(int) }, + modifiers: null); +#endif + } /// /// Gets completions for the symbol found in the Ast at @@ -58,10 +80,9 @@ static public async Task GetCompletions( CancellationToken cancellationToken) { - IScriptPosition cursorPosition = - (IScriptPosition)GetExtentCloneMethod(scriptAst).Invoke( - scriptAst.Extent.StartScriptPosition, - new object[] { fileOffset }); + IScriptPosition cursorPosition = (IScriptPosition)s_extentCloneWithNewOffset.Invoke( + scriptAst.Extent.StartScriptPosition, + new object[] { fileOffset }); logger.Write( LogLevel.Verbose, @@ -326,28 +347,5 @@ static public string[] FindDotSourcedIncludes(Ast scriptAst) return dotSourcedVisitor.DotSourcedFiles.ToArray(); } - - private static MethodInfo GetExtentCloneMethod(Ast scriptAst) - { - if (s_extentCloneWithNewOffset == null) - { - Type type = scriptAst.Extent.StartScriptPosition.GetType(); - s_extentCloneWithNewOffset = -#if CoreCLR - type.GetMethod( - "CloneWithNewOffset", - BindingFlags.Instance | BindingFlags.NonPublic); -#else - type.GetMethod( - "CloneWithNewOffset", - BindingFlags.Instance | BindingFlags.NonPublic, - null, - new[] { typeof(int) }, null); -#endif - } - - return s_extentCloneWithNewOffset; - } - } } From 6d0822c798f7ebf910ea2efc08e92d435846ceaf Mon Sep 17 00:00:00 2001 From: Robert Holt Date: Mon, 3 Sep 2018 12:57:42 +1000 Subject: [PATCH 3/4] Fix up usings --- src/PowerShellEditorServices/Language/AstOperations.cs | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/PowerShellEditorServices/Language/AstOperations.cs b/src/PowerShellEditorServices/Language/AstOperations.cs index 12eec173f..d79f8ded9 100644 --- a/src/PowerShellEditorServices/Language/AstOperations.cs +++ b/src/PowerShellEditorServices/Language/AstOperations.cs @@ -5,19 +5,18 @@ using Microsoft.PowerShell.EditorServices.Utility; using System; +using System.Diagnostics; using System.Collections.Generic; using System.Linq; using System.Reflection; using System.Threading; using System.Threading.Tasks; +using System.Management.Automation.Language; +using System.Management.Automation.Runspaces; namespace Microsoft.PowerShell.EditorServices { - using System.Diagnostics; - using System.Linq.Expressions; using System.Management.Automation; - using System.Management.Automation.Language; - using System.Management.Automation.Runspaces; /// /// Provides common operations for the syntax tree of a parsed script. From 701a4a2b57e466ae00ffa3e3cf2b4ebdde422162 Mon Sep 17 00:00:00 2001 From: Robert Holt Date: Mon, 10 Sep 2018 19:33:02 -0700 Subject: [PATCH 4/4] Simplify reflection call --- .../Language/AstOperations.cs | 27 ++++--------------- 1 file changed, 5 insertions(+), 22 deletions(-) diff --git a/src/PowerShellEditorServices/Language/AstOperations.cs b/src/PowerShellEditorServices/Language/AstOperations.cs index d79f8ded9..38a8956a3 100644 --- a/src/PowerShellEditorServices/Language/AstOperations.cs +++ b/src/PowerShellEditorServices/Language/AstOperations.cs @@ -23,28 +23,11 @@ namespace Microsoft.PowerShell.EditorServices /// internal static class AstOperations { - private static readonly MethodInfo s_extentCloneWithNewOffset; - - static AstOperations() - { - // TODO: When netstandard is upgraded to 2.0, see if - // Delegate.CreateDelegate can be used here instead - s_extentCloneWithNewOffset = -#if CoreCLR - typeof(PSObject).GetTypeInfo().Assembly - .GetType("System.Management.Automation.Language.InternalScriptPosition") - .GetMethod("CloneWithNewOffset", BindingFlags.Instance | BindingFlags.NonPublic); -#else - typeof(PSObject).GetType().Assembly - .GetType("System.Management.Automation.Language.InternalScriptPosition") - .GetMethod( - "CloneWithNewOffset", - BindingFlags.Instance | BindingFlags.NonPublic, - binder: null, - types: new [] { typeof(int) }, - modifiers: null); -#endif - } + // TODO: When netstandard is upgraded to 2.0, see if + // Delegate.CreateDelegate can be used here instead + private static readonly MethodInfo s_extentCloneWithNewOffset = typeof(PSObject).GetTypeInfo().Assembly + .GetType("System.Management.Automation.Language.InternalScriptPosition") + .GetMethod("CloneWithNewOffset", BindingFlags.Instance | BindingFlags.NonPublic); /// /// Gets completions for the symbol found in the Ast at