Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/monodevelop.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Hutchinson <mhutchinson@novell.com>2010-07-26 08:50:38 +0400
committerMichael Hutchinson <mhutchinson@novell.com>2010-07-30 10:07:50 +0400
commit2f43baa9a1b92e2f8d7ee3d8e7d17cfb091e2266 (patch)
tree7385dd693de12ad1e2454b0196903ef81521fd22 /main/src/addins/MonoDevelop.AnalysisCore
parent4778fee7dffb5d77d79fa520e7e10934e945d6d2 (diff)
Get adapters and rules working.
Got adapters and rules working. Made them distinct addin nodes. Fixed various small issues including the DynamicMethod IL.
Diffstat (limited to 'main/src/addins/MonoDevelop.AnalysisCore')
-rw-r--r--main/src/addins/MonoDevelop.AnalysisCore/Adaptors.cs57
-rw-r--r--main/src/addins/MonoDevelop.AnalysisCore/AnalysisExtensions.cs24
-rw-r--r--main/src/addins/MonoDevelop.AnalysisCore/AnalysisRuleAddinNode.cs46
-rw-r--r--main/src/addins/MonoDevelop.AnalysisCore/MonoDevelop.AnalysisCore.addin.xml13
-rw-r--r--main/src/addins/MonoDevelop.AnalysisCore/MonoDevelop.AnalysisCore.csproj2
-rw-r--r--main/src/addins/MonoDevelop.AnalysisCore/ResultsEditorExtension.cs12
-rw-r--r--main/src/addins/MonoDevelop.AnalysisCore/RuleTreeNode.cs4
7 files changed, 125 insertions, 33 deletions
diff --git a/main/src/addins/MonoDevelop.AnalysisCore/Adaptors.cs b/main/src/addins/MonoDevelop.AnalysisCore/Adaptors.cs
new file mode 100644
index 0000000000..b8fbcc00c8
--- /dev/null
+++ b/main/src/addins/MonoDevelop.AnalysisCore/Adaptors.cs
@@ -0,0 +1,57 @@
+//
+// Adaptors.cs
+//
+// Author:
+// Michael Hutchinson <mhutchinson@novell.com>
+//
+// Copyright (c) 2010 Novell, Inc.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+
+using System;
+using MonoDevelop.Projects.Dom;
+using System.Collections.Generic;
+
+namespace MonoDevelop.AnalysisCore
+{
+ public static class Adapters
+ {
+ public static ICompilationUnit GetCompilationUnit (ParsedDocument input)
+ {
+ return input.CompilationUnit;
+ }
+ }
+
+ public static class Rules
+ {
+ public static IEnumerable<Result> NamingConventions (ICompilationUnit input)
+ {
+ foreach (var type in input.Types) {
+ if (!char.IsUpper (type.Name[0])) {
+ var start = type.BodyRegion.Start;
+ yield return new Result (
+ new DomRegion (start, new DomLocation (start.Line, start.Column + type.Name.Length)),
+ "Type names should begin with an uppercase letter",
+ ResultLevel.Warning, ResultCertainty.High, ResultImportance.Medium);
+ }
+ }
+ }
+ }
+}
+
diff --git a/main/src/addins/MonoDevelop.AnalysisCore/AnalysisExtensions.cs b/main/src/addins/MonoDevelop.AnalysisCore/AnalysisExtensions.cs
index a11b0cf67f..6ef741c2a2 100644
--- a/main/src/addins/MonoDevelop.AnalysisCore/AnalysisExtensions.cs
+++ b/main/src/addins/MonoDevelop.AnalysisCore/AnalysisExtensions.cs
@@ -92,6 +92,8 @@ namespace MonoDevelop.AnalysisCore
List<AnalysisRuleAddinNode> list;
if (!rulesByInput.TryGetValue (node.Input, out list))
list = rulesByInput[node.Input] = new List<AnalysisRuleAddinNode> ();
+
+ Console.WriteLine (node.GetErrSource ());
list.Add (node);
}
@@ -127,7 +129,7 @@ namespace MonoDevelop.AnalysisCore
internal static Type GetType (string name)
{
//this is hardcoded as the tree leaf node
- if (name == "Results")
+ if (name == RuleTreeLeaf.TYPE)
return typeof (IEnumerable<Result>);
//throws if not present
@@ -139,8 +141,15 @@ namespace MonoDevelop.AnalysisCore
public static RuleTreeRoot GetAnalysisTree (NodeTreeType treeType)
{
RuleTreeRoot tree;
- if (!analysisTreeCache.TryGetValue (treeType, out tree))
- analysisTreeCache [treeType] = tree = BuildTree (treeType);
+ if (analysisTreeCache.TryGetValue (treeType, out tree))
+ return tree;
+
+ analysisTreeCache [treeType] = tree = BuildTree (treeType);
+
+#if DEBUG
+ if (tree != null)
+ Console.WriteLine (tree.GetTreeStructure ());
+#endif
return tree;
}
@@ -167,7 +176,6 @@ namespace MonoDevelop.AnalysisCore
var list = new List<IRuleTreeNode> ();
foreach (var n in validNodes) {
-
//leaf node, return directly
if (n.Output == RuleTreeLeaf.TYPE) {
list.Add (new RuleTreeLeaf (n));
@@ -175,9 +183,8 @@ namespace MonoDevelop.AnalysisCore
}
if (depth > 50)
- throw new InvalidOperationException (string.Format (
- "Analysis tree too deep. Check for circular dependencies in rule '{0}' (Input='{1}',Output='{2}')",
- n.Name, n.Input, n.Output));
+ throw new InvalidOperationException ("Analysis tree too deep. Check for circular dependencies " +
+ n.GetErrSource ());
//get the nodes that will handle the output - by recursively calling this
var childNodes = GetTreeNodes (treeType, n.Output, depth + 1);
@@ -190,6 +197,7 @@ namespace MonoDevelop.AnalysisCore
}
return list.ToArray ();
- }}
+ }
+ }
}
diff --git a/main/src/addins/MonoDevelop.AnalysisCore/AnalysisRuleAddinNode.cs b/main/src/addins/MonoDevelop.AnalysisCore/AnalysisRuleAddinNode.cs
index a317378ea2..609a23a1a7 100644
--- a/main/src/addins/MonoDevelop.AnalysisCore/AnalysisRuleAddinNode.cs
+++ b/main/src/addins/MonoDevelop.AnalysisCore/AnalysisRuleAddinNode.cs
@@ -32,29 +32,41 @@ using System.Reflection.Emit;
namespace MonoDevelop.AnalysisCore
{
- public class AnalysisRuleAddinNode : ExtensionNode
+ class NamedAnalysisRuleAddinNode : AnalysisRuleAddinNode
+ {
+ [NodeAttribute ("_name", Required=true, Localizable=true, Description="User-visible name of the rule")]
+ string name = null;
+
+ public string Name { get { return name; } }
+
+ public override string Output { get { return RuleTreeLeaf.TYPE; } }
+ }
+
+ //hidden in GUIs
+ class AdaptorAnalysisRuleAddinNode : AnalysisRuleAddinNode
+ {
+ [NodeAttribute (Required=true, Description="The ID of the output type.")]
+ string output = null;
+
+ public override string Output { get { return output; } }
+ }
+
+ abstract class AnalysisRuleAddinNode : ExtensionNode
{
//generally rules should not need to use fileExtensions, since their input types (e.g.CSharpDom) should be enough
//but it's needed for the proprocessor/typemapping rules like ParsedDocument->CSharpDom
[NodeAttribute (Description="Comma separated list of file extensions to which this rule applies. It applies to all if none is specified.")]
string[] fileExtensions = null;
- [NodeAttribute (Description="The ID of the output type. Assumed to be Results if none specified.")]
- string output = null;
-
[NodeAttribute (Required=true, Description="The ID of the input type")]
string input = null;
-
- [NodeAttribute ("_name", Required=true, Localizable=true, Description="User-visible name of the rule")]
- string name = null;
[NodeAttribute ("func", Required=true, Description="The static Func<T,T> that processes the rule.")]
string funcName = null;
public string[] FileExtensions { get { return fileExtensions; } }
public string Input { get { return input; } }
- public string Output { get { return output ?? "Results"; } }
- public string Name { get { return name; } }
+ public abstract string Output {get; }
public string FuncName { get { return funcName; } }
//Lazy so we avoid loading assemblies until needed
@@ -83,10 +95,10 @@ namespace MonoDevelop.AnalysisCore
string typeName = funcName.Substring (0, dotIdx);
var type = this.Addin.GetType (typeName, true);
- var inputType = AnalysisExtensions.GetType (input);
- var outputType = AnalysisExtensions.GetType (output);
+ var inputType = AnalysisExtensions.GetType (Input);
+ var outputType = AnalysisExtensions.GetType (Output);
- string methodName = funcName.Substring (dotIdx);
+ string methodName = funcName.Substring (dotIdx + 1);
var methodInfo = type.GetMethod (methodName,
BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic,
Type.DefaultBinder, new Type[] { inputType},
@@ -99,13 +111,13 @@ namespace MonoDevelop.AnalysisCore
throw new InvalidOperationException ("Rule func ' " + funcName + "' has wrong output type " + GetErrSource ());
var wrapper = new DynamicMethod (methodName + "_obj" + (dynamicMethodKey++),
- typeof (object), new Type[] { typeof (object) });
+ typeof (object), new Type[] { typeof (object) }, true);
var il = wrapper.GetILGenerator ();
il.Emit (OpCodes.Ldarg_0);
il.Emit (OpCodes.Castclass, inputType);
- il.Emit (OpCodes.Call, methodInfo);
- il.Emit(OpCodes.Stloc_0);
+ il.Emit ((methodInfo.IsFinal || !methodInfo.IsVirtual)? OpCodes.Call : OpCodes.Callvirt, methodInfo);
+ il.Emit (OpCodes.Ret);
rule = (Func<object,object>) wrapper.CreateDelegate (typeof(Func<object,object>));
} finally {
@@ -115,9 +127,9 @@ namespace MonoDevelop.AnalysisCore
static int dynamicMethodKey = 0;
- string GetErrSource ()
+ internal string GetErrSource ()
{
- return string.Format ("({0}:{1}.{2})", Addin.Id, Path, Id);
+ return string.Format ("({0}:{1})", Addin.Id, Path);
}
static object NullRule (object o)
diff --git a/main/src/addins/MonoDevelop.AnalysisCore/MonoDevelop.AnalysisCore.addin.xml b/main/src/addins/MonoDevelop.AnalysisCore/MonoDevelop.AnalysisCore.addin.xml
index 3e2a16db67..fdca1872e5 100644
--- a/main/src/addins/MonoDevelop.AnalysisCore/MonoDevelop.AnalysisCore.addin.xml
+++ b/main/src/addins/MonoDevelop.AnalysisCore/MonoDevelop.AnalysisCore.addin.xml
@@ -17,7 +17,8 @@
<ExtensionNode name="Category" type="MonoDevelop.Ide.Codons.CategoryNode">
<ExtensionNodeSet id="MonoDevelop.AnalysisCore.Rules" />
</ExtensionNode>
- <ExtensionNode name="Rule" type="MonoDevelop.AnalysisCore.RuleExtensionNode" />
+ <ExtensionNode name="Rule" type="MonoDevelop.AnalysisCore.NamedAnalysisRuleAddinNode" />
+ <ExtensionNode name="Adaptor" type="MonoDevelop.AnalysisCore.AdaptorAnalysisRuleAddinNode" />
</ExtensionNodeSet>
<ExtensionPoint path = "/MonoDevelop/AnalysisCore/Rules" name = "Analysis Rules">
@@ -35,6 +36,14 @@
</Extension>
<Extension path = "/MonoDevelop/AnalysisCore/Types">
- <Type name="ParsedDocument" class="MonoDevelop.Projects.Dom.Parser.ParsedDocument" />
+ <Type name="ParsedDocument" class="MonoDevelop.Projects.Dom.ParsedDocument" />
+ <Type name="CompilationUnit" class="MonoDevelop.Projects.Dom.ICompilationUnit" />
+ </Extension>
+
+ <Extension path = "/MonoDevelop/AnalysisCore/Rules">
+ <Adaptor func="MonoDevelop.AnalysisCore.Adapters.GetCompilationUnit" input="ParsedDocument" output="CompilationUnit" />
+ <Category _name="Design Guidelines">
+ <Rule _name="Naming Conventions" func="MonoDevelop.AnalysisCore.Rules.NamingConventions" input="CompilationUnit" />
+ </Category>
</Extension>
</Addin> \ No newline at end of file
diff --git a/main/src/addins/MonoDevelop.AnalysisCore/MonoDevelop.AnalysisCore.csproj b/main/src/addins/MonoDevelop.AnalysisCore/MonoDevelop.AnalysisCore.csproj
index a8d42fc8e0..296c5b7eaa 100644
--- a/main/src/addins/MonoDevelop.AnalysisCore/MonoDevelop.AnalysisCore.csproj
+++ b/main/src/addins/MonoDevelop.AnalysisCore/MonoDevelop.AnalysisCore.csproj
@@ -47,6 +47,7 @@
<ProjectReference Include="..\..\core\Mono.Texteditor\Mono.TextEditor.csproj">
<Project>{A2329308-3751-4DBD-9A75-5F7B8B024625}</Project>
<Name>Mono.TextEditor</Name>
+ <Private>False</Private>
</ProjectReference>
</ItemGroup>
<ItemGroup>
@@ -81,6 +82,7 @@
<Compile Include="NodeTreeType.cs" />
<Compile Include="AnalysisTypeExtensionNode.cs" />
<Compile Include="AnalysisExtensions.cs" />
+ <Compile Include="Adaptors.cs" />
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
</Project> \ No newline at end of file
diff --git a/main/src/addins/MonoDevelop.AnalysisCore/ResultsEditorExtension.cs b/main/src/addins/MonoDevelop.AnalysisCore/ResultsEditorExtension.cs
index 12f9aabe5b..16f76af3f8 100644
--- a/main/src/addins/MonoDevelop.AnalysisCore/ResultsEditorExtension.cs
+++ b/main/src/addins/MonoDevelop.AnalysisCore/ResultsEditorExtension.cs
@@ -66,8 +66,11 @@ namespace MonoDevelop.AnalysisCore
{
lock (updaterLock) {
if (!updaterRunning) {
- GLib.Idle.Add (ResultsUpdater);
- updaterRunning = true;
+ if (results != null) {
+ nextResults = results;
+ GLib.Idle.Add (ResultsUpdater);
+ updaterRunning = true;
+ }
}
}
}
@@ -76,7 +79,7 @@ namespace MonoDevelop.AnalysisCore
//protected by lock. This is how we hand new results over to ResultsUpdater from the callback.
bool updaterRunning;
- List<Result> nextResults;
+ IList<Result> nextResults;
//only accessed by ResultsUpdater. This is the list it's using to update the text editor.
int updateIndex = 0;
@@ -112,7 +115,7 @@ namespace MonoDevelop.AnalysisCore
//clear the old results out at the same rate we add in the new ones
for (int i = 0; oldMarkers > 0 && i < UPDATE_COUNT; i++) {
Editor.Document.RemoveMarker (markers.Dequeue ());
- oldMarkers --;
+ oldMarkers--;
}
//add in the new markers
@@ -120,6 +123,7 @@ namespace MonoDevelop.AnalysisCore
var marker = new ResultMarker (currentResults[i]);
Editor.Document.AddMarker (marker.Line, marker);
markers.Enqueue (marker);
+ Console.WriteLine (marker.Result.Message);
}
return true;
diff --git a/main/src/addins/MonoDevelop.AnalysisCore/RuleTreeNode.cs b/main/src/addins/MonoDevelop.AnalysisCore/RuleTreeNode.cs
index 74bd202428..5d70a8451e 100644
--- a/main/src/addins/MonoDevelop.AnalysisCore/RuleTreeNode.cs
+++ b/main/src/addins/MonoDevelop.AnalysisCore/RuleTreeNode.cs
@@ -43,7 +43,7 @@ namespace MonoDevelop.AnalysisCore
{
AnalysisRuleAddinNode rule;
- internal const string TYPE = "Result";
+ internal const string TYPE = "Results";
public RuleTreeLeaf (AnalysisRuleAddinNode rule)
{
@@ -153,7 +153,7 @@ namespace MonoDevelop.AnalysisCore
}
var branch = (RuleTreeBranch) c;
- builder.AppendFormat ("[Branch (Output='{0}',Rule='{1}')", branch.Rule.Output, branch.Rule.FuncName);
+ builder.AppendFormat ("[Branch (Output='{0}',Rule='{1}')\n", branch.Rule.Output, branch.Rule.FuncName);
PrintTreeStructure (builder, branch.Children, indent + " ");