diff --git a/src/AddIns/BackendBindings/Boo/BooBinding.sln b/src/AddIns/BackendBindings/Boo/BooBinding.sln
new file mode 100644
index 0000000000..8e83b8b057
--- /dev/null
+++ b/src/AddIns/BackendBindings/Boo/BooBinding.sln
@@ -0,0 +1,14 @@
+Microsoft Visual Studio Solution File, Format Version 9.00
+# SharpDevelop 2.0.0.539
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NRefactoryToBooConverter", "NRefactoryToBooConverter\Project\NRefactoryToBooConverter.csproj", "{DBCF20A1-BA13-4582-BFA9-74DE4D987B73}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NRefactoryToBooConverter.Tests", "NRefactoryToBooConverter\Test\NRefactoryToBooConverter.Tests.csproj", "{C9DE556D-325C-4544-B29F-16A9EB7C9830}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NRefactoryBooCompiler", "NRefactoryBooCompiler\NRefactoryBooCompiler.csproj", "{6AEB826B-DCB6-4440-8A81-5D77A1E4D36E}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StandaloneConverter", "StandaloneConverter\StandaloneConverter.csproj", "{66338092-7611-40FC-B69C-B73A0528DA82}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BooBinding", "BooBinding\Project\BooBinding.csproj", "{4AC2D5F1-F671-480C-A075-6BF62B3721B2}"
+EndProject
+Global
+EndGlobal
diff --git a/src/AddIns/BackendBindings/Boo/BooBinding/Project/BooBinding.addin b/src/AddIns/BackendBindings/Boo/BooBinding/Project/BooBinding.addin
new file mode 100644
index 0000000000..41b65901a5
--- /dev/null
+++ b/src/AddIns/BackendBindings/Boo/BooBinding/Project/BooBinding.addin
@@ -0,0 +1,78 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/AddIns/BackendBindings/Boo/BooBinding/Project/BooBinding.csproj b/src/AddIns/BackendBindings/Boo/BooBinding/Project/BooBinding.csproj
new file mode 100644
index 0000000000..55d9ea0786
--- /dev/null
+++ b/src/AddIns/BackendBindings/Boo/BooBinding/Project/BooBinding.csproj
@@ -0,0 +1,94 @@
+
+
+ Library
+ Grunwald.BooBinding
+ BooBinding
+ Debug
+ AnyCPU
+ {4AC2D5F1-F671-480C-A075-6BF62B3721B2}
+ False
+ False
+ False
+ Auto
+ 4194304
+ AnyCPU
+ 4096
+ 4
+ false
+ ..\..\..\..\..\..\AddIns\AddIns\BackendBindings\BooBinding\
+
+
+ False
+ DEBUG;TRACE
+ true
+ Full
+ True
+
+
+ True
+ TRACE
+ False
+ None
+ False
+
+
+
+
+
+ ..\..\RequiredLibraries\Boo.Lang.Compiler.dll
+ False
+
+
+ ..\..\RequiredLibraries\Boo.Lang.dll
+ False
+
+
+ ..\..\RequiredLibraries\Boo.Lang.Parser.dll
+ False
+
+
+
+
+
+ Never
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Always
+
+
+ Always
+
+
+ Always
+
+
+ Always
+
+
+
+ {2748AD25-9C63-4E12-877B-4DCE96FBED54}
+ ICSharpCode.SharpDevelop
+
+
+ {35CEF10F-2D4C-45F2-9DD1-161E0FEC583C}
+ ICSharpCode.Core
+
+
+ {2D18BE89-D210-49EB-A9DD-2246FBB3DF6D}
+ ICSharpCode.TextEditor
+
+
+
+
\ No newline at end of file
diff --git a/src/AddIns/BackendBindings/Boo/BooBinding/Project/Resources/Boo.xshd b/src/AddIns/BackendBindings/Boo/BooBinding/Project/Resources/Boo.xshd
new file mode 100644
index 0000000000..59fbdfcc32
--- /dev/null
+++ b/src/AddIns/BackendBindings/Boo/BooBinding/Project/Resources/Boo.xshd
@@ -0,0 +1,304 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ &<>~!@%^*()-+=|\#/{}[]:;"' , .?
+
+
+ """
+ """
+
+
+
+ #
+
+
+
+ //
+
+
+
+ /*
+ */
+
+
+
+ "
+ "
+
+
+
+ """
+ """
+
+
+
+ '
+ '
+
+
+
+ /@!/@
+ /
+
+
+ (
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ &<>~!@%^*()-+=|\#/{}[]:;"' , .?
+
+
+ /*
+ */
+
+
+
+
+
+ &<>~!@%^*()-+=|\#/{}[]:;"' , .?
+
+
+ /*
+ */
+
+
+
+
+
+ &<>~!@%^*()-+=|\#/{}[]:;"' , .?
+
+
+ ${
+ }
+
+
+
+
+
+
+
+
diff --git a/src/AddIns/BackendBindings/Boo/BooBinding/Project/Src/AssemblyInfo.cs b/src/AddIns/BackendBindings/Boo/BooBinding/Project/Src/AssemblyInfo.cs
new file mode 100644
index 0000000000..e0ee20a70e
--- /dev/null
+++ b/src/AddIns/BackendBindings/Boo/BooBinding/Project/Src/AssemblyInfo.cs
@@ -0,0 +1,32 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+
+// Information about this assembly is defined by the following
+// attributes.
+//
+// change them to the information which is associated with the assembly
+// you compile.
+
+[assembly: AssemblyTitle("BooBinding")]
+[assembly: AssemblyDescription("Boo language binding for #develop")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("www.icsharpcode.net")]
+[assembly: AssemblyProduct("SharpDevelop")]
+[assembly: AssemblyCopyright("(c) 2005 Daniel Grunwald")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// The assembly version has following format :
+//
+// Major.Minor.Build.Revision
+//
+// You can specify all values by your own or you can build default build and revision
+// numbers with the '*' character (the default):
+
+[assembly: AssemblyVersion("2.0.0.1")]
+
+// The following attributes specify the key for the sign of your assembly. See the
+// .NET Framework documentation for more information about signing.
+// This is not required, if you don't want signing let these attributes like they're.
+[assembly: AssemblyDelaySign(false)]
+[assembly: AssemblyKeyFile("")]
diff --git a/src/AddIns/BackendBindings/Boo/BooBinding/Project/Src/BooAmbience.cs b/src/AddIns/BackendBindings/Boo/BooBinding/Project/Src/BooAmbience.cs
new file mode 100644
index 0000000000..232e71967f
--- /dev/null
+++ b/src/AddIns/BackendBindings/Boo/BooBinding/Project/Src/BooAmbience.cs
@@ -0,0 +1,560 @@
+//
+// 2002-2005 AlphaSierraPapa
+// GNU General Public License
+//
+// $Revision$
+//
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+using ICSharpCode.Core;
+using ICSharpCode.SharpDevelop.Dom;
+
+namespace Grunwald.BooBinding
+{
+ public class BooAmbience : AbstractAmbience
+ {
+ // Fields
+ static Dictionary reverseTypeConversionTable = new Dictionary();
+ static Dictionary typeConversionTable = new Dictionary();
+
+ public readonly static BooAmbience Instance = new BooAmbience();
+
+ ///
+ /// Gets a dictionary with boo's short names as keys and
+ /// the fully qualified type names as values.
+ ///
+ public static Dictionary ReverseTypeConversionTable {
+ get {
+ return reverseTypeConversionTable;
+ }
+ }
+
+ ///
+ /// Gets a dictionary with the fully qualified type names as keys and
+ /// boo's short names as values.
+ ///
+ public static Dictionary TypeConversionTable {
+ get {
+ return typeConversionTable;
+ }
+ }
+
+ static BooAmbience()
+ {
+ typeConversionTable.Add("System.Void", "void");
+ typeConversionTable.Add("System.Object", "object");
+ typeConversionTable.Add("System.Boolean", "bool");
+ typeConversionTable.Add("System.Byte", "byte");
+ typeConversionTable.Add("System.SByte", "sbyte");
+ typeConversionTable.Add("System.Char", "char");
+ typeConversionTable.Add("System.Int16", "short");
+ typeConversionTable.Add("System.Int32", "int");
+ typeConversionTable.Add("System.Int64", "long");
+ typeConversionTable.Add("System.UInt16", "ushort");
+ typeConversionTable.Add("System.UInt32", "uint");
+ typeConversionTable.Add("System.UInt64", "ulong");
+ typeConversionTable.Add("System.Single", "single");
+ typeConversionTable.Add("System.Double", "double");
+ typeConversionTable.Add("System.Decimal", "decimal");
+ typeConversionTable.Add("System.String", "string");
+ typeConversionTable.Add("System.DateTime", "date");
+ typeConversionTable.Add("System.TimeSpan", "timespan");
+ typeConversionTable.Add("System.Type", "type");
+ typeConversionTable.Add("System.Array", "array");
+ typeConversionTable.Add("System.Text.RegularExpressions.Regex", "regex");
+ foreach (KeyValuePair pair in typeConversionTable) {
+ reverseTypeConversionTable.Add(pair.Value, pair.Key);
+ }
+ }
+
+ public override string GetIntrinsicTypeName(string typeName)
+ {
+ if (typeConversionTable.ContainsKey(typeName))
+ return typeConversionTable[typeName];
+ else
+ return typeName;
+ }
+
+ public static string GetFullTypeName(string shortName)
+ {
+ if (reverseTypeConversionTable.ContainsKey(shortName))
+ return reverseTypeConversionTable[shortName];
+ else
+ return shortName;
+ }
+
+ public static IEnumerable> BooSpecialTypes {
+ get {
+ return typeConversionTable;
+ }
+ }
+
+ // Methods
+
+ bool ModifierIsSet(ModifierEnum modifier, ModifierEnum query)
+ {
+ return (modifier & query) == query;
+ }
+
+ public override string Convert(ModifierEnum modifier)
+ {
+ if (ShowAccessibility) {
+ if (ModifierIsSet(modifier, ModifierEnum.Public)) {
+ return "public ";
+ } else if (ModifierIsSet(modifier, ModifierEnum.Private)) {
+ return "private ";
+ } else if (ModifierIsSet(modifier, ModifierEnum.ProtectedAndInternal)) {
+ return "protected internal ";
+ } else if (ModifierIsSet(modifier, ModifierEnum.ProtectedOrInternal)) {
+ return "internal protected ";
+ } else if (ModifierIsSet(modifier, ModifierEnum.Internal)) {
+ return "internal ";
+ } else if (ModifierIsSet(modifier, ModifierEnum.Protected)) {
+ return "protected ";
+ }
+ }
+ return string.Empty;
+ }
+
+ string GetModifier(IDecoration decoration)
+ {
+ string ret = "";
+
+ if (IncludeHTMLMarkup) {
+ ret += "";
+ }
+ if (decoration.IsStatic) {
+ ret += "static ";
+ } else if (decoration.IsSealed) {
+ ret += "final ";
+ } else if (decoration.IsOverride) {
+ ret += "override ";
+ } else if (decoration.IsNew) {
+ ret += "new ";
+ }
+ if (IncludeHTMLMarkup) {
+ ret += "";
+ }
+ return ret;
+ }
+
+
+ public override string Convert(IClass c)
+ {
+ StringBuilder builder = new StringBuilder();
+
+ builder.Append(Convert(c.Modifiers));
+
+ if (IncludeHTMLMarkup) {
+ builder.Append("");
+ }
+
+ if (ShowModifiers) {
+ if (c.IsSealed) {
+ switch (c.ClassType) {
+ case ClassType.Delegate:
+ case ClassType.Struct:
+ case ClassType.Enum:
+ break;
+
+ default:
+ builder.Append("final ");
+ break;
+ }
+ } else if (c.IsAbstract && c.ClassType != ClassType.Interface) {
+ builder.Append("abstract ");
+ }
+ }
+
+ if (IncludeHTMLMarkup) {
+ builder.Append("");
+ }
+
+ if (ShowModifiers) {
+ switch (c.ClassType) {
+ case ClassType.Delegate:
+ builder.Append("callable");
+ break;
+ case ClassType.Class:
+ case ClassType.Module:
+ builder.Append("class");
+ break;
+ case ClassType.Struct:
+ builder.Append("struct");
+ break;
+ case ClassType.Interface:
+ builder.Append("interface");
+ break;
+ case ClassType.Enum:
+ builder.Append("enum");
+ break;
+ }
+ builder.Append(' ');
+ }
+
+ if (IncludeHTMLMarkup) {
+ builder.Append("");
+ }
+
+ if (UseFullyQualifiedMemberNames) {
+ builder.Append(c.FullyQualifiedName);
+ } else {
+ builder.Append(c.Name);
+ }
+
+ if (IncludeHTMLMarkup) {
+ builder.Append("");
+ }
+ if (c.TypeParameters.Count > 0) {
+ builder.Append("[of ");
+ for (int i = 0; i < c.TypeParameters.Count; ++i) {
+ if (i > 0) builder.Append(", ");
+ builder.Append(c.TypeParameters[i].Name);
+ }
+ builder.Append(']');
+ }
+
+ if (ShowReturnType && c.ClassType == ClassType.Delegate) {
+ builder.Append(" (");
+ if (IncludeHTMLMarkup) builder.Append("
");
+
+ foreach(IMethod m in c.Methods) {
+ if (m.Name != "Invoke") continue;
+
+ for (int i = 0; i < m.Parameters.Count; ++i) {
+ if (IncludeHTMLMarkup) builder.Append(" ");
+
+ builder.Append(Convert(m.Parameters[i]));
+ if (i + 1 < m.Parameters.Count) builder.Append(", ");
+
+ if (IncludeHTMLMarkup) builder.Append("
");
+ }
+ }
+ builder.Append(')');
+
+ foreach(IMethod m in c.Methods) {
+ if (m.Name != "Invoke") continue;
+
+ builder.Append(" as ");
+ builder.Append(Convert(m.ReturnType));
+ }
+
+ } else if (ShowInheritanceList) {
+ if (c.BaseTypes.Count > 0) {
+ builder.Append("(");
+ for (int i = 0; i < c.BaseTypes.Count; ++i) {
+ builder.Append(c.BaseTypes[i]);
+ if (i + 1 < c.BaseTypes.Count) {
+ builder.Append(", ");
+ }
+ }
+ builder.Append(")");
+ }
+ }
+
+ if (IncludeBodies) {
+ builder.Append(":\n");
+ }
+
+ return builder.ToString();
+ }
+
+ public override string ConvertEnd(IClass c)
+ {
+ return "";
+ }
+
+ public override string Convert(IField field)
+ {
+ StringBuilder builder = new StringBuilder();
+
+ builder.Append(Convert(field.Modifiers));
+
+ if (IncludeHTMLMarkup) {
+ builder.Append("");
+ }
+
+ if (ShowModifiers) {
+ if (field.IsConst) {
+ builder.Append("static final ");
+ } else if (field.IsStatic) {
+ builder.Append("static ");
+ }
+
+ if (field.IsReadonly) {
+ builder.Append("final ");
+ }
+ }
+
+ if (IncludeHTMLMarkup) {
+ builder.Append("");
+ }
+
+ if (IncludeHTMLMarkup) {
+ builder.Append("");
+ }
+
+ if (UseFullyQualifiedMemberNames) {
+ builder.Append(field.FullyQualifiedName);
+ } else {
+ builder.Append(field.Name);
+ }
+
+ if (IncludeHTMLMarkup) {
+ builder.Append("");
+ }
+
+ if (field.ReturnType != null && ShowReturnType) {
+ builder.Append(" as ");
+ builder.Append(Convert(field.ReturnType));
+ }
+
+ return builder.ToString();
+ }
+
+ public override string Convert(IProperty property)
+ {
+ StringBuilder builder = new StringBuilder();
+
+ builder.Append(Convert(property.Modifiers));
+
+ if (ShowModifiers) {
+ builder.Append(GetModifier(property));
+ }
+
+ if (property.IsIndexer) {
+ builder.Append("self");
+ } else {
+ if (IncludeHTMLMarkup) {
+ builder.Append("");
+ }
+ if (UseFullyQualifiedMemberNames) {
+ builder.Append(property.FullyQualifiedName);
+ } else {
+ builder.Append(property.Name);
+ }
+ if (IncludeHTMLMarkup) {
+ builder.Append("");
+ }
+ }
+
+ if (property.Parameters.Count > 0) {
+ builder.Append('[');
+ if (IncludeHTMLMarkup) builder.Append("
");
+
+ for (int i = 0; i < property.Parameters.Count; ++i) {
+ if (IncludeHTMLMarkup) builder.Append(" ");
+ builder.Append(Convert(property.Parameters[i]));
+ if (i + 1 < property.Parameters.Count) {
+ builder.Append(", ");
+ }
+ if (IncludeHTMLMarkup) builder.Append("
");
+ }
+
+ builder.Append(']');
+ }
+
+ if (property.ReturnType != null && ShowReturnType) {
+ builder.Append(" as ");
+ builder.Append(Convert(property.ReturnType));
+ }
+
+ if (IncludeBodies) {
+ builder.Append(":");
+
+ if (property.CanGet) {
+ builder.Append(" get");
+ }
+ if (property.CanSet) {
+ builder.Append(" set");
+ }
+ }
+
+ return builder.ToString();
+ }
+
+ public override string Convert(IEvent e)
+ {
+ StringBuilder builder = new StringBuilder();
+
+ builder.Append(Convert(e.Modifiers));
+
+ if (ShowModifiers) {
+ builder.Append(GetModifier(e));
+ }
+
+ builder.Append("event ");
+
+ if (IncludeHTMLMarkup) {
+ builder.Append("");
+ }
+
+ if (UseFullyQualifiedMemberNames) {
+ builder.Append(e.FullyQualifiedName);
+ } else {
+ builder.Append(e.Name);
+ }
+
+ if (IncludeHTMLMarkup) {
+ builder.Append("");
+ }
+
+ if (e.ReturnType != null && ShowReturnType) {
+ builder.Append(" as ");
+ builder.Append(Convert(e.ReturnType));
+ }
+
+ return builder.ToString();
+ }
+
+ public override string Convert(IMethod m)
+ {
+ StringBuilder builder = new StringBuilder();
+ builder.Append(Convert(m.Modifiers));
+
+ if (ShowModifiers) {
+ builder.Append(GetModifier(m));
+ }
+
+ builder.Append("def ");
+
+ if (IncludeHTMLMarkup) {
+ builder.Append("");
+ }
+
+ if (m.IsConstructor) {
+ builder.Append("constructor");
+ } else {
+ if (UseFullyQualifiedMemberNames) {
+ builder.Append(m.FullyQualifiedName);
+ } else {
+ builder.Append(m.Name);
+ }
+ }
+
+ if (IncludeHTMLMarkup) {
+ builder.Append("");
+ }
+
+ if (m.TypeParameters.Count > 0) {
+ builder.Append("[of ");
+ for (int i = 0; i < m.TypeParameters.Count; ++i) {
+ if (i > 0) builder.Append(", ");
+ builder.Append(m.TypeParameters[i].Name);
+ }
+ builder.Append(']');
+ }
+
+ builder.Append("(");
+ if (IncludeHTMLMarkup) builder.Append("
");
+
+ for (int i = 0; i < m.Parameters.Count; ++i) {
+ if (IncludeHTMLMarkup) builder.Append(" ");
+ builder.Append(Convert(m.Parameters[i]));
+ if (i + 1 < m.Parameters.Count) {
+ builder.Append(", ");
+ }
+ if (IncludeHTMLMarkup) builder.Append("
");
+ }
+
+ builder.Append(')');
+
+ if (m.ReturnType != null && ShowReturnType) {
+ builder.Append(" as ");
+ builder.Append(Convert(m.ReturnType));
+ }
+
+ return builder.ToString();
+ }
+
+ public override string ConvertEnd(IMethod m)
+ {
+ return "";
+ }
+
+ public override string Convert(IReturnType returnType)
+ {
+ if (returnType == null) {
+ return String.Empty;
+ }
+ StringBuilder builder = new StringBuilder();
+ UnpackNestedType(builder, returnType);
+ return builder.ToString();
+ }
+
+ void UnpackNestedType(StringBuilder builder, IReturnType returnType)
+ {
+ ArrayReturnType art = returnType as ArrayReturnType;
+ if (art != null) {
+ builder.Append('(');
+ UnpackNestedType(builder, art.ElementType);
+ for (int i = 1; i < art.ArrayDimensions; ++i) {
+ builder.Append(',');
+ }
+ builder.Append(')');
+ } else if (returnType is ConstructedReturnType) {
+ ConstructedReturnType rt = (ConstructedReturnType)returnType;
+ UnpackNestedType(builder, rt.BaseType);
+ builder.Append("[of ");
+ for (int i = 0; i < rt.TypeArguments.Count; ++i) {
+ if (i > 0) builder.Append(", ");
+ builder.Append(Convert(rt.TypeArguments[i]));
+ }
+ builder.Append(']');
+ } else {
+ string fullName = returnType.FullyQualifiedName;
+ if (fullName != null && typeConversionTable.ContainsKey(fullName)) {
+ builder.Append(typeConversionTable[fullName].ToString());
+ } else {
+ if (UseFullyQualifiedNames) {
+ builder.Append(fullName);
+ } else {
+ builder.Append(returnType.Name);
+ }
+ }
+ }
+ }
+
+ public override string Convert(IParameter param)
+ {
+ StringBuilder builder = new StringBuilder();
+
+ if (IncludeHTMLMarkup) {
+ builder.Append("");
+ }
+
+ if (param.IsRef) {
+ builder.Append("ref ");
+ } else if (param.IsOut) {
+ builder.Append("ref ");
+ } else if (param.IsParams) {
+ builder.Append("*");
+ }
+
+ if (IncludeHTMLMarkup) {
+ builder.Append("");
+ }
+
+ if (ShowParameterNames) {
+ builder.Append(param.Name);
+ builder.Append(" as ");
+ }
+
+ builder.Append(Convert(param.ReturnType));
+
+ return builder.ToString();
+ }
+
+ public override string WrapAttribute(string attribute)
+ {
+ return "[" + attribute + "]";
+ }
+
+ public override string WrapComment(string comment)
+ {
+ return "// " + comment;
+ }
+ }
+}
diff --git a/src/AddIns/BackendBindings/Boo/BooBinding/Project/Src/BooLanguageBinding.cs b/src/AddIns/BackendBindings/Boo/BooBinding/Project/Src/BooLanguageBinding.cs
new file mode 100644
index 0000000000..5a546893e2
--- /dev/null
+++ b/src/AddIns/BackendBindings/Boo/BooBinding/Project/Src/BooLanguageBinding.cs
@@ -0,0 +1,73 @@
+//
+// 2002-2005 AlphaSierraPapa
+// GNU General Public License
+//
+// $Revision$
+//
+
+using System;
+using System.IO;
+using System.Diagnostics;
+using System.Collections;
+using System.Reflection;
+using System.Resources;
+using System.Windows.Forms;
+using System.Xml;
+using System.CodeDom.Compiler;
+using System.Threading;
+using ICSharpCode.SharpDevelop.Project;
+using ICSharpCode.SharpDevelop.Internal.Templates;
+using ICSharpCode.SharpDevelop.Gui;
+using ICSharpCode.Core;
+
+namespace Grunwald.BooBinding
+{
+ public class BooLanguageBinding : ILanguageBinding
+ {
+ public const string LanguageName = "Boo";
+
+ public string Language {
+ get {
+ return LanguageName;
+ }
+ }
+
+ #region routines for single file compilation
+ public bool CanCompile(string fileName)
+ {
+ string ext = Path.GetExtension(fileName);
+ if (ext == null)
+ return false;
+ return string.Equals(ext, ".BOO", StringComparison.InvariantCultureIgnoreCase);
+ }
+
+ public string GetCompiledOutputName(string fileName)
+ {
+ return Path.ChangeExtension(fileName, ".exe");
+ }
+
+ public CompilerResults CompileFile(string fileName)
+ {
+ throw new NotImplementedException();
+ }
+
+ public void Execute(string fileName, bool debug)
+ {
+ throw new NotImplementedException(); // only needed for single-file compilation
+ }
+ #endregion
+
+ public IProject LoadProject(string fileName, string projectName)
+ {
+ return new BooProject(fileName, projectName);
+ }
+
+ public IProject CreateProject(ProjectCreateInformation info, XmlElement projectOptions)
+ {
+ BooProject p = new BooProject(info);
+ if (projectOptions != null)
+ p.ImportOptions(projectOptions.Attributes);
+ return p;
+ }
+ }
+}
diff --git a/src/AddIns/BackendBindings/Boo/BooBinding/Project/Src/BooProject.cs b/src/AddIns/BackendBindings/Boo/BooBinding/Project/Src/BooProject.cs
new file mode 100644
index 0000000000..d7c5caf28c
--- /dev/null
+++ b/src/AddIns/BackendBindings/Boo/BooBinding/Project/Src/BooProject.cs
@@ -0,0 +1,45 @@
+//
+// 2002-2005 AlphaSierraPapa
+// GNU General Public License
+//
+// $Revision$
+//
+
+using System;
+using System.ComponentModel;
+using ICSharpCode.SharpDevelop.Internal.Templates;
+using ICSharpCode.SharpDevelop.Project;
+using ICSharpCode.Core;
+
+namespace Grunwald.BooBinding
+{
+ public class BooProject : MSBuildProject
+ {
+ public BooProject(string fileName, string projectName)
+ {
+ this.Name = projectName;
+ Language = "Boo";
+ SetupProject(fileName);
+ IdGuid = BaseConfiguration["ProjectGuid"];
+ }
+
+ public BooProject(ProjectCreateInformation info)
+ {
+ Language = "Boo";
+ Create(info);
+ imports.Add("$(BooBinPath)\\MsBuild.Boo.Targets");
+ }
+
+ public override bool CanCompile(string fileName)
+ {
+ return new BooLanguageBinding().CanCompile(fileName);
+ }
+
+ [Browsable(false)]
+ public override IAmbience Ambience {
+ get {
+ return BooAmbience.Instance;
+ }
+ }
+ }
+}
diff --git a/src/AddIns/BackendBindings/Boo/BooBinding/Project/Src/CodeCompletion/BooParser.cs b/src/AddIns/BackendBindings/Boo/BooBinding/Project/Src/CodeCompletion/BooParser.cs
new file mode 100644
index 0000000000..42f4f8c00b
--- /dev/null
+++ b/src/AddIns/BackendBindings/Boo/BooBinding/Project/Src/CodeCompletion/BooParser.cs
@@ -0,0 +1,128 @@
+//
+// 2002-2005 AlphaSierraPapa
+// GNU General Public License
+//
+// $Revision$
+//
+
+using System;
+using System.IO;
+using ICSharpCode.Core;
+using ICSharpCode.SharpDevelop.Project;
+using ICSharpCode.SharpDevelop.Dom;
+using Boo.Lang.Compiler;
+using Boo.Lang.Compiler.IO;
+using Boo.Lang.Compiler.Pipelines;
+using Boo.Lang.Compiler.Steps;
+using Boo.Lang.Parser;
+
+namespace Grunwald.BooBinding.CodeCompletion
+{
+ public class BooParser : IParser
+ {
+ ///IParser Interface
+ string[] lexerTags;
+
+ public string[] LexerTags {
+ get {
+ return lexerTags;
+ }
+ set {
+ lexerTags = value;
+ }
+ }
+
+ public IExpressionFinder CreateExpressionFinder(string fileName)
+ {
+ return new ExpressionFinder(fileName);
+ }
+
+ public bool CanParse(string fileName)
+ {
+ return string.Equals(Path.GetExtension(fileName), ".boo", StringComparison.InvariantCultureIgnoreCase);
+ }
+
+ public bool CanParse(IProject project)
+ {
+ return project.Language == BooLanguageBinding.LanguageName;
+ }
+
+ public ICompilationUnit Parse(IProjectContent projectContent, string fileName)
+ {
+ string content;
+ using (StreamReader reader = new StreamReader(fileName)) {
+ content = reader.ReadToEnd();
+ }
+ return Parse(projectContent, fileName, content);
+ }
+
+ public ICompilationUnit Parse(IProjectContent projectContent, string fileName, string fileContent)
+ {
+ LoggingService.Debug("Parse " + fileName);
+ int lineCount = 1;
+ foreach (char c in fileContent) {
+ if (c == '\n') {
+ lineCount++;
+ }
+ }
+ int[] lineLength = new int[lineCount];
+ int length = 0;
+ int i = 0;
+ foreach (char c in fileContent) {
+ if (c == '\n') {
+ lineLength[i] = length;
+ i += 1;
+ length = 0;
+ } else if (c != '\r') {
+ length += 1;
+ }
+ }
+ lineLength[i] = length;
+ BooCompiler compiler = new BooCompiler();
+ compiler.Parameters.Input.Add(new StringInput(fileName, fileContent));
+ return Parse(projectContent, fileName, lineLength, compiler);
+ }
+
+ private ICompilationUnit Parse(IProjectContent projectContent, string fileName, int[] lineLength, BooCompiler compiler)
+ {
+ compiler.Parameters.OutputWriter = new StringWriter();
+ compiler.Parameters.TraceSwitch.Level = System.Diagnostics.TraceLevel.Warning;
+
+ Compile compilePipe = new Compile();
+ BooParsingStep parsingStep = (BooParsingStep)compilePipe[0];
+ parsingStep.TabSize = 1;
+
+ ConvertVisitor visitor = new ConvertVisitor(lineLength, projectContent);
+ visitor.Cu.FileName = fileName;
+
+ // Remove unneccessary compiler steps
+ int num = 1 + compilePipe.Find(typeof(NormalizeTypeAndMemberDefinitions));
+ compilePipe[num] = visitor;
+ while (compilePipe.Count > num + 1)
+ compilePipe.RemoveAt(compilePipe.Count - 1);
+ num = compilePipe.Find(typeof(TransformCallableDefinitions));
+ compilePipe.RemoveAt(num);
+
+ for (int i = 0; i < compilePipe.Count; i++) {
+ Console.WriteLine(compilePipe[i]);
+ }
+
+ compilePipe.BreakOnErrors = false;
+ compiler.Parameters.Pipeline = compilePipe;
+
+ try {
+ compiler.Run();
+ // somehow the SD parser thread goes into an endless loop if this flag is not set
+ visitor.Cu.ErrorsDuringCompile = true; //context.Errors.Count > 0
+ } catch (Exception ex) {
+ MessageService.ShowError(ex);
+ }
+ return visitor.Cu;
+ }
+
+ public IResolver CreateResolver()
+ {
+ return new BooResolver();
+ }
+ }
+}
diff --git a/src/AddIns/BackendBindings/Boo/BooBinding/Project/Src/CodeCompletion/BooResolver.cs b/src/AddIns/BackendBindings/Boo/BooBinding/Project/Src/CodeCompletion/BooResolver.cs
new file mode 100644
index 0000000000..7140a79315
--- /dev/null
+++ b/src/AddIns/BackendBindings/Boo/BooBinding/Project/Src/CodeCompletion/BooResolver.cs
@@ -0,0 +1,181 @@
+//
+// 2002-2005 AlphaSierraPapa
+// GNU General Public License
+//
+// $Revision$
+//
+
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using ICSharpCode.Core;
+using ICSharpCode.SharpDevelop.Dom;
+using Boo.Lang.Compiler;
+using AST = Boo.Lang.Compiler.Ast;
+using Boo.Lang.Compiler.IO;
+using Boo.Lang.Compiler.Steps;
+using NRResolver = ICSharpCode.SharpDevelop.Dom.NRefactoryResolver.NRefactoryResolver;
+
+namespace Grunwald.BooBinding.CodeCompletion
+{
+ public class BooResolver : IResolver
+ {
+ #region Fields and properties
+ ICompilationUnit cu;
+ IProjectContent pc;
+ int caretLine;
+ int caretColumn;
+ IClass callingClass;
+ IMember callingMember;
+
+ public IClass CallingClass {
+ get {
+ return callingClass;
+ }
+ }
+
+ public IMember CallingMember {
+ get {
+ return callingMember;
+ }
+ }
+
+ public int CaretLine {
+ get {
+ return caretLine;
+ }
+ }
+
+ public int CaretColumn {
+ get {
+ return caretColumn;
+ }
+ }
+
+ public IProjectContent ProjectContent {
+ get {
+ return pc;
+ }
+ }
+
+ public ICompilationUnit CompilationUnit {
+ get {
+ return cu;
+ }
+ }
+ #endregion
+
+ #region Initialization
+ bool Initialize(string fileName, int caretLine, int caretColumn)
+ {
+ ParseInformation parseInfo = ParserService.GetParseInformation(fileName);
+ if (parseInfo == null) {
+ return false;
+ }
+ this.cu = parseInfo.MostRecentCompilationUnit;
+ this.pc = cu.ProjectContent;
+ this.caretLine = caretLine;
+ this.caretColumn = caretColumn;
+ this.callingClass = cu.GetInnermostClass(caretLine, caretColumn);
+ if (callingClass == null) {
+ if (cu.Classes.Count == 0) return false;
+ callingClass = cu.Classes[cu.Classes.Count - 1];
+ if (!callingClass.Region.IsEmpty) {
+ if (callingClass.Region.BeginLine > caretLine)
+ return false;
+ }
+ }
+ callingMember = ResolveCurrentMember();
+ return true;
+ }
+
+ IMember ResolveCurrentMember()
+ {
+ LoggingService.DebugFormatted("Getting current method... caretLine = {0}, caretColumn = {1}", caretLine, caretColumn);
+ if (callingClass == null) return null;
+ IMember best = null;
+ int line = 0;
+ foreach (IMember m in callingClass.Methods) {
+ if (m.Region.BeginLine <= caretLine && m.Region.BeginLine > line) {
+ line = m.Region.BeginLine;
+ best = m;
+ }
+ }
+ foreach (IMember m in callingClass.Properties) {
+ if (m.Region.BeginLine <= caretLine && m.Region.BeginLine > line) {
+ line = m.Region.BeginLine;
+ best = m;
+ }
+ }
+ if (callingClass.Region.IsEmpty) {
+ foreach (IMember m in callingClass.Methods) {
+ if (best == null || best.Region.EndLine < caretLine)
+ return m;
+ }
+ }
+ return best;
+ }
+ #endregion
+
+ #region Resolve
+ public ResolveResult Resolve(ExpressionResult expressionResult,
+ int caretLineNumber, int caretColumn,
+ string fileName, string fileContent)
+ {
+ if (!Initialize(fileName, caretLineNumber, caretColumn))
+ return null;
+ AST.Expression expr = Boo.Lang.Parser.BooParser.ParseExpression("expression", expressionResult.Expression);
+ if (expr is AST.IntegerLiteralExpression)
+ return null; // no CC for "5."
+ ResolveVisitor visitor = new ResolveVisitor(this);
+ visitor.Visit(expr);
+ return visitor.ResolveResult;
+ }
+ #endregion
+
+ #region CtrlSpace
+ IClass GetPrimitiveClass(string systemType, string newName)
+ {
+ IClass c = pc.GetClass(systemType);
+ if (c == null) {
+ LoggingService.Warn("Could not find " + systemType);
+ return null;
+ }
+ DefaultClass c2 = new DefaultClass(c.CompilationUnit, newName);
+ c2.ClassType = c.ClassType;
+ c2.Modifiers = c.Modifiers;
+ c2.Documentation = c.Documentation;
+ c2.BaseTypes.AddRange(c.BaseTypes);
+ c2.Methods.AddRange(c.Methods);
+ c2.Fields.AddRange(c.Fields);
+ c2.Properties.AddRange(c.Properties);
+ c2.Events.AddRange(c.Events);
+ return c2;
+ }
+
+ public ArrayList CtrlSpace(int caretLine, int caretColumn, string fileName, string fileContent)
+ {
+ if (!Initialize(fileName, caretLine, caretColumn))
+ return null;
+ ArrayList result = GetImportedNamespaceContents();
+
+ NRResolver.AddContentsFromCalling(result, callingClass, callingMember);
+
+ return result;
+ }
+
+ // used by ctrl+space and resolve visitor (resolve identifier)
+ public ArrayList GetImportedNamespaceContents()
+ {
+ ArrayList list = new ArrayList();
+ IClass c;
+ foreach (KeyValuePair pair in BooAmbience.TypeConversionTable) {
+ c = GetPrimitiveClass(pair.Key, pair.Value);
+ if (c != null) list.Add(c);
+ }
+ NRResolver.AddImportedNamespaceContents(list, cu, callingClass);
+ return list;
+ }
+ #endregion
+ }
+}
diff --git a/src/AddIns/BackendBindings/Boo/BooBinding/Project/Src/CodeCompletion/CompletionBinding.cs b/src/AddIns/BackendBindings/Boo/BooBinding/Project/Src/CodeCompletion/CompletionBinding.cs
new file mode 100644
index 0000000000..3cef8aa611
--- /dev/null
+++ b/src/AddIns/BackendBindings/Boo/BooBinding/Project/Src/CodeCompletion/CompletionBinding.cs
@@ -0,0 +1,51 @@
+//
+// 2002-2005 AlphaSierraPapa
+// GNU General Public License
+//
+// $Revision$
+//
+
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+
+using ICSharpCode.Core;
+using ICSharpCode.TextEditor.Gui.CompletionWindow;
+using ICSharpCode.TextEditor.Document;
+using ICSharpCode.SharpDevelop;
+using ICSharpCode.SharpDevelop.Dom;
+using ICSharpCode.SharpDevelop.DefaultEditor.Gui.Editor;
+
+namespace Grunwald.BooBinding.CodeCompletion
+{
+ public class CompletionBinding : DefaultCodeCompletionBinding
+ {
+ public CompletionBinding()
+ {
+ this.EnableXmlCommentCompletion = false;
+ }
+
+ bool IsInComment(SharpDevelopTextAreaControl editor)
+ {
+ ExpressionFinder ef = new ExpressionFinder(editor.FileName);
+ int cursor = editor.ActiveTextAreaControl.Caret.Offset - 1;
+ return ef.SimplifyCode(editor.Document.GetText(0, cursor + 1), cursor) == null;
+ }
+
+ public override bool HandleKeyword(SharpDevelopTextAreaControl editor, string word)
+ {
+ switch (word.ToLower(CultureInfo.InvariantCulture)) {
+ case "import":
+ editor.ShowCompletionWindow(new CodeCompletionDataProvider(new ExpressionResult("Global", ExpressionContext.Type)), ' ');
+ return true;
+ case "as":
+ case "isa":
+ if (IsInComment(editor)) return false;
+ editor.ShowCompletionWindow(new CtrlSpaceCompletionDataProvider(ExpressionContext.Type), ' ');
+ return true;
+ default:
+ return base.HandleKeyword(editor, word);
+ }
+ }
+ }
+}
diff --git a/src/AddIns/BackendBindings/Boo/BooBinding/Project/Src/CodeCompletion/ConvertVisitor.cs b/src/AddIns/BackendBindings/Boo/BooBinding/Project/Src/CodeCompletion/ConvertVisitor.cs
new file mode 100644
index 0000000000..0eb747c704
--- /dev/null
+++ b/src/AddIns/BackendBindings/Boo/BooBinding/Project/Src/CodeCompletion/ConvertVisitor.cs
@@ -0,0 +1,393 @@
+//
+// 2002-2005 AlphaSierraPapa
+// GNU General Public License
+//
+// $Revision$
+//
+
+using System;
+using System.Collections.Generic;
+using ICSharpCode.Core;
+using ICSharpCode.SharpDevelop.Dom;
+using Boo.Lang.Compiler;
+using AST = Boo.Lang.Compiler.Ast;
+using Boo.Lang.Compiler.IO;
+using Boo.Lang.Compiler.Steps;
+
+namespace Grunwald.BooBinding.CodeCompletion
+{
+ public class ConvertVisitor : AbstractVisitorCompilerStep
+ {
+ int[] _lineLength;
+
+ public ConvertVisitor(int[] _lineLength, IProjectContent pc)
+ {
+ this._lineLength = _lineLength;
+ this._cu = new DefaultCompilationUnit(pc);
+ }
+
+ DefaultCompilationUnit _cu;
+
+ public DefaultCompilationUnit Cu {
+ get {
+ return _cu;
+ }
+ }
+
+ Stack _currentClass = new Stack();
+ bool _firstModule = true;
+
+ public override void Run()
+ {
+ LoggingService.Debug("RUN");
+ try {
+ Visit(CompileUnit);
+ } catch (Exception ex) {
+ MessageService.ShowError(ex);
+ }
+ }
+
+ private ModifierEnum GetModifier(AST.TypeMember m)
+ {
+ ModifierEnum r = ModifierEnum.None;
+ if (m.IsPublic) r |= ModifierEnum.Public;
+ if (m.IsProtected) r |= ModifierEnum.Protected;
+ if (m.IsPrivate) r |= ModifierEnum.Private;
+ if (m.IsInternal) r |= ModifierEnum.Internal;
+
+ if (m.IsStatic) r |= ModifierEnum.Static;
+ if (m is AST.Field) {
+ if (m.IsFinal) r |= ModifierEnum.Readonly;
+ } else {
+ if (!m.IsFinal) r |= ModifierEnum.Virtual;
+ }
+ if (m.IsAbstract) r |= ModifierEnum.Abstract;
+ if (m.IsOverride) r |= ModifierEnum.Override;
+ return r;
+ }
+
+ private int GetLineEnd(int line)
+ {
+ if (_lineLength == null || line < 1 || line > _lineLength.Length)
+ return 0;
+ else
+ return _lineLength[line - 1] + 1;
+ }
+
+ private DomRegion GetRegion(AST.Node m)
+ {
+ AST.LexicalInfo l = m.LexicalInfo;
+ if (l.Line < 0)
+ return DomRegion.Empty;
+ else
+ return new DomRegion(l.Line, 0 /*l.Column*/, l.Line, GetLineEnd(l.Line));
+ }
+
+ private DomRegion GetClientRegion(AST.Node m)
+ {
+ AST.LexicalInfo l = m.LexicalInfo;
+ if (l.Line < 0)
+ return DomRegion.Empty;
+ AST.SourceLocation l2;
+ if (m is AST.Method) {
+ l2 = ((AST.Method)m).Body.EndSourceLocation;
+ } else if (m is AST.Property) {
+ AST.Property p = (AST.Property)m;
+ if (p.Getter != null && p.Getter.Body != null) {
+ l2 = p.Getter.Body.EndSourceLocation;
+ if (p.Setter != null && p.Setter.Body != null) {
+ if (p.Setter.Body.EndSourceLocation.Line > l2.Line)
+ l2 = p.Setter.Body.EndSourceLocation;
+ }
+ } else if (p.Setter != null && p.Setter.Body != null) {
+ l2 = p.Setter.Body.EndSourceLocation;
+ } else {
+ l2 = p.EndSourceLocation;
+ }
+ } else {
+ l2 = m.EndSourceLocation;
+ }
+ if (l2 == null || l2.Line < 0 || l.Line == l2.Line)
+ return DomRegion.Empty;
+ // TODO: use l.Column / l2.Column when the tab-bug has been fixed
+ return new DomRegion(l.Line, GetLineEnd(l.Line), l2.Line, GetLineEnd(l2.Line));
+ }
+
+ public override void OnImport(AST.Import p)
+ {
+ DefaultUsing u = new DefaultUsing(_cu.ProjectContent);
+ if (p.Alias == null)
+ u.Usings.Add(p.Namespace);
+ else
+ u.Aliases[p.Alias.Name] = new GetClassReturnType(_cu.ProjectContent, p.Namespace, 0);
+ _cu.Usings.Add(u);
+ }
+
+ private IClass OuterClass {
+ get {
+ if (_currentClass.Count > 0)
+ return _currentClass.Peek();
+ else
+ return null;
+ }
+ }
+
+ void ConvertTemplates(AST.Node node, DefaultClass c)
+ {
+ c.TypeParameters = DefaultTypeParameter.EmptyTypeParameterList;
+ }
+
+ void ConvertTemplates(AST.Node node, DefaultMethod m)
+ {
+ m.TypeParameters = DefaultTypeParameter.EmptyTypeParameterList;
+ }
+
+ void ConvertAttributes(AST.Node node, AbstractDecoration c)
+ {
+ c.Attributes = DefaultAttribute.EmptyAttributeList;
+ c.Documentation = node.Documentation;
+ }
+
+ void ConvertParameters(AST.ParameterDeclarationCollection parameters, DefaultMethod m)
+ {
+ if (parameters == null || parameters.Count == 0) {
+ m.Parameters = DefaultParameter.EmptyParameterList;
+ } else {
+ AddParameters(parameters, m.Parameters);
+ }
+ }
+ void ConvertParameters(AST.ParameterDeclarationCollection parameters, DefaultProperty p)
+ {
+ if (parameters == null || parameters.Count == 0) {
+ p.Parameters = DefaultParameter.EmptyParameterList;
+ } else {
+ AddParameters(parameters, p.Parameters);
+ }
+ }
+ void AddParameters(AST.ParameterDeclarationCollection parameters, IList output)
+ {
+ DefaultParameter p = null;
+ foreach (AST.ParameterDeclaration par in parameters) {
+ p = new DefaultParameter(par.Name, CreateReturnType(par.Type), GetRegion(par));
+ if (par.IsByRef) p.Modifiers |= ParameterModifiers.Ref;
+ output.Add(p);
+ }
+ if (parameters.VariableNumber) {
+ p.Modifiers |= ParameterModifiers.Params;
+ }
+ }
+
+ IReturnType CreateReturnType(AST.TypeReference reference, IMethod method)
+ {
+ IClass c = OuterClass;
+ if (c == null) {
+ return CreateReturnType(reference, new DefaultClass(_cu, "___DummyClass"), method, 1, 1, _cu.ProjectContent, true);
+ } else {
+ return CreateReturnType(reference, c, method, c.Region.BeginLine + 1, 1, _cu.ProjectContent, true);
+ }
+ }
+ public static IReturnType CreateReturnType(AST.TypeReference reference, IClass callingClass,
+ IMember callingMember, int caretLine, int caretColumn,
+ IProjectContent projectContent,
+ bool useLazyReturnType)
+ {
+ if (reference == null) {
+ LoggingService.Warn("inferred return type!");
+ return ReflectionReturnType.Object;
+ }
+ if (reference is AST.ArrayTypeReference) {
+ AST.ArrayTypeReference arr = (AST.ArrayTypeReference)reference;
+ return new ArrayReturnType(CreateReturnType(arr.ElementType, callingClass, callingMember,
+ caretLine, caretColumn, projectContent, useLazyReturnType),
+ (int)arr.Rank.Value);
+ } else if (reference is AST.SimpleTypeReference) {
+ string name = ((AST.SimpleTypeReference)reference).Name;
+ if (BooAmbience.ReverseTypeConversionTable.ContainsKey(name))
+ return new GetClassReturnType(ProjectContentRegistry.Mscorlib, BooAmbience.ReverseTypeConversionTable[name], 0);
+ return new SearchClassReturnType(projectContent, callingClass, caretLine, caretColumn,
+ name, 0);
+ } else if (reference is AST.CallableTypeReference) {
+ return new AnonymousMethodReturnType();
+ } else {
+ throw new NotSupportedException("unknown reference type: " + reference.ToString());
+ }
+ }
+ IReturnType CreateReturnType(AST.TypeReference reference)
+ {
+ return CreateReturnType(reference, null);
+ }
+ IReturnType CreateReturnType(Type type)
+ {
+ return ReflectionReturnType.CreatePrimitive(type);
+ }
+ // TODO: Type inference
+ IReturnType CreateReturnType(AST.Field field)
+ {
+ return CreateReturnType(field.Type);
+ }
+ IReturnType CreateReturnType(AST.Method node, IMethod method)
+ {
+ return CreateReturnType(node.ReturnType, method);
+ }
+ IReturnType CreateReturnType(AST.Property property)
+ {
+ return CreateReturnType(property.Type);
+ }
+
+ public override void OnCallableDefinition(AST.CallableDefinition node)
+ {
+ LoggingService.Debug("OnCallableDefinition: " + node.FullName);
+ DomRegion region = GetRegion(node);
+ DefaultClass c = new DefaultClass(_cu, ClassType.Delegate, GetModifier(node), region, OuterClass);
+ ConvertAttributes(node, c);
+ c.BaseTypes.Add(ReflectionReturnType.CreatePrimitive(typeof(Delegate)));
+ c.FullyQualifiedName = node.FullName;
+ if (_currentClass.Count > 0) {
+ OuterClass.InnerClasses.Add(c);
+ } else {
+ _cu.Classes.Add(c);
+ }
+ _currentClass.Push(c); // necessary for CreateReturnType
+ ConvertTemplates(node, c);
+ IReturnType returnType = CreateReturnType(node.ReturnType);
+ DefaultMethod invokeMethod = new DefaultMethod("Invoke", returnType, ModifierEnum.Public, DomRegion.Empty, DomRegion.Empty, c);
+ ConvertParameters(node.Parameters, invokeMethod);
+ c.Methods.Add(invokeMethod);
+ invokeMethod = new DefaultMethod("BeginInvoke", CreateReturnType(typeof(IAsyncResult)), ModifierEnum.Public, DomRegion.Empty, DomRegion.Empty, c);
+ ConvertParameters(node.Parameters, invokeMethod);
+ invokeMethod.Parameters.Add(new DefaultParameter("callback", CreateReturnType(typeof(AsyncCallback)), DomRegion.Empty));
+ invokeMethod.Parameters.Add(new DefaultParameter("object", ReflectionReturnType.Object, DomRegion.Empty));
+ c.Methods.Add(invokeMethod);
+ invokeMethod = new DefaultMethod("EndInvoke", returnType, ModifierEnum.Public, DomRegion.Empty, DomRegion.Empty, c);
+ invokeMethod.Parameters.Add(new DefaultParameter("result", CreateReturnType(typeof(IAsyncResult)), DomRegion.Empty));
+ c.Methods.Add(invokeMethod);
+ _currentClass.Pop();
+ }
+
+ public override bool EnterClassDefinition(AST.ClassDefinition node)
+ {
+ EnterTypeDefinition(node, ClassType.Class);
+ return base.EnterClassDefinition(node);
+ }
+
+ public override bool EnterInterfaceDefinition(AST.InterfaceDefinition node)
+ {
+ EnterTypeDefinition(node, ClassType.Interface);
+ return base.EnterInterfaceDefinition(node);
+ }
+
+ public override bool EnterEnumDefinition(AST.EnumDefinition node)
+ {
+ EnterTypeDefinition(node, ClassType.Enum);
+ return base.EnterEnumDefinition(node);
+ }
+
+ public override bool EnterModule(AST.Module node)
+ {
+ if (_firstModule) EnterTypeDefinition(node, ClassType.Class);
+ _firstModule = false;
+ return base.EnterModule(node);
+ }
+
+ private void EnterTypeDefinition(AST.TypeDefinition node, ClassType classType)
+ {
+ LoggingService.Debug("Enter " + node.GetType().Name + " (" + node.FullName + ")");
+ DomRegion region = GetClientRegion(node);
+ DefaultClass c = new DefaultClass(_cu, classType, GetModifier(node), region, OuterClass);
+ c.FullyQualifiedName = node.FullName;
+ if (_currentClass.Count > 0)
+ _currentClass.Peek().InnerClasses.Add(c);
+ else
+ _cu.Classes.Add(c);
+ _currentClass.Push(c);
+ ConvertAttributes(node, c);
+ ConvertTemplates(node, c);
+ if (node.BaseTypes != null) {
+ foreach (AST.TypeReference r in node.BaseTypes) {
+ c.BaseTypes.Add(CreateReturnType(r));
+ }
+ }
+ }
+
+ public override void LeaveClassDefinition(AST.ClassDefinition node)
+ {
+ LeaveTypeDefinition(node);
+ base.LeaveClassDefinition(node);
+ }
+
+ public override void LeaveInterfaceDefinition(AST.InterfaceDefinition node)
+ {
+ LeaveTypeDefinition(node);
+ base.LeaveInterfaceDefinition(node);
+ }
+
+ public override void LeaveEnumDefinition(AST.EnumDefinition node)
+ {
+ LeaveTypeDefinition(node);
+ base.LeaveEnumDefinition(node);
+ }
+
+ public override void LeaveModule(AST.Module node)
+ {
+ if (_currentClass.Count != 0) LeaveTypeDefinition(node);
+ base.LeaveModule(node);
+ }
+
+ private void LeaveTypeDefinition(AST.TypeDefinition node)
+ {
+ DefaultClass c = _currentClass.Pop();
+ LoggingService.Debug("Leave "+node.GetType().Name+" "+node.FullName+" (Class = "+c.FullyQualifiedName+")");
+ }
+
+ public override void OnMethod(AST.Method node)
+ {
+ LoggingService.Debug("Method: " + node.FullName);
+ DefaultMethod method = new DefaultMethod(node.Name, null, GetModifier(node), GetRegion(node), GetClientRegion(node), OuterClass);
+ ConvertAttributes(node, method);
+ ConvertTemplates(node, method);
+ // return type must be assign AFTER ConvertTemplates
+ method.ReturnType = CreateReturnType(node, method);
+ ConvertParameters(node.Parameters, method);
+ _currentClass.Peek().Methods.Add(method);
+ }
+
+ public override void OnConstructor(AST.Constructor node)
+ {
+ if (node.Body.Statements.Count == 0) return;
+ Constructor ctor = new Constructor(GetModifier(node), GetRegion(node), GetClientRegion(node), OuterClass);
+ ConvertAttributes(node, ctor);
+ ConvertParameters(node.Parameters, ctor);
+ _currentClass.Peek().Methods.Add(ctor);
+ }
+
+ public override void OnEnumMember(AST.EnumMember node)
+ {
+ DefaultField field = new DefaultField(OuterClass.DefaultReturnType, node.Name, ModifierEnum.Const | ModifierEnum.Public, GetRegion(node), OuterClass);
+ ConvertAttributes(node, field);
+ OuterClass.Fields.Add(field);
+ }
+
+ public override void OnField(AST.Field node)
+ {
+ DefaultField field = new DefaultField(CreateReturnType(node), node.Name, GetModifier(node), GetRegion(node), OuterClass);
+ ConvertAttributes(node, field);
+ OuterClass.Fields.Add(field);
+ }
+
+ public override void OnEvent(AST.Event node)
+ {
+ DomRegion region = GetRegion(node);
+ DefaultEvent e = new DefaultEvent(node.Name, CreateReturnType(node.Type), GetModifier(node), region, region, OuterClass);
+ ConvertAttributes(node, e);
+ OuterClass.Events.Add(e);
+ }
+
+ public override void OnProperty(AST.Property node)
+ {
+ DefaultProperty property = new DefaultProperty(node.Name, CreateReturnType(node), GetModifier(node), GetRegion(node), GetClientRegion(node), OuterClass);
+ ConvertAttributes(node, property);
+ ConvertParameters(node.Parameters, property);
+ OuterClass.Properties.Add(property);
+ }
+ }
+}
diff --git a/src/AddIns/BackendBindings/Boo/BooBinding/Project/Src/CodeCompletion/ExpressionFinder.cs b/src/AddIns/BackendBindings/Boo/BooBinding/Project/Src/CodeCompletion/ExpressionFinder.cs
new file mode 100644
index 0000000000..ae6f58843a
--- /dev/null
+++ b/src/AddIns/BackendBindings/Boo/BooBinding/Project/Src/CodeCompletion/ExpressionFinder.cs
@@ -0,0 +1,359 @@
+//
+// 2002-2005 AlphaSierraPapa
+// GNU General Public License
+//
+// $Revision$
+//
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+using ICSharpCode.Core;
+using ICSharpCode.SharpDevelop.Dom;
+
+namespace Grunwald.BooBinding.CodeCompletion
+{
+ public class ExpressionFinder : IExpressionFinder
+ {
+ string fileName;
+
+ public ExpressionFinder(string fileName)
+ {
+ this.fileName = fileName;
+ }
+
+ #region RemoveLastPart
+ ///
+ /// Removes the last part of the expression.
+ ///
+ ///
+ /// "arr[i]" => "arr"
+ /// "obj.Field" => "obj"
+ /// "obj.Method(args,...)" => "obj.Method"
+ ///
+ public string RemoveLastPart(string expression)
+ {
+ throw new NotImplementedException();
+ }
+ #endregion
+
+ #region Find Expression
+ // The expression finder can find an expression in a text
+ // inText is the full source code, offset the cursor position
+
+ // example: "_var = 'bla'\n_var^\nprint _var"
+ // where ^ is the cursor position
+ // in that simple case the expression finder should return 'n_var'.
+
+ // but also complex expressions like
+ // 'filename.Substring(filename.IndexOf("var="))'
+ // should be returned if the cursor is after the last ).
+
+ // implementation note: the text after offset is irrelevant, so
+ // every operation on the string aborts after reaching offset
+
+ const string _closingBrackets = "}])";
+ const string _openingBrackets = "{[(";
+
+ public ExpressionResult FindExpression(string inText, int offset)
+ {
+ if (inText == null) return new ExpressionResult(null);
+ // OK, first try a kind of "quick find"
+ int i = offset + 1;
+ const string forbidden = "\"\'/#)]}";
+ const string finish = "([{=+*<,:";
+ int start = -1;
+ while (i > 0) {
+ i -= 1;
+ char c = inText[i];
+ if (finish.IndexOf(c) >= 0) {
+ start = i + 1;
+ break;
+ }
+ if (forbidden.IndexOf(c) >= 0) {
+ LoggingService.Debug("Quickfind failed: got " + c);
+ break;
+ }
+ if (char.IsWhiteSpace(c)) {
+ if (i > 6 && inText.Substring(i - 6, 6) == "import") {
+ i -= 7; // include 'import' in the expression
+ }
+ start = i + 1;
+ break;
+ }
+ if (start >= 0) {
+ if (CheckString(inText, start, "/#\"\'", "\r\n")) {
+ return GetExpression(inText, start, offset + 1);
+ }
+ }
+ }
+
+ inText = SimplifyCode(inText, offset);
+ if (inText == null) {
+ LoggingService.Debug("SimplifyCode returned null (cursor is in comment/string???)");
+ return new ExpressionResult(null);
+ }
+ // inText now has no comments or string literals, but the same meaning in
+ // terms of the type system
+ // Now go back until a finish-character or a whitespace character
+ Stack bracketStack = new Stack();
+ i = inText.Length;
+ while (i > 0) {
+ i -= 1;
+ char c = inText[i];
+ if (bracketStack.Count == 0 && (finish.IndexOf(c) >= 0 || Char.IsWhiteSpace(c))) {
+ return GetExpression(inText, i + 1, inText.Length);
+ }
+ int bracket = _closingBrackets.IndexOf(c);
+ if (bracket >= 0) {
+ bracketStack.Push(bracket);
+ }
+ bracket = _openingBrackets.IndexOf(c);
+ if (bracket >= 0) {
+ while (bracketStack.Count > 0 && bracketStack.Pop() > bracket);
+ }
+ }
+ return new ExpressionResult(null);
+ }
+
+ bool CheckString(string text, int offset, string forbidden, string finish)
+ {
+ int i = offset;
+ while (i > 0) {
+ i -= 1;
+ char c = text[i];
+ if (forbidden.IndexOf(c) >= 0) return false;
+ if (finish.IndexOf(c) >= 0) return true;
+ }
+ return true;
+ }
+
+ ExpressionResult GetExpression(string inText, int start, int end)
+ {
+ if (start == end) return new ExpressionResult(null);
+ StringBuilder b = new StringBuilder();
+ bool wasSpace = true;
+ int i = start;
+ while (i < end) {
+ char c = inText[i];
+ if (Char.IsWhiteSpace(c)) {
+ if (!wasSpace) b.Append(' ');
+ wasSpace = true;
+ } else {
+ wasSpace = false;
+ b.Append(c);
+ }
+ i += 1;
+ }
+ return new ExpressionResult(b.ToString());
+ }
+ // TODO: We could need some unit tests for this.
+ #endregion
+
+ #region Find Full Expression
+ public ExpressionResult FindFullExpression(string inText, int offset)
+ {
+ ExpressionResult result = FindExpression(inText, offset);
+ if (result.Expression == null)
+ return result;
+ StringBuilder b = new StringBuilder(result.Expression);
+ ResetStateMachine();
+ int state = -1;
+ // state = -1 : accepting current identifier
+ // state >= 0 : accepting brackets/parenthesis
+ Stack bracketStack = new Stack();
+ for (int i = offset + 1; i < inText.Length; i++) {
+ char c = inText[i];
+ if (state == -1) {
+ if (char.IsLetterOrDigit(c) || c == '_') {
+ // continue reading identifier
+ } else {
+ state = 0;
+ }
+ }
+ if (state >= 0) {
+ state = FeedStateMachine(state, c);
+ if (IsInNormalCode(state)) {
+ int bracket = _openingBrackets.IndexOf(c);
+ if (bracket >= 0) {
+ bracketStack.Push(bracket);
+ } else {
+ if (bracketStack.Count == 0) {
+ result.Expression = b.ToString();
+ return result;
+ }
+ }
+ bracket = _closingBrackets.IndexOf(c);
+ if (bracket >= 0) {
+ while (bracketStack.Count > 0 && bracketStack.Pop() > bracket);
+ }
+ }
+ }
+ b.Append(c);
+ }
+ return new ExpressionResult(null);
+ }
+ #endregion
+
+ #region State Machine / SimplifyCode
+ static readonly int[] inputTable;
+
+ static ExpressionFinder()
+ {
+ inputTable = new int[128];
+ for (int i = 0; i < inputTable.Length; i++) {
+ inputTable[i] = _elseIndex;
+ }
+ inputTable[ 34] = 0; // "
+ inputTable[ 39] = 1; // '
+ inputTable[ 92] = 2; // \
+ inputTable[ 10] = 3; // \n
+ inputTable[ 13] = 3; // \r
+ inputTable[ 36] = 4; // $
+ inputTable[123] = 5; // {
+ inputTable[125] = 6; // }
+ inputTable[ 35] = 7; // #
+ inputTable[ 47] = 8; // /
+ inputTable[ 42] = 9; // *
+ }
+
+ const int _elseIndex = 10;
+
+ static readonly
+ int[][] _stateTable = { // " ' \ \n $ { } # / * else
+ /* 0: in Code */ new int[] { 1 , 7 , 0 , 0 , 0 , 0 , 0 , 13 , 12 , 0 , 0 },
+ /* 1: after " */ new int[] { 2 , 6 , 10 , 0 , 8 , 6 , 6 , 6 , 6 , 6 , 6 },
+ /* 2: after "" */ new int[] { 3 , 7 , 0 , 0 , 0 , 0 , 0 , 13 , 12 , 0 , 0 },
+ /* 3: in """ */ new int[] { 4 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 3 },
+ /* 4: in """, " */ new int[] { 5 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 3 },
+ /* 5: in """, "" */ new int[] { 0 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 3 },
+ /* 6: in "-string */ new int[] { 0 , 6 , 10 , 0 , 8 , 6 , 6 , 6 , 6 , 6 , 6 },
+ /* 7: in '-string */ new int[] { 7 , 0 , 11 , 0 , 7 , 7 , 7 , 7 , 7 , 7 , 7 },
+ /* 8: after $ in " */ new int[] { 0 , 6 , 10 , 0 , 8 , 9 , 6 , 6 , 6 , 6 , 6 },
+ /* 9: in "{ */ new int[] { 9 , 9 , 9 , 9 , 9 , 9 , 6 , 9 , 9 , 9 , 9 },
+ /* 10: after \ in " */ new int[] { 6 , 6 , 6 , 0 , 6 , 6 , 6 , 6 , 6 , 6 , 6 },
+ /* 11: after \ in ' */ new int[] { 7 , 7 , 7 , 0 , 7 , 7 , 7 , 7 , 7 , 7 , 7 },
+ /* 12: after / */ new int[] { 1 , 7 , 0 , 0 , 0 , 0 , 0 , 0 , 13 ,-14 , 0 },
+ /* 13: line comment */ new int[] { 13 , 13 , 13 , 0 , 13 , 13 , 13 , 13 , 13 , 13 , 13 },
+ /* 14: block comment*/ new int[] { 14 , 14 , 14 , 14 , 14 , 14 , 14 , 14 , 14 , 15 , 14 },
+ /* 15: after * in bc*/ new int[] { 14 , 14 , 14 , 14 , 14 , 14 , 14 , 14 ,-15 , 15 , 14 }
+ };
+
+ static bool IsInNormalCode(int state)
+ {
+ return state == 0 || state == 2 || state == 12;
+ }
+
+ int commentblocks;
+
+ void ResetStateMachine()
+ {
+ commentblocks = 0;
+ }
+
+ int FeedStateMachine(int oldState, char c)
+ {
+ int charNum = (int)c;
+ int input;
+ if (charNum < inputTable.Length) {
+ input = inputTable[charNum];
+ } else {
+ input = _elseIndex;
+ }
+ int action = _stateTable[oldState][input];
+ if (action == -14) {
+ // enter block comment
+ commentblocks += 1;
+ return 14;
+ } else if (action == -15) {
+ // leave block comment
+ commentblocks -= 1;
+ if (commentblocks == 0)
+ return 0;
+ else
+ return 14;
+ }
+ return action;
+ }
+
+ /// This method makes boo source code "simpler" by removing all comments
+ /// and replacing all string litarals through string.Empty.
+ /// Regular expressions literals are replaced with the simple regex /a/
+ public string SimplifyCode(string inText, int offset)
+ {
+ StringBuilder result = new StringBuilder();
+ StringBuilder inStringResult = new StringBuilder(" ");
+ int state = 0;
+ ResetStateMachine();
+ int i = -1;
+ while (i < offset) {
+ i += 1;
+ char c = inText[i];
+ int action = FeedStateMachine(state, c);
+ if (action == 9) {
+ // enter inner string expression (${...})
+ if (state == 9)
+ inStringResult.Append(c);
+ else
+ inStringResult.Length = 1;
+ state = action;
+ } else if (action == 0 || action == 12) {
+ // go to normal code
+ if (action == 12) {
+ // after / could be a regular expression, do a special check for that
+ int regexEnd = SkipRegularExpression(inText, i, offset);
+ if (regexEnd > 0) {
+ i = regexEnd;
+ result.Append("/a");
+ } else if (regexEnd == -1) {
+ // cursor is in regex
+ return null;
+ }
+ }
+ if (state == 2 || (state >= 6 && state <= 11))
+ result.Append("string.Empty");
+ if (IsInNormalCode(state))
+ result.Append(c);
+ state = action;
+ } else {
+ state = action;
+ }
+ }
+ if (IsInNormalCode(state)) {
+ // cursor is in normal code
+ return result.ToString();
+ } else if (state == 9) {
+ // cursor is in inner string expression (${...})
+ return inStringResult.ToString();
+ } else {
+ // cursor is in comment/string
+ return null;
+ }
+ }
+
+ /// Skips the regular expression in inText at position pos. Returns end position of the ending / if
+ /// successful or 0 is no regular expression was found at the location.
+ /// Return -1 if maxOffset is inside the regular expression.
+ int SkipRegularExpression(string inText, int pos, int maxOffset)
+ {
+ bool containsWhitespace;
+ if (pos > 0) {
+ containsWhitespace = (inText[pos - 1] == '@');
+ } else {
+ containsWhitespace = false;
+ }
+ if (pos == maxOffset) return -1; // cursor is after / -> cursor inside regex
+ if (inText[pos + 1] == '/') return 0; // double // is comment, no regex
+ int i = pos;
+ while (i < maxOffset) {
+ i += 1;
+ if (!containsWhitespace && Char.IsWhiteSpace(inText, i))
+ return 0; // this is no regex
+ if (inText[i] == '/')
+ return i;
+ }
+ return -1; // maxOffset inside regex
+ }
+ #endregion
+ }
+}
diff --git a/src/AddIns/BackendBindings/Boo/BooBinding/Project/Src/CodeCompletion/ResolveVisitor.cs b/src/AddIns/BackendBindings/Boo/BooBinding/Project/Src/CodeCompletion/ResolveVisitor.cs
new file mode 100644
index 0000000000..507dc29cc0
--- /dev/null
+++ b/src/AddIns/BackendBindings/Boo/BooBinding/Project/Src/CodeCompletion/ResolveVisitor.cs
@@ -0,0 +1,484 @@
+//
+// 2002-2005 AlphaSierraPapa
+// GNU General Public License
+//
+// $Revision$
+//
+
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using ICSharpCode.Core;
+using ICSharpCode.SharpDevelop.Dom;
+using Boo.Lang.Compiler.Ast;
+
+namespace Grunwald.BooBinding.CodeCompletion
+{
+ public class ResolveVisitor : DepthFirstVisitor
+ {
+ #region Field + Constructor
+ BooResolver resolver;
+ ResolveResult resolveResult;
+ IClass callingClass;
+ IProjectContent projectContent;
+ ICompilationUnit cu;
+
+ public ResolveVisitor(BooResolver resolver)
+ {
+ this.resolver = resolver;
+ this.callingClass = resolver.CallingClass;
+ this.projectContent = resolver.ProjectContent;
+ this.cu = resolver.CompilationUnit;
+ }
+
+ public ResolveResult ResolveResult {
+ get {
+ return resolveResult;
+ }
+ }
+ #endregion
+
+ #region Make Result
+ void MakeResult(IReturnType type)
+ {
+ if (type == null)
+ resolveResult = null;
+ else
+ resolveResult = new ResolveResult(callingClass, resolver.CallingMember, type);
+ }
+
+ void MakeLiteralResult(string fullTypeName)
+ {
+ resolveResult = new ResolveResult(callingClass, resolver.CallingMember,
+ new GetClassReturnType(projectContent, fullTypeName, 0));
+ }
+
+ void MakeResult(IMember member)
+ {
+ IField field = member as IField;
+ if (field != null && (field.IsLocalVariable || field.IsParameter)) {
+ resolveResult = new LocalResolveResult(resolver.CallingMember, field);
+ } else if (member != null) {
+ resolveResult = new MemberResolveResult(callingClass, resolver.CallingMember, member);
+ } else {
+ resolveResult = null;
+ }
+ }
+
+ void MakeTypeResult(IClass c)
+ {
+ resolveResult = new TypeResolveResult(callingClass, resolver.CallingMember, c);
+ }
+
+ void MakeTypeResult(IReturnType rt)
+ {
+ resolveResult = new TypeResolveResult(callingClass, resolver.CallingMember, rt);
+ }
+
+ void MakeMethodResult(IReturnType type, string methodName)
+ {
+ resolveResult = new MethodResolveResult(callingClass, resolver.CallingMember, type, methodName);
+ }
+
+ void MakeNamespaceResult(string namespaceName)
+ {
+ resolveResult = new NamespaceResolveResult(callingClass, resolver.CallingMember, namespaceName);
+ }
+
+ static bool IsSameName(string name1, string name2)
+ {
+ // boo is currently always case sensitive
+ return name1 == name2;
+ }
+ #endregion
+
+ #region Resolve Identifier
+ public override void OnReferenceExpression(ReferenceExpression node)
+ {
+ string identifier = node.Name;
+ bool wasResolved = ResolveIdentifier(identifier);
+ if (wasResolved && resolveResult is TypeResolveResult) {
+ return;
+ }
+ // was not resolved or was resolved as local, member etc.
+ ResolveResult oldResult = resolveResult;
+ resolveResult = null;
+ // Try to resolve as type:
+ IReturnType t = projectContent.SearchType(identifier, 0, callingClass, cu, resolver.CaretLine, resolver.CaretColumn);
+ if (t != null) {
+ MakeTypeResult(t);
+ } else {
+ if (callingClass != null) {
+ if (resolver.CallingMember is IMethod) {
+ foreach (ITypeParameter typeParameter in (resolver.CallingMember as IMethod).TypeParameters) {
+ if (IsSameName(identifier, typeParameter.Name)) {
+ MakeTypeResult(new GenericReturnType(typeParameter));
+ return;
+ }
+ }
+ }
+ foreach (ITypeParameter typeParameter in callingClass.TypeParameters) {
+ if (IsSameName(identifier, typeParameter.Name)) {
+ MakeTypeResult(new GenericReturnType(typeParameter));
+ return;
+ }
+ }
+ }
+ }
+ if (!wasResolved)
+ return; // return type result, if existant
+ if (resolveResult == null) {
+ resolveResult = oldResult;
+ } else {
+ // TODO: return type or mixed dependant on context!
+ resolveResult = new MixedResolveResult(oldResult, resolveResult);
+ }
+ }
+
+ bool ResolveIdentifier(string identifier)
+ {
+ resolveResult = null;
+ if (resolver.CallingMember != null) {
+ // TODO: Search local variables
+
+ IMethodOrProperty method = resolver.CallingMember as IMethodOrProperty;
+ if (method != null) {
+ foreach (IParameter p in method.Parameters) {
+ if (IsSameName(p.Name, identifier)) {
+ MakeResult(new DefaultField.ParameterField(p.ReturnType, p.Name, p.Region, callingClass));
+ return true;
+ }
+ }
+ if (method is IProperty && IsSameName(identifier, "value")) {
+ if (((IProperty)method).SetterRegion.IsInside(resolver.CaretLine, resolver.CaretColumn)) {
+ MakeResult(new DefaultField.ParameterField(method.ReturnType, "value", method.Region, callingClass));
+ return true;
+ }
+ }
+ }
+ }
+ if (callingClass == null)
+ return false;
+ if (ResolveMember(callingClass.DefaultReturnType, identifier))
+ return true;
+
+ string namespaceName = projectContent.SearchNamespace(identifier, callingClass, cu, resolver.CaretLine, resolver.CaretColumn);
+ if (namespaceName != null && namespaceName.Length > 0) {
+ MakeNamespaceResult(namespaceName);
+ return true;
+ }
+
+ // Boo can import classes:
+ foreach (IUsing @using in cu.Usings) {
+ foreach (string import in @using.Usings) {
+ IClass c = projectContent.GetClass(import);
+ if (c != null) {
+ if (ResolveMember(c.DefaultReturnType, identifier))
+ return true;
+ }
+ }
+ }
+ // Boo can import modules:
+ foreach (object o in resolver.GetImportedNamespaceContents()) {
+ IClass c = o as IClass;
+ if (c != null && IsSameName(identifier, c.Name)) {
+ MakeTypeResult(c);
+ return true;
+ }
+ IMember member = o as IMember;
+ if (member != null && IsSameName(identifier, member.Name)) {
+ if (member is IMethod) {
+ MakeMethodResult(member.DeclaringType.DefaultReturnType, member.Name);
+ } else {
+ MakeResult(member);
+ }
+ return true;
+ }
+ }
+ return false;
+ }
+ #endregion
+
+ #region Resolve Member
+ public override void OnMemberReferenceExpression(MemberReferenceExpression node)
+ {
+ resolveResult = null;
+ node.Target.Accept(this);
+ if (resolveResult is NamespaceResolveResult) {
+ string namespaceName = (resolveResult as NamespaceResolveResult).Name;
+ string combinedName;
+ if (namespaceName.Length == 0)
+ combinedName = node.Name;
+ else
+ combinedName = namespaceName + "." + node.Name;
+ if (projectContent.NamespaceExists(combinedName)) {
+ MakeNamespaceResult(combinedName);
+ return;
+ }
+ IClass c = projectContent.GetClass(combinedName);
+ if (c != null) {
+ MakeTypeResult(c);
+ return;
+ }
+ // go through the members of the modules in that namespace
+ foreach (object o in projectContent.GetNamespaceContents(namespaceName)) {
+ IMember member = o as IMember;
+ if (member != null && IsSameName(member.Name, node.Name)) {
+ if (member is IMethod) {
+ MakeMethodResult(member.DeclaringType.DefaultReturnType, member.Name);
+ } else {
+ MakeResult(member);
+ }
+ break;
+ }
+ }
+ } else {
+ if (resolveResult != null) {
+ ResolveMember(resolveResult.ResolvedType, node.Name);
+ }
+ }
+ }
+
+ bool ResolveMember(IReturnType type, string memberName)
+ {
+ if (type == null)
+ return false;
+ bool isClassInInheritanceTree = false;
+ if (callingClass != null)
+ isClassInInheritanceTree = callingClass.IsTypeInInheritanceTree(type.GetUnderlyingClass());
+ foreach (IProperty p in type.GetProperties()) {
+ if (IsSameName(p.Name, memberName)) {
+ MakeResult(p);
+ return true;
+ }
+ }
+ foreach (IField f in type.GetFields()) {
+ if (IsSameName(f.Name, memberName)) {
+ MakeResult(f);
+ return true;
+ }
+ }
+ foreach (IEvent e in type.GetEvents()) {
+ if (IsSameName(e.Name, memberName)) {
+ MakeResult(e);
+ return true;
+ }
+ }
+ foreach (IMethod m in type.GetMethods()) {
+ if (IsSameName(m.Name, memberName)) {
+ MakeMethodResult(type, memberName);
+ return true;
+ }
+ }
+ return false;
+ }
+ #endregion
+
+ #region Resolve Method Invocation
+ public override void OnMethodInvocationExpression(MethodInvocationExpression node)
+ {
+ resolveResult = null;
+ node.Target.Accept(this);
+ if (resolveResult == null)
+ return;
+ if (resolveResult is MethodResolveResult) {
+ // normal method call
+ string methodName = ((MethodResolveResult)resolveResult).Name;
+ IReturnType containingType = ((MethodResolveResult)resolveResult).ContainingType;
+
+ List methods = new List();
+ bool isClassInInheritanceTree = false;
+ if (callingClass != null)
+ isClassInInheritanceTree = callingClass.IsTypeInInheritanceTree(containingType.GetUnderlyingClass());
+
+ foreach (IMethod m in containingType.GetMethods()) {
+ if (IsSameName(m.Name, methodName)
+ && m.IsAccessible(callingClass, isClassInInheritanceTree)
+ ) {
+ methods.Add(m);
+ }
+ }
+ ResolveInvocation(methods, node.Arguments);
+ } else if (resolveResult is TypeResolveResult || resolveResult is MixedResolveResult) {
+ TypeResolveResult trr = resolveResult as TypeResolveResult;
+ if (trr == null)
+ trr = (resolveResult as MixedResolveResult).TypeResult;
+ if (trr != null && trr.ResolvedClass != null) {
+ List methods = new List();
+ bool isClassInInheritanceTree = false;
+ if (callingClass != null)
+ isClassInInheritanceTree = callingClass.IsTypeInInheritanceTree(trr.ResolvedClass);
+
+ foreach (IMethod m in trr.ResolvedClass.Methods) {
+ if (m.IsConstructor && !m.IsStatic
+ && m.IsAccessible(callingClass, isClassInInheritanceTree))
+ {
+ methods.Add(m);
+ }
+ }
+ ResolveInvocation(methods, node.Arguments);
+ } else {
+ resolveResult = null;
+ }
+ } else if (resolveResult.ResolvedType != null) {
+ // maybe event or callable call or call on System.Type -> constructor by reflection
+ IClass c = resolveResult.ResolvedType.GetUnderlyingClass();
+ if (c != null) {
+ if (c.ClassType == ClassType.Delegate) {
+ // find the delegate's invoke method
+ IMethod invoke = c.Methods.Find(delegate(IMethod innerMethod) { return innerMethod.Name == "Invoke"; });
+ if (invoke != null) {
+ resolveResult.ResolvedType = invoke.ReturnType;
+ }
+ } else if (c.FullyQualifiedName == "System.Type") {
+ resolveResult.ResolvedType = ReflectionReturnType.Object;
+ } else {
+ resolveResult = null;
+ }
+ } else {
+ resolveResult = null;
+ }
+ } else {
+ resolveResult = null;
+ }
+ }
+
+ void ResolveInvocation(List methods, ExpressionCollection arguments)
+ {
+ resolveResult = null;
+ if (methods.Count == 0) {
+ return;
+ }
+ // MemberLookupHelper does type argument inference and type substitution for us
+ IReturnType[] types = new IReturnType[arguments.Count];
+ for (int i = 0; i < types.Length; ++i) {
+ arguments[i].Accept(this);
+ types[i] = (resolveResult != null) ? resolveResult.ResolvedType : null;
+ resolveResult = null;
+ }
+ MakeResult(MemberLookupHelper.FindOverload(methods, new IReturnType[0], types));
+ }
+ #endregion
+
+ #region Resolve Slice Expression
+ public override void OnSlicingExpression(SlicingExpression node)
+ {
+ resolveResult = null;
+ }
+ #endregion
+
+ protected override void OnError(Node node, Exception error)
+ {
+ MessageService.ShowError(error, "ResolveVisitor: error processing " + node);
+ }
+
+ public override void OnCallableBlockExpression(CallableBlockExpression node)
+ {
+ MakeResult(new AnonymousMethodReturnType());
+ }
+
+ public override void OnCallableTypeReference(CallableTypeReference node)
+ {
+ MakeTypeResult(ConvertType(node));
+ }
+
+ public override void OnRELiteralExpression(RELiteralExpression node)
+ {
+ MakeLiteralResult("System.Text.RegularExpressions.Regex");
+ }
+
+ public override void OnCharLiteralExpression(CharLiteralExpression node)
+ {
+ MakeLiteralResult("System.Char");
+ }
+
+ public override void OnArrayLiteralExpression(ArrayLiteralExpression node)
+ {
+ // TODO: get real array type
+ MakeLiteralResult("System.Array");
+ }
+
+ public override void OnAsExpression(AsExpression node)
+ {
+ MakeResult(ConvertType(node.Type));
+ }
+
+ public override void OnCastExpression(CastExpression node)
+ {
+ MakeResult(ConvertType(node.Type));
+ }
+
+ public override void OnBoolLiteralExpression(BoolLiteralExpression node)
+ {
+ MakeResult(ReflectionReturnType.Bool);
+ }
+
+ public override void OnDoubleLiteralExpression(DoubleLiteralExpression node)
+ {
+ if (node.IsSingle)
+ MakeLiteralResult("System.Single");
+ else
+ MakeLiteralResult("System.Double");
+ }
+
+ public override void OnListLiteralExpression(ListLiteralExpression node)
+ {
+ MakeLiteralResult("Boo.Lang.List");
+ }
+
+ public override void OnHashLiteralExpression(HashLiteralExpression node)
+ {
+ MakeLiteralResult("Boo.Lang.Hash");
+ }
+
+ public override void OnIntegerLiteralExpression(IntegerLiteralExpression node)
+ {
+ if (node.IsLong)
+ MakeLiteralResult("System.Int64");
+ else
+ MakeResult(ReflectionReturnType.Int);
+ }
+
+ public override void OnNullLiteralExpression(NullLiteralExpression node)
+ {
+ MakeResult(NullReturnType.Instance);
+ }
+
+ public override void OnSelfLiteralExpression(SelfLiteralExpression node)
+ {
+ MakeResult(callingClass.DefaultReturnType);
+ }
+
+ public override void OnSuperLiteralExpression(SuperLiteralExpression node)
+ {
+ MakeResult(callingClass.BaseType);
+ }
+
+ public override void OnSimpleTypeReference(SimpleTypeReference node)
+ {
+ MakeTypeResult(ConvertType(node));
+ }
+
+ public override void OnStringLiteralExpression(StringLiteralExpression node)
+ {
+ MakeResult(ReflectionReturnType.String);
+ }
+
+ public override void OnTimeSpanLiteralExpression(TimeSpanLiteralExpression node)
+ {
+ MakeLiteralResult("System.TimeSpan");
+ }
+
+ public override void OnTypeofExpression(TypeofExpression node)
+ {
+ MakeLiteralResult("System.Type");
+ }
+
+ IReturnType ConvertType(TypeReference typeRef)
+ {
+ return ConvertVisitor.CreateReturnType(typeRef, callingClass, resolver.CallingMember,
+ resolver.CaretLine, resolver.CaretColumn,
+ projectContent, false);
+ }
+ }
+}
diff --git a/src/AddIns/BackendBindings/Boo/BooBinding/Project/Templates/ConsoleProject.xpt b/src/AddIns/BackendBindings/Boo/BooBinding/Project/Templates/ConsoleProject.xpt
new file mode 100644
index 0000000000..317a100834
--- /dev/null
+++ b/src/AddIns/BackendBindings/Boo/BooBinding/Project/Templates/ConsoleProject.xpt
@@ -0,0 +1,38 @@
+
+
+
+ ${res:Templates.Project.ConsoleProject.Name}
+ Boo
+ C#.Project.DOSProject
+ Boo
+ ${res:Templates.Project.ConsoleProject.Description}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/AddIns/BackendBindings/Boo/BooBinding/Project/Templates/FormsProject.xpt b/src/AddIns/BackendBindings/Boo/BooBinding/Project/Templates/FormsProject.xpt
new file mode 100644
index 0000000000..da0c8403ad
--- /dev/null
+++ b/src/AddIns/BackendBindings/Boo/BooBinding/Project/Templates/FormsProject.xpt
@@ -0,0 +1,96 @@
+
+
+
+ ${res:Templates.Project.WindowsApplication.Name}
+ Boo
+ C#.Project.Form
+ Boo
+ ${res:Templates.Project.WindowsApplication.Description}
+
+
+
+
+
+
+
+
+ ${ProjectName}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/AddIns/BackendBindings/Boo/BooBinding/Project/Templates/Library.xpt b/src/AddIns/BackendBindings/Boo/BooBinding/Project/Templates/Library.xpt
new file mode 100644
index 0000000000..3634404633
--- /dev/null
+++ b/src/AddIns/BackendBindings/Boo/BooBinding/Project/Templates/Library.xpt
@@ -0,0 +1,73 @@
+
+
+
+ ${res:Templates.Project.ClassLibrary.Name}
+ Boo
+ C#.Project.Library
+ Boo
+ ${res:Templates.Project.ClassLibrary.Description}
+
+
+
+
+
+
+
+
+ ${ProjectName}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/AddIns/BackendBindings/Boo/NRefactoryToBooConverter/Project/AssemblyInfo.cs b/src/AddIns/BackendBindings/Boo/NRefactoryToBooConverter/Project/AssemblyInfo.cs
new file mode 100644
index 0000000000..9792e3e822
--- /dev/null
+++ b/src/AddIns/BackendBindings/Boo/NRefactoryToBooConverter/Project/AssemblyInfo.cs
@@ -0,0 +1,50 @@
+#region license
+// Copyright (c) 2005, Daniel Grunwald (daniel@danielgrunwald.de)
+// All rights reserved.
+//
+// NRefactoryToBoo is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// NRefactoryToBoo is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with NRefactoryToBoo; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#endregion
+
+using System.Reflection;
+using System.Runtime.CompilerServices;
+
+// Information about this assembly is defined by the following
+// attributes.
+//
+// change them to the information which is associated with the assembly
+// you compile.
+
+[assembly: AssemblyTitle("NRefactoryToBooConverter")]
+[assembly: AssemblyDescription("Converts from NRefactory AST (C#, VB) to Boo AST")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("Daniel Grunwald")]
+[assembly: AssemblyProduct("BooBinding")]
+[assembly: AssemblyCopyright("(C) 2005, Daniel Grunwald")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// The assembly version has following format :
+//
+// Major.Minor.Build.Revision
+//
+// You can specify all values by your own or you can build default build and revision
+// numbers with the '*' character (the default):
+[assembly: AssemblyVersion(NRefactoryToBooConverter.VersionInfo.VersionNumber)]
+
+namespace NRefactoryToBooConverter {
+ public static class VersionInfo {
+ public const string VersionNumber = "0.1.*";
+ }
+}
diff --git a/src/AddIns/BackendBindings/Boo/NRefactoryToBooConverter/Project/BooPrinterVisitorWithComments.cs b/src/AddIns/BackendBindings/Boo/NRefactoryToBooConverter/Project/BooPrinterVisitorWithComments.cs
new file mode 100644
index 0000000000..5153eb94bf
--- /dev/null
+++ b/src/AddIns/BackendBindings/Boo/NRefactoryToBooConverter/Project/BooPrinterVisitorWithComments.cs
@@ -0,0 +1,202 @@
+#region license
+// Copyright (c) 2005, Daniel Grunwald (daniel@danielgrunwald.de)
+// All rights reserved.
+//
+// NRefactoryToBoo is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// NRefactoryToBoo is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with NRefactoryToBoo; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Drawing;
+using System.IO;
+using Boo.Lang.Compiler;
+using Boo.Lang.Compiler.Ast;
+using Boo.Lang.Compiler.Ast.Visitors;
+using ICSharpCode.NRefactory.Parser;
+
+namespace NRefactoryToBooConverter
+{
+ public class BooPrinterVisitorWithComments : BooPrinterVisitor, ISpecialVisitor
+ {
+ IEnumerator enumerator;
+ bool available; // true when more specials are available
+
+ public BooPrinterVisitorWithComments(IEnumerable specials, TextWriter writer)
+ : base(writer)
+ {
+ if (specials == null) throw new ArgumentNullException("specials");
+ enumerator = specials.GetEnumerator();
+ available = enumerator.MoveNext();
+ }
+
+ void AcceptPoint(LexicalInfo lex)
+ {
+ if (lex != null && lex.IsValid) {
+ AcceptPoint(lex.Line, lex.Column);
+ }
+ }
+
+ void AcceptPoint(SourceLocation loc)
+ {
+ if (loc != null && loc.IsValid) {
+ AcceptPoint(loc.Line, loc.Column);
+ }
+ }
+
+ ///
+ /// Writes all specials up to the specified location.
+ ///
+ void AcceptPoint(int line, int column)
+ {
+ while (available) {
+ Point b = enumerator.Current.StartPosition;
+ if (b.Y < line || (b.Y == line && b.X <= column)) {
+ WriteCurrent();
+ } else {
+ break;
+ }
+ }
+ }
+
+ void WriteCurrent()
+ {
+ enumerator.Current.AcceptVisitor(this, null);
+ available = enumerator.MoveNext();
+ }
+
+ ///
+ /// Outputs all missing specials to the writer.
+ ///
+ public void Finish()
+ {
+ while (available) {
+ WriteCurrent();
+ }
+ }
+
+ Node currentDocuNode;
+ bool isInEndMode = false;
+
+ public override bool Visit(Node node)
+ {
+ if (node == null) return base.Visit(node);
+ currentDocuNode = node;
+ AcceptPoint(node.LexicalInfo);
+ currentDocuNode = null;
+ bool result = base.Visit(node);
+ isInEndMode = true;
+ AcceptPoint(node.EndSourceLocation);
+ isInEndMode = false;
+ oldIndentation = _indent;
+ return result;
+ }
+
+ #region ICSharpCode.NRefactory.Parser.ISpecialVisitor interface implementation
+ int oldIndentation;
+
+ struct DelayedSpecial {
+ public readonly int Indentation;
+ public readonly string Format;
+ public readonly object[] Args;
+ public DelayedSpecial(int indentation, string Format, object[] Args) {
+ this.Indentation = indentation;
+ this.Format = Format;
+ this.Args = Args;
+ }
+ }
+
+ List delayedSpecials = new List();
+
+ bool writingDelayedSpecials;
+
+ public override void WriteLine()
+ {
+ if (_disableNewLine == 0) {
+ base.WriteLine();
+ if (!writingDelayedSpecials) {
+ writingDelayedSpecials = true;
+ int tmp = _indent;
+ foreach (DelayedSpecial special in delayedSpecials) {
+ _indent = special.Indentation;
+ WriteLine(special.Format, special.Args);
+ }
+ delayedSpecials.Clear();
+ writingDelayedSpecials = false;
+ _indent = tmp;
+ }
+ oldIndentation = _indent;
+ }
+ }
+
+ void WriteSpecialText(bool writeInline, string format, params object[] args)
+ {
+ // write comment in it's own line
+ if (_needsIndenting || writeInline) {
+ int tmp = _indent;
+ if (isInEndMode) {
+ _indent = oldIndentation;
+ }
+ if (writeInline && !_needsIndenting) {
+ WriteIndented(format, args);
+ } else {
+ WriteLine(format, args);
+ }
+ if (isInEndMode) {
+ _indent = tmp;
+ }
+ } else {
+ // comment is in the middle of line
+ // put it after the next line
+ delayedSpecials.Add(new DelayedSpecial(isInEndMode ? oldIndentation : _indent, format, args));
+ }
+ }
+
+ object ISpecialVisitor.Visit(ISpecial special, object data)
+ {
+ throw new NotImplementedException();
+ }
+
+ object ISpecialVisitor.Visit(BlankLine special, object data)
+ {
+ WriteSpecialText(false, "");
+ return null;
+ }
+
+ object ISpecialVisitor.Visit(Comment special, object data)
+ {
+ switch (special.CommentType) {
+ case CommentType.Documentation:
+ if (currentDocuNode == null)
+ goto default;
+ currentDocuNode.Documentation += special.CommentText;
+ break;
+ case CommentType.Block:
+ WriteSpecialText(true, "/*{0}*/", special.CommentText);
+ break;
+ default:
+ WriteSpecialText(false, "//{0}", special.CommentText);
+ break;
+ }
+ return null;
+ }
+
+ object ISpecialVisitor.Visit(PreProcessingDirective special, object data)
+ {
+ WriteSpecialText(false, "{0} {1}", special.Cmd, special.Arg);
+ return null;
+ }
+ #endregion
+ }
+}
diff --git a/src/AddIns/BackendBindings/Boo/NRefactoryToBooConverter/Project/ConvertVisitor.cs b/src/AddIns/BackendBindings/Boo/NRefactoryToBooConverter/Project/ConvertVisitor.cs
new file mode 100644
index 0000000000..198bb578e5
--- /dev/null
+++ b/src/AddIns/BackendBindings/Boo/NRefactoryToBooConverter/Project/ConvertVisitor.cs
@@ -0,0 +1,283 @@
+#region license
+// Copyright (c) 2005, Daniel Grunwald (daniel@danielgrunwald.de)
+// All rights reserved.
+//
+// NRefactoryToBoo is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// NRefactoryToBoo is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with NRefactoryToBoo; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Drawing;
+using ICSharpCode.NRefactory.Parser;
+using ICSharpCode.NRefactory.Parser.AST;
+using Boo.Lang.Compiler;
+using B = Boo.Lang.Compiler.Ast;
+
+namespace NRefactoryToBooConverter
+{
+ public partial class ConvertVisitor : IASTVisitor
+ {
+ string fileName;
+ CompilerErrorCollection errors;
+ CompilerWarningCollection warnings;
+ StringComparer nameComparer;
+ ConverterSettings settings;
+
+ B.Module module;
+
+ public ConvertVisitor(ConverterSettings settings)
+ {
+ this.settings = settings;
+ this.fileName = settings.FileName;
+ this.errors = settings.Errors;
+ this.warnings = settings.Warnings;
+ this.nameComparer = settings.NameComparer;
+ }
+
+ int generatedNameNumber;
+
+ string GenerateName()
+ {
+ return settings.NameGenerationPrefix + (++generatedNameNumber).ToString(System.Globalization.NumberFormatInfo.InvariantInfo);
+ }
+
+ B.LexicalInfo lastLexicalInfo;
+
+ B.LexicalInfo GetLexicalInfo(INode node)
+ {
+ if (node == null)
+ return new B.LexicalInfo(fileName);
+ Point point = node.StartLocation;
+ if (!point.IsEmpty) {
+ lastLexicalInfo = new B.LexicalInfo(fileName, point.Y, point.X);
+ }
+ if (lastLexicalInfo == null) {
+ lastLexicalInfo = new B.LexicalInfo(fileName);
+ }
+ return lastLexicalInfo;
+ }
+
+ void AddError(B.LexicalInfo lex, string errorMessage)
+ {
+ errors.Add(new CompilerError(lex, errorMessage));
+ }
+
+ void AddError(INode node, string errorMessage)
+ {
+ AddError(GetLexicalInfo(node), errorMessage);
+ }
+
+ void AddWarning(B.LexicalInfo lex, string warningMessage)
+ {
+ warnings.Add(new CompilerWarning(warningMessage));
+ }
+
+ void AddWarning(INode node, string warningMessage)
+ {
+ AddWarning(GetLexicalInfo(node), warningMessage);
+ }
+
+ B.SourceLocation GetEndLocation(INode node)
+ {
+ return GetLocation(node.EndLocation);
+ }
+
+ B.SourceLocation GetLocation(Point point)
+ {
+ return new B.SourceLocation(point.Y, point.X);
+ }
+
+ B.TypeMemberModifiers ConvertModifier(AttributedNode node, B.TypeMemberModifiers defaultVisibility)
+ {
+ Modifier m = node.Modifier;
+ B.TypeMemberModifiers r = B.TypeMemberModifiers.None;
+ if ((m & Modifier.Private) != 0)
+ r |= B.TypeMemberModifiers.Private;
+ if ((m & Modifier.Internal) != 0)
+ r |= B.TypeMemberModifiers.Internal;
+ if ((m & Modifier.Public) != 0)
+ r |= B.TypeMemberModifiers.Public;
+ if ((m & Modifier.Protected) != 0)
+ r |= B.TypeMemberModifiers.Protected;
+ if (r == B.TypeMemberModifiers.None)
+ r = defaultVisibility;
+
+ if ((m & Modifier.Abstract) != 0)
+ r |= B.TypeMemberModifiers.Abstract;
+ if ((m & Modifier.Virtual) != 0)
+ r |= B.TypeMemberModifiers.Virtual;
+ if ((m & Modifier.Sealed) != 0)
+ r |= B.TypeMemberModifiers.Final;
+ if ((m & Modifier.Static) != 0) {
+ r |= B.TypeMemberModifiers.Static;
+ } else if (currentType != null && currentType.IsStatic) {
+ if (!(node is TypeDeclaration))
+ r |= B.TypeMemberModifiers.Static;
+ } else {
+ if ((m & (Modifier.Abstract | Modifier.Virtual | Modifier.Override)) == 0) {
+ if (node is MethodDeclaration || node is PropertyDeclaration)
+ r |= B.TypeMemberModifiers.Final;
+ }
+ }
+ if ((m & Modifier.Override) != 0)
+ r |= B.TypeMemberModifiers.Override;
+ if ((m & Modifier.Readonly) != 0 && !(node is PropertyDeclaration)) {
+ // allow readonly on VB properties only
+ AddWarning(node, "readonly modifier is ignored");
+ }
+ if ((m & Modifier.Const) != 0)
+ r |= B.TypeMemberModifiers.Final;
+ if ((m & Modifier.New) != 0) {
+ AddError(node, "shadowing is not supported");
+ }
+ if ((m & Modifier.Partial) != 0) {
+ AddError(node, "Partial types are not supported");
+ }
+ if ((m & Modifier.Extern) != 0) {
+ AddError(node, "Extern modifier is not supported");
+ }
+ if ((m & Modifier.Volatile) != 0) {
+ AddError(node, "Volatile modifier is not supported");
+ }
+ if ((m & Modifier.Unsafe) != 0) {
+ AddError(node, "Unsafe modifier is not supported");
+ }
+ if ((m & Modifier.Overloads) != 0) {
+ // not necessary in Boo
+ }
+ if ((m & Modifier.WithEvents) != 0) {
+ // not necessary in Boo
+ }
+ if ((m & Modifier.Default) != 0) {
+ ParametrizedNode parametrizedNode = node as ParametrizedNode;
+ string name = null;
+ if (node is IndexerDeclaration) {
+ name = DefaultIndexerName;
+ } else if (parametrizedNode != null) {
+ name = parametrizedNode.Name;
+ } else {
+ AddError(node, "Default modifier is not supported on this member.");
+ }
+ if (name != null) {
+ currentType.Attributes.Add(MakeAttribute("System.Reflection.DefaultMember", new B.StringLiteralExpression(name)));
+ }
+ }
+ if ((m & Modifier.Narrowing) != 0) {
+ AddError(node, "Narrowing modifier is not supported");
+ }
+ if ((m & Modifier.Widening) != 0) {
+ AddError(node, "Widening modifier is not supported");
+ }
+ return r;
+ }
+
+ B.Attribute MakeAttribute(string name, params B.Expression[] arguments)
+ {
+ B.Attribute a = new B.Attribute(lastLexicalInfo, name);
+ foreach (B.Expression arg in arguments) {
+ a.Arguments.Add(arg);
+ }
+ return a;
+ }
+
+ void ConvertTypeReferences(List input, B.TypeReferenceCollection output)
+ {
+ foreach (TypeReference t in input) {
+ B.TypeReference r = ConvertTypeReference(t);
+ if (r != null) {
+ output.Add(r);
+ }
+ }
+ }
+
+ Dictionary intrinsicTypeDictionary;
+
+ class BooTypeSystemServices : Boo.Lang.Compiler.TypeSystem.TypeSystemServices
+ {
+ public System.Collections.Hashtable Primitives {
+ get {
+ return _primitives;
+ }
+ }
+ }
+
+ string GetIntrinsicTypeName(string typeName)
+ {
+ if (settings.SimplifyTypeNames) {
+ if (intrinsicTypeDictionary == null) {
+ intrinsicTypeDictionary = new Dictionary();
+ foreach (System.Collections.DictionaryEntry entry in new BooTypeSystemServices().Primitives) {
+ try {
+ intrinsicTypeDictionary.Add(((Boo.Lang.Compiler.TypeSystem.IEntity)entry.Value).FullName, (string)entry.Key);
+ } catch (ArgumentException) {}
+ }
+ }
+ string result;
+ if (intrinsicTypeDictionary.TryGetValue(typeName, out result))
+ return result;
+ }
+ return typeName;
+ }
+
+ B.TypeReference ConvertTypeReference(TypeReference t)
+ {
+ if (t == null || t.IsNull)
+ return null;
+ B.TypeReference r = new B.SimpleTypeReference(GetLexicalInfo(t), GetIntrinsicTypeName(t.SystemType));
+ if (t.GenericTypes.Count > 0) {
+ AddError(t, "Consuming generics is not supported by boo.");
+ }
+ if (t.IsArrayType) {
+ for (int i = t.RankSpecifier.Length - 1; i >= 0; --i) {
+ r = new B.ArrayTypeReference(GetLexicalInfo(t), r, new B.IntegerLiteralExpression(t.RankSpecifier[i] + 1));
+ }
+ }
+ if (t.PointerNestingLevel != 0) {
+ AddError(t, "Pointers are not supported by boo.");
+ }
+ return r;
+ }
+
+ B.TypeReference ConvertTypeReference(B.Expression expr)
+ {
+ B.TypeofExpression te = expr as B.TypeofExpression;
+ if (te != null)
+ return te.Type;
+ if (expr is B.ReferenceExpression) {
+ return new B.SimpleTypeReference(expr.ToCodeString());
+ }
+ AddError(expr.LexicalInfo, "Expected type, but found expression.");
+ return null;
+ }
+
+ ///
+ /// Convert TypeReference and wrap it into an TypeofExpression.
+ ///
+ B.TypeofExpression WrapTypeReference(TypeReference t)
+ {
+ return new B.TypeofExpression(GetLexicalInfo(t), ConvertTypeReference(t));
+ }
+
+ public object Visit(TypeReference typeReference, object data)
+ {
+ return ConvertTypeReference(typeReference);
+ }
+
+ public object Visit(InnerClassTypeReference typeReference, object data)
+ {
+ return ConvertTypeReference(typeReference);
+ }
+ }
+}
diff --git a/src/AddIns/BackendBindings/Boo/NRefactoryToBooConverter/Project/ConvertVisitorExpressions.cs b/src/AddIns/BackendBindings/Boo/NRefactoryToBooConverter/Project/ConvertVisitorExpressions.cs
new file mode 100644
index 0000000000..6670223aa7
--- /dev/null
+++ b/src/AddIns/BackendBindings/Boo/NRefactoryToBooConverter/Project/ConvertVisitorExpressions.cs
@@ -0,0 +1,519 @@
+#region license
+// Copyright (c) 2005, Daniel Grunwald (daniel@danielgrunwald.de)
+// All rights reserved.
+//
+// NRefactoryToBoo is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// NRefactoryToBoo is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with NRefactoryToBoo; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#endregion
+
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using ICSharpCode.NRefactory.Parser;
+using ICSharpCode.NRefactory.Parser.AST;
+using Boo.Lang.Compiler;
+using B = Boo.Lang.Compiler.Ast;
+
+namespace NRefactoryToBooConverter
+{
+ partial class ConvertVisitor
+ {
+ void ConvertExpressions(IEnumerable input, B.ExpressionCollection output)
+ {
+ foreach (Expression e in input) {
+ B.Expression expr = ConvertExpression(e);
+ if (expr != null) {
+ output.Add(expr);
+ }
+ }
+ }
+
+ B.Expression ConvertExpression(Expression expr)
+ {
+ if (expr.IsNull)
+ return null;
+ return (B.Expression)expr.AcceptVisitor(this, null);
+ }
+
+ B.ReferenceExpression MakeReferenceExpression(string fullName)
+ {
+ string[] parts = fullName.Split('.');
+ B.ReferenceExpression r = new B.ReferenceExpression(lastLexicalInfo, parts[0]);
+ for (int i = 1; i < parts.Length; i++)
+ r = new B.MemberReferenceExpression(lastLexicalInfo, r, parts[i]);
+ return r;
+ }
+
+ B.MethodInvocationExpression MakeMethodCall(string fullName, params B.Expression[] arguments)
+ {
+ return new B.MethodInvocationExpression(MakeReferenceExpression(fullName), arguments);
+ }
+
+ public object Visit(PrimitiveExpression pe, object data)
+ {
+ object val = pe.Value;
+ if (val == null) {
+ return new B.NullLiteralExpression(GetLexicalInfo(pe));
+ }
+ if (val is string) {
+ return new B.StringLiteralExpression(GetLexicalInfo(pe), (string)val);
+ }
+ if (val is char) {
+ return new B.CharLiteralExpression(GetLexicalInfo(pe), ((char)val).ToString());
+ }
+ if (val is bool) {
+ return new B.BoolLiteralExpression(GetLexicalInfo(pe), (bool)val);
+ }
+ if (val is byte) {
+ AddWarning(pe, "Converting byte literal to int literal");
+ return new B.IntegerLiteralExpression(GetLexicalInfo(pe), (byte)val, false);
+ }
+ if (val is short) {
+ AddWarning(pe, "Converting short literal to int literal");
+ return new B.IntegerLiteralExpression(GetLexicalInfo(pe), (short)val, false);
+ }
+ if (val is int) {
+ return new B.IntegerLiteralExpression(GetLexicalInfo(pe), (int)val, false);
+ }
+ if (val is long) {
+ return new B.IntegerLiteralExpression(GetLexicalInfo(pe), (long)val, true);
+ }
+ if (val is sbyte) {
+ AddWarning(pe, "Converting sbyte literal to int literal");
+ return new B.IntegerLiteralExpression(GetLexicalInfo(pe), (sbyte)val, false);
+ }
+ if (val is ushort) {
+ AddWarning(pe, "Converting ushort literal to int literal");
+ return new B.IntegerLiteralExpression(GetLexicalInfo(pe), (ushort)val, false);
+ }
+ if (val is uint) {
+ AddWarning(pe, "Converting uint literal to int/long literal");
+ return new B.IntegerLiteralExpression(GetLexicalInfo(pe), (uint)val);
+ }
+ if (val is ulong) {
+ AddWarning(pe, "Converting ulong literal to long literal");
+ return new B.IntegerLiteralExpression(GetLexicalInfo(pe), (long)((ulong)val), true);
+ }
+ if (val is float) {
+ return new B.DoubleLiteralExpression(GetLexicalInfo(pe), (float)val, true);
+ }
+ if (val is double) {
+ return new B.DoubleLiteralExpression(GetLexicalInfo(pe), (double)val, false);
+ }
+ AddError(pe, "Unknown primitive literal of type " + val.GetType().FullName);
+ return null;
+ }
+
+ public object Visit(IdentifierExpression identifierExpression, object data)
+ {
+ return new B.ReferenceExpression(GetLexicalInfo(identifierExpression), identifierExpression.Identifier);
+ }
+
+ public object Visit(FieldReferenceExpression fre, object data)
+ {
+ B.Expression target = null;
+ if (fre.TargetObject is TypeReferenceExpression) {
+ // not typeof, so this is something like int.Parse()
+ TypeReference typeRef = ((TypeReferenceExpression)fre.TargetObject).TypeReference;
+ if (!typeRef.IsArrayType)
+ target = MakeReferenceExpression(typeRef.SystemType);
+ }
+ if (target == null) {
+ target = (B.Expression)fre.TargetObject.AcceptVisitor(this, data);
+ if (target == null) return null;
+ }
+ return new B.MemberReferenceExpression(GetLexicalInfo(fre), target, fre.FieldName);
+ }
+
+ public object Visit(ClassReferenceExpression classReferenceExpression, object data)
+ {
+ // VB's MyClass.Method references methods in the CURRENT class, ignoring overrides!!!
+ // that is supported neither by C# nor Boo.
+ // Most of the time, "Me"="self" should also do the job.
+ AddWarning(classReferenceExpression, "Class reference is not supported, replaced with self reference.");
+ return new B.SelfLiteralExpression(GetLexicalInfo(classReferenceExpression));
+ }
+
+ B.BinaryOperatorType ConvertOperator(AssignmentOperatorType op, out bool isInPlace)
+ {
+ isInPlace = true;
+ switch (op) {
+ case AssignmentOperatorType.Add:
+ return B.BinaryOperatorType.InPlaceAddition;
+ case AssignmentOperatorType.Assign:
+ return B.BinaryOperatorType.Assign;
+ case AssignmentOperatorType.BitwiseAnd:
+ return B.BinaryOperatorType.InPlaceBitwiseAnd;
+ case AssignmentOperatorType.BitwiseOr:
+ return B.BinaryOperatorType.InPlaceBitwiseOr;
+ case AssignmentOperatorType.ConcatString:
+ return B.BinaryOperatorType.InPlaceAddition;
+ case AssignmentOperatorType.Divide:
+ return B.BinaryOperatorType.InPlaceDivision;
+ case AssignmentOperatorType.DivideInteger:
+ return B.BinaryOperatorType.InPlaceDivision;
+ case AssignmentOperatorType.ExclusiveOr:
+ return B.BinaryOperatorType.InPlaceExclusiveOr;
+ case AssignmentOperatorType.Modulus:
+ isInPlace = false;
+ return B.BinaryOperatorType.Modulus;
+ case AssignmentOperatorType.Multiply:
+ return B.BinaryOperatorType.InPlaceMultiply;
+ case AssignmentOperatorType.Power:
+ isInPlace = false;
+ return B.BinaryOperatorType.Exponentiation;
+ case AssignmentOperatorType.ShiftLeft:
+ return B.BinaryOperatorType.InPlaceShiftLeft;
+ case AssignmentOperatorType.ShiftRight:
+ return B.BinaryOperatorType.InPlaceShiftRight;
+ case AssignmentOperatorType.Subtract:
+ return B.BinaryOperatorType.InPlaceSubtraction;
+ default:
+ return B.BinaryOperatorType.None;
+ }
+ }
+
+ public object Visit(AssignmentExpression assignmentExpression, object data)
+ {
+ B.Expression left = ConvertExpression(assignmentExpression.Left);
+ B.Expression right = ConvertExpression(assignmentExpression.Right);
+ bool isInPlace;
+ B.BinaryOperatorType op = ConvertOperator(assignmentExpression.Op, out isInPlace);
+ if (op == B.BinaryOperatorType.None) {
+ AddError(assignmentExpression, "Unknown operator.");
+ return null;
+ }
+ if (!isInPlace) {
+ // convert L = R to L = L OP R
+ right = new B.BinaryExpression(GetLexicalInfo(assignmentExpression), op, left, right);
+ op = B.BinaryOperatorType.Assign;
+ }
+ return new B.BinaryExpression(GetLexicalInfo(assignmentExpression), op, left, right);
+ }
+
+ B.BinaryOperatorType ConvertOperator(BinaryOperatorType op)
+ {
+ switch (op) {
+ case BinaryOperatorType.Add:
+ return B.BinaryOperatorType.Addition;
+ //case BinaryOperatorType.AsCast: special case: converted to AsExpression
+ case BinaryOperatorType.BitwiseAnd:
+ return B.BinaryOperatorType.BitwiseAnd;
+ case BinaryOperatorType.BitwiseOr:
+ return B.BinaryOperatorType.BitwiseOr;
+ case BinaryOperatorType.Concat:
+ return B.BinaryOperatorType.Addition;
+ case BinaryOperatorType.Divide:
+ return B.BinaryOperatorType.Division;
+ case BinaryOperatorType.DivideInteger:
+ return B.BinaryOperatorType.Division;
+ case BinaryOperatorType.Equality:
+ return B.BinaryOperatorType.Equality;
+ case BinaryOperatorType.ExclusiveOr:
+ return B.BinaryOperatorType.ExclusiveOr;
+ case BinaryOperatorType.GreaterThan:
+ return B.BinaryOperatorType.GreaterThan;
+ case BinaryOperatorType.GreaterThanOrEqual:
+ return B.BinaryOperatorType.GreaterThanOrEqual;
+ case BinaryOperatorType.InEquality:
+ return B.BinaryOperatorType.Inequality;
+ case BinaryOperatorType.LessThan:
+ return B.BinaryOperatorType.LessThan;
+ case BinaryOperatorType.LessThanOrEqual:
+ return B.BinaryOperatorType.LessThanOrEqual;
+ case BinaryOperatorType.Like:
+ return B.BinaryOperatorType.Match;
+ case BinaryOperatorType.LogicalAnd:
+ return B.BinaryOperatorType.And;
+ case BinaryOperatorType.LogicalOr:
+ return B.BinaryOperatorType.Or;
+ case BinaryOperatorType.Modulus:
+ return B.BinaryOperatorType.Modulus;
+ case BinaryOperatorType.Multiply:
+ return B.BinaryOperatorType.Multiply;
+ case BinaryOperatorType.Power:
+ return B.BinaryOperatorType.Exponentiation;
+ case BinaryOperatorType.ReferenceEquality:
+ return B.BinaryOperatorType.ReferenceEquality;
+ case BinaryOperatorType.ReferenceInequality:
+ return B.BinaryOperatorType.ReferenceInequality;
+ case BinaryOperatorType.ShiftLeft:
+ return B.BinaryOperatorType.ShiftLeft;
+ case BinaryOperatorType.ShiftRight:
+ return B.BinaryOperatorType.ShiftRight;
+ case BinaryOperatorType.Subtract:
+ return B.BinaryOperatorType.Subtraction;
+ case BinaryOperatorType.TypeCheck:
+ return B.BinaryOperatorType.TypeTest;
+ default:
+ return B.BinaryOperatorType.None;
+ }
+ }
+
+
+ B.UnaryOperatorType ConvertOperator(UnaryOperatorType op)
+ {
+ switch (op) {
+ case UnaryOperatorType.BitNot:
+ return B.UnaryOperatorType.OnesComplement;
+ case UnaryOperatorType.Not:
+ return B.UnaryOperatorType.LogicalNot;
+ case UnaryOperatorType.Decrement:
+ return B.UnaryOperatorType.Decrement;
+ case UnaryOperatorType.Increment:
+ return B.UnaryOperatorType.Increment;
+ case UnaryOperatorType.Minus:
+ return B.UnaryOperatorType.UnaryNegation;
+ case UnaryOperatorType.PostDecrement:
+ return B.UnaryOperatorType.PostDecrement;
+ case UnaryOperatorType.PostIncrement:
+ return B.UnaryOperatorType.PostIncrement;
+ default:
+ return B.UnaryOperatorType.None;
+ }
+ }
+
+ public object Visit(BinaryOperatorExpression binaryOperatorExpression, object data)
+ {
+ B.Expression left = ConvertExpression(binaryOperatorExpression.Left);
+ B.Expression right = ConvertExpression(binaryOperatorExpression.Right);
+ B.BinaryOperatorType op = ConvertOperator(binaryOperatorExpression.Op);
+ if (op == B.BinaryOperatorType.None) {
+ if (binaryOperatorExpression.Op == BinaryOperatorType.AsCast) {
+ return new B.AsExpression(GetLexicalInfo(binaryOperatorExpression), left, ConvertTypeReference(right));
+ } else {
+ AddError(binaryOperatorExpression, "Unknown operator.");
+ return null;
+ }
+ }
+// if (binaryOperatorExpression.Op == BinaryOperatorType.DivideInteger) {
+// AddWarning(binaryOperatorExpression, "Integer division converted to normal division.");
+// }
+ return new B.BinaryExpression(GetLexicalInfo(binaryOperatorExpression), op, left, right);
+ }
+
+ public object Visit(UnaryOperatorExpression unaryOperatorExpression, object data)
+ {
+ B.Expression expr = ConvertExpression(unaryOperatorExpression.Expression);
+ if (unaryOperatorExpression.Op == UnaryOperatorType.Plus)
+ return expr;
+ B.UnaryOperatorType op = ConvertOperator(unaryOperatorExpression.Op);
+ if (op == B.UnaryOperatorType.None) {
+ AddError(unaryOperatorExpression, "Unknown operator.");
+ return null;
+ }
+ return new B.UnaryExpression(GetLexicalInfo(unaryOperatorExpression), op, expr);
+ }
+
+ public object Visit(ParenthesizedExpression parenthesizedExpression, object data)
+ {
+ return ConvertExpression(parenthesizedExpression.Expression);
+ }
+
+ public object Visit(InvocationExpression ie, object data)
+ {
+ if (ie.TypeArguments != null && ie.TypeArguments.Count > 0) {
+ AddError(ie, "Generic method calls are not supported.");
+ }
+ B.Expression e = ConvertExpression(ie.TargetObject);
+ if (e == null)
+ return null;
+ if (settings.IsVisualBasic && ie.TargetObject is IdentifierExpression && currentStatement != null) {
+ VariableResolver resolver = new VariableResolver(nameComparer);
+ TypeReference typeRef = resolver.FindType((ie.TargetObject as IdentifierExpression).Identifier, currentStatement);
+ if (typeRef != null && typeRef.IsArrayType) {
+ // Visual Basic: indexer expression
+ B.SlicingExpression s = new B.SlicingExpression(GetLexicalInfo(ie));
+ s.Target = e;
+ foreach (Expression expr in ie.Arguments) {
+ s.Indices.Add(new B.Slice(ConvertExpression(expr)));
+ }
+ return s;
+ }
+ }
+ B.MethodInvocationExpression r = new B.MethodInvocationExpression(GetLexicalInfo(ie), e);
+ foreach (Expression expr in ie.Arguments) {
+ e = ConvertExpression(expr);
+ if (e != null) {
+ r.Arguments.Add(e);
+ }
+ }
+ return r;
+ }
+
+ public object Visit(ObjectCreateExpression objectCreateExpression, object data)
+ {
+ TypeReference t = objectCreateExpression.CreateType;
+ if (t.IsArrayType) {
+ throw new ApplicationException("ObjectCreateExpression cannot be called with an ArrayType");
+ }
+ // HACK: Tricking out event handlers
+ if (t.SystemType.EndsWith("EventHandler") && objectCreateExpression.Parameters.Count == 1)
+ return ConvertExpression((Expression)objectCreateExpression.Parameters[0]);
+
+ B.MethodInvocationExpression mie = new B.MethodInvocationExpression(GetLexicalInfo(objectCreateExpression), MakeReferenceExpression(t.SystemType));
+ ConvertExpressions(objectCreateExpression.Parameters, mie.Arguments);
+ return mie;
+ }
+
+ public object Visit(TypeReferenceExpression typeReferenceExpression, object data)
+ {
+ return WrapTypeReference(typeReferenceExpression.TypeReference);
+ }
+
+ public object Visit(SizeOfExpression sizeOfExpression, object data)
+ {
+ AddError(sizeOfExpression, "sizeof is not supported.");
+ return null;
+ }
+
+ public object Visit(DefaultValueExpression defaultValueExpression, object data)
+ {
+ AddError(defaultValueExpression, "default() is not supported.");
+ return null;
+ }
+
+ public object Visit(TypeOfExpression typeOfExpression, object data)
+ {
+ return new B.TypeofExpression(GetLexicalInfo(typeOfExpression), ConvertTypeReference(typeOfExpression.TypeReference));
+ }
+
+ public object Visit(TypeOfIsExpression typeOfIsExpression, object data)
+ {
+ return new B.BinaryExpression(GetLexicalInfo(typeOfIsExpression), B.BinaryOperatorType.TypeTest,
+ ConvertExpression(typeOfIsExpression.Expression),
+ WrapTypeReference(typeOfIsExpression.TypeReference));
+ }
+
+ public object Visit(AddressOfExpression addressOfExpression, object data)
+ {
+ // Boo can reference methods directly
+ return ConvertExpression(addressOfExpression.Expression);
+ }
+
+ public object Visit(PointerReferenceExpression pointerReferenceExpression, object data)
+ {
+ AddError(pointerReferenceExpression, "Pointers are not supported.");
+ return null;
+ }
+
+ public object Visit(CastExpression castExpression, object data)
+ {
+ return new B.CastExpression(GetLexicalInfo(castExpression),
+ ConvertTypeReference(castExpression.CastTo),
+ ConvertExpression(castExpression.Expression));
+ }
+
+ public object Visit(StackAllocExpression stackAllocExpression, object data)
+ {
+ AddError(stackAllocExpression, "StackAlloc is not supported.");
+ return null;
+ }
+
+ public object Visit(ThisReferenceExpression thisReferenceExpression, object data)
+ {
+ return new B.SelfLiteralExpression(GetLexicalInfo(thisReferenceExpression));
+ }
+
+ public object Visit(BaseReferenceExpression baseReferenceExpression, object data)
+ {
+ return new B.SuperLiteralExpression(GetLexicalInfo(baseReferenceExpression));
+ }
+
+ public object Visit(DirectionExpression directionExpression, object data)
+ {
+ // boo does not need to specify the direction when calling out/ref methods
+ return ConvertExpression(directionExpression.Expression);
+ }
+
+ public object Visit(ArrayCreateExpression arrayCreateExpression, object data)
+ {
+ if (!arrayCreateExpression.ArrayInitializer.IsNull) {
+ return arrayCreateExpression.ArrayInitializer.AcceptVisitor(this, data);
+ }
+ ArrayCreationParameter acp = (ArrayCreationParameter)arrayCreateExpression.Parameters[0];
+ string builtInName = (acp.Expressions.Count == 1) ? "array" : "matrix";
+ B.MethodInvocationExpression mie = new B.MethodInvocationExpression(GetLexicalInfo(arrayCreateExpression),
+ MakeReferenceExpression(builtInName));
+ if (arrayCreateExpression.Parameters.Count > 1) {
+ arrayCreateExpression.CreateType.RankSpecifier = new int[arrayCreateExpression.Parameters.Count - 1];
+ mie.Arguments.Add(WrapTypeReference(arrayCreateExpression.CreateType));
+ } else {
+ mie.Arguments.Add(MakeReferenceExpression(arrayCreateExpression.CreateType.SystemType));
+ }
+ if (acp.Expressions.Count == 1) {
+ mie.Arguments.Add(ConvertExpression((Expression)acp.Expressions[0]));
+ } else {
+ B.ArrayLiteralExpression dims = new B.ArrayLiteralExpression(GetLexicalInfo(acp));
+ ConvertExpressions(acp.Expressions, dims.Items);
+ mie.Arguments.Add(dims);
+ }
+ return mie;
+ }
+
+ public object Visit(ArrayCreationParameter arrayCreationParameter, object data)
+ {
+ throw new ApplicationException("Visited ArrayCreationParameter.");
+ }
+
+ public object Visit(ArrayInitializerExpression aie, object data)
+ {
+ B.ArrayLiteralExpression dims = new B.ArrayLiteralExpression(GetLexicalInfo(aie));
+ ConvertExpressions(aie.CreateExpressions, dims.Items);
+ return dims;
+ }
+
+ public object Visit(IndexerExpression indexerExpression, object data)
+ {
+ B.SlicingExpression s = new B.SlicingExpression(GetLexicalInfo(indexerExpression));
+ s.Target = ConvertExpression(indexerExpression.TargetObject);
+ foreach (Expression expr in indexerExpression.Indices) {
+ s.Indices.Add(new B.Slice(ConvertExpression(expr)));
+ }
+ return s;
+ }
+
+ public object Visit(AnonymousMethodExpression anonymousMethodExpression, object data)
+ {
+ B.CallableBlockExpression cbe = new B.CallableBlockExpression(GetLexicalInfo(anonymousMethodExpression));
+ cbe.EndSourceLocation = GetLocation(anonymousMethodExpression.EndLocation);
+ cbe.Body = ConvertBlock(anonymousMethodExpression.Body);
+ ConvertParameters(anonymousMethodExpression.Parameters, cbe.Parameters);
+ return cbe;
+ }
+
+ public object Visit(ConditionalExpression conditionalExpression, object data)
+ {
+ B.TernaryExpression te = new B.TernaryExpression(GetLexicalInfo(conditionalExpression));
+ te.Condition = ConvertExpression(conditionalExpression.Condition);
+ te.TrueValue = ConvertExpression(conditionalExpression.TrueExpression);
+ te.FalseValue = ConvertExpression(conditionalExpression.FalseExpression);
+ return te;
+ }
+
+ public object Visit(CheckedExpression checkedExpression, object data)
+ {
+ AddError(checkedExpression, "Using 'checked' inside an expression is not supported by boo, " +
+ "use the checked {} block instead.");
+ return null;
+ }
+
+ public object Visit(UncheckedExpression uncheckedExpression, object data)
+ {
+ AddError(uncheckedExpression, "Using 'unchecked' inside an expression is not supported by boo, " +
+ "use the unchecked {} block instead.");
+ return null;
+ }
+ }
+}
diff --git a/src/AddIns/BackendBindings/Boo/NRefactoryToBooConverter/Project/ConvertVisitorGlobal.cs b/src/AddIns/BackendBindings/Boo/NRefactoryToBooConverter/Project/ConvertVisitorGlobal.cs
new file mode 100644
index 0000000000..de2b31eabf
--- /dev/null
+++ b/src/AddIns/BackendBindings/Boo/NRefactoryToBooConverter/Project/ConvertVisitorGlobal.cs
@@ -0,0 +1,221 @@
+#region license
+// Copyright (c) 2005, Daniel Grunwald (daniel@danielgrunwald.de)
+// All rights reserved.
+//
+// NRefactoryToBoo is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// NRefactoryToBoo is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with NRefactoryToBoo; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#endregion
+
+using System;
+using System.Collections.Generic;
+using ICSharpCode.NRefactory.Parser;
+using ICSharpCode.NRefactory.Parser.AST;
+using Boo.Lang.Compiler;
+using B = Boo.Lang.Compiler.Ast;
+
+namespace NRefactoryToBooConverter
+{
+ partial class ConvertVisitor
+ {
+ public object Visit(INode node, object data)
+ {
+ AddError(node, "Visited INode: " + node);
+ return null;
+ }
+
+ public object Visit(CompilationUnit compilationUnit, object data)
+ {
+ module = new B.Module();
+ module.LexicalInfo = new B.LexicalInfo(fileName, 1, 1);
+ compilationUnit.AcceptChildren(this, data);
+ if (entryPointMethod != null) {
+ bool allMembersAreStatic = true;
+ foreach (B.TypeMember member in entryPointMethod.DeclaringType.Members) {
+ allMembersAreStatic &= member.IsStatic;
+ }
+ if (allMembersAreStatic) {
+ entryPointMethod.DeclaringType.Attributes.Add(MakeAttribute(("module")));
+ } else {
+ lastLexicalInfo = entryPointMethod.LexicalInfo;
+ B.Expression expr = MakeReferenceExpression(entryPointMethod.DeclaringType.Name + ".Main");
+ B.MethodInvocationExpression mie = new B.MethodInvocationExpression(lastLexicalInfo, expr);
+ if (entryPointMethod.Parameters.Count > 0) {
+ mie.Arguments.Add(MakeReferenceExpression("argv"));
+ }
+ B.SimpleTypeReference ret = entryPointMethod.ReturnType as B.SimpleTypeReference;
+ if (ret.Name == "void" || ret.Name == "System.Void")
+ module.Globals.Add(new B.ExpressionStatement(mie));
+ else
+ module.Globals.Add(new B.ReturnStatement(lastLexicalInfo, mie, null));
+ }
+ }
+ B.Module tmp = module;
+ module = null;
+ return tmp;
+ }
+
+ public object Visit(NamespaceDeclaration namespaceDeclaration, object data)
+ {
+ if (module.Namespace != null) {
+ AddError(namespaceDeclaration, "Only one namespace declaration per file is supported.");
+ return null;
+ }
+ module.Namespace = new B.NamespaceDeclaration(GetLexicalInfo(namespaceDeclaration));
+ module.Namespace.Name = namespaceDeclaration.Name;
+ return namespaceDeclaration.AcceptChildren(this, data);
+ }
+
+ public object Visit(UsingDeclaration usingDeclaration, object data)
+ {
+ foreach (Using u in usingDeclaration.Usings) {
+ Visit(u, data);
+ }
+ return null;
+ }
+
+ public object Visit(Using @using, object data)
+ {
+ B.Import import;
+ if (@using.IsAlias) {
+ import = new B.Import(@using.Alias.Type, null, new B.ReferenceExpression(@using.Name));
+ import.LexicalInfo = GetLexicalInfo(@using);
+ } else {
+ import = new B.Import(GetLexicalInfo(@using), @using.Name);
+ }
+ module.Imports.Add(import);
+ return import;
+ }
+
+ B.TypeDefinition currentType;
+
+ public object Visit(TypeDeclaration typeDeclaration, object data)
+ {
+ if (typeDeclaration.Templates.Count > 0) {
+ AddError(typeDeclaration, "Generic type definitions are not supported.");
+ }
+ B.TypeDefinition oldType = currentType;
+ B.TypeDefinition typeDef;
+ switch (typeDeclaration.Type) {
+ case ClassType.Class:
+ typeDef = new B.ClassDefinition(GetLexicalInfo(typeDeclaration));
+ break;
+ case ClassType.Interface:
+ typeDef = new B.InterfaceDefinition(GetLexicalInfo(typeDeclaration));
+ break;
+ case ClassType.Enum:
+ typeDef = new B.EnumDefinition(GetLexicalInfo(typeDeclaration));
+ break;
+ case ClassType.Struct:
+ typeDef = new B.StructDefinition(GetLexicalInfo(typeDeclaration));
+ break;
+ case ClassType.Module:
+ typeDef = new B.ClassDefinition(GetLexicalInfo(typeDeclaration));
+ typeDeclaration.Modifier |= Modifier.Static;
+ break;
+ default:
+ AddError(typeDeclaration, "Unknown class type.");
+ return null;
+ }
+ if (currentType != null)
+ typeDef.Modifiers = ConvertModifier(typeDeclaration, B.TypeMemberModifiers.Private);
+ else
+ typeDef.Modifiers = ConvertModifier(typeDeclaration, B.TypeMemberModifiers.Internal);
+ typeDef.Name = typeDeclaration.Name;
+ typeDef.EndSourceLocation = GetLocation(typeDeclaration.EndLocation);
+ ConvertAttributes(typeDeclaration.Attributes, typeDef.Attributes);
+ ConvertTypeReferences(typeDeclaration.BaseTypes, typeDef.BaseTypes);
+
+ if (currentType != null)
+ currentType.Members.Add(typeDef);
+ else
+ module.Members.Add(typeDef);
+ currentType = typeDef;
+ typeDeclaration.AcceptChildren(this, data);
+ currentType = oldType;
+ return typeDef;
+ }
+
+ public object Visit(DelegateDeclaration delegateDeclaration, object data)
+ {
+ B.CallableDefinition cd = new B.CallableDefinition(GetLexicalInfo(delegateDeclaration));
+ cd.Name = delegateDeclaration.Name;
+ ConvertAttributes(delegateDeclaration.Attributes, cd.Attributes);
+ cd.Modifiers = ConvertModifier(delegateDeclaration, B.TypeMemberModifiers.Private);
+ ConvertParameters(delegateDeclaration.Parameters, cd.Parameters);
+ cd.ReturnType = ConvertTypeReference(delegateDeclaration.ReturnType);
+ if (currentType != null)
+ currentType.Members.Add(cd);
+ else
+ module.Members.Add(cd);
+ return cd;
+ }
+
+ void ConvertAttributes(List sections, B.AttributeCollection col)
+ {
+ foreach (AttributeSection s in sections) {
+ if (s.AttributeTarget.Length > 0) {
+ AddError(s, "Attribute target not supported");
+ continue;
+ }
+ foreach (ICSharpCode.NRefactory.Parser.AST.Attribute a in s.Attributes) {
+ col.Add((B.Attribute)Visit(a, null));
+ }
+ }
+ }
+
+ public object Visit(ICSharpCode.NRefactory.Parser.AST.Attribute a, object data)
+ {
+ B.Attribute att = new B.Attribute(GetLexicalInfo(a), a.Name);
+ att.EndSourceLocation = GetLocation(a.EndLocation);
+ ConvertExpressions(a.PositionalArguments, att.Arguments);
+ foreach (NamedArgumentExpression nae in a.NamedArguments) {
+ B.Expression expr = ConvertExpression(nae.Expression);
+ if (expr != null) {
+ att.NamedArguments.Add(new B.ExpressionPair(new B.ReferenceExpression(nae.Name), expr));
+ }
+ }
+ return att;
+ }
+
+ public object Visit(AttributeSection s, object data)
+ {
+ if (s.AttributeTarget.ToLower() == "assembly") {
+ foreach (ICSharpCode.NRefactory.Parser.AST.Attribute a in s.Attributes) {
+ module.AssemblyAttributes.Add((B.Attribute)Visit(a, null));
+ }
+ } else {
+ AddError(s, "Attribute must have the target 'assembly'");
+ }
+ return null;
+ }
+
+ // Some classes are handled by their parent (NamedArgumentExpression by Attribute etc.)
+ // so we don't need to implement Visit for them.
+ public object Visit(TemplateDefinition templateDefinition, object data)
+ {
+ throw new ApplicationException("Visited TemplateDefinition.");
+ }
+
+ public object Visit(NamedArgumentExpression namedArgumentExpression, object data)
+ {
+ throw new ApplicationException("Visited NamedArgumentExpression.");
+ }
+
+ public object Visit(OptionDeclaration optionDeclaration, object data)
+ {
+ AddError(optionDeclaration, "Option statement is not supported.");
+ return null;
+ }
+ }
+}
diff --git a/src/AddIns/BackendBindings/Boo/NRefactoryToBooConverter/Project/ConvertVisitorStatements.cs b/src/AddIns/BackendBindings/Boo/NRefactoryToBooConverter/Project/ConvertVisitorStatements.cs
new file mode 100644
index 0000000000..ec0ec8d6cf
--- /dev/null
+++ b/src/AddIns/BackendBindings/Boo/NRefactoryToBooConverter/Project/ConvertVisitorStatements.cs
@@ -0,0 +1,686 @@
+#region license
+// Copyright (c) 2005, Daniel Grunwald (daniel@danielgrunwald.de)
+// All rights reserved.
+//
+// NRefactoryToBoo is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// NRefactoryToBoo is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with NRefactoryToBoo; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#endregion
+
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using ICSharpCode.NRefactory.Parser;
+using ICSharpCode.NRefactory.Parser.AST;
+using Boo.Lang.Compiler;
+using B = Boo.Lang.Compiler.Ast;
+
+namespace NRefactoryToBooConverter
+{
+ partial class ConvertVisitor
+ {
+ void ConvertStatements(IEnumerable statements, B.Block b)
+ {
+ foreach (Statement n in statements) {
+ AddToBlock(n, b);
+ }
+ }
+
+ Statement currentStatement;
+
+ object ConvertStatementInternal(Statement stmt)
+ {
+ Statement oldStatement = currentStatement;
+ currentStatement = stmt;
+ try {
+ return stmt.AcceptVisitor(this, null);
+ } finally {
+ currentStatement = oldStatement;
+ }
+ }
+
+ void AddToBlock(Statement n, B.Block b)
+ {
+ object result = ConvertStatementInternal(n);
+ if (result is ArrayList) {
+ foreach (B.Statement stmt in (ArrayList)result) {
+ b.Add(stmt);
+ }
+ } else {
+ B.Statement stmt = (B.Statement)result;
+ if (stmt != null) {
+ b.Add(stmt);
+ }
+ }
+ }
+
+ ArrayList ConvertStatements(IEnumerable statements)
+ {
+ ArrayList r = new ArrayList();
+ foreach (Statement n in statements) {
+ object result = ConvertStatementInternal(n);
+ if (result is ArrayList) {
+ r.AddRange((ArrayList)result);
+ } else if (result != null) {
+ r.Add(result);
+ }
+ }
+ return r;
+ }
+
+ B.Block ConvertBlock(Statement statement)
+ {
+ if (statement == null || statement.IsNull)
+ return null;
+ ArrayList statements = new ArrayList(1);
+ statements.Add(statement);
+ return ConvertBlock(statements);
+ }
+
+ B.Block ConvertBlock(BlockStatement block)
+ {
+ B.Block b = new B.Block(GetLexicalInfo(block));
+ b.EndSourceLocation = GetLocation(block.EndLocation);
+ ConvertStatements(block.Children, b);
+ return b;
+ }
+
+ B.Block ConvertBlock(ArrayList statements)
+ {
+ if (statements.Count == 1) {
+ if (statements[0] is BlockStatement)
+ return ConvertBlock(statements[0] as BlockStatement);
+ }
+ B.Block b = new B.Block();
+ ConvertStatements(statements, b);
+ return b;
+ }
+
+ public object Visit(BlockStatement blockStatement, object data)
+ {
+ return ConvertBlock(blockStatement);
+ }
+
+ B.MacroStatement CreateMacro(INode node, string name, Statement embedded, params Expression[] arguments)
+ {
+ B.MacroStatement macro = new B.MacroStatement(GetLexicalInfo(node));
+ macro.Name = name;
+ ConvertExpressions(arguments, macro.Arguments);
+ if (embedded is BlockStatement) {
+ macro.Block = ConvertBlock((BlockStatement)embedded);
+ } else {
+ macro.Block = new B.Block();
+ macro.Block.Add((B.Statement)embedded.AcceptVisitor(this, null));
+ }
+ return macro;
+ }
+
+ public object Visit(FixedStatement fixedStatement, object data)
+ {
+ AddError(fixedStatement, "FixedStatement is not supported.");
+ return null;
+ }
+
+ public object Visit(UnsafeStatement unsafeStatement, object data)
+ {
+ AddError(unsafeStatement, "UnsafeStatement is not supported.");
+ return null;
+ }
+
+ public object Visit(CheckedStatement checkedStatement, object data)
+ {
+ return CreateMacro(checkedStatement, "checked", checkedStatement.Block);
+ }
+
+ public object Visit(UncheckedStatement uncheckedStatement, object data)
+ {
+ return CreateMacro(uncheckedStatement, "unchecked", uncheckedStatement.Block);
+ }
+
+ public object Visit(ExitStatement exitStatement, object data)
+ {
+ if (exitStatement.ExitType == ExitType.Function || exitStatement.ExitType == ExitType.Sub || exitStatement.ExitType == ExitType.Property) {
+ AddWarning(exitStatement, "ExitStatement is converted to 'return'");
+ return new B.ReturnStatement(GetLexicalInfo(exitStatement));
+ } else {
+ AddWarning(exitStatement, "ExitStatement is converted to 'break'");
+ return new B.BreakStatement(GetLexicalInfo(exitStatement));
+ }
+ }
+
+ ///
+ /// Make a loop:
+ /// $initializers
+ /// goto ___converterGeneratedName#
+ /// while true:
+ /// $iterators
+ /// :___converterGeneratedName#
+ /// break $conditionType $condition
+ /// $body
+ ///
+ ArrayList MakeManualLoop(INode node, ArrayList initializers, B.StatementModifierType conditionType, Expression condition, ArrayList iterators, Statement body)
+ {
+ // we use this "while true" form because "continue" may not skip the iterator.
+
+ ArrayList list = ConvertStatements(initializers);
+ B.LabelStatement labelStatement = MakeLabel(GenerateName());
+ B.GotoStatement gotoStatement = new B.GotoStatement();
+ gotoStatement.Label = new B.ReferenceExpression(labelStatement.Name);
+ list.Add(gotoStatement);
+
+ B.WhileStatement w = new B.WhileStatement(GetLexicalInfo(node));
+ w.Condition = new B.BoolLiteralExpression(true);
+ list.Add(w);
+ w.Block = ConvertBlock(iterators);
+ B.BreakStatement breakStatement = new B.BreakStatement();
+ breakStatement.Modifier = new B.StatementModifier(conditionType, ConvertExpression(condition));
+ w.Block.Add(labelStatement);
+ w.Block.Add(breakStatement);
+ foreach (B.Statement st in ConvertBlock(body).Statements) {
+ w.Block.Add(st);
+ }
+ return list;
+ }
+
+ ArrayList MakeManualLoop(ForNextStatement forNextStatement)
+ {
+ Expression var = new IdentifierExpression(forNextStatement.VariableName);
+ ArrayList initializers = new ArrayList(1);
+ initializers.Add(new StatementExpression(new AssignmentExpression(var, AssignmentOperatorType.Assign, forNextStatement.Start)));
+ ArrayList iterators = new ArrayList(1);
+ Expression step = forNextStatement.Step;
+ if (step == null || step.IsNull)
+ step = new PrimitiveExpression(1, "1");
+ iterators.Add(new StatementExpression(new AssignmentExpression(var, AssignmentOperatorType.Add, step)));
+ PrimitiveExpression stepPE = step as PrimitiveExpression;
+ if (stepPE == null || !(stepPE.Value is int)) {
+ AddError(forNextStatement, "Step must be an integer literal");
+ return null;
+ }
+ BinaryOperatorType conditionOperator;
+ if ((int)stepPE.Value < 0) {
+ conditionOperator = BinaryOperatorType.GreaterThanOrEqual;// counting down
+ } else {
+ conditionOperator = BinaryOperatorType.LessThanOrEqual;// counting up
+ }
+ Expression condition = new BinaryOperatorExpression(var, conditionOperator, forNextStatement.End);
+ return MakeManualLoop(forNextStatement, initializers, B.StatementModifierType.Unless, condition, iterators, forNextStatement.EmbeddedStatement);
+ }
+
+ public object Visit(ForNextStatement forNextStatement, object data)
+ {
+ if (forNextStatement.TypeReference.IsNull)
+ return MakeManualLoop(forNextStatement);
+ B.ForStatement fs = new B.ForStatement(GetLexicalInfo(forNextStatement));
+ fs.Block = ConvertBlock(forNextStatement.EmbeddedStatement);
+ fs.Declarations.Add(new B.Declaration(forNextStatement.VariableName, null));
+ B.Expression start = ConvertExpression(forNextStatement.Start);
+ Expression end = forNextStatement.End;
+ if (forNextStatement.Step == null || forNextStatement.Step.IsNull) {
+ // range only goes to end - 1, so increment end
+ end = Expression.AddInteger(end, 1);
+ fs.Iterator = MakeMethodCall("range", start, ConvertExpression(end));
+ } else {
+ PrimitiveExpression stepPE = forNextStatement.Step as PrimitiveExpression;
+ if (stepPE == null || !(stepPE.Value is int)) {
+ AddError(forNextStatement, "Step must be an integer literal");
+ } else {
+ if ((int)stepPE.Value < 0)
+ end = Expression.AddInteger(end, -1);
+ else
+ end = Expression.AddInteger(end, 1);
+ }
+ fs.Iterator = MakeMethodCall("range", start, ConvertExpression(end), ConvertExpression(forNextStatement.Step));
+ }
+ return fs;
+ }
+
+ public object Visit(ForStatement forStatement, object data)
+ {
+ return MakeManualLoop(forStatement, forStatement.Initializers, B.StatementModifierType.Unless,
+ forStatement.Condition, forStatement.Iterator, forStatement.EmbeddedStatement);
+ }
+
+ public object Visit(DoLoopStatement doLoopStatement, object data)
+ {
+ bool frontCondition = doLoopStatement.ConditionPosition != ConditionPosition.End;
+ bool negateCondition = doLoopStatement.ConditionType == ConditionType.Until;
+ if (frontCondition && negateCondition) {
+ // VB: Do Unless * : ** : Loop
+ B.UnlessStatement u = new B.UnlessStatement(GetLexicalInfo(doLoopStatement));
+ u.Condition = ConvertExpression(doLoopStatement.Condition);
+ u.Block = ConvertBlock(doLoopStatement.EmbeddedStatement);
+ return u;
+ }
+ // While and Do loop
+ B.WhileStatement w = new B.WhileStatement(GetLexicalInfo(doLoopStatement));
+ if (frontCondition)
+ w.Condition = ConvertExpression(doLoopStatement.Condition);
+ else
+ w.Condition = new B.BoolLiteralExpression(true);
+ w.Block = ConvertBlock(doLoopStatement.EmbeddedStatement);
+ if (!frontCondition) {
+ B.BreakStatement breakStatement = new B.BreakStatement();
+ breakStatement.Modifier = new B.StatementModifier(negateCondition ? B.StatementModifierType.If : B.StatementModifierType.Unless,
+ ConvertExpression(doLoopStatement.Condition));
+ w.Block.Add(breakStatement);
+ }
+ return w;
+ }
+
+ public object Visit(ForeachStatement foreachStatement, object data)
+ {
+ B.ForStatement fs = new B.ForStatement(GetLexicalInfo(foreachStatement));
+ fs.EndSourceLocation = GetLocation(foreachStatement.EndLocation);
+ fs.Iterator = ConvertExpression(foreachStatement.Expression);
+ fs.Declarations.Add(new B.Declaration(foreachStatement.VariableName, ConvertTypeReference(foreachStatement.TypeReference)));
+ fs.Block = ConvertBlock(foreachStatement.EmbeddedStatement);
+ return fs;
+ }
+
+ public object Visit(AddHandlerStatement addHandlerStatement, object data)
+ {
+ return new B.BinaryExpression(GetLexicalInfo(addHandlerStatement),
+ B.BinaryOperatorType.InPlaceAddition,
+ ConvertExpression(addHandlerStatement.EventExpression),
+ ConvertExpression(addHandlerStatement.HandlerExpression));
+ }
+
+ public object Visit(RemoveHandlerStatement removeHandlerStatement, object data)
+ {
+ return new B.BinaryExpression(GetLexicalInfo(removeHandlerStatement),
+ B.BinaryOperatorType.InPlaceSubtraction,
+ ConvertExpression(removeHandlerStatement.EventExpression),
+ ConvertExpression(removeHandlerStatement.HandlerExpression));
+ }
+
+ public object Visit(RaiseEventStatement raiseEventStatement, object data)
+ {
+ B.MethodInvocationExpression mie = new B.MethodInvocationExpression(GetLexicalInfo(raiseEventStatement));
+ mie.Target = new B.ReferenceExpression(raiseEventStatement.EventName);
+ ConvertExpressions(raiseEventStatement.Arguments, mie.Arguments);
+ return mie;
+ }
+
+ public object Visit(EraseStatement eraseStatement, object data)
+ {
+ ArrayList statements = new ArrayList();
+ foreach (Expression expr in eraseStatement.Expressions) {
+ B.Expression e = ConvertExpression(expr);
+ e = new B.BinaryExpression(B.BinaryOperatorType.Assign, e, new B.NullLiteralExpression());
+ statements.Add(new B.ExpressionStatement(e));
+ }
+ return statements;
+ }
+
+ public object Visit(ReDimStatement reDimStatement, object data)
+ {
+ // Redim [Preserve] a(newBounds)
+ // without preserve:
+ // a = array(Type, newBounds)
+ // with preserve:
+ // ??1 = array(Type, newBounds)
+ // Array.Copy(a, ??1, System.Math.Min(a.Length, ??1.Length))
+ // a = ??1
+ ArrayList list = new ArrayList();
+ foreach (InvocationExpression o in reDimStatement.ReDimClauses) {
+ if (o.TypeArguments != null && o.TypeArguments.Count > 0) {
+ AddError(o, "Type parameter are not allowed here.");
+ }
+ IdentifierExpression identifier = o.TargetObject as IdentifierExpression;
+ if (identifier == null) {
+ AddError(o, "Sorry, that expression is too complex to be resolved by the converter.");
+ } else {
+ // first we need to find out the array type
+ VariableResolver resolver = new VariableResolver(nameComparer);
+ TypeReference r = resolver.FindType(identifier.Identifier, reDimStatement);
+ if (r == null) {
+ AddError(o, "The name '" + identifier.Identifier + "' could not be resolved by the converter.");
+ } else if (!r.IsArrayType) {
+ AddError(o, identifier.Identifier + " is not an array.");
+ } else {
+ r = r.Clone();
+ ArrayList bounds = new ArrayList(o.Arguments);
+ for (int i = 0; i < bounds.Count; i++) {
+ bounds[i] = Expression.AddInteger((Expression)bounds[i], 1);
+ }
+ ArrayList acps = new ArrayList();
+ acps.Add(new ArrayCreationParameter(bounds));
+ for (int i = 1; i < r.RankSpecifier.Length; i++) {
+ acps.Add(new ArrayCreationParameter(r.RankSpecifier[i]));
+ }
+ r.RankSpecifier = null;
+ ArrayCreateExpression ace = new ArrayCreateExpression(r, acps);
+ ace.StartLocation = o.StartLocation;
+ B.Expression expr = new B.ReferenceExpression(GetLexicalInfo(identifier), identifier.Identifier);
+ expr = new B.BinaryExpression(GetLexicalInfo(reDimStatement), B.BinaryOperatorType.Assign, expr, ConvertExpression(ace));
+ list.Add(new B.ExpressionStatement(expr));
+ }
+ }
+ }
+ return list;
+ }
+
+ public object Visit(StatementExpression statementExpression, object data)
+ {
+ B.ExpressionStatement st = new B.ExpressionStatement(GetLexicalInfo(statementExpression));
+ st.Expression = ConvertExpression(statementExpression.Expression);
+ return st;
+ }
+
+ public object Visit(LocalVariableDeclaration lvd, object data)
+ {
+ ArrayList list = new ArrayList();
+ for (int i = 0; i < lvd.Variables.Count; i++) {
+ B.DeclarationStatement varDecl = new B.DeclarationStatement(GetLexicalInfo(lvd));
+ varDecl.Declaration = new B.Declaration(GetLexicalInfo(lvd.Variables[i]), lvd.Variables[i].Name, ConvertTypeReference(lvd.GetTypeForVariable(i)));
+ varDecl.Initializer = ConvertExpression(lvd.Variables[i].Initializer);
+ list.Add(varDecl);
+ }
+ return list;
+ }
+
+ public object Visit(EmptyStatement emptyStatement, object data)
+ {
+ return null;
+ }
+
+ public object Visit(ReturnStatement returnStatement, object data)
+ {
+ return new B.ReturnStatement(GetLexicalInfo(returnStatement), ConvertExpression(returnStatement.Expression), null);
+ }
+
+ public object Visit(YieldStatement yieldStatement, object data)
+ {
+ ReturnStatement rs = yieldStatement.Statement as ReturnStatement;
+ if (rs == null)
+ return new B.ReturnStatement(GetLexicalInfo(yieldStatement));
+ return new B.YieldStatement(GetLexicalInfo(yieldStatement), ConvertExpression(rs.Expression));
+ }
+
+ public object Visit(ThrowStatement throwStatement, object data)
+ {
+ return new B.RaiseStatement(GetLexicalInfo(throwStatement), ConvertExpression(throwStatement.Expression), null);
+ }
+
+ public object Visit(IfElseStatement ifElseStatement, object data)
+ {
+ B.IfStatement ifs = new B.IfStatement(GetLexicalInfo(ifElseStatement));
+ ifs.EndSourceLocation = GetLocation(ifElseStatement.EndLocation);
+ ifs.Condition = ConvertExpression(ifElseStatement.Condition);
+ ifs.TrueBlock = ConvertBlock(ifElseStatement.TrueStatement);
+ if (ifElseStatement.HasElseIfSections) {
+ // TODO: implement elseif
+ AddError(ifElseStatement, "ElseIfSections are not supported (because Daniel was lazy)");
+ }
+ if (ifElseStatement.HasElseStatements) {
+ ifs.FalseBlock = ConvertBlock(ifElseStatement.FalseStatement);
+ }
+ return ifs;
+ }
+
+ public object Visit(ElseIfSection elseIfSection, object data)
+ {
+ throw new ApplicationException("ElseIfSection visited");
+ }
+
+ B.LabelStatement MakeLabel(string name)
+ {
+ return new B.LabelStatement(lastLexicalInfo, name);
+ }
+
+ public object Visit(LabelStatement labelStatement, object data)
+ {
+ return new B.LabelStatement(GetLexicalInfo(labelStatement), labelStatement.Label);
+ }
+
+ public object Visit(GotoStatement gotoStatement, object data)
+ {
+ return new B.GotoStatement(GetLexicalInfo(gotoStatement), new B.ReferenceExpression(gotoStatement.Label));
+ }
+
+ public object Visit(StopStatement stopStatement, object data)
+ {
+ return new B.ExpressionStatement(MakeMethodCall("System.Diagnostics.Debugger.Break"));
+ }
+
+ public object Visit(EndStatement endStatement, object data)
+ {
+ return new B.ExpressionStatement(MakeMethodCall("System.Environment.Exit", new B.IntegerLiteralExpression(0)));
+ }
+
+ public object Visit(BreakStatement breakStatement, object data)
+ {
+ return new B.BreakStatement(GetLexicalInfo(breakStatement));
+ }
+
+ public object Visit(ContinueStatement continueStatement, object data)
+ {
+ return new B.ContinueStatement(GetLexicalInfo(continueStatement));
+ }
+
+ public object Visit(LockStatement lockStatement, object data)
+ {
+ return CreateMacro(lockStatement, "lock", lockStatement.EmbeddedStatement, lockStatement.LockExpression);
+ }
+
+ public object Visit(UsingStatement usingStatement, object data)
+ {
+ LocalVariableDeclaration varDecl = usingStatement.ResourceAcquisition as LocalVariableDeclaration;
+ Expression expr;
+ if (varDecl != null) {
+ if (varDecl.Variables.Count != 1) {
+ AddError(usingStatement, "Only one variable can be used with the using statement.");
+ return null;
+ }
+ expr = new AssignmentExpression(new IdentifierExpression(varDecl.Variables[0].Name),
+ AssignmentOperatorType.Assign,
+ varDecl.Variables[0].Initializer);
+ } else {
+ StatementExpression se = usingStatement.ResourceAcquisition as StatementExpression;
+ if (se == null) {
+ AddError(usingStatement, "Expected: VariableDeclaration or StatementExpression");
+ return null;
+ }
+ expr = se.Expression;
+ }
+ return CreateMacro(usingStatement, "using", usingStatement.EmbeddedStatement, expr);
+ }
+
+ public object Visit(WithStatement withStatement, object data)
+ {
+ return CreateMacro(withStatement, "with", withStatement.Body, withStatement.Expression);
+ }
+
+ public object Visit(OnErrorStatement onErrorStatement, object data)
+ {
+ AddError(onErrorStatement, "old VB-style exception handling is not supported.");
+ return null;
+ }
+
+ public object Visit(ErrorStatement errorStatement, object data)
+ {
+ AddError(errorStatement, "old VB-style exception handling is not supported.");
+ return null;
+ }
+
+ public object Visit(ResumeStatement resumeStatement, object data)
+ {
+ AddError(resumeStatement, "old VB-style exception handling is not supported.");
+ return null;
+ }
+
+ public object Visit(TryCatchStatement tryCatchStatement, object data)
+ {
+ B.TryStatement t = new B.TryStatement(GetLexicalInfo(tryCatchStatement));
+ t.EndSourceLocation = GetLocation(tryCatchStatement.EndLocation);
+ t.ProtectedBlock = ConvertBlock(tryCatchStatement.StatementBlock);
+ t.EnsureBlock = ConvertBlock(tryCatchStatement.FinallyBlock);
+ foreach (CatchClause clause in tryCatchStatement.CatchClauses) {
+ B.ExceptionHandler handler = new B.ExceptionHandler(GetLexicalInfo(clause));
+ handler.Block = ConvertBlock(clause.StatementBlock);
+ B.TypeReference typeRef = ConvertTypeReference(clause.TypeReference);
+ string name = clause.VariableName;
+ if (typeRef != null) {
+ if (name == null || name.Length == 0)
+ name = GenerateName();
+ handler.Declaration = new B.Declaration(name, typeRef);
+ } else {
+ if (name != null && name.Length > 0)
+ handler.Declaration = new B.Declaration(name, null);
+ }
+ t.ExceptionHandlers.Add(handler);
+ }
+ return t;
+ }
+
+ public object Visit(CatchClause catchClause, object data)
+ {
+ throw new ApplicationException("CatchClause visited.");
+ }
+
+ B.Statement GetLastStatement(B.Block block)
+ {
+ if (block == null || block.Statements.Count == 0)
+ return null;
+ return block.Statements[block.Statements.Count - 1];
+ }
+
+ string currentSwitchTempName;
+
+ public object Visit(SwitchStatement switchStatement, object data)
+ {
+ // We have a problem: given is still not implemented in boo.
+ // So here's the if / else workaround:
+ string oldSwitchTempName = currentSwitchTempName;
+ currentSwitchTempName = GenerateName();
+ ArrayList l = new ArrayList(3);
+ B.BinaryExpression init = new B.BinaryExpression(B.BinaryOperatorType.Assign,
+ new B.ReferenceExpression(currentSwitchTempName),
+ ConvertExpression(switchStatement.SwitchExpression));
+ l.Add(new B.ExpressionStatement(init));
+ B.IfStatement first = null;
+ B.IfStatement current = null;
+ B.BreakStatement bs;
+ for (int i = 0; i < switchStatement.SwitchSections.Count; i++) {
+ current = (B.IfStatement)((INode)switchStatement.SwitchSections[i]).AcceptVisitor(this, current);
+ if (i == 0) {
+ first = current;
+ }
+ bs = GetLastStatement(current.TrueBlock) as B.BreakStatement;
+ if (bs != null)
+ bs.ReplaceBy(null);
+ }
+ bs = GetLastStatement(current.FalseBlock) as B.BreakStatement;
+ if (bs != null)
+ bs.ReplaceBy(null);
+
+ l.Add(first);
+
+ string endSwitchName = currentSwitchTempName + "_end";
+ first.Accept(new ReplaceBreakStatementsVisitor(endSwitchName));
+
+ FindUnneededLabelsVisitor fulv = new FindUnneededLabelsVisitor(currentSwitchTempName + "_", nameComparer);
+ first.Accept(fulv);
+
+ if (fulv.NeededLabels.Contains(endSwitchName)) {
+ l.Add(MakeLabel(endSwitchName));
+ }
+
+ fulv.RemoveLabels(); // remove "goto case" labels that aren't needed
+ currentSwitchTempName = oldSwitchTempName;
+ return l;
+ }
+
+ public object Visit(SwitchSection switchSection, object data)
+ {
+ B.IfStatement surroundingIf = (B.IfStatement)data;
+ bool isDefault = false;
+ ArrayList conditions = new ArrayList();
+ ArrayList labels = new ArrayList();
+ foreach (CaseLabel caseLabel in switchSection.SwitchLabels) {
+ if (caseLabel.IsDefault) {
+ isDefault = true;
+ } else {
+ if (caseLabel.BinaryOperatorType != BinaryOperatorType.None) {
+ AddError(caseLabel, "VB's Case Is currently not supported (Daniel's too lazy for VB stuff)");
+ } else {
+ B.Expression expr = ConvertExpression(caseLabel.Label);
+ if (expr != null) {
+ conditions.Add(new B.BinaryExpression(B.BinaryOperatorType.Equality,
+ new B.ReferenceExpression(currentSwitchTempName),
+ expr));
+ string labelName = expr.ToCodeString().GetHashCode().ToString(System.Globalization.NumberFormatInfo.InvariantInfo);
+ labels.Add(MakeLabel(currentSwitchTempName + "_" + labelName));
+ }
+ }
+ }
+ }
+ B.IfStatement s = null;
+ if (conditions.Count > 0) {
+ s = new B.IfStatement(GetLexicalInfo(switchSection));
+ if (surroundingIf != null) {
+ s.FalseBlock = surroundingIf.FalseBlock;
+ surroundingIf.FalseBlock = new B.Block();
+ surroundingIf.FalseBlock.Add(s);
+ }
+ s.TrueBlock = new B.Block();
+ foreach (B.Statement stmt in labels) {
+ s.TrueBlock.Add(stmt);
+ }
+ B.Expression combined = (B.Expression)conditions[0];
+ for (int i = 1; i < conditions.Count; i++) {
+ combined = new B.BinaryExpression(B.BinaryOperatorType.Or, combined, (B.Expression)conditions[i]);
+ }
+ s.Condition = combined;
+ foreach (Statement node in switchSection.Children) {
+ AddToBlock(node, s.TrueBlock);
+ }
+ }
+ if (s == null)
+ s = surroundingIf;
+ if (isDefault) {
+ if (s.FalseBlock == null)
+ s.FalseBlock = new B.Block();
+ s.FalseBlock.Add(MakeLabel(currentSwitchTempName + "_default"));
+ foreach (Statement node in switchSection.Children) {
+ AddToBlock(node, s.FalseBlock);
+ }
+ }
+ return s;
+ }
+
+ public object Visit(GotoCaseStatement gotoCaseStatement, object data)
+ {
+ if (currentSwitchTempName == null) {
+ AddError(gotoCaseStatement, "goto case cannot be used outside switch");
+ return null;
+ }
+ string labelName;
+ if (gotoCaseStatement.IsDefaultCase) {
+ labelName = "default";
+ } else {
+ B.Expression expr = ConvertExpression(gotoCaseStatement.Expression);
+ if (expr == null) return null;
+ labelName = expr.ToCodeString().GetHashCode().ToString(System.Globalization.NumberFormatInfo.InvariantInfo);
+ }
+ return new B.GotoStatement(GetLexicalInfo(gotoCaseStatement),
+ new B.ReferenceExpression(currentSwitchTempName + "_" + labelName));
+ }
+
+ public object Visit(CaseLabel caseLabel, object data)
+ {
+ throw new ApplicationException("CaseLabel was visited.");
+ }
+ }
+}
diff --git a/src/AddIns/BackendBindings/Boo/NRefactoryToBooConverter/Project/ConvertVisitorTypeMembers.cs b/src/AddIns/BackendBindings/Boo/NRefactoryToBooConverter/Project/ConvertVisitorTypeMembers.cs
new file mode 100644
index 0000000000..b1845b3067
--- /dev/null
+++ b/src/AddIns/BackendBindings/Boo/NRefactoryToBooConverter/Project/ConvertVisitorTypeMembers.cs
@@ -0,0 +1,324 @@
+#region license
+// Copyright (c) 2005, Daniel Grunwald (daniel@danielgrunwald.de)
+// All rights reserved.
+//
+// NRefactoryToBoo is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// NRefactoryToBoo is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with NRefactoryToBoo; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#endregion
+
+using System;
+using System.Collections.Generic;
+using ICSharpCode.NRefactory.Parser;
+using ICSharpCode.NRefactory.Parser.AST;
+using Boo.Lang.Compiler;
+using B = Boo.Lang.Compiler.Ast;
+
+namespace NRefactoryToBooConverter
+{
+ partial class ConvertVisitor
+ {
+ public object Visit(FieldDeclaration fieldDeclaration, object data)
+ {
+ for (int i = 0; i < fieldDeclaration.Fields.Count; i++) {
+ ConvertField(fieldDeclaration.GetTypeForField(i), fieldDeclaration.Fields[i], fieldDeclaration);
+ }
+ return null;
+ }
+
+ public object Visit(VariableDeclaration variableDeclaration, object data)
+ {
+ throw new ApplicationException("Visited VariableDeclaration.");
+ }
+
+ void ConvertField(TypeReference typeRef, VariableDeclaration variable, FieldDeclaration fieldDeclaration)
+ {
+ B.TypeMember m;
+ if (currentType is B.EnumDefinition) {
+ if (variable.Initializer.IsNull) {
+ m = new B.EnumMember(GetLexicalInfo(fieldDeclaration));
+ } else {
+ PrimitiveExpression p = variable.Initializer as PrimitiveExpression;
+ if (p == null || !(p.Value is int)) {
+ AddError(fieldDeclaration, "enum member initializer must be integer value");
+ return;
+ }
+ m = new B.EnumMember(GetLexicalInfo(fieldDeclaration), new B.IntegerLiteralExpression((int)p.Value));
+ }
+ } else {
+ m = new B.Field(GetLexicalInfo(fieldDeclaration), ConvertTypeReference(typeRef), ConvertExpression(variable.Initializer));
+ m.Modifiers = ConvertModifier(fieldDeclaration, B.TypeMemberModifiers.Private);
+ }
+ m.Name = variable.Name;
+ ConvertAttributes(fieldDeclaration.Attributes, m.Attributes);
+ currentType.Members.Add(m);
+ }
+
+ B.Block ConvertMethodBlock(BlockStatement block)
+ {
+ B.Block b = ConvertBlock(block);
+ RenameLocalsVisitor.RenameLocals(b, nameComparer);
+ return b;
+ }
+
+ B.Method entryPointMethod;
+
+ public object Visit(MethodDeclaration methodDeclaration, object data)
+ {
+ B.Method m = new B.Method(GetLexicalInfo(methodDeclaration));
+ m.Name = methodDeclaration.Name;
+ m.Modifiers = ConvertModifier(methodDeclaration, B.TypeMemberModifiers.Private);
+ ConvertAttributes(methodDeclaration.Attributes, m.Attributes);
+ currentType.Members.Add(m);
+ if (methodDeclaration.HandlesClause.Count > 0) {
+ // TODO: Convert handles clauses to [Handles] attribute
+ AddError(methodDeclaration, "Handles-clause is not supported.");
+ }
+ if (methodDeclaration.ImplementsClause.Count > 0) {
+ AddError(methodDeclaration, "Explicit interface implementation is not supported.");
+ }
+ if (methodDeclaration.Templates.Count > 0) {
+ AddError(methodDeclaration, "Declaring generic methods is not supported.");
+ }
+ ConvertParameters(methodDeclaration.Parameters, m.Parameters);
+ m.EndSourceLocation = GetEndLocation((INode)methodDeclaration.Body ?? methodDeclaration);
+ m.ReturnType = ConvertTypeReference(methodDeclaration.TypeReference);
+ m.Body = ConvertMethodBlock(methodDeclaration.Body);
+ if (m.Name == "Main" && m.IsStatic && m.Parameters.Count <= 1 &&
+ (methodDeclaration.TypeReference.SystemType == "System.Void" || methodDeclaration.TypeReference.SystemType == "System.Int32"))
+ {
+ entryPointMethod = m;
+ }
+ return m;
+ }
+
+
+ public object Visit(ConstructorDeclaration constructorDeclaration, object data)
+ {
+ B.Constructor m = new B.Constructor(GetLexicalInfo(constructorDeclaration));
+ m.Modifiers = ConvertModifier(constructorDeclaration, B.TypeMemberModifiers.Private);
+ ConvertAttributes(constructorDeclaration.Attributes, m.Attributes);
+ currentType.Members.Add(m);
+ ConvertParameters(constructorDeclaration.Parameters, m.Parameters);
+ m.EndSourceLocation = GetEndLocation((INode)constructorDeclaration.Body ?? constructorDeclaration);
+ m.Body = ConvertMethodBlock(constructorDeclaration.Body);
+ ConstructorInitializer ci = constructorDeclaration.ConstructorInitializer;
+ if (ci != null && !ci.IsNull) {
+ B.Expression initializerBase;
+ if (ci.ConstructorInitializerType == ConstructorInitializerType.Base)
+ initializerBase = new B.SuperLiteralExpression();
+ else
+ initializerBase = new B.SelfLiteralExpression();
+ B.MethodInvocationExpression initializer = new B.MethodInvocationExpression(initializerBase);
+ ConvertExpressions(ci.Arguments, initializer.Arguments);
+ m.Body.Insert(0, new B.ExpressionStatement(initializer));
+ }
+ return m;
+ }
+
+ public object Visit(DestructorDeclaration destructorDeclaration, object data)
+ {
+ B.Destructor m = new B.Destructor(GetLexicalInfo(destructorDeclaration));
+ ConvertAttributes(destructorDeclaration.Attributes, m.Attributes);
+ currentType.Members.Add(m);
+ m.EndSourceLocation = GetLocation(destructorDeclaration.EndLocation);
+ m.Body = ConvertMethodBlock(destructorDeclaration.Body);
+ return m;
+ }
+
+ void ConvertParameters(List input, B.ParameterDeclarationCollection output)
+ {
+ bool isParams = false;
+ foreach (ParameterDeclarationExpression pde in input) {
+ B.ParameterDeclaration para = ConvertParameter(pde, out isParams);
+ if (para != null)
+ output.Add(para);
+ }
+ output.VariableNumber = isParams;
+ }
+
+ B.ParameterDeclaration ConvertParameter(ParameterDeclarationExpression pde, out bool isParams)
+ {
+ B.ParameterDeclaration para = new B.ParameterDeclaration(pde.ParameterName, ConvertTypeReference(pde.TypeReference));
+ if ((pde.ParamModifier & ParamModifier.Optional) != 0) {
+ AddError(pde, "Optional parameters are not supported.");
+ }
+ if ((pde.ParamModifier & ParamModifier.Out) != 0) {
+ para.Modifiers |= B.ParameterModifiers.Ref;
+ }
+ if ((pde.ParamModifier & ParamModifier.Ref) != 0) {
+ para.Modifiers |= B.ParameterModifiers.Ref;
+ }
+ isParams = (pde.ParamModifier & ParamModifier.Params) != 0;
+ ConvertAttributes(pde.Attributes, para.Attributes);
+ return para;
+ }
+
+ public object Visit(ParameterDeclarationExpression parameterDeclarationExpression, object data)
+ {
+ bool tmp;
+ return ConvertParameter(parameterDeclarationExpression, out tmp);
+ }
+
+ public object Visit(PropertyDeclaration propertyDeclaration, object data)
+ {
+ B.Property m = new B.Property(GetLexicalInfo(propertyDeclaration));
+ m.Name = propertyDeclaration.Name;
+ m.Modifiers = ConvertModifier(propertyDeclaration, B.TypeMemberModifiers.Private);
+ ConvertAttributes(propertyDeclaration.Attributes, m.Attributes);
+ currentType.Members.Add(m);
+ ConvertParameters(propertyDeclaration.Parameters, m.Parameters);
+ m.EndSourceLocation = GetLocation(propertyDeclaration.EndLocation);
+ m.Type = ConvertTypeReference(propertyDeclaration.TypeReference);
+ if (propertyDeclaration.ImplementsClause.Count > 0) {
+ AddError(propertyDeclaration, "Explicit interface implementation is not supported.");
+ }
+ if (!propertyDeclaration.IsWriteOnly) {
+ m.Getter = new B.Method(GetLexicalInfo(propertyDeclaration.GetRegion));
+ if (propertyDeclaration.GetRegion != null) {
+ ConvertAttributes(propertyDeclaration.GetRegion.Attributes, m.Getter.Attributes);
+ m.Modifiers = ConvertModifier(propertyDeclaration.GetRegion, m.Visibility);
+ m.Getter.Body = ConvertMethodBlock(propertyDeclaration.GetRegion.Block);
+ m.Getter.ReturnType = m.Type;
+ }
+ }
+ if (!propertyDeclaration.IsReadOnly) {
+ m.Setter = new B.Method(GetLexicalInfo(propertyDeclaration.SetRegion));
+ if (propertyDeclaration.SetRegion != null) {
+ ConvertAttributes(propertyDeclaration.SetRegion.Attributes, m.Setter.Attributes);
+ m.Modifiers = ConvertModifier(propertyDeclaration.SetRegion, m.Visibility);
+ m.Setter.Body = ConvertMethodBlock(propertyDeclaration.SetRegion.Block);
+ }
+ }
+ return m;
+ }
+
+ public const string DefaultIndexerName = "Indexer";
+
+ public object Visit(IndexerDeclaration indexerDeclaration, object data)
+ {
+ indexerDeclaration.Modifier |= Modifier.Default;
+
+ B.Property m = new B.Property(GetLexicalInfo(indexerDeclaration));
+ m.Name = DefaultIndexerName;
+ m.Modifiers = ConvertModifier(indexerDeclaration, B.TypeMemberModifiers.Private);
+ ConvertAttributes(indexerDeclaration.Attributes, m.Attributes);
+ currentType.Members.Add(m);
+ ConvertParameters(indexerDeclaration.Parameters, m.Parameters);
+ m.EndSourceLocation = GetLocation(indexerDeclaration.EndLocation);
+ m.Type = ConvertTypeReference(indexerDeclaration.TypeReference);
+ if (!indexerDeclaration.IsWriteOnly) {
+ m.Getter = new B.Method(GetLexicalInfo(indexerDeclaration.GetRegion));
+ if (indexerDeclaration.GetRegion != null) {
+ ConvertAttributes(indexerDeclaration.GetRegion.Attributes, m.Getter.Attributes);
+ m.Modifiers = ConvertModifier(indexerDeclaration.GetRegion, m.Visibility);
+ m.Getter.Body = ConvertMethodBlock(indexerDeclaration.GetRegion.Block);
+ m.Getter.ReturnType = m.Type;
+ }
+ }
+ if (!indexerDeclaration.IsReadOnly) {
+ m.Setter = new B.Method(GetLexicalInfo(indexerDeclaration.SetRegion));
+ if (indexerDeclaration.SetRegion != null) {
+ ConvertAttributes(indexerDeclaration.SetRegion.Attributes, m.Setter.Attributes);
+ m.Modifiers = ConvertModifier(indexerDeclaration.SetRegion, m.Visibility);
+ m.Setter.Body = ConvertMethodBlock(indexerDeclaration.SetRegion.Block);
+ }
+ }
+ return m;
+ }
+
+ public object Visit(PropertyGetRegion propertyGetRegion, object data)
+ {
+ throw new ApplicationException("PropertyGetRegion visited.");
+ }
+
+ public object Visit(PropertySetRegion propertySetRegion, object data)
+ {
+ throw new ApplicationException("PropertySetRegion visited.");
+ }
+
+ public object Visit(EventDeclaration eventDeclaration, object data)
+ {
+ B.Event m = new B.Event(GetLexicalInfo(eventDeclaration));
+ if (eventDeclaration.Name == null || eventDeclaration.Name.Length == 0) {
+ m.Name = eventDeclaration.VariableDeclarators[0].Name;
+ } else {
+ m.Name = eventDeclaration.Name;
+ }
+ m.Modifiers = ConvertModifier(eventDeclaration, B.TypeMemberModifiers.Private);
+ ConvertAttributes(eventDeclaration.Attributes, m.Attributes);
+ currentType.Members.Add(m);
+ m.EndSourceLocation = GetLocation(eventDeclaration.EndLocation);
+ m.Type = ConvertTypeReference(eventDeclaration.TypeReference);
+ if (eventDeclaration.ImplementsClause.Count > 0) {
+ AddError(eventDeclaration, "Explicit interface implementation is not supported.");
+ }
+ if (eventDeclaration.Parameters.Count > 0) {
+ AddError(eventDeclaration, "Events with parameters are not supported.");
+ }
+ if (eventDeclaration.VariableDeclarators.Count > 1) {
+ AddError(eventDeclaration, "You can only define one event per line.");
+ }
+ if (eventDeclaration.HasAddRegion) {
+ m.Add = new B.Method(GetLexicalInfo(eventDeclaration.AddRegion));
+ ConvertAttributes(eventDeclaration.AddRegion.Attributes, m.Add.Attributes);
+ m.Modifiers = ConvertModifier(eventDeclaration.AddRegion, m.Visibility);
+ m.Add.Body = ConvertMethodBlock(eventDeclaration.AddRegion.Block);
+ }
+ if (eventDeclaration.HasRemoveRegion) {
+ m.Remove = new B.Method(GetLexicalInfo(eventDeclaration.RemoveRegion));
+ ConvertAttributes(eventDeclaration.RemoveRegion.Attributes, m.Remove.Attributes);
+ m.Modifiers = ConvertModifier(eventDeclaration.RemoveRegion, m.Visibility);
+ m.Remove.Body = ConvertMethodBlock(eventDeclaration.RemoveRegion.Block);
+ }
+ if (eventDeclaration.HasRaiseRegion) {
+ m.Raise = new B.Method(GetLexicalInfo(eventDeclaration.RaiseRegion));
+ ConvertAttributes(eventDeclaration.RaiseRegion.Attributes, m.Raise.Attributes);
+ m.Modifiers = ConvertModifier(eventDeclaration.RaiseRegion, m.Visibility);
+ m.Raise.Body = ConvertMethodBlock(eventDeclaration.RaiseRegion.Block);
+ }
+ return m;
+ }
+
+ public object Visit(EventAddRegion eventAddRegion, object data)
+ {
+ throw new ApplicationException("EventAddRegion visited.");
+ }
+
+ public object Visit(EventRemoveRegion eventRemoveRegion, object data)
+ {
+ throw new ApplicationException("EventRemoveRegion visited.");
+ }
+
+ public object Visit(EventRaiseRegion eventRaiseRegion, object data)
+ {
+ throw new ApplicationException("EventRaiseRegion visited.");
+ }
+
+ public object Visit(ConstructorInitializer constructorInitializer, object data)
+ {
+ throw new ApplicationException("ConstructorInitializer visited.");
+ }
+
+ public object Visit(OperatorDeclaration operatorDeclaration, object data)
+ {
+ AddError(operatorDeclaration, "Declaring operators is not supported (BOO-223).");
+ return null;
+ }
+
+ public object Visit(DeclareDeclaration declareDeclaration, object data)
+ {
+ throw new NotImplementedException();
+ }
+ }
+}
diff --git a/src/AddIns/BackendBindings/Boo/NRefactoryToBooConverter/Project/Converter.cs b/src/AddIns/BackendBindings/Boo/NRefactoryToBooConverter/Project/Converter.cs
new file mode 100644
index 0000000000..fec1981c20
--- /dev/null
+++ b/src/AddIns/BackendBindings/Boo/NRefactoryToBooConverter/Project/Converter.cs
@@ -0,0 +1,51 @@
+#region license
+// Copyright (c) 2005, Daniel Grunwald (daniel@danielgrunwald.de)
+// All rights reserved.
+//
+// NRefactoryToBoo is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// NRefactoryToBoo is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with NRefactoryToBoo; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#endregion
+
+using System;
+using NR = ICSharpCode.NRefactory.Parser.AST;
+using Boo.Lang.Compiler;
+using Boo.Lang.Compiler.Ast;
+
+namespace NRefactoryToBooConverter
+{
+ ///
+ /// Class with static conversion methods.
+ ///
+ public static class Converter
+ {
+ public static Module Convert(NR.CompilationUnit cu, ConverterSettings settings)
+ {
+ if (cu == null)
+ throw new ArgumentNullException("cu");
+ if (settings == null)
+ throw new ArgumentNullException("settings");
+ cu.AcceptVisitor(new RefactoryVisitor(), null);
+ return (Module)cu.AcceptVisitor(new ConvertVisitor(settings), null);
+ }
+
+ public static Expression Convert(NR.Expression expression, ConverterSettings settings)
+ {
+ if (expression == null)
+ throw new ArgumentNullException("expression");
+ if (settings == null)
+ throw new ArgumentNullException("settings");
+ return (Expression)expression.AcceptVisitor(new ConvertVisitor(settings), null);
+ }
+ }
+}
diff --git a/src/AddIns/BackendBindings/Boo/NRefactoryToBooConverter/Project/ConverterSettings.cs b/src/AddIns/BackendBindings/Boo/NRefactoryToBooConverter/Project/ConverterSettings.cs
new file mode 100644
index 0000000000..59d58858da
--- /dev/null
+++ b/src/AddIns/BackendBindings/Boo/NRefactoryToBooConverter/Project/ConverterSettings.cs
@@ -0,0 +1,105 @@
+#region license
+// Copyright (c) 2005, Daniel Grunwald (daniel@danielgrunwald.de)
+// All rights reserved.
+//
+// NRefactoryToBoo is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// NRefactoryToBoo is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with NRefactoryToBoo; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#endregion
+
+using System;
+using Boo.Lang.Compiler;
+
+namespace NRefactoryToBooConverter
+{
+ public sealed class ConverterSettings
+ {
+ CompilerErrorCollection errors;
+ CompilerWarningCollection warnings;
+ string fileName;
+ StringComparer nameComparer;
+
+ public const string DefaultNameGenerationPrefix = "converterGeneratedName";
+ public string NameGenerationPrefix = DefaultNameGenerationPrefix;
+ public bool SimplifyTypeNames = true;
+
+ static StringComparer GetComparer(string fileName)
+ {
+ if (System.IO.Path.GetExtension(fileName).ToLower() == ".vb")
+ return StringComparer.InvariantCultureIgnoreCase;
+ else
+ return StringComparer.InvariantCulture;
+ }
+
+ public bool IsVisualBasic {
+ get {
+ return System.IO.Path.GetExtension(fileName).ToLower() == ".vb";
+ }
+ }
+
+ public ConverterSettings(string fileName)
+ : this(fileName, GetComparer(fileName))
+ {
+ }
+
+ public ConverterSettings(string fileName, StringComparer nameComparer)
+ : this(fileName, nameComparer, new CompilerErrorCollection(), new CompilerWarningCollection())
+ {
+ }
+
+ public ConverterSettings(string fileName, CompilerErrorCollection errors, CompilerWarningCollection warnings)
+ : this(fileName, GetComparer(fileName), errors, warnings)
+ {
+ }
+
+ public ConverterSettings(string fileName, StringComparer nameComparer, CompilerErrorCollection errors, CompilerWarningCollection warnings)
+ {
+ if (fileName == null)
+ throw new ArgumentNullException("fileName");
+ if (nameComparer == null)
+ throw new ArgumentNullException("nameComparer");
+ if (errors == null)
+ throw new ArgumentNullException("errors");
+ if (warnings == null)
+ throw new ArgumentNullException("warnings");
+ this.errors = errors;
+ this.warnings = warnings;
+ this.fileName = fileName;
+ this.nameComparer = nameComparer;
+ }
+
+ public CompilerErrorCollection Errors {
+ get {
+ return errors;
+ }
+ }
+
+ public CompilerWarningCollection Warnings {
+ get {
+ return warnings;
+ }
+ }
+
+ public string FileName {
+ get {
+ return fileName;
+ }
+ }
+
+ public StringComparer NameComparer {
+ get {
+ return nameComparer;
+ }
+ }
+ }
+}
diff --git a/src/AddIns/BackendBindings/Boo/NRefactoryToBooConverter/Project/FindUnneededLabelsVisitor.cs b/src/AddIns/BackendBindings/Boo/NRefactoryToBooConverter/Project/FindUnneededLabelsVisitor.cs
new file mode 100644
index 0000000000..59cc6d0fa4
--- /dev/null
+++ b/src/AddIns/BackendBindings/Boo/NRefactoryToBooConverter/Project/FindUnneededLabelsVisitor.cs
@@ -0,0 +1,102 @@
+#region license
+// Copyright (c) 2005, Daniel Grunwald (daniel@danielgrunwald.de)
+// All rights reserved.
+//
+// NRefactoryToBoo is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// NRefactoryToBoo is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with NRefactoryToBoo; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#endregion
+
+using System;
+using System.Collections.Generic;
+using Boo.Lang.Compiler;
+using Boo.Lang.Compiler.Ast;
+using Boo.Lang.Compiler.Ast.Visitors;
+
+namespace NRefactoryToBooConverter
+{
+ ///
+ /// This visitor finds label statements that have no matching goto statements.
+ ///
+ public class FindUnneededLabelsVisitor : DepthFirstVisitor
+ {
+ string prefix;
+ StringComparer nameComparer;
+
+ ///
+ /// Remove only those unneeded labels that start with .
+ /// Use null to remove all unneeded labels.
+ ///
+ public FindUnneededLabelsVisitor(string prefix, StringComparer nameComparer)
+ {
+ this.prefix = prefix;
+ this.nameComparer = nameComparer;
+ }
+
+ List unneededLabels = new List();
+ List neededLabels = new List();
+
+ public List NeededLabels {
+ get {
+ return neededLabels;
+ }
+ }
+
+ public List UnneededLabels {
+ get {
+ return unneededLabels;
+ }
+ }
+
+ ///
+ /// Removes all unneeded labels that have been found from the AST.
+ ///
+ public void RemoveLabels()
+ {
+ foreach (LabelStatement l in unneededLabels) {
+ l.ReplaceBy(null);
+ }
+ unneededLabels.Clear();
+ neededLabels.Clear();
+ }
+
+ bool MatchName(string name)
+ {
+ if (prefix == null)
+ return true;
+ if (name.Length < prefix.Length)
+ return false;
+ return nameComparer.Equals(prefix, name.Substring(0, prefix.Length));
+ }
+
+ public override void OnLabelStatement(LabelStatement node)
+ {
+ string name = node.Name;
+ if (!MatchName(name)) return;
+ if (neededLabels.Contains(name)) return;
+ unneededLabels.Add(node);
+ }
+
+ public override void OnGotoStatement(GotoStatement node)
+ {
+ string name = node.Label.Name;
+ if (!MatchName(name)) return;
+ if (neededLabels.Contains(name)) return;
+ neededLabels.Add(name);
+ for (int i = 0; i < unneededLabels.Count; i++) {
+ if (unneededLabels[i].Name == name)
+ unneededLabels.RemoveAt(i--);
+ }
+ }
+ }
+}
diff --git a/src/AddIns/BackendBindings/Boo/NRefactoryToBooConverter/Project/NRefactoryToBooConverter.csproj b/src/AddIns/BackendBindings/Boo/NRefactoryToBooConverter/Project/NRefactoryToBooConverter.csproj
new file mode 100644
index 0000000000..099902a839
--- /dev/null
+++ b/src/AddIns/BackendBindings/Boo/NRefactoryToBooConverter/Project/NRefactoryToBooConverter.csproj
@@ -0,0 +1,51 @@
+
+
+ Library
+ NRefactoryToBooConverter
+ NRefactoryToBooConverter
+ Debug
+ AnyCPU
+ {DBCF20A1-BA13-4582-BFA9-74DE4D987B73}
+
+
+ bin\Debug\
+ false
+ DEBUG;TRACE
+
+
+ bin\Release\
+ true
+ TRACE
+
+
+
+
+
+
+ ..\..\RequiredLibraries\Boo.Lang.Compiler.dll
+ False
+
+
+ ..\..\RequiredLibraries\Boo.Lang.dll
+ False
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/AddIns/BackendBindings/Boo/NRefactoryToBooConverter/Project/Parser.cs b/src/AddIns/BackendBindings/Boo/NRefactoryToBooConverter/Project/Parser.cs
new file mode 100644
index 0000000000..d142cc780d
--- /dev/null
+++ b/src/AddIns/BackendBindings/Boo/NRefactoryToBooConverter/Project/Parser.cs
@@ -0,0 +1,90 @@
+#region license
+// Copyright (c) 2005, Daniel Grunwald (daniel@danielgrunwald.de)
+// All rights reserved.
+//
+// NRefactoryToBoo is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// NRefactoryToBoo is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with NRefactoryToBoo; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.IO;
+using Boo.Lang.Compiler;
+using Boo.Lang.Compiler.Ast;
+using ICSharpCode.NRefactory.Parser;
+
+namespace NRefactoryToBooConverter
+{
+ ///
+ /// Class with static methods to parse C# and VB code.
+ ///
+ public static class Parser
+ {
+ public static Module ParseModule(CompileUnit cu, TextReader input, ConverterSettings settings)
+ {
+ IList specials;
+ return ParseModule(cu, input, settings, out specials);
+ }
+
+ public static Module ParseModule(CompileUnit cu, TextReader input, ConverterSettings settings, out IList specials)
+ {
+ if (cu == null)
+ throw new ArgumentNullException("cu");
+ if (input == null)
+ throw new ArgumentNullException("input");
+ if (settings == null)
+ throw new ArgumentNullException("settings");
+ IParser parser = ParserFactory.CreateParser(settings.IsVisualBasic ? SupportedLanguage.VBNet : SupportedLanguage.CSharp, input);
+ ErrorTrap errorTrap = new ErrorTrap(settings);
+ parser.Errors.SemErr = errorTrap.DefaultCodeError;
+ parser.Errors.SynErr = errorTrap.DefaultCodeError;
+ parser.Errors.Error = errorTrap.DefaultMsgError;
+ parser.Parse();
+ specials = parser.Lexer.SpecialTracker.CurrentSpecials;
+ // abort when file has errors
+ if (errorTrap.count > 0)
+ return null;
+ Module m = Converter.Convert(parser.CompilationUnit, settings);
+ if (m != null && cu != null) {
+ cu.Modules.Add(m);
+ }
+ return m;
+ }
+
+ internal class ErrorTrap
+ {
+ CompilerErrorCollection errors;
+ string fileName;
+ internal int count;
+
+ internal ErrorTrap(ConverterSettings settings)
+ {
+ this.errors = settings.Errors;
+ this.fileName = settings.FileName;
+ }
+
+ internal void DefaultCodeError(int line, int col, int n)
+ {
+ errors.Add(new CompilerError(new LexicalInfo(fileName, line, col), "Error number " + n));
+ count++;
+ }
+
+ internal void DefaultMsgError(int line, int col, string s)
+ {
+ errors.Add(new CompilerError(new LexicalInfo(fileName, line, col), s));
+ count++;
+ }
+ }
+ }
+}
diff --git a/src/AddIns/BackendBindings/Boo/NRefactoryToBooConverter/Project/RefactoryVisitor.cs b/src/AddIns/BackendBindings/Boo/NRefactoryToBooConverter/Project/RefactoryVisitor.cs
new file mode 100644
index 0000000000..869dbbb685
--- /dev/null
+++ b/src/AddIns/BackendBindings/Boo/NRefactoryToBooConverter/Project/RefactoryVisitor.cs
@@ -0,0 +1,42 @@
+#region license
+// Copyright (c) 2005, Daniel Grunwald (daniel@danielgrunwald.de)
+// All rights reserved.
+//
+// NRefactoryToBoo is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// NRefactoryToBoo is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with NRefactoryToBoo; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#endregion
+
+using System;
+using ICSharpCode.NRefactory.Parser;
+using ICSharpCode.NRefactory.Parser.AST;
+
+namespace NRefactoryToBooConverter
+{
+ ///
+ /// Visitor that prepares the conversion by converting source-language specific constructs
+ /// into "better suited" constructs.
+ ///
+ ///
+ /// ForStatements of the form "for(int i = Start; i < End; i += Step)" are
+ /// converted to "For i As Integer = Start To End Step Step" (VB-Style) which has the better-matching
+ /// Boo representation of "for i as int in range(Start, End, Step):"
+ ///
+ public class RefactoryVisitor : CSharpToVBNetConvertVisitor
+ {
+ public RefactoryVisitor()
+ {
+ base.RenameConflictingFieldNames = false; // do not rename fields to VB-style
+ }
+ }
+}
diff --git a/src/AddIns/BackendBindings/Boo/NRefactoryToBooConverter/Project/RenameLocalsVisitor.cs b/src/AddIns/BackendBindings/Boo/NRefactoryToBooConverter/Project/RenameLocalsVisitor.cs
new file mode 100644
index 0000000000..8ae07e532b
--- /dev/null
+++ b/src/AddIns/BackendBindings/Boo/NRefactoryToBooConverter/Project/RenameLocalsVisitor.cs
@@ -0,0 +1,158 @@
+#region license
+// Copyright (c) 2005, Daniel Grunwald (daniel@danielgrunwald.de)
+// All rights reserved.
+//
+// NRefactoryToBoo is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// NRefactoryToBoo is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with NRefactoryToBoo; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#endregion
+
+using System;
+using System.Collections.Generic;
+using Boo.Lang.Compiler;
+using Boo.Lang.Compiler.Ast;
+using Boo.Lang.Compiler.Ast.Visitors;
+
+namespace NRefactoryToBooConverter
+{
+ public sealed class RenameLocalsVisitor : DepthFirstVisitor
+ {
+ public static void RenameLocals(Block block, StringComparer nameComparer)
+ {
+ FindVariableDeclarationsVisitor fvdv = new FindVariableDeclarationsVisitor();
+ block.Accept(fvdv);
+ List list = new List();
+ foreach (DeclarationStatement decl in fvdv.Declarations) {
+ DeclarationStatement conflict = null;
+ int conflictIndex = -1;
+ for (int i = 0; i < list.Count; i++) {
+ if (nameComparer.Equals(list[i].Declaration.Name, decl.Declaration.Name)) {
+ conflict = list[i];
+ conflictIndex = i;
+ break;
+ }
+ }
+ if (conflict == null) {
+ list.Add(decl);
+ } else {
+ // Handle conflict: try if "moveup" would be sufficient
+ if (IsSameType(decl.Declaration.Type, conflict.Declaration.Type, nameComparer)) {
+ // create declaration at beginning of class and
+ // replace decl & conflict by assignment
+ DeclarationStatement newDecl = new DeclarationStatement(conflict.LexicalInfo);
+ newDecl.Declaration = new Declaration(conflict.Declaration.LexicalInfo, conflict.Declaration.Name, conflict.Declaration.Type);
+ block.Insert(0, newDecl);
+ ReplaceWithInitializer(decl);
+ ReplaceWithInitializer(conflict);
+ list[conflictIndex] = newDecl;
+ } else {
+ string newName = FindFreeName(decl.Declaration.Name, list, fvdv.Declarations, nameComparer);
+ decl.ParentNode.Accept(new RenameLocalsVisitor(decl.Declaration.Name, newName, nameComparer));
+ decl.Declaration.Name = newName;
+ }
+ }
+ }
+ }
+
+ static string FindFreeName(string baseName, List list1, List list2, StringComparer nameComparer)
+ {
+ string tmp = baseName + "__";
+ for (int i = 2;; i++) {
+ string tryName = tmp + i.ToString(System.Globalization.NumberFormatInfo.InvariantInfo);
+ bool found = false;
+ foreach (DeclarationStatement d in list1) {
+ if (nameComparer.Equals(d.Declaration.Name, tryName)) {
+ found = true;
+ break;
+ }
+ }
+ if (found) continue;
+ foreach (DeclarationStatement d in list2) {
+ if (nameComparer.Equals(d.Declaration.Name, tryName)) {
+ found = true;
+ break;
+ }
+ }
+ if (!found)
+ return tryName;
+ }
+ }
+
+ static void ReplaceWithInitializer(DeclarationStatement decl)
+ {
+ if (decl.Initializer == null) {
+ decl.ReplaceBy(null);
+ } else {
+ ExpressionStatement statement = new ExpressionStatement(decl.LexicalInfo);
+ statement.Expression = new BinaryExpression(decl.LexicalInfo, BinaryOperatorType.Assign,
+ new ReferenceExpression(decl.Declaration.LexicalInfo, decl.Declaration.Name),
+ decl.Initializer);
+ decl.ReplaceBy(statement);
+ }
+ }
+
+ static bool IsSameType(TypeReference a, TypeReference b, StringComparer nameComparer)
+ {
+ ArrayTypeReference arr1 = a as ArrayTypeReference;
+ ArrayTypeReference arr2 = b as ArrayTypeReference;
+ SimpleTypeReference s1 = a as SimpleTypeReference;
+ SimpleTypeReference s2 = b as SimpleTypeReference;
+ if (arr1 != null && arr2 != null) {
+ if (arr1.Rank.Value != arr2.Rank.Value)
+ return false;
+ return IsSameType(arr1.ElementType, arr2.ElementType, nameComparer);
+ } else if (s1 != null && s2 != null) {
+ return nameComparer.Equals(s1.Name, s2.Name);
+ } else {
+ return false;
+ }
+ }
+
+ string oldName, newName;
+ StringComparer nameComparer;
+
+ private RenameLocalsVisitor(string oldName, string newName, StringComparer nameComparer)
+ {
+ this.oldName = oldName;
+ this.newName = newName;
+ this.nameComparer = nameComparer;
+ }
+
+ public override void OnReferenceExpression(ReferenceExpression node)
+ {
+ if (nameComparer.Equals(node.Name, oldName)) {
+ node.Name = newName;
+ }
+ }
+ }
+
+ public class FindVariableDeclarationsVisitor : DepthFirstVisitor
+ {
+ List declarations = new List();
+
+ public List Declarations {
+ get {
+ return declarations;
+ }
+ }
+
+ public override void OnCallableDefinition(CallableDefinition node) { }
+ public override void OnCallableBlockExpression(CallableBlockExpression node) { }
+
+ public override void OnDeclarationStatement(DeclarationStatement node)
+ {
+ declarations.Add(node);
+ base.OnDeclarationStatement(node);
+ }
+ }
+}
diff --git a/src/AddIns/BackendBindings/Boo/NRefactoryToBooConverter/Project/ReplaceBreakStatementsVisitor.cs b/src/AddIns/BackendBindings/Boo/NRefactoryToBooConverter/Project/ReplaceBreakStatementsVisitor.cs
new file mode 100644
index 0000000000..62dc04bfdf
--- /dev/null
+++ b/src/AddIns/BackendBindings/Boo/NRefactoryToBooConverter/Project/ReplaceBreakStatementsVisitor.cs
@@ -0,0 +1,52 @@
+#region license
+// Copyright (c) 2005, Daniel Grunwald (daniel@danielgrunwald.de)
+// All rights reserved.
+//
+// NRefactoryToBoo is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// NRefactoryToBoo is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with NRefactoryToBoo; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#endregion
+
+using System;
+using System.Collections.Generic;
+using Boo.Lang.Compiler;
+using Boo.Lang.Compiler.Ast;
+using Boo.Lang.Compiler.Ast.Visitors;
+
+namespace NRefactoryToBooConverter
+{
+ public class ReplaceBreakStatementsVisitor : DepthFirstVisitor
+ {
+ string label;
+
+ public ReplaceBreakStatementsVisitor(string label)
+ {
+ this.label = label;
+ }
+
+ public override void OnGivenStatement(GivenStatement node) { }
+
+ public override void OnForStatement(ForStatement node) { }
+
+ public override void OnWhileStatement(WhileStatement node) { }
+
+ public override void OnUnlessStatement(UnlessStatement node) { }
+
+ public override void OnBreakStatement(BreakStatement node)
+ {
+ GotoStatement gotoStatement = new GotoStatement(node.LexicalInfo);
+ gotoStatement.Label = new ReferenceExpression(node.LexicalInfo, label);
+ node.ReplaceBy(gotoStatement);
+ }
+ }
+}
diff --git a/src/AddIns/BackendBindings/Boo/NRefactoryToBooConverter/Project/VariableResolver.cs b/src/AddIns/BackendBindings/Boo/NRefactoryToBooConverter/Project/VariableResolver.cs
new file mode 100644
index 0000000000..95183d5d25
--- /dev/null
+++ b/src/AddIns/BackendBindings/Boo/NRefactoryToBooConverter/Project/VariableResolver.cs
@@ -0,0 +1,59 @@
+#region license
+// Copyright (c) 2005, Daniel Grunwald (daniel@danielgrunwald.de)
+// All rights reserved.
+//
+// NRefactoryToBoo is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// NRefactoryToBoo is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with NRefactoryToBoo; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#endregion
+
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using ICSharpCode.NRefactory.Parser;
+using ICSharpCode.NRefactory.Parser.AST;
+
+namespace NRefactoryToBooConverter
+{
+ ///
+ /// This class tries to find out the type of an identifier by looking at the NRefactory AST.
+ /// The possibilities inside the parser are very limited, we can only
+ /// search for local variables and fields.
+ ///
+ public class VariableResolver
+ {
+ StringComparer nameComparer;
+
+ public VariableResolver(StringComparer nameComparer)
+ {
+ this.nameComparer = nameComparer;
+ }
+
+ public TypeReference FindType(string name, Statement currentStatement)
+ {
+ INode node = currentStatement;
+ while ((node = node.Parent) != null) {
+ foreach (INode childNode in node.Children) {
+ LocalVariableDeclaration varDecl = childNode as LocalVariableDeclaration;
+ if (varDecl != null) {
+ foreach (VariableDeclaration var in varDecl.Variables) {
+ if (nameComparer.Equals(var.Name, name))
+ return var.TypeReference;
+ }
+ }
+ }
+ }
+ return null;
+ }
+ }
+}
diff --git a/src/AddIns/BackendBindings/Boo/NRefactoryToBooConverter/Test/ComplexTests.cs b/src/AddIns/BackendBindings/Boo/NRefactoryToBooConverter/Test/ComplexTests.cs
new file mode 100644
index 0000000000..c78fbd1dbd
--- /dev/null
+++ b/src/AddIns/BackendBindings/Boo/NRefactoryToBooConverter/Test/ComplexTests.cs
@@ -0,0 +1,51 @@
+#region license
+// Copyright (c) 2005, Daniel Grunwald (daniel@danielgrunwald.de)
+// All rights reserved.
+//
+// NRefactoryToBoo is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// NRefactoryToBoo is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with NRefactoryToBoo; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#endregion
+
+using System;
+using NUnit.Framework;
+
+namespace NRefactoryToBooConverter.Tests
+{
+ [TestFixture]
+ public class ComplexTests : TestHelper
+ {
+ [Test]
+ public void MovingLocals()
+ {
+ TestInClass("public void Run() { if (a) { int b = 1; } else { int b = 2; } }",
+ "public final def Run() as System.Void:\n" +
+ "\tb as System.Int32\n" +
+ "\tif a:\n" +
+ "\t\tb = 1\n" +
+ "\telse:\n" +
+ "\t\tb = 2");
+ }
+
+ [Test]
+ public void RenamingLocals()
+ {
+ TestInClass("public void Run() { if (a) { int b = 1; } else { double b = 2; } }",
+ "public final def Run() as System.Void:\n" +
+ "\tif a:\n" +
+ "\t\tb as System.Int32 = 1\n" +
+ "\telse:\n" +
+ "\t\tb__2 as System.Double = 2");
+ }
+ }
+}
diff --git a/src/AddIns/BackendBindings/Boo/NRefactoryToBooConverter/Test/ErrorTests.cs b/src/AddIns/BackendBindings/Boo/NRefactoryToBooConverter/Test/ErrorTests.cs
new file mode 100644
index 0000000000..39fb0c55c8
--- /dev/null
+++ b/src/AddIns/BackendBindings/Boo/NRefactoryToBooConverter/Test/ErrorTests.cs
@@ -0,0 +1,44 @@
+#region license
+// Copyright (c) 2005, Daniel Grunwald (daniel@danielgrunwald.de)
+// All rights reserved.
+//
+// NRefactoryToBoo is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// NRefactoryToBoo is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with NRefactoryToBoo; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#endregion
+
+using System;
+using System.IO;
+using Boo.Lang.Compiler;
+using Boo.Lang.Compiler.Ast;
+using NUnit.Framework;
+
+namespace NRefactoryToBooConverter.Tests
+{
+ ///
+ /// Tests for special cases that have to fail.
+ ///
+ //[TestFixture]
+ public class ErrorTests : TestHelper
+ {
+ /*
+ For the following errors are currently no checks implemented:
+
+ enum Enumeration : WithBaseType
+ enum Enumeration
+ static class Bla : WithBaseType
+ static class Bla
+ enum Enumeration { void Main(); } // check that enums can only have fields is not implemented
+ */
+ }
+}
diff --git a/src/AddIns/BackendBindings/Boo/NRefactoryToBooConverter/Test/ExpressionTests.cs b/src/AddIns/BackendBindings/Boo/NRefactoryToBooConverter/Test/ExpressionTests.cs
new file mode 100644
index 0000000000..1cff07af64
--- /dev/null
+++ b/src/AddIns/BackendBindings/Boo/NRefactoryToBooConverter/Test/ExpressionTests.cs
@@ -0,0 +1,226 @@
+#region license
+// Copyright (c) 2005, Daniel Grunwald (daniel@danielgrunwald.de)
+// All rights reserved.
+//
+// NRefactoryToBoo is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// NRefactoryToBoo is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with NRefactoryToBoo; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#endregion
+
+using System;
+using NUnit.Framework;
+
+namespace NRefactoryToBooConverter.Tests
+{
+ [TestFixture]
+ public class ExpressionTests : TestHelper
+ {
+ [Test]
+ public void Null()
+ {
+ TestExpr("null", "null");
+ }
+
+ [Test]
+ public void This()
+ {
+ TestExpr("this", "self");
+ }
+
+ [Test]
+ public void Super()
+ {
+ TestExpr("base.Member", "super.Member");
+ }
+
+ [Test]
+ public void Reference()
+ {
+ TestExpr("c", "c");
+ }
+
+ [Test]
+ public void MemberReference()
+ {
+ TestExpr("c.d", "c.d");
+ }
+
+ [Test]
+ public void MethodCall()
+ {
+ TestExpr("a()", "a()");
+ }
+
+ [Test]
+ public void MethodCallWithParameter()
+ {
+ TestExpr("a(4)", "a(4)");
+ }
+
+ [Test]
+ public void ObjectConstruction()
+ {
+ TestExpr("new MainClass()", "MainClass()");
+ }
+
+ [Test]
+ public void QualifiedConstruction()
+ {
+ TestExpr("new System.DefaultComparer()", "System.DefaultComparer()");
+ }
+
+ [Test]
+ public void Integer()
+ {
+ TestExpr("1", "1");
+ }
+
+ [Test]
+ public void Double()
+ {
+ TestExpr("1.0", "1.0");
+ }
+
+ [Test]
+ public void Single()
+ {
+ TestExpr("1f", "1.0F");
+ }
+
+ [Test]
+ public void UnaryMinus()
+ {
+ TestExpr("-(1)", "(-1)");
+ }
+
+ [Test]
+ public void UnaryBitNegation()
+ {
+ TestExpr("~1", "(~1)");
+ }
+
+ [Test]
+ public void UnaryLogicalNot()
+ {
+ TestExpr("!false", "(not false)");
+ }
+
+ [Test]
+ public void UnaryPlus()
+ {
+ TestExpr("+(1)", "1");
+ }
+
+ [Test]
+ public void PostIncrement()
+ {
+ TestExpr("i++", "(i++)");
+ }
+
+ [Test]
+ public void PostDecrement()
+ {
+ TestExpr("i--", "(i--)");
+ }
+
+ [Test]
+ public void Increment()
+ {
+ TestExpr("++i", "(++i)");
+ }
+
+ [Test]
+ public void Decrement()
+ {
+ TestExpr("--i", "(--i)");
+ }
+
+ [Test]
+ public void ArrayAccess()
+ {
+ TestExpr("arr[i]", "arr[i]");
+ }
+
+ [Test]
+ public void MultidimensionalArrayAccess()
+ {
+ TestExpr("arr[x,y]", "arr[x, y]");
+ }
+
+ [Test]
+ public void CreateArray()
+ {
+ TestExpr("new int[4]", "array(System.Int32, 4)");
+ }
+
+ [Test]
+ public void CreateNestedArray()
+ {
+ TestExpr("new int[4][]", "array(typeof((System.Int32)), 4)");
+ }
+
+ [Test]
+ public void CreateMultidimensionalArray()
+ {
+ TestExpr("new int[2, 3]", "matrix(System.Int32, (2, 3))");
+ }
+
+ [Test]
+ public void CreateEmptyArray()
+ {
+ TestExpr("new int[] { }", "(,)");
+ }
+
+ [Test]
+ public void CreateArrayWithOneElement()
+ {
+ TestExpr("new int[] { 1 }", "(1,)");
+ }
+
+ [Test]
+ public void CreateArrayWithTwoElements()
+ {
+ TestExpr("new int[] { 1 , 2 }", "(1, 2)");
+ }
+
+ [Test]
+ public void AnonymousMethod()
+ {
+ TestExpr("delegate { }", "def ():\n\tpass");
+ }
+
+ [Test]
+ public void AnonymousMethodWithEmptyParameterList()
+ {
+ TestExpr("delegate () { }", "def ():\n\tpass");
+ }
+
+ [Test]
+ public void AnonymousMethodWithParameters()
+ {
+ TestExpr("delegate (int a, string b) { }", "def (a as System.Int32, b as System.String):\n\tpass");
+ }
+
+ [Test, Ignore("ConditionalExpression does not have a boo syntax")]
+ public void Conditional()
+ {
+ TestExpr("a ? b : c", "a ? b : c");
+ }
+
+ [Test, Ignore("ConditionalExpression does not have a boo syntax")]
+ public void NullCoalescing()
+ {
+ TestExpr("a ?? b", "(a != null) ? a : b");
+ }
+ }
+}
diff --git a/src/AddIns/BackendBindings/Boo/NRefactoryToBooConverter/Test/GlobalTests.cs b/src/AddIns/BackendBindings/Boo/NRefactoryToBooConverter/Test/GlobalTests.cs
new file mode 100644
index 0000000000..c0175b253c
--- /dev/null
+++ b/src/AddIns/BackendBindings/Boo/NRefactoryToBooConverter/Test/GlobalTests.cs
@@ -0,0 +1,148 @@
+#region license
+// Copyright (c) 2005, Daniel Grunwald (daniel@danielgrunwald.de)
+// All rights reserved.
+//
+// NRefactoryToBoo is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// NRefactoryToBoo is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with NRefactoryToBoo; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#endregion
+
+using System;
+using NUnit.Framework;
+
+namespace NRefactoryToBooConverter.Tests
+{
+ [TestFixture]
+ public class GlobalTests : TestHelper
+ {
+ [Test]
+ public void EmptyFile()
+ {
+ Test("", "");
+ }
+
+ [Test]
+ public void EmptyNamespace()
+ {
+ Test("namespace A.B {}", "namespace A.B");
+ }
+
+ [Test]
+ public void SimpleUsing()
+ {
+ Test("using System.Windows.Forms;", "import System.Windows.Forms");
+ }
+
+ [Test]
+ public void AliasUsing()
+ {
+ Test("using WinForms = System.Windows.Forms;", "import System.Windows.Forms as WinForms");
+ }
+
+ [Test]
+ public void UsingOutsideNamespace()
+ {
+ Test("using System.Windows.Forms;\nnamespace A.B { } ", "namespace A.B\nimport System.Windows.Forms");
+ }
+
+ [Test]
+ public void UsingInsideNamespace()
+ {
+ Test("namespace A.B { using System.Windows.Forms; } ", "namespace A.B\nimport System.Windows.Forms");
+ }
+
+ [Test]
+ public void ClassDeclaration()
+ {
+ Test("public class Test {}", "public class Test:\n\tpass");
+ }
+
+ [Test]
+ public void ClassDeclarationWithAttribute()
+ {
+ Test("[TestFixture] class Test {}", "[TestFixture]\ninternal class Test:\n\tpass");
+ }
+
+ [Test]
+ public void ClassDeclarationWithMultipleAttributes()
+ {
+ Test("[TestFixture] [OtherA] class Test {}", "[TestFixture]\n[OtherA]\ninternal class Test:\n\tpass");
+ }
+
+ [Test]
+ public void ClassDeclarationWithBaseType()
+ {
+ Test("public class TestException : Exception {}", "public class TestException(Exception):\n\tpass");
+ }
+
+ [Test]
+ public void ClassDeclarationWithMultipleBaseTypes()
+ {
+ Test("public class TestException : Exception, IDisposable {}", "public class TestException(Exception, IDisposable):\n\tpass");
+ }
+
+ [Test]
+ public void InnerClassDeclaration()
+ {
+ Test("public class Test { class Inner {} }", "public class Test:\n\tprivate class Inner:\n\t\tpass");
+ }
+
+ [Test]
+ public void InterfaceDeclaration()
+ {
+ Test("public interface Test {}", "public interface Test:\n\tpass");
+ }
+
+ [Test]
+ public void InterfaceDeclarationWithAttribute()
+ {
+ Test("[TestFixture] interface Test {}", "[TestFixture]\ninternal interface Test:\n\tpass");
+ }
+
+ [Test]
+ public void InterfaceDeclarationWithBaseType()
+ {
+ Test("public interface ExtendedDisposable : IDisposable {}", "public interface ExtendedDisposable(IDisposable):\n\tpass");
+ }
+
+ [Test]
+ public void EnumerationDeclaration()
+ {
+ Test("public enum Test {}", "public enum Test:\n\tpass");
+ }
+
+ [Test]
+ public void EnumerationDeclarationWithAttribute()
+ {
+ Test("[TestFixture] enum Test {}", "[TestFixture]\ninternal enum Test:\n\tpass");
+ }
+
+ [Test]
+ public void StructureDeclaration()
+ {
+ Test("public struct Test {}", "public struct Test:\n\tpass");
+ }
+
+ [Test]
+ public void StructureDeclarationWithAttribute()
+ {
+ Test("[TestFixture] struct Test {}", "[TestFixture]\ninternal struct Test:\n\tpass");
+ }
+
+ [Test]
+ public void StructureDeclarationWithBaseType()
+ {
+ Test("public struct Bla : ValueType {}", "public struct Bla(ValueType):\n\tpass");
+ }
+ }
+}
diff --git a/src/AddIns/BackendBindings/Boo/NRefactoryToBooConverter/Test/MemberTests.cs b/src/AddIns/BackendBindings/Boo/NRefactoryToBooConverter/Test/MemberTests.cs
new file mode 100644
index 0000000000..ed1b5aedb4
--- /dev/null
+++ b/src/AddIns/BackendBindings/Boo/NRefactoryToBooConverter/Test/MemberTests.cs
@@ -0,0 +1,247 @@
+#region license
+// Copyright (c) 2005, Daniel Grunwald (daniel@danielgrunwald.de)
+// All rights reserved.
+//
+// NRefactoryToBoo is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// NRefactoryToBoo is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with NRefactoryToBoo; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#endregion
+
+using System;
+using NUnit.Framework;
+
+namespace NRefactoryToBooConverter.Tests
+{
+ [TestFixture]
+ public class MemberTests : TestHelper
+ {
+ [Test]
+ public void EnumerationMember()
+ {
+ Test("public enum Trool { No, Maybe, Yes }", "public enum Trool:\n\tNo\n\tMaybe\n\tYes");
+ }
+
+ [Test]
+ public void EnumerationMemberWithAttribute()
+ {
+ Test("public enum Trool { No, [XXX] Maybe, Yes }", "public enum Trool:\n\tNo\n\t[XXX]\n\tMaybe\n\tYes");
+ }
+
+ [Test]
+ public void EnumerationMemberWithValue()
+ {
+ Test("public enum Trool { No = 0, Maybe = 2, Yes = 4 }", "public enum Trool:\n\tNo = 0\n\tMaybe = 2\n\tYes = 4");
+ }
+
+ [Test]
+ public void Field()
+ {
+ TestInClass("MyType o;", "private o as MyType");
+ }
+
+ [Test]
+ public void MultipleFields()
+ {
+ TestInClass("MyType a, b, c;", "private a as MyType\nprivate b as MyType\nprivate c as MyType");
+ }
+
+ [Test]
+ public void PrimitiveField()
+ {
+ TestInClass("int num;", "private num as System.Int32");
+ }
+
+ [Test]
+ public void ArrayField()
+ {
+ TestInClass("Field[] Core;", "private Core as (Field)");
+ }
+
+ [Test]
+ public void FieldWithModifier()
+ {
+ TestInClass("public static int num;", "public static num as System.Int32");
+ }
+
+ [Test]
+ public void FullyQualifiedField()
+ {
+ TestInClass("System.IDisposable d;", "private d as System.IDisposable");
+ }
+
+ [Test]
+ public void FieldWithInitializer()
+ {
+ TestInClass("MyType o = null;", "private o as MyType = null");
+ }
+
+ [Test]
+ public void Method()
+ {
+ TestInClass("void Main() {}", "private final def Main() as System.Void:\n\tpass");
+ }
+
+ [Test]
+ public void MethodWithAttribute()
+ {
+ TestInClass("[Test] void Main() {}", "[Test]\nprivate final def Main() as System.Void:\n\tpass");
+ }
+
+ [Test]
+ public void MethodWithParameters()
+ {
+ TestInClass("void Main(int a, MyType b) {}", "private final def Main(a as System.Int32, b as MyType) as System.Void:\n\tpass");
+ }
+
+ [Test]
+ public void MethodWithRefParameters()
+ {
+ TestInClass("void Main(ref int a, out MyType b) {}", "private final def Main(ref a as System.Int32, ref b as MyType) as System.Void:\n\tpass");
+ }
+
+ [Test]
+ public void MethodWithParamsParameters()
+ {
+ TestInClass("void Main(int a, params string[] args) {}", "private final def Main(a as System.Int32, *args as (System.String)) as System.Void:\n\tpass");
+ }
+
+ [Test]
+ public void MethodWithReturnType()
+ {
+ TestInClass("MyType Main() {}", "private final def Main() as MyType:\n\tpass");
+ }
+
+ [Test]
+ public void MethodWithModifier()
+ {
+ TestInClass("public static void Run() {}", "public static def Run() as System.Void:\n\tpass");
+ }
+
+ [Test]
+ public void StaticMethodInStaticClass()
+ {
+ Test("public static class MainClass { public static void Run() {} }",
+ "public static class MainClass:\n\tpublic static def Run() as System.Void:\n\t\tpass");
+ }
+
+ [Test]
+ public void Constructor()
+ {
+ TestInClass("ClassName() {}", "private def constructor():\n\tpass");
+ }
+
+ [Test]
+ public void ConstructorWithAttribute()
+ {
+ TestInClass("[Test] ClassName() {}", "[Test]\nprivate def constructor():\n\tpass");
+ }
+
+ [Test]
+ public void ConstructorWithParameters()
+ {
+ TestInClass("ClassName(int a, MyType b) {}", "private def constructor(a as System.Int32, b as MyType):\n\tpass");
+ }
+
+ [Test]
+ public void ConstructorWithModifier()
+ {
+ TestInClass("public static ClassName() {}", "public static def constructor():\n\tpass");
+ }
+
+ [Test]
+ public void ConstructorWithThisCall()
+ {
+ TestInClass("public ClassName() : this(5) {}", "public def constructor():\n\tself(5)");
+ }
+
+ [Test]
+ public void ConstructorWithBaseCall()
+ {
+ TestInClass("public ClassName() : base(5) {}", "public def constructor():\n\tsuper(5)");
+ }
+
+ [Test]
+ public void Destructor()
+ {
+ TestInClass("~ClassName() {}", "def destructor():\n\tpass");
+ }
+
+ [Test]
+ public void DestructorWithAttribute()
+ {
+ TestInClass("[Test] ~ClassName() {}", "[Test]\ndef destructor():\n\tpass");
+ }
+
+ [Test]
+ public void ReadOnlyProperty()
+ {
+ TestInClass("public string Text { get { } }", "public Text as System.String:\n\tget:\n\t\tpass");
+ }
+
+ [Test]
+ public void WriteOnlyProperty()
+ {
+ TestInClass("public string Text { set { } }", "public Text as System.String:\n\tset:\n\t\tpass");
+ }
+
+ [Test]
+ public void Property()
+ {
+ TestInClass("public string Text { get {} set { } }", "public Text as System.String:\n\tget:\n\t\tpass\n\tset:\n\t\tpass");
+ }
+
+ [Test]
+ public void PropertyWithAttributes()
+ {
+ TestInClass("[AA] public string Text { [BB] get {} [CC] set { } }",
+ "[AA]\npublic Text as System.String:\n\t[BB]\n\tget:\n\t\tpass\n\t[CC]\n\tset:\n\t\tpass");
+ }
+
+ [Test]
+ public void ReadOnlyIndexer()
+ {
+ TestInClassWithIndexer("public string this[int index] { get { } }", "public Indexer(index as System.Int32) as System.String:\n\tget:\n\t\tpass");
+ }
+
+ [Test]
+ public void WriteOnlyIndexer()
+ {
+ TestInClassWithIndexer("public string this[int index] { set { } }", "public Indexer(index as System.Int32) as System.String:\n\tset:\n\t\tpass");
+ }
+
+ [Test]
+ public void Indexer()
+ {
+ TestInClassWithIndexer("public string this[int index] { get {} set { } }", "public Indexer(index as System.Int32) as System.String:\n\tget:\n\t\tpass\n\tset:\n\t\tpass");
+ }
+
+ [Test]
+ public void IndexerWithAttributes()
+ {
+ TestInClassWithIndexer("[AA] public string this[int index] { [BB] get {} [CC] set { } }",
+ "[AA]\npublic Indexer(index as System.Int32) as System.String:\n\t[BB]\n\tget:\n\t\tpass\n\t[CC]\n\tset:\n\t\tpass");
+ }
+
+ [Test]
+ public void Event()
+ {
+ TestInClass("public event EventHandler Closed;", "public event Closed as EventHandler");
+ }
+
+ [Test]
+ public void EventWithAttribute()
+ {
+ TestInClass("[LookHere] event EventHandler Closed;", "[LookHere]\nprivate event Closed as EventHandler");
+ }
+ }
+}
diff --git a/src/AddIns/BackendBindings/Boo/NRefactoryToBooConverter/Test/NRefactoryToBooConverter.Tests.csproj b/src/AddIns/BackendBindings/Boo/NRefactoryToBooConverter/Test/NRefactoryToBooConverter.Tests.csproj
new file mode 100644
index 0000000000..e824250723
--- /dev/null
+++ b/src/AddIns/BackendBindings/Boo/NRefactoryToBooConverter/Test/NRefactoryToBooConverter.Tests.csproj
@@ -0,0 +1,54 @@
+
+
+ Library
+ NRefactoryToBooConverter.Tests
+ NRefactoryToBooConverter.Tests
+ Debug
+ AnyCPU
+ {C9DE556D-325C-4544-B29F-16A9EB7C9830}
+
+
+ bin\Debug\
+ false
+ DEBUG;TRACE
+
+
+ bin\Release\
+ true
+ TRACE
+
+
+
+
+
+
+ ..\..\RequiredLibraries\Boo.Lang.Compiler.dll
+ False
+
+
+ ..\..\RequiredLibraries\Boo.Lang.dll
+ False
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {DBCF20A1-BA13-4582-BFA9-74DE4D987B73}
+ NRefactoryToBooConverter
+
+
+ {3A9AE6AA-BC07-4A2F-972C-581E3AE2F195}
+ NRefactory
+ True
+
+
+
+
\ No newline at end of file
diff --git a/src/AddIns/BackendBindings/Boo/NRefactoryToBooConverter/Test/StatementTests.cs b/src/AddIns/BackendBindings/Boo/NRefactoryToBooConverter/Test/StatementTests.cs
new file mode 100644
index 0000000000..a099ce6051
--- /dev/null
+++ b/src/AddIns/BackendBindings/Boo/NRefactoryToBooConverter/Test/StatementTests.cs
@@ -0,0 +1,223 @@
+#region license
+// Copyright (c) 2005, Daniel Grunwald (daniel@danielgrunwald.de)
+// All rights reserved.
+//
+// NRefactoryToBoo is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// NRefactoryToBoo is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with NRefactoryToBoo; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#endregion
+
+using System;
+using NUnit.Framework;
+
+namespace NRefactoryToBooConverter.Tests
+{
+ [TestFixture]
+ public class StatementTests : TestHelper
+ {
+ [Test]
+ public void IfStatement()
+ {
+ TestStatement("if (a) B();", "if a:\n\tB()");
+ }
+
+ [Test]
+ public void IfElseStatement()
+ {
+ TestStatement("if (a) B(); else C();", "if a:\n\tB()\nelse:\n\tC()");
+ }
+
+ [Test]
+ public void ForLoop()
+ {
+ TestStatement("for (int i = 0; i < 10; i++) {}", "for i in range(0, 10):\n\tpass");
+ }
+
+ [Test]
+ public void ForLoopWithoutBody()
+ {
+ TestStatement("for (int i = 0; i < 10; i++);", "for i in range(0, 10):\n\tpass");
+ }
+
+ [Test]
+ public void ForLoopWithStep()
+ {
+ TestStatement("for (int i = 0; i <= 10; i += 2);", "for i in range(0, 11, 2):\n\tpass");
+ }
+
+ [Test]
+ public void ForLoopDecrementing()
+ {
+ TestStatement("for (int i = 10; i > 0; --i);", "for i in range(10, 0, -1):\n\tpass");
+ }
+
+ [Test]
+ public void ForLoopDecrementingWithStep()
+ {
+ TestStatement("for (int i = 10; i >= 0; i -= 2);", "for i in range(10, -1, -2):\n\tpass");
+ }
+
+ [Test]
+ public void ForLoop2()
+ {
+ TestStatement("for (i = 0; i < 10; i++) {}", "i = 0\ngoto ??1\nwhile true:\n\ti += 1\n\t:??1\n\tbreak unless (i <= 9)");
+ }
+
+ [Test]
+ public void ForLoopWithStep2()
+ {
+ TestStatement("for (i = 0; i <= 10; i += 2);", "i = 0\ngoto ??1\nwhile true:\n\ti += 2\n\t:??1\n\tbreak unless (i <= 10)");
+ }
+
+ [Test]
+ public void ForLoopDecrementing2()
+ {
+ TestStatement("for (i = 10; i > 0; --i);", "i = 10\ngoto ??1\nwhile true:\n\ti += -1\n\t:??1\n\tbreak unless (i >= 1)");
+ }
+
+ [Test]
+ public void AdvancedForLoop()
+ {
+ TestStatement("for (f = Open(); (next = Peek()) != -1; Process(next));",
+ "f = Open()\ngoto ??1\nwhile true:\n\tProcess(next)\n\t:??1\n\tbreak unless ((next = Peek()) != (-1))");
+ }
+
+ [Test]
+ public void WhileLoop()
+ {
+ TestStatement("while ((next = Peek()) != -1) { Process(next); }",
+ "while ((next = Peek()) != (-1)):\n\tProcess(next)");
+ }
+
+ [Test]
+ public void DoLoop()
+ {
+ TestStatement("do { ok = Next(); } while (ok);",
+ "while true:\n\tok = Next()\n\tbreak unless ok");
+ }
+
+ [Test]
+ public void ForeachLoop()
+ {
+ TestStatement("foreach (string s in list) {}",
+ "for s as System.String in list:\n\tpass");
+ }
+
+ [Test]
+ public void Using()
+ {
+ TestStatement("using (StringReader r = file.Open()) { r.ReadLine(); }",
+ "using (r = file.Open()):\n\tr.ReadLine()");
+ }
+
+ [Test]
+ public void Return()
+ {
+ TestStatement("return val;", "return val");
+ }
+
+ [Test]
+ public void Throw()
+ {
+ TestStatement("throw cachedException;", "raise cachedException");
+ }
+
+ [Test]
+ public void TryFinally()
+ {
+ TestStatement("try { Action(); } finally { CleanUp(); }",
+ "try:\n\tAction()\nensure:\n\tCleanUp()");
+ }
+
+ [Test]
+ public void TryCatch()
+ {
+ TestStatement("try { Action(); } catch { DisplayError(); }",
+ "try:\n\tAction()\nexcept:\n\tDisplayError()");
+ }
+
+ [Test]
+ public void TryCatchWithTypes()
+ {
+ TestStatement("try { Action(); }" +
+ "catch(FirstException ex) { DisplayError(ex); }" +
+ "catch(SecondException ex) { DisplayError(ex); }",
+ "try:\n\tAction()\n" +
+ "except ex as FirstException:\n\tDisplayError(ex)\n" +
+ "except ex as SecondException:\n\tDisplayError(ex)");
+ }
+
+ [Test]
+ public void Switch()
+ {
+ TestStatement("switch (var) { case 1: A1(); break; default: A3(); break; case 2: case 3: A2(); break; }",
+ "??1 = var\n" +
+ "if (??1 == 1):\n" +
+ "\tA1()\n" +
+ "else:\n" +
+ "\tif ((??1 == 2) or (??1 == 3)):\n" +
+ "\t\tA2()\n" +
+ "\telse:\n" +
+ "\t\tA3()");
+ }
+
+ [Test]
+ public void SwitchWithEarlyBreak()
+ {
+ TestStatement("switch (var) { case 1: if (a) break; B(); break; }",
+ "??1 = var\n" +
+ "if (??1 == 1):\n" +
+ "\tif a:\n" +
+ "\t\tgoto ??1_end\n" +
+ "\tB()\n" +
+ ":??1_end");
+ }
+
+ [Test]
+ public void SwitchWithGotoCase()
+ {
+ TestStatement("switch (var) { case 1: B(); goto default; default: A(); break; }",
+ "??1 = var\n" +
+ "if (??1 == 1):\n" +
+ "\tB()\n" +
+ "\tgoto ??1_default\n" +
+ "else:\n" +
+ "\t:??1_default\n" +
+ "\tA()");
+ }
+
+ [Test]
+ public void VBArrayDecl()
+ {
+ TestStatementVB("Dim A(10) As Integer", "A as (System.Int32) = array(System.Int32, 11)");
+ }
+
+ [Test]
+ public void RedimTest()
+ {
+ TestStatementVB("Dim A As Integer()\nRedim A(5)", "A as (System.Int32)\nA = array(System.Int32, 6)");
+ }
+
+ [Test]
+ public void VBMethodCall()
+ {
+ TestStatementVB("B = A(5)", "B = A(5)");
+ }
+
+ [Test]
+ public void VBIndexerCall()
+ {
+ TestStatementVB("Dim A As Integer()\nB = A(5)", "A as (System.Int32)\nB = A[5]");
+ }
+ }
+}
diff --git a/src/AddIns/BackendBindings/Boo/NRefactoryToBooConverter/Test/TestHelper.cs b/src/AddIns/BackendBindings/Boo/NRefactoryToBooConverter/Test/TestHelper.cs
new file mode 100644
index 0000000000..27652ae255
--- /dev/null
+++ b/src/AddIns/BackendBindings/Boo/NRefactoryToBooConverter/Test/TestHelper.cs
@@ -0,0 +1,109 @@
+#region license
+// Copyright (c) 2005, Daniel Grunwald (daniel@danielgrunwald.de)
+// All rights reserved.
+//
+// NRefactoryToBoo is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// NRefactoryToBoo is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with NRefactoryToBoo; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#endregion
+
+using System;
+using System.IO;
+using Boo.Lang.Compiler;
+using Boo.Lang.Compiler.Ast;
+using NUnit.Framework;
+
+namespace NRefactoryToBooConverter.Tests
+{
+ public class TestHelper
+ {
+ protected string Convert(string program)
+ {
+ ConverterSettings settings = new ConverterSettings("prog.cs");
+ settings.SimplifyTypeNames = false;
+ Module module = Parser.ParseModule(new CompileUnit(), new StringReader(program), settings);
+ return GetStringFromModule(module, settings);
+ }
+
+ protected string ConvertVB(string program)
+ {
+ ConverterSettings settings = new ConverterSettings("prog.vb");
+ settings.SimplifyTypeNames = false;
+ Module module = Parser.ParseModule(new CompileUnit(), new StringReader(program), settings);
+ return GetStringFromModule(module, settings);
+ }
+
+ string GetStringFromModule(Module module, ConverterSettings settings)
+ {
+ if (settings.Errors.Count > 0) {
+ Assert.Fail(settings.Errors.Count.ToString() + " errors: " + settings.Errors[0]);
+ }
+ if (settings.Warnings.Count > 0) {
+ Assert.Fail(settings.Warnings.Count.ToString() + " warnings: " + settings.Warnings[0]);
+ }
+ Assert.IsNotNull(module, "Module is null");
+ string str = module.ToCodeString();
+ str = str.Trim().Replace("\r", "");
+ for (int i = 0; i < 5; i++) {
+ str = str.Replace("\n\n", "\n");
+ str = str.Replace(" ", " ");
+ }
+ return str;
+ }
+
+ protected void Test(string input, string output)
+ {
+ Assert.AreEqual(output.Replace("??", ConverterSettings.DefaultNameGenerationPrefix), Convert(input));
+ }
+
+ protected void TestVB(string input, string output)
+ {
+ Assert.AreEqual(output.Replace("??", ConverterSettings.DefaultNameGenerationPrefix), ConvertVB(input));
+ }
+
+ protected void TestInClass(string input, string output)
+ {
+ Test("public class ClassName {\n" + input + "\n}", "public class ClassName:\n\t" + output.Replace("\n", "\n\t"));
+ }
+
+ protected void TestInClassVB(string input, string output)
+ {
+ TestVB("Public Class ClassName\n" + input + "\nEnd Class\n", "public class ClassName:\n\t" + output.Replace("\n", "\n\t"));
+ }
+
+ protected void TestInClassWithIndexer(string input, string output)
+ {
+ Test("public class ClassName {\n" + input + "\n}", "[System.Reflection.DefaultMember('Indexer')]\npublic class ClassName:\n\t" + output.Replace("\n", "\n\t"));
+ }
+
+ protected void TestStatement(string input, string output)
+ {
+ TestInClass("public void Method() {\n" + input + "\n}", "public final def Method() as System.Void:\n\t" + output.Replace("\n", "\n\t"));
+ }
+
+ protected void TestStatementVB(string input, string output)
+ {
+ TestInClassVB("Public Sub Method()\n" + input + "\nEnd Sub", "public final def Method() as System.Void:\n\t" + output.Replace("\n", "\n\t"));
+ }
+
+ protected void TestExpr(string input, string output)
+ {
+ TestStatement("a = " + input + ";", "a = " + output);
+ }
+
+ protected void TestExprVB(string input, string output)
+ {
+ TestStatementVB("a = " + input, "a = " + output);
+ }
+ }
+}
diff --git a/src/AddIns/BackendBindings/Boo/StandaloneConverter/AssemblyInfo.cs b/src/AddIns/BackendBindings/Boo/StandaloneConverter/AssemblyInfo.cs
new file mode 100644
index 0000000000..c3b8af0656
--- /dev/null
+++ b/src/AddIns/BackendBindings/Boo/StandaloneConverter/AssemblyInfo.cs
@@ -0,0 +1,46 @@
+#region license
+// Copyright (c) 2005, Daniel Grunwald (daniel@danielgrunwald.de)
+// All rights reserved.
+//
+// NRefactoryToBoo is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// NRefactoryToBoo is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with NRefactoryToBoo; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#endregion
+
+using System.Reflection;
+using System.Runtime.CompilerServices;
+
+// Information about this assembly is defined by the following
+// attributes.
+//
+// change them to the information which is associated with the assembly
+// you compile.
+
+[assembly: AssemblyTitle("NRefactoryToBooConverter Executable")]
+[assembly: AssemblyDescription("Converts from C# and VB.NET source files to boo source files")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("Daniel Grunwald")]
+[assembly: AssemblyProduct("BooBinding")]
+[assembly: AssemblyCopyright("(C) 2005, Daniel Grunwald")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// The assembly version has following format :
+//
+// Major.Minor.Build.Revision
+//
+// You can specify all values by your own or you can build default build and revision
+// numbers with the '*' character (the default):
+
+[assembly: AssemblyVersion(NRefactoryToBooConverter.VersionInfo.VersionNumber)]
+
diff --git a/src/AddIns/BackendBindings/Boo/StandaloneConverter/Main.cs b/src/AddIns/BackendBindings/Boo/StandaloneConverter/Main.cs
new file mode 100644
index 0000000000..bf6b8439f4
--- /dev/null
+++ b/src/AddIns/BackendBindings/Boo/StandaloneConverter/Main.cs
@@ -0,0 +1,363 @@
+#region license
+// Copyright (c) 2005, Daniel Grunwald (daniel@danielgrunwald.de)
+// All rights reserved.
+//
+// NRefactoryToBoo is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// NRefactoryToBoo is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with NRefactoryToBoo; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Text;
+using NRefactoryToBooConverter;
+using Boo.Lang.Compiler;
+using Boo.Lang.Compiler.Ast;
+
+namespace StandaloneConverter
+{
+ class MainClass
+ {
+ ///
+ /// 0 = conversion successful
+ /// 1 = internal error
+ /// 2 = invalid command line parameters
+ /// 3 = no command line parameters
+ /// 4 = conversion error
+ ///
+ public static int Main(string[] args)
+ {
+ Console.WriteLine("Standalone C# to Boo converter");
+ Console.WriteLine("(C) Daniel Grunwald, 2005");
+ Console.WriteLine();
+ return new MainClass().Run(args);
+ }
+
+ bool overwriteFiles = false;
+
+ public int Run(string[] args)
+ {
+ try {
+ bool failed = false;
+ string outputdir = null;
+ List input = new List();
+ for (int i = 0; i < args.Length; i++) {
+ string arg = args[i];
+ switch (arg.ToLower()) {
+ case "--help":
+ case "-?":
+ case "/?":
+ ShowHelp();
+ return 0;
+ case "-o":
+ case "--output":
+ outputdir = args[++i];
+ break;
+ case "--overwrite":
+ case "--force":
+ case "-f":
+ overwriteFiles = true;
+ break;
+ case "--version":
+ Console.WriteLine("Version " + typeof(MainClass).Assembly.GetName().Version.ToString());
+ return 0;
+ case "--noprimitivenames":
+ simplifyTypeNames = false;
+ break;
+ default:
+ if (arg.StartsWith("-")) {
+ Console.WriteLine("Invalid argument: " + arg);
+ failed = true;
+ } else {
+ input.Add(arg);
+ }
+ break;
+ }
+ }
+ if (failed)
+ return 2;
+ if (input.Count == 0) {
+ Console.WriteLine("No input(s) specified.");
+ Console.WriteLine("Use the parameter '--help' to display the possible command line arguments.");
+ return 3;
+ }
+ if (Convert(input, outputdir)) {
+ Console.WriteLine();
+ Console.WriteLine("Conversion successful.");
+ return 0;
+ } else {
+ Console.WriteLine();
+ Console.WriteLine("Conversion failed.");
+ return 4;
+ }
+ } catch (Exception ex) {
+ Console.WriteLine(ex);
+ return 1;
+ }
+ }
+
+ void ShowHelp()
+ {
+ Console.Write(Path.GetFileName(typeof(MainClass).Assembly.Location));
+ Console.WriteLine(" [-o outputdirectory] [switches] input1 input2 ...");
+ Console.WriteLine();
+ Console.WriteLine("An input parameter can be either a C# or VB.NET file or a directory.");
+ Console.WriteLine("When a directory is specified, all .cs and .vb files inside that");
+ Console.WriteLine("directory are converted recursivly.");
+ Console.WriteLine();
+ Console.WriteLine(" --output (short: -o)");
+ Console.WriteLine(" Specifies the output directory to store the generated files in.");
+ Console.WriteLine(" When no output directory is specified, the generated files are stored");
+ Console.WriteLine(" in the directory of the source files.");
+ Console.WriteLine();
+ Console.WriteLine("Switches:");
+ Console.WriteLine(" --overwrite or --force (short: -f)");
+ Console.WriteLine(" Overwrite existing .boo files.");
+ Console.WriteLine(" --noPrimitiveNames");
+ Console.WriteLine(" Use the fully type names (System.Int32) instead of the short names (int).");
+ Console.WriteLine(" --help (short: -? or /?)");
+ Console.WriteLine(" Shows this help text");
+ }
+
+ bool simplifyTypeNames = true;
+
+ ConverterSettings ApplySettings(string fileName, CompilerErrorCollection errors, CompilerWarningCollection warnings)
+ {
+ ConverterSettings settings = new ConverterSettings(fileName, errors, warnings);
+ settings.SimplifyTypeNames = simplifyTypeNames;
+ return settings;
+ }
+
+ bool Convert(List inputs, string outputdir)
+ {
+ bool success = true;
+ foreach (string input in inputs) {
+ if (Directory.Exists(input)) {
+ success &= ConvertDirectory(input, GetOutputName(outputdir, input));
+ } else {
+ success &= ConvertFile(input, GetOutputName(outputdir, input));
+ }
+ }
+ return success;
+ }
+
+ string GetOutputName(string outputdir, string input)
+ {
+ return outputdir == null ? input : Path.Combine(outputdir, Path.GetFileName(input));
+ }
+
+ bool ConvertDirectory(string inputdir, string outputdir)
+ {
+ bool success = true;
+ foreach (string file in Directory.GetFiles(inputdir, "*.cs")) {
+ success &= ConvertFile(file, Path.Combine(outputdir, Path.GetFileName(file)));
+ }
+ foreach (string file in Directory.GetFiles(inputdir, "*.vb")) {
+ success &= ConvertFile(file, Path.Combine(outputdir, Path.GetFileName(file)));
+ }
+ foreach (string dir in Directory.GetDirectories(inputdir)) {
+ success &= ConvertDirectory(dir, Path.Combine(outputdir, Path.GetFileName(dir)));
+ }
+ return success;
+ }
+
+ bool ConvertFile(string input, string output)
+ {
+ try {
+ return ConvertFileInternal(input, Path.ChangeExtension(output, ".boo"));
+ } catch (Exception ex) {
+ Console.WriteLine("Error converting " + input + ":");
+ Console.WriteLine(" " + ex.Message);
+ return false;
+ }
+ }
+
+ bool ConvertFileInternal(string input, string output)
+ {
+ string directory = Path.GetDirectoryName(output);
+ if (directory.Length > 0) {
+ if (!Directory.Exists(directory)) {
+ Directory.CreateDirectory(directory);
+ }
+ }
+ bool isFailed = false;
+ if (!overwriteFiles && File.Exists(output)) {
+ FailFile(ref isFailed, input, "The output file '{0}' already exists.", output);
+ return false;
+ }
+ try {
+ CompilerErrorCollection errors = new CompilerErrorCollection();
+ CompilerWarningCollection warnings = new CompilerWarningCollection();
+ Module module;
+ IList specials;
+ CompileUnit compileUnit = new CompileUnit();
+ using (StreamReader r = OpenFile(input)) {
+ module = Parser.ParseModule(compileUnit, r, ApplySettings(input, errors, warnings), out specials);
+ }
+ foreach (CompilerError error in errors) {
+ FailFile(ref isFailed, input, error.ToString());
+ }
+ if (isFailed) {
+ return false;
+ }
+ if (warnings.Count > 0) {
+ Console.WriteLine(input + ":");
+ foreach (CompilerWarning warning in warnings) {
+ Console.WriteLine(" " + warning.ToString());
+ }
+ }
+ using (StreamWriter w = new StreamWriter(output, false, Encoding.UTF8)) {
+ BooPrinterVisitorWithComments printer = new BooPrinterVisitorWithComments(specials, w);
+ printer.OnModule(module);
+ printer.Finish();
+ }
+ } catch (Exception ex) {
+ FailFile(ref isFailed, input, ex);
+ }
+ return !isFailed;
+ }
+
+ void FailFile(ref bool isFailed, string input, Exception ex)
+ {
+ FailFile(ref isFailed, input, "Internal error:");
+ CompilerError cerr = ex as CompilerError;
+ if (cerr != null)
+ Console.WriteLine(cerr.ToString(true));
+ else
+ Console.WriteLine(ex.ToString());
+ }
+
+ void FailFile(ref bool isFailed, string input, string message, params object[] args)
+ {
+ if (!isFailed) {
+ isFailed = true;
+ Console.WriteLine(input + " failed:");
+ }
+ if (args.Length == 0) {
+ Console.WriteLine(" " + message);
+ } else {
+ Console.WriteLine(" " + message, args);
+ }
+ }
+
+ #region Open file with encoding autodetection
+ StreamReader OpenFile(string fileName)
+ {
+ FileStream fs = new FileStream(fileName, FileMode.Open, FileAccess.Read);
+ if (fs.Length > 3) {
+ // the autodetection of StreamReader is not capable of detecting the difference
+ // between ISO-8859-1 and UTF-8 without BOM.
+ int firstByte = fs.ReadByte();
+ int secondByte = fs.ReadByte();
+ switch ((firstByte << 8) | secondByte) {
+ case 0x0000: // either UTF-32 Big Endian or a binary file; use StreamReader
+ case 0xfffe: // Unicode BOM (UTF-16 LE or UTF-32 LE)
+ case 0xfeff: // UTF-16 BE BOM
+ case 0xefbb: // start of UTF-8 BOM
+ // StreamReader autodetection works
+ fs.Position = 0;
+ return new StreamReader(fs);
+ default:
+ return AutoDetect(fs, (byte)firstByte, (byte)secondByte);
+ }
+ } else {
+ return new StreamReader(fs);
+ }
+ }
+
+ StreamReader AutoDetect(FileStream fs, byte firstByte, byte secondByte)
+ {
+ int max = (int)Math.Min(fs.Length, 500000); // look at max. 500 KB
+ const int ASCII = 0;
+ const int Error = 1;
+ const int UTF8 = 2;
+ const int UTF8Sequence = 3;
+ int state = ASCII;
+ int sequenceLength = 0;
+ byte b;
+ for (int i = 0; i < max; i++) {
+ if (i == 0) {
+ b = firstByte;
+ } else if (i == 1) {
+ b = secondByte;
+ } else {
+ b = (byte)fs.ReadByte();
+ }
+ if (b < 0x80) {
+ // normal ASCII character
+ if (state == UTF8Sequence) {
+ state = Error;
+ break;
+ }
+ } else if (b < 0xc0) {
+ // 10xxxxxx : continues UTF8 byte sequence
+ if (state == UTF8Sequence) {
+ --sequenceLength;
+ if (sequenceLength < 0) {
+ state = Error;
+ break;
+ } else if (sequenceLength == 0) {
+ state = UTF8;
+ }
+ } else {
+ state = Error;
+ break;
+ }
+ } else if (b > 0xc2 && b < 0xf5) {
+ // beginning of byte sequence
+ if (state == UTF8 || state == ASCII) {
+ state = UTF8Sequence;
+ if (b < 0xe0) {
+ sequenceLength = 1; // one more byte following
+ } else if (b < 0xf0) {
+ sequenceLength = 2; // two more bytes following
+ } else {
+ sequenceLength = 3; // three more bytes following
+ }
+ } else {
+ state = Error;
+ break;
+ }
+ } else {
+ // 0xc0, 0xc1, 0xf5 to 0xff are invalid in UTF-8 (see RFC 3629)
+ state = Error;
+ break;
+ }
+ }
+ fs.Position = 0;
+ switch (state) {
+ case ASCII:
+ // when the file seems to be ASCII, we read it using the user-specified encoding
+ // so it is saved again using that encoding.
+ return new StreamReader(fs, GetDefaultEncoding());
+ case Error:
+ return new StreamReader(fs, GetDefaultEncoding());
+ default:
+ return new StreamReader(fs);
+ }
+ }
+
+ Encoding GetDefaultEncoding()
+ {
+ Encoding encoding = Encoding.Default;
+ int codepage = encoding.CodePage;
+ if (codepage == 65001 || codepage == 65000 || codepage == 1200 || codepage == 1201) {
+ return Encoding.GetEncoding("ISO-8859-1");
+ } else {
+ return encoding;
+ }
+ }
+ #endregion
+ }
+}
diff --git a/src/AddIns/BackendBindings/Boo/StandaloneConverter/StandaloneConverter.csproj b/src/AddIns/BackendBindings/Boo/StandaloneConverter/StandaloneConverter.csproj
new file mode 100644
index 0000000000..edc2d55782
--- /dev/null
+++ b/src/AddIns/BackendBindings/Boo/StandaloneConverter/StandaloneConverter.csproj
@@ -0,0 +1,51 @@
+
+
+ Exe
+ StandaloneConverter
+ StandaloneConverter
+ Debug
+ AnyCPU
+ {66338092-7611-40FC-B69C-B73A0528DA82}
+
+
+ bin\Debug\
+ False
+ DEBUG;TRACE
+ True
+ Full
+ True
+
+
+ bin\Release\
+ True
+ TRACE
+ False
+ None
+ False
+
+
+
+
+
+
+ ..\RequiredLibraries\Boo.Lang.Compiler.dll
+ False
+
+
+
+
+
+
+
+
+ {DBCF20A1-BA13-4582-BFA9-74DE4D987B73}
+ NRefactoryToBooConverter
+
+
+ {3A9AE6AA-BC07-4A2F-972C-581E3AE2F195}
+ NRefactory
+ False
+
+
+
+
\ No newline at end of file
diff --git a/src/Main/Base/Project/Src/Dom/NRefactoryResolver/NRefactoryResolver.cs b/src/Main/Base/Project/Src/Dom/NRefactoryResolver/NRefactoryResolver.cs
index 5e0940d130..a6e834cfb3 100644
--- a/src/Main/Base/Project/Src/Dom/NRefactoryResolver/NRefactoryResolver.cs
+++ b/src/Main/Base/Project/Src/Dom/NRefactoryResolver/NRefactoryResolver.cs
@@ -549,7 +549,7 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver
if (languageProperties.ImportModules) {
ArrayList list = new ArrayList();
- AddImportedNamespaceContents(list);
+ AddImportedNamespaceContents(list, cu, callingClass);
foreach (object o in list) {
IClass c = o as IClass;
if (c != null && IsSameName(identifier, c.Name)) {
@@ -721,7 +721,7 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver
if (languageProperties.ImportModules) {
ArrayList list = new ArrayList();
- AddImportedNamespaceContents(list);
+ AddImportedNamespaceContents(list, cu, callingClass);
foreach (object o in list) {
IMethod m = o as IMethod;
if (m != null && IsSameName(m.Name, memberName)) {
@@ -807,7 +807,7 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver
IParameter SearchMethodParameter(string parameter)
{
- IMethod method = callingMember as IMethod;
+ IMethodOrProperty method = callingMember as IMethodOrProperty;
if (method == null) {
return null;
}
@@ -904,10 +904,29 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver
}
}
- IMethod method = callingMember as IMethod;
- if (method != null) {
- foreach (IParameter p in method.Parameters) {
- result.Add(new DefaultField.ParameterField(p.ReturnType, p.Name, method.Region, callingClass));
+ AddContentsFromCalling(result, callingClass, callingMember);
+
+ foreach (KeyValuePair> pair in lookupTableVisitor.Variables) {
+ if (pair.Value != null && pair.Value.Count > 0) {
+ foreach (LocalLookupVariable v in pair.Value) {
+ if (IsInside(new Point(caretColumn, caretLine), v.StartPos, v.EndPos)) {
+ // convert to a field for display
+ result.Add(CreateLocalVariableField(v, pair.Key));
+ break;
+ }
+ }
+ }
+ }
+ AddImportedNamespaceContents(result, cu, callingClass);
+ return result;
+ }
+
+ public static void AddContentsFromCalling(ArrayList result, IClass callingClass, IMember callingMember)
+ {
+ IMethodOrProperty methodOrProperty = callingMember as IMethodOrProperty;
+ if (methodOrProperty != null) {
+ foreach (IParameter p in methodOrProperty.Parameters) {
+ result.Add(new DefaultField.ParameterField(p.ReturnType, p.Name, methodOrProperty.Region, callingClass));
}
}
@@ -927,43 +946,33 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver
result.Add(m);
}
}
- if (callingClass.DeclaringType != null) {
- result.Add(callingClass.DeclaringType);
- members.Clear();
- t = callingClass.DeclaringType.DefaultReturnType;
+ members.Clear();
+ IClass c = callingClass.DeclaringType;
+ while (c != null) {
+ result.Add(c);
+ t = c.DefaultReturnType;
members.AddRange(t.GetMethods());
members.AddRange(t.GetFields());
members.AddRange(t.GetEvents());
members.AddRange(t.GetProperties());
- foreach (IMember m in members) {
- if (m.IsStatic) {
- result.Add(m);
- }
- }
+ c = c.DeclaringType;
}
- }
- foreach (KeyValuePair> pair in lookupTableVisitor.Variables) {
- if (pair.Value != null && pair.Value.Count > 0) {
- foreach (LocalLookupVariable v in pair.Value) {
- if (IsInside(new Point(caretColumn, caretLine), v.StartPos, v.EndPos)) {
- // convert to a field for display
- result.Add(CreateLocalVariableField(v, pair.Key));
- break;
- }
+ foreach (IMember m in members) {
+ if (m.IsStatic) {
+ result.Add(m);
}
}
}
- AddImportedNamespaceContents(result);
- return result;
}
- void AddImportedNamespaceContents(ArrayList result)
+ public static void AddImportedNamespaceContents(ArrayList result, ICompilationUnit cu, IClass callingClass)
{
- projectContent.AddNamespaceContents(result, "", languageProperties, true);
+ IProjectContent projectContent = cu.ProjectContent;
+ projectContent.AddNamespaceContents(result, "", projectContent.Language, true);
foreach (IUsing u in cu.Usings) {
- AddUsing(result, u);
+ AddUsing(result, u, projectContent);
}
- AddUsing(result, projectContent.DefaultImports);
+ AddUsing(result, projectContent.DefaultImports, projectContent);
if (callingClass != null) {
foreach (object member in projectContent.GetNamespaceContents(callingClass.Namespace)) {
@@ -981,15 +990,15 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver
}
}
- void AddUsing(ArrayList result, IUsing u)
+ static void AddUsing(ArrayList result, IUsing u, IProjectContent projectContent)
{
if (u == null) {
return;
}
- bool importNamespaces = languageProperties.ImportNamespaces;
+ bool importNamespaces = projectContent.Language.ImportNamespaces;
foreach (string name in u.Usings) {
if (importNamespaces) {
- projectContent.AddNamespaceContents(result, name, languageProperties, true);
+ projectContent.AddNamespaceContents(result, name, projectContent.Language, true);
} else {
foreach (object o in projectContent.GetNamespaceContents(name)) {
if (!(o is string))
diff --git a/src/Main/Base/Project/Src/Dom/ResolveResult.cs b/src/Main/Base/Project/Src/Dom/ResolveResult.cs
index 688a624766..d0b9adcd3c 100644
--- a/src/Main/Base/Project/Src/Dom/ResolveResult.cs
+++ b/src/Main/Base/Project/Src/Dom/ResolveResult.cs
@@ -128,6 +128,16 @@ namespace ICSharpCode.SharpDevelop.Dom
}
}
+ public TypeResolveResult TypeResult {
+ get {
+ if (primaryResult is TypeResolveResult)
+ return (TypeResolveResult)primaryResult;
+ if (secondaryResult is TypeResolveResult)
+ return (TypeResolveResult)secondaryResult;
+ return null;
+ }
+ }
+
public MixedResolveResult(ResolveResult primaryResult, ResolveResult secondaryResult)
: base(primaryResult.CallingClass, primaryResult.CallingMember, primaryResult.ResolvedType)
{
diff --git a/src/Main/Base/Project/Src/TextEditor/Gui/Editor/SharpDevelopTextAreaControl.cs b/src/Main/Base/Project/Src/TextEditor/Gui/Editor/SharpDevelopTextAreaControl.cs
index 0a32aca853..dd1b308ff0 100644
--- a/src/Main/Base/Project/Src/TextEditor/Gui/Editor/SharpDevelopTextAreaControl.cs
+++ b/src/Main/Base/Project/Src/TextEditor/Gui/Editor/SharpDevelopTextAreaControl.cs
@@ -247,20 +247,22 @@ namespace ICSharpCode.SharpDevelop.DefaultEditor.Gui.Editor
return false;
}
}
- string word = GetWordBeforeCaret();
- if (word != null) {
- CodeTemplateGroup templateGroup = CodeTemplateLoader.GetTemplateGroupPerFilename(FileName);
- if (templateGroup != null) {
- foreach (CodeTemplate template in templateGroup.Templates) {
- if (template.Shortcut == word) {
- if (word.Length > 0) {
- int newCaretOffset = DeleteWordBeforeCaret();
- //// set new position in text area
- ActiveTextAreaControl.TextArea.Caret.Position = Document.OffsetToPosition(newCaretOffset);
+ if (ch == ' ') {
+ string word = GetWordBeforeCaret();
+ if (word != null) {
+ CodeTemplateGroup templateGroup = CodeTemplateLoader.GetTemplateGroupPerFilename(FileName);
+ if (templateGroup != null) {
+ foreach (CodeTemplate template in templateGroup.Templates) {
+ if (template.Shortcut == word) {
+ if (word.Length > 0) {
+ int newCaretOffset = DeleteWordBeforeCaret();
+ //// set new position in text area
+ ActiveTextAreaControl.TextArea.Caret.Position = Document.OffsetToPosition(newCaretOffset);
+ }
+
+ InsertTemplate(template);
+ return true;
}
-
- InsertTemplate(template);
- return true;
}
}
}
diff --git a/src/SharpDevelop.WithTests.sln b/src/SharpDevelop.WithTests.sln
index 3ee3ede2e3..b70a26e7ba 100644
--- a/src/SharpDevelop.WithTests.sln
+++ b/src/SharpDevelop.WithTests.sln
@@ -1,5 +1,5 @@
-Microsoft Visual Studio Solution File, Format Version 9.00
-# SharpDevelop 2.0.0.413
+Microsoft Visual Studio Solution File, Format Version 9.00
+# SharpDevelop 2.0.0.539
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "AddIns", "AddIns", "{14A277EE-7DF1-4529-B639-7D1EF334C1C5}"
ProjectSection(SolutionItems) = postProject
EndProjectSection
@@ -20,6 +20,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Backends", "Backends", "{FE
ProjectSection(SolutionItems) = postProject
EndProjectSection
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BooBinding", "AddIns\BackendBindings\Boo\BooBinding\Project\BooBinding.csproj", "{4AC2D5F1-F671-480C-A075-6BF62B3721B2}"
+EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CSharpBinding.Tests", "AddIns\BackendBindings\CSharpBinding\Test\CSharpBinding.Tests.csproj", "{4D0DFCB0-F6FB-469D-AA6F-C7F1D5FD5DE7}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ILAsmBinding", "AddIns\BackendBindings\ILAsmBinding\Project\ILAsmBinding.csproj", "{6e59af58-f635-459a-9a35-c9ac41c00339}"
@@ -182,6 +184,7 @@ Global
{BF38FB72-B380-4196-AF8C-95749D726C61} = {FEB825FA-4AD8-425D-8E4A-B5A18EE1B81C}
{6e59af58-f635-459a-9a35-c9ac41c00339} = {FEB825FA-4AD8-425D-8E4A-B5A18EE1B81C}
{4D0DFCB0-F6FB-469D-AA6F-C7F1D5FD5DE7} = {FEB825FA-4AD8-425D-8E4A-B5A18EE1B81C}
+ {4AC2D5F1-F671-480C-A075-6BF62B3721B2} = {FEB825FA-4AD8-425D-8E4A-B5A18EE1B81C}
{4B8F0F98-8BE1-402B-AA8B-C8D548577B38} = {CE5B42B7-6E8C-4385-9E97-F4023FC16BF2}
{7D5C266F-D6FF-4D14-B315-0C0FC6C4EF51} = {CE5B42B7-6E8C-4385-9E97-F4023FC16BF2}
{64A3E5E6-90BF-47F6-94DF-68C94B62C817} = {CE5B42B7-6E8C-4385-9E97-F4023FC16BF2}
diff --git a/src/SharpDevelop.sln b/src/SharpDevelop.sln
index cf62c55a51..e2bd514574 100644
--- a/src/SharpDevelop.sln
+++ b/src/SharpDevelop.sln
@@ -1,5 +1,5 @@
-Microsoft Visual Studio Solution File, Format Version 9.00
-# SharpDevelop 2.0.0.377
+Microsoft Visual Studio Solution File, Format Version 9.00
+# SharpDevelop 2.0.0.539
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "AddIns", "AddIns", "{14A277EE-7DF1-4529-B639-7D1EF334C1C5}"
ProjectSection(SolutionItems) = postProject
EndProjectSection
@@ -18,6 +18,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Backends", "Backends", "{FE
ProjectSection(SolutionItems) = postProject
EndProjectSection
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BooBinding", "AddIns\BackendBindings\Boo\BooBinding\Project\BooBinding.csproj", "{4AC2D5F1-F671-480C-A075-6BF62B3721B2}"
+EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ILAsmBinding", "AddIns\BackendBindings\ILAsmBinding\Project\ILAsmBinding.csproj", "{6e59af58-f635-459a-9a35-c9ac41c00339}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "VBNetBinding", "AddIns\BackendBindings\VBNetBinding\Project\VBNetBinding.csproj", "{BF38FB72-B380-4196-AF8C-95749D726C61}"
@@ -168,6 +170,7 @@ Global
{1F1AC7CD-D154-45BB-8EAF-804CA8055F5A} = {FEB825FA-4AD8-425D-8E4A-B5A18EE1B81C}
{BF38FB72-B380-4196-AF8C-95749D726C61} = {FEB825FA-4AD8-425D-8E4A-B5A18EE1B81C}
{6e59af58-f635-459a-9a35-c9ac41c00339} = {FEB825FA-4AD8-425D-8E4A-B5A18EE1B81C}
+ {4AC2D5F1-F671-480C-A075-6BF62B3721B2} = {FEB825FA-4AD8-425D-8E4A-B5A18EE1B81C}
{4B8F0F98-8BE1-402B-AA8B-C8D548577B38} = {CE5B42B7-6E8C-4385-9E97-F4023FC16BF2}
{7D5C266F-D6FF-4D14-B315-0C0FC6C4EF51} = {CE5B42B7-6E8C-4385-9E97-F4023FC16BF2}
{64A3E5E6-90BF-47F6-94DF-68C94B62C817} = {CE5B42B7-6E8C-4385-9E97-F4023FC16BF2}