Browse Source
git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/trunk@541 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61shortcuts
49 changed files with 7638 additions and 51 deletions
@ -0,0 +1,14 @@
@@ -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 |
||||
@ -0,0 +1,78 @@
@@ -0,0 +1,78 @@
|
||||
<AddIn name = "BooBinding" |
||||
author = "Daniel Grunwald" |
||||
copyright = "GPL" |
||||
url = "http://www.icsharpcode.net" |
||||
description = "Binding for the Boo language" |
||||
version = "1.0.0"> |
||||
|
||||
<Runtime> |
||||
<Import assembly = "BooBinding.dll"/> |
||||
<Import assembly = ":ICSharpCode.SharpDevelop"/> |
||||
</Runtime> |
||||
|
||||
<Path name = "/SharpDevelop/Workbench/FileFilter"> |
||||
<FileFilter id = "Boo" |
||||
insertbefore="AllFiles" |
||||
name = "Boo Files (*.boo)" |
||||
extensions = "*.boo"/> |
||||
</Path> |
||||
|
||||
<Path name = "/SharpDevelop/BackendBindings/Templates"> |
||||
<Directory id = "Boo" path = "./Templates" /> |
||||
</Path> |
||||
|
||||
<Path name = "/SharpDevelop/Workbench/Ambiences"> |
||||
<Class id = "Boo" |
||||
class = "Grunwald.BooBinding.BooAmbience"/> |
||||
</Path> |
||||
|
||||
<Path name = "/Workspace/Parser"> |
||||
<Parser id = "Boo" |
||||
supportedextensions = ".boo" |
||||
projectfileextension = ".booproj" |
||||
class = "Grunwald.BooBinding.CodeCompletion.BooParser"/> |
||||
</Path> |
||||
|
||||
<Path name = "/AddIns/DefaultTextEditor/CodeCompletion"> |
||||
<CodeCompletionBinding id = "Boo" extensions = ".boo" class = "Grunwald.BooBinding.CodeCompletion.CompletionBinding"/> |
||||
</Path> |
||||
|
||||
<Path name = "/SharpDevelop/ViewContent/DefaultTextEditor/SyntaxModes"> |
||||
<SyntaxMode id = "Boo Syntax Mode" |
||||
name = "Boo" |
||||
extensions = ".boo" |
||||
resource = "Grunwald.BooBinding.Resources.Boo.xshd" /> |
||||
</Path> |
||||
|
||||
<Path path = "/SharpDevelop/BackendBindings/ProjectOptions/Boo"> |
||||
<DialogPanel id = "Application" |
||||
label = "Application" |
||||
class = "ICSharpCode.SharpDevelop.Gui.OptionPanels.ApplicationSettings"/> |
||||
<!--<DialogPanel id = "ReferencePaths" |
||||
label = "Reference Paths" |
||||
class = "ICSharpCode.SharpDevelop.Gui.OptionPanels.ReferencePaths"/>--> |
||||
<!--<DialogPanel id = "Signing" |
||||
label = "Signing" |
||||
class = "ICSharpCode.SharpDevelop.Gui.OptionPanels.Signing"/>--> |
||||
<DialogPanel id = "BuildEvents" |
||||
label = "Build Events" |
||||
class = "ICSharpCode.SharpDevelop.Gui.OptionPanels.BuildEvents"/> |
||||
<!--<DialogPanel id = "BuildOptions" |
||||
label = "Build" |
||||
class = "ICSharpCode.ILAsmBinding.BuildOptions"/>--> |
||||
<DialogPanel id = "DebugOptions" |
||||
label = "Debug" |
||||
class = "ICSharpCode.SharpDevelop.Gui.OptionPanels.DebugOptions"/> |
||||
<!--<DialogPanel id = "Publish" |
||||
label = "Publish" |
||||
class = "ICSharpCode.SharpDevelop.Gui.OptionPanels.Publish"/>--> |
||||
</Path> |
||||
|
||||
<Path name = "/SharpDevelop/Workbench/LanguageBindings"> |
||||
<LanguageBinding id = "Boo" |
||||
guid = "{A33008B1-5DAC-44D5-9060-242E3B6E38F2}" |
||||
supportedextensions = ".boo" |
||||
projectfileextension = ".booproj" |
||||
class = "Grunwald.BooBinding.BooLanguageBinding" /> |
||||
</Path> |
||||
</AddIn> |
||||
@ -0,0 +1,94 @@
@@ -0,0 +1,94 @@
|
||||
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> |
||||
<PropertyGroup> |
||||
<OutputType>Library</OutputType> |
||||
<RootNamespace>Grunwald.BooBinding</RootNamespace> |
||||
<AssemblyName>BooBinding</AssemblyName> |
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> |
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> |
||||
<ProjectGuid>{4AC2D5F1-F671-480C-A075-6BF62B3721B2}</ProjectGuid> |
||||
<AllowUnsafeBlocks>False</AllowUnsafeBlocks> |
||||
<NoStdLib>False</NoStdLib> |
||||
<RegisterForComInterop>False</RegisterForComInterop> |
||||
<GenerateSerializationAssemblies>Auto</GenerateSerializationAssemblies> |
||||
<BaseAddress>4194304</BaseAddress> |
||||
<PlatformTarget>AnyCPU</PlatformTarget> |
||||
<FileAlignment>4096</FileAlignment> |
||||
<WarningLevel>4</WarningLevel> |
||||
<TreatWarningsAsErrors>false</TreatWarningsAsErrors> |
||||
<OutputPath>..\..\..\..\..\..\AddIns\AddIns\BackendBindings\BooBinding\</OutputPath> |
||||
</PropertyGroup> |
||||
<PropertyGroup Condition=" '$(Configuration)' == 'Debug' "> |
||||
<Optimize>False</Optimize> |
||||
<DefineConstants>DEBUG;TRACE</DefineConstants> |
||||
<DebugSymbols>true</DebugSymbols> |
||||
<DebugType>Full</DebugType> |
||||
<CheckForOverflowUnderflow>True</CheckForOverflowUnderflow> |
||||
</PropertyGroup> |
||||
<PropertyGroup Condition=" '$(Configuration)' == 'Release' "> |
||||
<Optimize>True</Optimize> |
||||
<DefineConstants>TRACE</DefineConstants> |
||||
<DebugSymbols>False</DebugSymbols> |
||||
<DebugType>None</DebugType> |
||||
<CheckForOverflowUnderflow>False</CheckForOverflowUnderflow> |
||||
</PropertyGroup> |
||||
<ItemGroup> |
||||
<Reference Include="System" /> |
||||
<Reference Include="System.Xml" /> |
||||
<Reference Include="Boo.Lang.Compiler"> |
||||
<HintPath>..\..\RequiredLibraries\Boo.Lang.Compiler.dll</HintPath> |
||||
<SpecificVersion>False</SpecificVersion> |
||||
</Reference> |
||||
<Reference Include="Boo.Lang"> |
||||
<HintPath>..\..\RequiredLibraries\Boo.Lang.dll</HintPath> |
||||
<SpecificVersion>False</SpecificVersion> |
||||
</Reference> |
||||
<Reference Include="Boo.Lang.Parser"> |
||||
<HintPath>..\..\RequiredLibraries\Boo.Lang.Parser.dll</HintPath> |
||||
<SpecificVersion>False</SpecificVersion> |
||||
</Reference> |
||||
<Reference Include="System.Windows.Forms" /> |
||||
</ItemGroup> |
||||
<ItemGroup> |
||||
<EmbeddedResource Include="Resources\Boo.xshd"> |
||||
<CopyToOutputDirectory>Never</CopyToOutputDirectory> |
||||
</EmbeddedResource> |
||||
<Compile Include="Src\AssemblyInfo.cs" /> |
||||
<Compile Include="Src\BooProject.cs" /> |
||||
<Compile Include="Src\BooLanguageBinding.cs" /> |
||||
<Compile Include="Src\BooAmbience.cs" /> |
||||
<Compile Include="Src\CodeCompletion\BooParser.cs" /> |
||||
<Compile Include="Src\CodeCompletion\ExpressionFinder.cs" /> |
||||
<Compile Include="Src\CodeCompletion\ConvertVisitor.cs" /> |
||||
<Compile Include="Src\CodeCompletion\BooResolver.cs" /> |
||||
<Compile Include="Src\CodeCompletion\ResolveVisitor.cs" /> |
||||
<Compile Include="Src\CodeCompletion\CompletionBinding.cs" /> |
||||
</ItemGroup> |
||||
<ItemGroup> |
||||
<Content Include="BooBinding.addin"> |
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory> |
||||
</Content> |
||||
<Content Include="Templates\ConsoleProject.xpt"> |
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory> |
||||
</Content> |
||||
<Content Include="Templates\FormsProject.xpt"> |
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory> |
||||
</Content> |
||||
<Content Include="Templates\Library.xpt"> |
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory> |
||||
</Content> |
||||
<Folder Include="Src\CodeCompletion" /> |
||||
<ProjectReference Include="..\..\..\..\..\Main\Base\Project\ICSharpCode.SharpDevelop.csproj"> |
||||
<Project>{2748AD25-9C63-4E12-877B-4DCE96FBED54}</Project> |
||||
<Name>ICSharpCode.SharpDevelop</Name> |
||||
</ProjectReference> |
||||
<ProjectReference Include="..\..\..\..\..\Main\Core\Project\ICSharpCode.Core.csproj"> |
||||
<Project>{35CEF10F-2D4C-45F2-9DD1-161E0FEC583C}</Project> |
||||
<Name>ICSharpCode.Core</Name> |
||||
</ProjectReference> |
||||
<ProjectReference Include="..\..\..\..\..\Libraries\ICSharpCode.TextEditor\Project\ICSharpCode.TextEditor.csproj"> |
||||
<Project>{2D18BE89-D210-49EB-A9DD-2246FBB3DF6D}</Project> |
||||
<Name>ICSharpCode.TextEditor</Name> |
||||
</ProjectReference> |
||||
</ItemGroup> |
||||
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.Targets" /> |
||||
</Project> |
||||
@ -0,0 +1,304 @@
@@ -0,0 +1,304 @@
|
||||
<?xml version="1.0"?> |
||||
|
||||
<SyntaxDefinition name="Boo" extensions=".boo"> |
||||
|
||||
<Environment> |
||||
<Default bold="false" italic="false" color="SystemColors.WindowText" bgcolor="SystemColors.Window" /> |
||||
<Selection bold="false" italic="false" color="SystemColors.HighlightText" bgcolor="SystemColors.Highlight" /> |
||||
<VRuler bold="false" italic="false" color="SystemColors.ControlLight" /> |
||||
<InvalidLines bold="false" italic="false" color="Red" /> |
||||
<CaretMarker bold="false" italic="false" color="Yellow" /> |
||||
<LineNumbers bold="false" italic="false" color="SystemColors.ControlDark" bgcolor="SystemColors.Window" /> |
||||
<FoldLine bold="false" italic="false" color="Gray" bgcolor="Black" /> |
||||
<FoldMarker bold="false" italic="false" color="Gray" bgcolor="White" /> |
||||
<EOLMarkers bold="false" italic="false" color="#E0E0E5" /> |
||||
<SpaceMarkers bold="false" italic="false" color="#E0E0E5" /> |
||||
<TabMarkers bold="false" italic="false" color="#E0E0E5" /> |
||||
</Environment> |
||||
|
||||
<Properties> |
||||
<Property name="LineComment" value="#"/> |
||||
</Properties> |
||||
|
||||
<Digits name="Digits" bold="false" italic="false" color="DarkBlue" /> |
||||
|
||||
<RuleSets> |
||||
<RuleSet ignorecase="false" > |
||||
<Delimiters>&<>~!@%^*()-+=|\#/{}[]:;"' , .?</Delimiters> |
||||
|
||||
<Span name="DocLineComment" stopateol="false" bold="false" italic="false" color="Green" > |
||||
<Begin >"""</Begin> |
||||
<End >"""</End> |
||||
</Span> |
||||
|
||||
<Span name="LineComment" stopateol="true" bold="false" italic="false" color="Gray" > |
||||
<Begin >#</Begin> |
||||
</Span> |
||||
|
||||
<Span name="LineComment2" stopateol="true" bold="false" italic="false" color="#999999" > |
||||
<Begin >//</Begin> |
||||
</Span> |
||||
|
||||
<Span name="BlockComment" rule="comments set" stopateol="false" bold="false" italic="false" color="Green" > |
||||
<Begin >/*</Begin> |
||||
<End >*/</End> |
||||
</Span> |
||||
|
||||
<Span name="String" rule="str formatting" stopateol="true" bold="false" italic="false" color="Fuchsia" > |
||||
<Begin >"</Begin> |
||||
<End >"</End> |
||||
</Span> |
||||
|
||||
<Span name="MultiLineString" noescapesequences="true" rule="str formatting" stopateol="false" bold="false" italic="false" color="Fuchsia" > |
||||
<Begin >"""</Begin> |
||||
<End >"""</End> |
||||
</Span> |
||||
|
||||
<Span name="Char" stopateol="true" bold="false" italic="false" color="Fuchsia" > |
||||
<Begin >'</Begin> |
||||
<End >'</End> |
||||
</Span> |
||||
|
||||
<Span name="RegEx" stopateol="true" bold="false" italic="false" color="#FF6600" > |
||||
<Begin >/@!/@</Begin> |
||||
<End >/</End> |
||||
</Span> |
||||
|
||||
<MarkPrevious bold="false" italic="false" color="MidnightBlue" >(</MarkPrevious> |
||||
|
||||
<KeyWords name="Punctuation" bold="false" italic="false" color="DarkGreen" > |
||||
<Key word="?"/> |
||||
<Key word=","/> |
||||
<Key word="."/> |
||||
<Key word=";"/> |
||||
<Key word="("/> |
||||
<Key word=")"/> |
||||
<Key word="["/> |
||||
<Key word="]"/> |
||||
<Key word="{"/> |
||||
<Key word="}"/> |
||||
<Key word="+"/> |
||||
<Key word="-"/> |
||||
<Key word="/"/> |
||||
<Key word="%"/> |
||||
<Key word="*"/> |
||||
<Key word="<"/> |
||||
<Key word=">"/> |
||||
<Key word="^"/> |
||||
<Key word="="/> |
||||
<Key word="~"/> |
||||
<Key word="!"/> |
||||
<Key word="|"/> |
||||
<Key word="&"/> |
||||
</KeyWords> |
||||
|
||||
<KeyWords name="AccessKeywords" bold="true" italic="false" color="Black" > |
||||
<Key word="self"/> |
||||
<Key word="super"/> |
||||
</KeyWords> |
||||
|
||||
<KeyWords name="OperatorKeywords" bold="true" italic="false" color="DarkCyan" > |
||||
<Key word="is"/> |
||||
<Key word="isa"/> |
||||
<Key word="and"/> |
||||
<Key word="or"/> |
||||
<Key word="not"/> |
||||
</KeyWords> |
||||
|
||||
<KeyWords name="SelectionStatements" bold="true" italic="false" color="Blue" > |
||||
<Key word="else"/> |
||||
<Key word="elif"/> |
||||
<Key word="if"/> |
||||
<Key word="given"/> |
||||
<Key word="when"/> |
||||
<Key word="unless"/> |
||||
<Key word="otherwise"/> |
||||
</KeyWords> |
||||
|
||||
<KeyWords name="IterationStatements" bold="true" italic="false" color="Blue" > |
||||
<Key word="for"/> |
||||
<Key word="in"/> |
||||
<Key word="while"/> |
||||
</KeyWords> |
||||
|
||||
<KeyWords name="JumpStatements" bold="false" italic="false" color="Navy" > |
||||
<Key word="break"/> |
||||
<Key word="continue"/> |
||||
<Key word="return"/> |
||||
<Key word="yield"/> |
||||
<Key word="goto" /> |
||||
</KeyWords> |
||||
|
||||
<KeyWords name="ExceptionHandlingStatements" bold="true" italic="false" color="Teal" > |
||||
<Key word="try"/> |
||||
<Key word="raise"/> |
||||
<Key word="ensure"/> |
||||
<Key word="except"/> |
||||
<Key word="retry"/> |
||||
<Key word="success"/> |
||||
</KeyWords> |
||||
|
||||
<KeyWords name="CheckedUncheckedStatements" bold="true" italic="false" color="DarkGray" > |
||||
<Key word="checked"/> |
||||
<Key word="unchecked"/> |
||||
</KeyWords> |
||||
|
||||
<KeyWords name="UnsafeFixedStatements" bold="false" italic="false" color="Olive" > |
||||
<Key word="fixed"/> |
||||
<Key word="unsafe"/> |
||||
</KeyWords> |
||||
|
||||
<KeyWords name="ValueTypes" bold="true" italic="false" color="Purple" > |
||||
<Key word="bool"/> |
||||
<Key word="double"/> |
||||
<Key word="single"/> |
||||
<Key word="byte"/> |
||||
<Key word="sbyte"/> |
||||
<Key word="short"/> |
||||
<Key word="ushort"/> |
||||
<Key word="int"/> |
||||
<Key word="uint"/> |
||||
<Key word="long"/> |
||||
<Key word="ulong"/> |
||||
<Key word="date"/> |
||||
<Key word="timespan" /> |
||||
<Key word="decimal" /> |
||||
<Key word="char" /> |
||||
</KeyWords> |
||||
|
||||
<KeyWords name="ReferenceTypes" bold="true" italic="false" color="Purple" > |
||||
<Key word="object"/> |
||||
<Key word="string"/> |
||||
<Key word="regex"/> |
||||
</KeyWords> |
||||
|
||||
<KeyWords name="Void" bold="false" italic="false" color="Red" > |
||||
<Key word="void"/> |
||||
</KeyWords> |
||||
|
||||
<KeyWords name="ConversionKeyWords" bold="true" italic="false" color="Blue" > |
||||
<Key word="cast"/> |
||||
<Key word="as"/> |
||||
</KeyWords> |
||||
|
||||
<KeyWords name="Modifiers" bold="false" italic="false" color="Brown" > |
||||
<Key word="override"/> |
||||
<Key word="static"/> |
||||
<Key word="virtual"/> |
||||
<Key word="abstract"/> |
||||
<Key word="final"/> |
||||
<Key word="transient"/> |
||||
</KeyWords> |
||||
|
||||
<KeyWords name="AccessModifiers" bold="true" italic="false" color="Blue" > |
||||
<Key word="public"/> |
||||
<Key word="protected"/> |
||||
<Key word="private"/> |
||||
<Key word="internal"/> |
||||
</KeyWords> |
||||
|
||||
<KeyWords name="NameSpaces" bold="true" italic="false" color="Green" > |
||||
<Key word="namespace"/> |
||||
<Key word="import"/> |
||||
<Key word="from"/> |
||||
</KeyWords> |
||||
|
||||
<KeyWords name="GetSet" bold="false" italic="false" color="SaddleBrown" > |
||||
<Key word="get"/> |
||||
<Key word="set"/> |
||||
</KeyWords> |
||||
|
||||
<KeyWords name="Literals" bold="true" italic="false" color="Black" > |
||||
<Key word="null"/> |
||||
<Key word="value"/> |
||||
<Key word="true"/> |
||||
<Key word="false"/> |
||||
<Key word="ast" /> |
||||
</KeyWords> |
||||
|
||||
<KeyWords name="DefaultMacros" bold="false" italic="false" color="Maroon" > |
||||
<Key word="using"/> |
||||
<Key word="unchecked"/> |
||||
<Key word="checked"/> |
||||
<Key word="lock"/> |
||||
<Key word="getter"/> |
||||
<Key word="required"/> |
||||
<Key word="rawArrayIndexing"/> |
||||
<Key word="normalArrayIndexing"/> |
||||
</KeyWords> |
||||
|
||||
<KeyWords name="Builtins" bold="false" italic="false" color="Purple" > |
||||
<Key word="assert"/> |
||||
<Key word="array"/> |
||||
<Key word="matrix" /> |
||||
<Key word="print"/> |
||||
<Key word="gets"/> |
||||
<Key word="prompt"/> |
||||
<Key word="enumerate"/> |
||||
<Key word="zip"/> |
||||
<Key word="filter"/> |
||||
<Key word="map"/> |
||||
<Key word="cat"/> |
||||
<Key word="__eval__" /> |
||||
<Key word="__switch__" /> |
||||
</KeyWords> |
||||
|
||||
<KeyWords name="Methods" bold="true" italic="false" color="Blue" > |
||||
<Key word="constructor"/> |
||||
<Key word="destructor"/> |
||||
<Key word="def"/> |
||||
<Key word="include"/> |
||||
<Key word="event" /> |
||||
<Key word="ref"/> |
||||
</KeyWords> |
||||
|
||||
<KeyWords name="Pass" bold="false" italic="false" color="Gray" > |
||||
<Key word="pass"/> |
||||
</KeyWords> |
||||
|
||||
<KeyWords name="TypesDef" bold="true" italic="false" color="Blue" > |
||||
<Key word="enum"/> |
||||
<Key word="class"/> |
||||
<Key word="struct" /> |
||||
<Key word="interface"/> |
||||
<Key word="mixin"/> |
||||
<Key word="callable"/> |
||||
<Key word="do" /> |
||||
</KeyWords> |
||||
|
||||
</RuleSet> |
||||
|
||||
<RuleSet ignorecase="false" name="comments set" > |
||||
<Delimiters>&<>~!@%^*()-+=|\#/{}[]:;"' , .?</Delimiters> |
||||
|
||||
<Span name="BlockComment" rule="comment set 2" stopateol="false" bold="false" italic="false" color="#339966" > |
||||
<Begin >/*</Begin> |
||||
<End >*/</End> |
||||
</Span> |
||||
|
||||
</RuleSet> |
||||
|
||||
<RuleSet ignorecase="false" name="comment set 2" > |
||||
<Delimiters>&<>~!@%^*()-+=|\#/{}[]:;"' , .?</Delimiters> |
||||
|
||||
<Span name="BlockComment" rule="comments set" stopateol="false" bold="false" italic="false" color="Teal" > |
||||
<Begin >/*</Begin> |
||||
<End >*/</End> |
||||
</Span> |
||||
|
||||
</RuleSet> |
||||
|
||||
<RuleSet ignorecase="false" name="str formatting" > |
||||
<Delimiters>&<>~!@%^*()-+=|\#/{}[]:;"' , .?</Delimiters> |
||||
|
||||
<Span name="Formatting" stopateol="false" bold="false" italic="false" color="#993366" > |
||||
<Begin >${</Begin> |
||||
<End >}</End> |
||||
</Span> |
||||
|
||||
</RuleSet> |
||||
|
||||
</RuleSets> |
||||
|
||||
</SyntaxDefinition> |
||||
|
||||
@ -0,0 +1,32 @@
@@ -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("")] |
||||
@ -0,0 +1,560 @@
@@ -0,0 +1,560 @@
|
||||
// <file>
|
||||
// <copyright see="prj:///doc/copyright.txt">2002-2005 AlphaSierraPapa</copyright>
|
||||
// <license see="prj:///doc/license.txt">GNU General Public License</license>
|
||||
// <owner name="Daniel Grunwald" email="daniel@danielgrunwald.de"/>
|
||||
// <version>$Revision$</version>
|
||||
// </file>
|
||||
|
||||
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<string, string> reverseTypeConversionTable = new Dictionary<string, string>(); |
||||
static Dictionary<string, string> typeConversionTable = new Dictionary<string, string>(); |
||||
|
||||
public readonly static BooAmbience Instance = new BooAmbience(); |
||||
|
||||
/// <summary>
|
||||
/// Gets a dictionary with boo's short names as keys and
|
||||
/// the fully qualified type names as values.
|
||||
/// </summary>
|
||||
public static Dictionary<string, string> ReverseTypeConversionTable { |
||||
get { |
||||
return reverseTypeConversionTable; |
||||
} |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Gets a dictionary with the fully qualified type names as keys and
|
||||
/// boo's short names as values.
|
||||
/// </summary>
|
||||
public static Dictionary<string, string> 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<string, string> 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<KeyValuePair<string, string>> 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 += "<i>"; |
||||
} |
||||
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 += "</i>"; |
||||
} |
||||
return ret; |
||||
} |
||||
|
||||
|
||||
public override string Convert(IClass c) |
||||
{ |
||||
StringBuilder builder = new StringBuilder(); |
||||
|
||||
builder.Append(Convert(c.Modifiers)); |
||||
|
||||
if (IncludeHTMLMarkup) { |
||||
builder.Append("<i>"); |
||||
} |
||||
|
||||
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("</i>"); |
||||
} |
||||
|
||||
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("<b>"); |
||||
} |
||||
|
||||
if (UseFullyQualifiedMemberNames) { |
||||
builder.Append(c.FullyQualifiedName); |
||||
} else { |
||||
builder.Append(c.Name); |
||||
} |
||||
|
||||
if (IncludeHTMLMarkup) { |
||||
builder.Append("</b>"); |
||||
} |
||||
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("<br>"); |
||||
|
||||
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("<br>"); |
||||
} |
||||
} |
||||
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("<i>"); |
||||
} |
||||
|
||||
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("</i>"); |
||||
} |
||||
|
||||
if (IncludeHTMLMarkup) { |
||||
builder.Append("<b>"); |
||||
} |
||||
|
||||
if (UseFullyQualifiedMemberNames) { |
||||
builder.Append(field.FullyQualifiedName); |
||||
} else { |
||||
builder.Append(field.Name); |
||||
} |
||||
|
||||
if (IncludeHTMLMarkup) { |
||||
builder.Append("</b>"); |
||||
} |
||||
|
||||
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("<b>"); |
||||
} |
||||
if (UseFullyQualifiedMemberNames) { |
||||
builder.Append(property.FullyQualifiedName); |
||||
} else { |
||||
builder.Append(property.Name); |
||||
} |
||||
if (IncludeHTMLMarkup) { |
||||
builder.Append("</b>"); |
||||
} |
||||
} |
||||
|
||||
if (property.Parameters.Count > 0) { |
||||
builder.Append('['); |
||||
if (IncludeHTMLMarkup) builder.Append("<br>"); |
||||
|
||||
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("<br>"); |
||||
} |
||||
|
||||
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("<b>"); |
||||
} |
||||
|
||||
if (UseFullyQualifiedMemberNames) { |
||||
builder.Append(e.FullyQualifiedName); |
||||
} else { |
||||
builder.Append(e.Name); |
||||
} |
||||
|
||||
if (IncludeHTMLMarkup) { |
||||
builder.Append("</b>"); |
||||
} |
||||
|
||||
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("<b>"); |
||||
} |
||||
|
||||
if (m.IsConstructor) { |
||||
builder.Append("constructor"); |
||||
} else { |
||||
if (UseFullyQualifiedMemberNames) { |
||||
builder.Append(m.FullyQualifiedName); |
||||
} else { |
||||
builder.Append(m.Name); |
||||
} |
||||
} |
||||
|
||||
if (IncludeHTMLMarkup) { |
||||
builder.Append("</b>"); |
||||
} |
||||
|
||||
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("<br>"); |
||||
|
||||
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("<br>"); |
||||
} |
||||
|
||||
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("<i>"); |
||||
} |
||||
|
||||
if (param.IsRef) { |
||||
builder.Append("ref "); |
||||
} else if (param.IsOut) { |
||||
builder.Append("ref "); |
||||
} else if (param.IsParams) { |
||||
builder.Append("*"); |
||||
} |
||||
|
||||
if (IncludeHTMLMarkup) { |
||||
builder.Append("</i>"); |
||||
} |
||||
|
||||
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; |
||||
} |
||||
} |
||||
} |
||||
@ -0,0 +1,73 @@
@@ -0,0 +1,73 @@
|
||||
// <file>
|
||||
// <copyright see="prj:///doc/copyright.txt">2002-2005 AlphaSierraPapa</copyright>
|
||||
// <license see="prj:///doc/license.txt">GNU General Public License</license>
|
||||
// <owner name="Daniel Grunwald" email="daniel@danielgrunwald.de"/>
|
||||
// <version>$Revision$</version>
|
||||
// </file>
|
||||
|
||||
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; |
||||
} |
||||
} |
||||
} |
||||
@ -0,0 +1,45 @@
@@ -0,0 +1,45 @@
|
||||
// <file>
|
||||
// <copyright see="prj:///doc/copyright.txt">2002-2005 AlphaSierraPapa</copyright>
|
||||
// <license see="prj:///doc/license.txt">GNU General Public License</license>
|
||||
// <owner name="Daniel Grunwald" email="daniel@danielgrunwald.de"/>
|
||||
// <version>$Revision$</version>
|
||||
// </file>
|
||||
|
||||
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; |
||||
} |
||||
} |
||||
} |
||||
} |
||||
@ -0,0 +1,128 @@
@@ -0,0 +1,128 @@
|
||||
// <file>
|
||||
// <copyright see="prj:///doc/copyright.txt">2002-2005 AlphaSierraPapa</copyright>
|
||||
// <license see="prj:///doc/license.txt">GNU General Public License</license>
|
||||
// <owner name="Daniel Grunwald" email="daniel@danielgrunwald.de"/>
|
||||
// <version>$Revision$</version>
|
||||
// </file>
|
||||
|
||||
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 |
||||
{ |
||||
///<summary>IParser Interface</summary>
|
||||
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(); |
||||
} |
||||
} |
||||
} |
||||
@ -0,0 +1,181 @@
@@ -0,0 +1,181 @@
|
||||
// <file>
|
||||
// <copyright see="prj:///doc/copyright.txt">2002-2005 AlphaSierraPapa</copyright>
|
||||
// <license see="prj:///doc/license.txt">GNU General Public License</license>
|
||||
// <owner name="Daniel Grunwald" email="daniel@danielgrunwald.de"/>
|
||||
// <version>$Revision$</version>
|
||||
// </file>
|
||||
|
||||
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<string, string> pair in BooAmbience.TypeConversionTable) { |
||||
c = GetPrimitiveClass(pair.Key, pair.Value); |
||||
if (c != null) list.Add(c); |
||||
} |
||||
NRResolver.AddImportedNamespaceContents(list, cu, callingClass); |
||||
return list; |
||||
} |
||||
#endregion
|
||||
} |
||||
} |
||||
@ -0,0 +1,51 @@
@@ -0,0 +1,51 @@
|
||||
// <file>
|
||||
// <copyright see="prj:///doc/copyright.txt">2002-2005 AlphaSierraPapa</copyright>
|
||||
// <license see="prj:///doc/license.txt">GNU General Public License</license>
|
||||
// <owner name="Daniel Grunwald" email="daniel@danielgrunwald.de"/>
|
||||
// <version>$Revision$</version>
|
||||
// </file>
|
||||
|
||||
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); |
||||
} |
||||
} |
||||
} |
||||
} |
||||
@ -0,0 +1,393 @@
@@ -0,0 +1,393 @@
|
||||
// <file>
|
||||
// <copyright see="prj:///doc/copyright.txt">2002-2005 AlphaSierraPapa</copyright>
|
||||
// <license see="prj:///doc/license.txt">GNU General Public License</license>
|
||||
// <owner name="Daniel Grunwald" email="daniel@danielgrunwald.de"/>
|
||||
// <version>$Revision$</version>
|
||||
// </file>
|
||||
|
||||
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<DefaultClass> _currentClass = new Stack<DefaultClass>(); |
||||
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<IParameter> 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); |
||||
} |
||||
} |
||||
} |
||||
@ -0,0 +1,359 @@
@@ -0,0 +1,359 @@
|
||||
// <file>
|
||||
// <copyright see="prj:///doc/copyright.txt">2002-2005 AlphaSierraPapa</copyright>
|
||||
// <license see="prj:///doc/license.txt">GNU General Public License</license>
|
||||
// <owner name="Daniel Grunwald" email="daniel@danielgrunwald.de"/>
|
||||
// <version>$Revision$</version>
|
||||
// </file>
|
||||
|
||||
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
|
||||
/// <summary>
|
||||
/// Removes the last part of the expression.
|
||||
/// </summary>
|
||||
/// <example>
|
||||
/// "arr[i]" => "arr"
|
||||
/// "obj.Field" => "obj"
|
||||
/// "obj.Method(args,...)" => "obj.Method"
|
||||
/// </example>
|
||||
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<int> bracketStack = new Stack<int>(); |
||||
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<int> bracketStack = new Stack<int>(); |
||||
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; |
||||
} |
||||
|
||||
/// <summary>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/</summary>
|
||||
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; |
||||
} |
||||
} |
||||
|
||||
/// <summary>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.</summary>
|
||||
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
|
||||
} |
||||
} |
||||
@ -0,0 +1,484 @@
@@ -0,0 +1,484 @@
|
||||
// <file>
|
||||
// <copyright see="prj:///doc/copyright.txt">2002-2005 AlphaSierraPapa</copyright>
|
||||
// <license see="prj:///doc/license.txt">GNU General Public License</license>
|
||||
// <owner name="Daniel Grunwald" email="daniel@danielgrunwald.de"/>
|
||||
// <version>$Revision$</version>
|
||||
// </file>
|
||||
|
||||
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<IMethod> methods = new List<IMethod>(); |
||||
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<IMethod> methods = new List<IMethod>(); |
||||
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<IMethod> 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); |
||||
} |
||||
} |
||||
} |
||||
@ -0,0 +1,38 @@
@@ -0,0 +1,38 @@
|
||||
<?xml version="1.0"?> |
||||
<Template originator = "Daniel Grunwald"> |
||||
<TemplateConfiguration> |
||||
<Name>${res:Templates.Project.ConsoleProject.Name}</Name> |
||||
<Category>Boo</Category> |
||||
<Icon>C#.Project.DOSProject</Icon> |
||||
<LanguageName>Boo</LanguageName> |
||||
<Description>${res:Templates.Project.ConsoleProject.Description}</Description> |
||||
</TemplateConfiguration> |
||||
|
||||
<!-- Actions --> |
||||
<Actions> |
||||
<Open filename = "Program.boo"/> |
||||
</Actions> |
||||
|
||||
<!-- Template Content --> |
||||
<Combine name = "${ProjectName}" directory = "."> |
||||
<Options/> |
||||
|
||||
<Project name = "${ProjectName}" directory = "."> |
||||
<Options/> |
||||
|
||||
<ProjectItems> |
||||
<Reference Include="System" /> |
||||
<Reference Include="System.Data" /> |
||||
<Reference Include="System.Xml" /> |
||||
</ProjectItems> |
||||
|
||||
<Files> |
||||
<File name="Program.boo"><![CDATA[import System |
||||
import System.Collections |
||||
|
||||
print "Hello, World!" |
||||
]]></File> |
||||
</Files> |
||||
</Project> |
||||
</Combine> |
||||
</Template> |
||||
@ -0,0 +1,96 @@
@@ -0,0 +1,96 @@
|
||||
<?xml version="1.0"?> |
||||
<Template originator = "Daniel Grunwald"> |
||||
<TemplateConfiguration> |
||||
<Name>${res:Templates.Project.WindowsApplication.Name}</Name> |
||||
<Category>Boo</Category> |
||||
<Icon>C#.Project.Form</Icon> |
||||
<LanguageName>Boo</LanguageName> |
||||
<Description>${res:Templates.Project.WindowsApplication.Description}</Description> |
||||
</TemplateConfiguration> |
||||
|
||||
<Actions> |
||||
<Open filename = "MainForm.boo"/> |
||||
</Actions> |
||||
|
||||
<Combine name = "${ProjectName}" directory = "."> |
||||
<Options> |
||||
<StartupProject>${ProjectName}</StartupProject> |
||||
</Options> |
||||
|
||||
<Project name = "${ProjectName}" directory = "."> |
||||
<Options OutputType = "WinExe" /> |
||||
|
||||
<ProjectItems> |
||||
<Reference Include="System" /> |
||||
<Reference Include="System.Data" /> |
||||
<Reference Include="System.Drawing" /> |
||||
<Reference Include="System.Windows.Forms" /> |
||||
<Reference Include="System.Xml" /> |
||||
</ProjectItems> |
||||
|
||||
<Files> |
||||
<File name="MainForm.boo"><![CDATA[namespace ${StandardNamespace} |
||||
|
||||
import System |
||||
import System.Collections |
||||
import System.Drawing |
||||
import System.Windows.Forms |
||||
|
||||
|
||||
class MainForm(System.Windows.Forms.Form): |
||||
"""Description of MainForm.""" |
||||
def constructor(): |
||||
// The InitializeComponent() call is required for Windows Forms designer support. |
||||
InitializeComponent() |
||||
// TODO: Add constructor code after the InitializeComponent() call. |
||||
|
||||
|
||||
#region Windows Forms Designer generated code |
||||
// This method is required for Windows Forms designer support. |
||||
// Do not change the method contents inside the source code editor. The Forms designer might |
||||
// not be able to load this method if it was changed manually. |
||||
def InitializeComponent(): |
||||
// Form1 |
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font |
||||
this.ClientSize = new System.Drawing.Size(292, 266) |
||||
this.Text = 'MainForm' |
||||
this.Name = 'MainForm' |
||||
#endregion |
||||
|
||||
Application.EnableVisualStyles() |
||||
Application.Run(new MainForm()) |
||||
|
||||
}]]></File> |
||||
<File name="AssemblyInfo.cs"> |
||||
<![CDATA[import System.Reflection |
||||
import 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('')] |
||||
[assembly: AssemblyDescription('')] |
||||
[assembly: AssemblyConfiguration('')] |
||||
[assembly: AssemblyCompany('')] |
||||
[assembly: AssemblyProduct('')] |
||||
[assembly: AssemblyCopyright('')] |
||||
[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("1.0.*")] |
||||
|
||||
]]></File> |
||||
</Files> |
||||
</Project> |
||||
</Combine> |
||||
</Template> |
||||
@ -0,0 +1,73 @@
@@ -0,0 +1,73 @@
|
||||
<?xml version="1.0"?> |
||||
<Template originator = "Daniel Grunwald"> |
||||
<TemplateConfiguration> |
||||
<Name>${res:Templates.Project.ClassLibrary.Name}</Name> |
||||
<Category>Boo</Category> |
||||
<Icon>C#.Project.Library</Icon> |
||||
<LanguageName>Boo</LanguageName> |
||||
<Description>${res:Templates.Project.ClassLibrary.Description}</Description> |
||||
</TemplateConfiguration> |
||||
|
||||
<Actions> |
||||
<Open filename = "MyClass.boo"/> |
||||
</Actions> |
||||
|
||||
<Combine name = "${ProjectName}" directory = "."> |
||||
<Options> |
||||
<StartupProject>${ProjectName}</StartupProject> |
||||
</Options> |
||||
|
||||
<Project name = "${ProjectName}" directory = "."> |
||||
<Options OutputType = "Library" /> |
||||
|
||||
<ProjectItems> |
||||
<Reference Include="System" /> |
||||
<Reference Include="System.Xml" /> |
||||
</ProjectItems> |
||||
|
||||
<Files> |
||||
<File name="MyClass.boo"><![CDATA[namespace ${StandardNamespace} |
||||
|
||||
import System |
||||
import System.Collections |
||||
|
||||
class MyClass: |
||||
"""Description of MyClass.""" |
||||
|
||||
def constructor(): |
||||
pass |
||||
|
||||
}]]></File> |
||||
<File name="AssemblyInfo.cs"> |
||||
<![CDATA[import System.Reflection |
||||
import 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('')] |
||||
[assembly: AssemblyDescription('')] |
||||
[assembly: AssemblyConfiguration('')] |
||||
[assembly: AssemblyCompany('')] |
||||
[assembly: AssemblyProduct('')] |
||||
[assembly: AssemblyCopyright('')] |
||||
[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("1.0.*")] |
||||
|
||||
]]></File> |
||||
</Files> |
||||
</Project> |
||||
</Combine> |
||||
</Template> |
||||
@ -0,0 +1,50 @@
@@ -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.*"; |
||||
} |
||||
} |
||||
@ -0,0 +1,202 @@
@@ -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<ISpecial> enumerator; |
||||
bool available; // true when more specials are available
|
||||
|
||||
public BooPrinterVisitorWithComments(IEnumerable<ISpecial> 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); |
||||
} |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Writes all specials up to the specified location.
|
||||
/// </summary>
|
||||
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(); |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Outputs all missing specials to the writer.
|
||||
/// </summary>
|
||||
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<DelayedSpecial> delayedSpecials = new List<DelayedSpecial>(); |
||||
|
||||
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
|
||||
} |
||||
} |
||||
@ -0,0 +1,283 @@
@@ -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<TypeReference> input, B.TypeReferenceCollection output) |
||||
{ |
||||
foreach (TypeReference t in input) { |
||||
B.TypeReference r = ConvertTypeReference(t); |
||||
if (r != null) { |
||||
output.Add(r); |
||||
} |
||||
} |
||||
} |
||||
|
||||
Dictionary<string, string> 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<string, string>(); |
||||
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; |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Convert TypeReference and wrap it into an TypeofExpression.
|
||||
/// </summary>
|
||||
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); |
||||
} |
||||
} |
||||
} |
||||
@ -0,0 +1,519 @@
@@ -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 <OP>= 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; |
||||
} |
||||
} |
||||
} |
||||
@ -0,0 +1,221 @@
@@ -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<AttributeSection> 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; |
||||
} |
||||
} |
||||
} |
||||
@ -0,0 +1,686 @@
@@ -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)); |
||||
} |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Make a loop:
|
||||
/// $initializers
|
||||
/// goto ___converterGeneratedName#
|
||||
/// while true:
|
||||
/// $iterators
|
||||
/// :___converterGeneratedName#
|
||||
/// break $conditionType $condition
|
||||
/// $body
|
||||
/// </summary>
|
||||
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."); |
||||
} |
||||
} |
||||
} |
||||
@ -0,0 +1,324 @@
@@ -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<ParameterDeclarationExpression> 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(); |
||||
} |
||||
} |
||||
} |
||||
@ -0,0 +1,51 @@
@@ -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 |
||||
{ |
||||
/// <summary>
|
||||
/// Class with static conversion methods.
|
||||
/// </summary>
|
||||
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); |
||||
} |
||||
} |
||||
} |
||||
@ -0,0 +1,105 @@
@@ -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; |
||||
} |
||||
} |
||||
} |
||||
} |
||||
@ -0,0 +1,102 @@
@@ -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 |
||||
{ |
||||
/// <summary>
|
||||
/// This visitor finds label statements that have no matching goto statements.
|
||||
/// </summary>
|
||||
public class FindUnneededLabelsVisitor : DepthFirstVisitor |
||||
{ |
||||
string prefix; |
||||
StringComparer nameComparer; |
||||
|
||||
/// <summary>
|
||||
/// Remove only those unneeded labels that start with <param name="prefix"/>.
|
||||
/// Use null to remove all unneeded labels.
|
||||
/// </summary>
|
||||
public FindUnneededLabelsVisitor(string prefix, StringComparer nameComparer) |
||||
{ |
||||
this.prefix = prefix; |
||||
this.nameComparer = nameComparer; |
||||
} |
||||
|
||||
List<LabelStatement> unneededLabels = new List<LabelStatement>(); |
||||
List<string> neededLabels = new List<string>(); |
||||
|
||||
public List<string> NeededLabels { |
||||
get { |
||||
return neededLabels; |
||||
} |
||||
} |
||||
|
||||
public List<LabelStatement> UnneededLabels { |
||||
get { |
||||
return unneededLabels; |
||||
} |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Removes all unneeded labels that have been found from the AST.
|
||||
/// </summary>
|
||||
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--); |
||||
} |
||||
} |
||||
} |
||||
} |
||||
@ -0,0 +1,51 @@
@@ -0,0 +1,51 @@
|
||||
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> |
||||
<PropertyGroup> |
||||
<OutputType>Library</OutputType> |
||||
<RootNamespace>NRefactoryToBooConverter</RootNamespace> |
||||
<AssemblyName>NRefactoryToBooConverter</AssemblyName> |
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> |
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> |
||||
<ProjectGuid>{DBCF20A1-BA13-4582-BFA9-74DE4D987B73}</ProjectGuid> |
||||
</PropertyGroup> |
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "> |
||||
<OutputPath>bin\Debug\</OutputPath> |
||||
<Optimize>false</Optimize> |
||||
<DefineConstants>DEBUG;TRACE</DefineConstants> |
||||
</PropertyGroup> |
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' "> |
||||
<OutputPath>bin\Release\</OutputPath> |
||||
<Optimize>true</Optimize> |
||||
<DefineConstants>TRACE</DefineConstants> |
||||
</PropertyGroup> |
||||
<ItemGroup> |
||||
<Reference Include="System" /> |
||||
<Reference Include="System.Drawing" /> |
||||
<Reference Include="System.Xml" /> |
||||
<Reference Include="Boo.Lang.Compiler"> |
||||
<HintPath>..\..\RequiredLibraries\Boo.Lang.Compiler.dll</HintPath> |
||||
<SpecificVersion>False</SpecificVersion> |
||||
</Reference> |
||||
<Reference Include="Boo.Lang"> |
||||
<HintPath>..\..\RequiredLibraries\Boo.Lang.dll</HintPath> |
||||
<SpecificVersion>False</SpecificVersion> |
||||
</Reference> |
||||
</ItemGroup> |
||||
<ItemGroup> |
||||
<Compile Include="AssemblyInfo.cs" /> |
||||
<Compile Include="Converter.cs" /> |
||||
<Compile Include="RefactoryVisitor.cs" /> |
||||
<Compile Include="ConvertVisitor.cs" /> |
||||
<Compile Include="Parser.cs" /> |
||||
<Compile Include="ConvertVisitorGlobal.cs" /> |
||||
<Compile Include="ConvertVisitorTypeMembers.cs" /> |
||||
<Compile Include="ConvertVisitorStatements.cs" /> |
||||
<Compile Include="ConvertVisitorExpressions.cs" /> |
||||
<Compile Include="FindUnneededLabelsVisitor.cs" /> |
||||
<Compile Include="ReplaceBreakStatementsVisitor.cs" /> |
||||
<Compile Include="RenameLocalsVisitor.cs" /> |
||||
<Compile Include="VariableResolver.cs" /> |
||||
<Compile Include="ConverterSettings.cs" /> |
||||
<Compile Include="BooPrinterVisitorWithComments.cs" /> |
||||
</ItemGroup> |
||||
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.Targets" /> |
||||
</Project> |
||||
@ -0,0 +1,90 @@
@@ -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 |
||||
{ |
||||
/// <summary>
|
||||
/// Class with static methods to parse C# and VB code.
|
||||
/// </summary>
|
||||
public static class Parser |
||||
{ |
||||
public static Module ParseModule(CompileUnit cu, TextReader input, ConverterSettings settings) |
||||
{ |
||||
IList<ISpecial> specials; |
||||
return ParseModule(cu, input, settings, out specials); |
||||
} |
||||
|
||||
public static Module ParseModule(CompileUnit cu, TextReader input, ConverterSettings settings, out IList<ISpecial> 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++; |
||||
} |
||||
} |
||||
} |
||||
} |
||||
@ -0,0 +1,42 @@
@@ -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 |
||||
{ |
||||
/// <summary>
|
||||
/// Visitor that prepares the conversion by converting source-language specific constructs
|
||||
/// into "better suited" constructs.
|
||||
/// </summary>
|
||||
/// <example>
|
||||
/// 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):"
|
||||
/// </example>
|
||||
public class RefactoryVisitor : CSharpToVBNetConvertVisitor |
||||
{ |
||||
public RefactoryVisitor() |
||||
{ |
||||
base.RenameConflictingFieldNames = false; // do not rename fields to VB-style
|
||||
} |
||||
} |
||||
} |
||||
@ -0,0 +1,158 @@
@@ -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<DeclarationStatement> list = new List<DeclarationStatement>(); |
||||
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<DeclarationStatement> list1, List<DeclarationStatement> 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<DeclarationStatement> declarations = new List<DeclarationStatement>(); |
||||
|
||||
public List<DeclarationStatement> 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); |
||||
} |
||||
} |
||||
} |
||||
@ -0,0 +1,52 @@
@@ -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); |
||||
} |
||||
} |
||||
} |
||||
@ -0,0 +1,59 @@
@@ -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 |
||||
{ |
||||
/// <summary>
|
||||
/// 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.
|
||||
/// </summary>
|
||||
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; |
||||
} |
||||
} |
||||
} |
||||
@ -0,0 +1,51 @@
@@ -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"); |
||||
} |
||||
} |
||||
} |
||||
@ -0,0 +1,44 @@
@@ -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 |
||||
{ |
||||
/// <summary>
|
||||
/// Tests for special cases that have to fail.
|
||||
/// </summary>
|
||||
//[TestFixture]
|
||||
public class ErrorTests : TestHelper |
||||
{ |
||||
/* |
||||
For the following errors are currently no checks implemented: |
||||
|
||||
enum Enumeration : WithBaseType |
||||
enum Enumeration<T> |
||||
static class Bla : WithBaseType |
||||
static class Bla<T> |
||||
enum Enumeration { void Main(); } // check that enums can only have fields is not implemented
|
||||
*/ |
||||
} |
||||
} |
||||
@ -0,0 +1,226 @@
@@ -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"); |
||||
} |
||||
} |
||||
} |
||||
@ -0,0 +1,148 @@
@@ -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"); |
||||
} |
||||
} |
||||
} |
||||
@ -0,0 +1,247 @@
@@ -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"); |
||||
} |
||||
} |
||||
} |
||||
@ -0,0 +1,54 @@
@@ -0,0 +1,54 @@
|
||||
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> |
||||
<PropertyGroup> |
||||
<OutputType>Library</OutputType> |
||||
<RootNamespace>NRefactoryToBooConverter.Tests</RootNamespace> |
||||
<AssemblyName>NRefactoryToBooConverter.Tests</AssemblyName> |
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> |
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> |
||||
<ProjectGuid>{C9DE556D-325C-4544-B29F-16A9EB7C9830}</ProjectGuid> |
||||
</PropertyGroup> |
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "> |
||||
<OutputPath>bin\Debug\</OutputPath> |
||||
<Optimize>false</Optimize> |
||||
<DefineConstants>DEBUG;TRACE</DefineConstants> |
||||
</PropertyGroup> |
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' "> |
||||
<OutputPath>bin\Release\</OutputPath> |
||||
<Optimize>true</Optimize> |
||||
<DefineConstants>TRACE</DefineConstants> |
||||
</PropertyGroup> |
||||
<ItemGroup> |
||||
<Reference Include="System" /> |
||||
<Reference Include="System.Xml" /> |
||||
<Reference Include="nunit.framework" /> |
||||
<Reference Include="Boo.Lang.Compiler"> |
||||
<HintPath>..\..\RequiredLibraries\Boo.Lang.Compiler.dll</HintPath> |
||||
<SpecificVersion>False</SpecificVersion> |
||||
</Reference> |
||||
<Reference Include="Boo.Lang"> |
||||
<HintPath>..\..\RequiredLibraries\Boo.Lang.dll</HintPath> |
||||
<SpecificVersion>False</SpecificVersion> |
||||
</Reference> |
||||
</ItemGroup> |
||||
<ItemGroup> |
||||
<Compile Include="GlobalTests.cs" /> |
||||
<Compile Include="TestHelper.cs" /> |
||||
<Compile Include="ErrorTests.cs" /> |
||||
<Compile Include="MemberTests.cs" /> |
||||
<Compile Include="ExpressionTests.cs" /> |
||||
<Compile Include="StatementTests.cs" /> |
||||
<Compile Include="ComplexTests.cs" /> |
||||
</ItemGroup> |
||||
<ItemGroup> |
||||
<ProjectReference Include="..\Project\NRefactoryToBooConverter.csproj"> |
||||
<Project>{DBCF20A1-BA13-4582-BFA9-74DE4D987B73}</Project> |
||||
<Name>NRefactoryToBooConverter</Name> |
||||
</ProjectReference> |
||||
<ProjectReference Include="..\..\..\..\..\Libraries\NRefactory\Project\NRefactory.csproj"> |
||||
<Project>{3A9AE6AA-BC07-4A2F-972C-581E3AE2F195}</Project> |
||||
<Name>NRefactory</Name> |
||||
<Private>True</Private> |
||||
</ProjectReference> |
||||
</ItemGroup> |
||||
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.Targets" /> |
||||
</Project> |
||||
@ -0,0 +1,223 @@
@@ -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]"); |
||||
} |
||||
} |
||||
} |
||||
@ -0,0 +1,109 @@
@@ -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); |
||||
} |
||||
} |
||||
} |
||||
@ -0,0 +1,46 @@
@@ -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)] |
||||
|
||||
@ -0,0 +1,363 @@
@@ -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 |
||||
{ |
||||
/// <returns>
|
||||
/// 0 = conversion successful
|
||||
/// 1 = internal error
|
||||
/// 2 = invalid command line parameters
|
||||
/// 3 = no command line parameters
|
||||
/// 4 = conversion error
|
||||
/// </returns>
|
||||
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<string> input = new List<string>(); |
||||
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<string> 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<ICSharpCode.NRefactory.Parser.ISpecial> 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
|
||||
} |
||||
} |
||||
@ -0,0 +1,51 @@
@@ -0,0 +1,51 @@
|
||||
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> |
||||
<PropertyGroup> |
||||
<OutputType>Exe</OutputType> |
||||
<RootNamespace>StandaloneConverter</RootNamespace> |
||||
<AssemblyName>StandaloneConverter</AssemblyName> |
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> |
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> |
||||
<ProjectGuid>{66338092-7611-40FC-B69C-B73A0528DA82}</ProjectGuid> |
||||
</PropertyGroup> |
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "> |
||||
<OutputPath>bin\Debug\</OutputPath> |
||||
<Optimize>False</Optimize> |
||||
<DefineConstants>DEBUG;TRACE</DefineConstants> |
||||
<DebugSymbols>True</DebugSymbols> |
||||
<DebugType>Full</DebugType> |
||||
<CheckForOverflowUnderflow>True</CheckForOverflowUnderflow> |
||||
</PropertyGroup> |
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' "> |
||||
<OutputPath>bin\Release\</OutputPath> |
||||
<Optimize>True</Optimize> |
||||
<DefineConstants>TRACE</DefineConstants> |
||||
<DebugSymbols>False</DebugSymbols> |
||||
<DebugType>None</DebugType> |
||||
<CheckForOverflowUnderflow>False</CheckForOverflowUnderflow> |
||||
</PropertyGroup> |
||||
<ItemGroup> |
||||
<Reference Include="System" /> |
||||
<Reference Include="System.Data" /> |
||||
<Reference Include="System.Xml" /> |
||||
<Reference Include="Boo.Lang.Compiler"> |
||||
<HintPath>..\RequiredLibraries\Boo.Lang.Compiler.dll</HintPath> |
||||
<SpecificVersion>False</SpecificVersion> |
||||
</Reference> |
||||
</ItemGroup> |
||||
<ItemGroup> |
||||
<Compile Include="Main.cs" /> |
||||
<Compile Include="AssemblyInfo.cs" /> |
||||
</ItemGroup> |
||||
<ItemGroup> |
||||
<ProjectReference Include="..\..\..\NET\BooNRefactory\NRefactoryToBooConverter\Project\NRefactoryToBooConverter.csproj"> |
||||
<Project>{DBCF20A1-BA13-4582-BFA9-74DE4D987B73}</Project> |
||||
<Name>NRefactoryToBooConverter</Name> |
||||
</ProjectReference> |
||||
<ProjectReference Include="..\..\..\..\Libraries\NRefactory\Project\NRefactory.csproj"> |
||||
<Project>{3A9AE6AA-BC07-4A2F-972C-581E3AE2F195}</Project> |
||||
<Name>NRefactory</Name> |
||||
<Private>False</Private> |
||||
</ProjectReference> |
||||
</ItemGroup> |
||||
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.Targets" /> |
||||
</Project> |
||||
Loading…
Reference in new issue