mirror of https://github.com/icsharpcode/ILSpy.git
140 changed files with 27920 additions and 11 deletions
@ -0,0 +1,103 @@
@@ -0,0 +1,103 @@
|
||||
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
|
||||
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
|
||||
using System; |
||||
using ICSharpCode.SharpDevelop.Dom; |
||||
using ICSharpCode.SharpDevelop.Dom.CSharp; |
||||
using ICSharpCode.SharpDevelop.Dom.NRefactoryResolver; |
||||
|
||||
namespace ILSpy.Debugger.Services.ParserService |
||||
{ |
||||
public class TParser : IParser |
||||
{ |
||||
///<summary>IParser Interface</summary>
|
||||
string[] lexerTags; |
||||
|
||||
public string[] LexerTags { |
||||
get { |
||||
return lexerTags; |
||||
} |
||||
set { |
||||
lexerTags = value; |
||||
} |
||||
} |
||||
|
||||
public LanguageProperties Language { |
||||
get { |
||||
return LanguageProperties.CSharp; |
||||
} |
||||
} |
||||
|
||||
public IExpressionFinder CreateExpressionFinder(string fileName) |
||||
{ |
||||
return new CSharpExpressionFinder(null); |
||||
} |
||||
|
||||
void RetrieveRegions(ICompilationUnit cu, ICSharpCode.NRefactory.Parser.SpecialTracker tracker) |
||||
{ |
||||
for (int i = 0; i < tracker.CurrentSpecials.Count; ++i) { |
||||
ICSharpCode.NRefactory.PreprocessingDirective directive = tracker.CurrentSpecials[i] as ICSharpCode.NRefactory.PreprocessingDirective; |
||||
if (directive != null) { |
||||
if (directive.Cmd == "#region") { |
||||
int deep = 1; |
||||
for (int j = i + 1; j < tracker.CurrentSpecials.Count; ++j) { |
||||
ICSharpCode.NRefactory.PreprocessingDirective nextDirective = tracker.CurrentSpecials[j] as ICSharpCode.NRefactory.PreprocessingDirective; |
||||
if (nextDirective != null) { |
||||
switch (nextDirective.Cmd) { |
||||
case "#region": |
||||
++deep; |
||||
break; |
||||
case "#endregion": |
||||
--deep; |
||||
if (deep == 0) { |
||||
cu.FoldingRegions.Add(new FoldingRegion(directive.Arg.Trim(), DomRegion.FromLocation(directive.StartPosition, nextDirective.EndPosition))); |
||||
goto end; |
||||
} |
||||
break; |
||||
} |
||||
} |
||||
} |
||||
end: ; |
||||
} |
||||
} |
||||
} |
||||
} |
||||
|
||||
public ICompilationUnit Parse(IProjectContent projectContent, string fileName = null, ITextBuffer fileContent) |
||||
{ |
||||
using (ICSharpCode.NRefactory.IParser p = ICSharpCode.NRefactory.ParserFactory.CreateParser(ICSharpCode.NRefactory.SupportedLanguage.CSharp, fileContent.CreateReader())) { |
||||
return Parse(p, fileName, projectContent); |
||||
} |
||||
} |
||||
|
||||
ICompilationUnit Parse(ICSharpCode.NRefactory.IParser p, string fileName, IProjectContent projectContent) |
||||
{ |
||||
p.Lexer.SpecialCommentTags = lexerTags; |
||||
p.ParseMethodBodies = false; |
||||
p.Parse(); |
||||
|
||||
NRefactoryASTConvertVisitor visitor = new NRefactoryASTConvertVisitor(projectContent, ICSharpCode.NRefactory.SupportedLanguage.CSharp); |
||||
visitor.Specials = p.Lexer.SpecialTracker.CurrentSpecials; |
||||
visitor.VisitCompilationUnit(p.CompilationUnit, null); |
||||
visitor.Cu.FileName = fileName; |
||||
visitor.Cu.ErrorsDuringCompile = p.Errors.Count > 0; |
||||
RetrieveRegions(visitor.Cu, p.Lexer.SpecialTracker); |
||||
AddCommentTags(visitor.Cu, p.Lexer.TagComments); |
||||
return visitor.Cu; |
||||
} |
||||
|
||||
void AddCommentTags(ICompilationUnit cu, System.Collections.Generic.List<ICSharpCode.NRefactory.Parser.TagComment> tagComments) |
||||
{ |
||||
foreach (ICSharpCode.NRefactory.Parser.TagComment tagComment in tagComments) { |
||||
DomRegion tagRegion = new DomRegion(tagComment.StartPosition.Y, tagComment.StartPosition.X); |
||||
var tag = new ICSharpCode.SharpDevelop.Dom.TagComment(tagComment.Tag, tagRegion, tagComment.CommentText); |
||||
cu.TagComments.Add(tag); |
||||
} |
||||
} |
||||
|
||||
public IResolver CreateResolver() |
||||
{ |
||||
return new NRefactoryResolver(LanguageProperties.CSharp); |
||||
} |
||||
///////// IParser Interface END
|
||||
} |
||||
} |
||||
@ -0,0 +1,18 @@
@@ -0,0 +1,18 @@
|
||||
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
|
||||
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
|
||||
|
||||
using System; |
||||
using System.Reflection; |
||||
using System.Runtime.CompilerServices; |
||||
using System.Security.Permissions; |
||||
|
||||
[assembly: CLSCompliant(true)] |
||||
[assembly: StringFreezing()] |
||||
|
||||
[assembly: Dependency("System.Core", LoadHint.Always)] |
||||
|
||||
[assembly: AssemblyTitle("ICSharpCode.SharpDevelop.Dom")] |
||||
[assembly: AssemblyDescription("Code-completion library")] |
||||
[assembly: AssemblyConfiguration("")] |
||||
[assembly: AssemblyTrademark("")] |
||||
[assembly: AssemblyCulture("")] |
||||
@ -0,0 +1,216 @@
@@ -0,0 +1,216 @@
|
||||
<?xml version="1.0" encoding="utf-8"?> |
||||
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0"> |
||||
<PropertyGroup> |
||||
<OutputType>Library</OutputType> |
||||
<RootNamespace>ICSharpCode.SharpDevelop.Dom</RootNamespace> |
||||
<AssemblyName>ICSharpCode.SharpDevelop.Dom</AssemblyName> |
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> |
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> |
||||
<ProjectGuid>{924EE450-603D-49C1-A8E5-4AFAA31CE6F3}</ProjectGuid> |
||||
<SignAssembly>False</SignAssembly> |
||||
<AssemblyOriginatorKeyFile>..\..\ICSharpCode.SharpDevelop.snk</AssemblyOriginatorKeyFile> |
||||
<DelaySign>False</DelaySign> |
||||
<AssemblyOriginatorKeyMode>File</AssemblyOriginatorKeyMode> |
||||
<OutputPath>bin\Debug\</OutputPath> |
||||
<AllowUnsafeBlocks>False</AllowUnsafeBlocks> |
||||
<NoStdLib>False</NoStdLib> |
||||
<RegisterForComInterop>False</RegisterForComInterop> |
||||
<GenerateSerializationAssemblies>Auto</GenerateSerializationAssemblies> |
||||
<BaseAddress>132644864</BaseAddress> |
||||
<PlatformTarget>AnyCPU</PlatformTarget> |
||||
<FileAlignment>4096</FileAlignment> |
||||
<WarningLevel>4</WarningLevel> |
||||
<TreatWarningsAsErrors>false</TreatWarningsAsErrors> |
||||
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion> |
||||
<RunCodeAnalysis>False</RunCodeAnalysis> |
||||
<CodeAnalysisRules>-Microsoft.Design#CA1002;-Microsoft.Design#CA1063;-Microsoft.Performance#CA1800;-Microsoft.Security#CA2104</CodeAnalysisRules> |
||||
<TargetFrameworkProfile> |
||||
</TargetFrameworkProfile> |
||||
<RunPostBuildEvent>OnBuildSuccess</RunPostBuildEvent> |
||||
<SourceAnalysisOverrideSettingsFile>C:\Users\Eusebiu\AppData\Roaming\ICSharpCode/SharpDevelop4.1\Settings.SourceAnalysis</SourceAnalysisOverrideSettingsFile> |
||||
</PropertyGroup> |
||||
<PropertyGroup Condition=" '$(Configuration)' == 'Debug' "> |
||||
<IntermediateOutputPath>obj\Debug\</IntermediateOutputPath> |
||||
<Optimize>False</Optimize> |
||||
<DefineConstants>DEBUG;TRACE</DefineConstants> |
||||
<DebugSymbols>true</DebugSymbols> |
||||
<DebugType>Full</DebugType> |
||||
<CheckForOverflowUnderflow>True</CheckForOverflowUnderflow> |
||||
<StartAction>Project</StartAction> |
||||
</PropertyGroup> |
||||
<PropertyGroup Condition=" '$(Configuration)' == 'Release' "> |
||||
<IntermediateOutputPath>obj\Release\</IntermediateOutputPath> |
||||
<Optimize>True</Optimize> |
||||
<DefineConstants>TRACE</DefineConstants> |
||||
<DebugSymbols>False</DebugSymbols> |
||||
<DebugType>None</DebugType> |
||||
<CheckForOverflowUnderflow>False</CheckForOverflowUnderflow> |
||||
</PropertyGroup> |
||||
<ItemGroup> |
||||
<Reference Include="log4net"> |
||||
<HintPath>..\..\..\Libraries\log4net\log4net.dll</HintPath> |
||||
</Reference> |
||||
<Reference Include="System" /> |
||||
<Reference Include="System.Core"> |
||||
<RequiredTargetFramework>3.5</RequiredTargetFramework> |
||||
</Reference> |
||||
<Reference Include="System.Xml" /> |
||||
</ItemGroup> |
||||
<ItemGroup> |
||||
<Compile Include="Configuration\AssemblyInfo.cs" /> |
||||
<Compile Include="Src\BusyManager.cs" /> |
||||
<Compile Include="Src\CecilReader.cs" /> |
||||
<Compile Include="Src\CSharp\CSharpExpressionContext.cs" /> |
||||
<Compile Include="Src\CSharp\OverloadResolution.cs" /> |
||||
<Compile Include="Src\CSharp\TypeInference.cs" /> |
||||
<Compile Include="Src\DomCache.cs" /> |
||||
<Compile Include="Src\ExtensionMethods.cs" /> |
||||
<Compile Include="Src\FileUtility.Minimal.cs" /> |
||||
<Compile Include="Src\Implementations\AbstractEntity.cs" /> |
||||
<Compile Include="Src\Implementations\AbstractMember.cs" /> |
||||
<Compile Include="Src\Implementations\AbstractReturnType.cs" /> |
||||
<Compile Include="Src\Implementations\AnonymousMethodReturnType.cs" /> |
||||
<Compile Include="Src\Implementations\ArrayReturnType.cs" /> |
||||
<Compile Include="Src\Implementations\AttributeReturnType.cs" /> |
||||
<Compile Include="Src\Implementations\BoundTypeParameter.cs" /> |
||||
<Compile Include="Src\Implementations\CombinedReturnType.cs" /> |
||||
<Compile Include="Src\Implementations\CompoundClass.cs" /> |
||||
<Compile Include="Src\Implementations\ConstructedReturnType.cs" /> |
||||
<Compile Include="Src\Implementations\DecoratingReturnType.cs" /> |
||||
<Compile Include="Src\Implementations\DefaultAttribute.cs" /> |
||||
<Compile Include="Src\Implementations\DefaultClass.cs" /> |
||||
<Compile Include="Src\Implementations\DefaultComment.cs" /> |
||||
<Compile Include="Src\Implementations\DefaultCompilationUnit.cs" /> |
||||
<Compile Include="Src\Implementations\DefaultEvent.cs" /> |
||||
<Compile Include="Src\Implementations\DefaultField.cs" /> |
||||
<Compile Include="Src\Implementations\DefaultMethod.cs" /> |
||||
<Compile Include="Src\Implementations\DefaultParameter.cs" /> |
||||
<Compile Include="Src\Implementations\DefaultProperty.cs" /> |
||||
<Compile Include="Src\Implementations\DefaultReturnType.cs" /> |
||||
<Compile Include="Src\Implementations\DefaultTypeParameter.cs" /> |
||||
<Compile Include="Src\Implementations\DefaultUsing.cs" /> |
||||
<Compile Include="Src\Implementations\DefaultUsingScope.cs" /> |
||||
<Compile Include="Src\Implementations\DynamicReturnType.cs" /> |
||||
<Compile Include="Src\Implementations\ElementReturnType.cs" /> |
||||
<Compile Include="Src\Implementations\GenericReturnType.cs" /> |
||||
<Compile Include="Src\Implementations\GetClassReturnType.cs" /> |
||||
<Compile Include="Src\Implementations\MethodGroupReturnType.cs" /> |
||||
<Compile Include="Src\Implementations\NullReturnType.cs" /> |
||||
<Compile Include="Src\Implementations\PointerReturnType.cs" /> |
||||
<Compile Include="Src\Implementations\ProxyReturnType.cs" /> |
||||
<Compile Include="Src\Implementations\ReferenceReturnType.cs" /> |
||||
<Compile Include="Src\Implementations\SearchClassReturnType.cs" /> |
||||
<Compile Include="Src\Implementations\SystemTypes.cs" /> |
||||
<Compile Include="Src\Implementations\UnknownReturnType.cs" /> |
||||
<Compile Include="Src\Interfaces\ExplicitInterfaceImplementation.cs" /> |
||||
<Compile Include="Src\Interfaces\ICompletionEntry.cs" /> |
||||
<Compile Include="Src\Interfaces\IDomProgressMonitor.cs" /> |
||||
<Compile Include="Src\Interfaces\IFreezable.cs" /> |
||||
<Compile Include="Src\Interfaces\IUsingScope.cs" /> |
||||
<Compile Include="Src\LazyList.cs" /> |
||||
<Compile Include="Src\NRefactoryResolver\CodeSnippetConverter.cs" /> |
||||
<Compile Include="Src\NRefactoryResolver\CSharpToVBNetConvertVisitor.cs" /> |
||||
<Compile Include="Src\NRefactoryResolver\InferredReturnType.cs" /> |
||||
<Compile Include="Src\NRefactoryResolver\LambdaParameterReturnType.cs" /> |
||||
<Compile Include="Src\NRefactoryResolver\LambdaReturnType.cs" /> |
||||
<Compile Include="Src\NRefactoryResolver\NRefactoryASTConvertVisitor.cs" /> |
||||
<Compile Include="Src\NRefactoryResolver\NRefactoryInformationProvider.cs" /> |
||||
<Compile Include="Src\NRefactoryResolver\NRefactoryResolver.cs" /> |
||||
<Compile Include="Src\NRefactoryResolver\ResolveVisitor.cs" /> |
||||
<Compile Include="Src\NRefactoryResolver\TypeVisitor.cs" /> |
||||
<Compile Include="Src\NRefactoryResolver\VBNetToCSharpConvertVisitor.cs" /> |
||||
<Compile Include="Src\ParameterListComparer.cs" /> |
||||
<Compile Include="Src\ProjectContent\DomAssemblyName.cs" /> |
||||
<Compile Include="Src\ReadOnlyDictionary.cs" /> |
||||
<Compile Include="Src\Refactoring\CodeGeneratorOptions.cs" /> |
||||
<Compile Include="Src\Refactoring\CSharpCodeGenerator.cs" /> |
||||
<Compile Include="Src\Refactoring\TextFinder.cs" /> |
||||
<Compile Include="Src\Refactoring\VBNetCodeGenerator.cs" /> |
||||
<Compile Include="Src\ReflectionLayer\DomPersistence.cs" /> |
||||
<Compile Include="Src\ReflectionLayer\ReflectionClass.cs" /> |
||||
<Compile Include="Src\ReflectionLayer\ReflectionEvent.cs" /> |
||||
<Compile Include="Src\ReflectionLayer\ReflectionField.cs" /> |
||||
<Compile Include="Src\ReflectionLayer\ReflectionMethod.cs" /> |
||||
<Compile Include="Src\ReflectionLayer\ReflectionParameter.cs" /> |
||||
<Compile Include="Src\ReflectionLayer\ReflectionProperty.cs" /> |
||||
<Compile Include="Src\ReflectionLayer\ReflectionReturnType.cs" /> |
||||
<Compile Include="Src\ExpressionContext.cs" /> |
||||
<Compile Include="Src\FilePosition.cs" /> |
||||
<Compile Include="Src\FoldingRegion.cs" /> |
||||
<Compile Include="Src\IComment.cs" /> |
||||
<Compile Include="Src\ReflectionLayer\ReflectionTypeNameSyntaxError.cs" /> |
||||
<Compile Include="Src\SignatureComparer.cs" /> |
||||
<Compile Include="Src\VBNet\IVBNetOptionProvider.cs" /> |
||||
<Compile Include="Src\VBNet\VBNetCompilationUnit.cs" /> |
||||
<Compile Include="Src\VBNet\VBNetExpressionFinder.cs" /> |
||||
<Compile Include="Src\XmlDoc.cs" /> |
||||
<Compile Include="Src\Tag.cs" /> |
||||
<Compile Include="Src\ResolveResult.cs" /> |
||||
<Compile Include="Src\MemberLookupHelper.cs" /> |
||||
<Compile Include="Src\LanguageProperties.cs" /> |
||||
<Compile Include="Src\IResolver.cs" /> |
||||
<Compile Include="Src\IExpressionFinder.cs" /> |
||||
<Compile Include="Src\Interfaces\ClassType.cs" /> |
||||
<Compile Include="Src\Interfaces\IAttribute.cs" /> |
||||
<Compile Include="Src\Interfaces\IClass.cs" /> |
||||
<Compile Include="Src\Interfaces\ICompilationUnit.cs" /> |
||||
<Compile Include="Src\Interfaces\IEntity.cs" /> |
||||
<Compile Include="Src\Interfaces\IEvent.cs" /> |
||||
<Compile Include="Src\Interfaces\IField.cs" /> |
||||
<Compile Include="Src\Interfaces\IMember.cs" /> |
||||
<Compile Include="Src\Interfaces\IMethod.cs" /> |
||||
<Compile Include="Src\Interfaces\IParameter.cs" /> |
||||
<Compile Include="Src\Interfaces\IProperty.cs" /> |
||||
<Compile Include="Src\Interfaces\IReturnType.cs" /> |
||||
<Compile Include="Src\Interfaces\IUsing.cs" /> |
||||
<Compile Include="Src\Interfaces\ModifierEnum.cs" /> |
||||
<Compile Include="Src\Interfaces\ParameterModifiers.cs" /> |
||||
<Compile Include="Src\Interfaces\Region.cs" /> |
||||
<Compile Include="Src\Interfaces\ITypeParameter.cs" /> |
||||
<Compile Include="Src\ProjectContent\DefaultProjectContent.cs" /> |
||||
<Compile Include="Src\ProjectContent\IProjectContent.cs" /> |
||||
<Compile Include="Src\ProjectContent\ReflectionProjectContent.cs" /> |
||||
<Compile Include="Src\LoggingService.cs" /> |
||||
<Compile Include="Src\ProjectContent\ProjectContentRegistry.cs" /> |
||||
<Compile Include="Src\FusionNative.cs" /> |
||||
<Compile Include="Src\DiffUtility.cs" /> |
||||
<Compile Include="Src\ProjectContent\ParseInformation.cs" /> |
||||
<Compile Include="Src\HostCallback.cs" /> |
||||
<Compile Include="Src\Refactoring\CodeGenerator.cs" /> |
||||
<Compile Include="Src\Refactoring\IRefactoringDocument.cs" /> |
||||
<Compile Include="Src\ClassFinder.cs" /> |
||||
<Compile Include="Src\Refactoring\NRefactoryCodeGenerator.cs" /> |
||||
<Compile Include="Src\Refactoring\RefactoringProvider.cs" /> |
||||
<Compile Include="Src\Refactoring\NRefactoryRefactoringProvider.cs" /> |
||||
<Compile Include="Src\GacInterop.cs" /> |
||||
<Compile Include="Src\CtrlSpaceResolveHelper.cs" /> |
||||
<Compile Include="Src\CSharp\CSharpAmbience.cs" /> |
||||
<Compile Include="Src\Ambience.cs" /> |
||||
<Compile Include="Src\CSharp\ExpressionFinder.cs" /> |
||||
<Compile Include="Src\VBNet\VBNetAmbience.cs" /> |
||||
<Compile Include="Src\EasyCodeDom.cs" /> |
||||
</ItemGroup> |
||||
<ItemGroup> |
||||
<Folder Include="Configuration" /> |
||||
<Folder Include="Src" /> |
||||
<Folder Include="Src\Implementations" /> |
||||
<Folder Include="Src\NRefactoryResolver" /> |
||||
<Folder Include="Src\ReflectionLayer" /> |
||||
<Folder Include="Src\Interfaces" /> |
||||
<Folder Include="Src\ProjectContent" /> |
||||
<Folder Include="Src\Refactoring" /> |
||||
<Folder Include="Src\CSharp" /> |
||||
<Folder Include="Src\VBNet" /> |
||||
</ItemGroup> |
||||
<ItemGroup> |
||||
<ProjectReference Include="..\..\..\Decompiler\lib\NRefactory\Project\NRefactory.csproj"> |
||||
<Project>{3A9AE6AA-BC07-4A2F-972C-581E3AE2F195}</Project> |
||||
<Name>NRefactory</Name> |
||||
</ProjectReference> |
||||
<ProjectReference Include="..\..\..\Mono.Cecil\Mono.Cecil.csproj"> |
||||
<Project>{D68133BD-1E63-496E-9EDE-4FBDBF77B486}</Project> |
||||
<Name>Mono.Cecil</Name> |
||||
</ProjectReference> |
||||
</ItemGroup> |
||||
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.Targets" /> |
||||
</Project> |
||||
@ -0,0 +1,242 @@
@@ -0,0 +1,242 @@
|
||||
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
|
||||
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
|
||||
|
||||
using System; |
||||
|
||||
namespace ICSharpCode.SharpDevelop.Dom |
||||
{ |
||||
[Flags] |
||||
public enum ConversionFlags |
||||
{ |
||||
/// <summary>
|
||||
/// Convert only the name.
|
||||
/// </summary>
|
||||
None = 0, |
||||
/// <summary>
|
||||
/// Show the parameter list
|
||||
/// </summary>
|
||||
ShowParameterList = 1, |
||||
/// <summary>
|
||||
/// Show names for parameters
|
||||
/// </summary>
|
||||
ShowParameterNames = 2, |
||||
/// <summary>
|
||||
/// Show the accessibility (private, public, etc.)
|
||||
/// </summary>
|
||||
ShowAccessibility = 4, |
||||
/// <summary>
|
||||
/// Show the definition key word (class, struct, Sub, Function, etc.)
|
||||
/// </summary>
|
||||
ShowDefinitionKeyWord = 8, |
||||
/// <summary>
|
||||
/// Show the fully qualified name for the member
|
||||
/// </summary>
|
||||
UseFullyQualifiedMemberNames = 0x10, |
||||
/// <summary>
|
||||
/// Show modifiers (virtual, override, etc.)
|
||||
/// </summary>
|
||||
ShowModifiers = 0x20, |
||||
/// <summary>
|
||||
/// Show the inheritance declaration
|
||||
/// </summary>
|
||||
ShowInheritanceList = 0x40, |
||||
|
||||
IncludeHtmlMarkup = 0x80, |
||||
/// <summary>
|
||||
/// Show the return type
|
||||
/// </summary>
|
||||
ShowReturnType = 0x100, |
||||
/// <summary>
|
||||
/// Use fully qualified names for return type and parameters.
|
||||
/// </summary>
|
||||
UseFullyQualifiedTypeNames = 0x200, |
||||
/// <summary>
|
||||
/// Include opening brace (or equivalent) for methods or classes;
|
||||
/// or semicolon (or equivalent) for field, events.
|
||||
/// For properties, a block indicating if there is a getter/setter is included.
|
||||
/// </summary>
|
||||
IncludeBody = 0x400, |
||||
/// <summary>
|
||||
/// Show the list of type parameters on method and class declarations.
|
||||
/// Type arguments for parameter/return types are always shown.
|
||||
/// </summary>
|
||||
ShowTypeParameterList = 0x800, |
||||
|
||||
StandardConversionFlags = ShowParameterNames | |
||||
ShowAccessibility | |
||||
ShowParameterList | |
||||
ShowReturnType | |
||||
ShowModifiers | |
||||
ShowTypeParameterList | |
||||
ShowDefinitionKeyWord, |
||||
|
||||
All = 0xfff, |
||||
} |
||||
|
||||
public interface IAmbience |
||||
{ |
||||
ConversionFlags ConversionFlags { |
||||
get; |
||||
set; |
||||
} |
||||
|
||||
string Convert(IClass c); |
||||
string ConvertEnd(IClass c); |
||||
|
||||
string Convert(IEntity e); |
||||
|
||||
string Convert(IField field); |
||||
string Convert(IProperty property); |
||||
string Convert(IEvent e); |
||||
|
||||
string Convert(IMethod m); |
||||
string ConvertEnd(IMethod m); |
||||
|
||||
string Convert(IParameter param); |
||||
string Convert(IReturnType returnType); |
||||
|
||||
string ConvertAccessibility(ModifierEnum accessibility); |
||||
|
||||
string WrapAttribute(string attribute); |
||||
string WrapComment(string comment); |
||||
|
||||
string GetIntrinsicTypeName(string dotNetTypeName); |
||||
} |
||||
|
||||
public abstract class AbstractAmbience : IAmbience |
||||
{ |
||||
#if DEBUG
|
||||
int ownerThread = System.Threading.Thread.CurrentThread.ManagedThreadId; |
||||
#endif
|
||||
|
||||
[System.Diagnostics.Conditional("DEBUG")] |
||||
protected void CheckThread() |
||||
{ |
||||
#if DEBUG
|
||||
if (ownerThread != System.Threading.Thread.CurrentThread.ManagedThreadId) |
||||
throw new InvalidOperationException("Ambience may only be used by the thread that created it"); |
||||
#endif
|
||||
} |
||||
|
||||
ConversionFlags conversionFlags = ConversionFlags.StandardConversionFlags; |
||||
|
||||
public ConversionFlags ConversionFlags { |
||||
get { |
||||
return conversionFlags; |
||||
} |
||||
set { |
||||
CheckThread(); |
||||
conversionFlags = value; |
||||
} |
||||
} |
||||
|
||||
public bool ShowReturnType { |
||||
get { |
||||
return (conversionFlags & ConversionFlags.ShowReturnType) == ConversionFlags.ShowReturnType; |
||||
} |
||||
} |
||||
|
||||
public bool ShowAccessibility { |
||||
get { |
||||
return (conversionFlags & ConversionFlags.ShowAccessibility) == ConversionFlags.ShowAccessibility; |
||||
} |
||||
} |
||||
|
||||
public bool ShowParameterNames { |
||||
get { |
||||
return (conversionFlags & ConversionFlags.ShowParameterNames) == ConversionFlags.ShowParameterNames; |
||||
} |
||||
} |
||||
|
||||
public bool UseFullyQualifiedTypeNames { |
||||
get { |
||||
return (conversionFlags & ConversionFlags.UseFullyQualifiedTypeNames) == ConversionFlags.UseFullyQualifiedTypeNames; |
||||
} |
||||
} |
||||
|
||||
public bool ShowDefinitionKeyWord { |
||||
get { |
||||
return (conversionFlags & ConversionFlags.ShowDefinitionKeyWord) == ConversionFlags.ShowDefinitionKeyWord; |
||||
} |
||||
} |
||||
|
||||
public bool ShowParameterList { |
||||
get { |
||||
return (conversionFlags & ConversionFlags.ShowParameterList) == ConversionFlags.ShowParameterList; |
||||
} |
||||
} |
||||
|
||||
public bool ShowModifiers { |
||||
get { |
||||
return (conversionFlags & ConversionFlags.ShowModifiers) == ConversionFlags.ShowModifiers; |
||||
} |
||||
} |
||||
|
||||
public bool ShowInheritanceList { |
||||
get { |
||||
return (conversionFlags & ConversionFlags.ShowInheritanceList) == ConversionFlags.ShowInheritanceList; |
||||
} |
||||
} |
||||
|
||||
public bool IncludeHtmlMarkup { |
||||
get { |
||||
return (conversionFlags & ConversionFlags.IncludeHtmlMarkup) == ConversionFlags.IncludeHtmlMarkup; |
||||
} |
||||
} |
||||
|
||||
public bool UseFullyQualifiedMemberNames { |
||||
get { |
||||
return (conversionFlags & ConversionFlags.UseFullyQualifiedMemberNames) == ConversionFlags.UseFullyQualifiedMemberNames; |
||||
} |
||||
} |
||||
|
||||
public bool IncludeBody { |
||||
get { |
||||
return (conversionFlags & ConversionFlags.IncludeBody) == ConversionFlags.IncludeBody; |
||||
} |
||||
} |
||||
|
||||
public bool ShowTypeParameterList { |
||||
get { |
||||
return (conversionFlags & ConversionFlags.ShowTypeParameterList) == ConversionFlags.ShowTypeParameterList; |
||||
} |
||||
} |
||||
|
||||
public abstract string Convert(IClass c); |
||||
public abstract string ConvertEnd(IClass c); |
||||
public abstract string Convert(IField c); |
||||
public abstract string Convert(IProperty property); |
||||
public abstract string Convert(IEvent e); |
||||
public abstract string Convert(IMethod m); |
||||
public abstract string ConvertEnd(IMethod m); |
||||
public abstract string Convert(IParameter param); |
||||
public abstract string Convert(IReturnType returnType); |
||||
|
||||
public virtual string Convert(IEntity entity) |
||||
{ |
||||
if (entity == null) |
||||
throw new ArgumentNullException("entity"); |
||||
IClass c = entity as IClass; |
||||
if (c != null) |
||||
return Convert(c); |
||||
IMethod m = entity as IMethod; |
||||
if (m != null) |
||||
return Convert(m); |
||||
IField f = entity as IField; |
||||
if (f != null) |
||||
return Convert(f); |
||||
IProperty p = entity as IProperty; |
||||
if (p != null) |
||||
return Convert(p); |
||||
IEvent e = entity as IEvent; |
||||
if (e != null) |
||||
return Convert(e); |
||||
return entity.ToString(); |
||||
} |
||||
|
||||
public abstract string WrapAttribute(string attribute); |
||||
public abstract string WrapComment(string comment); |
||||
public abstract string GetIntrinsicTypeName(string dotNetTypeName); |
||||
public abstract string ConvertAccessibility(ModifierEnum accessibility); |
||||
} |
||||
} |
||||
@ -0,0 +1,52 @@
@@ -0,0 +1,52 @@
|
||||
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
|
||||
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
|
||||
|
||||
using System; |
||||
using System.Collections.Generic; |
||||
|
||||
namespace ICSharpCode.SharpDevelop.Dom |
||||
{ |
||||
/// <summary>
|
||||
/// This class is used to prevent stack overflows by representing a 'busy' flag
|
||||
/// that prevents reentrance when another call is running.
|
||||
/// However, using a simple 'bool busy' is not thread-safe, so we use a
|
||||
/// thread-static BusyManager.
|
||||
/// </summary>
|
||||
sealed class BusyManager |
||||
{ |
||||
public struct BusyLock : IDisposable |
||||
{ |
||||
public static readonly BusyLock Failed = new BusyLock(null); |
||||
|
||||
readonly BusyManager manager; |
||||
|
||||
public BusyLock(BusyManager manager) |
||||
{ |
||||
this.manager = manager; |
||||
} |
||||
|
||||
public bool Success { |
||||
get { return manager != null; } |
||||
} |
||||
|
||||
public void Dispose() |
||||
{ |
||||
if (manager != null) { |
||||
manager.activeObjects.RemoveAt(manager.activeObjects.Count - 1); |
||||
} |
||||
} |
||||
} |
||||
|
||||
readonly List<object> activeObjects = new List<object>(); |
||||
|
||||
public BusyLock Enter(object obj) |
||||
{ |
||||
for (int i = 0; i < activeObjects.Count; i++) { |
||||
if (activeObjects[i] == obj) |
||||
return BusyLock.Failed; |
||||
} |
||||
activeObjects.Add(obj); |
||||
return new BusyLock(this); |
||||
} |
||||
} |
||||
} |
||||
@ -0,0 +1,606 @@
@@ -0,0 +1,606 @@
|
||||
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
|
||||
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
|
||||
|
||||
using System; |
||||
using System.Collections; |
||||
using System.Collections.Generic; |
||||
using System.Text; |
||||
using System.Linq; |
||||
|
||||
namespace ICSharpCode.SharpDevelop.Dom.CSharp |
||||
{ |
||||
public class CSharpAmbience : AbstractAmbience |
||||
{ |
||||
public static IDictionary<string, string> TypeConversionTable { |
||||
get { return ICSharpCode.NRefactory.Ast.TypeReference.PrimitiveTypesCSharpReverse; } |
||||
} |
||||
|
||||
bool ModifierIsSet(ModifierEnum modifier, ModifierEnum query) |
||||
{ |
||||
return (modifier & query) == query; |
||||
} |
||||
|
||||
public override string ConvertAccessibility(ModifierEnum accessibility) |
||||
{ |
||||
if (ShowAccessibility) { |
||||
if (ModifierIsSet(accessibility, ModifierEnum.Public)) { |
||||
return "public "; |
||||
} else if (ModifierIsSet(accessibility, ModifierEnum.Private)) { |
||||
return "private "; |
||||
} else if (ModifierIsSet(accessibility, ModifierEnum.ProtectedAndInternal)) { |
||||
return "protected internal "; |
||||
} else if (ModifierIsSet(accessibility, ModifierEnum.Internal)) { |
||||
return "internal "; |
||||
} else if (ModifierIsSet(accessibility, ModifierEnum.Protected)) { |
||||
return "protected "; |
||||
} |
||||
} |
||||
|
||||
return string.Empty; |
||||
} |
||||
|
||||
string GetModifier(IEntity decoration) |
||||
{ |
||||
string ret = ""; |
||||
|
||||
if (IncludeHtmlMarkup) { |
||||
ret += "<i>"; |
||||
} |
||||
|
||||
if (decoration.IsStatic) { |
||||
ret += "static "; |
||||
} else if (decoration.IsSealed) { |
||||
ret += "sealed "; |
||||
} else if (decoration.IsVirtual) { |
||||
ret += "virtual "; |
||||
} else if (decoration.IsOverride) { |
||||
ret += "override "; |
||||
} else if (decoration.IsNew) { |
||||
ret += "new "; |
||||
} |
||||
|
||||
if (IncludeHtmlMarkup) { |
||||
ret += "</i>"; |
||||
} |
||||
|
||||
return ret; |
||||
} |
||||
|
||||
public override string Convert(IClass c) |
||||
{ |
||||
CheckThread(); |
||||
|
||||
StringBuilder builder = new StringBuilder(); |
||||
|
||||
builder.Append(ConvertAccessibility(c.Modifiers)); |
||||
|
||||
if (IncludeHtmlMarkup) { |
||||
builder.Append("<i>"); |
||||
} |
||||
|
||||
if (ShowModifiers) { |
||||
if (c.IsStatic) { |
||||
builder.Append("static "); |
||||
} else if (c.IsSealed) { |
||||
switch (c.ClassType) { |
||||
case ClassType.Delegate: |
||||
case ClassType.Struct: |
||||
case ClassType.Enum: |
||||
break; |
||||
|
||||
default: |
||||
builder.Append("sealed "); |
||||
break; |
||||
} |
||||
} else if (c.IsAbstract && c.ClassType != ClassType.Interface) { |
||||
builder.Append("abstract "); |
||||
} |
||||
#if DEBUG
|
||||
if (c.HasCompoundClass) |
||||
builder.Append("multiple_parts "); |
||||
if (c is CompoundClass) { |
||||
builder.Append("compound{"); |
||||
builder.Append(string.Join(",", (c as CompoundClass).Parts.Select(p => p.CompilationUnit.FileName).ToArray())); |
||||
builder.Append("} "); |
||||
} |
||||
#endif
|
||||
} |
||||
|
||||
if (IncludeHtmlMarkup) { |
||||
builder.Append("</i>"); |
||||
} |
||||
|
||||
if (ShowDefinitionKeyWord) { |
||||
switch (c.ClassType) { |
||||
case ClassType.Delegate: |
||||
builder.Append("delegate"); |
||||
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 (ShowReturnType && c.ClassType == ClassType.Delegate) { |
||||
foreach(IMethod m in c.Methods) { |
||||
if (m.Name != "Invoke") continue; |
||||
|
||||
builder.Append(Convert(m.ReturnType)); |
||||
builder.Append(' '); |
||||
} |
||||
} |
||||
|
||||
AppendClassNameWithTypeParameters(builder, c, UseFullyQualifiedMemberNames, true, null); |
||||
|
||||
if (ShowParameterList && 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(')'); |
||||
|
||||
} 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(", "); |
||||
} |
||||
} |
||||
} |
||||
} |
||||
|
||||
if (IncludeBody) { |
||||
builder.Append("\n{"); |
||||
} |
||||
|
||||
return builder.ToString(); |
||||
} |
||||
|
||||
void AppendClassNameWithTypeParameters(StringBuilder builder, IClass c, bool fullyQualified, bool isConvertingClassName, IList<IReturnType> typeArguments) |
||||
{ |
||||
if (isConvertingClassName && IncludeHtmlMarkup) { |
||||
builder.Append("<b>"); |
||||
} |
||||
if (fullyQualified) { |
||||
if (c.DeclaringType != null) { |
||||
AppendClassNameWithTypeParameters(builder, c.DeclaringType, fullyQualified, false, typeArguments); |
||||
builder.Append('.'); |
||||
builder.Append(c.Name); |
||||
} else { |
||||
builder.Append(c.FullyQualifiedName); |
||||
} |
||||
} else { |
||||
builder.Append(c.Name); |
||||
} |
||||
if (isConvertingClassName && IncludeHtmlMarkup) { |
||||
builder.Append("</b>"); |
||||
} |
||||
// skip type parameters that belong to declaring types (in DOM, inner classes repeat type parameters from outer classes)
|
||||
int skippedTypeParameterCount = c.DeclaringType != null ? c.DeclaringType.TypeParameters.Count : 0; |
||||
// show type parameters for classes only if ShowTypeParameterList is set; but always show them in other cases.
|
||||
if ((ShowTypeParameterList || !isConvertingClassName) && c.TypeParameters.Count > skippedTypeParameterCount) { |
||||
builder.Append('<'); |
||||
for (int i = skippedTypeParameterCount; i < c.TypeParameters.Count; ++i) { |
||||
if (i > skippedTypeParameterCount) |
||||
builder.Append(", "); |
||||
if (typeArguments != null && i < typeArguments.Count) |
||||
AppendReturnType(builder, typeArguments[i], false); |
||||
else |
||||
builder.Append(ConvertTypeParameter(c.TypeParameters[i])); |
||||
} |
||||
builder.Append('>'); |
||||
} |
||||
} |
||||
|
||||
public override string ConvertEnd(IClass c) |
||||
{ |
||||
return "}"; |
||||
} |
||||
|
||||
public override string Convert(IField field) |
||||
{ |
||||
CheckThread(); |
||||
|
||||
StringBuilder builder = new StringBuilder(); |
||||
|
||||
builder.Append(ConvertAccessibility(field.Modifiers)); |
||||
|
||||
if (IncludeHtmlMarkup) { |
||||
builder.Append("<i>"); |
||||
} |
||||
|
||||
if (ShowModifiers) { |
||||
if (field.IsConst) { |
||||
builder.Append("const "); |
||||
} else if (field.IsStatic) { |
||||
builder.Append("static "); |
||||
} |
||||
|
||||
if (field.IsNew) { |
||||
builder.Append("new "); |
||||
} |
||||
if (field.IsReadonly) { |
||||
builder.Append("readonly "); |
||||
} |
||||
if ((field.Modifiers & ModifierEnum.Volatile) == ModifierEnum.Volatile) { |
||||
builder.Append("volatile "); |
||||
} |
||||
} |
||||
|
||||
if (IncludeHtmlMarkup) { |
||||
builder.Append("</i>"); |
||||
} |
||||
|
||||
if (field.ReturnType != null && ShowReturnType) { |
||||
builder.Append(Convert(field.ReturnType)); |
||||
builder.Append(' '); |
||||
} |
||||
|
||||
AppendTypeNameForFullyQualifiedMemberName(builder, field.DeclaringTypeReference); |
||||
|
||||
if (IncludeHtmlMarkup) { |
||||
builder.Append("<b>"); |
||||
} |
||||
|
||||
builder.Append(field.Name); |
||||
|
||||
if (IncludeHtmlMarkup) { |
||||
builder.Append("</b>"); |
||||
} |
||||
|
||||
if (IncludeBody) builder.Append(";"); |
||||
|
||||
return builder.ToString(); |
||||
} |
||||
|
||||
public override string Convert(IProperty property) |
||||
{ |
||||
CheckThread(); |
||||
|
||||
StringBuilder builder = new StringBuilder(); |
||||
|
||||
builder.Append(ConvertAccessibility(property.Modifiers)); |
||||
|
||||
if (ShowModifiers) { |
||||
builder.Append(GetModifier(property)); |
||||
} |
||||
|
||||
if (property.ReturnType != null && ShowReturnType) { |
||||
builder.Append(Convert(property.ReturnType)); |
||||
builder.Append(' '); |
||||
} |
||||
|
||||
AppendTypeNameForFullyQualifiedMemberName(builder, property.DeclaringTypeReference); |
||||
|
||||
if (property.IsIndexer) { |
||||
builder.Append("this"); |
||||
} else { |
||||
if (IncludeHtmlMarkup) { |
||||
builder.Append("<b>"); |
||||
} |
||||
builder.Append(property.Name); |
||||
if (IncludeHtmlMarkup) { |
||||
builder.Append("</b>"); |
||||
} |
||||
} |
||||
|
||||
if (property.Parameters.Count > 0 && ShowParameterList) { |
||||
builder.Append(property.IsIndexer ? '[' : '('); |
||||
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(property.IsIndexer ? ']' : ')'); |
||||
} |
||||
|
||||
if (IncludeBody) { |
||||
builder.Append(" { "); |
||||
|
||||
if (property.CanGet) { |
||||
builder.Append("get; "); |
||||
} |
||||
if (property.CanSet) { |
||||
builder.Append("set; "); |
||||
} |
||||
|
||||
builder.Append(" } "); |
||||
} |
||||
|
||||
return builder.ToString(); |
||||
} |
||||
|
||||
public override string Convert(IEvent e) |
||||
{ |
||||
CheckThread(); |
||||
|
||||
StringBuilder builder = new StringBuilder(); |
||||
|
||||
builder.Append(ConvertAccessibility(e.Modifiers)); |
||||
|
||||
if (ShowModifiers) { |
||||
builder.Append(GetModifier(e)); |
||||
} |
||||
|
||||
if (ShowDefinitionKeyWord) { |
||||
builder.Append("event "); |
||||
} |
||||
|
||||
if (e.ReturnType != null && ShowReturnType) { |
||||
builder.Append(Convert(e.ReturnType)); |
||||
builder.Append(' '); |
||||
} |
||||
|
||||
AppendTypeNameForFullyQualifiedMemberName(builder, e.DeclaringTypeReference); |
||||
|
||||
if (IncludeHtmlMarkup) { |
||||
builder.Append("<b>"); |
||||
} |
||||
|
||||
builder.Append(e.Name); |
||||
|
||||
if (IncludeHtmlMarkup) { |
||||
builder.Append("</b>"); |
||||
} |
||||
|
||||
if (IncludeBody) builder.Append(";"); |
||||
|
||||
return builder.ToString(); |
||||
} |
||||
|
||||
public override string Convert(IMethod m) |
||||
{ |
||||
CheckThread(); |
||||
|
||||
StringBuilder builder = new StringBuilder(); |
||||
builder.Append(ConvertAccessibility(m.Modifiers)); |
||||
|
||||
if (ShowModifiers) { |
||||
builder.Append(GetModifier(m)); |
||||
} |
||||
|
||||
if (!m.IsConstructor && m.ReturnType != null && ShowReturnType) { |
||||
builder.Append(Convert(m.ReturnType)); |
||||
builder.Append(' '); |
||||
} |
||||
|
||||
AppendTypeNameForFullyQualifiedMemberName(builder, m.DeclaringTypeReference); |
||||
|
||||
if (IncludeHtmlMarkup) { |
||||
builder.Append("<b>"); |
||||
} |
||||
|
||||
if (m.IsConstructor && m.DeclaringType != null) { |
||||
builder.Append(m.DeclaringType.Name); |
||||
} else { |
||||
builder.Append(m.Name); |
||||
} |
||||
|
||||
if (IncludeHtmlMarkup) { |
||||
builder.Append("</b>"); |
||||
} |
||||
|
||||
if (ShowTypeParameterList && m.TypeParameters.Count > 0) { |
||||
builder.Append('<'); |
||||
for (int i = 0; i < m.TypeParameters.Count; ++i) { |
||||
if (i > 0) builder.Append(", "); |
||||
builder.Append(ConvertTypeParameter(m.TypeParameters[i])); |
||||
} |
||||
builder.Append('>'); |
||||
} |
||||
|
||||
if (ShowParameterList) { |
||||
builder.Append("("); |
||||
if (IncludeHtmlMarkup) builder.Append("<br>"); |
||||
|
||||
if (m.IsExtensionMethod) builder.Append("this "); |
||||
|
||||
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 (IncludeBody) { |
||||
if (m.DeclaringType != null) { |
||||
if (m.DeclaringType.ClassType == ClassType.Interface) { |
||||
builder.Append(";"); |
||||
} else { |
||||
builder.Append(" {"); |
||||
} |
||||
} else { |
||||
builder.Append(" {"); |
||||
} |
||||
} |
||||
return builder.ToString(); |
||||
} |
||||
|
||||
void AppendTypeNameForFullyQualifiedMemberName(StringBuilder builder, IReturnType declaringType) |
||||
{ |
||||
if (UseFullyQualifiedMemberNames && declaringType != null) { |
||||
AppendReturnType(builder, declaringType, true); |
||||
builder.Append('.'); |
||||
} |
||||
} |
||||
|
||||
string ConvertTypeParameter(ITypeParameter tp) |
||||
{ |
||||
if (tp.BoundTo != null) |
||||
return Convert(tp.BoundTo); |
||||
else |
||||
return tp.Name; |
||||
} |
||||
|
||||
public override string ConvertEnd(IMethod m) |
||||
{ |
||||
return "}"; |
||||
} |
||||
|
||||
public override string Convert(IReturnType returnType) |
||||
{ |
||||
CheckThread(); |
||||
|
||||
if (returnType == null) { |
||||
return String.Empty; |
||||
} |
||||
|
||||
returnType = returnType.GetDirectReturnType(); |
||||
|
||||
StringBuilder builder = new StringBuilder(); |
||||
|
||||
AppendReturnType(builder, returnType, false); |
||||
|
||||
return builder.ToString(); |
||||
} |
||||
|
||||
void AppendReturnType(StringBuilder builder, IReturnType returnType, bool forceFullyQualifiedName) |
||||
{ |
||||
IReturnType arrayReturnType = returnType; |
||||
returnType = GetElementType(returnType); |
||||
|
||||
if (returnType == null) |
||||
return; |
||||
|
||||
string fullName = returnType.FullyQualifiedName; |
||||
string shortName; |
||||
bool isConstructedType = returnType.IsConstructedReturnType; |
||||
if (fullName != null && !isConstructedType && TypeConversionTable.TryGetValue(fullName, out shortName)) { |
||||
builder.Append(shortName); |
||||
} else { |
||||
IClass c = returnType.GetUnderlyingClass(); |
||||
|
||||
if (c != null) { |
||||
IList<IReturnType> ta = isConstructedType ? returnType.CastToConstructedReturnType().TypeArguments : null; |
||||
AppendClassNameWithTypeParameters(builder, c, forceFullyQualifiedName || UseFullyQualifiedTypeNames, false, ta); |
||||
} else { |
||||
if (UseFullyQualifiedTypeNames || forceFullyQualifiedName) { |
||||
builder.Append(fullName); |
||||
} else { |
||||
builder.Append(returnType.Name); |
||||
} |
||||
if (isConstructedType) { |
||||
builder.Append('<'); |
||||
IList<IReturnType> ta = returnType.CastToConstructedReturnType().TypeArguments; |
||||
for (int i = 0; i < ta.Count; ++i) { |
||||
if (i > 0) builder.Append(", "); |
||||
AppendReturnType(builder, ta[i], false); |
||||
} |
||||
builder.Append('>'); |
||||
} |
||||
} |
||||
} |
||||
|
||||
UnpackArrayType(builder, arrayReturnType); |
||||
} |
||||
|
||||
static IReturnType GetElementType(IReturnType potentialArrayType) |
||||
{ |
||||
if (potentialArrayType == null) |
||||
return null; |
||||
ArrayReturnType result; |
||||
while ((result = potentialArrayType.CastToArrayReturnType()) != null) { |
||||
potentialArrayType = result.ArrayElementType; |
||||
} |
||||
return potentialArrayType; |
||||
} |
||||
|
||||
static void UnpackArrayType(StringBuilder builder, IReturnType returnType) |
||||
{ |
||||
if (returnType.IsArrayReturnType) { |
||||
builder.Append('['); |
||||
int dimensions = returnType.CastToArrayReturnType().ArrayDimensions; |
||||
for (int i = 1; i < dimensions; ++i) { |
||||
builder.Append(','); |
||||
} |
||||
builder.Append(']'); |
||||
UnpackArrayType(builder, returnType.CastToArrayReturnType().ArrayElementType); |
||||
} |
||||
} |
||||
|
||||
public override string Convert(IParameter param) |
||||
{ |
||||
CheckThread(); |
||||
|
||||
StringBuilder builder = new StringBuilder(); |
||||
|
||||
if (IncludeHtmlMarkup) { |
||||
builder.Append("<i>"); |
||||
} |
||||
|
||||
if (param.IsRef) { |
||||
builder.Append("ref "); |
||||
} else if (param.IsOut) { |
||||
builder.Append("out "); |
||||
} else if (param.IsParams) { |
||||
builder.Append("params "); |
||||
} |
||||
|
||||
if (IncludeHtmlMarkup) { |
||||
builder.Append("</i>"); |
||||
} |
||||
|
||||
builder.Append(Convert(param.ReturnType)); |
||||
|
||||
if (ShowParameterNames) { |
||||
builder.Append(' '); |
||||
builder.Append(param.Name); |
||||
} |
||||
return builder.ToString(); |
||||
} |
||||
|
||||
public override string WrapAttribute(string attribute) |
||||
{ |
||||
return "[" + attribute + "]"; |
||||
} |
||||
|
||||
public override string WrapComment(string comment) |
||||
{ |
||||
return "// " + comment; |
||||
} |
||||
|
||||
public override string GetIntrinsicTypeName(string dotNetTypeName) |
||||
{ |
||||
string shortName; |
||||
if (TypeConversionTable.TryGetValue(dotNetTypeName, out shortName)) { |
||||
return shortName; |
||||
} |
||||
return dotNetTypeName; |
||||
} |
||||
|
||||
} |
||||
} |
||||
@ -0,0 +1,55 @@
@@ -0,0 +1,55 @@
|
||||
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
|
||||
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
|
||||
|
||||
using System; |
||||
using ICSharpCode.SharpDevelop.Dom; |
||||
|
||||
namespace ICSharpCode.SharpDevelop.Dom.CSharp |
||||
{ |
||||
public static class CSharpExpressionContext |
||||
{ |
||||
/// <summary>The context is the body of a property declaration.</summary>
|
||||
/// <example>string Name { *expr* }</example>
|
||||
public readonly static ExpressionContext PropertyDeclaration = new ExpressionContext.DefaultExpressionContext("PropertyDeclaration"); |
||||
|
||||
/// <summary>The context is the body of a property declaration inside an interface.</summary>
|
||||
/// <example>string Name { *expr* }</example>
|
||||
public readonly static ExpressionContext InterfacePropertyDeclaration = new ExpressionContext.DefaultExpressionContext("InterfacePropertyDeclaration"); |
||||
|
||||
/// <summary>The context is the body of a event declaration.</summary>
|
||||
/// <example>event EventHandler NameChanged { *expr* }</example>
|
||||
public readonly static ExpressionContext EventDeclaration = new ExpressionContext.DefaultExpressionContext("EventDeclaration"); |
||||
|
||||
/// <summary>The context is after the type parameters of a type/method declaration.
|
||||
/// The only valid keyword is "where"</summary>
|
||||
/// <example>class <T> *expr*</example>
|
||||
public readonly static ExpressionContext ConstraintsStart = new ExpressionContext.DefaultExpressionContext("ConstraintsStart"); |
||||
|
||||
/// <summary>The context is after the 'where' of a constraints list.</summary>
|
||||
/// <example>class <T> where *expr*</example>
|
||||
public readonly static ExpressionContext Constraints = new ExpressionContext.NonStaticTypeExpressionContext("Constraints", false); |
||||
|
||||
/// <summary>The context is the body of an interface declaration.</summary>
|
||||
public readonly static ExpressionContext InterfaceDeclaration = new ExpressionContext.NonStaticTypeExpressionContext("InterfaceDeclaration", true); |
||||
|
||||
/// <summary>Context expects "base" or "this".</summary>
|
||||
/// <example>public ClassName() : *expr*</example>
|
||||
public readonly static ExpressionContext BaseConstructorCall = new ExpressionContext.DefaultExpressionContext("BaseConstructorCall"); |
||||
|
||||
/// <summary>The first parameter</summary>
|
||||
/// <example>void MethodName(*expr*)</example>
|
||||
public readonly static ExpressionContext FirstParameterType = new ExpressionContext.NonStaticTypeExpressionContext("FirstParameterType", false); |
||||
|
||||
/// <summary>Another parameter</summary>
|
||||
/// <example>void MethodName(..., *expr*)</example>
|
||||
public readonly static ExpressionContext ParameterType = new ExpressionContext.NonStaticTypeExpressionContext("ParameterType", false); |
||||
|
||||
/// <summary>Context expects a fully qualified type name.</summary>
|
||||
/// <example>using Alias = *expr*;</example>
|
||||
public readonly static ExpressionContext FullyQualifiedType = new ExpressionContext.DefaultExpressionContext("FullyQualifiedType"); |
||||
|
||||
/// <summary>Context expects is a property name in an object initializer.</summary>
|
||||
/// <example>new *type* [(args)] { *expr* = ... }</example>
|
||||
public readonly static ExpressionContext ObjectInitializer = new ExpressionContext.DefaultExpressionContext("ObjectInitializer"); |
||||
} |
||||
} |
||||
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,340 @@
@@ -0,0 +1,340 @@
|
||||
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
|
||||
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
|
||||
|
||||
using System; |
||||
using System.Linq; |
||||
using System.Collections.Generic; |
||||
|
||||
namespace ICSharpCode.SharpDevelop.Dom.CSharp |
||||
{ |
||||
/// <summary>
|
||||
/// Implements C# 3.0 overload resolution.
|
||||
/// </summary>
|
||||
public sealed class OverloadResolution |
||||
{ |
||||
private OverloadResolution() {} |
||||
|
||||
public static IMethodOrProperty FindOverload(IEnumerable<IMethodOrProperty> list, |
||||
IReturnType[] arguments, |
||||
bool allowAdditionalArguments, |
||||
bool substituteInferredTypes, |
||||
out bool acceptableMatch) |
||||
{ |
||||
OverloadResolution or = new OverloadResolution(); |
||||
or.candidates = list.Select(m => new Candidate(m)).ToList(); |
||||
or.arguments = arguments; |
||||
or.allowAdditionalArguments = allowAdditionalArguments; |
||||
|
||||
if (or.candidates.Count == 0) |
||||
throw new ArgumentException("at least one candidate is required"); |
||||
|
||||
MemberLookupHelper.Log("OverloadResolution"); |
||||
MemberLookupHelper.Log(" arguments = ", arguments); |
||||
|
||||
or.ConstructExpandedForms(); |
||||
or.InferTypeArguments(); |
||||
or.CheckApplicability(); |
||||
|
||||
Candidate result = or.FindBestCandidate(); |
||||
MemberLookupHelper.Log("Overload resolution finished. Winning candidate = " + result); |
||||
acceptableMatch = result.Status == CandidateStatus.Success; |
||||
if (substituteInferredTypes) |
||||
return result.Method; |
||||
else |
||||
return result.OriginalMethod; |
||||
} |
||||
|
||||
enum CandidateStatus |
||||
{ |
||||
Success, |
||||
WrongParameterCount, |
||||
TypeInferenceFailed, |
||||
NotApplicable |
||||
} |
||||
|
||||
sealed class Candidate |
||||
{ |
||||
public bool IsExpanded; |
||||
public IMethodOrProperty Method; |
||||
public IMethodOrProperty OriginalMethod; |
||||
public CandidateStatus Status = CandidateStatus.Success; |
||||
public int ApplicableArgumentCount; |
||||
|
||||
public IList<IParameter> Parameters { |
||||
get { return Method.Parameters; } |
||||
} |
||||
|
||||
public int TypeParameterCount { |
||||
get { |
||||
IMethod m = Method as IMethod; |
||||
if (m != null) |
||||
return m.TypeParameters.Count; |
||||
else |
||||
return 0; |
||||
} |
||||
} |
||||
|
||||
public Candidate(IMethodOrProperty method) |
||||
{ |
||||
if (method == null) |
||||
throw new ArgumentNullException("method"); |
||||
this.Method = method; |
||||
this.OriginalMethod = method; |
||||
} |
||||
|
||||
public override string ToString() |
||||
{ |
||||
return "[Candidate: " + Method + ", Status=" + Status + "]"; |
||||
} |
||||
} |
||||
|
||||
List<Candidate> candidates; |
||||
IList<IReturnType> arguments; |
||||
bool allowAdditionalArguments; |
||||
|
||||
/// <summary>
|
||||
/// For methods having a params-array as last parameter, expand the params array to
|
||||
/// n parameters of the element type and add those as new candidates.
|
||||
/// Mark candidates with the wrong parameter count as Status.WrongParameterCount.
|
||||
/// </summary>
|
||||
void ConstructExpandedForms() |
||||
{ |
||||
LogStep("Step 1 (Construct expanded forms)"); |
||||
foreach (Candidate candidate in candidates.ToArray()) { |
||||
if (candidate.Status == CandidateStatus.Success) { |
||||
if (candidate.Parameters.Count > 0 && arguments.Count >= candidate.Parameters.Count - 1) { |
||||
IParameter lastParameter = candidate.Parameters[candidate.Parameters.Count - 1]; |
||||
if (lastParameter.IsParams && lastParameter.ReturnType.IsArrayReturnType) { |
||||
// try to construct an expanded form with the correct parameter count
|
||||
IReturnType elementType = lastParameter.ReturnType.CastToArrayReturnType().ArrayElementType; |
||||
IMethodOrProperty expanded = (IMethodOrProperty)candidate.Method.CreateSpecializedMember(); |
||||
expanded.Parameters.RemoveAt(candidate.Parameters.Count - 1); |
||||
int index = 0; |
||||
while (expanded.Parameters.Count < arguments.Count) { |
||||
expanded.Parameters.Add(new DefaultParameter(lastParameter.Name + (index++), elementType, lastParameter.Region)); |
||||
} |
||||
candidates.Add(new Candidate(expanded) { |
||||
IsExpanded = true, |
||||
OriginalMethod = candidate.Method |
||||
}); |
||||
} |
||||
} |
||||
|
||||
if (allowAdditionalArguments) { |
||||
if (candidate.Parameters.Count < arguments.Count) { |
||||
candidate.Status = CandidateStatus.WrongParameterCount; |
||||
} |
||||
} else { |
||||
if (candidate.Parameters.Count != arguments.Count) { |
||||
candidate.Status = CandidateStatus.WrongParameterCount; |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Infer the type arguments for generic methods.
|
||||
/// </summary>
|
||||
void InferTypeArguments() |
||||
{ |
||||
LogStep("Step 2 (Infer type arguments)"); |
||||
foreach (Candidate candidate in candidates) { |
||||
IMethod method = candidate.Method as IMethod; |
||||
if (method != null && method.TypeParameters.Count > 0 |
||||
&& candidate.Status == CandidateStatus.Success) |
||||
{ |
||||
bool success; |
||||
IReturnType[] typeArguments = TypeInference.InferTypeArguments(method, arguments, out success); |
||||
if (!success) { |
||||
candidate.Status = CandidateStatus.TypeInferenceFailed; |
||||
} |
||||
candidate.Method = ApplyTypeArgumentsToMethod(method, typeArguments); |
||||
} |
||||
} |
||||
} |
||||
|
||||
static IMethod ApplyTypeArgumentsToMethod(IMethod genericMethod, IList<IReturnType> typeArguments) |
||||
{ |
||||
if (typeArguments != null && typeArguments.Count > 0) { |
||||
// apply inferred type arguments
|
||||
IMethod method = (IMethod)genericMethod.CreateSpecializedMember(); |
||||
method.ReturnType = ConstructedReturnType.TranslateType(method.ReturnType, typeArguments, true); |
||||
for (int i = 0; i < method.Parameters.Count; ++i) { |
||||
method.Parameters[i].ReturnType = ConstructedReturnType.TranslateType(method.Parameters[i].ReturnType, typeArguments, true); |
||||
} |
||||
for (int i = 0; i < Math.Min(typeArguments.Count, method.TypeParameters.Count); i++) { |
||||
var tp = new BoundTypeParameter(method.TypeParameters[i], method.DeclaringType, method); |
||||
tp.BoundTo = typeArguments[i]; |
||||
method.TypeParameters[i] = tp; |
||||
} |
||||
return method; |
||||
} else { |
||||
return genericMethod; |
||||
} |
||||
} |
||||
|
||||
void CheckApplicability() |
||||
{ |
||||
LogStep("Step 3 (CheckApplicability)"); |
||||
foreach (Candidate candidate in candidates) { |
||||
int c = Math.Min(arguments.Count, candidate.Parameters.Count); |
||||
for (int i = 0; i < c; i++) { |
||||
if (MemberLookupHelper.IsApplicable(arguments[i], candidate.Parameters[i], candidate.Method as IMethod)) |
||||
candidate.ApplicableArgumentCount++; |
||||
} |
||||
if (candidate.Status == CandidateStatus.Success && candidate.ApplicableArgumentCount < arguments.Count) { |
||||
candidate.Status = CandidateStatus.NotApplicable; |
||||
} |
||||
} |
||||
} |
||||
|
||||
Candidate FindBestCandidate() |
||||
{ |
||||
LogStep("Step 4 (FindBestCandidate)"); |
||||
|
||||
// Find a candidate that is better than all other candidates
|
||||
Candidate best = null; |
||||
foreach (Candidate candidate in candidates) { |
||||
if (candidate.Status == CandidateStatus.Success) { |
||||
if (best == null || GetBetterFunctionMember(best, candidate) == 2) { |
||||
best = candidate; |
||||
} |
||||
} |
||||
} |
||||
|
||||
if (best != null) |
||||
return best; |
||||
|
||||
// no successful candidate found:
|
||||
// find the candidate that is nearest to being applicable
|
||||
// first try only candidates with the correct parameter count
|
||||
foreach (Candidate candidate in candidates) { |
||||
if (candidate.Status != CandidateStatus.WrongParameterCount) { |
||||
if (best == null || candidate.ApplicableArgumentCount > best.ApplicableArgumentCount) |
||||
best = candidate; |
||||
} |
||||
} |
||||
if (best != null) |
||||
return best; |
||||
// if all candidates have the wrong parameter count, return the candidate
|
||||
// with the most applicable parameters.
|
||||
best = candidates[0]; |
||||
foreach (Candidate candidate in candidates) { |
||||
if (candidate.ApplicableArgumentCount > best.ApplicableArgumentCount) |
||||
best = candidate; |
||||
} |
||||
return best; |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Gets which function member is better. (§ 14.4.2.2)
|
||||
/// </summary>
|
||||
/// <returns>0 if neither method is better. 1 if c1 is better. 2 if c2 is better.</returns>
|
||||
int GetBetterFunctionMember(Candidate c1, Candidate c2) |
||||
{ |
||||
int length = Math.Min(Math.Min(c1.Parameters.Count, c2.Parameters.Count), arguments.Count); |
||||
bool foundBetterParamIn1 = false; |
||||
bool foundBetterParamIn2 = false; |
||||
for (int i = 0; i < length; i++) { |
||||
if (arguments[i] == null) |
||||
continue; |
||||
int res = MemberLookupHelper.GetBetterConversion(arguments[i], c1.Parameters[i].ReturnType, c2.Parameters[i].ReturnType); |
||||
if (res == 1) foundBetterParamIn1 = true; |
||||
if (res == 2) foundBetterParamIn2 = true; |
||||
} |
||||
if (foundBetterParamIn1 && !foundBetterParamIn2) |
||||
return 1; |
||||
if (foundBetterParamIn2 && !foundBetterParamIn1) |
||||
return 2; |
||||
if (foundBetterParamIn1 && foundBetterParamIn2) |
||||
return 0; // ambigous
|
||||
// If none conversion is better than any other, it is possible that the
|
||||
// expanded parameter lists are the same:
|
||||
for (int i = 0; i < length; i++) { |
||||
if (!object.Equals(c1.Parameters[i].ReturnType, c2.Parameters[i].ReturnType)) { |
||||
// if expanded parameters are not the same, neither function member is better
|
||||
return 0; |
||||
} |
||||
} |
||||
|
||||
// the expanded parameters are the same, apply the tie-breaking rules from the spec:
|
||||
|
||||
// if one method is generic and the other non-generic, the non-generic is better
|
||||
bool m1IsGeneric = c1.TypeParameterCount > 0; |
||||
bool m2IsGeneric = c2.TypeParameterCount > 0; |
||||
if (m1IsGeneric && !m2IsGeneric) return 2; |
||||
if (m2IsGeneric && !m1IsGeneric) return 1; |
||||
|
||||
// for params parameters: non-expanded calls are better
|
||||
if (c1.IsExpanded && !c2.IsExpanded) return 2; |
||||
if (c2.IsExpanded && !c1.IsExpanded) return 1; |
||||
|
||||
// if the number of parameters is different, the one with more parameters is better
|
||||
// this occurs when only when both methods are expanded
|
||||
if (c1.OriginalMethod.Parameters.Count > c2.OriginalMethod.Parameters.Count) return 1; |
||||
if (c2.OriginalMethod.Parameters.Count > c1.OriginalMethod.Parameters.Count) return 2; |
||||
|
||||
IReturnType[] m1ParamTypes = new IReturnType[c1.Parameters.Count]; |
||||
IReturnType[] m2ParamTypes = new IReturnType[c2.Parameters.Count]; |
||||
for (int i = 0; i < m1ParamTypes.Length; i++) { |
||||
m1ParamTypes[i] = c1.Parameters[i].ReturnType; |
||||
m2ParamTypes[i] = c2.Parameters[i].ReturnType; |
||||
} |
||||
return GetMoreSpecific(m1ParamTypes, m2ParamTypes); |
||||
} |
||||
|
||||
|
||||
/// <summary>
|
||||
/// Gets which return type list is more specific.
|
||||
/// § 14.4.2.2: types with generic arguments are less specific than types with fixed arguments
|
||||
/// </summary>
|
||||
/// <returns>0 if both are equally specific, 1 if <paramref name="r"/> is more specific,
|
||||
/// 2 if <paramref name="s"/> is more specific.</returns>
|
||||
static int GetMoreSpecific(IList<IReturnType> r, IList<IReturnType> s) |
||||
{ |
||||
bool foundMoreSpecificParamIn1 = false; |
||||
bool foundMoreSpecificParamIn2 = false; |
||||
int length = Math.Min(r.Count, s.Count); |
||||
for (int i = 0; i < length; i++) { |
||||
int res = GetMoreSpecific(r[i], s[i]); |
||||
if (res == 1) foundMoreSpecificParamIn1 = true; |
||||
if (res == 2) foundMoreSpecificParamIn2 = true; |
||||
} |
||||
if (foundMoreSpecificParamIn1 && !foundMoreSpecificParamIn2) |
||||
return 1; |
||||
if (foundMoreSpecificParamIn2 && !foundMoreSpecificParamIn1) |
||||
return 2; |
||||
return 0; |
||||
} |
||||
|
||||
static int GetMoreSpecific(IReturnType r, IReturnType s) |
||||
{ |
||||
if (r == null && s == null) return 0; |
||||
if (r == null) return 2; |
||||
if (s == null) return 1; |
||||
if (r.IsGenericReturnType && !(s.IsGenericReturnType)) |
||||
return 2; |
||||
if (s.IsGenericReturnType && !(r.IsGenericReturnType)) |
||||
return 1; |
||||
if (r.IsArrayReturnType && s.IsArrayReturnType) |
||||
return GetMoreSpecific(r.CastToArrayReturnType().ArrayElementType, s.CastToArrayReturnType().ArrayElementType); |
||||
if (r.IsConstructedReturnType && s.IsConstructedReturnType) |
||||
return GetMoreSpecific(r.CastToConstructedReturnType().TypeArguments, s.CastToConstructedReturnType().TypeArguments); |
||||
return 0; |
||||
} |
||||
|
||||
[System.Diagnostics.ConditionalAttribute("DEBUG")] |
||||
void LogStep(string title) |
||||
{ |
||||
MemberLookupHelper.Log(" candidates = ", candidates); |
||||
MemberLookupHelper.Log("Overload resolution (" + title + ")"); |
||||
} |
||||
|
||||
[System.Diagnostics.ConditionalAttribute("DEBUG")] |
||||
void Log(string text) |
||||
{ |
||||
MemberLookupHelper.Log(text); |
||||
} |
||||
} |
||||
} |
||||
@ -0,0 +1,564 @@
@@ -0,0 +1,564 @@
|
||||
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
|
||||
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
|
||||
|
||||
using System; |
||||
using System.Collections; |
||||
using System.Collections.Generic; |
||||
using System.Text; |
||||
|
||||
using ICSharpCode.SharpDevelop.Dom.ReflectionLayer; |
||||
using Mono.Cecil; |
||||
using Mono.Collections.Generic; |
||||
|
||||
namespace ICSharpCode.SharpDevelop.Dom |
||||
{ |
||||
public static class CecilReader |
||||
{ |
||||
sealed class DummyAssemblyResolver : IAssemblyResolver |
||||
{ |
||||
public AssemblyDefinition Resolve(AssemblyNameReference name) |
||||
{ |
||||
return null; |
||||
} |
||||
|
||||
public AssemblyDefinition Resolve(string fullName) |
||||
{ |
||||
return null; |
||||
} |
||||
|
||||
public AssemblyDefinition Resolve(AssemblyNameReference name, ReaderParameters parameters) |
||||
{ |
||||
throw new NotImplementedException(); |
||||
} |
||||
|
||||
public AssemblyDefinition Resolve(string fullName, ReaderParameters parameters) |
||||
{ |
||||
throw new NotImplementedException(); |
||||
} |
||||
} |
||||
|
||||
public static ReflectionProjectContent LoadAssembly(string fileName, ProjectContentRegistry registry) |
||||
{ |
||||
if (fileName == null) |
||||
throw new ArgumentNullException("fileName"); |
||||
if (registry == null) |
||||
throw new ArgumentNullException("registry"); |
||||
LoggingService.Info("Cecil: Load from " + fileName); |
||||
AssemblyDefinition asm = AssemblyDefinition.ReadAssembly(fileName, new ReaderParameters { AssemblyResolver = new DummyAssemblyResolver() }); |
||||
List<DomAssemblyName> referencedAssemblies = new List<DomAssemblyName>(); |
||||
foreach (ModuleDefinition module in asm.Modules) { |
||||
foreach (AssemblyNameReference anr in module.AssemblyReferences) { |
||||
referencedAssemblies.Add(new DomAssemblyName(anr.FullName)); |
||||
} |
||||
} |
||||
return new CecilProjectContent(asm.Name.FullName, fileName, referencedAssemblies.ToArray(), asm, registry); |
||||
} |
||||
|
||||
static void AddAttributes(IProjectContent pc, IEntity member, IList<IAttribute> list, ICustomAttributeProvider attributeProvider) |
||||
{ |
||||
if (!attributeProvider.HasCustomAttributes) |
||||
return; |
||||
foreach (CustomAttribute att in attributeProvider.CustomAttributes) { |
||||
DefaultAttribute a = new DefaultAttribute(CreateType(pc, member, att.Constructor.DeclaringType)); |
||||
// Currently Cecil returns string instead of TypeReference for typeof() arguments to attributes
|
||||
try { |
||||
foreach (var argument in att.ConstructorArguments) { |
||||
a.PositionalArguments.Add(GetValue(pc, member, argument)); |
||||
} |
||||
foreach (CustomAttributeNamedArgument entry in att.Properties) { |
||||
// some obfuscated assemblies may contain duplicate named arguments; we'll have to ignore those
|
||||
if (!a.NamedArguments.ContainsKey(entry.Name)) |
||||
a.NamedArguments.Add(entry.Name, GetValue(pc, member, entry.Argument)); |
||||
} |
||||
} catch (InvalidOperationException) { |
||||
// Workaround for Cecil bug. (some types cannot be resolved)
|
||||
} |
||||
list.Add(a); |
||||
} |
||||
} |
||||
|
||||
static object GetValue(IProjectContent pc, IEntity member, CustomAttributeArgument argument) |
||||
{ |
||||
if (argument.Value is TypeReference) |
||||
return CreateType(pc, member, (TypeReference)argument.Value); |
||||
else |
||||
return argument.Value; |
||||
} |
||||
|
||||
static void AddConstraintsFromType(ITypeParameter tp, GenericParameter g) |
||||
{ |
||||
foreach (TypeReference constraint in g.Constraints) { |
||||
if (tp.Method != null) { |
||||
tp.Constraints.Add(CreateType(tp.Class.ProjectContent, tp.Method, constraint)); |
||||
} else { |
||||
tp.Constraints.Add(CreateType(tp.Class.ProjectContent, tp.Class, constraint)); |
||||
} |
||||
} |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Create a SharpDevelop return type from a Cecil type reference.
|
||||
/// </summary>
|
||||
internal static IReturnType CreateType(IProjectContent pc, IEntity member, TypeReference type, ICustomAttributeProvider attributeProvider = null) |
||||
{ |
||||
int typeIndex = 0; |
||||
return CreateType(pc, member, type, attributeProvider, ref typeIndex); |
||||
} |
||||
|
||||
static IReturnType CreateType(IProjectContent pc, IEntity member, TypeReference type, ICustomAttributeProvider attributeProvider, ref int typeIndex) |
||||
{ |
||||
while (type is OptionalModifierType || type is RequiredModifierType) { |
||||
type = ((TypeSpecification)type).ElementType; |
||||
} |
||||
if (type == null) { |
||||
LoggingService.Warn("CecilReader: Null type for: " + member); |
||||
return new VoidReturnType(pc); |
||||
} |
||||
if (type is ByReferenceType) { |
||||
// TODO: Use ByRefRefReturnType
|
||||
return CreateType(pc, member, (type as ByReferenceType).ElementType, attributeProvider, ref typeIndex); |
||||
} else if (type is PointerType) { |
||||
typeIndex++; |
||||
return new PointerReturnType(CreateType(pc, member, (type as PointerType).ElementType, attributeProvider, ref typeIndex)); |
||||
} else if (type is ArrayType) { |
||||
typeIndex++; |
||||
return new ArrayReturnType(pc, CreateType(pc, member, (type as ArrayType).ElementType, attributeProvider, ref typeIndex), (type as ArrayType).Rank); |
||||
} else if (type is GenericInstanceType) { |
||||
GenericInstanceType gType = (GenericInstanceType)type; |
||||
IReturnType baseType = CreateType(pc, member, gType.ElementType, attributeProvider, ref typeIndex); |
||||
IReturnType[] para = new IReturnType[gType.GenericArguments.Count]; |
||||
for (int i = 0; i < para.Length; ++i) { |
||||
typeIndex++; |
||||
para[i] = CreateType(pc, member, gType.GenericArguments[i], attributeProvider, ref typeIndex); |
||||
} |
||||
return new ConstructedReturnType(baseType, para); |
||||
} else if (type is GenericParameter) { |
||||
GenericParameter typeGP = type as GenericParameter; |
||||
if (typeGP.Owner is MethodDefinition) { |
||||
IMethod method = member as IMethod; |
||||
if (method != null) { |
||||
if (typeGP.Position < method.TypeParameters.Count) { |
||||
return new GenericReturnType(method.TypeParameters[typeGP.Position]); |
||||
} |
||||
} |
||||
return new GenericReturnType(new DefaultTypeParameter(method, typeGP.Name, typeGP.Position)); |
||||
} else { |
||||
IClass c = (member is IClass) ? (IClass)member : (member is IMember) ? ((IMember)member).DeclaringType : null; |
||||
if (c != null && typeGP.Position < c.TypeParameters.Count) { |
||||
if (c.TypeParameters[typeGP.Position].Name == type.Name) { |
||||
return new GenericReturnType(c.TypeParameters[typeGP.Position]); |
||||
} |
||||
} |
||||
return new GenericReturnType(new DefaultTypeParameter(c, typeGP.Name, typeGP.Position)); |
||||
} |
||||
} else { |
||||
string name = type.FullName; |
||||
if (name == null) |
||||
throw new ApplicationException("type.FullName returned null. Type: " + type.ToString()); |
||||
|
||||
int typeParameterCount; |
||||
if (name.IndexOf('/') > 0) { |
||||
typeParameterCount = 0; |
||||
StringBuilder newName = new StringBuilder(); |
||||
foreach (string namepart in name.Split('/')) { |
||||
if (newName.Length > 0) |
||||
newName.Append('.'); |
||||
int partTypeParameterCount; |
||||
newName.Append(ReflectionClass.SplitTypeParameterCountFromReflectionName(namepart, out partTypeParameterCount)); |
||||
typeParameterCount += partTypeParameterCount; |
||||
} |
||||
name = newName.ToString(); |
||||
} else { |
||||
name = ReflectionClass.SplitTypeParameterCountFromReflectionName(name, out typeParameterCount); |
||||
} |
||||
|
||||
if (typeParameterCount == 0 && name == "System.Object" && HasDynamicAttribute(attributeProvider, typeIndex)) |
||||
return new DynamicReturnType(pc); |
||||
|
||||
IClass c = pc.GetClass(name, typeParameterCount); |
||||
if (c != null) { |
||||
return c.DefaultReturnType; |
||||
} else { |
||||
// example where name is not found: pointers like System.Char*
|
||||
// or when the class is in a assembly that is not referenced
|
||||
return new GetClassReturnType(pc, name, typeParameterCount); |
||||
} |
||||
} |
||||
} |
||||
|
||||
static bool HasDynamicAttribute(ICustomAttributeProvider attributeProvider, int typeIndex) |
||||
{ |
||||
if (attributeProvider == null || attributeProvider.HasCustomAttributes == false) |
||||
return false; |
||||
foreach (CustomAttribute a in attributeProvider.CustomAttributes) { |
||||
if (a.Constructor.DeclaringType.FullName == "System.Runtime.CompilerServices.DynamicAttribute") { |
||||
if (a.ConstructorArguments.Count == 1) { |
||||
CustomAttributeArgument[] values = a.ConstructorArguments[0].Value as CustomAttributeArgument[]; |
||||
if (values != null && typeIndex < values.Length && values[typeIndex].Value is bool) |
||||
return (bool)values[typeIndex].Value; |
||||
} |
||||
return true; |
||||
} |
||||
} |
||||
return false; |
||||
} |
||||
|
||||
private sealed class CecilProjectContent : ReflectionProjectContent |
||||
{ |
||||
public CecilProjectContent(string fullName, string fileName, DomAssemblyName[] referencedAssemblies, |
||||
AssemblyDefinition assembly, ProjectContentRegistry registry) |
||||
: base(fullName, fileName, referencedAssemblies, registry) |
||||
{ |
||||
foreach (ModuleDefinition module in assembly.Modules) { |
||||
AddTypes(module.Types); |
||||
} |
||||
AddAttributes(this, null, this.AssemblyCompilationUnit.Attributes, assembly); |
||||
InitializeSpecialClasses(); |
||||
this.AssemblyCompilationUnit.Freeze(); |
||||
} |
||||
|
||||
void AddTypes(Collection<TypeDefinition> types) |
||||
{ |
||||
foreach (TypeDefinition td in types) { |
||||
if ((td.Attributes & TypeAttributes.VisibilityMask) == TypeAttributes.Public) { |
||||
string name = td.FullName; |
||||
if (name.Length == 0 || name[0] == '<') |
||||
continue; |
||||
name = ReflectionClass.SplitTypeParameterCountFromReflectionName(name); |
||||
AddClassToNamespaceListInternal(new CecilClass(this.AssemblyCompilationUnit, null, td, name)); |
||||
} |
||||
} |
||||
} |
||||
} |
||||
|
||||
private sealed class CecilClass : DefaultClass |
||||
{ |
||||
public static bool IsDelegate(TypeDefinition type) |
||||
{ |
||||
if (type.BaseType == null) |
||||
return false; |
||||
else |
||||
return type.BaseType.FullName == "System.Delegate" |
||||
|| type.BaseType.FullName == "System.MulticastDelegate"; |
||||
} |
||||
|
||||
protected override bool KeepInheritanceTree { |
||||
get { return true; } |
||||
} |
||||
|
||||
public CecilClass(ICompilationUnit compilationUnit, IClass declaringType, |
||||
TypeDefinition td, string fullName) |
||||
: base(compilationUnit, declaringType) |
||||
{ |
||||
this.FullyQualifiedName = fullName; |
||||
|
||||
AddAttributes(compilationUnit.ProjectContent, this, this.Attributes, td); |
||||
|
||||
// set classtype
|
||||
if (td.IsInterface) { |
||||
this.ClassType = ClassType.Interface; |
||||
} else if (td.IsEnum) { |
||||
this.ClassType = ClassType.Enum; |
||||
} else if (td.IsValueType) { |
||||
this.ClassType = ClassType.Struct; |
||||
} else if (IsDelegate(td)) { |
||||
this.ClassType = ClassType.Delegate; |
||||
} else { |
||||
this.ClassType = ClassType.Class; |
||||
} |
||||
if (td.GenericParameters.Count > 0) { |
||||
foreach (GenericParameter g in td.GenericParameters) { |
||||
this.TypeParameters.Add(new DefaultTypeParameter(this, g.Name, g.Position)); |
||||
} |
||||
int i = 0; |
||||
foreach (GenericParameter g in td.GenericParameters) { |
||||
AddConstraintsFromType(this.TypeParameters[i++], g); |
||||
} |
||||
} |
||||
|
||||
ModifierEnum modifiers = ModifierEnum.None; |
||||
|
||||
if (td.IsSealed) { |
||||
modifiers |= ModifierEnum.Sealed; |
||||
} |
||||
if (td.IsAbstract) { |
||||
modifiers |= ModifierEnum.Abstract; |
||||
} |
||||
if (td.IsSealed && td.IsAbstract) { |
||||
modifiers |= ModifierEnum.Static; |
||||
} |
||||
|
||||
if ((td.Attributes & TypeAttributes.VisibilityMask) == TypeAttributes.NestedPublic) { |
||||
modifiers |= ModifierEnum.Public; |
||||
} else if ((td.Attributes & TypeAttributes.VisibilityMask) == TypeAttributes.NestedFamily) { |
||||
modifiers |= ModifierEnum.Protected; |
||||
} else if ((td.Attributes & TypeAttributes.VisibilityMask) == TypeAttributes.NestedFamORAssem) { |
||||
modifiers |= ModifierEnum.Protected; |
||||
} else { |
||||
modifiers |= ModifierEnum.Public; |
||||
} |
||||
|
||||
this.Modifiers = modifiers; |
||||
|
||||
// set base classes
|
||||
if (td.BaseType != null) { |
||||
BaseTypes.Add(CreateType(this.ProjectContent, this, td.BaseType)); |
||||
} |
||||
|
||||
foreach (TypeReference iface in td.Interfaces) { |
||||
BaseTypes.Add(CreateType(this.ProjectContent, this, iface)); |
||||
} |
||||
|
||||
ReflectionClass.ApplySpecialsFromAttributes(this); |
||||
|
||||
InitMembers(td); |
||||
} |
||||
|
||||
void InitMembers(TypeDefinition type) |
||||
{ |
||||
string defaultMemberName = null; |
||||
foreach (CustomAttribute att in type.CustomAttributes) { |
||||
if (att.Constructor.DeclaringType.FullName == "System.Reflection.DefaultMemberAttribute" |
||||
&& att.ConstructorArguments.Count == 1) |
||||
{ |
||||
defaultMemberName = att.ConstructorArguments[0].Value as string; |
||||
} |
||||
} |
||||
|
||||
foreach (TypeDefinition nestedType in type.NestedTypes) { |
||||
TypeAttributes visibility = nestedType.Attributes & TypeAttributes.VisibilityMask; |
||||
if (visibility == TypeAttributes.NestedPublic || visibility == TypeAttributes.NestedFamily |
||||
|| visibility == TypeAttributes.NestedFamORAssem) |
||||
{ |
||||
string name = nestedType.Name; |
||||
int pos = name.LastIndexOf('/'); |
||||
if (pos > 0) |
||||
name = name.Substring(pos + 1); |
||||
if (name.Length == 0 || name[0] == '<') |
||||
continue; |
||||
name = ReflectionClass.SplitTypeParameterCountFromReflectionName(name); |
||||
name = this.FullyQualifiedName + "." + name; |
||||
InnerClasses.Add(new CecilClass(this.CompilationUnit, this, nestedType, name)); |
||||
} |
||||
} |
||||
|
||||
foreach (FieldDefinition field in type.Fields) { |
||||
if (IsVisible(field.Attributes) && !field.IsSpecialName) { |
||||
DefaultField f = new DefaultField(this, field.Name); |
||||
f.Modifiers = TranslateModifiers(field); |
||||
f.ReturnType = CreateType(this.ProjectContent, this, field.FieldType, field); |
||||
AddAttributes(CompilationUnit.ProjectContent, f, f.Attributes, field); |
||||
Fields.Add(f); |
||||
} |
||||
} |
||||
|
||||
foreach (PropertyDefinition property in type.Properties) { |
||||
AddProperty(defaultMemberName, property); |
||||
} |
||||
|
||||
foreach (EventDefinition eventDef in type.Events) { |
||||
if (eventDef.AddMethod != null && IsVisible(eventDef.AddMethod.Attributes)) { |
||||
DefaultEvent e = new DefaultEvent(this, eventDef.Name); |
||||
if (this.ClassType == ClassType.Interface) { |
||||
e.Modifiers = ModifierEnum.Public | ModifierEnum.Abstract; |
||||
} else { |
||||
e.Modifiers = TranslateModifiers(eventDef); |
||||
} |
||||
e.ReturnType = CreateType(this.ProjectContent, this, eventDef.EventType, eventDef); |
||||
AddAttributes(CompilationUnit.ProjectContent, e, e.Attributes, eventDef); |
||||
Events.Add(e); |
||||
} |
||||
} |
||||
|
||||
this.AddDefaultConstructorIfRequired = (this.ClassType == ClassType.Struct || this.ClassType == ClassType.Enum); |
||||
foreach (MethodDefinition method in type.Methods) { |
||||
if (method.IsConstructor || !method.IsSpecialName) { |
||||
AddMethod(method); |
||||
} |
||||
} |
||||
} |
||||
|
||||
void AddProperty(string defaultMemberName, PropertyDefinition property) |
||||
{ |
||||
if ((property.GetMethod != null && IsVisible(property.GetMethod.Attributes)) |
||||
|| (property.SetMethod != null && IsVisible(property.SetMethod.Attributes))) |
||||
{ |
||||
DefaultProperty p = new DefaultProperty(this, property.Name); |
||||
if (this.ClassType == ClassType.Interface) { |
||||
p.Modifiers = ModifierEnum.Public | ModifierEnum.Abstract; |
||||
} else { |
||||
p.Modifiers = TranslateModifiers(property); |
||||
} |
||||
p.ReturnType = CreateType(this.ProjectContent, this, property.PropertyType, property); |
||||
p.CanGet = property.GetMethod != null && IsVisible(property.GetMethod.Attributes); |
||||
p.CanSet = property.SetMethod != null && IsVisible(property.SetMethod.Attributes); |
||||
if (p.CanGet) |
||||
p.GetterModifiers = GetAccessorVisibility(p, property.GetMethod); |
||||
if (p.CanSet) |
||||
p.SetterModifiers = GetAccessorVisibility(p, property.SetMethod); |
||||
if (p.Name == defaultMemberName) { |
||||
p.IsIndexer = true; |
||||
} |
||||
AddParameters(p, property.Parameters); |
||||
AddAttributes(CompilationUnit.ProjectContent, p, p.Attributes, property); |
||||
Properties.Add(p); |
||||
} |
||||
} |
||||
|
||||
static ModifierEnum GetAccessorVisibility(IProperty p, MethodDefinition accessor) |
||||
{ |
||||
ModifierEnum visibility = ModifierEnum.VisibilityMask & TranslateModifiers(accessor); |
||||
if (visibility == (p.Modifiers & ModifierEnum.VisibilityMask)) |
||||
return ModifierEnum.None; |
||||
else |
||||
return visibility; |
||||
} |
||||
|
||||
void AddMethod(MethodDefinition method) |
||||
{ |
||||
if (IsVisible(method.Attributes)) { |
||||
DefaultMethod m = new DefaultMethod(this, method.IsConstructor ? "#ctor" : method.Name); |
||||
|
||||
if (method.GenericParameters.Count > 0) { |
||||
foreach (GenericParameter g in method.GenericParameters) { |
||||
m.TypeParameters.Add(new DefaultTypeParameter(m, g.Name, g.Position)); |
||||
} |
||||
int i = 0; |
||||
foreach (GenericParameter g in method.GenericParameters) { |
||||
AddConstraintsFromType(m.TypeParameters[i++], g); |
||||
} |
||||
} |
||||
|
||||
if (method.IsConstructor) |
||||
m.ReturnType = this.DefaultReturnType; |
||||
else |
||||
m.ReturnType = CreateType(this.ProjectContent, m, method.ReturnType, method.MethodReturnType); |
||||
AddAttributes(CompilationUnit.ProjectContent, m, m.Attributes, method); |
||||
if (this.ClassType == ClassType.Interface) { |
||||
m.Modifiers = ModifierEnum.Public | ModifierEnum.Abstract; |
||||
} else { |
||||
m.Modifiers = TranslateModifiers(method); |
||||
} |
||||
AddParameters(m, method.Parameters); |
||||
AddExplicitInterfaceImplementations(method.Overrides, m); |
||||
ReflectionLayer.ReflectionMethod.ApplySpecialsFromAttributes(m); |
||||
Methods.Add(m); |
||||
} |
||||
} |
||||
|
||||
void AddExplicitInterfaceImplementations(Collection<MethodReference> overrides, IMember targetMember) |
||||
{ |
||||
foreach (MethodReference overrideRef in overrides) { |
||||
if (overrideRef.Name == targetMember.Name && targetMember.IsPublic) { |
||||
continue; // is like implicit interface implementation / normal override
|
||||
} |
||||
targetMember.InterfaceImplementations.Add(new ExplicitInterfaceImplementation( |
||||
CreateType(this.ProjectContent, targetMember, overrideRef.DeclaringType), |
||||
overrideRef.Name |
||||
)); |
||||
} |
||||
} |
||||
|
||||
void AddParameters(IMethodOrProperty target, Collection<ParameterDefinition> plist) |
||||
{ |
||||
foreach (ParameterDefinition par in plist) { |
||||
IReturnType pReturnType = CreateType(this.ProjectContent, target, par.ParameterType, par); |
||||
DefaultParameter p = new DefaultParameter(par.Name, pReturnType, DomRegion.Empty); |
||||
if (par.ParameterType is ByReferenceType) { |
||||
if ((par.Attributes & ParameterAttributes.Out) == ParameterAttributes.Out) { |
||||
p.Modifiers = ParameterModifiers.Out; |
||||
} else { |
||||
p.Modifiers = ParameterModifiers.Ref; |
||||
} |
||||
} else { |
||||
p.Modifiers = ParameterModifiers.In; |
||||
} |
||||
if ((par.Attributes & ParameterAttributes.Optional) == ParameterAttributes.Optional) { |
||||
p.Modifiers |= ParameterModifiers.Optional; |
||||
} |
||||
if (p.ReturnType.IsArrayReturnType) { |
||||
foreach (CustomAttribute att in par.CustomAttributes) { |
||||
if (att.Constructor.DeclaringType.FullName == typeof(ParamArrayAttribute).FullName) { |
||||
p.Modifiers |= ParameterModifiers.Params; |
||||
} |
||||
} |
||||
} |
||||
target.Parameters.Add(p); |
||||
} |
||||
} |
||||
|
||||
static bool IsVisible(MethodAttributes att) |
||||
{ |
||||
return ((att & MethodAttributes.Public) == MethodAttributes.Public) |
||||
|| ((att & MethodAttributes.Family) == MethodAttributes.Family) |
||||
|| ((att & MethodAttributes.FamORAssem) == MethodAttributes.FamORAssem); |
||||
} |
||||
|
||||
static bool IsVisible(FieldAttributes att) |
||||
{ |
||||
return ((att & FieldAttributes.Public) == FieldAttributes.Public) |
||||
|| ((att & FieldAttributes.Family) == FieldAttributes.Family) |
||||
|| ((att & FieldAttributes.FamORAssem) == FieldAttributes.FamORAssem); |
||||
} |
||||
|
||||
static ModifierEnum TranslateModifiers(MethodDefinition method) |
||||
{ |
||||
ModifierEnum m = ModifierEnum.None; |
||||
|
||||
if (method.IsStatic) { |
||||
m |= ModifierEnum.Static; |
||||
} else { |
||||
if (method.IsAbstract) { |
||||
m |= ModifierEnum.Abstract; |
||||
} else if (method.IsFinal) { |
||||
m |= ModifierEnum.Sealed; |
||||
} else if (method.Overrides.Count > 0) { |
||||
m |= ModifierEnum.Override; |
||||
} else if (method.IsVirtual) { |
||||
if (method.IsNewSlot) |
||||
m |= ModifierEnum.Virtual; |
||||
else |
||||
m |= ModifierEnum.Override; |
||||
} |
||||
} |
||||
|
||||
if ((method.Attributes & MethodAttributes.Public) == MethodAttributes.Public) |
||||
m |= ModifierEnum.Public; |
||||
else |
||||
m |= ModifierEnum.Protected; |
||||
|
||||
return m; |
||||
} |
||||
|
||||
static ModifierEnum TranslateModifiers(PropertyDefinition property) |
||||
{ |
||||
return TranslateModifiers(property.GetMethod ?? property.SetMethod); |
||||
} |
||||
|
||||
static ModifierEnum TranslateModifiers(EventDefinition @event) |
||||
{ |
||||
return TranslateModifiers(@event.AddMethod); |
||||
} |
||||
|
||||
static ModifierEnum TranslateModifiers(FieldDefinition field) |
||||
{ |
||||
ModifierEnum m = ModifierEnum.None; |
||||
|
||||
if (field.IsStatic) |
||||
m |= ModifierEnum.Static; |
||||
|
||||
if (field.IsLiteral) |
||||
m |= ModifierEnum.Const; |
||||
else if (field.IsInitOnly) |
||||
m |= ModifierEnum.Readonly; |
||||
|
||||
if ((field.Attributes & FieldAttributes.Public) == FieldAttributes.Public) |
||||
m |= ModifierEnum.Public; |
||||
else |
||||
m |= ModifierEnum.Protected; |
||||
|
||||
return m; |
||||
} |
||||
} |
||||
} |
||||
} |
||||
@ -0,0 +1,130 @@
@@ -0,0 +1,130 @@
|
||||
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
|
||||
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
|
||||
|
||||
using System; |
||||
|
||||
namespace ICSharpCode.SharpDevelop.Dom |
||||
{ |
||||
/// <summary>
|
||||
/// Class that stores a source code context and can resolve type names
|
||||
/// in that context.
|
||||
/// </summary>
|
||||
public sealed class ClassFinder |
||||
{ |
||||
int caretLine, caretColumn; |
||||
ICompilationUnit cu; |
||||
IClass callingClass; |
||||
IProjectContent projectContent; |
||||
|
||||
public IClass CallingClass { |
||||
get { |
||||
return callingClass; |
||||
} |
||||
} |
||||
|
||||
public IProjectContent ProjectContent { |
||||
get { |
||||
return projectContent; |
||||
} |
||||
} |
||||
|
||||
public LanguageProperties Language { |
||||
get { |
||||
return projectContent.Language; |
||||
} |
||||
} |
||||
|
||||
public int CaretLine { |
||||
get { return caretLine; } |
||||
} |
||||
|
||||
public int CaretColumn { |
||||
get { return caretColumn; } |
||||
} |
||||
|
||||
public ClassFinder(ParseInformation parseInfo, string fileContent, int offset) |
||||
{ |
||||
caretLine = 0; |
||||
caretColumn = 0; |
||||
for (int i = 0; i < offset; i++) { |
||||
if (fileContent[i] == '\n') { |
||||
caretLine++; |
||||
caretColumn = 0; |
||||
} else { |
||||
caretColumn++; |
||||
} |
||||
} |
||||
Init(parseInfo); |
||||
} |
||||
|
||||
public ClassFinder(ParseInformation parseInfo, int caretLineNumber, int caretColumn) |
||||
{ |
||||
this.caretLine = caretLineNumber; |
||||
this.caretColumn = caretColumn; |
||||
|
||||
Init(parseInfo); |
||||
} |
||||
|
||||
public ClassFinder(IMember classMember) |
||||
: this(classMember.DeclaringType, classMember.Region.BeginLine, classMember.Region.BeginColumn) |
||||
{ |
||||
} |
||||
|
||||
public ClassFinder(IClass callingClass, int caretLine, int caretColumn) |
||||
{ |
||||
if (callingClass == null) |
||||
throw new ArgumentNullException("callingClass"); |
||||
if (callingClass is CompoundClass) |
||||
throw new ArgumentException("Cannot use compound class for ClassFinder - must pass a specific class part."); |
||||
this.caretLine = caretLine; |
||||
this.caretColumn = caretColumn; |
||||
this.callingClass = callingClass; |
||||
this.cu = callingClass.CompilationUnit; |
||||
this.projectContent = cu.ProjectContent; |
||||
if (projectContent == null) |
||||
throw new ArgumentException("callingClass must have a project content!"); |
||||
} |
||||
|
||||
// currently callingMember is not required
|
||||
public ClassFinder(IClass callingClass, IMember callingMember, int caretLine, int caretColumn) |
||||
: this(callingClass, caretLine, caretColumn) |
||||
{ |
||||
} |
||||
|
||||
void Init(ParseInformation parseInfo) |
||||
{ |
||||
if (parseInfo != null) { |
||||
cu = parseInfo.CompilationUnit; |
||||
} |
||||
|
||||
if (cu != null) { |
||||
callingClass = cu.GetInnermostClass(caretLine, caretColumn); |
||||
projectContent = cu.ProjectContent; |
||||
} else { |
||||
projectContent = DefaultProjectContent.DummyProjectContent; |
||||
} |
||||
if (projectContent == null) |
||||
throw new ArgumentException("projectContent not found!"); |
||||
} |
||||
|
||||
public IClass GetClass(string fullName, int typeParameterCount) |
||||
{ |
||||
return projectContent.GetClass(fullName, typeParameterCount); |
||||
} |
||||
|
||||
public IReturnType SearchType(string name, int typeParameterCount) |
||||
{ |
||||
return Search(name, typeParameterCount).Result; |
||||
} |
||||
|
||||
public SearchTypeResult Search(string name, int typeParameterCount) |
||||
{ |
||||
return projectContent.SearchType(new SearchTypeRequest(name, typeParameterCount, callingClass, cu, caretLine, caretColumn)); |
||||
} |
||||
|
||||
public string SearchNamespace(string name) |
||||
{ |
||||
return Search(name, 0).NamespaceResult; |
||||
} |
||||
} |
||||
} |
||||
@ -0,0 +1,285 @@
@@ -0,0 +1,285 @@
|
||||
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
|
||||
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
|
||||
|
||||
using System; |
||||
using System.Collections; |
||||
using System.Collections.Generic; |
||||
using System.Linq; |
||||
|
||||
namespace ICSharpCode.SharpDevelop.Dom |
||||
{ |
||||
/// <summary>
|
||||
/// Provides static methods that fill a list of completion results with entries
|
||||
/// reachable from a certain calling class/member or entries that introduced
|
||||
/// by a certain Using statement.
|
||||
/// </summary>
|
||||
public class CtrlSpaceResolveHelper |
||||
{ |
||||
static void AddTypeParametersForCtrlSpace(List<ICompletionEntry> result, IEnumerable<ITypeParameter> typeParameters) |
||||
{ |
||||
foreach (ITypeParameter p in typeParameters) { |
||||
DefaultClass c = DefaultTypeParameter.GetDummyClassForTypeParameter(p); |
||||
if (p.Method != null) { |
||||
c.Documentation = "Type parameter of " + p.Method.Name; |
||||
} else { |
||||
c.Documentation = "Type parameter of " + p.Class.Name; |
||||
} |
||||
result.Add(c); |
||||
} |
||||
} |
||||
|
||||
public static void AddContentsFromCalling(List<ICompletionEntry> result, IClass callingClass, IMember callingMember) |
||||
{ |
||||
IMethodOrProperty methodOrProperty = callingMember as IMethodOrProperty; |
||||
if (methodOrProperty != null) { |
||||
foreach (IParameter p in methodOrProperty.Parameters) { |
||||
result.Add(new DefaultField.ParameterField(p.ReturnType, p.Name, methodOrProperty.Region, callingClass)); |
||||
} |
||||
if (callingMember is IMethod) { |
||||
AddTypeParametersForCtrlSpace(result, ((IMethod)callingMember).TypeParameters); |
||||
} |
||||
} |
||||
|
||||
bool inStatic = false; |
||||
if (callingMember != null) |
||||
inStatic = callingMember.IsStatic; |
||||
|
||||
if (callingClass != null) { |
||||
AddTypeParametersForCtrlSpace(result, callingClass.TypeParameters); |
||||
|
||||
|
||||
List<ICompletionEntry> members = new List<ICompletionEntry>(); |
||||
IReturnType t = callingClass.DefaultReturnType; |
||||
var language = callingClass.ProjectContent.Language; |
||||
foreach (IMember m in MemberLookupHelper.GetAccessibleMembers(t, callingClass, language, true)) { |
||||
if ((!inStatic || m.IsStatic) && language.ShowMember(m, m.IsStatic)) |
||||
result.Add(m); |
||||
} |
||||
members.Clear(); |
||||
IClass c = callingClass.DeclaringType; |
||||
while (c != null) { |
||||
t = c.DefaultReturnType; |
||||
foreach (IMember m in MemberLookupHelper.GetAccessibleMembers(t, c, language, true)) { |
||||
if (language.ShowMember(m, true)) |
||||
result.Add(m); |
||||
} |
||||
c = c.DeclaringType; |
||||
} |
||||
} |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Adds contents of all assemblies referenced by <paramref name="cu" />'s project.
|
||||
/// Also adds contents of <paramref name="callingClass" />.
|
||||
/// </summary>
|
||||
public static void AddReferencedProjectsContents(List<ICompletionEntry> result, ICompilationUnit cu, IClass callingClass) |
||||
{ |
||||
IProjectContent projectContent = cu.ProjectContent; |
||||
projectContent.AddNamespaceContents(result, "", projectContent.Language, true); |
||||
var allContents = projectContent.GetAllContents(); |
||||
result.Capacity = result.Count + allContents.Count; |
||||
foreach (var entry in allContents.Where(e => !(e is NamespaceEntry))) { |
||||
result.Add(entry); |
||||
} |
||||
AddUsing(result, projectContent.DefaultImports, projectContent); |
||||
AddContentsFromCallingClass(result, projectContent, callingClass); |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Adds contents of all namespaces that this <paramref name="callingClass" /> imports to the <paramref name="result" /> list.
|
||||
/// Also adds contents of <paramref name="callingClass" />.
|
||||
/// </summary>
|
||||
public static void AddImportedNamespaceContents(List<ICompletionEntry> result, ICompilationUnit cu, IClass callingClass) |
||||
{ |
||||
IProjectContent projectContent = cu.ProjectContent; |
||||
projectContent.AddNamespaceContents(result, "", projectContent.Language, true); |
||||
IUsingScope scope = (callingClass != null) ? callingClass.UsingScope : cu.UsingScope; |
||||
while (scope != null) { |
||||
foreach (IUsing u in scope.Usings) |
||||
AddUsing(result, u, projectContent); |
||||
scope = scope.Parent; |
||||
} |
||||
AddUsing(result, projectContent.DefaultImports, projectContent); |
||||
AddContentsFromCallingClass(result, projectContent, callingClass); |
||||
} |
||||
|
||||
static void AddContentsFromCallingClass(List<ICompletionEntry> result, IProjectContent projectContent, IClass callingClass) |
||||
{ |
||||
if (callingClass == null) { |
||||
return; |
||||
} |
||||
// use HashSet so that Contains lookups are possible in O(1).
|
||||
HashSet<ICompletionEntry> existingResults = new HashSet<ICompletionEntry>(result); |
||||
string[] namespaceParts = callingClass.Namespace.Split('.'); |
||||
for (int i = 1; i <= namespaceParts.Length; i++) { |
||||
foreach (ICompletionEntry member in projectContent.GetNamespaceContents(string.Join(".", namespaceParts, 0, i))) { |
||||
if (!existingResults.Contains(member)) |
||||
result.Add(member); |
||||
} |
||||
} |
||||
IClass currentClass = callingClass; |
||||
do { |
||||
foreach (IClass innerClass in currentClass.GetCompoundClass().GetAccessibleTypes(currentClass)) { |
||||
if (!existingResults.Contains(innerClass)) |
||||
result.Add(innerClass); |
||||
} |
||||
currentClass = currentClass.DeclaringType; |
||||
} while (currentClass != null); |
||||
} |
||||
|
||||
public static void AddUsing(List<ICompletionEntry> result, IUsing u, IProjectContent projectContent) |
||||
{ |
||||
if (u == null) { |
||||
return; |
||||
} |
||||
bool importNamespaces = projectContent.Language.ImportNamespaces; |
||||
bool importClasses = projectContent.Language.CanImportClasses; |
||||
foreach (string name in u.Usings) { |
||||
if (importClasses) { |
||||
IClass c = projectContent.GetClass(name, 0); |
||||
if (c != null) { |
||||
ArrayList members = new ArrayList(); |
||||
IReturnType t = c.DefaultReturnType; |
||||
members.AddRange(t.GetMethods()); |
||||
members.AddRange(t.GetFields()); |
||||
members.AddRange(t.GetEvents()); |
||||
members.AddRange(t.GetProperties()); |
||||
foreach (IMember m in members) { |
||||
if (m.IsStatic && m.IsPublic) { |
||||
result.Add(m); |
||||
} |
||||
} |
||||
continue; |
||||
} |
||||
} |
||||
if (importNamespaces) { |
||||
string newName = null; |
||||
if (projectContent.DefaultImports != null) { |
||||
newName = projectContent.DefaultImports.SearchNamespace(name); |
||||
} |
||||
projectContent.AddNamespaceContents(result, newName ?? name, projectContent.Language, true); |
||||
} else { |
||||
foreach (ICompletionEntry o in projectContent.GetNamespaceContents(name)) { |
||||
if (!(o is NamespaceEntry)) |
||||
result.Add(o); |
||||
} |
||||
} |
||||
} |
||||
if (u.HasAliases) { |
||||
foreach (string alias in u.Aliases.Keys) { |
||||
result.Add(new AliasEntry(alias)); |
||||
} |
||||
} |
||||
} |
||||
|
||||
public class AliasEntry : ICompletionEntry |
||||
{ |
||||
public string Name { get; private set; } |
||||
|
||||
public AliasEntry(string name) |
||||
{ |
||||
if (name == null) |
||||
throw new ArgumentNullException("name"); |
||||
this.Name = name; |
||||
} |
||||
|
||||
public override int GetHashCode() |
||||
{ |
||||
return Name.GetHashCode(); |
||||
} |
||||
|
||||
public override bool Equals(object obj) |
||||
{ |
||||
AliasEntry e = obj as AliasEntry; |
||||
return e != null && e.Name == this.Name; |
||||
} |
||||
|
||||
public override string ToString() |
||||
{ |
||||
return Name; |
||||
} |
||||
} |
||||
|
||||
public static ResolveResult GetResultFromDeclarationLine(IClass callingClass, IMethodOrProperty callingMember, int caretLine, int caretColumn, ExpressionResult expressionResult) |
||||
{ |
||||
string expression = expressionResult.Expression; |
||||
if (expression == null) return null; |
||||
if (callingClass == null) return null; |
||||
int pos = expression.IndexOf('('); |
||||
if (pos >= 0) { |
||||
expression = expression.Substring(0, pos); |
||||
} |
||||
expression = expression.Trim(); |
||||
// if (!callingClass.BodyRegion.IsInside(caretLine, caretColumn)
|
||||
// && callingClass.ProjectContent.Language.NameComparer.Equals(expression, callingClass.Name))
|
||||
// {
|
||||
// return new TypeResolveResult(callingClass, callingMember, callingClass);
|
||||
// }
|
||||
if (expressionResult.Context != ExpressionContext.Type) { |
||||
if (callingMember != null |
||||
&& !callingMember.BodyRegion.IsInside(caretLine, caretColumn) |
||||
&& (callingClass.ProjectContent.Language.NameComparer.Equals(expression, callingMember.Name) || |
||||
// For constructor definition, the expression is the constructor name (e.g. "MyClass") but the name of the member is "#ctor"
|
||||
(callingMember.Name == "#ctor" && callingClass.ProjectContent.Language.NameComparer.Equals(expression, callingClass.Name)) |
||||
) |
||||
) |
||||
{ |
||||
return new MemberResolveResult(callingClass, callingMember, callingMember); |
||||
} |
||||
} |
||||
return null; |
||||
} |
||||
|
||||
public static IList<IMethodOrProperty> FindAllExtensions(LanguageProperties language, IClass callingClass, bool searchInAllNamespaces = false) |
||||
{ |
||||
if (language == null) |
||||
throw new ArgumentNullException("language"); |
||||
if (callingClass == null) |
||||
throw new ArgumentNullException("callingClass"); |
||||
|
||||
HashSet<IMethodOrProperty> res = new HashSet<IMethodOrProperty>(); |
||||
|
||||
bool supportsExtensionMethods = language.SupportsExtensionMethods; |
||||
bool supportsExtensionProperties = language.SupportsExtensionProperties; |
||||
if (supportsExtensionMethods || supportsExtensionProperties) { |
||||
List<ICompletionEntry> list = new List<ICompletionEntry>(); |
||||
IMethod dummyMethod = new DefaultMethod("dummy", callingClass.ProjectContent.SystemTypes.Void, |
||||
ModifierEnum.Static, DomRegion.Empty, DomRegion.Empty, callingClass); |
||||
CtrlSpaceResolveHelper.AddContentsFromCalling(list, callingClass, dummyMethod); |
||||
if (searchInAllNamespaces) { |
||||
// search extension methods in all referenced projects, no matter the using section
|
||||
CtrlSpaceResolveHelper.AddReferencedProjectsContents(list, callingClass.CompilationUnit, callingClass); |
||||
} else { |
||||
CtrlSpaceResolveHelper.AddImportedNamespaceContents(list, callingClass.CompilationUnit, callingClass); |
||||
} |
||||
|
||||
bool searchExtensionsInClasses = language.SearchExtensionsInClasses; |
||||
foreach (object o in list) { |
||||
IMethodOrProperty mp = o as IMethodOrProperty; |
||||
if (mp != null && mp.IsExtensionMethod && |
||||
(supportsExtensionMethods && o is IMethod || supportsExtensionProperties && o is IProperty)) |
||||
{ |
||||
res.Add(mp); |
||||
} else if (searchExtensionsInClasses && o is IClass) { |
||||
IClass c = o as IClass; |
||||
if (c.HasExtensionMethods) { |
||||
if (supportsExtensionProperties) { |
||||
foreach (IProperty p in c.Properties) { |
||||
if (p.IsExtensionMethod) |
||||
res.Add(p); |
||||
} |
||||
} |
||||
if (supportsExtensionMethods) { |
||||
foreach (IMethod m in c.Methods) { |
||||
if (m.IsExtensionMethod) |
||||
res.Add(m); |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
return res.ToList(); |
||||
} // FindAllExtensions
|
||||
} // CtrlSpaceResolveHelper class
|
||||
} |
||||
@ -0,0 +1,129 @@
@@ -0,0 +1,129 @@
|
||||
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
|
||||
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
|
||||
|
||||
using System; |
||||
using System.Collections; |
||||
using System.Collections.Generic; |
||||
|
||||
namespace ICSharpCode.SharpDevelop.Dom |
||||
{ |
||||
public static class DiffUtility |
||||
{ |
||||
public static int GetAddedItems(IList original, IList changed, IList result) |
||||
{ |
||||
return GetAddedItems(original, changed, result, Comparer.Default); |
||||
} |
||||
|
||||
public static int GetAddedItems(IList original, IList changed, IList result, IComparer comparer) |
||||
{ |
||||
int count = 0; |
||||
if(changed != null && result != null) { |
||||
if(original == null) { |
||||
foreach(object item in changed) { |
||||
result.Add(item); |
||||
} |
||||
count = changed.Count; |
||||
} |
||||
else { |
||||
foreach(object item in changed) { |
||||
if(!Contains(original, item, comparer)) { |
||||
result.Add(item); |
||||
count++; |
||||
} |
||||
} |
||||
} |
||||
} |
||||
return count; |
||||
} |
||||
|
||||
public static int GetRemovedItems(IList original, IList changed, IList result) |
||||
{ |
||||
return GetRemovedItems(original, changed, result, Comparer.Default); |
||||
} |
||||
|
||||
public static int GetRemovedItems(IList original, IList changed, IList result, IComparer comparer) |
||||
{ |
||||
return GetAddedItems(changed, original, result, comparer); |
||||
} |
||||
|
||||
static bool Contains(IList list, object value, IComparer comparer) |
||||
{ |
||||
foreach(object item in list) { |
||||
if(0 == comparer.Compare(item, value)) { |
||||
return true; |
||||
} |
||||
} |
||||
return false; |
||||
} |
||||
|
||||
static public int Compare(IList a, IList b) |
||||
{ |
||||
return Compare(a, b, Comparer.Default); |
||||
} |
||||
|
||||
static public int Compare<T>(IList<T> a, IList<T> b) |
||||
{ |
||||
return Compare(a, b, Comparer.Default); |
||||
} |
||||
|
||||
static public int Compare<T>(IList<T> a, IList<T> b, IComparer comparer) |
||||
{ |
||||
if (a == null || b == null) { |
||||
return 1; |
||||
} |
||||
if (a.Count != b.Count) { |
||||
return Math.Sign(a.Count - b.Count); |
||||
} |
||||
int limit = (a.Count < b.Count) ? a.Count : b.Count; |
||||
for(int i=0; i < limit; i++) { |
||||
if (a[i] is IComparable && b[i] is IComparable) { |
||||
int cmp = comparer.Compare(a[i], b[i]); |
||||
if (cmp != 0) { |
||||
return cmp; |
||||
} |
||||
} |
||||
} |
||||
return a.Count - b.Count; |
||||
} |
||||
|
||||
static public int Compare(IList a, IList b, IComparer comparer) |
||||
{ |
||||
if (a == null || b == null) { |
||||
return 1; |
||||
} |
||||
if (a.Count != b.Count) { |
||||
return Math.Sign(a.Count - b.Count); |
||||
} |
||||
int limit = (a.Count < b.Count) ? a.Count : b.Count; |
||||
for(int i=0; i < limit; i++) { |
||||
if (a[i] is IComparable && b[i] is IComparable) { |
||||
int cmp = comparer.Compare(a[i], b[i]); |
||||
if (cmp != 0) { |
||||
return cmp; |
||||
} |
||||
} |
||||
} |
||||
return a.Count - b.Count; |
||||
} |
||||
|
||||
static public int Compare(SortedList a, SortedList b) |
||||
{ |
||||
return Compare(a, b, Comparer.Default); |
||||
} |
||||
|
||||
static public int Compare(SortedList a, SortedList b, IComparer comparer) |
||||
{ |
||||
if (a == null || b == null) { |
||||
return 1; |
||||
} |
||||
int cmp; |
||||
int limit = (a.Count < b.Count) ? a.Count : b.Count; |
||||
for(int i=0; i < limit; i++) { |
||||
if(0 != (cmp = comparer.Compare(a.GetByIndex(i), b.GetByIndex(i)))) { |
||||
return cmp; |
||||
} |
||||
} |
||||
return a.Count - b.Count; |
||||
} |
||||
} |
||||
} |
||||
@ -0,0 +1,41 @@
@@ -0,0 +1,41 @@
|
||||
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
|
||||
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
|
||||
|
||||
using System; |
||||
using System.Collections.Generic; |
||||
|
||||
namespace ICSharpCode.SharpDevelop.Dom |
||||
{ |
||||
static class DomCache |
||||
{ |
||||
/// <summary>
|
||||
/// Clear the static searchclass cache. You should call this method
|
||||
/// whenever the DOM changes.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// automatically called by DefaultProjectContent.UpdateCompilationUnit
|
||||
/// and DefaultProjectContent.OnReferencedContentsChanged.
|
||||
/// </remarks>
|
||||
public static void Clear() |
||||
{ |
||||
List<Action> oldActions; |
||||
lock (lockObject) { |
||||
oldActions = actions; |
||||
actions = new List<Action>(); |
||||
} |
||||
foreach (Action a in oldActions) { |
||||
a(); |
||||
} |
||||
} |
||||
|
||||
static readonly object lockObject = new Object(); |
||||
static List<Action> actions = new List<Action>(); |
||||
|
||||
public static void RegisterForClear(Action action) |
||||
{ |
||||
lock (lockObject) { |
||||
actions.Add(action); |
||||
} |
||||
} |
||||
} |
||||
} |
||||
@ -0,0 +1,382 @@
@@ -0,0 +1,382 @@
|
||||
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
|
||||
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
|
||||
|
||||
using System; |
||||
using System.CodeDom; |
||||
|
||||
namespace ICSharpCode.EasyCodeDom |
||||
{ |
||||
public static class Easy |
||||
{ |
||||
public static CodeTypeReference TypeRef(Type type) |
||||
{ |
||||
return new CodeTypeReference(type, CodeTypeReferenceOptions.GlobalReference); |
||||
} |
||||
public static CodeTypeReference TypeRef(CodeTypeDeclaration type) |
||||
{ |
||||
return new CodeTypeReference(type.Name); |
||||
} |
||||
public static CodeTypeReference TypeRef(string typeName, params string[] typeArguments) |
||||
{ |
||||
CodeTypeReference tr = new CodeTypeReference(typeName); |
||||
foreach (string ta in typeArguments) { |
||||
tr.TypeArguments.Add(ta); |
||||
} |
||||
return tr; |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Gets the CodeExpression for any primitive value that can be expressed as literal.
|
||||
/// Also works for enumeration values.
|
||||
/// </summary>
|
||||
public static CodeExpression Prim(object literalValue) |
||||
{ |
||||
if (literalValue is Enum) { |
||||
return Type(literalValue.GetType()).Field(literalValue.ToString()); |
||||
} else { |
||||
return new CodePrimitiveExpression(literalValue); |
||||
} |
||||
} |
||||
|
||||
public static CodeTypeReferenceExpression Type(Type type) |
||||
{ |
||||
return Type(TypeRef(type)); |
||||
} |
||||
public static CodeTypeReferenceExpression Type(CodeTypeReference type) |
||||
{ |
||||
return new CodeTypeReferenceExpression(type); |
||||
} |
||||
public static CodeTypeReferenceExpression Type(string type) |
||||
{ |
||||
return Type(new CodeTypeReference(type)); |
||||
} |
||||
|
||||
public static CodeTypeOfExpression TypeOf(Type type) |
||||
{ |
||||
return TypeOf(TypeRef(type)); |
||||
} |
||||
public static CodeTypeOfExpression TypeOf(CodeTypeReference type) |
||||
{ |
||||
return new CodeTypeOfExpression(type); |
||||
} |
||||
|
||||
public static CodeObjectCreateExpression New(Type type, params CodeExpression[] arguments) |
||||
{ |
||||
return New(TypeRef(type), arguments); |
||||
} |
||||
public static CodeObjectCreateExpression New(CodeTypeReference type, params CodeExpression[] arguments) |
||||
{ |
||||
return new CodeObjectCreateExpression(type, arguments); |
||||
} |
||||
|
||||
public static CodeVariableReferenceExpression Var(string name) |
||||
{ |
||||
return new CodeVariableReferenceExpression(name); |
||||
} |
||||
|
||||
public static CodeBinaryOperatorExpression Binary(CodeExpression left, |
||||
CodeBinaryOperatorType op, |
||||
CodeExpression right) |
||||
{ |
||||
return new CodeBinaryOperatorExpression(left, op, right); |
||||
} |
||||
|
||||
public static CodeThisReferenceExpression This { |
||||
get { |
||||
return new CodeThisReferenceExpression(); |
||||
} |
||||
} |
||||
|
||||
public static CodeBaseReferenceExpression Base { |
||||
get { |
||||
return new CodeBaseReferenceExpression(); |
||||
} |
||||
} |
||||
|
||||
public static CodePropertySetValueReferenceExpression Value { |
||||
get { |
||||
return new CodePropertySetValueReferenceExpression(); |
||||
} |
||||
} |
||||
|
||||
public static CodePrimitiveExpression Null { |
||||
get { |
||||
return new CodePrimitiveExpression(null); |
||||
} |
||||
} |
||||
|
||||
public static void AddSummary(CodeTypeMember member, string summary) |
||||
{ |
||||
member.Comments.Add(new CodeCommentStatement("<summary>", true)); |
||||
member.Comments.Add(new CodeCommentStatement(summary, true)); |
||||
member.Comments.Add(new CodeCommentStatement("</summary>", true)); |
||||
} |
||||
|
||||
internal static CodeAttributeDeclaration AddAttribute(CodeAttributeDeclarationCollection col, |
||||
CodeTypeReference type, |
||||
CodeExpression[] arguments) |
||||
{ |
||||
CodeAttributeArgument[] attributeArguments = new CodeAttributeArgument[arguments.Length]; |
||||
for (int i = 0; i < arguments.Length; i++) { |
||||
attributeArguments[i] = new CodeAttributeArgument(arguments[i]); |
||||
} |
||||
CodeAttributeDeclaration cad = new CodeAttributeDeclaration(type, attributeArguments); |
||||
col.Add(cad); |
||||
return cad; |
||||
} |
||||
} |
||||
|
||||
public static class ExtensionMethods |
||||
{ |
||||
public static CodeMethodInvokeExpression InvokeMethod(this CodeExpression expr, string name, params CodeExpression[] arguments) |
||||
{ |
||||
return new CodeMethodInvokeExpression(expr, name, arguments); |
||||
} |
||||
|
||||
public static CodeCastExpression CastTo(this CodeExpression expr, Type type) |
||||
{ |
||||
return expr.CastTo(Easy.TypeRef(type)); |
||||
} |
||||
public static CodeCastExpression CastTo(this CodeExpression expr, CodeTypeReference type) |
||||
{ |
||||
return new CodeCastExpression(type, expr); |
||||
} |
||||
|
||||
public static CodeIndexerExpression Index(this CodeExpression expr, params CodeExpression[] indices) |
||||
{ |
||||
return new CodeIndexerExpression(expr, indices); |
||||
} |
||||
|
||||
public static CodeFieldReferenceExpression Field(this CodeExpression expr, string name) |
||||
{ |
||||
return new CodeFieldReferenceExpression(expr, name); |
||||
} |
||||
|
||||
public static CodePropertyReferenceExpression Property(this CodeExpression expr, string name) |
||||
{ |
||||
return new CodePropertyReferenceExpression(expr, name); |
||||
} |
||||
|
||||
public static CodeNamespace AddNamespace(this CodeCompileUnit ccu, string name) |
||||
{ |
||||
CodeNamespace n = new CodeNamespace(name); |
||||
ccu.Namespaces.Add(n); |
||||
return n; |
||||
} |
||||
|
||||
public static CodeTypeDeclaration AddType(this CodeNamespace ns, string name) |
||||
{ |
||||
CodeTypeDeclaration n = new CodeTypeDeclaration(name); |
||||
ns.Types.Add(n); |
||||
return n; |
||||
} |
||||
|
||||
public static CodeNamespaceImport AddImport(this CodeNamespace ns, string nameSpace) |
||||
{ |
||||
CodeNamespaceImport cni = new CodeNamespaceImport(nameSpace); |
||||
ns.Imports.Add(cni); |
||||
return cni; |
||||
} |
||||
|
||||
public static CodeMemberField AddField(this CodeTypeDeclaration typeDecl, Type type, string name) |
||||
{ |
||||
return typeDecl.AddField(Easy.TypeRef(type), name); |
||||
} |
||||
public static CodeMemberField AddField(this CodeTypeDeclaration typeDecl, CodeTypeReference type, string name) |
||||
{ |
||||
CodeMemberField f = new CodeMemberField(type, name); |
||||
typeDecl.Members.Add(f); |
||||
return f; |
||||
} |
||||
|
||||
public static EasyProperty AddProperty(this CodeTypeDeclaration typeDecl, Type type, string name) |
||||
{ |
||||
return AddProperty(typeDecl, Easy.TypeRef(type), name); |
||||
} |
||||
public static EasyProperty AddProperty(this CodeTypeDeclaration typeDecl, CodeTypeReference type, string name) |
||||
{ |
||||
EasyProperty p = new EasyProperty(type, name); |
||||
typeDecl.Members.Add(p); |
||||
if (typeDecl.IsInterface == false) { |
||||
p.Attributes = MemberAttributes.Public | MemberAttributes.Final; |
||||
} |
||||
return p; |
||||
} |
||||
|
||||
public static EasyProperty AddProperty(this CodeTypeDeclaration typeDecl, CodeMemberField field, string name) |
||||
{ |
||||
EasyProperty p = AddProperty(typeDecl, field.Type, name); |
||||
p.Getter.Return(new CodeVariableReferenceExpression(field.Name)); |
||||
p.Attributes |= field.Attributes & MemberAttributes.Static; // copy static flag
|
||||
return p; |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Adds a method with return type <c>void</c> and attributes=Public|Final to this type.
|
||||
/// </summary>
|
||||
public static EasyMethod AddMethod(this CodeTypeDeclaration typeDecl, string name) |
||||
{ |
||||
return AddMethod(typeDecl, Easy.TypeRef(typeof(void)), name); |
||||
} |
||||
/// <summary>
|
||||
/// Adds a method with return type <paramref name="type"/> and attributes=Public|Final to this type.
|
||||
/// </summary>
|
||||
public static EasyMethod AddMethod(this CodeTypeDeclaration typeDecl, Type type, string name) |
||||
{ |
||||
return AddMethod(typeDecl, Easy.TypeRef(type), name); |
||||
} |
||||
/// <summary>
|
||||
/// Adds a method with return type <paramref name="type"/> and attributes=Public|Final to this type.
|
||||
/// </summary>
|
||||
public static EasyMethod AddMethod(this CodeTypeDeclaration typeDecl, CodeTypeReference type, string name) |
||||
{ |
||||
EasyMethod p = new EasyMethod(type, name); |
||||
typeDecl.Members.Add(p); |
||||
if (typeDecl.IsInterface == false) { |
||||
p.Attributes = MemberAttributes.Public | MemberAttributes.Final; |
||||
} |
||||
return p; |
||||
} |
||||
|
||||
public static CodeAttributeDeclaration AddAttribute(this CodeTypeMember typeMember, Type type, params CodeExpression[] arguments) |
||||
{ |
||||
return Easy.AddAttribute(typeMember.CustomAttributes, Easy.TypeRef(type), arguments); |
||||
} |
||||
public static CodeAttributeDeclaration AddAttribute(this CodeTypeMember typeMember, CodeTypeReference type, params CodeExpression[] arguments) |
||||
{ |
||||
return Easy.AddAttribute(typeMember.CustomAttributes, type, arguments); |
||||
} |
||||
} |
||||
|
||||
public class EasyProperty : CodeMemberProperty |
||||
{ |
||||
EasyBlock getter, setter; |
||||
|
||||
public EasyProperty() |
||||
{ |
||||
getter = new EasyBlock(this.GetStatements); |
||||
setter = new EasyBlock(this.SetStatements); |
||||
} |
||||
|
||||
public EasyProperty(CodeTypeReference type, string name) : this() |
||||
{ |
||||
this.Type = type; |
||||
this.Name = name; |
||||
} |
||||
|
||||
public EasyBlock Getter { |
||||
get { return getter; } |
||||
} |
||||
|
||||
public EasyBlock Setter { |
||||
get { return setter; } |
||||
} |
||||
} |
||||
|
||||
public class EasyMethod : CodeMemberMethod |
||||
{ |
||||
EasyBlock body; |
||||
|
||||
public EasyMethod() |
||||
{ |
||||
body = new EasyBlock(this.Statements); |
||||
} |
||||
|
||||
public EasyMethod(CodeTypeReference type, string name) : this() |
||||
{ |
||||
this.ReturnType = type; |
||||
this.Name = name; |
||||
} |
||||
|
||||
public CodeParameterDeclarationExpression AddParameter(Type type, string name) |
||||
{ |
||||
return AddParameter(Easy.TypeRef(type), name); |
||||
} |
||||
public CodeParameterDeclarationExpression AddParameter(CodeTypeReference type, string name) |
||||
{ |
||||
CodeParameterDeclarationExpression cpde; |
||||
cpde = new CodeParameterDeclarationExpression(type, name); |
||||
this.Parameters.Add(cpde); |
||||
return cpde; |
||||
} |
||||
|
||||
public EasyBlock Body { |
||||
get { return body; } |
||||
} |
||||
} |
||||
|
||||
public sealed class EasyBlock |
||||
{ |
||||
readonly CodeStatementCollection csc; |
||||
|
||||
public EasyBlock(CodeStatementCollection csc) |
||||
{ |
||||
this.csc = csc; |
||||
} |
||||
|
||||
public CodeMethodReturnStatement Return(CodeExpression expr) |
||||
{ |
||||
CodeMethodReturnStatement st = new CodeMethodReturnStatement(expr); |
||||
csc.Add(st); |
||||
return st; |
||||
} |
||||
|
||||
public CodeThrowExceptionStatement Throw(CodeExpression expr) |
||||
{ |
||||
CodeThrowExceptionStatement st = new CodeThrowExceptionStatement(expr); |
||||
csc.Add(st); |
||||
return st; |
||||
} |
||||
|
||||
public CodeAssignStatement Assign(CodeExpression lhs, CodeExpression rhs) |
||||
{ |
||||
CodeAssignStatement st = new CodeAssignStatement(lhs, rhs); |
||||
csc.Add(st); |
||||
return st; |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Execute one expression as statement.
|
||||
/// </summary>
|
||||
public CodeExpressionStatement Add(CodeExpression expr) |
||||
{ |
||||
CodeExpressionStatement st = new CodeExpressionStatement(expr); |
||||
csc.Add(st); |
||||
return st; |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Adds the statement.
|
||||
/// </summary>
|
||||
public CodeStatement Add(CodeStatement st) |
||||
{ |
||||
csc.Add(st); |
||||
return st; |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Invoke a method on target as statement.
|
||||
/// </summary>
|
||||
public CodeExpressionStatement InvokeMethod(CodeExpression target, string name, params CodeExpression[] arguments) |
||||
{ |
||||
return Add(new CodeMethodInvokeExpression(target, name, arguments)); |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Declares a local variable.
|
||||
/// </summary>
|
||||
public CodeVariableDeclarationStatement DeclareVariable(Type type, string name) |
||||
{ |
||||
return DeclareVariable(Easy.TypeRef(type), name); |
||||
} |
||||
/// <summary>
|
||||
/// Declares a local variable.
|
||||
/// </summary>
|
||||
public CodeVariableDeclarationStatement DeclareVariable(CodeTypeReference type, string name) |
||||
{ |
||||
CodeVariableDeclarationStatement st = new CodeVariableDeclarationStatement(type, name); |
||||
csc.Add(st); |
||||
return st; |
||||
} |
||||
} |
||||
} |
||||
@ -0,0 +1,486 @@
@@ -0,0 +1,486 @@
|
||||
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
|
||||
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
|
||||
|
||||
using System; |
||||
|
||||
namespace ICSharpCode.SharpDevelop.Dom |
||||
{ |
||||
/// <summary>
|
||||
/// Class describing a context in which an expression can be.
|
||||
/// Serves as filter for code completion results, but the contexts exposed as static fields
|
||||
/// can also be used as a kind of enumeration for special behaviour in the resolver.
|
||||
/// </summary>
|
||||
public abstract class ExpressionContext |
||||
{ |
||||
#region Instance members
|
||||
public abstract bool ShowEntry(ICompletionEntry o); |
||||
|
||||
protected bool readOnly = true; |
||||
object suggestedItem; |
||||
|
||||
/// <summary>
|
||||
/// Gets if the expression is in the context of an object creation.
|
||||
/// </summary>
|
||||
public virtual bool IsObjectCreation { |
||||
get { |
||||
return false; |
||||
} |
||||
set { |
||||
if (value) |
||||
throw new NotSupportedException(); |
||||
} |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Gets/Sets the default item that should be included in a code completion popup
|
||||
/// in this context and selected as default value.
|
||||
/// </summary>
|
||||
/// <example>
|
||||
/// "List<TypeName> var = new *expr*();" has as suggested item the pseudo-class
|
||||
/// "List<TypeName>".
|
||||
/// </example>
|
||||
public object SuggestedItem { |
||||
get { |
||||
return suggestedItem; |
||||
} |
||||
set { |
||||
if (readOnly) |
||||
throw new NotSupportedException(); |
||||
suggestedItem = value; |
||||
} |
||||
} |
||||
|
||||
public virtual bool IsTypeContext { |
||||
get { return false; } |
||||
} |
||||
#endregion
|
||||
|
||||
#region VB specific contexts (public static fields) * MOVE TO ANOTHER CLASS *
|
||||
/// <summary>The context expects a new parameter declaration</summary>
|
||||
/// <example>Function Test(*expr*, *expr*, ...)</example>
|
||||
public static readonly ExpressionContext Parameter = new DefaultExpressionContext("Parameter"); |
||||
#endregion
|
||||
|
||||
#region Default contexts (public static fields)
|
||||
/// <summary>Default/unknown context</summary>
|
||||
public readonly static ExpressionContext Default = new DefaultExpressionContext("Default"); |
||||
|
||||
/// <summary>The context expects the base type of an enum.</summary>
|
||||
/// <example>enum Name : *expr* {}</example>
|
||||
public readonly static ExpressionContext EnumBaseType = new EnumBaseTypeExpressionContext(); |
||||
|
||||
/// <summary>Context expects a non-sealed type or interface</summary>
|
||||
/// <example>class C : *expr* {}</example>
|
||||
public readonly static ExpressionContext InheritableType = new InheritableTypeExpressionContext(); |
||||
|
||||
/// <summary>Context expects a namespace name</summary>
|
||||
/// <example>using *expr*;</example>
|
||||
public readonly static ExpressionContext Namespace = new ImportableExpressionContext(false); |
||||
|
||||
/// <summary>Context expects an importable type (namespace or class with public static members)</summary>
|
||||
/// <example>Imports *expr*;</example>
|
||||
public readonly static ExpressionContext Importable = new ImportableExpressionContext(true); |
||||
|
||||
/// <summary>Context expects a type name</summary>
|
||||
/// <example>typeof(*expr*)</example>
|
||||
public readonly static ExpressionContext Type = new TypeExpressionContext(null, false, true); |
||||
|
||||
/// <summary>Context expects the name of a non-static, non-void type</summary>
|
||||
/// <example>is *expr*, *expr* variableName</example>
|
||||
public readonly static ExpressionContext NonStaticNonVoidType = new NonStaticTypeExpressionContext("NonStaticType", false); |
||||
|
||||
/// <summary>Context expects a non-abstract type that has accessible constructors</summary>
|
||||
/// <example>new *expr*();</example>
|
||||
/// <remarks>When using this context, a resolver should treat the expression as object creation,
|
||||
/// even when the keyword "new" is not part of the expression.</remarks>
|
||||
public readonly static ExpressionContext ObjectCreation = new TypeExpressionContext(null, true, true); |
||||
|
||||
/// <summary>Context expects a type deriving from System.Attribute.</summary>
|
||||
/// <example>[*expr*()]</example>
|
||||
/// <remarks>When using this context, a resolver should try resolving typenames with an
|
||||
/// appended "Attribute" suffix and treat "invocations" of the attribute type as
|
||||
/// object creation.</remarks>
|
||||
public readonly static ExpressionContext Attribute = new AttributeExpressionContext(); |
||||
|
||||
/// <summary>Context expects a type name which has special base type</summary>
|
||||
/// <param name="baseClass">The class the expression must derive from.</param>
|
||||
/// <param name="isObjectCreation">Specifies whether classes must be constructable.</param>
|
||||
/// <example>catch(*expr* ...), using(*expr* ...), throw new *expr*();</example>
|
||||
public static ExpressionContext TypeDerivingFrom(IReturnType baseType, bool isObjectCreation) |
||||
{ |
||||
return new TypeExpressionContext(baseType, isObjectCreation, false); |
||||
} |
||||
|
||||
/// <summary>Context expects an interface</summary>
|
||||
/// <example>interface C : *expr* {}</example>
|
||||
/// <example>Implements *expr*</example>
|
||||
public readonly static ExpressionContext Interface = new ClassTypeExpressionContext(ClassType.Interface); |
||||
|
||||
/// <summary>Context expects a delegate</summary>
|
||||
/// <example>public event *expr*</example>
|
||||
public readonly static ExpressionContext DelegateType = new ClassTypeExpressionContext(ClassType.Delegate); |
||||
|
||||
/// <summary>The context expects a new identifier</summary>
|
||||
/// <example>class *expr* {}; string *expr*;</example>
|
||||
public readonly static ExpressionContext IdentifierExpected = new DefaultExpressionContext("IdentifierExpected"); |
||||
|
||||
/// <summary>The context is outside of any type declaration, expecting a global-level keyword.</summary>
|
||||
public readonly static ExpressionContext Global = new DefaultExpressionContext("Global"); |
||||
|
||||
/// <summary>The context is the body of a type declaration.</summary>
|
||||
public readonly static ExpressionContext TypeDeclaration = new ExpressionContext.NonStaticTypeExpressionContext("TypeDeclaration", true); |
||||
|
||||
/// <summary>The context is the body of a method.</summary>
|
||||
/// <example>void Main () { *expr* }</example>
|
||||
public readonly static ExpressionContext MethodBody = new ExpressionContext.DefaultExpressionContext("MethodBody"); |
||||
#endregion
|
||||
|
||||
#region DefaultExpressionContext
|
||||
internal sealed class DefaultExpressionContext : ExpressionContext |
||||
{ |
||||
string name; |
||||
|
||||
public DefaultExpressionContext(string name) |
||||
{ |
||||
this.name = name; |
||||
} |
||||
|
||||
public override bool ShowEntry(ICompletionEntry o) |
||||
{ |
||||
return true; |
||||
} |
||||
|
||||
public override string ToString() |
||||
{ |
||||
return "[" + GetType().Name + ": " + name + "]"; |
||||
} |
||||
} |
||||
#endregion
|
||||
|
||||
#region NamespaceExpressionContext
|
||||
sealed class ImportableExpressionContext : ExpressionContext |
||||
{ |
||||
bool allowImportClasses; |
||||
|
||||
public ImportableExpressionContext(bool allowImportClasses) |
||||
{ |
||||
this.allowImportClasses = allowImportClasses; |
||||
} |
||||
|
||||
public override bool ShowEntry(ICompletionEntry o) |
||||
{ |
||||
if (!(o is IEntity)) |
||||
return true; |
||||
IClass c = o as IClass; |
||||
if (allowImportClasses && c != null) { |
||||
return c.HasPublicOrInternalStaticMembers; |
||||
} |
||||
return false; |
||||
} |
||||
|
||||
public override string ToString() |
||||
{ |
||||
return "[" + GetType().Name + " AllowImportClasses=" + allowImportClasses.ToString() + "]"; |
||||
} |
||||
} |
||||
#endregion
|
||||
|
||||
#region TypeExpressionContext
|
||||
sealed class TypeExpressionContext : ExpressionContext |
||||
{ |
||||
IClass baseClass; |
||||
bool isObjectCreation; |
||||
|
||||
public TypeExpressionContext(IReturnType baseType, bool isObjectCreation, bool readOnly) |
||||
{ |
||||
if (baseType != null) |
||||
baseClass = baseType.GetUnderlyingClass(); |
||||
this.isObjectCreation = isObjectCreation; |
||||
this.readOnly = readOnly; |
||||
} |
||||
|
||||
public override bool ShowEntry(ICompletionEntry o) |
||||
{ |
||||
if (!(o is IEntity)) |
||||
return true; |
||||
IClass c = o as IClass; |
||||
if (c == null) |
||||
return false; |
||||
if (isObjectCreation) { |
||||
if (c.IsAbstract || c.IsStatic) return false; |
||||
if (c.ClassType == ClassType.Enum || c.ClassType == ClassType.Interface) |
||||
return false; |
||||
} |
||||
if (baseClass == null) |
||||
return true; |
||||
return c.IsTypeInInheritanceTree(baseClass); |
||||
} |
||||
|
||||
public override bool IsObjectCreation { |
||||
get { |
||||
return isObjectCreation; |
||||
} |
||||
set { |
||||
if (readOnly && value != isObjectCreation) |
||||
throw new NotSupportedException(); |
||||
isObjectCreation = value; |
||||
} |
||||
} |
||||
|
||||
public override bool IsTypeContext { |
||||
get { return true; } |
||||
} |
||||
|
||||
public override string ToString() |
||||
{ |
||||
if (baseClass != null) |
||||
return "[" + GetType().Name + ": " + baseClass.FullyQualifiedName |
||||
+ " IsObjectCreation=" + IsObjectCreation + "]"; |
||||
else |
||||
return "[" + GetType().Name + " IsObjectCreation=" + IsObjectCreation + "]"; |
||||
} |
||||
|
||||
public override bool Equals(object obj) |
||||
{ |
||||
TypeExpressionContext o = obj as TypeExpressionContext; |
||||
return o != null && object.Equals(baseClass, o.baseClass) && IsObjectCreation == o.IsObjectCreation; |
||||
} |
||||
|
||||
public override int GetHashCode() |
||||
{ |
||||
return ((baseClass != null) ? baseClass.GetHashCode() : 0) |
||||
^ isObjectCreation.GetHashCode(); |
||||
} |
||||
} |
||||
#endregion
|
||||
|
||||
#region CombinedExpressionContext
|
||||
public static ExpressionContext operator | (ExpressionContext a, ExpressionContext b) |
||||
{ |
||||
return new CombinedExpressionContext(0, a, b); |
||||
} |
||||
|
||||
public static ExpressionContext operator & (ExpressionContext a, ExpressionContext b) |
||||
{ |
||||
return new CombinedExpressionContext(1, a, b); |
||||
} |
||||
|
||||
public static ExpressionContext operator ^ (ExpressionContext a, ExpressionContext b) |
||||
{ |
||||
return new CombinedExpressionContext(2, a, b); |
||||
} |
||||
|
||||
sealed class CombinedExpressionContext : ExpressionContext |
||||
{ |
||||
byte opType; // 0 = or ; 1 = and ; 2 = xor
|
||||
ExpressionContext a; |
||||
ExpressionContext b; |
||||
|
||||
public CombinedExpressionContext(byte opType, ExpressionContext a, ExpressionContext b) |
||||
{ |
||||
if (a == null) |
||||
throw new ArgumentNullException("a"); |
||||
if (b == null) |
||||
throw new ArgumentNullException("a"); |
||||
this.opType = opType; |
||||
this.a = a; |
||||
this.b = b; |
||||
} |
||||
|
||||
public override bool ShowEntry(ICompletionEntry o) |
||||
{ |
||||
if (opType == 0) |
||||
return a.ShowEntry(o) || b.ShowEntry(o); |
||||
else if (opType == 1) |
||||
return a.ShowEntry(o) && b.ShowEntry(o); |
||||
else |
||||
return a.ShowEntry(o) ^ b.ShowEntry(o); |
||||
} |
||||
|
||||
public override string ToString() |
||||
{ |
||||
string op; |
||||
if (opType == 0) |
||||
op = " OR "; |
||||
else if (opType == 1) |
||||
op = " AND "; |
||||
else |
||||
op = " XOR "; |
||||
return "[" + GetType().Name + ": " + a + op + b + "]"; |
||||
} |
||||
|
||||
public override int GetHashCode() |
||||
{ |
||||
int hashCode = 0; |
||||
unchecked { |
||||
hashCode += opType.GetHashCode(); |
||||
if (a != null) hashCode += a.GetHashCode() * 3; |
||||
if (b != null) hashCode += b.GetHashCode() * 181247123; |
||||
} |
||||
return hashCode; |
||||
} |
||||
|
||||
public override bool Equals(object obj) |
||||
{ |
||||
CombinedExpressionContext cec = obj as CombinedExpressionContext; |
||||
return cec != null && this.opType == cec.opType && object.Equals(this.a, cec.a) && object.Equals(this.b, cec.b); |
||||
} |
||||
} |
||||
#endregion
|
||||
|
||||
#region EnumBaseTypeExpressionContext
|
||||
sealed class EnumBaseTypeExpressionContext : ExpressionContext |
||||
{ |
||||
public override bool ShowEntry(ICompletionEntry o) |
||||
{ |
||||
IClass c = o as IClass; |
||||
if (c != null) { |
||||
// use this hack to show dummy classes like "short"
|
||||
// (go from the dummy class to the real class)
|
||||
if (c.Methods.Count > 0) { |
||||
c = c.Methods[0].DeclaringType; |
||||
} |
||||
switch (c.FullyQualifiedName) { |
||||
case "System.Byte": |
||||
case "System.SByte": |
||||
case "System.Int16": |
||||
case "System.UInt16": |
||||
case "System.Int32": |
||||
case "System.UInt32": |
||||
case "System.Int64": |
||||
case "System.UInt64": |
||||
return true; |
||||
default: |
||||
return false; |
||||
} |
||||
} else { |
||||
return false; |
||||
} |
||||
} |
||||
|
||||
public override string ToString() |
||||
{ |
||||
return "[" + GetType().Name + "]"; |
||||
} |
||||
} |
||||
#endregion
|
||||
|
||||
#region AttributeExpressionContext
|
||||
sealed class AttributeExpressionContext : ExpressionContext |
||||
{ |
||||
public override bool ShowEntry(ICompletionEntry o) |
||||
{ |
||||
if (!(o is IEntity)) |
||||
return true; |
||||
IClass c = o as IClass; |
||||
if (c != null && !c.IsAbstract) { |
||||
return c.IsTypeInInheritanceTree(c.ProjectContent.SystemTypes.Attribute.GetUnderlyingClass()); |
||||
} else { |
||||
return false; |
||||
} |
||||
} |
||||
|
||||
public override bool IsTypeContext { |
||||
get { return true; } |
||||
} |
||||
|
||||
public override string ToString() |
||||
{ |
||||
return "[" + GetType().Name + "]"; |
||||
} |
||||
} |
||||
#endregion
|
||||
|
||||
#region InheritableTypeExpressionContext
|
||||
sealed class InheritableTypeExpressionContext : ExpressionContext |
||||
{ |
||||
public override bool ShowEntry(ICompletionEntry o) |
||||
{ |
||||
if (!(o is IEntity)) return true; |
||||
IClass c = o as IClass; |
||||
if (c != null) { |
||||
foreach (IClass innerClass in c.InnerClasses) { |
||||
if (ShowEntry(innerClass)) return true; |
||||
} |
||||
if (c.ClassType == ClassType.Interface) return true; |
||||
if (c.ClassType == ClassType.Class) { |
||||
if (!c.IsSealed && !c.IsStatic) return true; |
||||
} |
||||
} |
||||
return false; |
||||
} |
||||
|
||||
public override string ToString() |
||||
{ |
||||
return "[" + GetType().Name + "]"; |
||||
} |
||||
} |
||||
#endregion
|
||||
|
||||
#region ClassTypeExpressionContext
|
||||
sealed class ClassTypeExpressionContext : ExpressionContext |
||||
{ |
||||
readonly ClassType expectedType; |
||||
|
||||
public ClassTypeExpressionContext(ClassType expectedType) |
||||
{ |
||||
this.expectedType = expectedType; |
||||
} |
||||
|
||||
public override bool ShowEntry(ICompletionEntry o) |
||||
{ |
||||
if (!(o is IEntity)) return true; |
||||
IClass c = o as IClass; |
||||
if (c != null) { |
||||
foreach (IClass innerClass in c.InnerClasses) { |
||||
if (ShowEntry(innerClass)) return true; |
||||
} |
||||
if (c.ClassType == expectedType) return true; |
||||
} |
||||
return false; |
||||
} |
||||
|
||||
public override string ToString() |
||||
{ |
||||
return "[" + GetType().Name + " expectedType=" + expectedType.ToString() + "]"; |
||||
} |
||||
} |
||||
#endregion
|
||||
|
||||
#region NonStaticTypeExpressionContext
|
||||
internal sealed class NonStaticTypeExpressionContext : ExpressionContext |
||||
{ |
||||
string name; |
||||
bool allowVoid; |
||||
|
||||
public NonStaticTypeExpressionContext(string name, bool allowVoid) |
||||
{ |
||||
this.name = name; |
||||
this.allowVoid = allowVoid; |
||||
} |
||||
|
||||
public override bool ShowEntry(ICompletionEntry o) |
||||
{ |
||||
if (!(o is IEntity)) return true; |
||||
IClass c = o as IClass; |
||||
if (c != null) { |
||||
if (!allowVoid) { |
||||
if (c.FullyQualifiedName == "System.Void" || c.FullyQualifiedName == "void") return false; |
||||
} |
||||
|
||||
foreach (IClass innerClass in c.InnerClasses) { |
||||
if (ShowEntry(innerClass)) return true; |
||||
} |
||||
if (!c.IsStatic && c.ClassType != ClassType.Module) return true; |
||||
} |
||||
return false; |
||||
} |
||||
|
||||
public override string ToString() |
||||
{ |
||||
return "[" + GetType().Name + " " + name + "]"; |
||||
} |
||||
} |
||||
#endregion
|
||||
} |
||||
} |
||||
@ -0,0 +1,104 @@
@@ -0,0 +1,104 @@
|
||||
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
|
||||
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
|
||||
|
||||
using System; |
||||
using System.Collections; |
||||
using System.Collections.Generic; |
||||
using System.Linq; |
||||
|
||||
namespace ICSharpCode.SharpDevelop.Dom |
||||
{ |
||||
static class ExtensionMethods |
||||
{ |
||||
public static void AddRange(this ArrayList arrayList, IEnumerable elements) |
||||
{ |
||||
foreach (object o in elements) |
||||
arrayList.Add(o); |
||||
} |
||||
|
||||
public static void AddRange<T>(this ICollection<T> list, IEnumerable<T> elements) |
||||
{ |
||||
foreach (T o in elements) |
||||
list.Add(o); |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Converts a recursive data structure into a flat list.
|
||||
/// </summary>
|
||||
/// <param name="input">The root elements of the recursive data structure.</param>
|
||||
/// <param name="recursive">The function that gets the children of an element.</param>
|
||||
/// <returns>Iterator that enumerates the tree structure in preorder.</returns>
|
||||
public static IEnumerable<T> Flatten<T>(this IEnumerable<T> input, Func<T, IEnumerable<T>> recursion) |
||||
{ |
||||
Stack<IEnumerator<T>> stack = new Stack<IEnumerator<T>>(); |
||||
try { |
||||
stack.Push(input.GetEnumerator()); |
||||
while (stack.Count > 0) { |
||||
while (stack.Peek().MoveNext()) { |
||||
T element = stack.Peek().Current; |
||||
yield return element; |
||||
IEnumerable<T> children = recursion(element); |
||||
if (children != null) { |
||||
stack.Push(children.GetEnumerator()); |
||||
} |
||||
} |
||||
stack.Pop().Dispose(); |
||||
} |
||||
} finally { |
||||
while (stack.Count > 0) { |
||||
stack.Pop().Dispose(); |
||||
} |
||||
} |
||||
} |
||||
|
||||
public static IEnumerable<IUsing> GetAllUsings(this ICompilationUnit cu) |
||||
{ |
||||
return (new[]{cu.UsingScope}).Flatten(s=>s.ChildScopes).SelectMany(s=>s.Usings); |
||||
} |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Publicly visible helper methods.
|
||||
/// </summary>
|
||||
public static class ExtensionMethodsPublic |
||||
{ |
||||
// the difference between IClass and IReturnType is that IClass only contains the members
|
||||
// that are declared in this very class,
|
||||
// and IReturnType contains also members from base classes (including System.Object) and default (undeclared) constructors
|
||||
|
||||
static SignatureComparer memberSignatureComparer = new SignatureComparer(); |
||||
|
||||
public static bool HasMember(this IClass containingClass, IMember member) |
||||
{ |
||||
return containingClass.AllMembers.Any(m => memberSignatureComparer.Equals(member, m)); |
||||
} |
||||
|
||||
public static bool HasMember(this IReturnType containingClass, IMember member) |
||||
{ |
||||
return containingClass.GetMembers().Any(m => memberSignatureComparer.Equals(member, m)); |
||||
} |
||||
|
||||
public static bool ImplementsInterface(this IClass targetClass, IClass requiredInterface) |
||||
{ |
||||
var targetClassType = targetClass.GetCompoundClass().DefaultReturnType; |
||||
var requiredInterfaceType = requiredInterface.GetCompoundClass().DefaultReturnType; |
||||
// class.DefaultReturnType.GetMethods() returns also methods from base classes, default ctor, ToString() etc. etc.
|
||||
return !requiredInterfaceType.GetMembers().Any(missingMember => !targetClassType.HasMember(missingMember)); |
||||
} |
||||
|
||||
public static bool ImplementsAbstractClass(this IClass targetClass, IClass abstractClass) |
||||
{ |
||||
var requiredAbstractMembers = MemberLookupHelper.GetAccessibleMembers(abstractClass.DefaultReturnType, targetClass, LanguageProperties.CSharp, true).Where(m => m.IsAbstract); |
||||
return !requiredAbstractMembers.Any(missingMember => !targetClass.HasMember(missingMember)); |
||||
} |
||||
|
||||
public static IEnumerable<IMember> GetMembers(this IReturnType typeReference) |
||||
{ |
||||
var properties = typeReference.GetProperties().Cast<IMember>(); |
||||
var methods = typeReference.GetMethods().Cast<IMember>(); |
||||
var fields = typeReference.GetFields().Cast<IMember>(); |
||||
var events = typeReference.GetEvents().Cast<IMember>(); |
||||
return properties.Concat(methods).Concat(fields).Concat(events); |
||||
} |
||||
} |
||||
} |
||||
@ -0,0 +1,114 @@
@@ -0,0 +1,114 @@
|
||||
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
|
||||
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
|
||||
|
||||
using System; |
||||
using ICSharpCode.NRefactory; |
||||
|
||||
namespace ICSharpCode.SharpDevelop.Dom |
||||
{ |
||||
public struct FilePosition : IEquatable<FilePosition> |
||||
{ |
||||
string filename; |
||||
Location position; |
||||
ICompilationUnit compilationUnit; |
||||
|
||||
public static readonly FilePosition Empty = new FilePosition(null, Location.Empty); |
||||
|
||||
public FilePosition(ICompilationUnit compilationUnit, int line, int column) |
||||
{ |
||||
this.position = new Location(column, line); |
||||
this.compilationUnit = compilationUnit; |
||||
if (compilationUnit != null) { |
||||
this.filename = compilationUnit.FileName; |
||||
} else { |
||||
this.filename = null; |
||||
} |
||||
} |
||||
|
||||
public FilePosition(string filename) |
||||
: this(filename, Location.Empty) |
||||
{ |
||||
} |
||||
|
||||
public FilePosition(string filename, int line, int column) |
||||
: this(filename, new Location(column, line)) |
||||
{ |
||||
} |
||||
|
||||
public FilePosition(string filename, Location position) |
||||
{ |
||||
this.compilationUnit = null; |
||||
this.filename = filename; |
||||
this.position = position; |
||||
} |
||||
|
||||
public string FileName { |
||||
get { |
||||
return filename; |
||||
} |
||||
} |
||||
|
||||
public ICompilationUnit CompilationUnit { |
||||
get { |
||||
return compilationUnit; |
||||
} |
||||
} |
||||
|
||||
public Location Position { |
||||
get { |
||||
return position; |
||||
} |
||||
} |
||||
|
||||
public override string ToString() |
||||
{ |
||||
return String.Format("{0} : (line {1}, col {2})", |
||||
filename, |
||||
Line, |
||||
Column); |
||||
} |
||||
|
||||
public int Line { |
||||
get { |
||||
return position.Y; |
||||
} |
||||
} |
||||
|
||||
public int Column { |
||||
get { |
||||
return position.X; |
||||
} |
||||
} |
||||
|
||||
public bool IsEmpty { |
||||
get { |
||||
return filename == null; |
||||
} |
||||
} |
||||
|
||||
public override bool Equals(object obj) |
||||
{ |
||||
return obj is FilePosition && Equals((FilePosition)obj); |
||||
} |
||||
|
||||
public bool Equals(FilePosition other) |
||||
{ |
||||
return this.FileName == other.FileName && this.Position == other.Position; |
||||
} |
||||
|
||||
public override int GetHashCode() |
||||
{ |
||||
return filename.GetHashCode() ^ position.GetHashCode(); |
||||
} |
||||
|
||||
public static bool operator ==(FilePosition lhs, FilePosition rhs) |
||||
{ |
||||
return lhs.Equals(rhs); |
||||
} |
||||
|
||||
public static bool operator !=(FilePosition lhs, FilePosition rhs) |
||||
{ |
||||
return !lhs.Equals(rhs); |
||||
} |
||||
} |
||||
} |
||||
@ -0,0 +1,112 @@
@@ -0,0 +1,112 @@
|
||||
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
|
||||
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
|
||||
using System; |
||||
using System.IO; |
||||
using System.Text; |
||||
|
||||
namespace ICSharpCode.Core |
||||
{ |
||||
/// <summary>
|
||||
/// Description of FileUtility_Minimal.
|
||||
/// </summary>
|
||||
static class FileUtility |
||||
{ |
||||
/// <summary>
|
||||
/// Gets the normalized version of fileName.
|
||||
/// Slashes are replaced with backslashes, backreferences "." and ".." are 'evaluated'.
|
||||
/// </summary>
|
||||
public static string NormalizePath(string fileName) |
||||
{ |
||||
if (string.IsNullOrEmpty(fileName)) return fileName; |
||||
|
||||
int i; |
||||
|
||||
bool isWeb = false; |
||||
for (i = 0; i < fileName.Length; i++) { |
||||
if (fileName[i] == '/' || fileName[i] == '\\') |
||||
break; |
||||
if (fileName[i] == ':') { |
||||
if (i > 1) |
||||
isWeb = true; |
||||
break; |
||||
} |
||||
} |
||||
|
||||
char outputSeparator = isWeb ? '/' : System.IO.Path.DirectorySeparatorChar; |
||||
|
||||
StringBuilder result = new StringBuilder(); |
||||
if (isWeb == false && fileName.StartsWith(@"\\") || fileName.StartsWith("//")) { |
||||
i = 2; |
||||
result.Append(outputSeparator); |
||||
} else { |
||||
i = 0; |
||||
} |
||||
int segmentStartPos = i; |
||||
for (; i <= fileName.Length; i++) { |
||||
if (i == fileName.Length || fileName[i] == '/' || fileName[i] == '\\') { |
||||
int segmentLength = i - segmentStartPos; |
||||
switch (segmentLength) { |
||||
case 0: |
||||
// ignore empty segment (if not in web mode)
|
||||
// On unix, don't ignore empty segment if i==0
|
||||
if (isWeb || (i == 0 && Environment.OSVersion.Platform == PlatformID.Unix)) { |
||||
result.Append(outputSeparator); |
||||
} |
||||
break; |
||||
case 1: |
||||
// ignore /./ segment, but append other one-letter segments
|
||||
if (fileName[segmentStartPos] != '.') { |
||||
if (result.Length > 0) result.Append(outputSeparator); |
||||
result.Append(fileName[segmentStartPos]); |
||||
} |
||||
break; |
||||
case 2: |
||||
if (fileName[segmentStartPos] == '.' && fileName[segmentStartPos + 1] == '.') { |
||||
// remove previous segment
|
||||
int j; |
||||
for (j = result.Length - 1; j >= 0 && result[j] != outputSeparator; j--); |
||||
if (j > 0) { |
||||
result.Length = j; |
||||
} |
||||
break; |
||||
} else { |
||||
// append normal segment
|
||||
goto default; |
||||
} |
||||
default: |
||||
if (result.Length > 0) result.Append(outputSeparator); |
||||
result.Append(fileName, segmentStartPos, segmentLength); |
||||
break; |
||||
} |
||||
segmentStartPos = i + 1; // remember start position for next segment
|
||||
} |
||||
} |
||||
if (isWeb == false) { |
||||
if (result.Length > 0 && result[result.Length - 1] == outputSeparator) { |
||||
result.Length -= 1; |
||||
} |
||||
if (result.Length == 2 && result[1] == ':') { |
||||
result.Append(outputSeparator); |
||||
} |
||||
} |
||||
return result.ToString(); |
||||
} |
||||
|
||||
public static bool IsEqualFileName(string fileName1, string fileName2) |
||||
{ |
||||
return string.Equals(NormalizePath(fileName1), |
||||
NormalizePath(fileName2), |
||||
StringComparison.OrdinalIgnoreCase); |
||||
} |
||||
|
||||
public static bool IsBaseDirectory(string baseDirectory, string testDirectory) |
||||
{ |
||||
if (baseDirectory == null || testDirectory == null) |
||||
return false; |
||||
baseDirectory = NormalizePath(baseDirectory) + Path.DirectorySeparatorChar; |
||||
testDirectory = NormalizePath(testDirectory) + Path.DirectorySeparatorChar; |
||||
|
||||
return testDirectory.StartsWith(baseDirectory, StringComparison.OrdinalIgnoreCase); |
||||
} |
||||
} |
||||
} |
||||
@ -0,0 +1,31 @@
@@ -0,0 +1,31 @@
|
||||
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
|
||||
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
|
||||
|
||||
using System; |
||||
|
||||
namespace ICSharpCode.SharpDevelop.Dom |
||||
{ |
||||
public sealed class FoldingRegion : Immutable |
||||
{ |
||||
string name; |
||||
DomRegion region; |
||||
|
||||
public string Name { |
||||
get { |
||||
return name; |
||||
} |
||||
} |
||||
|
||||
public DomRegion Region { |
||||
get { |
||||
return region; |
||||
} |
||||
} |
||||
|
||||
public FoldingRegion(string name, DomRegion region) |
||||
{ |
||||
this.name = name; |
||||
this.region = region; |
||||
} |
||||
} |
||||
} |
||||
@ -0,0 +1,275 @@
@@ -0,0 +1,275 @@
|
||||
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
|
||||
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
|
||||
|
||||
using System; |
||||
using System.Runtime.InteropServices; |
||||
using System.Runtime.InteropServices.ComTypes; |
||||
using System.Text; |
||||
|
||||
namespace MSjogren.GacTool.FusionNative |
||||
{ |
||||
[ComImport(), Guid("E707DCDE-D1CD-11D2-BAB9-00C04F8ECEAE"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] |
||||
internal interface IAssemblyCache |
||||
{ |
||||
[PreserveSig()] |
||||
int UninstallAssembly(uint dwFlags, |
||||
[MarshalAs(UnmanagedType.LPWStr)] string pszAssemblyName, |
||||
IntPtr pvReserved, |
||||
out uint pulDisposition); |
||||
|
||||
[PreserveSig()] |
||||
int QueryAssemblyInfo(uint dwFlags, |
||||
[MarshalAs(UnmanagedType.LPWStr)] string pszAssemblyName, |
||||
IntPtr pAsmInfo); |
||||
|
||||
[PreserveSig()] |
||||
int CreateAssemblyCacheItem(uint dwFlags, |
||||
IntPtr pvReserved, |
||||
out IAssemblyCacheItem ppAsmItem, |
||||
[MarshalAs(UnmanagedType.LPWStr)] string pszAssemblyName); |
||||
|
||||
[PreserveSig()] |
||||
int CreateAssemblyScavenger(out object ppAsmScavenger); |
||||
|
||||
[PreserveSig()] |
||||
int InstallAssembly(uint dwFlags, |
||||
[MarshalAs(UnmanagedType.LPWStr)] string pszManifestFilePath, |
||||
IntPtr pvReserved); |
||||
} |
||||
|
||||
[ComImport(), Guid("9E3AAEB4-D1CD-11D2-BAB9-00C04F8ECEAE"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] |
||||
internal interface IAssemblyCacheItem |
||||
{ |
||||
void CreateStream([MarshalAs(UnmanagedType.LPWStr)] string pszName, |
||||
uint dwFormat, |
||||
uint dwFlags, |
||||
uint dwMaxSize, |
||||
out IStream ppStream); |
||||
|
||||
void IsNameEqual(IAssemblyName pName); |
||||
|
||||
void Commit(uint dwFlags); |
||||
|
||||
void MarkAssemblyVisible(uint dwFlags); |
||||
} |
||||
|
||||
[ComImport(), Guid("CD193BC0-B4BC-11D2-9833-00C04FC31D2E"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] |
||||
internal interface IAssemblyName |
||||
{ |
||||
//
|
||||
// Assembly name properties
|
||||
// 0 = PublicKey, byte[]* ; ???
|
||||
// 1 = PublicKeyToken, byte[8]*
|
||||
// 3 = Assembly Name, LPWSTR
|
||||
// 4 = Major Version, ushort*
|
||||
// 5 = Minor Version, ushort*
|
||||
// 6 = Build Number, ushort*
|
||||
// 7 = Revison Number, ushort*
|
||||
// 8 = Culture, LPWSTR
|
||||
// 9 = Processor Type, ??? ; ???
|
||||
// 10 = OS Type, ??? ; ???
|
||||
// 13 = Codebase, LPWSTR
|
||||
// 14 = Modified Date, FILETIME* ; Only for Downloaded assemblies ?
|
||||
// 17 = Custom, LPWSTR ; ZAP string, only for NGEN assemblies
|
||||
// 19 = MVID, byte[16]* ; MVID value from __AssemblyInfo__.ini - what's this?
|
||||
//
|
||||
[PreserveSig()] |
||||
int Set(uint PropertyId, |
||||
IntPtr pvProperty, |
||||
uint cbProperty); |
||||
|
||||
[PreserveSig()] |
||||
int Get(uint PropertyId, |
||||
IntPtr pvProperty, |
||||
ref uint pcbProperty); |
||||
|
||||
[PreserveSig()] |
||||
int Finalize(); |
||||
|
||||
[PreserveSig()] |
||||
int GetDisplayName([Out(), MarshalAs(UnmanagedType.LPWStr)] StringBuilder szDisplayName, |
||||
ref uint pccDisplayName, |
||||
uint dwDisplayFlags); |
||||
|
||||
[PreserveSig()] |
||||
int BindToObject(object refIID, |
||||
object pAsmBindSink, |
||||
IApplicationContext pApplicationContext, |
||||
[MarshalAs(UnmanagedType.LPWStr)] string szCodeBase, |
||||
long llFlags, |
||||
int pvReserved, |
||||
uint cbReserved, |
||||
out int ppv); |
||||
|
||||
[PreserveSig()] |
||||
int GetName(ref uint lpcwBuffer, |
||||
[Out(), MarshalAs(UnmanagedType.LPWStr)] StringBuilder pwzName); |
||||
|
||||
[PreserveSig()] |
||||
int GetVersion(out uint pdwVersionHi, |
||||
out uint pdwVersionLow); |
||||
|
||||
[PreserveSig()] |
||||
int IsEqual(IAssemblyName pName, |
||||
uint dwCmpFlags); |
||||
|
||||
[PreserveSig()] |
||||
int Clone(out IAssemblyName pName); |
||||
} |
||||
|
||||
[ComImport(), Guid("7C23FF90-33AF-11D3-95DA-00A024A85B51"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] |
||||
internal interface IApplicationContext |
||||
{ |
||||
void SetContextNameObject(IAssemblyName pName); |
||||
|
||||
void GetContextNameObject(out IAssemblyName ppName); |
||||
|
||||
void Set([MarshalAs(UnmanagedType.LPWStr)] string szName, |
||||
int pvValue, |
||||
uint cbValue, |
||||
uint dwFlags); |
||||
|
||||
void Get([MarshalAs(UnmanagedType.LPWStr)] string szName, |
||||
out int pvValue, |
||||
ref uint pcbValue, |
||||
uint dwFlags); |
||||
|
||||
void GetDynamicDirectory(out int wzDynamicDir, |
||||
ref uint pdwSize); |
||||
} |
||||
|
||||
[ComImport(), Guid("21B8916C-F28E-11D2-A473-00C04F8EF448"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] |
||||
internal interface IAssemblyEnum |
||||
{ |
||||
[PreserveSig()] |
||||
int GetNextAssembly(out IApplicationContext ppAppCtx, |
||||
out IAssemblyName ppName, |
||||
uint dwFlags); |
||||
|
||||
[PreserveSig()] |
||||
int Reset(); |
||||
|
||||
[PreserveSig()] |
||||
int Clone(out IAssemblyEnum ppEnum); |
||||
} |
||||
|
||||
|
||||
[ComImport(), Guid("1D23DF4D-A1E2-4B8B-93D6-6EA3DC285A54"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] |
||||
internal interface IHistoryReader |
||||
{ |
||||
[PreserveSig()] |
||||
int GetFilePath([Out(), MarshalAs(UnmanagedType.LPWStr)] StringBuilder wzFilePath, |
||||
ref uint pdwSize); |
||||
|
||||
[PreserveSig()] |
||||
int GetApplicationName([Out(), MarshalAs(UnmanagedType.LPWStr)] StringBuilder wzAppName, |
||||
ref uint pdwSize); |
||||
|
||||
[PreserveSig()] |
||||
int GetEXEModulePath([Out(), MarshalAs(UnmanagedType.LPWStr)] StringBuilder wzExePath, |
||||
ref uint pdwSize); |
||||
|
||||
void GetNumActivations(out uint pdwNumActivations); |
||||
|
||||
void GetActivationDate(uint dwIdx, // One-based!
|
||||
out long /* FILETIME */ pftDate); |
||||
|
||||
[PreserveSig()] |
||||
int GetRunTimeVersion(ref long /* FILETIME */ pftActivationDate, |
||||
[Out(), MarshalAs(UnmanagedType.LPWStr)] StringBuilder wzRunTimeVersion, |
||||
ref uint pdwSize); |
||||
|
||||
void GetNumAssemblies(ref long /* FILETIME */ pftActivationDate, |
||||
out uint pdwNumAsms); |
||||
|
||||
void GetHistoryAssembly(ref long /* FILETIME */ pftActivationDate, |
||||
uint dwIdx, // One-based!
|
||||
[MarshalAs(UnmanagedType.IUnknown)] out object ppHistAsm); |
||||
|
||||
} |
||||
|
||||
internal static class Fusion |
||||
{ |
||||
[DllImport("fusion.dll", CharSet=CharSet.Auto)] |
||||
internal static extern int CreateAssemblyCache(out IAssemblyCache ppAsmCache, |
||||
uint dwReserved); |
||||
|
||||
|
||||
//
|
||||
// dwFlags: 1 = Enumerate native image (NGEN) assemblies
|
||||
// 2 = Enumerate GAC assemblies
|
||||
// 4 = Enumerate Downloaded assemblies ???
|
||||
//
|
||||
[DllImport("fusion.dll", CharSet=CharSet.Auto)] |
||||
internal static extern int CreateAssemblyEnum(out IAssemblyEnum ppEnum, |
||||
IApplicationContext pAppCtx, |
||||
IAssemblyName pName, |
||||
uint dwFlags, |
||||
int pvReserved); |
||||
|
||||
[DllImport("fusion.dll", CharSet=CharSet.Auto)] |
||||
internal static extern int CreateAssemblyNameObject(out IAssemblyName ppName, |
||||
string szAssemblyName, |
||||
uint dwFlags, |
||||
int pvReserved); |
||||
|
||||
[DllImport("fusion.dll", CharSet=CharSet.Auto)] |
||||
internal static extern int CreateHistoryReader(string wzFilePath, |
||||
out IHistoryReader ppHistReader); |
||||
|
||||
// Retrieves the path of the ApplicationHistory folder, typically
|
||||
// Documents and Settings\<user>\Local Settings\Application Data\ApplicationHistory
|
||||
// containing .ini files that can be read with IHistoryReader.
|
||||
// pwdSize appears to be the offset of the last backslash in the returned
|
||||
// string after the call.
|
||||
// Returns S_OK on success, error HRESULT on failure.
|
||||
//
|
||||
[DllImport("fusion.dll", CharSet=CharSet.Unicode)] |
||||
internal static extern int GetHistoryFileDirectory([MarshalAs(UnmanagedType.LPWStr)] StringBuilder wzDir, |
||||
ref uint pdwSize); |
||||
|
||||
[DllImport("fusion.dll")] |
||||
internal static extern int NukeDownloadedCache(); |
||||
|
||||
// ?????
|
||||
[DllImport("fusion.dll")] |
||||
internal static extern int CreateApplicationContext(out IApplicationContext ppAppContext, |
||||
uint dw); |
||||
|
||||
[DllImport("fusion.dll")] |
||||
internal static extern int GetCachePath(uint flags, |
||||
[MarshalAs(UnmanagedType.LPWStr)] StringBuilder wzDir, |
||||
ref uint pdwSize); |
||||
|
||||
public static string GetGacPath(bool isCLRv4 = false) |
||||
{ |
||||
const uint ASM_CACHE_ROOT = 0x08; // CLR V2.0
|
||||
const uint ASM_CACHE_ROOT_EX = 0x80; // CLR V4.0
|
||||
uint flags = isCLRv4 ? ASM_CACHE_ROOT_EX : ASM_CACHE_ROOT; |
||||
|
||||
const int size = 260; // MAX_PATH
|
||||
StringBuilder b = new StringBuilder(size); |
||||
uint tmp = size; |
||||
GetCachePath(flags, b, ref tmp); |
||||
return b.ToString(); |
||||
} |
||||
|
||||
// _InstallCustomAssembly@16
|
||||
// _InstallCustomModule@8
|
||||
// _LookupHistoryAssembly@28
|
||||
// _PreBindAssembly@20
|
||||
// _CreateInstallReferenceEnum@16
|
||||
|
||||
|
||||
//
|
||||
// Brings up the .NET Applicaion Restore wizard
|
||||
// Returns S_OK, 0x80131075 (App not run) or 0x80131087 (Fix failed)
|
||||
//
|
||||
[DllImport("shfusion.dll", CharSet=CharSet.Unicode)] |
||||
internal static extern uint PolicyManager(IntPtr hWndParent, |
||||
string pwzFullyQualifiedAppPath, |
||||
string pwzAppName, |
||||
int dwFlags); |
||||
|
||||
} |
||||
} |
||||
@ -0,0 +1,139 @@
@@ -0,0 +1,139 @@
|
||||
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
|
||||
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
|
||||
|
||||
using System; |
||||
using System.Collections.Generic; |
||||
using System.Reflection; |
||||
using System.Text; |
||||
|
||||
using MSjogren.GacTool.FusionNative; |
||||
|
||||
namespace ICSharpCode.SharpDevelop.Dom |
||||
{ |
||||
/// <summary>
|
||||
/// Class with static members to access the content of the global assembly
|
||||
/// cache.
|
||||
/// </summary>
|
||||
public static class GacInterop |
||||
{ |
||||
volatile static string cachedGacPathV2; |
||||
volatile static string cachedGacPathV4; |
||||
|
||||
public static string GacRootPathV2 { |
||||
get { |
||||
if (cachedGacPathV2 == null) { |
||||
cachedGacPathV2 = Fusion.GetGacPath(false); |
||||
} |
||||
return cachedGacPathV2; |
||||
} |
||||
} |
||||
|
||||
public static string GacRootPathV4 { |
||||
get { |
||||
if (cachedGacPathV4 == null) { |
||||
cachedGacPathV4 = Fusion.GetGacPath(true); |
||||
} |
||||
return cachedGacPathV4; |
||||
} |
||||
} |
||||
|
||||
public static bool IsWithinGac(string assemblyLocation) |
||||
{ |
||||
return Core.FileUtility.IsBaseDirectory(GacRootPathV2, assemblyLocation) |
||||
|| Core.FileUtility.IsBaseDirectory(GacRootPathV4, assemblyLocation); |
||||
} |
||||
|
||||
public static List<DomAssemblyName> GetAssemblyList() |
||||
{ |
||||
IApplicationContext applicationContext = null; |
||||
IAssemblyEnum assemblyEnum = null; |
||||
IAssemblyName assemblyName = null; |
||||
|
||||
List<DomAssemblyName> l = new List<DomAssemblyName>(); |
||||
Fusion.CreateAssemblyEnum(out assemblyEnum, null, null, 2, 0); |
||||
while (assemblyEnum.GetNextAssembly(out applicationContext, out assemblyName, 0) == 0) { |
||||
uint nChars = 0; |
||||
assemblyName.GetDisplayName(null, ref nChars, 0); |
||||
|
||||
StringBuilder sb = new StringBuilder((int)nChars); |
||||
assemblyName.GetDisplayName(sb, ref nChars, 0); |
||||
|
||||
l.Add(new DomAssemblyName(sb.ToString())); |
||||
} |
||||
return l; |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Gets the full display name of the GAC assembly of the specified short name
|
||||
/// </summary>
|
||||
public static DomAssemblyName FindBestMatchingAssemblyName(string name) |
||||
{ |
||||
return FindBestMatchingAssemblyName(new DomAssemblyName(name)); |
||||
} |
||||
|
||||
public static DomAssemblyName FindBestMatchingAssemblyName(DomAssemblyName name) |
||||
{ |
||||
string[] info; |
||||
Version requiredVersion = name.Version; |
||||
string publicKey = name.PublicKeyToken; |
||||
|
||||
IApplicationContext applicationContext = null; |
||||
IAssemblyEnum assemblyEnum = null; |
||||
IAssemblyName assemblyName; |
||||
Fusion.CreateAssemblyNameObject(out assemblyName, name.ShortName, 0, 0); |
||||
Fusion.CreateAssemblyEnum(out assemblyEnum, null, assemblyName, 2, 0); |
||||
List<string> names = new List<string>(); |
||||
|
||||
while (assemblyEnum.GetNextAssembly(out applicationContext, out assemblyName, 0) == 0) { |
||||
uint nChars = 0; |
||||
assemblyName.GetDisplayName(null, ref nChars, 0); |
||||
|
||||
StringBuilder sb = new StringBuilder((int)nChars); |
||||
assemblyName.GetDisplayName(sb, ref nChars, 0); |
||||
|
||||
string fullName = sb.ToString(); |
||||
if (publicKey != null) { |
||||
info = fullName.Split(','); |
||||
if (publicKey != info[3].Substring(info[3].LastIndexOf('=') + 1)) { |
||||
// Assembly has wrong public key
|
||||
continue; |
||||
} |
||||
} |
||||
names.Add(fullName); |
||||
} |
||||
if (names.Count == 0) |
||||
return null; |
||||
string best = null; |
||||
Version bestVersion = null; |
||||
Version currentVersion; |
||||
if (requiredVersion != null) { |
||||
// use assembly with lowest version higher or equal to required version
|
||||
for (int i = 0; i < names.Count; i++) { |
||||
info = names[i].Split(','); |
||||
currentVersion = new Version(info[1].Substring(info[1].LastIndexOf('=') + 1)); |
||||
if (currentVersion.CompareTo(requiredVersion) < 0) |
||||
continue; // version not good enough
|
||||
if (best == null || currentVersion.CompareTo(bestVersion) < 0) { |
||||
bestVersion = currentVersion; |
||||
best = names[i]; |
||||
} |
||||
} |
||||
if (best != null) |
||||
return new DomAssemblyName(best); |
||||
} |
||||
// use assembly with highest version
|
||||
best = names[0]; |
||||
info = names[0].Split(','); |
||||
bestVersion = new Version(info[1].Substring(info[1].LastIndexOf('=') + 1)); |
||||
for (int i = 1; i < names.Count; i++) { |
||||
info = names[i].Split(','); |
||||
currentVersion = new Version(info[1].Substring(info[1].LastIndexOf('=') + 1)); |
||||
if (currentVersion.CompareTo(bestVersion) > 0) { |
||||
bestVersion = currentVersion; |
||||
best = names[i]; |
||||
} |
||||
} |
||||
return new DomAssemblyName(best); |
||||
} |
||||
} |
||||
} |
||||
@ -0,0 +1,62 @@
@@ -0,0 +1,62 @@
|
||||
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
|
||||
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
|
||||
|
||||
using System; |
||||
using ICSharpCode.SharpDevelop.Dom.Refactoring; |
||||
|
||||
namespace ICSharpCode.SharpDevelop.Dom |
||||
{ |
||||
/// <summary>
|
||||
/// A class containing static actions that should be overridden by the
|
||||
/// application using ICSharpCode.SharpDevelop.Dom.
|
||||
/// </summary>
|
||||
public static class HostCallback |
||||
{ |
||||
/// <summary>
|
||||
/// Show an error message. (string message, Exception ex)
|
||||
/// </summary>
|
||||
public static Action<string, Exception> ShowError = delegate(string message, Exception ex) { |
||||
LoggingService.Error(message, ex); |
||||
throw new Exception(message, ex); |
||||
}; |
||||
|
||||
public static Action<string> ShowMessage = delegate(string message) { |
||||
LoggingService.Info(message); |
||||
}; |
||||
|
||||
/// <summary>
|
||||
/// Get the current project content.
|
||||
/// </summary>
|
||||
public static Func<IProjectContent> GetCurrentProjectContent = delegate { |
||||
throw new NotImplementedException("GetCurrentProjectContent was not implemented by the host."); |
||||
}; |
||||
|
||||
/// <summary>
|
||||
/// Rename the member (first argument) to the new name (second argument).
|
||||
/// Returns true on success, false on failure.
|
||||
/// </summary>
|
||||
public static Func<IMember, string, bool> RenameMember = delegate { |
||||
return false; |
||||
}; |
||||
|
||||
/// <summary>
|
||||
/// Show error loading code-completion information.
|
||||
/// The arguments are: string fileName, string include, string message
|
||||
/// </summary>
|
||||
public static Action<string, string, string> ShowAssemblyLoadError = delegate {}; |
||||
|
||||
internal static void ShowAssemblyLoadErrorInternal(string fileName, string include, string message) |
||||
{ |
||||
LoggingService.Warn("Error loading code-completion information for " |
||||
+ include + " from " + fileName |
||||
+ ":\r\n" + message + "\r\n"); |
||||
ShowAssemblyLoadError(fileName, include, message); |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Initialize the code generator options of the passed CodeGenerator.
|
||||
/// Invoked exactly once for each created instance of a class derived from CodeGenerator.
|
||||
/// </summary>
|
||||
public static Action<CodeGenerator> InitializeCodeGeneratorOptions = delegate {}; |
||||
} |
||||
} |
||||
@ -0,0 +1,24 @@
@@ -0,0 +1,24 @@
|
||||
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
|
||||
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
|
||||
|
||||
namespace ICSharpCode.SharpDevelop.Dom |
||||
{ |
||||
public interface IComment |
||||
{ |
||||
bool IsBlockComment { |
||||
get; |
||||
} |
||||
|
||||
string CommentTag { |
||||
get; |
||||
} |
||||
|
||||
string CommentText { |
||||
get; |
||||
} |
||||
|
||||
DomRegion Region { |
||||
get; |
||||
} |
||||
} |
||||
} |
||||
@ -0,0 +1,66 @@
@@ -0,0 +1,66 @@
|
||||
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
|
||||
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
|
||||
|
||||
using System; |
||||
|
||||
namespace ICSharpCode.SharpDevelop.Dom |
||||
{ |
||||
public interface IExpressionFinder |
||||
{ |
||||
/// <summary>
|
||||
/// Finds an expression before the current offset.
|
||||
/// </summary>
|
||||
ExpressionResult FindExpression(string text, int offset); |
||||
|
||||
/// <summary>
|
||||
/// Finds an expression around the current offset.
|
||||
/// </summary>
|
||||
ExpressionResult FindFullExpression(string text, int offset); |
||||
|
||||
/// <summary>
|
||||
/// Removed the last part of the expression.
|
||||
/// </summary>
|
||||
/// <example>
|
||||
/// "arr[i]" => "arr"
|
||||
/// "obj.Field" => "obj"
|
||||
/// "obj.Method(args,...)" => "obj.Method"
|
||||
/// </example>
|
||||
string RemoveLastPart(string expression); |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Structure containing the result of a call to an expression finder.
|
||||
/// </summary>
|
||||
public struct ExpressionResult |
||||
{ |
||||
public static readonly ExpressionResult Empty = new ExpressionResult(null); |
||||
|
||||
/// <summary>The expression that has been found at the specified offset.</summary>
|
||||
public string Expression; |
||||
/// <summary>The exact source code location of the expression.</summary>
|
||||
public DomRegion Region; |
||||
/// <summary>Specifies the context in which the expression was found.</summary>
|
||||
public ExpressionContext Context; |
||||
/// <summary>An object carrying additional language-dependend data.</summary>
|
||||
public object Tag; |
||||
|
||||
public ExpressionResult(string expression) : this(expression, DomRegion.Empty, ExpressionContext.Default, null) {} |
||||
public ExpressionResult(string expression, ExpressionContext context) : this(expression, DomRegion.Empty, context, null) {} |
||||
|
||||
public ExpressionResult(string expression, DomRegion region, ExpressionContext context, object tag) |
||||
{ |
||||
this.Expression = expression; |
||||
this.Region = region; |
||||
this.Context = context; |
||||
this.Tag = tag; |
||||
} |
||||
|
||||
public override string ToString() |
||||
{ |
||||
if (Context == ExpressionContext.Default) |
||||
return "<" + Expression + ">"; |
||||
else |
||||
return "<" + Expression + "> (" + Context.ToString() + ")"; |
||||
} |
||||
} |
||||
} |
||||
@ -0,0 +1,22 @@
@@ -0,0 +1,22 @@
|
||||
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
|
||||
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
|
||||
|
||||
using System; |
||||
using System.Collections; |
||||
|
||||
namespace ICSharpCode.SharpDevelop.Dom |
||||
{ |
||||
/// <summary>
|
||||
/// Description of IResolver.
|
||||
/// </summary>
|
||||
public interface IResolver |
||||
{ |
||||
/// <summary>
|
||||
/// Resolves an expression.
|
||||
/// The caretLineNumber and caretColumn is 1 based.
|
||||
/// </summary>
|
||||
ResolveResult Resolve(ExpressionResult expressionResult, |
||||
ParseInformation parseInfo, |
||||
string fileContent); |
||||
} |
||||
} |
||||
@ -0,0 +1,358 @@
@@ -0,0 +1,358 @@
|
||||
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
|
||||
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
|
||||
|
||||
using System; |
||||
using System.Collections.Generic; |
||||
|
||||
namespace ICSharpCode.SharpDevelop.Dom |
||||
{ |
||||
public abstract class AbstractEntity : AbstractFreezable, IEntity |
||||
{ |
||||
ModifierEnum modifiers = ModifierEnum.None; |
||||
IList<IAttribute> attributes; |
||||
DomRegion bodyRegion; |
||||
|
||||
IClass declaringType; |
||||
|
||||
string fullyQualifiedName; |
||||
string name; |
||||
string nspace; |
||||
|
||||
public AbstractEntity(IClass declaringType) |
||||
{ |
||||
this.declaringType = declaringType; |
||||
} |
||||
|
||||
public AbstractEntity(IClass declaringType, string name) |
||||
{ |
||||
this.declaringType = declaringType; |
||||
this.name = name; |
||||
if (declaringType != null) |
||||
nspace = declaringType.FullyQualifiedName; |
||||
|
||||
// lazy-computing the fully qualified name for class members saves ~7 MB RAM (when loading the SharpDevelop solution).
|
||||
//fullyQualifiedName = nspace + '.' + name;
|
||||
} |
||||
|
||||
public override string ToString() |
||||
{ |
||||
return String.Format("[{0}: {1}]", GetType().Name, FullyQualifiedName); |
||||
} |
||||
|
||||
#region Naming
|
||||
static readonly char[] nameDelimiters = { '.', '+' }; |
||||
|
||||
|
||||
public string FullyQualifiedName { |
||||
get { |
||||
if (fullyQualifiedName == null) { |
||||
if (name != null && nspace != null) { |
||||
fullyQualifiedName = nspace + '.' + name; |
||||
} else { |
||||
return String.Empty; |
||||
} |
||||
} |
||||
return fullyQualifiedName; |
||||
} |
||||
set { |
||||
CheckBeforeMutation(); |
||||
if (fullyQualifiedName == value) |
||||
return; |
||||
fullyQualifiedName = value; |
||||
name = null; |
||||
nspace = null; |
||||
OnFullyQualifiedNameChanged(EventArgs.Empty); |
||||
} |
||||
} |
||||
|
||||
protected virtual void OnFullyQualifiedNameChanged(EventArgs e) |
||||
{ |
||||
} |
||||
|
||||
public virtual string DotNetName { |
||||
get { |
||||
if (this.DeclaringType != null) { |
||||
return this.DeclaringType.DotNetName + "." + this.Name; |
||||
} else { |
||||
return FullyQualifiedName; |
||||
} |
||||
} |
||||
} |
||||
|
||||
public string Name { |
||||
get { |
||||
if (name == null && FullyQualifiedName != null) { |
||||
int lastIndex = FullyQualifiedName.LastIndexOfAny(nameDelimiters); |
||||
|
||||
if (lastIndex < 0) { |
||||
name = FullyQualifiedName; |
||||
} else { |
||||
name = FullyQualifiedName.Substring(lastIndex + 1); |
||||
} |
||||
} |
||||
return name; |
||||
} |
||||
} |
||||
|
||||
public string Namespace { |
||||
get { |
||||
if (nspace == null && FullyQualifiedName != null) { |
||||
int lastIndex = FullyQualifiedName.LastIndexOf('.'); |
||||
|
||||
if (lastIndex < 0) { |
||||
nspace = String.Empty; |
||||
} else { |
||||
nspace = FullyQualifiedName.Substring(0, lastIndex); |
||||
} |
||||
} |
||||
return nspace; |
||||
} |
||||
} |
||||
|
||||
|
||||
#endregion
|
||||
|
||||
protected override void FreezeInternal() |
||||
{ |
||||
attributes = FreezeList(attributes); |
||||
base.FreezeInternal(); |
||||
} |
||||
|
||||
public IClass DeclaringType { |
||||
get { |
||||
return declaringType; |
||||
} |
||||
} |
||||
|
||||
public virtual DomRegion BodyRegion { |
||||
get { |
||||
return bodyRegion; |
||||
} |
||||
set { |
||||
CheckBeforeMutation(); |
||||
bodyRegion = value; |
||||
} |
||||
} |
||||
|
||||
public object UserData { get; set; } |
||||
|
||||
public IList<IAttribute> Attributes { |
||||
get { |
||||
if (attributes == null) { |
||||
attributes = new List<IAttribute>(); |
||||
} |
||||
return attributes; |
||||
} |
||||
set { |
||||
CheckBeforeMutation(); |
||||
attributes = value; |
||||
} |
||||
} |
||||
|
||||
string documentation; |
||||
|
||||
public string Documentation { |
||||
get { |
||||
if (documentation == null) { |
||||
string documentationTag = this.DocumentationTag; |
||||
if (documentationTag != null) { |
||||
IProjectContent pc = null; |
||||
if (this is IClass) { |
||||
pc = ((IClass)this).ProjectContent; |
||||
} else if (declaringType != null) { |
||||
pc = declaringType.ProjectContent; |
||||
} |
||||
if (pc != null) { |
||||
return pc.GetXmlDocumentation(documentationTag); |
||||
} |
||||
} |
||||
} |
||||
return documentation; |
||||
} |
||||
set { |
||||
CheckBeforeMutation(); |
||||
documentation = value; |
||||
} |
||||
} |
||||
|
||||
protected void CopyDocumentationFrom(IEntity entity) |
||||
{ |
||||
AbstractEntity ae = entity as AbstractEntity; |
||||
if (ae != null) { |
||||
this.Documentation = ae.documentation; // do not cause pc.GetXmlDocumentation call for documentation copy
|
||||
} else { |
||||
this.Documentation = entity.Documentation; |
||||
} |
||||
} |
||||
|
||||
public abstract string DocumentationTag { |
||||
get; |
||||
} |
||||
|
||||
#region Modifiers
|
||||
public ModifierEnum Modifiers { |
||||
get { |
||||
return modifiers; |
||||
} |
||||
set { |
||||
CheckBeforeMutation(); |
||||
modifiers = value; |
||||
} |
||||
} |
||||
|
||||
public bool IsAbstract { |
||||
get { |
||||
return (modifiers & ModifierEnum.Abstract) == ModifierEnum.Abstract; |
||||
} |
||||
} |
||||
|
||||
public bool IsSealed { |
||||
get { |
||||
return (modifiers & ModifierEnum.Sealed) == ModifierEnum.Sealed; |
||||
} |
||||
} |
||||
|
||||
public bool IsStatic { |
||||
get { |
||||
return ((modifiers & ModifierEnum.Static) == ModifierEnum.Static) || IsConst; |
||||
} |
||||
} |
||||
|
||||
public bool IsConst { |
||||
get { |
||||
return (modifiers & ModifierEnum.Const) == ModifierEnum.Const; |
||||
} |
||||
} |
||||
|
||||
public bool IsVirtual { |
||||
get { |
||||
return (modifiers & ModifierEnum.Virtual) == ModifierEnum.Virtual; |
||||
} |
||||
} |
||||
|
||||
public bool IsPublic { |
||||
get { |
||||
return (modifiers & ModifierEnum.Public) == ModifierEnum.Public; |
||||
} |
||||
} |
||||
|
||||
public bool IsProtected { |
||||
get { |
||||
return (modifiers & ModifierEnum.Protected) == ModifierEnum.Protected; |
||||
} |
||||
} |
||||
|
||||
public bool IsPrivate { |
||||
get { |
||||
return (modifiers & ModifierEnum.Private) == ModifierEnum.Private; |
||||
} |
||||
} |
||||
|
||||
public bool IsInternal { |
||||
get { |
||||
return (modifiers & ModifierEnum.Internal) == ModifierEnum.Internal; |
||||
} |
||||
} |
||||
|
||||
[Obsolete("This property does not do what one would expect - it merely checks if protected+internal are set, it is not the equivalent of AssemblyAndFamily in Reflection!")] |
||||
public bool IsProtectedAndInternal { |
||||
get { |
||||
return (modifiers & (ModifierEnum.Internal | ModifierEnum.Protected)) == (ModifierEnum.Internal | ModifierEnum.Protected); |
||||
} |
||||
} |
||||
|
||||
[Obsolete("This property does not do what one would expect - it merely checks if one of protected+internal is set, it is not the equivalent of AssemblyOrFamily in Reflection!")] |
||||
public bool IsProtectedOrInternal { |
||||
get { |
||||
return IsProtected || IsInternal; |
||||
} |
||||
} |
||||
|
||||
public bool IsReadonly { |
||||
get { |
||||
return (modifiers & ModifierEnum.Readonly) == ModifierEnum.Readonly; |
||||
} |
||||
} |
||||
|
||||
public bool IsOverride { |
||||
get { |
||||
return (modifiers & ModifierEnum.Override) == ModifierEnum.Override; |
||||
} |
||||
} |
||||
public bool IsOverridable { |
||||
get { |
||||
return (IsOverride || IsVirtual || IsAbstract || |
||||
// Interface members have IsVirtual == IsAbstract == false. These properties are based on modifiers only.
|
||||
(this.DeclaringType != null && this.DeclaringType.ClassType == ClassType.Interface)) |
||||
&& !IsSealed; |
||||
} |
||||
} |
||||
public bool IsNew { |
||||
get { |
||||
return (modifiers & ModifierEnum.New) == ModifierEnum.New; |
||||
} |
||||
} |
||||
public bool IsSynthetic { |
||||
get { |
||||
return (modifiers & ModifierEnum.Synthetic) == ModifierEnum.Synthetic; |
||||
} |
||||
} |
||||
#endregion
|
||||
|
||||
public bool IsAccessible(IClass callingClass, bool isAccessThoughReferenceOfCurrentClass) |
||||
{ |
||||
if (IsPublic) { |
||||
return true; |
||||
} else if (IsInternal) { |
||||
// members can be both internal and protected: in that case, we want to return true if it is visible
|
||||
// through any of the modifiers
|
||||
if (callingClass != null && this.DeclaringType.ProjectContent.InternalsVisibleTo(callingClass.ProjectContent)) |
||||
return true; |
||||
} |
||||
// protected or private:
|
||||
// search in callingClass and, if callingClass is a nested class, in its outer classes
|
||||
while (callingClass != null) { |
||||
if (IsProtected) { |
||||
if (!isAccessThoughReferenceOfCurrentClass && !IsStatic) |
||||
return false; |
||||
return callingClass.IsTypeInInheritanceTree(this.DeclaringType); |
||||
} else { |
||||
// private
|
||||
if (DeclaringType.FullyQualifiedName == callingClass.FullyQualifiedName |
||||
&& DeclaringType.TypeParameters.Count == callingClass.TypeParameters.Count) |
||||
{ |
||||
return true; |
||||
} |
||||
} |
||||
|
||||
callingClass = callingClass.DeclaringType; |
||||
} |
||||
return false; |
||||
} |
||||
|
||||
public abstract ICompilationUnit CompilationUnit { |
||||
get; |
||||
} |
||||
|
||||
public IProjectContent ProjectContent { |
||||
[System.Diagnostics.DebuggerStepThrough] |
||||
get { |
||||
return this.CompilationUnit.ProjectContent; |
||||
} |
||||
} |
||||
|
||||
public virtual int CompareTo(IEntity value) |
||||
{ |
||||
return this.Modifiers - value.Modifiers; |
||||
} |
||||
|
||||
int IComparable.CompareTo(object value) |
||||
{ |
||||
return CompareTo((IEntity)value); |
||||
} |
||||
|
||||
public abstract EntityType EntityType { |
||||
get; |
||||
} |
||||
} |
||||
} |
||||
@ -0,0 +1,97 @@
@@ -0,0 +1,97 @@
|
||||
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
|
||||
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
|
||||
|
||||
using System; |
||||
using System.Collections.Generic; |
||||
|
||||
namespace ICSharpCode.SharpDevelop.Dom |
||||
{ |
||||
public abstract class AbstractMember : AbstractEntity, IMember |
||||
{ |
||||
IReturnType returnType; |
||||
DomRegion region; |
||||
IList<ExplicitInterfaceImplementation> interfaceImplementations; |
||||
IReturnType declaringTypeReference; |
||||
|
||||
protected override void FreezeInternal() |
||||
{ |
||||
interfaceImplementations = FreezeList(interfaceImplementations); |
||||
base.FreezeInternal(); |
||||
} |
||||
|
||||
public sealed override ICompilationUnit CompilationUnit { |
||||
[System.Diagnostics.DebuggerStepThrough] |
||||
get { |
||||
return this.DeclaringType.CompilationUnit; |
||||
} |
||||
} |
||||
|
||||
public virtual DomRegion Region { |
||||
get { |
||||
return region; |
||||
} |
||||
set { |
||||
CheckBeforeMutation(); |
||||
region = value; |
||||
} |
||||
} |
||||
|
||||
public virtual IReturnType ReturnType { |
||||
get { |
||||
return returnType; |
||||
} |
||||
set { |
||||
CheckBeforeMutation(); |
||||
returnType = value; |
||||
} |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Gets the declaring type reference (declaring type incl. type arguments)
|
||||
/// </summary>
|
||||
public virtual IReturnType DeclaringTypeReference { |
||||
get { |
||||
return declaringTypeReference ?? this.DeclaringType.DefaultReturnType; |
||||
} |
||||
set { |
||||
CheckBeforeMutation(); |
||||
declaringTypeReference = value; |
||||
} |
||||
} |
||||
|
||||
public IList<ExplicitInterfaceImplementation> InterfaceImplementations { |
||||
get { |
||||
return interfaceImplementations ?? (interfaceImplementations = new List<ExplicitInterfaceImplementation>()); |
||||
} |
||||
} |
||||
|
||||
public AbstractMember(IClass declaringType, string name) : base(declaringType, name) |
||||
{ |
||||
// members must have a parent class
|
||||
if (declaringType == null) |
||||
throw new ArgumentNullException("declaringType"); |
||||
} |
||||
|
||||
public abstract IMember Clone(); |
||||
|
||||
object ICloneable.Clone() |
||||
{ |
||||
return this.Clone(); |
||||
} |
||||
|
||||
IMember genericMember; |
||||
|
||||
public virtual IMember GenericMember { |
||||
get { return genericMember; } |
||||
} |
||||
|
||||
public virtual IMember CreateSpecializedMember() |
||||
{ |
||||
AbstractMember copy = Clone() as AbstractMember; |
||||
if (copy == null) |
||||
throw new Exception("Clone() must return an AbstractMember instance, or CreateSpecializedMember must also be overridden."); |
||||
copy.genericMember = this; |
||||
return copy; |
||||
} |
||||
} |
||||
} |
||||
@ -0,0 +1,136 @@
@@ -0,0 +1,136 @@
|
||||
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
|
||||
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
|
||||
|
||||
using System; |
||||
using System.Collections.Generic; |
||||
|
||||
namespace ICSharpCode.SharpDevelop.Dom |
||||
{ |
||||
/// <summary>
|
||||
/// Abstract return type for return types that are not a <see cref="ProxyReturnType"/>.
|
||||
/// </summary>
|
||||
public abstract class AbstractReturnType : IReturnType |
||||
{ |
||||
public abstract IClass GetUnderlyingClass(); |
||||
public abstract List<IMethod> GetMethods(); |
||||
public abstract List<IProperty> GetProperties(); |
||||
public abstract List<IField> GetFields(); |
||||
public abstract List<IEvent> GetEvents(); |
||||
|
||||
public virtual int TypeArgumentCount { |
||||
get { |
||||
return 0; |
||||
} |
||||
} |
||||
|
||||
public virtual bool Equals(IReturnType other) |
||||
{ |
||||
if (other == null) |
||||
return false; |
||||
return other.IsDefaultReturnType && DefaultReturnType.Equals(this, other); |
||||
} |
||||
|
||||
public sealed override bool Equals(object o) |
||||
{ |
||||
return Equals(o as IReturnType); |
||||
} |
||||
|
||||
public override int GetHashCode() |
||||
{ |
||||
return DefaultReturnType.GetHashCode(this); |
||||
} |
||||
|
||||
string fullyQualifiedName = null; |
||||
|
||||
public virtual string FullyQualifiedName { |
||||
get { |
||||
if (fullyQualifiedName == null) { |
||||
return String.Empty; |
||||
} |
||||
return fullyQualifiedName; |
||||
} |
||||
set { |
||||
fullyQualifiedName = value; |
||||
} |
||||
} |
||||
|
||||
public virtual string Name { |
||||
get { |
||||
if (FullyQualifiedName == null) { |
||||
return null; |
||||
} |
||||
int index = FullyQualifiedName.LastIndexOf('.'); |
||||
return index < 0 ? FullyQualifiedName : FullyQualifiedName.Substring(index + 1); |
||||
} |
||||
} |
||||
|
||||
public virtual string Namespace { |
||||
get { |
||||
if (FullyQualifiedName == null) { |
||||
return null; |
||||
} |
||||
int index = FullyQualifiedName.LastIndexOf('.'); |
||||
return index < 0 ? String.Empty : FullyQualifiedName.Substring(0, index); |
||||
} |
||||
} |
||||
|
||||
public virtual string DotNetName { |
||||
get { |
||||
return FullyQualifiedName; |
||||
} |
||||
} |
||||
|
||||
public virtual bool IsDefaultReturnType { |
||||
get { |
||||
return true; |
||||
} |
||||
} |
||||
|
||||
public virtual bool IsArrayReturnType { |
||||
get { |
||||
return false; |
||||
} |
||||
} |
||||
public virtual ArrayReturnType CastToArrayReturnType() |
||||
{ |
||||
return null; |
||||
} |
||||
|
||||
public virtual bool IsGenericReturnType { |
||||
get { |
||||
return false; |
||||
} |
||||
} |
||||
public virtual GenericReturnType CastToGenericReturnType() |
||||
{ |
||||
return null; |
||||
} |
||||
|
||||
public virtual bool IsConstructedReturnType { |
||||
get { |
||||
return false; |
||||
} |
||||
} |
||||
public virtual ConstructedReturnType CastToConstructedReturnType() |
||||
{ |
||||
return null; |
||||
} |
||||
|
||||
public bool IsDecoratingReturnType<T>() where T : DecoratingReturnType |
||||
{ |
||||
return false; |
||||
} |
||||
|
||||
public T CastToDecoratingReturnType<T>() where T : DecoratingReturnType |
||||
{ |
||||
return null; |
||||
} |
||||
|
||||
public virtual bool? IsReferenceType { get { return null; } } |
||||
|
||||
public virtual IReturnType GetDirectReturnType() |
||||
{ |
||||
return this; |
||||
} |
||||
} |
||||
} |
||||
@ -0,0 +1,190 @@
@@ -0,0 +1,190 @@
|
||||
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
|
||||
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
|
||||
|
||||
using System; |
||||
using System.Collections.Generic; |
||||
using System.Text; |
||||
using System.Linq; |
||||
|
||||
namespace ICSharpCode.SharpDevelop.Dom |
||||
{ |
||||
/// <summary>
|
||||
/// The return type of anonymous method expressions or lambda expressions.
|
||||
/// </summary>
|
||||
public class AnonymousMethodReturnType : DecoratingReturnType |
||||
{ |
||||
IReturnType returnType; |
||||
IList<IParameter> parameters; |
||||
ICompilationUnit cu; |
||||
|
||||
public AnonymousMethodReturnType(ICompilationUnit cu) |
||||
{ |
||||
this.cu = cu; |
||||
} |
||||
|
||||
public override bool Equals(IReturnType other) |
||||
{ |
||||
if (other == null) return false; |
||||
AnonymousMethodReturnType o = other.CastToDecoratingReturnType<AnonymousMethodReturnType>(); |
||||
if (o == null) return false; |
||||
return this.FullyQualifiedName == o.FullyQualifiedName; |
||||
} |
||||
|
||||
public override int GetHashCode() |
||||
{ |
||||
return this.FullyQualifiedName.GetHashCode(); |
||||
} |
||||
|
||||
public override T CastToDecoratingReturnType<T>() |
||||
{ |
||||
if (typeof(T) == typeof(AnonymousMethodReturnType)) { |
||||
return (T)(object)this; |
||||
} else { |
||||
return null; |
||||
} |
||||
} |
||||
|
||||
public IReturnType ToDefaultDelegate() |
||||
{ |
||||
IReturnType type = new GetClassReturnType(cu.ProjectContent, "System.Func", 0); |
||||
List<IReturnType> parameters = new List<IReturnType>(); |
||||
|
||||
if (this.HasParameterList) |
||||
parameters = MethodParameters.Select(p => p.ReturnType ?? new GetClassReturnType(cu.ProjectContent, "System.Object", 0)).ToList(); |
||||
|
||||
if (this.MethodReturnType != null && this.MethodReturnType.FullyQualifiedName == "System.Void") |
||||
type = new GetClassReturnType(cu.ProjectContent, "System.Action", 0); |
||||
else { |
||||
var rt = this.MethodReturnType; |
||||
if (rt == null) |
||||
rt = new GetClassReturnType(cu.ProjectContent, "System.Object", 0); |
||||
parameters.Add(rt); |
||||
} |
||||
|
||||
return new ConstructedReturnType(type, parameters); |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Return type of the anonymous method. Can be null if inferred from context.
|
||||
/// </summary>
|
||||
public IReturnType MethodReturnType { |
||||
get { return returnType; } |
||||
set { returnType = value; } |
||||
} |
||||
|
||||
public virtual IReturnType ResolveReturnType() |
||||
{ |
||||
return returnType; |
||||
} |
||||
|
||||
public virtual IReturnType ResolveReturnType(IReturnType[] parameterTypes) |
||||
{ |
||||
return returnType; |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Gets the list of method parameters. Can be null if the anonymous method has no parameter list.
|
||||
/// </summary>
|
||||
public IList<IParameter> MethodParameters { |
||||
get { return parameters; } |
||||
set { parameters = value; } |
||||
} |
||||
|
||||
public virtual bool CanBeConvertedToExpressionTree { |
||||
get { return false; } |
||||
} |
||||
|
||||
public bool HasParameterList { |
||||
get { return parameters != null; } |
||||
} |
||||
|
||||
public bool HasImplicitlyTypedParameters { |
||||
get { |
||||
if (parameters == null) |
||||
return false; |
||||
else |
||||
return parameters.Any(p => p.ReturnType == null); |
||||
} |
||||
} |
||||
|
||||
DefaultClass cachedClass; |
||||
|
||||
public override IClass GetUnderlyingClass() |
||||
{ |
||||
if (cachedClass != null) return cachedClass; |
||||
DefaultClass c = new DefaultClass(cu, ClassType.Delegate, ModifierEnum.None, DomRegion.Empty, null); |
||||
c.BaseTypes.Add(cu.ProjectContent.SystemTypes.Delegate); |
||||
AddDefaultDelegateMethod(c, returnType ?? cu.ProjectContent.SystemTypes.Object, parameters ?? new IParameter[0]); |
||||
cachedClass = c; |
||||
return c; |
||||
} |
||||
|
||||
internal static void AddDefaultDelegateMethod(DefaultClass c, IReturnType returnType, IList<IParameter> parameters) |
||||
{ |
||||
ModifierEnum modifiers = ModifierEnum.Public | ModifierEnum.Synthetic; |
||||
DefaultMethod invokeMethod = new DefaultMethod("Invoke", returnType, modifiers, c.Region, DomRegion.Empty, c); |
||||
foreach (IParameter par in parameters) { |
||||
invokeMethod.Parameters.Add(par); |
||||
} |
||||
c.Methods.Add(invokeMethod); |
||||
invokeMethod = new DefaultMethod("BeginInvoke", c.ProjectContent.SystemTypes.IAsyncResult, modifiers, c.Region, DomRegion.Empty, c); |
||||
foreach (IParameter par in parameters) { |
||||
invokeMethod.Parameters.Add(par); |
||||
} |
||||
invokeMethod.Parameters.Add(new DefaultParameter("callback", c.ProjectContent.SystemTypes.AsyncCallback, DomRegion.Empty)); |
||||
invokeMethod.Parameters.Add(new DefaultParameter("object", c.ProjectContent.SystemTypes.Object, DomRegion.Empty)); |
||||
c.Methods.Add(invokeMethod); |
||||
invokeMethod = new DefaultMethod("EndInvoke", returnType, modifiers, c.Region, DomRegion.Empty, c); |
||||
invokeMethod.Parameters.Add(new DefaultParameter("result", c.ProjectContent.SystemTypes.IAsyncResult, DomRegion.Empty)); |
||||
c.Methods.Add(invokeMethod); |
||||
} |
||||
|
||||
public override IReturnType BaseType { |
||||
get { |
||||
return GetUnderlyingClass().DefaultReturnType; |
||||
} |
||||
} |
||||
|
||||
public override string Name { |
||||
get { |
||||
return "delegate"; |
||||
} |
||||
} |
||||
|
||||
public override string FullyQualifiedName { |
||||
get { |
||||
StringBuilder b = new StringBuilder("delegate"); |
||||
if (HasParameterList) { |
||||
bool first = true; |
||||
b.Append("("); |
||||
foreach (IParameter p in parameters) { |
||||
if (first) first = false; else b.Append(", "); |
||||
b.Append(p.Name); |
||||
if (p.ReturnType != null) { |
||||
b.Append(":"); |
||||
b.Append(p.ReturnType.Name); |
||||
} |
||||
} |
||||
b.Append(")"); |
||||
} |
||||
if (returnType != null) { |
||||
b.Append(":"); |
||||
b.Append(returnType.Name); |
||||
} |
||||
return b.ToString(); |
||||
} |
||||
} |
||||
|
||||
public override string Namespace { |
||||
get { |
||||
return ""; |
||||
} |
||||
} |
||||
|
||||
public override string DotNetName { |
||||
get { |
||||
return Name; |
||||
} |
||||
} |
||||
} |
||||
} |
||||
@ -0,0 +1,154 @@
@@ -0,0 +1,154 @@
|
||||
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
|
||||
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
|
||||
|
||||
using System; |
||||
using System.Collections.Generic; |
||||
using System.Text; |
||||
|
||||
namespace ICSharpCode.SharpDevelop.Dom |
||||
{ |
||||
/// <summary>
|
||||
/// The ArrayReturnType wraps around another type, converting it into an array
|
||||
/// with the specified number of dimensions.
|
||||
/// The element type is only used as return type for the indexer; all methods and fields
|
||||
/// are retrieved from System.Array.
|
||||
/// </summary>
|
||||
public sealed class ArrayReturnType : DecoratingReturnType |
||||
{ |
||||
IReturnType elementType; |
||||
int dimensions; |
||||
IProjectContent pc; |
||||
|
||||
internal IProjectContent ProjectContent { |
||||
get { |
||||
return pc; |
||||
} |
||||
} |
||||
|
||||
public ArrayReturnType(IProjectContent pc, IReturnType elementType, int dimensions) |
||||
{ |
||||
if (pc == null) |
||||
throw new ArgumentNullException("pc"); |
||||
if (dimensions <= 0) |
||||
throw new ArgumentOutOfRangeException("dimensions", dimensions, "dimensions must be positive"); |
||||
if (elementType == null) |
||||
throw new ArgumentNullException("elementType"); |
||||
this.pc = pc; |
||||
this.elementType = elementType; |
||||
this.dimensions = dimensions; |
||||
} |
||||
|
||||
public override IReturnType GetDirectReturnType() |
||||
{ |
||||
IReturnType newElementType = elementType.GetDirectReturnType(); |
||||
if (newElementType == elementType) |
||||
return this; |
||||
else |
||||
return new ArrayReturnType(pc, newElementType, dimensions); |
||||
} |
||||
|
||||
public override bool Equals(IReturnType rt) |
||||
{ |
||||
if (rt == null || !rt.IsArrayReturnType) return false; |
||||
ArrayReturnType art = rt.CastToArrayReturnType(); |
||||
if (art.ArrayDimensions != dimensions) return false; |
||||
return elementType.Equals(art.ArrayElementType); |
||||
} |
||||
|
||||
public override int GetHashCode() |
||||
{ |
||||
unchecked { |
||||
return 2 * elementType.GetHashCode() + 27 * dimensions; |
||||
} |
||||
} |
||||
|
||||
public override T CastToDecoratingReturnType<T>() |
||||
{ |
||||
if (typeof(T) == typeof(ArrayReturnType)) { |
||||
return (T)(object)this; |
||||
} else { |
||||
return null; |
||||
} |
||||
} |
||||
|
||||
public IReturnType ArrayElementType { |
||||
get { |
||||
return elementType; |
||||
} |
||||
} |
||||
|
||||
public int ArrayDimensions { |
||||
get { |
||||
return dimensions; |
||||
} |
||||
} |
||||
|
||||
public override string FullyQualifiedName { |
||||
get { |
||||
return elementType.FullyQualifiedName; |
||||
} |
||||
} |
||||
|
||||
public override string Name { |
||||
get { |
||||
return elementType.Name; |
||||
} |
||||
} |
||||
|
||||
public override string DotNetName { |
||||
get { |
||||
return AppendArrayString(elementType.DotNetName); |
||||
} |
||||
} |
||||
|
||||
public override IReturnType BaseType { |
||||
get { |
||||
return pc.SystemTypes.Array; |
||||
} |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Indexer used exclusively for array return types
|
||||
/// </summary>
|
||||
public class ArrayIndexer : DefaultProperty |
||||
{ |
||||
public ArrayIndexer(IReturnType elementType, IClass systemArray) |
||||
: base("Indexer", elementType, ModifierEnum.Public, DomRegion.Empty, DomRegion.Empty, systemArray) |
||||
{ |
||||
IsIndexer = true; |
||||
} |
||||
} |
||||
|
||||
public override List<IProperty> GetProperties() |
||||
{ |
||||
List<IProperty> l = base.GetProperties(); |
||||
ArrayIndexer property = new ArrayIndexer(elementType, this.BaseType.GetUnderlyingClass()); |
||||
IReturnType int32 = pc.SystemTypes.Int32; |
||||
for (int i = 0; i < dimensions; ++i) { |
||||
property.Parameters.Add(new DefaultParameter("index", int32, DomRegion.Empty)); |
||||
} |
||||
property.Freeze(); |
||||
l.Add(property); |
||||
return l; |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Appends the array characters ([,,,]) to the string <paramref name="a"/>.
|
||||
/// </summary>
|
||||
string AppendArrayString(string a) |
||||
{ |
||||
StringBuilder b = new StringBuilder(a, a.Length + 1 + dimensions); |
||||
b.Append('['); |
||||
for (int i = 1; i < dimensions; ++i) { |
||||
b.Append(','); |
||||
} |
||||
b.Append(']'); |
||||
return b.ToString(); |
||||
} |
||||
|
||||
public override string ToString() |
||||
{ |
||||
return String.Format("[ArrayReturnType: {0}{1}]", elementType, AppendArrayString("")); |
||||
} |
||||
} |
||||
} |
||||
@ -0,0 +1,47 @@
@@ -0,0 +1,47 @@
|
||||
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
|
||||
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
|
||||
|
||||
using System; |
||||
using System.Linq; |
||||
|
||||
namespace ICSharpCode.SharpDevelop.Dom |
||||
{ |
||||
/// <summary>
|
||||
/// Like SearchClassReturnType, but tries both the specified name and name+"Attribute".
|
||||
/// </summary>
|
||||
public class AttributeReturnType : ProxyReturnType |
||||
{ |
||||
string name; |
||||
SearchClassReturnType scrt1, scrt2; |
||||
|
||||
public AttributeReturnType(ClassFinder context, string name) |
||||
{ |
||||
if (context == null) |
||||
throw new ArgumentNullException("context"); |
||||
if (name == null) |
||||
throw new ArgumentNullException("name"); |
||||
this.name = name; |
||||
scrt1 = new SearchClassReturnType(context.ProjectContent, context.CallingClass, |
||||
context.CaretLine, context.CaretColumn, name, 0); |
||||
scrt2 = new SearchClassReturnType(context.ProjectContent, context.CallingClass, |
||||
context.CaretLine, context.CaretColumn, name + "Attribute", 0); |
||||
} |
||||
|
||||
public override IReturnType BaseType { |
||||
get { |
||||
IClass class1 = scrt1.GetUnderlyingClass(); |
||||
IClass class2 = scrt2.GetUnderlyingClass(); |
||||
if (class1 != null && class2 != null) { |
||||
if (class1.ClassInheritanceTree.Any(c => c.FullyQualifiedName == "System.Attribute")) |
||||
return scrt1; |
||||
else |
||||
return scrt2; |
||||
} else if (class2 != null) { |
||||
return scrt2; |
||||
} else { |
||||
return scrt1; |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
@ -0,0 +1,91 @@
@@ -0,0 +1,91 @@
|
||||
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
|
||||
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
|
||||
|
||||
using System; |
||||
using System.Collections.Generic; |
||||
|
||||
namespace ICSharpCode.SharpDevelop.Dom |
||||
{ |
||||
/// <summary>
|
||||
/// A type parameter that was bound to a concrete type.
|
||||
/// </summary>
|
||||
public sealed class BoundTypeParameter : AbstractFreezable, ITypeParameter |
||||
{ |
||||
readonly ITypeParameter baseTypeParameter; |
||||
readonly IMethod owningMethod; |
||||
readonly IClass owningClass; |
||||
IReturnType boundTo; |
||||
|
||||
public BoundTypeParameter(ITypeParameter baseTypeParameter, IClass owningClass) |
||||
: this(baseTypeParameter, owningClass, null) |
||||
{ |
||||
} |
||||
|
||||
public BoundTypeParameter(ITypeParameter baseTypeParameter, IClass owningClass, IMethod owningMethod) |
||||
{ |
||||
if (owningClass == null) |
||||
throw new ArgumentNullException("owningClass"); |
||||
if (baseTypeParameter == null) |
||||
throw new ArgumentNullException("baseTypeParameter"); |
||||
this.baseTypeParameter = baseTypeParameter; |
||||
this.owningMethod = owningMethod; |
||||
this.owningClass = owningClass; |
||||
} |
||||
|
||||
protected override void FreezeInternal() |
||||
{ |
||||
base.FreezeInternal(); |
||||
baseTypeParameter.Freeze(); |
||||
owningMethod.Freeze(); |
||||
owningClass.Freeze(); |
||||
} |
||||
|
||||
public string Name { |
||||
get { return baseTypeParameter.Name; } |
||||
} |
||||
|
||||
public int Index { |
||||
get { return baseTypeParameter.Index; } |
||||
} |
||||
|
||||
public IList<IAttribute> Attributes { |
||||
get { return baseTypeParameter.Attributes; } |
||||
} |
||||
|
||||
public IMethod Method { |
||||
get { return owningMethod; } |
||||
} |
||||
|
||||
public IClass Class { |
||||
get { return owningClass; } |
||||
} |
||||
|
||||
public IList<IReturnType> Constraints { |
||||
get { return baseTypeParameter.Constraints; } |
||||
} |
||||
|
||||
public bool HasConstructableConstraint { |
||||
get { return baseTypeParameter.HasConstructableConstraint; } |
||||
} |
||||
|
||||
public bool HasReferenceTypeConstraint { |
||||
get { return baseTypeParameter.HasReferenceTypeConstraint; } |
||||
} |
||||
|
||||
public bool HasValueTypeConstraint { |
||||
get { return baseTypeParameter.HasValueTypeConstraint; } |
||||
} |
||||
|
||||
public IReturnType BoundTo { |
||||
get { return boundTo; } |
||||
set { |
||||
CheckBeforeMutation(); |
||||
boundTo = value; |
||||
} |
||||
} |
||||
|
||||
public ITypeParameter UnboundTypeParameter { |
||||
get { return baseTypeParameter.UnboundTypeParameter; } |
||||
} |
||||
} |
||||
} |
||||
@ -0,0 +1,152 @@
@@ -0,0 +1,152 @@
|
||||
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
|
||||
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
|
||||
|
||||
using System; |
||||
using System.Collections.Generic; |
||||
|
||||
namespace ICSharpCode.SharpDevelop.Dom |
||||
{ |
||||
/// <summary>
|
||||
/// Combines multiple return types for use in constraints.
|
||||
/// </summary>
|
||||
public sealed class CombinedReturnType : AbstractReturnType |
||||
{ |
||||
IList<IReturnType> baseTypes; |
||||
|
||||
string fullName; |
||||
string name; |
||||
string @namespace; |
||||
string dotnetName; |
||||
|
||||
public override bool Equals(IReturnType obj) |
||||
{ |
||||
CombinedReturnType combined = obj as CombinedReturnType; |
||||
if (combined == null) return false; |
||||
if (baseTypes.Count != combined.baseTypes.Count) return false; |
||||
for (int i = 0; i < baseTypes.Count; i++) { |
||||
if (!baseTypes[i].Equals(combined.baseTypes[i])) { |
||||
return false; |
||||
} |
||||
} |
||||
return true; |
||||
} |
||||
|
||||
public override int GetHashCode() |
||||
{ |
||||
unchecked { |
||||
int res = 0; |
||||
foreach (IReturnType rt in baseTypes) { |
||||
res *= 1300027; |
||||
res += rt.GetHashCode(); |
||||
} |
||||
return res; |
||||
} |
||||
} |
||||
|
||||
public CombinedReturnType(IList<IReturnType> baseTypes, string fullName, string name, string @namespace, string dotnetName) |
||||
{ |
||||
this.baseTypes = baseTypes; |
||||
this.fullName = fullName; |
||||
this.name = name; |
||||
this.@namespace = @namespace; |
||||
this.dotnetName = dotnetName; |
||||
} |
||||
|
||||
public IList<IReturnType> BaseTypes { |
||||
get { |
||||
return baseTypes; |
||||
} |
||||
} |
||||
|
||||
List<T> Combine<T>(Converter<IReturnType, List<T>> conv) where T : IMember |
||||
{ |
||||
int count = baseTypes.Count; |
||||
if (count == 0) |
||||
return null; |
||||
List<T> list = null; |
||||
foreach (IReturnType baseType in baseTypes) { |
||||
List<T> newList = conv(baseType); |
||||
if (newList == null) |
||||
continue; |
||||
if (list == null) { |
||||
list = newList; |
||||
} else { |
||||
foreach (T element in newList) { |
||||
bool found = false; |
||||
foreach (T t in list) { |
||||
if (t.CompareTo(element) == 0) { |
||||
found = true; |
||||
break; |
||||
} |
||||
} |
||||
if (!found) { |
||||
list.Add(element); |
||||
} |
||||
} |
||||
} |
||||
} |
||||
return list; |
||||
} |
||||
|
||||
public override List<IMethod> GetMethods() |
||||
{ |
||||
return Combine<IMethod>(delegate(IReturnType type) { return type.GetMethods(); }); |
||||
} |
||||
|
||||
public override List<IProperty> GetProperties() |
||||
{ |
||||
return Combine<IProperty>(delegate(IReturnType type) { return type.GetProperties(); }); |
||||
} |
||||
|
||||
public override List<IField> GetFields() |
||||
{ |
||||
return Combine<IField>(delegate(IReturnType type) { return type.GetFields(); }); |
||||
} |
||||
|
||||
public override List<IEvent> GetEvents() |
||||
{ |
||||
return Combine<IEvent>(delegate(IReturnType type) { return type.GetEvents(); }); |
||||
} |
||||
|
||||
public override string FullyQualifiedName { |
||||
get { |
||||
return fullName; |
||||
} |
||||
} |
||||
|
||||
public override string Name { |
||||
get { |
||||
return name; |
||||
} |
||||
} |
||||
|
||||
public override string Namespace { |
||||
get { |
||||
return @namespace; |
||||
} |
||||
} |
||||
|
||||
public override string DotNetName { |
||||
get { |
||||
return dotnetName; |
||||
} |
||||
} |
||||
|
||||
public override bool IsDefaultReturnType { |
||||
get { |
||||
return false; |
||||
} |
||||
} |
||||
|
||||
public override int TypeArgumentCount { |
||||
get { |
||||
return 0; |
||||
} |
||||
} |
||||
|
||||
public override IClass GetUnderlyingClass() |
||||
{ |
||||
return null; |
||||
} |
||||
} |
||||
} |
||||
@ -0,0 +1,131 @@
@@ -0,0 +1,131 @@
|
||||
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
|
||||
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
|
||||
|
||||
using System; |
||||
using System.Collections.Generic; |
||||
using System.Collections.ObjectModel; |
||||
using System.Linq; |
||||
using System.Diagnostics; |
||||
|
||||
namespace ICSharpCode.SharpDevelop.Dom |
||||
{ |
||||
/// <summary>
|
||||
/// A class made up of multiple partial classes.
|
||||
///
|
||||
/// CompoundClass is immutable, it freezes the underlying DefaultClass in the constructor.
|
||||
/// The constructor also freezes all parts to ensure that the methods/properties/fields/events of a
|
||||
/// CompoundClass never change.
|
||||
/// When you want to build add or remove parts from a CompoundClass, you need to create a new
|
||||
/// CompoundClass instance with the new parts.
|
||||
/// </summary>
|
||||
public sealed class CompoundClass : DefaultClass |
||||
{ |
||||
/// <summary>
|
||||
/// The parts this class is based on.
|
||||
/// </summary>
|
||||
readonly ReadOnlyCollection<IClass> parts; |
||||
|
||||
/// <summary>
|
||||
/// Gets the parts this class is based on.
|
||||
/// </summary>
|
||||
public ReadOnlyCollection<IClass> Parts { |
||||
get { |
||||
return parts; |
||||
} |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Creates a new CompoundClass with the specified parts.
|
||||
/// </summary>
|
||||
public static CompoundClass Create(IEnumerable<IClass> parts) |
||||
{ |
||||
// Ensure that the list of parts does not change.
|
||||
var p = parts.ToList(); |
||||
foreach (IClass c in p) { |
||||
c.Freeze(); |
||||
} |
||||
return new CompoundClass(p); |
||||
} |
||||
|
||||
private CompoundClass(List<IClass> parts) : base(new DefaultCompilationUnit(parts[0].ProjectContent), parts[0].FullyQualifiedName) |
||||
{ |
||||
this.CompilationUnit.Classes.Add(this); |
||||
|
||||
this.parts = parts.AsReadOnly(); |
||||
|
||||
UpdateInformationFromParts(); |
||||
this.CompilationUnit.Freeze(); |
||||
Debug.Assert(this.IsFrozen); |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Calculate information from class parts (Modifier, Base classes, Type parameters etc.)
|
||||
/// </summary>
|
||||
void UpdateInformationFromParts() |
||||
{ |
||||
// Common for all parts:
|
||||
this.ClassType = parts[0].ClassType; |
||||
|
||||
ModifierEnum modifier = ModifierEnum.None; |
||||
const ModifierEnum defaultClassVisibility = ModifierEnum.Internal; |
||||
|
||||
this.BaseTypes.Clear(); |
||||
this.InnerClasses.Clear(); |
||||
this.Attributes.Clear(); |
||||
this.Methods.Clear(); |
||||
this.Properties.Clear(); |
||||
this.Events.Clear(); |
||||
this.Fields.Clear(); |
||||
|
||||
string shortestFileName = null; |
||||
|
||||
foreach (IClass part in parts) { |
||||
if (!string.IsNullOrEmpty(part.CompilationUnit.FileName)) { |
||||
if (shortestFileName == null || part.CompilationUnit.FileName.Length < shortestFileName.Length) { |
||||
shortestFileName = part.CompilationUnit.FileName; |
||||
this.Region = part.Region; |
||||
} |
||||
} |
||||
|
||||
if ((part.Modifiers & ModifierEnum.VisibilityMask) != defaultClassVisibility) { |
||||
modifier |= part.Modifiers; |
||||
} else { |
||||
modifier |= part.Modifiers &~ ModifierEnum.VisibilityMask; |
||||
} |
||||
foreach (IReturnType rt in part.BaseTypes) { |
||||
if (!rt.IsDefaultReturnType || rt.FullyQualifiedName != "System.Object") { |
||||
this.BaseTypes.Add(rt); |
||||
} |
||||
} |
||||
this.InnerClasses.AddRange(part.InnerClasses); |
||||
this.Attributes.AddRange(part.Attributes); |
||||
this.Methods.AddRange(part.Methods); |
||||
this.Properties.AddRange(part.Properties); |
||||
this.Events.AddRange(part.Events); |
||||
this.Fields.AddRange(part.Fields); |
||||
|
||||
this.AddDefaultConstructorIfRequired |= part.AddDefaultConstructorIfRequired; |
||||
} |
||||
this.CompilationUnit.FileName = shortestFileName; |
||||
if ((modifier & ModifierEnum.VisibilityMask) == ModifierEnum.None) { |
||||
modifier |= defaultClassVisibility; |
||||
} |
||||
this.Modifiers = modifier; |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Type parameters are the same on all parts.
|
||||
/// </summary>
|
||||
public override IList<ITypeParameter> TypeParameters { |
||||
get { |
||||
// Locking for the time of getting the reference to the sub-list is sufficient:
|
||||
// Classes used for parts never change, instead the whole part is replaced with
|
||||
// a new IClass instance.
|
||||
return parts[0].TypeParameters; |
||||
} |
||||
set { |
||||
throw new NotSupportedException(); |
||||
} |
||||
} |
||||
} |
||||
} |
||||
@ -0,0 +1,259 @@
@@ -0,0 +1,259 @@
|
||||
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
|
||||
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
|
||||
|
||||
using System; |
||||
using System.Collections.Generic; |
||||
using System.Text; |
||||
|
||||
namespace ICSharpCode.SharpDevelop.Dom |
||||
{ |
||||
/// <summary>
|
||||
/// ConstructedReturnType is a reference to generic class that specifies the type parameters.
|
||||
/// When getting the Members, this return type modifies the lists in such a way that the
|
||||
/// <see cref="GenericReturnType"/>s are replaced with the return types in the type parameters
|
||||
/// collection.
|
||||
/// Example: List<string>
|
||||
/// </summary>
|
||||
public sealed class ConstructedReturnType : DecoratingReturnType |
||||
{ |
||||
// Return types that should be substituted for the generic types
|
||||
// If a substitution is unknown (type could not be resolved), the list
|
||||
// contains a null entry.
|
||||
IList<IReturnType> typeArguments; |
||||
IReturnType baseType; |
||||
|
||||
public IList<IReturnType> TypeArguments { |
||||
get { |
||||
return typeArguments; |
||||
} |
||||
} |
||||
|
||||
public ConstructedReturnType(IReturnType baseType, IList<IReturnType> typeArguments) |
||||
{ |
||||
if (baseType == null) |
||||
throw new ArgumentNullException("baseType"); |
||||
if (typeArguments == null) |
||||
throw new ArgumentNullException("typeArguments"); |
||||
this.typeArguments = typeArguments; |
||||
this.baseType = baseType; |
||||
} |
||||
|
||||
public override T CastToDecoratingReturnType<T>() |
||||
{ |
||||
if (typeof(T) == typeof(ConstructedReturnType)) { |
||||
return (T)(object)this; |
||||
} else { |
||||
return null; |
||||
} |
||||
} |
||||
|
||||
public override bool Equals(IReturnType rt) |
||||
{ |
||||
return rt != null |
||||
&& rt.IsConstructedReturnType |
||||
&& this.DotNetName == rt.DotNetName; |
||||
} |
||||
|
||||
public override int GetHashCode() |
||||
{ |
||||
return this.DotNetName.GetHashCode(); |
||||
} |
||||
|
||||
public override IReturnType GetDirectReturnType() |
||||
{ |
||||
IReturnType newBaseType = baseType.GetDirectReturnType(); |
||||
IReturnType[] newTypeArguments = new IReturnType[typeArguments.Count]; |
||||
bool typeArgumentsChanged = false; |
||||
for (int i = 0; i < typeArguments.Count; i++) { |
||||
if (typeArguments[i] != null) |
||||
newTypeArguments[i] = typeArguments[i].GetDirectReturnType(); |
||||
if (typeArguments[i] != newTypeArguments[i]) |
||||
typeArgumentsChanged = true; |
||||
} |
||||
if (baseType == newBaseType && !typeArgumentsChanged) |
||||
return this; |
||||
else |
||||
return new ConstructedReturnType(newBaseType, newTypeArguments); |
||||
} |
||||
|
||||
public override IReturnType BaseType { |
||||
get { |
||||
return baseType; |
||||
} |
||||
} |
||||
|
||||
public IReturnType UnboundType { |
||||
get { |
||||
return baseType; |
||||
} |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Gets if <paramref name="t"/> is/contains a generic return type referring to a class type parameter.
|
||||
/// </summary>
|
||||
bool CheckReturnType(IReturnType t) |
||||
{ |
||||
if (t == null) { |
||||
return false; |
||||
} |
||||
if (t.IsGenericReturnType) { |
||||
return t.CastToGenericReturnType().TypeParameter.Method == null; |
||||
} else if (t.IsArrayReturnType) { |
||||
return CheckReturnType(t.CastToArrayReturnType().ArrayElementType); |
||||
} else if (t.IsConstructedReturnType) { |
||||
foreach (IReturnType para in t.CastToConstructedReturnType().TypeArguments) { |
||||
if (CheckReturnType(para)) return true; |
||||
} |
||||
return false; |
||||
} else { |
||||
return false; |
||||
} |
||||
} |
||||
|
||||
bool CheckParameters(IList<IParameter> l) |
||||
{ |
||||
foreach (IParameter p in l) { |
||||
if (CheckReturnType(p.ReturnType)) return true; |
||||
} |
||||
return false; |
||||
} |
||||
|
||||
public override string DotNetName { |
||||
get { |
||||
string baseName = baseType.DotNetName; |
||||
int pos = baseName.LastIndexOf('`'); |
||||
StringBuilder b; |
||||
if (pos < 0) |
||||
b = new StringBuilder(baseName); |
||||
else |
||||
b = new StringBuilder(baseName, 0, pos, pos + 20); |
||||
b.Append('{'); |
||||
for (int i = 0; i < typeArguments.Count; ++i) { |
||||
if (i > 0) b.Append(','); |
||||
if (typeArguments[i] != null) { |
||||
b.Append(typeArguments[i].DotNetName); |
||||
} |
||||
} |
||||
b.Append('}'); |
||||
return b.ToString(); |
||||
} |
||||
} |
||||
|
||||
public static IReturnType TranslateType(IReturnType input, IList<IReturnType> typeParameters, bool convertForMethod) |
||||
{ |
||||
if (input == null || typeParameters == null || typeParameters.Count == 0) { |
||||
return input; // nothing to do when there are no type parameters specified
|
||||
} |
||||
if (input.IsGenericReturnType) { |
||||
GenericReturnType rt = input.CastToGenericReturnType(); |
||||
if (convertForMethod ? (rt.TypeParameter.Method != null) : (rt.TypeParameter.Method == null)) { |
||||
if (rt.TypeParameter.Index < typeParameters.Count) { |
||||
IReturnType newType = typeParameters[rt.TypeParameter.Index]; |
||||
if (newType != null) { |
||||
return newType; |
||||
} |
||||
} |
||||
} |
||||
} else if (input.IsArrayReturnType) { |
||||
ArrayReturnType arInput = input.CastToArrayReturnType(); |
||||
IReturnType e = arInput.ArrayElementType; |
||||
IReturnType t = TranslateType(e, typeParameters, convertForMethod); |
||||
if (e != t && t != null) |
||||
return new ArrayReturnType(arInput.ProjectContent, t, arInput.ArrayDimensions); |
||||
} else if (input.IsConstructedReturnType) { |
||||
ConstructedReturnType cinput = input.CastToConstructedReturnType(); |
||||
List<IReturnType> para = new List<IReturnType>(cinput.TypeArguments.Count); |
||||
foreach (IReturnType argument in cinput.TypeArguments) { |
||||
para.Add(TranslateType(argument, typeParameters, convertForMethod)); |
||||
} |
||||
return new ConstructedReturnType(cinput.UnboundType, para); |
||||
} |
||||
return input; |
||||
} |
||||
|
||||
IReturnType TranslateType(IReturnType input) |
||||
{ |
||||
return TranslateType(input, typeArguments, false); |
||||
} |
||||
|
||||
public override List<IMethod> GetMethods() |
||||
{ |
||||
List<IMethod> l = baseType.GetMethods(); |
||||
for (int i = 0; i < l.Count; ++i) { |
||||
if (CheckReturnType(l[i].ReturnType) || CheckParameters(l[i].Parameters)) { |
||||
l[i] = (IMethod)l[i].CreateSpecializedMember(); |
||||
if (l[i].DeclaringType == baseType.GetUnderlyingClass()) { |
||||
l[i].DeclaringTypeReference = this; |
||||
} |
||||
l[i].ReturnType = TranslateType(l[i].ReturnType); |
||||
for (int j = 0; j < l[i].Parameters.Count; ++j) { |
||||
l[i].Parameters[j].ReturnType = TranslateType(l[i].Parameters[j].ReturnType); |
||||
} |
||||
} |
||||
} |
||||
return l; |
||||
} |
||||
|
||||
public override List<IProperty> GetProperties() |
||||
{ |
||||
List<IProperty> l = baseType.GetProperties(); |
||||
for (int i = 0; i < l.Count; ++i) { |
||||
if (CheckReturnType(l[i].ReturnType) || CheckParameters(l[i].Parameters)) { |
||||
l[i] = (IProperty)l[i].CreateSpecializedMember(); |
||||
if (l[i].DeclaringType == baseType.GetUnderlyingClass()) { |
||||
l[i].DeclaringTypeReference = this; |
||||
} |
||||
l[i].ReturnType = TranslateType(l[i].ReturnType); |
||||
for (int j = 0; j < l[i].Parameters.Count; ++j) { |
||||
l[i].Parameters[j].ReturnType = TranslateType(l[i].Parameters[j].ReturnType); |
||||
} |
||||
} |
||||
} |
||||
return l; |
||||
} |
||||
|
||||
public override List<IField> GetFields() |
||||
{ |
||||
List<IField> l = baseType.GetFields(); |
||||
for (int i = 0; i < l.Count; ++i) { |
||||
if (CheckReturnType(l[i].ReturnType)) { |
||||
l[i] = (IField)l[i].CreateSpecializedMember(); |
||||
if (l[i].DeclaringType == baseType.GetUnderlyingClass()) { |
||||
l[i].DeclaringTypeReference = this; |
||||
} |
||||
l[i].ReturnType = TranslateType(l[i].ReturnType); |
||||
} |
||||
} |
||||
return l; |
||||
} |
||||
|
||||
public override List<IEvent> GetEvents() |
||||
{ |
||||
List<IEvent> l = baseType.GetEvents(); |
||||
for (int i = 0; i < l.Count; ++i) { |
||||
if (CheckReturnType(l[i].ReturnType)) { |
||||
l[i] = (IEvent)l[i].CreateSpecializedMember(); |
||||
if (l[i].DeclaringType == baseType.GetUnderlyingClass()) { |
||||
l[i].DeclaringTypeReference = this; |
||||
} |
||||
l[i].ReturnType = TranslateType(l[i].ReturnType); |
||||
} |
||||
} |
||||
return l; |
||||
} |
||||
|
||||
public override string ToString() |
||||
{ |
||||
string r = "[ConstructedReturnType: "; |
||||
r += baseType; |
||||
r += "<"; |
||||
for (int i = 0; i < typeArguments.Count; i++) { |
||||
if (i > 0) r += ","; |
||||
if (typeArguments[i] != null) { |
||||
r += typeArguments[i]; |
||||
} |
||||
} |
||||
return r + ">]"; |
||||
} |
||||
} |
||||
} |
||||
@ -0,0 +1,29 @@
@@ -0,0 +1,29 @@
|
||||
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
|
||||
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
|
||||
|
||||
using System; |
||||
|
||||
namespace ICSharpCode.SharpDevelop.Dom |
||||
{ |
||||
/// <summary>
|
||||
/// A return type that modifies the base return type and is not regarded equal to its base type.
|
||||
/// </summary>
|
||||
public abstract class DecoratingReturnType : ProxyReturnType |
||||
{ |
||||
public abstract override bool Equals(IReturnType other); |
||||
public abstract override int GetHashCode(); |
||||
|
||||
public sealed override bool IsDefaultReturnType { |
||||
get { |
||||
return false; |
||||
} |
||||
} |
||||
|
||||
public abstract override T CastToDecoratingReturnType<T>(); |
||||
|
||||
public override IReturnType GetDirectReturnType() |
||||
{ |
||||
return this; |
||||
} |
||||
} |
||||
} |
||||
@ -0,0 +1,88 @@
@@ -0,0 +1,88 @@
|
||||
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
|
||||
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
|
||||
|
||||
using System; |
||||
using System.Collections.Generic; |
||||
using System.Collections.ObjectModel; |
||||
|
||||
namespace ICSharpCode.SharpDevelop.Dom |
||||
{ |
||||
public class DefaultAttribute : AbstractFreezable, IAttribute |
||||
{ |
||||
public static readonly IList<IAttribute> EmptyAttributeList = EmptyList<IAttribute>.Instance; |
||||
|
||||
IList<object> positionalArguments; |
||||
IDictionary<string, object> namedArguments; |
||||
|
||||
protected override void FreezeInternal() |
||||
{ |
||||
if (positionalArguments.Count == 0) |
||||
positionalArguments = EmptyList<object>.Instance; |
||||
else |
||||
positionalArguments = new ReadOnlyCollection<object>(positionalArguments); |
||||
|
||||
namedArguments = new ReadOnlyDictionary<string, object>(namedArguments); |
||||
|
||||
base.FreezeInternal(); |
||||
} |
||||
|
||||
public DefaultAttribute(IReturnType attributeType) : this(attributeType, AttributeTarget.None) {} |
||||
|
||||
public DefaultAttribute(IReturnType attributeType, AttributeTarget attributeTarget) |
||||
: this(attributeType, attributeTarget, null, null) |
||||
{ |
||||
} |
||||
|
||||
public DefaultAttribute(IReturnType attributeType, AttributeTarget attributeTarget, IList<object> positionalArguments, IDictionary<string, object> namedArguments) |
||||
{ |
||||
if (attributeType == null) |
||||
throw new ArgumentNullException("attributeType"); |
||||
this.AttributeType = attributeType; |
||||
this.AttributeTarget = attributeTarget; |
||||
this.positionalArguments = positionalArguments ?? new List<object>(); |
||||
this.namedArguments = namedArguments ?? new SortedList<string, object>(); |
||||
} |
||||
|
||||
IReturnType attributeType; |
||||
public IReturnType AttributeType { |
||||
get { return attributeType; } |
||||
set { |
||||
CheckBeforeMutation(); |
||||
attributeType = value; |
||||
} |
||||
} |
||||
AttributeTarget attributeTarget; |
||||
public AttributeTarget AttributeTarget { |
||||
get { return attributeTarget; } |
||||
set { |
||||
CheckBeforeMutation(); |
||||
attributeTarget = value; |
||||
} |
||||
} |
||||
|
||||
public IList<object> PositionalArguments { |
||||
get { return positionalArguments; } |
||||
} |
||||
|
||||
public IDictionary<string, object> NamedArguments { |
||||
get { return namedArguments; } |
||||
} |
||||
|
||||
ICompilationUnit compilationUnit; |
||||
public ICompilationUnit CompilationUnit { |
||||
get { return compilationUnit; } |
||||
set { |
||||
CheckBeforeMutation(); |
||||
compilationUnit = value; |
||||
} |
||||
} |
||||
DomRegion region; |
||||
public DomRegion Region { |
||||
get { return region; } |
||||
set { |
||||
CheckBeforeMutation(); |
||||
region = value; |
||||
} |
||||
} |
||||
} |
||||
} |
||||
@ -0,0 +1,662 @@
@@ -0,0 +1,662 @@
|
||||
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
|
||||
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
|
||||
|
||||
using System; |
||||
using System.Collections.Generic; |
||||
using System.Linq; |
||||
using System.Threading; |
||||
|
||||
namespace ICSharpCode.SharpDevelop.Dom |
||||
{ |
||||
public class DefaultClass : AbstractEntity, IClass, IComparable |
||||
{ |
||||
ClassType classType; |
||||
DomRegion region; |
||||
|
||||
ICompilationUnit compilationUnit; |
||||
|
||||
IList<IReturnType> baseTypes; |
||||
|
||||
IList<IClass> innerClasses; |
||||
IList<IField> fields; |
||||
IList<IProperty> properties; |
||||
IList<IMethod> methods; |
||||
IList<IEvent> events; |
||||
IList<ITypeParameter> typeParameters; |
||||
IUsingScope usingScope; |
||||
|
||||
protected override void FreezeInternal() |
||||
{ |
||||
baseTypes = FreezeList(baseTypes); |
||||
innerClasses = FreezeList(innerClasses); |
||||
fields = FreezeList(fields); |
||||
properties = FreezeList(properties); |
||||
methods = FreezeList(methods); |
||||
events = FreezeList(events); |
||||
typeParameters = FreezeList(typeParameters); |
||||
base.FreezeInternal(); |
||||
} |
||||
|
||||
/* |
||||
public virtual IClass Unfreeze() |
||||
{ |
||||
DefaultClass copy = new DefaultClass(compilationUnit, DeclaringType); |
||||
copy.FullyQualifiedName = this.FullyQualifiedName; |
||||
copy.Attributes.AddRange(this.Attributes); |
||||
copy.BaseTypes.AddRange(this.BaseTypes); |
||||
copy.BodyRegion = this.BodyRegion; |
||||
copy.ClassType = this.ClassType; |
||||
copy.Documentation = this.Documentation; |
||||
copy.Events.AddRange(this.Events); |
||||
copy.Fields.AddRange(this.Fields); |
||||
copy.InnerClasses.AddRange(this.InnerClasses); |
||||
copy.Methods.AddRange(this.Methods); |
||||
copy.Modifiers = this.Modifiers; |
||||
copy.Properties.AddRange(this.Properties); |
||||
copy.Region = this.Region; |
||||
copy.TypeParameters.AddRange(this.TypeParameters); |
||||
copy.UserData = this.UserData; |
||||
return copy; |
||||
} |
||||
*/ |
||||
|
||||
byte flags = addDefaultConstructorIfRequiredFlag; |
||||
const byte calculatedFlagsReady = 0x01; |
||||
const byte hasPublicOrInternalStaticMembersFlag = 0x02; |
||||
const byte hasExtensionMethodsFlag = 0x04; |
||||
const byte addDefaultConstructorIfRequiredFlag = 0x08; |
||||
|
||||
internal byte CalculatedFlags { |
||||
get { |
||||
if ((flags & calculatedFlagsReady) == 0) { |
||||
flags |= calculatedFlagsReady; |
||||
foreach (IMember m in this.Fields) { |
||||
if (m.IsStatic && (m.IsPublic || m.IsInternal)) { |
||||
flags |= hasPublicOrInternalStaticMembersFlag; |
||||
} |
||||
} |
||||
foreach (IProperty m in this.Properties) { |
||||
if (m.IsStatic && (m.IsPublic || m.IsInternal)) { |
||||
flags |= hasPublicOrInternalStaticMembersFlag; |
||||
} |
||||
if (m.IsExtensionMethod) { |
||||
flags |= hasExtensionMethodsFlag; |
||||
} |
||||
} |
||||
foreach (IMethod m in this.Methods) { |
||||
if (m.IsStatic && (m.IsPublic || m.IsInternal)) { |
||||
flags |= hasPublicOrInternalStaticMembersFlag; |
||||
} |
||||
if (m.IsExtensionMethod) { |
||||
flags |= hasExtensionMethodsFlag; |
||||
} |
||||
} |
||||
foreach (IMember m in this.Events) { |
||||
if (m.IsStatic && (m.IsPublic || m.IsInternal)) { |
||||
flags |= hasPublicOrInternalStaticMembersFlag; |
||||
} |
||||
} |
||||
foreach (IClass c in this.InnerClasses) { |
||||
if (c.IsPublic || c.IsInternal) { |
||||
flags |= hasPublicOrInternalStaticMembersFlag; |
||||
} |
||||
} |
||||
} |
||||
return flags; |
||||
} |
||||
set { |
||||
CheckBeforeMutation(); |
||||
flags = value; |
||||
} |
||||
} |
||||
public bool HasPublicOrInternalStaticMembers { |
||||
get { |
||||
return (CalculatedFlags & hasPublicOrInternalStaticMembersFlag) == hasPublicOrInternalStaticMembersFlag; |
||||
} |
||||
} |
||||
public bool HasExtensionMethods { |
||||
get { |
||||
return (CalculatedFlags & hasExtensionMethodsFlag) == hasExtensionMethodsFlag; |
||||
} |
||||
} |
||||
public bool AddDefaultConstructorIfRequired { |
||||
get { |
||||
return (flags & addDefaultConstructorIfRequiredFlag) == addDefaultConstructorIfRequiredFlag; |
||||
} |
||||
set { |
||||
if (value) |
||||
flags |= addDefaultConstructorIfRequiredFlag; |
||||
else |
||||
flags &= unchecked((byte)~addDefaultConstructorIfRequiredFlag); |
||||
} |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Gets the using scope of contains this class.
|
||||
/// </summary>
|
||||
public IUsingScope UsingScope { |
||||
get { return usingScope; } |
||||
set { |
||||
if (value == null) |
||||
throw new ArgumentNullException("UsingScope"); |
||||
CheckBeforeMutation(); |
||||
usingScope = value; |
||||
} |
||||
} |
||||
|
||||
public DefaultClass(ICompilationUnit compilationUnit, string fullyQualifiedName) : base(null) |
||||
{ |
||||
if (compilationUnit == null) |
||||
throw new ArgumentNullException("compilationUnit"); |
||||
if (fullyQualifiedName == null) |
||||
throw new ArgumentNullException("fullyQualifiedName"); |
||||
this.compilationUnit = compilationUnit; |
||||
this.FullyQualifiedName = fullyQualifiedName; |
||||
this.UsingScope = compilationUnit.UsingScope; |
||||
} |
||||
|
||||
public DefaultClass(ICompilationUnit compilationUnit, IClass declaringType) : base(declaringType) |
||||
{ |
||||
if (compilationUnit == null) |
||||
throw new ArgumentNullException("compilationUnit"); |
||||
this.compilationUnit = compilationUnit; |
||||
this.UsingScope = compilationUnit.UsingScope; |
||||
} |
||||
|
||||
public DefaultClass(ICompilationUnit compilationUnit, ClassType classType, ModifierEnum modifiers, DomRegion region, IClass declaringType) : base(declaringType) |
||||
{ |
||||
if (compilationUnit == null) |
||||
throw new ArgumentNullException("compilationUnit"); |
||||
this.compilationUnit = compilationUnit; |
||||
this.region = region; |
||||
this.classType = classType; |
||||
Modifiers = modifiers; |
||||
this.UsingScope = compilationUnit.UsingScope; |
||||
} |
||||
|
||||
// fields must be volatile to ensure that the optimizer doesn't reorder accesses to it
|
||||
// or causes DefaultReturnType to return null when the local copy of this.defaultReturnType is
|
||||
// optimized away.
|
||||
volatile IReturnType defaultReturnType; |
||||
bool hasCompoundClass; |
||||
|
||||
public IReturnType DefaultReturnType { |
||||
get { |
||||
IReturnType defaultReturnType = this.defaultReturnType; |
||||
if (defaultReturnType == null) { |
||||
lock (this) { |
||||
this.defaultReturnType = defaultReturnType = CreateDefaultReturnType(); |
||||
} |
||||
} |
||||
return defaultReturnType; |
||||
} |
||||
} |
||||
|
||||
protected virtual IReturnType CreateDefaultReturnType() |
||||
{ |
||||
if (hasCompoundClass) { |
||||
return new GetClassReturnType(ProjectContent, FullyQualifiedName, TypeParameters.Count); |
||||
} else { |
||||
return new DefaultReturnType(this); |
||||
} |
||||
} |
||||
|
||||
bool IClass.HasCompoundClass { |
||||
get { return hasCompoundClass; } |
||||
set { |
||||
if (hasCompoundClass != value) { |
||||
lock (this) { |
||||
hasCompoundClass = value; |
||||
defaultReturnType = null; |
||||
} |
||||
} |
||||
} |
||||
} |
||||
|
||||
public bool IsPartial { |
||||
get { |
||||
return (this.Modifiers & ModifierEnum.Partial) == ModifierEnum.Partial; |
||||
} |
||||
set { |
||||
CheckBeforeMutation(); |
||||
if (value) |
||||
this.Modifiers |= ModifierEnum.Partial; |
||||
else |
||||
this.Modifiers &= ~ModifierEnum.Partial; |
||||
} |
||||
} |
||||
|
||||
public IClass GetCompoundClass() |
||||
{ |
||||
return this.DefaultReturnType.GetUnderlyingClass() ?? this; |
||||
} |
||||
|
||||
protected override void OnFullyQualifiedNameChanged(EventArgs e) |
||||
{ |
||||
base.OnFullyQualifiedNameChanged(e); |
||||
defaultReturnType = null; // re-create default return type
|
||||
} |
||||
|
||||
public sealed override ICompilationUnit CompilationUnit { |
||||
[System.Diagnostics.DebuggerStepThrough] |
||||
get { |
||||
return compilationUnit; |
||||
} |
||||
} |
||||
|
||||
public ClassType ClassType { |
||||
get { |
||||
return classType; |
||||
} |
||||
set { |
||||
CheckBeforeMutation(); |
||||
classType = value; |
||||
} |
||||
} |
||||
|
||||
public DomRegion Region { |
||||
get { |
||||
return region; |
||||
} |
||||
set { |
||||
CheckBeforeMutation(); |
||||
region = value; |
||||
} |
||||
} |
||||
|
||||
public override string DotNetName { |
||||
get { |
||||
string fullName; |
||||
int typeParametersCount = this.TypeParameters.Count; |
||||
if (this.DeclaringType != null) { |
||||
fullName = this.DeclaringType.DotNetName + "+" + this.Name; |
||||
typeParametersCount -= this.DeclaringType.TypeParameters.Count; |
||||
} else { |
||||
fullName = this.FullyQualifiedName; |
||||
} |
||||
if (typeParametersCount == 0) { |
||||
return fullName; |
||||
} else { |
||||
return fullName + "`" + typeParametersCount; |
||||
} |
||||
} |
||||
} |
||||
|
||||
public override string DocumentationTag { |
||||
get { |
||||
return "T:" + DotNetName; |
||||
} |
||||
} |
||||
|
||||
public IList<IReturnType> BaseTypes { |
||||
get { |
||||
if (baseTypes == null) { |
||||
baseTypes = new List<IReturnType>(); |
||||
} |
||||
return baseTypes; |
||||
} |
||||
} |
||||
|
||||
public virtual IList<IClass> InnerClasses { |
||||
get { |
||||
if (innerClasses == null) { |
||||
innerClasses = new List<IClass>(); |
||||
} |
||||
return innerClasses; |
||||
} |
||||
} |
||||
|
||||
public virtual IList<IField> Fields { |
||||
get { |
||||
if (fields == null) { |
||||
fields = new List<IField>(); |
||||
} |
||||
return fields; |
||||
} |
||||
} |
||||
|
||||
public virtual IList<IProperty> Properties { |
||||
get { |
||||
if (properties == null) { |
||||
properties = new List<IProperty>(); |
||||
} |
||||
return properties; |
||||
} |
||||
} |
||||
|
||||
public virtual IList<IMethod> Methods { |
||||
get { |
||||
if (methods == null) { |
||||
methods = new List<IMethod>(); |
||||
} |
||||
return methods; |
||||
} |
||||
} |
||||
|
||||
public virtual IList<IEvent> Events { |
||||
get { |
||||
if (events == null) { |
||||
events = new List<IEvent>(); |
||||
} |
||||
return events; |
||||
} |
||||
} |
||||
|
||||
public virtual IList<ITypeParameter> TypeParameters { |
||||
get { |
||||
if (typeParameters == null) { |
||||
typeParameters = new List<ITypeParameter>(); |
||||
} |
||||
return typeParameters; |
||||
} |
||||
set { |
||||
CheckBeforeMutation(); |
||||
typeParameters = value; |
||||
} |
||||
} |
||||
|
||||
public virtual int CompareTo(IClass value) |
||||
{ |
||||
int cmp; |
||||
|
||||
if(0 != (cmp = base.CompareTo((IEntity)value))) { |
||||
return cmp; |
||||
} |
||||
|
||||
if (FullyQualifiedName != null) { |
||||
cmp = FullyQualifiedName.CompareTo(value.FullyQualifiedName); |
||||
if (cmp != 0) { |
||||
return cmp; |
||||
} |
||||
return this.TypeParameters.Count - value.TypeParameters.Count; |
||||
} |
||||
return -1; |
||||
} |
||||
|
||||
int IComparable.CompareTo(object o) |
||||
{ |
||||
return CompareTo((IClass)o); |
||||
} |
||||
|
||||
volatile IClass[] inheritanceTreeCache; |
||||
volatile IClass[] inheritanceTreeClassesOnlyCache; |
||||
|
||||
public IEnumerable<IClass> ClassInheritanceTree { |
||||
get { |
||||
IClass compoundClass = GetCompoundClass(); |
||||
if (compoundClass != this) |
||||
return compoundClass.ClassInheritanceTree; |
||||
|
||||
// Notes:
|
||||
// the ClassInheritanceTree must work even if the following things happen:
|
||||
// - cyclic inheritance
|
||||
// - multithreaded calls
|
||||
|
||||
// Recursive calls are possible if the SearchType request done by GetUnderlyingClass()
|
||||
// uses ClassInheritanceTree.
|
||||
// Such recursive calls are tricky, they have caused incorrect behavior (SD2-1474)
|
||||
// or performance problems (SD2-1510) in the past.
|
||||
// As of revision 3769, NRefactoryAstConvertVisitor sets up the SearchClassReturnType
|
||||
// used for base types so that it does not look up inner classes in the class itself,
|
||||
// so the ClassInheritanceTree is not used created in those cases.
|
||||
// However, other language bindings might not set up base types correctly, so it's
|
||||
// still possible that ClassInheritanceTree is called recursivly.
|
||||
// In that case, we'll return an invalid inheritance tree because of
|
||||
// ProxyReturnType's automatic stack overflow prevention.
|
||||
|
||||
// We do not use locks to protect against multithreaded calls because
|
||||
// resolving one class's base types can cause getting the inheritance tree
|
||||
// of another class -> beware of deadlocks
|
||||
|
||||
IClass[] inheritanceTree = this.inheritanceTreeCache; |
||||
if (inheritanceTree != null) { |
||||
return inheritanceTree; |
||||
} |
||||
|
||||
inheritanceTree = CalculateClassInheritanceTree(false); |
||||
|
||||
this.inheritanceTreeCache = inheritanceTree; |
||||
if (!KeepInheritanceTree) |
||||
DomCache.RegisterForClear(ClearCachedInheritanceTree); |
||||
|
||||
return inheritanceTree; |
||||
} |
||||
} |
||||
|
||||
public IEnumerable<IClass> ClassInheritanceTreeClassesOnly { |
||||
get { |
||||
IClass compoundClass = GetCompoundClass(); |
||||
if (compoundClass != this) |
||||
return compoundClass.ClassInheritanceTreeClassesOnly; |
||||
|
||||
// Notes:
|
||||
// the ClassInheritanceTree must work even if the following things happen:
|
||||
// - cyclic inheritance
|
||||
// - multithreaded calls
|
||||
|
||||
// Recursive calls are possible if the SearchType request done by GetUnderlyingClass()
|
||||
// uses ClassInheritanceTree.
|
||||
// Such recursive calls are tricky, they have caused incorrect behavior (SD2-1474)
|
||||
// or performance problems (SD2-1510) in the past.
|
||||
// As of revision 3769, NRefactoryAstConvertVisitor sets up the SearchClassReturnType
|
||||
// used for base types so that it does not look up inner classes in the class itself,
|
||||
// so the ClassInheritanceTree is not used created in those cases.
|
||||
// However, other language bindings might not set up base types correctly, so it's
|
||||
// still possible that ClassInheritanceTree is called recursivly.
|
||||
// In that case, we'll return an invalid inheritance tree because of
|
||||
// ProxyReturnType's automatic stack overflow prevention.
|
||||
|
||||
// We do not use locks to protect against multithreaded calls because
|
||||
// resolving one class's base types can cause getting the inheritance tree
|
||||
// of another class -> beware of deadlocks
|
||||
|
||||
IClass[] inheritanceTreeClassesOnly = this.inheritanceTreeClassesOnlyCache; |
||||
if (inheritanceTreeClassesOnly != null) { |
||||
return inheritanceTreeClassesOnly; |
||||
} |
||||
|
||||
inheritanceTreeClassesOnly = CalculateClassInheritanceTree(true); |
||||
|
||||
this.inheritanceTreeClassesOnlyCache = inheritanceTreeClassesOnly; |
||||
if (!KeepInheritanceTree) |
||||
DomCache.RegisterForClear(ClearCachedInheritanceTree); |
||||
|
||||
return inheritanceTreeClassesOnly; |
||||
} |
||||
} |
||||
|
||||
void ClearCachedInheritanceTree() |
||||
{ |
||||
inheritanceTreeClassesOnlyCache = null; |
||||
inheritanceTreeCache = null; |
||||
} |
||||
|
||||
IClass[] CalculateClassInheritanceTree(bool ignoreInterfaces) |
||||
{ |
||||
List<IClass> visitedList = new List<IClass>(); |
||||
Queue<IReturnType> typesToVisit = new Queue<IReturnType>(); |
||||
bool enqueuedLastBaseType = false; |
||||
IClass currentClass = this; |
||||
IReturnType nextType; |
||||
do { |
||||
if (currentClass != null) { |
||||
if ((!ignoreInterfaces || currentClass.ClassType != ClassType.Interface) && !visitedList.Contains(currentClass)) { |
||||
visitedList.Add(currentClass); |
||||
foreach (IReturnType type in currentClass.BaseTypes) { |
||||
typesToVisit.Enqueue(type); |
||||
} |
||||
} |
||||
} |
||||
if (typesToVisit.Count > 0) { |
||||
nextType = typesToVisit.Dequeue(); |
||||
} else { |
||||
nextType = enqueuedLastBaseType ? null : GetBaseTypeByClassType(this); |
||||
enqueuedLastBaseType = true; |
||||
} |
||||
if (nextType != null) { |
||||
currentClass = nextType.GetUnderlyingClass(); |
||||
} |
||||
} while (nextType != null); |
||||
return visitedList.ToArray(); |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Specifies whether to keep the inheritance tree when the DomCache is cleared.
|
||||
/// </summary>
|
||||
protected virtual bool KeepInheritanceTree { |
||||
get { return false; } |
||||
} |
||||
|
||||
IReturnType cachedBaseType; |
||||
|
||||
public IReturnType BaseType { |
||||
get { |
||||
if (cachedBaseType == null) { |
||||
foreach (IReturnType baseType in this.BaseTypes) { |
||||
IClass baseClass = baseType.GetUnderlyingClass(); |
||||
if (baseClass != null && baseClass.ClassType == this.ClassType) { |
||||
cachedBaseType = baseType; |
||||
break; |
||||
} |
||||
} |
||||
} |
||||
if (cachedBaseType == null) { |
||||
return GetBaseTypeByClassType(this); |
||||
} else { |
||||
return cachedBaseType; |
||||
} |
||||
} |
||||
} |
||||
|
||||
internal static IReturnType GetBaseTypeByClassType(IClass c) |
||||
{ |
||||
switch (c.ClassType) { |
||||
case ClassType.Class: |
||||
case ClassType.Interface: |
||||
if (c.FullyQualifiedName != "System.Object") { |
||||
return c.ProjectContent.SystemTypes.Object; |
||||
} |
||||
break; |
||||
case ClassType.Enum: |
||||
return c.ProjectContent.SystemTypes.Enum; |
||||
case ClassType.Delegate: |
||||
return c.ProjectContent.SystemTypes.Delegate; |
||||
case ClassType.Struct: |
||||
return c.ProjectContent.SystemTypes.ValueType; |
||||
} |
||||
return null; |
||||
} |
||||
|
||||
public IClass BaseClass { |
||||
get { |
||||
foreach (IReturnType baseType in this.BaseTypes) { |
||||
IClass baseClass = baseType.GetUnderlyingClass(); |
||||
if (baseClass != null && baseClass.ClassType == this.ClassType) |
||||
return baseClass; |
||||
} |
||||
IReturnType defaultBaseType = GetBaseTypeByClassType(this); |
||||
if (defaultBaseType != null) |
||||
return defaultBaseType.GetUnderlyingClass(); |
||||
else |
||||
return null; |
||||
} |
||||
} |
||||
|
||||
public bool IsTypeInInheritanceTree(IClass possibleBaseClass) |
||||
{ |
||||
if (possibleBaseClass == null) { |
||||
return false; |
||||
} |
||||
foreach (IClass baseClass in this.ClassInheritanceTree) { |
||||
if (possibleBaseClass.FullyQualifiedName == baseClass.FullyQualifiedName |
||||
&& possibleBaseClass.TypeParameters.Count == baseClass.TypeParameters.Count) |
||||
return true; |
||||
} |
||||
return false; |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Searches the member with the specified name. Returns the first member/overload found.
|
||||
/// </summary>
|
||||
public IMember SearchMember(string memberName, LanguageProperties language) |
||||
{ |
||||
if (memberName == null || memberName.Length == 0) { |
||||
return null; |
||||
} |
||||
StringComparer cmp = language.NameComparer; |
||||
foreach (IProperty p in Properties) { |
||||
if (cmp.Equals(p.Name, memberName)) { |
||||
return p; |
||||
} |
||||
} |
||||
foreach (IEvent e in Events) { |
||||
if (cmp.Equals(e.Name, memberName)) { |
||||
return e; |
||||
} |
||||
} |
||||
foreach (IField f in Fields) { |
||||
if (cmp.Equals(f.Name, memberName)) { |
||||
return f; |
||||
} |
||||
} |
||||
foreach (IMethod m in Methods) { |
||||
if (cmp.Equals(m.Name, memberName)) { |
||||
return m; |
||||
} |
||||
} |
||||
return null; |
||||
} |
||||
|
||||
public IClass GetInnermostClass(int caretLine, int caretColumn) |
||||
{ |
||||
foreach (IClass c in InnerClasses) { |
||||
if (c != null && IsInside(c, caretLine, caretColumn)) { |
||||
return c.GetInnermostClass(caretLine, caretColumn); |
||||
} |
||||
} |
||||
return this; |
||||
} |
||||
|
||||
internal static bool IsInside(IClass c, int caretLine, int caretColumn) |
||||
{ |
||||
return c.Region.IsInside(caretLine, caretColumn) |
||||
|| c.Attributes.Any((IAttribute a) => a.Region.IsInside(caretLine, caretColumn)); |
||||
} |
||||
|
||||
public List<IClass> GetAccessibleTypes(IClass callingClass) |
||||
{ |
||||
List<IClass> types = new List<IClass>(); |
||||
List<IClass> visitedTypes = new List<IClass>(); |
||||
|
||||
IClass currentClass = this; |
||||
do { |
||||
if (visitedTypes.Contains(currentClass)) |
||||
break; |
||||
visitedTypes.Add(currentClass); |
||||
bool isClassInInheritanceTree = callingClass != null ? callingClass.IsTypeInInheritanceTree(currentClass) : false; |
||||
foreach (IClass c in currentClass.InnerClasses) { |
||||
if (c.IsAccessible(callingClass, isClassInInheritanceTree)) { |
||||
types.Add(c); |
||||
} |
||||
} |
||||
currentClass = currentClass.BaseClass; |
||||
} while (currentClass != null); |
||||
return types; |
||||
} |
||||
|
||||
public IEnumerable<IMember> AllMembers { |
||||
get { |
||||
IEnumerable<IMember> p = properties; |
||||
return p.Concat(methods) |
||||
.Concat(fields) |
||||
.Concat(events); |
||||
} |
||||
} |
||||
|
||||
public override EntityType EntityType { |
||||
get { |
||||
return EntityType.Class; |
||||
} |
||||
} |
||||
} |
||||
} |
||||
@ -0,0 +1,47 @@
@@ -0,0 +1,47 @@
|
||||
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
|
||||
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
|
||||
|
||||
using System; |
||||
|
||||
namespace ICSharpCode.SharpDevelop.Dom { |
||||
|
||||
public class DefaultComment : IComment |
||||
{ |
||||
bool isBlockComment; |
||||
string commentTag; |
||||
string commentText; |
||||
DomRegion region; |
||||
|
||||
public DefaultComment(bool isBlockComment, string commentTag, string commentText, DomRegion region) |
||||
{ |
||||
this.isBlockComment = isBlockComment; |
||||
this.commentTag = commentTag; |
||||
this.commentText = commentText; |
||||
this.region = region; |
||||
} |
||||
|
||||
public bool IsBlockComment { |
||||
get { |
||||
return isBlockComment; |
||||
} |
||||
} |
||||
|
||||
public string CommentTag { |
||||
get { |
||||
return commentTag; |
||||
} |
||||
} |
||||
|
||||
public string CommentText { |
||||
get { |
||||
return commentText; |
||||
} |
||||
} |
||||
|
||||
public DomRegion Region { |
||||
get { |
||||
return region; |
||||
} |
||||
} |
||||
} |
||||
} |
||||
@ -0,0 +1,160 @@
@@ -0,0 +1,160 @@
|
||||
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
|
||||
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
|
||||
|
||||
using System; |
||||
using System.Collections.Generic; |
||||
using System.Diagnostics; |
||||
|
||||
namespace ICSharpCode.SharpDevelop.Dom |
||||
{ |
||||
public class DefaultCompilationUnit : AbstractFreezable, ICompilationUnit |
||||
{ |
||||
public static readonly ICompilationUnit DummyCompilationUnit = new DefaultCompilationUnit(DefaultProjectContent.DummyProjectContent).FreezeAndReturnSelf(); |
||||
|
||||
DefaultCompilationUnit FreezeAndReturnSelf() |
||||
{ |
||||
Freeze(); |
||||
return this; |
||||
} |
||||
|
||||
IUsingScope usingScope = new DefaultUsingScope(); |
||||
IList<IClass> classes = new List<IClass>(); |
||||
IList<IAttribute> attributes = new List<IAttribute>(); |
||||
IList<FoldingRegion> foldingRegions = new List<FoldingRegion>(); |
||||
IList<TagComment> tagComments = new List<TagComment>(); |
||||
|
||||
protected override void FreezeInternal() |
||||
{ |
||||
// Deep Freeze: freeze lists and their contents
|
||||
classes = FreezeList(classes); |
||||
attributes = FreezeList(attributes); |
||||
foldingRegions = FreezeList(foldingRegions); |
||||
tagComments = FreezeList(tagComments); |
||||
usingScope.Freeze(); |
||||
|
||||
base.FreezeInternal(); |
||||
} |
||||
|
||||
bool errorsDuringCompile = false; |
||||
object tag = null; |
||||
string fileName = null; |
||||
IProjectContent projectContent; |
||||
|
||||
/// <summary>
|
||||
/// Source code file this compilation unit was created from. For compiled are compiler-generated
|
||||
/// code, this property returns null.
|
||||
/// </summary>
|
||||
public string FileName { |
||||
get { |
||||
return fileName; |
||||
} |
||||
set { |
||||
CheckBeforeMutation(); |
||||
fileName = value; |
||||
} |
||||
} |
||||
|
||||
public IProjectContent ProjectContent { |
||||
[System.Diagnostics.DebuggerStepThrough] |
||||
get { |
||||
return projectContent; |
||||
} |
||||
} |
||||
|
||||
public bool ErrorsDuringCompile { |
||||
get { |
||||
return errorsDuringCompile; |
||||
} |
||||
set { |
||||
CheckBeforeMutation(); |
||||
errorsDuringCompile = value; |
||||
} |
||||
} |
||||
|
||||
public object Tag { |
||||
get { |
||||
return tag; |
||||
} |
||||
set { |
||||
CheckBeforeMutation(); |
||||
tag = value; |
||||
} |
||||
} |
||||
|
||||
public virtual IUsingScope UsingScope { |
||||
get { return usingScope; } |
||||
set { |
||||
if (value == null) |
||||
throw new ArgumentNullException("UsingScope"); |
||||
CheckBeforeMutation(); |
||||
usingScope = value; |
||||
} |
||||
} |
||||
|
||||
public virtual IList<IAttribute> Attributes { |
||||
get { |
||||
return attributes; |
||||
} |
||||
} |
||||
|
||||
public virtual IList<IClass> Classes { |
||||
get { |
||||
return classes; |
||||
} |
||||
} |
||||
|
||||
public IList<FoldingRegion> FoldingRegions { |
||||
get { |
||||
return foldingRegions; |
||||
} |
||||
} |
||||
|
||||
public virtual IList<IComment> MiscComments { |
||||
get { |
||||
return null; |
||||
} |
||||
} |
||||
|
||||
public virtual IList<IComment> DokuComments { |
||||
get { |
||||
return null; |
||||
} |
||||
} |
||||
|
||||
public virtual IList<TagComment> TagComments { |
||||
get { |
||||
return tagComments; |
||||
} |
||||
} |
||||
|
||||
public DefaultCompilationUnit(IProjectContent projectContent) |
||||
{ |
||||
if (projectContent == null) |
||||
throw new ArgumentNullException("projectContent"); |
||||
this.projectContent = projectContent; |
||||
} |
||||
|
||||
public IClass GetInnermostClass(int caretLine, int caretColumn) |
||||
{ |
||||
foreach (IClass c in Classes) { |
||||
if (c != null && DefaultClass.IsInside(c, caretLine, caretColumn)) { |
||||
return c.GetInnermostClass(caretLine, caretColumn); |
||||
} |
||||
} |
||||
return null; |
||||
} |
||||
|
||||
public override string ToString() |
||||
{ |
||||
return String.Format("[CompilationUnit: classes = {0}, fileName = {1}]", |
||||
classes.Count, |
||||
fileName); |
||||
} |
||||
|
||||
public LanguageProperties Language { |
||||
get { |
||||
return projectContent.Language; |
||||
} |
||||
} |
||||
} |
||||
} |
||||
@ -0,0 +1,117 @@
@@ -0,0 +1,117 @@
|
||||
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
|
||||
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
|
||||
|
||||
using System; |
||||
|
||||
namespace ICSharpCode.SharpDevelop.Dom |
||||
{ |
||||
public class DefaultEvent : AbstractMember, IEvent |
||||
{ |
||||
IMethod addMethod; |
||||
IMethod removeMethod; |
||||
IMethod raiseMethod; |
||||
|
||||
protected override void FreezeInternal() |
||||
{ |
||||
if (addMethod != null) |
||||
addMethod.Freeze(); |
||||
if (removeMethod != null) |
||||
removeMethod.Freeze(); |
||||
if (raiseMethod != null) |
||||
raiseMethod.Freeze(); |
||||
base.FreezeInternal(); |
||||
} |
||||
|
||||
public override string DocumentationTag { |
||||
get { |
||||
return "E:" + this.DotNetName; |
||||
} |
||||
} |
||||
|
||||
public override IMember Clone() |
||||
{ |
||||
DefaultEvent de = new DefaultEvent(Name, ReturnType, Modifiers, Region, BodyRegion, DeclaringType); |
||||
de.CopyDocumentationFrom(this); |
||||
foreach (ExplicitInterfaceImplementation eii in InterfaceImplementations) { |
||||
de.InterfaceImplementations.Add(eii.Clone()); |
||||
} |
||||
if (addMethod != null) |
||||
de.addMethod = (IMethod)addMethod.Clone(); |
||||
if (removeMethod != null) |
||||
de.removeMethod = (IMethod)removeMethod.Clone(); |
||||
if (raiseMethod != null) |
||||
de.raiseMethod = (IMethod)raiseMethod.Clone(); |
||||
return de; |
||||
} |
||||
|
||||
public DefaultEvent(IClass declaringType, string name) : base(declaringType, name) |
||||
{ |
||||
} |
||||
|
||||
public DefaultEvent(string name, IReturnType type, ModifierEnum m, DomRegion region, DomRegion bodyRegion, IClass declaringType) : base(declaringType, name) |
||||
{ |
||||
this.ReturnType = type; |
||||
this.Region = region; |
||||
this.BodyRegion = bodyRegion; |
||||
Modifiers = (ModifierEnum)m; |
||||
if (Modifiers == ModifierEnum.None) { |
||||
Modifiers = ModifierEnum.Private; |
||||
} |
||||
} |
||||
|
||||
public virtual int CompareTo(IEvent value) |
||||
{ |
||||
int cmp; |
||||
|
||||
if(0 != (cmp = base.CompareTo((IEntity)value))) |
||||
return cmp; |
||||
|
||||
if (FullyQualifiedName != null) { |
||||
return FullyQualifiedName.CompareTo(value.FullyQualifiedName); |
||||
} |
||||
|
||||
return 0; |
||||
} |
||||
|
||||
int IComparable.CompareTo(object value) |
||||
{ |
||||
return CompareTo((IEvent)value); |
||||
} |
||||
|
||||
public virtual IMethod AddMethod { |
||||
get { |
||||
return addMethod; |
||||
} |
||||
set { |
||||
CheckBeforeMutation(); |
||||
addMethod = value; |
||||
} |
||||
} |
||||
|
||||
public virtual IMethod RemoveMethod { |
||||
get { |
||||
return removeMethod; |
||||
} |
||||
set { |
||||
CheckBeforeMutation(); |
||||
removeMethod = value; |
||||
} |
||||
} |
||||
|
||||
public virtual IMethod RaiseMethod { |
||||
get { |
||||
return raiseMethod; |
||||
} |
||||
set { |
||||
CheckBeforeMutation(); |
||||
raiseMethod = value; |
||||
} |
||||
} |
||||
|
||||
public override EntityType EntityType { |
||||
get { |
||||
return EntityType.Event; |
||||
} |
||||
} |
||||
} |
||||
} |
||||
@ -0,0 +1,94 @@
@@ -0,0 +1,94 @@
|
||||
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
|
||||
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
|
||||
|
||||
using System; |
||||
|
||||
namespace ICSharpCode.SharpDevelop.Dom |
||||
{ |
||||
public class DefaultField : AbstractMember, IField |
||||
{ |
||||
public override string DocumentationTag { |
||||
get { |
||||
return "F:" + this.DotNetName; |
||||
} |
||||
} |
||||
|
||||
public DefaultField(IClass declaringType, string name) : base(declaringType, name) |
||||
{ |
||||
} |
||||
|
||||
public DefaultField(IReturnType type, string name, ModifierEnum m, DomRegion region, IClass declaringType) : base(declaringType, name) |
||||
{ |
||||
this.ReturnType = type; |
||||
this.Region = region; |
||||
this.Modifiers = m; |
||||
} |
||||
|
||||
public override IMember Clone() |
||||
{ |
||||
DefaultField field = new DefaultField(ReturnType, Name, Modifiers, Region, DeclaringType); |
||||
field.CopyDocumentationFrom(this); |
||||
return field; |
||||
} |
||||
|
||||
public virtual int CompareTo(IField field) |
||||
{ |
||||
int cmp; |
||||
|
||||
cmp = base.CompareTo((IEntity)field); |
||||
if (cmp != 0) { |
||||
return cmp; |
||||
} |
||||
|
||||
if (FullyQualifiedName != null) { |
||||
return FullyQualifiedName.CompareTo(field.FullyQualifiedName); |
||||
} |
||||
return 0; |
||||
} |
||||
|
||||
int IComparable.CompareTo(object value) |
||||
{ |
||||
return CompareTo((IField)value); |
||||
} |
||||
|
||||
/// <summary>Gets if this field is a local variable that has been converted into a field.</summary>
|
||||
public virtual bool IsLocalVariable { |
||||
get { return false; } |
||||
} |
||||
|
||||
/// <summary>Gets if this field is a parameter that has been converted into a field.</summary>
|
||||
public virtual bool IsParameter { |
||||
get { return false; } |
||||
} |
||||
|
||||
public override EntityType EntityType { |
||||
get { |
||||
return EntityType.Field; |
||||
} |
||||
} |
||||
|
||||
public class LocalVariableField : DefaultField |
||||
{ |
||||
public override bool IsLocalVariable { |
||||
get { return true; } |
||||
} |
||||
|
||||
public LocalVariableField(IReturnType type, string name, DomRegion region, IClass callingClass) |
||||
: base(type, name, ModifierEnum.None, region, callingClass) |
||||
{ |
||||
} |
||||
} |
||||
|
||||
public class ParameterField : DefaultField |
||||
{ |
||||
public override bool IsParameter { |
||||
get { return true; } |
||||
} |
||||
|
||||
public ParameterField(IReturnType type, string name, DomRegion region, IClass callingClass) |
||||
: base(type, name, ModifierEnum.None, region, callingClass) |
||||
{ |
||||
} |
||||
} |
||||
} |
||||
} |
||||
@ -0,0 +1,228 @@
@@ -0,0 +1,228 @@
|
||||
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
|
||||
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
|
||||
|
||||
using System; |
||||
using System.Collections.Generic; |
||||
using System.Linq; |
||||
using System.Text; |
||||
|
||||
namespace ICSharpCode.SharpDevelop.Dom |
||||
{ |
||||
public class Constructor : DefaultMethod |
||||
{ |
||||
public Constructor(ModifierEnum m, DomRegion region, DomRegion bodyRegion, IClass declaringType) |
||||
: base((m & ModifierEnum.Static) != 0 ? "#cctor" : "#ctor", |
||||
declaringType.DefaultReturnType, |
||||
m, region, bodyRegion, declaringType) |
||||
{ |
||||
} |
||||
|
||||
public Constructor(ModifierEnum m, IReturnType returnType, IClass declaringType) |
||||
: base((m & ModifierEnum.Static) != 0 ? "#cctor" : "#ctor", |
||||
returnType, m, DomRegion.Empty, DomRegion.Empty, declaringType) |
||||
{ |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Creates a default constructor for the class.
|
||||
/// The constructor has the region of the class and a documentation comment saying
|
||||
/// it is a default constructor.
|
||||
/// </summary>
|
||||
public static Constructor CreateDefault(IClass c) |
||||
{ |
||||
if (c == null) |
||||
throw new ArgumentNullException("c"); |
||||
|
||||
ModifierEnum modifiers = ModifierEnum.Synthetic; |
||||
if (c.IsAbstract) |
||||
modifiers |= ModifierEnum.Protected; |
||||
else |
||||
modifiers |= ModifierEnum.Public; |
||||
DomRegion region = new DomRegion(c.Region.BeginLine, c.Region.BeginColumn, c.Region.BeginLine, c.Region.BeginColumn); |
||||
Constructor con = new Constructor(modifiers, region, region, c); |
||||
con.Documentation = "Default constructor of " + c.Name; |
||||
return con; |
||||
} |
||||
} |
||||
|
||||
[Serializable] |
||||
public class Destructor : DefaultMethod |
||||
{ |
||||
public Destructor(DomRegion region, DomRegion bodyRegion, IClass declaringType) |
||||
: base("#dtor", null, ModifierEnum.None, region, bodyRegion, declaringType) |
||||
{ |
||||
} |
||||
} |
||||
|
||||
[Serializable] |
||||
public class DefaultMethod : AbstractMember, IMethod |
||||
{ |
||||
IList<IParameter> parameters; |
||||
IList<ITypeParameter> typeParameters; |
||||
IList<string> handlesClauses; |
||||
|
||||
protected override void FreezeInternal() |
||||
{ |
||||
parameters = FreezeList(parameters); |
||||
typeParameters = FreezeList(typeParameters); |
||||
handlesClauses = FreezeList(handlesClauses); |
||||
base.FreezeInternal(); |
||||
} |
||||
|
||||
bool isExtensionMethod; |
||||
|
||||
public bool IsExtensionMethod { |
||||
get { |
||||
return isExtensionMethod; |
||||
} |
||||
set { |
||||
CheckBeforeMutation(); |
||||
isExtensionMethod = value; |
||||
} |
||||
} |
||||
|
||||
public override IMember Clone() |
||||
{ |
||||
DefaultMethod p = new DefaultMethod(Name, ReturnType, Modifiers, Region, BodyRegion, DeclaringType); |
||||
p.parameters = DefaultParameter.Clone(this.Parameters); |
||||
p.typeParameters = new List<ITypeParameter>(this.typeParameters); |
||||
p.CopyDocumentationFrom(this); |
||||
p.isExtensionMethod = this.isExtensionMethod; |
||||
foreach (ExplicitInterfaceImplementation eii in InterfaceImplementations) { |
||||
p.InterfaceImplementations.Add(eii.Clone()); |
||||
} |
||||
return p; |
||||
} |
||||
|
||||
public override string DotNetName { |
||||
get { |
||||
if (typeParameters == null || typeParameters.Count == 0) |
||||
return base.DotNetName; |
||||
else |
||||
return base.DotNetName + "``" + typeParameters.Count; |
||||
} |
||||
} |
||||
|
||||
public override string DocumentationTag { |
||||
get { |
||||
string dotnetName = this.DotNetName; |
||||
StringBuilder b = new StringBuilder("M:", dotnetName.Length + 2); |
||||
b.Append(dotnetName); |
||||
IList<IParameter> paras = this.Parameters; |
||||
if (paras.Count > 0) { |
||||
b.Append('('); |
||||
for (int i = 0; i < paras.Count; ++i) { |
||||
if (i > 0) b.Append(','); |
||||
IReturnType rt = paras[i].ReturnType; |
||||
if (rt != null) { |
||||
b.Append(rt.DotNetName); |
||||
} |
||||
} |
||||
b.Append(')'); |
||||
} |
||||
return b.ToString(); |
||||
} |
||||
} |
||||
|
||||
public virtual IList<ITypeParameter> TypeParameters { |
||||
get { |
||||
if (typeParameters == null) { |
||||
typeParameters = new List<ITypeParameter>(); |
||||
} |
||||
return typeParameters; |
||||
} |
||||
set { |
||||
CheckBeforeMutation(); |
||||
typeParameters = value; |
||||
} |
||||
} |
||||
|
||||
public virtual IList<IParameter> Parameters { |
||||
get { |
||||
if (parameters == null) { |
||||
parameters = new List<IParameter>(); |
||||
} |
||||
return parameters; |
||||
} |
||||
set { |
||||
CheckBeforeMutation(); |
||||
parameters = value; |
||||
} |
||||
} |
||||
|
||||
public IList<string> HandlesClauses { |
||||
get { |
||||
if (handlesClauses == null) { |
||||
handlesClauses = new List<string>(); |
||||
} |
||||
return handlesClauses; |
||||
} |
||||
set { |
||||
CheckBeforeMutation(); |
||||
handlesClauses = value; |
||||
} |
||||
} |
||||
|
||||
public virtual bool IsConstructor { |
||||
get { |
||||
return Name == "#ctor" || Name == "#cctor"; |
||||
} |
||||
} |
||||
|
||||
public virtual bool IsOperator { |
||||
get { |
||||
return Name.StartsWith("op_", StringComparison.Ordinal); |
||||
} |
||||
} |
||||
|
||||
public DefaultMethod(IClass declaringType, string name) : base(declaringType, name) |
||||
{ |
||||
} |
||||
|
||||
public DefaultMethod(string name, IReturnType type, ModifierEnum m, DomRegion region, DomRegion bodyRegion, IClass declaringType) : base(declaringType, name) |
||||
{ |
||||
this.ReturnType = type; |
||||
this.Region = region; |
||||
this.BodyRegion = bodyRegion; |
||||
Modifiers = m; |
||||
} |
||||
|
||||
public override string ToString() |
||||
{ |
||||
return String.Format("[DefaultMethod: {0}]", |
||||
(new Dom.CSharp.CSharpAmbience { |
||||
ConversionFlags = ConversionFlags.StandardConversionFlags |
||||
| ConversionFlags.UseFullyQualifiedMemberNames |
||||
}).Convert(this)); |
||||
} |
||||
|
||||
public virtual int CompareTo(IMethod value) |
||||
{ |
||||
int cmp = string.CompareOrdinal(this.FullyQualifiedName, value.FullyQualifiedName); |
||||
if (cmp != 0) { |
||||
return cmp; |
||||
} |
||||
|
||||
cmp = this.TypeParameters.Count - value.TypeParameters.Count; |
||||
if (cmp != 0) { |
||||
return cmp; |
||||
} |
||||
|
||||
return DiffUtility.Compare(Parameters, value.Parameters); |
||||
} |
||||
|
||||
int IComparable.CompareTo(object value) |
||||
{ |
||||
if (value == null) { |
||||
return 0; |
||||
} |
||||
return CompareTo((IMethod)value); |
||||
} |
||||
|
||||
public override EntityType EntityType { |
||||
get { |
||||
return EntityType.Method; |
||||
} |
||||
} |
||||
} |
||||
} |
||||
@ -0,0 +1,173 @@
@@ -0,0 +1,173 @@
|
||||
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
|
||||
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
|
||||
|
||||
using System; |
||||
using System.Collections.Generic; |
||||
|
||||
namespace ICSharpCode.SharpDevelop.Dom |
||||
{ |
||||
public class DefaultParameter : AbstractFreezable, IParameter |
||||
{ |
||||
public static readonly IList<IParameter> EmptyParameterList = EmptyList<IParameter>.Instance; |
||||
|
||||
string name; |
||||
string documentation; |
||||
|
||||
// int nameHashCode = -1;
|
||||
// int documentationHash = -1;
|
||||
|
||||
IReturnType returnType; |
||||
ParameterModifiers modifier; |
||||
DomRegion region; |
||||
IList<IAttribute> attributes; |
||||
|
||||
protected override void FreezeInternal() |
||||
{ |
||||
attributes = FreezeList(attributes); |
||||
base.FreezeInternal(); |
||||
} |
||||
|
||||
protected DefaultParameter(string name) |
||||
{ |
||||
Name = name; |
||||
} |
||||
|
||||
public DefaultParameter(IParameter p) |
||||
{ |
||||
this.name = p.Name; |
||||
this.region = p.Region; |
||||
this.modifier = p.Modifiers; |
||||
this.returnType = p.ReturnType; |
||||
} |
||||
|
||||
public DefaultParameter(string name, IReturnType type, DomRegion region) : this(name) |
||||
{ |
||||
returnType = type; |
||||
this.region = region; |
||||
} |
||||
|
||||
public DomRegion Region { |
||||
get { |
||||
return region; |
||||
} |
||||
} |
||||
public bool IsOut { |
||||
get { |
||||
return (modifier & ParameterModifiers.Out) == ParameterModifiers.Out; |
||||
} |
||||
} |
||||
public bool IsRef { |
||||
get { |
||||
return (modifier & ParameterModifiers.Ref) == ParameterModifiers.Ref; |
||||
} |
||||
} |
||||
public bool IsParams { |
||||
get { |
||||
return (modifier & ParameterModifiers.Params) == ParameterModifiers.Params; |
||||
} |
||||
} |
||||
public bool IsOptional { |
||||
get { |
||||
return (modifier & ParameterModifiers.Optional) == ParameterModifiers.Optional; |
||||
} |
||||
} |
||||
|
||||
public virtual string Name { |
||||
get { |
||||
return name; |
||||
// return (string)AbstractNamedEntity.fullyQualifiedNames[nameHashCode];
|
||||
} |
||||
set { |
||||
CheckBeforeMutation(); |
||||
name = value; |
||||
// nameHashCode = value.GetHashCode();
|
||||
// if (AbstractNamedEntity.fullyQualifiedNames[nameHashCode] == null) {
|
||||
// AbstractNamedEntity.fullyQualifiedNames[nameHashCode] = value;
|
||||
// }
|
||||
} |
||||
} |
||||
|
||||
public virtual IReturnType ReturnType { |
||||
get { |
||||
return returnType; |
||||
} |
||||
set { |
||||
CheckBeforeMutation(); |
||||
returnType = value; |
||||
} |
||||
} |
||||
|
||||
public virtual IList<IAttribute> Attributes { |
||||
get { |
||||
if (attributes == null) { |
||||
attributes = new List<IAttribute>(); |
||||
} |
||||
return attributes; |
||||
} |
||||
set { |
||||
CheckBeforeMutation(); |
||||
attributes = value; |
||||
} |
||||
} |
||||
|
||||
public virtual ParameterModifiers Modifiers { |
||||
get { |
||||
return modifier; |
||||
} |
||||
set { |
||||
CheckBeforeMutation(); |
||||
modifier = value; |
||||
} |
||||
} |
||||
|
||||
public string Documentation { |
||||
get { |
||||
return documentation; |
||||
// if (documentationHash == -1) {
|
||||
// return String.Empty;
|
||||
// }
|
||||
// return (string)AbstractDecoration.documentationHashtable[documentationHash];
|
||||
} |
||||
set { |
||||
CheckBeforeMutation(); |
||||
documentation = value; |
||||
// documentationHash = value.GetHashCode();
|
||||
// if (AbstractDecoration.documentationHashtable[documentationHash] == null) {
|
||||
// AbstractDecoration.documentationHashtable[documentationHash] = value;
|
||||
// }
|
||||
} |
||||
} |
||||
|
||||
public static List<IParameter> Clone(IList<IParameter> l) |
||||
{ |
||||
List<IParameter> r = new List<IParameter>(l.Count); |
||||
for (int i = 0; i < l.Count; ++i) { |
||||
r.Add(new DefaultParameter(l[i])); |
||||
} |
||||
return r; |
||||
} |
||||
|
||||
public virtual int CompareTo(IParameter value) |
||||
{ |
||||
if (value == null) return -1; |
||||
|
||||
// two parameters are equal if they have the same return type
|
||||
// (they may have different names)
|
||||
if (object.Equals(ReturnType, value.ReturnType)) { |
||||
return 0; |
||||
} else { |
||||
// if the parameters are not equal, use the parameter name to provide the ordering
|
||||
int r = string.Compare(this.Name, value.Name); |
||||
if (r != 0) |
||||
return r; |
||||
else |
||||
return -1; // but equal names don't make parameters of different return types equal
|
||||
} |
||||
} |
||||
|
||||
int IComparable.CompareTo(object value) |
||||
{ |
||||
return CompareTo(value as IParameter); |
||||
} |
||||
} |
||||
} |
||||
@ -0,0 +1,175 @@
@@ -0,0 +1,175 @@
|
||||
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
|
||||
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
|
||||
|
||||
using System; |
||||
using System.Collections.Generic; |
||||
using System.Text; |
||||
|
||||
namespace ICSharpCode.SharpDevelop.Dom { |
||||
|
||||
public class DefaultProperty : AbstractMember, IProperty |
||||
{ |
||||
DomRegion getterRegion = DomRegion.Empty; |
||||
DomRegion setterRegion = DomRegion.Empty; |
||||
|
||||
IList<IParameter> parameters = null; |
||||
internal byte accessFlags; |
||||
const byte indexerFlag = 0x01; |
||||
const byte getterFlag = 0x02; |
||||
const byte setterFlag = 0x04; |
||||
const byte extensionFlag = 0x08; |
||||
ModifierEnum getterModifiers, setterModifiers; |
||||
|
||||
protected override void FreezeInternal() |
||||
{ |
||||
parameters = FreezeList(parameters); |
||||
base.FreezeInternal(); |
||||
} |
||||
|
||||
public bool IsIndexer { |
||||
get { return (accessFlags & indexerFlag) == indexerFlag; } |
||||
set { |
||||
CheckBeforeMutation(); |
||||
if (value) accessFlags |= indexerFlag; else accessFlags &= 255-indexerFlag; |
||||
} |
||||
} |
||||
|
||||
public bool CanGet { |
||||
get { return (accessFlags & getterFlag) == getterFlag; } |
||||
set { |
||||
CheckBeforeMutation(); |
||||
if (value) accessFlags |= getterFlag; else accessFlags &= 255-getterFlag; |
||||
} |
||||
} |
||||
|
||||
public bool CanSet { |
||||
get { return (accessFlags & setterFlag) == setterFlag; } |
||||
set { |
||||
CheckBeforeMutation(); |
||||
if (value) accessFlags |= setterFlag; else accessFlags &= 255-setterFlag; |
||||
} |
||||
} |
||||
|
||||
public bool IsExtensionMethod { |
||||
get { return (accessFlags & extensionFlag) == extensionFlag; } |
||||
set { |
||||
CheckBeforeMutation(); |
||||
if (value) accessFlags |= extensionFlag; else accessFlags &= 255-extensionFlag; |
||||
} |
||||
} |
||||
|
||||
public override string DocumentationTag { |
||||
get { |
||||
string dotnetName = this.DotNetName; |
||||
StringBuilder b = new StringBuilder("P:", dotnetName.Length + 2); |
||||
b.Append(dotnetName); |
||||
IList<IParameter> paras = this.Parameters; |
||||
if (paras.Count > 0) { |
||||
b.Append('('); |
||||
for (int i = 0; i < paras.Count; ++i) { |
||||
if (i > 0) b.Append(','); |
||||
IReturnType rt = paras[i].ReturnType; |
||||
if (rt != null) { |
||||
b.Append(rt.DotNetName); |
||||
} |
||||
} |
||||
b.Append(')'); |
||||
} |
||||
return b.ToString(); |
||||
} |
||||
} |
||||
|
||||
public override IMember Clone() |
||||
{ |
||||
DefaultProperty p = new DefaultProperty(Name, ReturnType, Modifiers, Region, BodyRegion, DeclaringType); |
||||
p.parameters = DefaultParameter.Clone(this.Parameters); |
||||
p.getterModifiers = this.getterModifiers; |
||||
p.setterModifiers = this.setterModifiers; |
||||
p.getterRegion = this.getterRegion; |
||||
p.setterRegion = this.setterRegion; |
||||
p.CopyDocumentationFrom(this); |
||||
p.accessFlags = this.accessFlags; |
||||
foreach (ExplicitInterfaceImplementation eii in InterfaceImplementations) { |
||||
p.InterfaceImplementations.Add(eii.Clone()); |
||||
} |
||||
return p; |
||||
} |
||||
|
||||
public virtual IList<IParameter> Parameters { |
||||
get { |
||||
if (parameters == null) { |
||||
parameters = new List<IParameter>(); |
||||
} |
||||
return parameters; |
||||
} |
||||
set { |
||||
CheckBeforeMutation(); |
||||
parameters = value; |
||||
} |
||||
} |
||||
|
||||
public DomRegion GetterRegion { |
||||
get { return getterRegion; } |
||||
set { |
||||
CheckBeforeMutation(); |
||||
getterRegion = value; |
||||
} |
||||
} |
||||
|
||||
public DomRegion SetterRegion { |
||||
get { return setterRegion; } |
||||
set { |
||||
CheckBeforeMutation(); |
||||
setterRegion = value; |
||||
} |
||||
} |
||||
|
||||
public ModifierEnum GetterModifiers { |
||||
get { return getterModifiers; } |
||||
set { |
||||
CheckBeforeMutation(); |
||||
getterModifiers = value; |
||||
} |
||||
} |
||||
|
||||
public ModifierEnum SetterModifiers { |
||||
get { return setterModifiers; } |
||||
set { |
||||
CheckBeforeMutation(); |
||||
setterModifiers = value; |
||||
} |
||||
} |
||||
|
||||
public DefaultProperty(IClass declaringType, string name) : base(declaringType, name) |
||||
{ |
||||
} |
||||
|
||||
public DefaultProperty(string name, IReturnType type, ModifierEnum m, DomRegion region, DomRegion bodyRegion, IClass declaringType) : base(declaringType, name) |
||||
{ |
||||
this.ReturnType = type; |
||||
this.Region = region; |
||||
this.BodyRegion = bodyRegion; |
||||
Modifiers = m; |
||||
} |
||||
|
||||
public virtual int CompareTo(IProperty value) |
||||
{ |
||||
int cmp = string.CompareOrdinal(this.FullyQualifiedName, value.FullyQualifiedName); |
||||
if (cmp != 0) { |
||||
return cmp; |
||||
} |
||||
|
||||
return DiffUtility.Compare(Parameters, value.Parameters); |
||||
} |
||||
|
||||
int IComparable.CompareTo(object value) { |
||||
return CompareTo((IProperty)value); |
||||
} |
||||
|
||||
public override EntityType EntityType { |
||||
get { |
||||
return EntityType.Property; |
||||
} |
||||
} |
||||
} |
||||
} |
||||
@ -0,0 +1,254 @@
@@ -0,0 +1,254 @@
|
||||
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
|
||||
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
|
||||
|
||||
using System; |
||||
using System.Collections.Generic; |
||||
|
||||
namespace ICSharpCode.SharpDevelop.Dom |
||||
{ |
||||
/// <summary>
|
||||
/// DefaultReturnType is a reference to a normal class or a reference to a generic class where
|
||||
/// the type parameters are NOT specified.
|
||||
/// E.g. "System.Int32", "System.Void", "System.String", "System.Collections.Generic.List"
|
||||
/// </summary>
|
||||
public class DefaultReturnType : AbstractReturnType |
||||
{ |
||||
public static bool Equals(IReturnType rt1, IReturnType rt2) |
||||
{ |
||||
if (rt1 == rt2) return true; |
||||
if (rt1 == null || rt2 == null) return false; |
||||
IClass c1 = rt1.GetUnderlyingClass(); |
||||
IClass c2 = rt2.GetUnderlyingClass(); |
||||
if (c1 == null && c2 == null) { |
||||
// guess if the classes are equal
|
||||
return rt1.FullyQualifiedName == rt2.FullyQualifiedName && rt1.TypeArgumentCount == rt2.TypeArgumentCount; |
||||
} else { |
||||
if (c1 == c2) |
||||
return true; |
||||
if (c1 == null || c2 == null) |
||||
return false; |
||||
return c1.FullyQualifiedName == c2.FullyQualifiedName && c1.TypeParameters.Count == c2.TypeParameters.Count; |
||||
} |
||||
} |
||||
|
||||
public static int GetHashCode(IReturnType rt) |
||||
{ |
||||
if (rt == null) |
||||
return 0; |
||||
return (rt.FullyQualifiedName ?? "").GetHashCode() ^ rt.TypeArgumentCount; |
||||
} |
||||
|
||||
IClass c; |
||||
|
||||
public DefaultReturnType(IClass c) |
||||
{ |
||||
if (c == null) |
||||
throw new ArgumentNullException("c"); |
||||
this.c = c; |
||||
} |
||||
|
||||
public override string ToString() |
||||
{ |
||||
return c.FullyQualifiedName; |
||||
} |
||||
|
||||
public override int TypeArgumentCount { |
||||
get { |
||||
return c.TypeParameters.Count; |
||||
} |
||||
} |
||||
|
||||
public override IClass GetUnderlyingClass() |
||||
{ |
||||
return c; |
||||
} |
||||
|
||||
// Required to prevent stack overflow when calling GetMethods() on a class with cyclic inheritance
|
||||
// replaces old 'getMembersBusy' flag which wasn't thread-safe
|
||||
[ThreadStatic] static BusyManager _busyManager; |
||||
|
||||
static BusyManager busyManager { |
||||
get { return _busyManager ?? (_busyManager = new BusyManager()); } |
||||
} |
||||
|
||||
public override List<IMethod> GetMethods() |
||||
{ |
||||
List<IMethod> l = new List<IMethod>(); |
||||
using (var busyLock = busyManager.Enter(this)) { |
||||
if (busyLock.Success) { |
||||
l.AddRange(c.Methods); |
||||
if (c.AddDefaultConstructorIfRequired && !c.IsStatic) { |
||||
// A constructor is added for classes that do not have a default constructor;
|
||||
// and for all structs.
|
||||
if (c.ClassType == ClassType.Class && !l.Exists(m => m.IsConstructor)) { |
||||
l.Add(Constructor.CreateDefault(c)); |
||||
} else if (c.ClassType == ClassType.Struct || c.ClassType == ClassType.Enum) { |
||||
l.Add(Constructor.CreateDefault(c)); |
||||
} |
||||
} |
||||
|
||||
if (c.ClassType == ClassType.Interface) { |
||||
if (c.BaseTypes.Count == 0) { |
||||
AddMethodsFromBaseType(l, c.ProjectContent.SystemTypes.Object); |
||||
} else { |
||||
foreach (IReturnType baseType in c.BaseTypes) { |
||||
AddMethodsFromBaseType(l, baseType); |
||||
} |
||||
} |
||||
} else { |
||||
AddMethodsFromBaseType(l, c.BaseType); |
||||
} |
||||
} |
||||
} |
||||
return l; |
||||
} |
||||
|
||||
void AddMethodsFromBaseType(List<IMethod> l, IReturnType baseType) |
||||
{ |
||||
if (baseType != null) { |
||||
foreach (IMethod m in baseType.GetMethods()) { |
||||
if (m.IsConstructor) |
||||
continue; |
||||
|
||||
/*bool ok = true; |
||||
if (m.IsOverridable) { |
||||
StringComparer comparer = m.DeclaringType.ProjectContent.Language.NameComparer; |
||||
foreach (IMethod oldMethod in c.Methods) { |
||||
if (comparer.Equals(oldMethod.Name, m.Name)) { |
||||
if (m.IsStatic == oldMethod.IsStatic && object.Equals(m.ReturnType, oldMethod.ReturnType)) { |
||||
if (DiffUtility.Compare(oldMethod.Parameters, m.Parameters) == 0) { |
||||
ok = false; |
||||
break; |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
if (ok) |
||||
l.Add(m);*/ |
||||
l.Add(m); |
||||
} |
||||
} |
||||
} |
||||
|
||||
public override List<IProperty> GetProperties() |
||||
{ |
||||
List<IProperty> l = new List<IProperty>(); |
||||
using (var busyLock = busyManager.Enter(this)) { |
||||
if (busyLock.Success) { |
||||
l.AddRange(c.Properties); |
||||
if (c.ClassType == ClassType.Interface) { |
||||
foreach (IReturnType baseType in c.BaseTypes) { |
||||
AddPropertiesFromBaseType(l, baseType); |
||||
} |
||||
} else { |
||||
AddPropertiesFromBaseType(l, c.BaseType); |
||||
} |
||||
} |
||||
} |
||||
return l; |
||||
} |
||||
|
||||
void AddPropertiesFromBaseType(List<IProperty> l, IReturnType baseType) |
||||
{ |
||||
if (baseType != null) { |
||||
foreach (IProperty p in baseType.GetProperties()) { |
||||
/*bool ok = true; |
||||
if (p.IsOverridable) { |
||||
StringComparer comparer = p.DeclaringType.ProjectContent.Language.NameComparer; |
||||
foreach (IProperty oldProperty in c.Properties) { |
||||
if (comparer.Equals(oldProperty.Name, p.Name)) { |
||||
if (p.IsStatic == oldProperty.IsStatic && object.Equals(p.ReturnType, oldProperty.ReturnType)) { |
||||
if (DiffUtility.Compare(oldProperty.Parameters, p.Parameters) == 0) { |
||||
ok = false; |
||||
break; |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
if (ok) |
||||
l.Add(p);*/ |
||||
l.Add(p); |
||||
} |
||||
} |
||||
} |
||||
|
||||
public override List<IField> GetFields() |
||||
{ |
||||
List<IField> l = new List<IField>(); |
||||
using (var busyLock = busyManager.Enter(this)) { |
||||
if (busyLock.Success) { |
||||
l.AddRange(c.Fields); |
||||
if (c.ClassType == ClassType.Interface) { |
||||
foreach (IReturnType baseType in c.BaseTypes) { |
||||
l.AddRange(baseType.GetFields()); |
||||
} |
||||
} else { |
||||
IReturnType baseType = c.BaseType; |
||||
if (baseType != null) { |
||||
l.AddRange(baseType.GetFields()); |
||||
} |
||||
} |
||||
} |
||||
} |
||||
return l; |
||||
} |
||||
|
||||
public override List<IEvent> GetEvents() |
||||
{ |
||||
List<IEvent> l = new List<IEvent>(); |
||||
using (var busyLock = busyManager.Enter(this)) { |
||||
if (busyLock.Success) { |
||||
l.AddRange(c.Events); |
||||
if (c.ClassType == ClassType.Interface) { |
||||
foreach (IReturnType baseType in c.BaseTypes) { |
||||
l.AddRange(baseType.GetEvents()); |
||||
} |
||||
} else { |
||||
IReturnType baseType = c.BaseType; |
||||
if (baseType != null) { |
||||
l.AddRange(baseType.GetEvents()); |
||||
} |
||||
} |
||||
} |
||||
} |
||||
return l; |
||||
} |
||||
|
||||
public override string FullyQualifiedName { |
||||
get { |
||||
return c.FullyQualifiedName; |
||||
} |
||||
set { |
||||
throw new NotSupportedException(); |
||||
} |
||||
} |
||||
|
||||
public override string Name { |
||||
get { |
||||
return c.Name; |
||||
} |
||||
} |
||||
|
||||
public override string Namespace { |
||||
get { |
||||
return c.Namespace; |
||||
} |
||||
} |
||||
|
||||
public override string DotNetName { |
||||
get { |
||||
return c.DotNetName; |
||||
} |
||||
} |
||||
|
||||
public override Nullable<bool> IsReferenceType { |
||||
get { |
||||
return (this.c.ClassType == ClassType.Class |
||||
|| this.c.ClassType == ClassType.Interface |
||||
|| this.c.ClassType == ClassType.Delegate); |
||||
} |
||||
} |
||||
} |
||||
} |
||||
@ -0,0 +1,194 @@
@@ -0,0 +1,194 @@
|
||||
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
|
||||
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
|
||||
|
||||
using System; |
||||
using System.Collections.Generic; |
||||
|
||||
namespace ICSharpCode.SharpDevelop.Dom |
||||
{ |
||||
/// <summary>
|
||||
/// Type parameter of a generic class/method.
|
||||
/// </summary>
|
||||
public class DefaultTypeParameter : AbstractFreezable, ITypeParameter |
||||
{ |
||||
public static readonly IList<ITypeParameter> EmptyTypeParameterList = EmptyList<ITypeParameter>.Instance; |
||||
|
||||
readonly string name; |
||||
readonly IMethod method; |
||||
readonly IClass targetClass; |
||||
readonly int index; |
||||
IList<IReturnType> constraints = new List<IReturnType>(); |
||||
|
||||
protected override void FreezeInternal() |
||||
{ |
||||
constraints = FreezeList(constraints); |
||||
base.FreezeInternal(); |
||||
} |
||||
|
||||
public string Name { |
||||
get { |
||||
return name; |
||||
} |
||||
} |
||||
|
||||
public int Index { |
||||
get { |
||||
return index; |
||||
} |
||||
} |
||||
|
||||
public IMethod Method { |
||||
get { |
||||
return method; |
||||
} |
||||
} |
||||
|
||||
public IClass Class { |
||||
get { |
||||
return targetClass; |
||||
} |
||||
} |
||||
|
||||
public IList<IReturnType> Constraints { |
||||
get { |
||||
return constraints; |
||||
} |
||||
} |
||||
|
||||
public IList<IAttribute> Attributes { |
||||
get { |
||||
return DefaultAttribute.EmptyAttributeList; |
||||
} |
||||
} |
||||
|
||||
bool hasConstructableConstraint = false; |
||||
bool hasReferenceTypeConstraint = false; |
||||
bool hasValueTypeConstraint = false; |
||||
|
||||
/// <summary>
|
||||
/// Gets/Sets if the type parameter has the 'new()' constraint.
|
||||
/// </summary>
|
||||
public bool HasConstructableConstraint { |
||||
get { return hasConstructableConstraint; } |
||||
set { |
||||
CheckBeforeMutation(); |
||||
hasConstructableConstraint = value; |
||||
} |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Gets/Sets if the type parameter has the 'class' constraint.
|
||||
/// </summary>
|
||||
public bool HasReferenceTypeConstraint { |
||||
get { return hasReferenceTypeConstraint; } |
||||
set { |
||||
CheckBeforeMutation(); |
||||
hasReferenceTypeConstraint = value; |
||||
} |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Gets/Sets if the type parameter has the 'struct' constraint.
|
||||
/// </summary>
|
||||
public bool HasValueTypeConstraint { |
||||
get { return hasValueTypeConstraint; } |
||||
set { |
||||
CheckBeforeMutation(); |
||||
hasValueTypeConstraint = value; |
||||
} |
||||
} |
||||
|
||||
public DefaultTypeParameter(IMethod method, string name, int index) |
||||
{ |
||||
this.method = method; |
||||
this.targetClass = method.DeclaringType; |
||||
this.name = name; |
||||
this.index = index; |
||||
} |
||||
|
||||
public DefaultTypeParameter(IMethod method, Type type) |
||||
{ |
||||
this.method = method; |
||||
this.targetClass = method.DeclaringType; |
||||
this.name = type.Name; |
||||
this.index = type.GenericParameterPosition; |
||||
} |
||||
|
||||
public DefaultTypeParameter(IClass targetClass, string name, int index) |
||||
{ |
||||
this.targetClass = targetClass; |
||||
this.name = name; |
||||
this.index = index; |
||||
} |
||||
|
||||
public DefaultTypeParameter(IClass targetClass, Type type) |
||||
{ |
||||
this.targetClass = targetClass; |
||||
this.name = type.Name; |
||||
this.index = type.GenericParameterPosition; |
||||
} |
||||
|
||||
public override bool Equals(object obj) |
||||
{ |
||||
DefaultTypeParameter tp = obj as DefaultTypeParameter; |
||||
if (tp == null) return false; |
||||
if (tp.index != index) return false; |
||||
if (tp.name != name) return false; |
||||
if (tp.hasConstructableConstraint != hasConstructableConstraint) return false; |
||||
if (tp.hasReferenceTypeConstraint != hasReferenceTypeConstraint) return false; |
||||
if (tp.hasValueTypeConstraint != hasValueTypeConstraint) return false; |
||||
if (tp.method != method) { |
||||
if (tp.method == null || method == null) return false; |
||||
if (tp.method.FullyQualifiedName != method.FullyQualifiedName) return false; |
||||
} else { |
||||
if (tp.targetClass.FullyQualifiedName != targetClass.FullyQualifiedName) return false; |
||||
} |
||||
return true; |
||||
} |
||||
|
||||
public override int GetHashCode() |
||||
{ |
||||
return base.GetHashCode(); |
||||
} |
||||
|
||||
public override string ToString() |
||||
{ |
||||
return String.Format("[{0}: {1}]", GetType().Name, name); |
||||
} |
||||
|
||||
public static DefaultClass GetDummyClassForTypeParameter(ITypeParameter p) |
||||
{ |
||||
DefaultClass c = new DefaultClass(p.Class.CompilationUnit, p.Name); |
||||
if (p.Method != null) { |
||||
c.Region = new DomRegion(p.Method.Region.BeginLine, p.Method.Region.BeginColumn); |
||||
} else { |
||||
c.Region = new DomRegion(p.Class.Region.BeginLine, p.Class.Region.BeginColumn); |
||||
} |
||||
c.Modifiers = ModifierEnum.Public; |
||||
if (p.HasValueTypeConstraint) { |
||||
c.ClassType = ClassType.Struct; |
||||
} else if (p.HasConstructableConstraint) { |
||||
c.ClassType = ClassType.Class; |
||||
} else { |
||||
c.ClassType = ClassType.Interface; |
||||
} |
||||
return c; |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Gets the type that was used to bind this type parameter.
|
||||
/// This property returns null for generic methods/classes, it
|
||||
/// is non-null only for constructed versions of generic methods.
|
||||
/// </summary>
|
||||
public virtual IReturnType BoundTo { |
||||
get { return null; } |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// If this type parameter was bound, returns the unbound version of it.
|
||||
/// </summary>
|
||||
public virtual ITypeParameter UnboundTypeParameter { |
||||
get { return this; } |
||||
} |
||||
} |
||||
} |
||||
@ -0,0 +1,174 @@
@@ -0,0 +1,174 @@
|
||||
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
|
||||
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
|
||||
|
||||
using System; |
||||
using System.Collections.Generic; |
||||
using System.Text; |
||||
|
||||
namespace ICSharpCode.SharpDevelop.Dom |
||||
{ |
||||
public class DefaultUsing : AbstractFreezable, IUsing |
||||
{ |
||||
DomRegion region; |
||||
IProjectContent projectContent; |
||||
|
||||
public DefaultUsing(IProjectContent projectContent) |
||||
{ |
||||
this.projectContent = projectContent; |
||||
} |
||||
|
||||
public DefaultUsing(IProjectContent projectContent, DomRegion region) : this(projectContent) |
||||
{ |
||||
this.region = region; |
||||
} |
||||
|
||||
IList<string> usings = new List<string>(); |
||||
IDictionary<string, IReturnType> aliases = null; |
||||
|
||||
protected override void FreezeInternal() |
||||
{ |
||||
usings = FreezeList(usings); |
||||
if (aliases != null) |
||||
aliases = new ReadOnlyDictionary<string, IReturnType>(aliases); |
||||
base.FreezeInternal(); |
||||
} |
||||
|
||||
public DomRegion Region { |
||||
get { |
||||
return region; |
||||
} |
||||
} |
||||
|
||||
public IList<string> Usings { |
||||
get { |
||||
return usings; |
||||
} |
||||
} |
||||
|
||||
public IDictionary<string, IReturnType> Aliases { |
||||
get { |
||||
return aliases; |
||||
} |
||||
} |
||||
|
||||
public bool HasAliases { |
||||
get { |
||||
return aliases != null && aliases.Count > 0; |
||||
} |
||||
} |
||||
|
||||
public void AddAlias(string alias, IReturnType type) |
||||
{ |
||||
CheckBeforeMutation(); |
||||
if (aliases == null) aliases = new SortedList<string, IReturnType>(); |
||||
aliases.Add(alias, type); |
||||
} |
||||
|
||||
public string SearchNamespace(string partialNamespaceName) |
||||
{ |
||||
if (HasAliases) { |
||||
foreach (KeyValuePair<string, IReturnType> entry in aliases) { |
||||
string aliasString = entry.Key; |
||||
string nsName; |
||||
if (projectContent.Language.NameComparer.Equals(partialNamespaceName, aliasString)) { |
||||
nsName = entry.Value.FullyQualifiedName; |
||||
if (projectContent.NamespaceExists(nsName)) |
||||
return nsName; |
||||
} |
||||
if (partialNamespaceName.Length > aliasString.Length) { |
||||
if (projectContent.Language.NameComparer.Equals(partialNamespaceName.Substring(0, aliasString.Length + 1), aliasString + ".")) { |
||||
nsName = String.Concat(entry.Value.FullyQualifiedName, partialNamespaceName.Remove(0, aliasString.Length)); |
||||
if (projectContent.NamespaceExists(nsName)) { |
||||
return nsName; |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
if (projectContent.Language.ImportNamespaces) { |
||||
foreach (string str in usings) { |
||||
string possibleNamespace = String.Concat(str, ".", partialNamespaceName); |
||||
if (projectContent.NamespaceExists(possibleNamespace)) |
||||
return possibleNamespace; |
||||
} |
||||
} |
||||
return null; |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Returns a collection of possible types that could be meant when using this Import
|
||||
/// to search the type.
|
||||
/// Types with the incorrect type parameter count might be returned, but for each
|
||||
/// same using entry or alias entry at most one (the best matching) type should be returned.
|
||||
/// </summary>
|
||||
public IEnumerable<IReturnType> SearchType(string partialTypeName, int typeParameterCount) |
||||
{ |
||||
if (HasAliases) { |
||||
foreach (KeyValuePair<string, IReturnType> entry in aliases) { |
||||
string aliasString = entry.Key; |
||||
if (projectContent.Language.NameComparer.Equals(partialTypeName, aliasString)) { |
||||
if (entry.Value.GetUnderlyingClass() == null) |
||||
continue; // type not found, maybe entry was a namespace
|
||||
yield return entry.Value; |
||||
} |
||||
if (partialTypeName.Length > aliasString.Length) { |
||||
if (projectContent.Language.NameComparer.Equals(partialTypeName.Substring(0, aliasString.Length + 1), aliasString + ".")) { |
||||
string className = entry.Value.FullyQualifiedName + partialTypeName.Remove(0, aliasString.Length); |
||||
IClass c = projectContent.GetClass(className, typeParameterCount); |
||||
if (c != null) { |
||||
yield return c.DefaultReturnType; |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
if (projectContent.Language.ImportNamespaces) { |
||||
foreach (string str in usings) { |
||||
IClass c = projectContent.GetClass(str + "." + partialTypeName, typeParameterCount); |
||||
if (c != null) { |
||||
yield return c.DefaultReturnType; |
||||
} |
||||
} |
||||
} else { |
||||
int pos = partialTypeName.IndexOf('.'); |
||||
string className, subClassName; |
||||
if (pos < 0) { |
||||
className = partialTypeName; |
||||
subClassName = null; |
||||
} else { |
||||
className = partialTypeName.Substring(0, pos); |
||||
subClassName = partialTypeName.Substring(pos + 1); |
||||
} |
||||
foreach (string str in usings) { |
||||
IClass c = projectContent.GetClass(str + "." + className, typeParameterCount); |
||||
if (c != null) { |
||||
c = projectContent.GetClass(str + "." + partialTypeName, typeParameterCount); |
||||
if (c != null) { |
||||
yield return c.DefaultReturnType; |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
|
||||
public override string ToString() |
||||
{ |
||||
StringBuilder builder = new StringBuilder("[DefaultUsing: "); |
||||
foreach (string str in usings) { |
||||
builder.Append(str); |
||||
builder.Append(", "); |
||||
} |
||||
if (HasAliases) { |
||||
foreach (KeyValuePair<string, IReturnType> p in aliases) { |
||||
builder.Append(p.Key); |
||||
builder.Append("="); |
||||
builder.Append(p.Value.ToString()); |
||||
builder.Append(", "); |
||||
} |
||||
} |
||||
builder.Length -= 2; // remove last ", "
|
||||
builder.Append("]"); |
||||
return builder.ToString(); |
||||
} |
||||
} |
||||
} |
||||
@ -0,0 +1,66 @@
@@ -0,0 +1,66 @@
|
||||
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
|
||||
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
|
||||
|
||||
using System; |
||||
using System.Collections.Generic; |
||||
|
||||
namespace ICSharpCode.SharpDevelop.Dom |
||||
{ |
||||
public class DefaultUsingScope : AbstractFreezable, IUsingScope |
||||
{ |
||||
DomRegion region; |
||||
IUsingScope parent; |
||||
IList<IUsing> usings; |
||||
IList<IUsingScope> childScopes; |
||||
string namespaceName = ""; |
||||
|
||||
protected override void FreezeInternal() |
||||
{ |
||||
base.FreezeInternal(); |
||||
usings = FreezeList(usings); |
||||
childScopes = FreezeList(childScopes); |
||||
} |
||||
|
||||
public DomRegion Region { |
||||
get { return region; } |
||||
set { |
||||
CheckBeforeMutation(); |
||||
region = value; |
||||
} |
||||
} |
||||
|
||||
public IUsingScope Parent { |
||||
get { return parent; } |
||||
set { |
||||
CheckBeforeMutation(); |
||||
parent = value; |
||||
} |
||||
} |
||||
|
||||
public virtual IList<IUsing> Usings { |
||||
get { |
||||
if (usings == null) |
||||
usings = new List<IUsing>(); |
||||
return usings; |
||||
} |
||||
} |
||||
|
||||
public virtual IList<IUsingScope> ChildScopes { |
||||
get { |
||||
if (childScopes == null) |
||||
childScopes = new List<IUsingScope>(); |
||||
return childScopes; |
||||
} |
||||
} |
||||
|
||||
public string NamespaceName { |
||||
get { return namespaceName; } |
||||
set { |
||||
if (value == null) |
||||
throw new ArgumentNullException("NamespaceName"); |
||||
CheckBeforeMutation(); |
||||
namespaceName = value; |
||||
} |
||||
} |
||||
} |
||||
} |
||||
@ -0,0 +1,51 @@
@@ -0,0 +1,51 @@
|
||||
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
|
||||
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
|
||||
|
||||
using System; |
||||
using System.Collections.Generic; |
||||
|
||||
namespace ICSharpCode.SharpDevelop.Dom |
||||
{ |
||||
public class DynamicReturnType : AbstractReturnType |
||||
{ |
||||
readonly IProjectContent pc; |
||||
|
||||
public DynamicReturnType(IProjectContent pc) |
||||
{ |
||||
if (pc == null) |
||||
throw new ArgumentNullException("pc"); |
||||
this.pc = pc; |
||||
} |
||||
|
||||
public override IClass GetUnderlyingClass() |
||||
{ |
||||
return null; |
||||
} |
||||
|
||||
public override List<IMethod> GetMethods() |
||||
{ |
||||
return new List<IMethod>(); |
||||
} |
||||
public override List<IProperty> GetProperties() |
||||
{ |
||||
return new List<IProperty>(); |
||||
} |
||||
public override List<IField> GetFields() |
||||
{ |
||||
return new List<IField>(); |
||||
} |
||||
public override List<IEvent> GetEvents() |
||||
{ |
||||
return new List<IEvent>(); |
||||
} |
||||
|
||||
public override string Name { |
||||
get { return "dynamic"; } |
||||
} |
||||
|
||||
public override string FullyQualifiedName { |
||||
get { return "dynamic"; } |
||||
set { throw new NotSupportedException(); } |
||||
} |
||||
} |
||||
} |
||||
@ -0,0 +1,64 @@
@@ -0,0 +1,64 @@
|
||||
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
|
||||
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
|
||||
|
||||
using System; |
||||
|
||||
namespace ICSharpCode.SharpDevelop.Dom |
||||
{ |
||||
/// <summary>
|
||||
/// The type reference that is the element of an enumerable.
|
||||
/// This class is used in combination with an InferredReturnType to
|
||||
/// represent the implicitly typed loop variable <c>v</c> in
|
||||
/// "<c>foreach (var v in enumerableInstance) {}</c>"
|
||||
/// </summary>
|
||||
public class ElementReturnType : ProxyReturnType |
||||
{ |
||||
IReturnType enumerableType; |
||||
IProjectContent pc; |
||||
|
||||
public ElementReturnType(IProjectContent pc, IReturnType enumerableType) |
||||
{ |
||||
if (pc == null) |
||||
throw new ArgumentNullException("pc"); |
||||
this.enumerableType = enumerableType; |
||||
this.pc = pc; |
||||
} |
||||
|
||||
[ThreadStatic] static BusyManager _busyManager; |
||||
|
||||
static BusyManager busyManager { |
||||
get { return _busyManager ?? (_busyManager = new BusyManager()); } |
||||
} |
||||
|
||||
public override IReturnType BaseType { |
||||
get { |
||||
using (var l = busyManager.Enter(this)) { |
||||
if (!l.Success) |
||||
return null; |
||||
|
||||
// get element type from enumerableType
|
||||
if (enumerableType.IsArrayReturnType) |
||||
return enumerableType.CastToArrayReturnType().ArrayElementType; |
||||
|
||||
IClass c = enumerableType.GetUnderlyingClass(); |
||||
if (c == null) |
||||
return null; |
||||
IClass genumerable = pc.GetClass("System.Collections.Generic.IEnumerable", 1); |
||||
if (c.IsTypeInInheritanceTree(genumerable)) { |
||||
return MemberLookupHelper.GetTypeParameterPassedToBaseClass(enumerableType, genumerable, 0); |
||||
} |
||||
IClass enumerable = pc.GetClass("System.Collections.IEnumerable", 0); |
||||
if (c.IsTypeInInheritanceTree(enumerable)) { |
||||
return pc.SystemTypes.Object; |
||||
} |
||||
return null; |
||||
} |
||||
} |
||||
} |
||||
|
||||
public override string ToString() |
||||
{ |
||||
return "[ElementReturnType " + enumerableType + "]"; |
||||
} |
||||
} |
||||
} |
||||
@ -0,0 +1,125 @@
@@ -0,0 +1,125 @@
|
||||
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
|
||||
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
|
||||
|
||||
using System; |
||||
using System.Collections.Generic; |
||||
|
||||
namespace ICSharpCode.SharpDevelop.Dom |
||||
{ |
||||
/// <summary>
|
||||
/// GenericReturnType is a reference to a type parameter.
|
||||
/// </summary>
|
||||
public sealed class GenericReturnType : DecoratingReturnType |
||||
{ |
||||
ITypeParameter typeParameter; |
||||
|
||||
public ITypeParameter TypeParameter { |
||||
get { |
||||
return typeParameter; |
||||
} |
||||
} |
||||
|
||||
public override bool Equals(IReturnType rt) |
||||
{ |
||||
if (rt == null || !rt.IsGenericReturnType) |
||||
return false; |
||||
GenericReturnType grt = rt.CastToGenericReturnType(); |
||||
if ((typeParameter.Method == null) != (grt.typeParameter.Method == null)) |
||||
return false; |
||||
return typeParameter.Index == grt.typeParameter.Index; |
||||
} |
||||
|
||||
public override int GetHashCode() |
||||
{ |
||||
if (typeParameter.Method != null) |
||||
return 17491 + typeParameter.Index; |
||||
else |
||||
return 81871 + typeParameter.Index; |
||||
} |
||||
|
||||
public override T CastToDecoratingReturnType<T>() |
||||
{ |
||||
if (typeof(T) == typeof(GenericReturnType)) { |
||||
return (T)(object)this; |
||||
} else { |
||||
return null; |
||||
} |
||||
} |
||||
|
||||
public GenericReturnType(ITypeParameter typeParameter) |
||||
{ |
||||
if (typeParameter == null) |
||||
throw new ArgumentNullException("typeParameter"); |
||||
this.typeParameter = typeParameter; |
||||
} |
||||
|
||||
public override string FullyQualifiedName { |
||||
get { |
||||
return typeParameter.Name; |
||||
} |
||||
} |
||||
|
||||
public override string Name { |
||||
get { |
||||
return typeParameter.Name; |
||||
} |
||||
} |
||||
|
||||
public override string Namespace { |
||||
get { |
||||
return ""; |
||||
} |
||||
} |
||||
|
||||
public override string DotNetName { |
||||
get { |
||||
if (typeParameter.Method != null) |
||||
return "``" + typeParameter.Index; |
||||
else |
||||
return "`" + typeParameter.Index; |
||||
} |
||||
} |
||||
|
||||
public override IClass GetUnderlyingClass() |
||||
{ |
||||
return null; |
||||
} |
||||
|
||||
public override IReturnType BaseType { |
||||
get { |
||||
int count = typeParameter.Constraints.Count; |
||||
if (count == 0) |
||||
return typeParameter.Class.ProjectContent.SystemTypes.Object; |
||||
if (count == 1) |
||||
return typeParameter.Constraints[0]; |
||||
return new CombinedReturnType(typeParameter.Constraints, |
||||
FullyQualifiedName, |
||||
Name, Namespace, |
||||
DotNetName); |
||||
} |
||||
} |
||||
|
||||
// remove static methods (T.ReferenceEquals() is not possible)
|
||||
public override List<IMethod> GetMethods() |
||||
{ |
||||
List<IMethod> list = base.GetMethods(); |
||||
if (list != null) { |
||||
list.RemoveAll(delegate(IMethod m) { return m.IsStatic || m.IsConstructor; }); |
||||
if (typeParameter.HasConstructableConstraint || typeParameter.HasValueTypeConstraint) { |
||||
list.Add(new Constructor(ModifierEnum.Public, this, |
||||
DefaultTypeParameter.GetDummyClassForTypeParameter(typeParameter))); |
||||
} |
||||
} |
||||
return list; |
||||
} |
||||
|
||||
public override Nullable<bool> IsReferenceType { |
||||
get { return null; } |
||||
} |
||||
|
||||
public override string ToString() |
||||
{ |
||||
return String.Format("[GenericReturnType: {0}]", typeParameter); |
||||
} |
||||
} |
||||
} |
||||
@ -0,0 +1,104 @@
@@ -0,0 +1,104 @@
|
||||
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
|
||||
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
|
||||
|
||||
using System; |
||||
|
||||
namespace ICSharpCode.SharpDevelop.Dom |
||||
{ |
||||
/// <summary>
|
||||
/// The GetClassReturnType is used when the class should be resolved on demand, but the
|
||||
/// full name is already known.
|
||||
/// </summary>
|
||||
public sealed class GetClassReturnType : ProxyReturnType |
||||
{ |
||||
IProjectContent content; |
||||
string fullName; |
||||
string shortName; |
||||
int typeArgumentCount; |
||||
GetClassOptions options; |
||||
|
||||
public GetClassReturnType(IProjectContent content, string fullName, int typeArgumentCount) |
||||
: this(content, fullName, typeArgumentCount, GetClassOptions.Default) |
||||
{ |
||||
} |
||||
|
||||
public GetClassReturnType(IProjectContent content, string fullName, int typeArgumentCount, GetClassOptions options) |
||||
{ |
||||
this.content = content; |
||||
this.typeArgumentCount = typeArgumentCount; |
||||
SetFullyQualifiedName(fullName); |
||||
this.options = options; |
||||
} |
||||
|
||||
public override bool IsDefaultReturnType { |
||||
get { |
||||
return true; |
||||
} |
||||
} |
||||
|
||||
public override int TypeArgumentCount { |
||||
get { |
||||
return typeArgumentCount; |
||||
} |
||||
} |
||||
|
||||
public override IReturnType BaseType { |
||||
get { |
||||
IClass c = content.GetClass(fullName, typeArgumentCount, content.Language, options); |
||||
return (c != null) ? c.DefaultReturnType : null; |
||||
} |
||||
} |
||||
|
||||
public override string FullyQualifiedName { |
||||
get { |
||||
return fullName; |
||||
} |
||||
} |
||||
|
||||
void SetFullyQualifiedName(string fullName) |
||||
{ |
||||
if (fullName == null) |
||||
throw new ArgumentNullException("fullName"); |
||||
this.fullName = fullName; |
||||
int pos = fullName.LastIndexOf('.'); |
||||
if (pos < 0) |
||||
shortName = fullName; |
||||
else |
||||
shortName = fullName.Substring(pos + 1); |
||||
} |
||||
|
||||
public override string Name { |
||||
get { |
||||
return shortName; |
||||
} |
||||
} |
||||
|
||||
public override string Namespace { |
||||
get { |
||||
string tmp = base.Namespace; |
||||
if (tmp == "?") { |
||||
if (fullName.IndexOf('.') > 0) |
||||
return fullName.Substring(0, fullName.LastIndexOf('.')); |
||||
else |
||||
return ""; |
||||
} |
||||
return tmp; |
||||
} |
||||
} |
||||
|
||||
public override string DotNetName { |
||||
get { |
||||
string tmp = base.DotNetName; |
||||
if (tmp == "?") { |
||||
return fullName; |
||||
} |
||||
return tmp; |
||||
} |
||||
} |
||||
|
||||
public override string ToString() |
||||
{ |
||||
return String.Format("[GetClassReturnType: {0}]", fullName); |
||||
} |
||||
} |
||||
} |
||||
@ -0,0 +1,43 @@
@@ -0,0 +1,43 @@
|
||||
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
|
||||
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
|
||||
|
||||
using System; |
||||
using System.Collections.Generic; |
||||
|
||||
namespace ICSharpCode.SharpDevelop.Dom |
||||
{ |
||||
/// <summary>
|
||||
/// Return type used for MethodGroupResolveResult.
|
||||
/// </summary>
|
||||
public class MethodGroupReturnType : AbstractReturnType |
||||
{ |
||||
public MethodGroupReturnType() |
||||
{ |
||||
} |
||||
|
||||
public override IClass GetUnderlyingClass() |
||||
{ |
||||
return null; |
||||
} |
||||
|
||||
public override List<IMethod> GetMethods() |
||||
{ |
||||
return new List<IMethod>(); |
||||
} |
||||
|
||||
public override List<IProperty> GetProperties() |
||||
{ |
||||
return new List<IProperty>(); |
||||
} |
||||
|
||||
public override List<IField> GetFields() |
||||
{ |
||||
return new List<IField>(); |
||||
} |
||||
|
||||
public override List<IEvent> GetEvents() |
||||
{ |
||||
return new List<IEvent>(); |
||||
} |
||||
} |
||||
} |
||||
@ -0,0 +1,38 @@
@@ -0,0 +1,38 @@
|
||||
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
|
||||
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
|
||||
|
||||
using System; |
||||
using System.Collections.Generic; |
||||
|
||||
namespace ICSharpCode.SharpDevelop.Dom |
||||
{ |
||||
/// <summary>The type of the 'null'/'nothing' literal.</summary>
|
||||
public sealed class NullReturnType : AbstractReturnType |
||||
{ |
||||
private NullReturnType() {} |
||||
|
||||
public static readonly NullReturnType Instance = new NullReturnType(); |
||||
|
||||
public override bool Equals(IReturnType o) |
||||
{ |
||||
return o is NullReturnType; |
||||
} |
||||
|
||||
public override int GetHashCode() |
||||
{ |
||||
return 0; |
||||
} |
||||
|
||||
public override bool IsDefaultReturnType { |
||||
get { |
||||
return false; |
||||
} |
||||
} |
||||
|
||||
public override IClass GetUnderlyingClass() { return null; } |
||||
public override List<IMethod> GetMethods() { return new List<IMethod>(); } |
||||
public override List<IProperty> GetProperties() { return new List<IProperty>(); } |
||||
public override List<IField> GetFields() { return new List<IField>(); } |
||||
public override List<IEvent> GetEvents() { return new List<IEvent>(); } |
||||
} |
||||
} |
||||
@ -0,0 +1,105 @@
@@ -0,0 +1,105 @@
|
||||
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
|
||||
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
|
||||
|
||||
using System; |
||||
using System.Collections.Generic; |
||||
|
||||
namespace ICSharpCode.SharpDevelop.Dom |
||||
{ |
||||
/// <summary>
|
||||
/// Represents an unmanaged pointer type.
|
||||
/// </summary>
|
||||
public class PointerReturnType : DecoratingReturnType |
||||
{ |
||||
IReturnType baseType; |
||||
|
||||
public PointerReturnType(IReturnType baseType) |
||||
{ |
||||
if (baseType == null) |
||||
throw new ArgumentNullException("baseType"); |
||||
this.baseType = baseType; |
||||
} |
||||
|
||||
public override IReturnType BaseType { |
||||
get { return baseType; } |
||||
} |
||||
|
||||
public override T CastToDecoratingReturnType<T>() |
||||
{ |
||||
if (typeof(T) == typeof(PointerReturnType)) { |
||||
return (T)(object)this; |
||||
} else { |
||||
return null; |
||||
} |
||||
} |
||||
|
||||
public override IReturnType GetDirectReturnType() |
||||
{ |
||||
IReturnType newBaseType = baseType.GetDirectReturnType(); |
||||
if (newBaseType == baseType) |
||||
return this; |
||||
else |
||||
return new PointerReturnType(newBaseType); |
||||
} |
||||
|
||||
public override bool Equals(IReturnType rt) |
||||
{ |
||||
if (rt == null) return false; |
||||
PointerReturnType prt = rt.CastToDecoratingReturnType<PointerReturnType>(); |
||||
if (prt == null) return false; |
||||
return baseType.Equals(prt.baseType); |
||||
} |
||||
|
||||
public override int GetHashCode() |
||||
{ |
||||
unchecked { |
||||
return 53 * baseType.GetHashCode(); |
||||
} |
||||
} |
||||
|
||||
public override string DotNetName { |
||||
get { return baseType.DotNetName + "*"; } |
||||
} |
||||
|
||||
public override string FullyQualifiedName { |
||||
get { return baseType.FullyQualifiedName + "*"; } |
||||
} |
||||
|
||||
public override List<IEvent> GetEvents() |
||||
{ |
||||
return new List<IEvent>(); |
||||
} |
||||
|
||||
public override List<IField> GetFields() |
||||
{ |
||||
return new List<IField>(); |
||||
} |
||||
|
||||
public override List<IMethod> GetMethods() |
||||
{ |
||||
return new List<IMethod>(); |
||||
} |
||||
|
||||
public override List<IProperty> GetProperties() |
||||
{ |
||||
return new List<IProperty>(); |
||||
} |
||||
|
||||
public override IClass GetUnderlyingClass() |
||||
{ |
||||
return null; |
||||
} |
||||
|
||||
public override string Name { |
||||
get { return baseType.Name + "*"; } |
||||
} |
||||
|
||||
public override string Namespace { |
||||
get { return baseType.Namespace; } |
||||
} |
||||
|
||||
public override int TypeArgumentCount { |
||||
get { return 0; } |
||||
} |
||||
} |
||||
} |
||||
@ -0,0 +1,212 @@
@@ -0,0 +1,212 @@
|
||||
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
|
||||
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
|
||||
|
||||
using System; |
||||
using System.Collections.Generic; |
||||
|
||||
namespace ICSharpCode.SharpDevelop.Dom |
||||
{ |
||||
/// <summary>
|
||||
/// Base class for return types that wrap around other return types.
|
||||
/// </summary>
|
||||
public abstract class ProxyReturnType : IReturnType |
||||
{ |
||||
public abstract IReturnType BaseType { |
||||
get; |
||||
} |
||||
|
||||
public sealed override bool Equals(object obj) |
||||
{ |
||||
return Equals(obj as IReturnType); |
||||
} |
||||
|
||||
public virtual bool Equals(IReturnType other) |
||||
{ |
||||
// this check is necessary because the underlying Equals implementation
|
||||
// expects to be able to retrieve the base type of "other" - which fails when
|
||||
// this==other and therefore other.busy.
|
||||
if (other == this) |
||||
return true; |
||||
|
||||
IReturnType baseType = BaseType; |
||||
using (var l = busyManager.Enter(this)) { |
||||
return (l.Success && baseType != null) ? baseType.Equals(other) : false; |
||||
} |
||||
} |
||||
|
||||
public override int GetHashCode() |
||||
{ |
||||
IReturnType baseType = BaseType; |
||||
using (var l = busyManager.Enter(this)) { |
||||
return (l.Success && baseType != null) ? baseType.GetHashCode() : 0; |
||||
} |
||||
} |
||||
|
||||
protected int GetObjectHashCode() |
||||
{ |
||||
return base.GetHashCode(); |
||||
} |
||||
|
||||
// Required to prevent stack overflow on inferrence cycles
|
||||
[ThreadStatic] static BusyManager _busyManager; |
||||
|
||||
static BusyManager busyManager { |
||||
get { return _busyManager ?? (_busyManager = new BusyManager()); } |
||||
} |
||||
|
||||
public virtual string FullyQualifiedName { |
||||
get { |
||||
IReturnType baseType = BaseType; |
||||
using (var l = busyManager.Enter(this)) { |
||||
return (l.Success && baseType != null) ? baseType.FullyQualifiedName : "?"; |
||||
} |
||||
} |
||||
} |
||||
|
||||
public virtual string Name { |
||||
get { |
||||
IReturnType baseType = BaseType; |
||||
using (var l = busyManager.Enter(this)) { |
||||
return (l.Success && baseType != null) ? baseType.Name : "?"; |
||||
} |
||||
} |
||||
} |
||||
|
||||
public virtual string Namespace { |
||||
get { |
||||
IReturnType baseType = BaseType; |
||||
using (var l = busyManager.Enter(this)) { |
||||
return (l.Success && baseType != null) ? baseType.Namespace : "?"; |
||||
} |
||||
} |
||||
} |
||||
|
||||
public virtual string DotNetName { |
||||
get { |
||||
IReturnType baseType = BaseType; |
||||
using (var l = busyManager.Enter(this)) { |
||||
return (l.Success && baseType != null) ? baseType.DotNetName : "?"; |
||||
} |
||||
} |
||||
} |
||||
|
||||
public virtual int TypeArgumentCount { |
||||
get { |
||||
IReturnType baseType = BaseType; |
||||
using (var l = busyManager.Enter(this)) { |
||||
return (l.Success && baseType != null) ? baseType.TypeArgumentCount : 0; |
||||
} |
||||
} |
||||
} |
||||
|
||||
public virtual IClass GetUnderlyingClass() |
||||
{ |
||||
IReturnType baseType = BaseType; |
||||
using (var l = busyManager.Enter(this)) { |
||||
return (l.Success && baseType != null) ? baseType.GetUnderlyingClass() : null; |
||||
} |
||||
} |
||||
|
||||
public virtual List<IMethod> GetMethods() |
||||
{ |
||||
IReturnType baseType = BaseType; |
||||
using (var l = busyManager.Enter(this)) { |
||||
return (l.Success && baseType != null) ? baseType.GetMethods() : new List<IMethod>(); |
||||
} |
||||
} |
||||
|
||||
public virtual List<IProperty> GetProperties() |
||||
{ |
||||
IReturnType baseType = BaseType; |
||||
using (var l = busyManager.Enter(this)) { |
||||
return (l.Success && baseType != null) ? baseType.GetProperties() : new List<IProperty>(); |
||||
} |
||||
} |
||||
|
||||
public virtual List<IField> GetFields() |
||||
{ |
||||
IReturnType baseType = BaseType; |
||||
using (var l = busyManager.Enter(this)) { |
||||
return (l.Success && baseType != null) ? baseType.GetFields() : new List<IField>(); |
||||
} |
||||
} |
||||
|
||||
public virtual List<IEvent> GetEvents() |
||||
{ |
||||
IReturnType baseType = BaseType; |
||||
using (var l = busyManager.Enter(this)) { |
||||
return (l.Success && baseType != null) ? baseType.GetEvents() : new List<IEvent>(); |
||||
} |
||||
} |
||||
|
||||
public virtual bool IsDefaultReturnType { |
||||
get { |
||||
IReturnType baseType = BaseType; |
||||
using (var l = busyManager.Enter(this)) { |
||||
return (l.Success && baseType != null) ? baseType.IsDefaultReturnType : false; |
||||
} |
||||
} |
||||
} |
||||
|
||||
public bool IsDecoratingReturnType<T>() where T : DecoratingReturnType |
||||
{ |
||||
return CastToDecoratingReturnType<T>() != null; |
||||
} |
||||
|
||||
public virtual T CastToDecoratingReturnType<T>() where T : DecoratingReturnType |
||||
{ |
||||
IReturnType baseType = BaseType; |
||||
using (var l = busyManager.Enter(this)) { |
||||
return (l.Success && baseType != null) ? baseType.CastToDecoratingReturnType<T>() : null; |
||||
} |
||||
} |
||||
|
||||
|
||||
public bool IsArrayReturnType { |
||||
get { |
||||
return IsDecoratingReturnType<ArrayReturnType>(); |
||||
} |
||||
} |
||||
public ArrayReturnType CastToArrayReturnType() |
||||
{ |
||||
return CastToDecoratingReturnType<ArrayReturnType>(); |
||||
} |
||||
|
||||
public bool IsGenericReturnType { |
||||
get { |
||||
return IsDecoratingReturnType<GenericReturnType>(); |
||||
} |
||||
} |
||||
public GenericReturnType CastToGenericReturnType() |
||||
{ |
||||
return CastToDecoratingReturnType<GenericReturnType>(); |
||||
} |
||||
|
||||
public bool IsConstructedReturnType { |
||||
get { |
||||
return IsDecoratingReturnType<ConstructedReturnType>(); |
||||
} |
||||
} |
||||
public ConstructedReturnType CastToConstructedReturnType() |
||||
{ |
||||
return CastToDecoratingReturnType<ConstructedReturnType>(); |
||||
} |
||||
|
||||
public virtual bool? IsReferenceType { |
||||
get { |
||||
IReturnType baseType = BaseType; |
||||
using (var l = busyManager.Enter(this)) { |
||||
return (l.Success && baseType != null) ? baseType.IsReferenceType : null; |
||||
} |
||||
} |
||||
} |
||||
|
||||
public virtual IReturnType GetDirectReturnType() |
||||
{ |
||||
IReturnType baseType = BaseType; |
||||
using (var l = busyManager.Enter(this)) { |
||||
return (l.Success && baseType != null) ? baseType.GetDirectReturnType() : UnknownReturnType.Instance; |
||||
} |
||||
} |
||||
} |
||||
} |
||||
@ -0,0 +1,56 @@
@@ -0,0 +1,56 @@
|
||||
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
|
||||
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
|
||||
|
||||
using System; |
||||
|
||||
namespace ICSharpCode.SharpDevelop.Dom |
||||
{ |
||||
/// <summary>
|
||||
/// Return type used for "ref" or "out" expressions.
|
||||
/// </summary>
|
||||
public class ReferenceReturnType : DecoratingReturnType |
||||
{ |
||||
IReturnType baseType; |
||||
|
||||
public ReferenceReturnType(IReturnType baseType) |
||||
{ |
||||
this.baseType = baseType; |
||||
} |
||||
|
||||
public override IReturnType GetDirectReturnType() |
||||
{ |
||||
if (baseType == null) |
||||
return this; |
||||
IReturnType newBaseType = baseType.GetDirectReturnType(); |
||||
if (newBaseType == baseType) |
||||
return this; |
||||
else |
||||
return new ReferenceReturnType(newBaseType); |
||||
} |
||||
|
||||
public override IReturnType BaseType { |
||||
get { return baseType; } |
||||
} |
||||
|
||||
public override bool Equals(IReturnType other) |
||||
{ |
||||
return object.Equals(baseType, other); |
||||
} |
||||
|
||||
public override int GetHashCode() |
||||
{ |
||||
return baseType != null ? baseType.GetHashCode() : 0; |
||||
} |
||||
|
||||
public override T CastToDecoratingReturnType<T>() |
||||
{ |
||||
if (typeof(T) == typeof(ReferenceReturnType)) { |
||||
return (T)(object)this; |
||||
} else if (baseType != null) { |
||||
return baseType.CastToDecoratingReturnType<T>(); |
||||
} else { |
||||
return null; |
||||
} |
||||
} |
||||
} |
||||
} |
||||
@ -0,0 +1,126 @@
@@ -0,0 +1,126 @@
|
||||
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
|
||||
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
|
||||
|
||||
using System; |
||||
using System.Collections.Generic; |
||||
using System.Threading; |
||||
|
||||
namespace ICSharpCode.SharpDevelop.Dom |
||||
{ |
||||
/// <summary>
|
||||
/// The SearchClassReturnType is used when only a part of the class name is known and the
|
||||
/// type can only be resolved on demand (the ConvertVisitor uses SearchClassReturnTypes).
|
||||
/// </summary>
|
||||
public sealed class SearchClassReturnType : ProxyReturnType |
||||
{ |
||||
IClass declaringClass; |
||||
IProjectContent pc; |
||||
int caretLine; |
||||
int caretColumn; |
||||
string name; |
||||
string shortName; |
||||
int typeParameterCount; |
||||
bool lookForInnerClassesInDeclaringClass = true; |
||||
|
||||
public SearchClassReturnType(IProjectContent projectContent, IClass declaringClass, int caretLine, int caretColumn, string name, int typeParameterCount) |
||||
{ |
||||
if (declaringClass == null) |
||||
throw new ArgumentNullException("declaringClass"); |
||||
this.declaringClass = declaringClass; |
||||
this.pc = projectContent; |
||||
this.caretLine = caretLine; |
||||
this.caretColumn = caretColumn; |
||||
this.typeParameterCount = typeParameterCount; |
||||
this.name = name; |
||||
int pos = name.LastIndexOf('.'); |
||||
if (pos < 0) |
||||
shortName = name; |
||||
else |
||||
shortName = name.Substring(pos + 1); |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Gets/Sets whether to look for inner classes in the declaring class.
|
||||
/// The default is true.
|
||||
/// Set this property to false for return types that are used as base type references.
|
||||
/// </summary>
|
||||
public bool LookForInnerClassesInDeclaringClass { |
||||
get { return lookForInnerClassesInDeclaringClass; } |
||||
set { |
||||
lookForInnerClassesInDeclaringClass = value; |
||||
ClearCachedBaseType(); |
||||
} |
||||
} |
||||
|
||||
volatile IReturnType cachedBaseType; |
||||
|
||||
//int isSearching; // 0=false, 1=true
|
||||
|
||||
// Required to prevent stack overflow on inferrence cycles
|
||||
// replaces old 'isSearching' flag which wasn't thread-safe
|
||||
[ThreadStatic] static BusyManager _busyManager; |
||||
|
||||
static BusyManager busyManager { |
||||
get { return _busyManager ?? (_busyManager = new BusyManager()); } |
||||
} |
||||
|
||||
void ClearCachedBaseType() |
||||
{ |
||||
cachedBaseType = null; |
||||
} |
||||
|
||||
public override IReturnType BaseType { |
||||
get { |
||||
IReturnType type = cachedBaseType; |
||||
if (type != null) |
||||
return type; |
||||
using (var l = busyManager.Enter(this)) { |
||||
// abort if called recursively on the same thread
|
||||
if (!l.Success) |
||||
return null; |
||||
SearchTypeRequest request = new SearchTypeRequest(name, typeParameterCount, declaringClass, caretLine, caretColumn); |
||||
if (!lookForInnerClassesInDeclaringClass) { |
||||
// skip looking for inner classes by adjusting the CurrentType for the lookup
|
||||
request.CurrentType = declaringClass.DeclaringType; |
||||
} |
||||
type = pc.SearchType(request).Result; |
||||
cachedBaseType = type; |
||||
if (type != null) |
||||
DomCache.RegisterForClear(ClearCachedBaseType); |
||||
return type; |
||||
} |
||||
} |
||||
} |
||||
|
||||
public override string FullyQualifiedName { |
||||
get { |
||||
string tmp = base.FullyQualifiedName; |
||||
if (tmp == "?") { |
||||
return name; |
||||
} |
||||
return tmp; |
||||
} |
||||
} |
||||
|
||||
public override string Name { |
||||
get { |
||||
return shortName; |
||||
} |
||||
} |
||||
|
||||
public override string DotNetName { |
||||
get { |
||||
string tmp = base.DotNetName; |
||||
if (tmp == "?") { |
||||
return name; |
||||
} |
||||
return tmp; |
||||
} |
||||
} |
||||
|
||||
public override string ToString() |
||||
{ |
||||
return String.Format("[SearchClassReturnType: {0}]", name); |
||||
} |
||||
} |
||||
} |
||||
@ -0,0 +1,135 @@
@@ -0,0 +1,135 @@
|
||||
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
|
||||
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
|
||||
|
||||
using System; |
||||
using System.Collections.Generic; |
||||
|
||||
namespace ICSharpCode.SharpDevelop.Dom |
||||
{ |
||||
public class SystemTypes |
||||
{ |
||||
public readonly IReturnType Void; |
||||
public readonly IReturnType Object; |
||||
public readonly IReturnType Delegate; |
||||
public readonly IReturnType MulticastDelegate; |
||||
public readonly IReturnType ValueType; |
||||
public readonly IReturnType Enum; |
||||
|
||||
public readonly IReturnType Boolean; |
||||
public readonly IReturnType Int32; |
||||
public readonly IReturnType String; |
||||
|
||||
public readonly IReturnType Array; |
||||
public readonly IReturnType Attribute; |
||||
public readonly IReturnType Type; |
||||
|
||||
public readonly IReturnType Exception; |
||||
public readonly IReturnType AsyncCallback; |
||||
public readonly IReturnType IAsyncResult; |
||||
public readonly IReturnType IDisposable; |
||||
|
||||
IProjectContent pc; |
||||
|
||||
public SystemTypes(IProjectContent pc) |
||||
{ |
||||
this.pc = pc; |
||||
Void = new VoidReturnType(pc); |
||||
Object = CreateFromName("System.Object"); |
||||
Delegate = CreateFromName("System.Delegate"); |
||||
MulticastDelegate = CreateFromName("System.MulticastDelegate"); |
||||
ValueType = CreateFromName("System.ValueType"); |
||||
Enum = CreateFromName("System.Enum"); |
||||
|
||||
Boolean = CreateFromName("System.Boolean"); |
||||
Int32 = CreateFromName("System.Int32"); |
||||
String = CreateFromName("System.String"); |
||||
|
||||
Array = CreateFromName("System.Array"); |
||||
Attribute = CreateFromName("System.Attribute"); |
||||
Type = CreateFromName("System.Type"); |
||||
|
||||
Exception = CreateFromName("System.Exception"); |
||||
AsyncCallback = CreateFromName("System.AsyncCallback"); |
||||
IAsyncResult = CreateFromName("System.IAsyncResult"); |
||||
IDisposable = CreateFromName("System.IDisposable"); |
||||
} |
||||
|
||||
IReturnType CreateFromName(string name) |
||||
{ |
||||
IClass c = pc.GetClass(name, 0); |
||||
if (c != null) { |
||||
return c.DefaultReturnType; |
||||
} else { |
||||
LoggingService.Warn("SystemTypes.CreateFromName could not find " + name); |
||||
return Void; |
||||
} |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Creates the return type for a primitive system type.
|
||||
/// </summary>
|
||||
public IReturnType CreatePrimitive(Type type) |
||||
{ |
||||
if (type.HasElementType || type.ContainsGenericParameters) { |
||||
throw new ArgumentException("Only primitive types are supported."); |
||||
} |
||||
return CreateFromName(type.FullName); |
||||
} |
||||
} |
||||
|
||||
public sealed class VoidClass : DefaultClass |
||||
{ |
||||
internal static readonly string VoidName = typeof(void).FullName; |
||||
|
||||
public VoidClass(IProjectContent pc) |
||||
: base(new DefaultCompilationUnit(pc), VoidName) |
||||
{ |
||||
this.ClassType = ClassType.Struct; |
||||
this.Modifiers = ModifierEnum.Public | ModifierEnum.Sealed; |
||||
Freeze(); |
||||
} |
||||
|
||||
protected override IReturnType CreateDefaultReturnType() |
||||
{ |
||||
return ProjectContent.SystemTypes.Void; |
||||
} |
||||
} |
||||
|
||||
public sealed class VoidReturnType : AbstractReturnType |
||||
{ |
||||
IProjectContent pc; |
||||
|
||||
public VoidReturnType(IProjectContent pc) |
||||
{ |
||||
if (pc == null) |
||||
throw new ArgumentNullException("pc"); |
||||
this.pc = pc; |
||||
FullyQualifiedName = VoidClass.VoidName; |
||||
} |
||||
|
||||
public override IClass GetUnderlyingClass() |
||||
{ |
||||
return pc.GetClass("System.Void", 0, LanguageProperties.CSharp, GetClassOptions.LookInReferences); |
||||
} |
||||
|
||||
public override List<IMethod> GetMethods() |
||||
{ |
||||
return new List<IMethod>(); |
||||
} |
||||
|
||||
public override List<IProperty> GetProperties() |
||||
{ |
||||
return new List<IProperty>(); |
||||
} |
||||
|
||||
public override List<IField> GetFields() |
||||
{ |
||||
return new List<IField>(); |
||||
} |
||||
|
||||
public override List<IEvent> GetEvents() |
||||
{ |
||||
return new List<IEvent>(); |
||||
} |
||||
} |
||||
} |
||||
@ -0,0 +1,18 @@
@@ -0,0 +1,18 @@
|
||||
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
|
||||
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
|
||||
|
||||
using System; |
||||
|
||||
namespace ICSharpCode.SharpDevelop.Dom |
||||
{ |
||||
sealed class UnknownReturnType : ProxyReturnType |
||||
{ |
||||
public static readonly UnknownReturnType Instance = new UnknownReturnType(); |
||||
|
||||
public override IReturnType BaseType { |
||||
get { |
||||
return null; |
||||
} |
||||
} |
||||
} |
||||
} |
||||
@ -0,0 +1,14 @@
@@ -0,0 +1,14 @@
|
||||
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
|
||||
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
|
||||
|
||||
namespace ICSharpCode.SharpDevelop.Dom |
||||
{ |
||||
public enum ClassType { |
||||
Class = ICSharpCode.NRefactory.Ast.ClassType.Class, |
||||
Enum = ICSharpCode.NRefactory.Ast.ClassType.Enum, |
||||
Interface = ICSharpCode.NRefactory.Ast.ClassType.Interface, |
||||
Struct = ICSharpCode.NRefactory.Ast.ClassType.Struct, |
||||
Delegate = 0x5, |
||||
Module = ICSharpCode.NRefactory.Ast.ClassType.Module |
||||
} |
||||
} |
||||
@ -0,0 +1,51 @@
@@ -0,0 +1,51 @@
|
||||
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
|
||||
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
|
||||
|
||||
using System; |
||||
using System.Collections.Generic; |
||||
|
||||
namespace ICSharpCode.SharpDevelop.Dom |
||||
{ |
||||
public sealed class ExplicitInterfaceImplementation : Immutable, IEquatable<ExplicitInterfaceImplementation> |
||||
{ |
||||
readonly IReturnType interfaceReference; |
||||
readonly string memberName; |
||||
|
||||
public ExplicitInterfaceImplementation(IReturnType interfaceReference, string memberName) |
||||
{ |
||||
this.interfaceReference = interfaceReference; |
||||
this.memberName = memberName; |
||||
} |
||||
|
||||
public IReturnType InterfaceReference { |
||||
get { return interfaceReference; } |
||||
} |
||||
|
||||
public string MemberName { |
||||
get { return memberName; } |
||||
} |
||||
|
||||
public ExplicitInterfaceImplementation Clone() |
||||
{ |
||||
return this; // object is immutable, no Clone() required
|
||||
} |
||||
|
||||
public override int GetHashCode() |
||||
{ |
||||
return interfaceReference.GetHashCode() ^ memberName.GetHashCode(); |
||||
} |
||||
|
||||
public override bool Equals(object obj) |
||||
{ |
||||
return Equals(obj as ExplicitInterfaceImplementation); |
||||
} |
||||
|
||||
public bool Equals(ExplicitInterfaceImplementation other) |
||||
{ |
||||
if (other == null) |
||||
return false; |
||||
else |
||||
return this.interfaceReference == other.interfaceReference && this.memberName == other.memberName; |
||||
} |
||||
} |
||||
} |
||||
@ -0,0 +1,55 @@
@@ -0,0 +1,55 @@
|
||||
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
|
||||
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
|
||||
|
||||
using System; |
||||
using System.Collections.Generic; |
||||
|
||||
namespace ICSharpCode.SharpDevelop.Dom |
||||
{ |
||||
public interface IAttribute : IFreezable |
||||
{ |
||||
/// <summary>
|
||||
/// Gets the compilation unit in which this attribute is defined.
|
||||
/// </summary>
|
||||
ICompilationUnit CompilationUnit { |
||||
get; |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Gets the code region of this attribute.
|
||||
/// </summary>
|
||||
DomRegion Region { |
||||
get; |
||||
} |
||||
|
||||
AttributeTarget AttributeTarget { |
||||
get; |
||||
} |
||||
|
||||
IReturnType AttributeType { |
||||
get; |
||||
} |
||||
|
||||
IList<object> PositionalArguments { |
||||
get; |
||||
} |
||||
|
||||
IDictionary<string, object> NamedArguments { |
||||
get; |
||||
} |
||||
} |
||||
|
||||
public enum AttributeTarget |
||||
{ |
||||
None, |
||||
Assembly, |
||||
Field, |
||||
Event, |
||||
Method, |
||||
Module, |
||||
Param, |
||||
Property, |
||||
Return, |
||||
Type |
||||
} |
||||
} |
||||
@ -0,0 +1,150 @@
@@ -0,0 +1,150 @@
|
||||
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
|
||||
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
|
||||
|
||||
using System; |
||||
using System.Collections.Generic; |
||||
using System.Collections.ObjectModel; |
||||
|
||||
namespace ICSharpCode.SharpDevelop.Dom |
||||
{ |
||||
public interface IClass : IEntity |
||||
{ |
||||
/// <summary>
|
||||
/// Region of the whole class including the body.
|
||||
/// </summary>
|
||||
DomRegion Region { |
||||
get; |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// The default return type to use for this class.
|
||||
/// This property is mutable even when the IClass is frozen, see
|
||||
/// documentation for <see cref="HasCompoundClass"/>.
|
||||
/// This property is thread-safe.
|
||||
/// </summary>
|
||||
IReturnType DefaultReturnType { get; } |
||||
|
||||
ClassType ClassType { |
||||
get; |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Gets the using scope of contains this class.
|
||||
/// </summary>
|
||||
IUsingScope UsingScope { |
||||
get; |
||||
} |
||||
|
||||
IList<IReturnType> BaseTypes { |
||||
get; |
||||
} |
||||
|
||||
IList<IClass> InnerClasses { |
||||
get; |
||||
} |
||||
|
||||
IList<IField> Fields { |
||||
get; |
||||
} |
||||
|
||||
IList<IProperty> Properties { |
||||
get; |
||||
} |
||||
|
||||
IList<IMethod> Methods { |
||||
get; |
||||
} |
||||
|
||||
IList<IEvent> Events { |
||||
get; |
||||
} |
||||
|
||||
IEnumerable<IMember> AllMembers { |
||||
get; |
||||
} |
||||
|
||||
IList<ITypeParameter> TypeParameters { |
||||
get; |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Returns the list of all classes that this class inherits from (directly or indirectly).
|
||||
/// If this property is used on part of a partial class, it will also return classes inherited in other parts.
|
||||
/// </summary>
|
||||
IEnumerable<IClass> ClassInheritanceTree { |
||||
get; |
||||
} |
||||
|
||||
IEnumerable<IClass> ClassInheritanceTreeClassesOnly { |
||||
get; |
||||
} |
||||
|
||||
IClass BaseClass { |
||||
get; |
||||
} |
||||
|
||||
IReturnType BaseType { |
||||
get; |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// If this is a partial class, gets the compound class containing information from all parts.
|
||||
/// If this is not a partial class, a reference to this class is returned.
|
||||
/// </summary>
|
||||
IClass GetCompoundClass(); |
||||
|
||||
IClass GetInnermostClass(int caretLine, int caretColumn); |
||||
|
||||
List<IClass> GetAccessibleTypes(IClass callingClass); |
||||
|
||||
/// <summary>
|
||||
/// Searches the member with the specified name. Returns the first member/overload found.
|
||||
/// </summary>
|
||||
IMember SearchMember(string memberName, LanguageProperties language); |
||||
|
||||
/// <summary>Return true if the specified class is a base class of this class; otherwise return false.</summary>
|
||||
/// <remarks>Returns false when possibleBaseClass is null.</remarks>
|
||||
bool IsTypeInInheritanceTree(IClass possibleBaseClass); |
||||
|
||||
bool HasPublicOrInternalStaticMembers { |
||||
get; |
||||
} |
||||
bool HasExtensionMethods { |
||||
get; |
||||
} |
||||
|
||||
bool IsPartial { |
||||
get; |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Gets/sets if this class has an associated compound class.
|
||||
/// This property is mutable even if the IClass instance is frozen.
|
||||
/// This property is thread-safe.
|
||||
///
|
||||
/// This property may only be set by the IProjectContent implementation to which this class is added.
|
||||
///
|
||||
/// Rational: some languages support partial classes where only one of the parts needs
|
||||
/// the "partial" modifier. If the part without the modifier is added to the project
|
||||
/// content first, it is added without compound class and may get a DefaultReturnType that refers
|
||||
/// to itself.
|
||||
/// However, when the other part with the modifier is added, a compound class is created, and the
|
||||
/// DefaultReturnType of this class must change even though it is frozen.
|
||||
/// </summary>
|
||||
bool HasCompoundClass { |
||||
get; |
||||
set; |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Gets whether a default constructor should be added to this class if it is required.
|
||||
/// Such automatic default constructors will not appear in IClass.Methods, but will be present
|
||||
/// in IClass.DefaultReturnType.GetMethods().
|
||||
/// </summary>
|
||||
/// <remarks>This way of creating the default constructor is necessary because
|
||||
/// we cannot create it directly in the IClass - we need to consider partial classes.</remarks>
|
||||
bool AddDefaultConstructorIfRequired { |
||||
get; |
||||
} |
||||
} |
||||
} |
||||
@ -0,0 +1,74 @@
@@ -0,0 +1,74 @@
|
||||
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
|
||||
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
|
||||
|
||||
using System.Collections.Generic; |
||||
|
||||
namespace ICSharpCode.SharpDevelop.Dom |
||||
{ |
||||
public interface ICompilationUnit : IFreezable |
||||
{ |
||||
string FileName { |
||||
get; |
||||
set; |
||||
} |
||||
|
||||
bool ErrorsDuringCompile { |
||||
get; |
||||
set; |
||||
} |
||||
|
||||
object Tag { |
||||
get; |
||||
set; |
||||
} |
||||
|
||||
IProjectContent ProjectContent { |
||||
get; |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Gets the language this compilation unit was written in.
|
||||
/// </summary>
|
||||
LanguageProperties Language { |
||||
get; |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Gets the main using scope of the compilation unit.
|
||||
/// That scope usually represents the root namespace.
|
||||
/// </summary>
|
||||
IUsingScope UsingScope { |
||||
get; |
||||
} |
||||
|
||||
IList<IAttribute> Attributes { |
||||
get; |
||||
} |
||||
|
||||
IList<IClass> Classes { |
||||
get; |
||||
} |
||||
|
||||
IList<IComment> MiscComments { |
||||
get; |
||||
} |
||||
|
||||
IList<IComment> DokuComments { |
||||
get; |
||||
} |
||||
|
||||
IList<TagComment> TagComments { |
||||
get; |
||||
} |
||||
|
||||
IList<FoldingRegion> FoldingRegions { |
||||
get; |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Returns the innermost class in which the carret currently is, returns null
|
||||
/// if the carret is outside any class boundaries.
|
||||
/// </summary>
|
||||
IClass GetInnermostClass(int caretLine, int caretColumn); |
||||
} |
||||
} |
||||
@ -0,0 +1,18 @@
@@ -0,0 +1,18 @@
|
||||
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
|
||||
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
|
||||
|
||||
using System; |
||||
using System.Collections.Generic; |
||||
|
||||
namespace ICSharpCode.SharpDevelop.Dom |
||||
{ |
||||
/// <summary>
|
||||
/// Element of namespace or Dom completion list.
|
||||
/// </summary>
|
||||
public interface ICompletionEntry |
||||
{ |
||||
string Name { |
||||
get; |
||||
} |
||||
} |
||||
} |
||||
@ -0,0 +1,23 @@
@@ -0,0 +1,23 @@
|
||||
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
|
||||
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
|
||||
|
||||
using System; |
||||
|
||||
namespace ICSharpCode.SharpDevelop.Dom |
||||
{ |
||||
/// <summary>
|
||||
/// This is a basic interface to a "progress bar" type of
|
||||
/// control.
|
||||
/// </summary>
|
||||
public interface IDomProgressMonitor |
||||
{ |
||||
/// <summary>
|
||||
/// Gets/sets if the task current shows a modal dialog. Set this property to true to make progress
|
||||
/// dialogs windows temporarily invisible while your modal dialog is showing.
|
||||
/// </summary>
|
||||
bool ShowingDialog { |
||||
get; |
||||
set; |
||||
} |
||||
} |
||||
} |
||||
@ -0,0 +1,171 @@
@@ -0,0 +1,171 @@
|
||||
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
|
||||
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
|
||||
|
||||
using System; |
||||
using System.Collections.Generic; |
||||
|
||||
namespace ICSharpCode.SharpDevelop.Dom |
||||
{ |
||||
public interface IEntity : ICompletionEntry, IFreezable, IComparable |
||||
{ |
||||
string FullyQualifiedName { |
||||
get; |
||||
} |
||||
|
||||
string Namespace { |
||||
get; |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// The fully qualified name in the internal .NET notation (with `1 for generic types)
|
||||
/// </summary>
|
||||
string DotNetName { |
||||
get; |
||||
} |
||||
|
||||
DomRegion BodyRegion { |
||||
get; |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Gets the declaring type.
|
||||
/// For members, this is the type that contains the member.
|
||||
/// For classes, this is the outer class (for nested classes), or null if there this
|
||||
/// is a top-level class.
|
||||
/// </summary>
|
||||
IClass DeclaringType { |
||||
get; |
||||
} |
||||
|
||||
ModifierEnum Modifiers { |
||||
get; |
||||
} |
||||
|
||||
IList<IAttribute> Attributes { |
||||
get; |
||||
} |
||||
|
||||
string Documentation { |
||||
get; |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Returns true if this entity has the 'abstract' modifier set.
|
||||
/// (Returns false for interface members).
|
||||
/// </summary>
|
||||
bool IsAbstract { |
||||
get; |
||||
} |
||||
|
||||
bool IsSealed { |
||||
get; |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Gets whether this entity is static.
|
||||
/// Returns true if either the 'static' or the 'const' modifier is set.
|
||||
/// </summary>
|
||||
bool IsStatic { |
||||
get; |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Gets whether this entity is a constant (C#-like const).
|
||||
/// </summary>
|
||||
bool IsConst { |
||||
get; |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Gets if the member is virtual. Is true only if the "virtual" modifier was used, but non-virtual
|
||||
/// members can be overridden, too; if they are already overriding a method.
|
||||
/// </summary>
|
||||
bool IsVirtual { |
||||
get; |
||||
} |
||||
|
||||
bool IsPublic { |
||||
get; |
||||
} |
||||
|
||||
bool IsProtected { |
||||
get; |
||||
} |
||||
|
||||
bool IsPrivate { |
||||
get; |
||||
} |
||||
|
||||
bool IsInternal { |
||||
get; |
||||
} |
||||
|
||||
bool IsReadonly { |
||||
get; |
||||
} |
||||
|
||||
[Obsolete("This property does not do what one would expect - it merely checks if protected+internal are set, it is not the equivalent of AssemblyAndFamily in Reflection!")] |
||||
bool IsProtectedAndInternal { |
||||
get; |
||||
} |
||||
|
||||
[Obsolete("This property does not do what one would expect - it merely checks if one of protected+internal is set, it is not the equivalent of AssemblyOrFamily in Reflection!")] |
||||
bool IsProtectedOrInternal { |
||||
get; |
||||
} |
||||
|
||||
bool IsOverride { |
||||
get; |
||||
} |
||||
/// <summary>
|
||||
/// Gets if the member can be overridden. Returns true when the member is "virtual" or "override" but not "sealed".
|
||||
/// </summary>
|
||||
bool IsOverridable { |
||||
get; |
||||
} |
||||
|
||||
bool IsNew { |
||||
get; |
||||
} |
||||
bool IsSynthetic { |
||||
get; |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Gets the compilation unit that contains this entity.
|
||||
/// </summary>
|
||||
ICompilationUnit CompilationUnit { |
||||
get; |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// The project content in which this entity is defined.
|
||||
/// </summary>
|
||||
IProjectContent ProjectContent { |
||||
get; |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// This property can be used to attach any user-defined data to this class/method.
|
||||
/// This property is mutable, it can be changed when the class/method is frozen.
|
||||
/// </summary>
|
||||
object UserData { |
||||
get; |
||||
set; |
||||
} |
||||
|
||||
EntityType EntityType { |
||||
get; |
||||
} |
||||
|
||||
bool IsAccessible(IClass callingClass, bool isAccessThoughReferenceOfCurrentClass); |
||||
} |
||||
|
||||
public enum EntityType { |
||||
Class, |
||||
Field, |
||||
Property, |
||||
Method, |
||||
Event |
||||
} |
||||
} |
||||
@ -0,0 +1,22 @@
@@ -0,0 +1,22 @@
|
||||
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
|
||||
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
|
||||
|
||||
using System; |
||||
|
||||
namespace ICSharpCode.SharpDevelop.Dom |
||||
{ |
||||
public interface IEvent : IMember |
||||
{ |
||||
IMethod AddMethod { |
||||
get; |
||||
} |
||||
|
||||
IMethod RemoveMethod { |
||||
get; |
||||
} |
||||
|
||||
IMethod RaiseMethod { |
||||
get; |
||||
} |
||||
} |
||||
} |
||||
@ -0,0 +1,16 @@
@@ -0,0 +1,16 @@
|
||||
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
|
||||
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
|
||||
|
||||
using System; |
||||
|
||||
namespace ICSharpCode.SharpDevelop.Dom |
||||
{ |
||||
public interface IField : IMember |
||||
{ |
||||
/// <summary>Gets if this field is a local variable that has been converted into a field.</summary>
|
||||
bool IsLocalVariable { get; } |
||||
|
||||
/// <summary>Gets if this field is a parameter that has been converted into a field.</summary>
|
||||
bool IsParameter { get; } |
||||
} |
||||
} |
||||
@ -0,0 +1,103 @@
@@ -0,0 +1,103 @@
|
||||
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
|
||||
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
|
||||
|
||||
using System; |
||||
using System.Collections.Generic; |
||||
using System.Collections.ObjectModel; |
||||
using System.Linq; |
||||
|
||||
namespace ICSharpCode.SharpDevelop.Dom |
||||
{ |
||||
public interface IFreezable |
||||
{ |
||||
/// <summary>
|
||||
/// Gets if this instance is frozen. Frozen instances are immutable and thus thread-safe.
|
||||
/// </summary>
|
||||
bool IsFrozen { get; } |
||||
|
||||
/// <summary>
|
||||
/// Freezes this instance.
|
||||
/// </summary>
|
||||
void Freeze(); |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Base class for immutable objects. Provides implementation for IFreezable that reports the
|
||||
/// object as always-frozen.
|
||||
/// </summary>
|
||||
public abstract class Immutable : IFreezable |
||||
{ |
||||
bool IFreezable.IsFrozen { |
||||
get { return true; } |
||||
} |
||||
|
||||
void IFreezable.Freeze() |
||||
{ |
||||
} |
||||
} |
||||
|
||||
public abstract class AbstractFreezable : IFreezable |
||||
{ |
||||
bool isFrozen; |
||||
|
||||
/// <summary>
|
||||
/// Gets if this instance is frozen. Frozen instances are immutable and thus thread-safe.
|
||||
/// </summary>
|
||||
public bool IsFrozen { |
||||
get { return isFrozen; } |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Freezes this instance.
|
||||
/// </summary>
|
||||
public void Freeze() |
||||
{ |
||||
if (!isFrozen) { |
||||
FreezeInternal(); |
||||
isFrozen = true; |
||||
} |
||||
} |
||||
|
||||
protected virtual void FreezeInternal() |
||||
{ |
||||
} |
||||
|
||||
protected void CheckBeforeMutation() |
||||
{ |
||||
if (isFrozen) |
||||
throw new InvalidOperationException("Cannot mutate frozen " + GetType().Name); |
||||
} |
||||
|
||||
protected static IList<T> FreezeList<T>(IList<T> list) where T : IFreezable |
||||
{ |
||||
if (list == null || list.Count == 0) |
||||
return EmptyList<T>.Instance; |
||||
list = new ReadOnlyCollection<T>(list.ToArray()); |
||||
foreach (T item in list) { |
||||
item.Freeze(); |
||||
} |
||||
return list; |
||||
} |
||||
|
||||
protected static IList<IReturnType> FreezeList(IList<IReturnType> list) |
||||
{ |
||||
if (list == null || list.Count == 0) |
||||
return EmptyList<IReturnType>.Instance; |
||||
else |
||||
return new ReadOnlyCollection<IReturnType>(list.ToArray()); |
||||
} |
||||
|
||||
protected static IList<string> FreezeList(IList<string> list) |
||||
{ |
||||
if (list == null || list.Count == 0) |
||||
return EmptyList<string>.Instance; |
||||
else |
||||
return new ReadOnlyCollection<string>(list.ToArray()); |
||||
} |
||||
} |
||||
|
||||
static class EmptyList<T> |
||||
{ |
||||
public static readonly ReadOnlyCollection<T> Instance = new ReadOnlyCollection<T>(new T[0]); |
||||
} |
||||
} |
||||
@ -0,0 +1,54 @@
@@ -0,0 +1,54 @@
|
||||
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
|
||||
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
|
||||
|
||||
using System; |
||||
using System.Collections.Generic; |
||||
|
||||
namespace ICSharpCode.SharpDevelop.Dom |
||||
{ |
||||
public interface IMember : IEntity, ICloneable |
||||
{ |
||||
/// <summary>
|
||||
/// Declaration region of the member (without body!)
|
||||
/// </summary>
|
||||
DomRegion Region { |
||||
get; |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Gets/Sets the declaring type reference (declaring type incl. type arguments).
|
||||
/// Never returns null.
|
||||
/// If the property is set to null (e.g. when this is not a specialized member),
|
||||
/// it should return the default type reference to the <see cref="DeclaringType"/>.
|
||||
/// </summary>
|
||||
IReturnType DeclaringTypeReference { |
||||
get; |
||||
set; |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Gets the generic member this member is based on.
|
||||
/// Returns null if this is not a specialized member.
|
||||
/// Specialized members are the result of overload resolution with type substitution.
|
||||
/// </summary>
|
||||
IMember GenericMember { |
||||
get; |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Creates a copy of this member with its GenericMember property set to this member.
|
||||
/// Use this method to create copies of a member that should be regarded as the "same member"
|
||||
/// for refactoring purposes.
|
||||
/// </summary>
|
||||
IMember CreateSpecializedMember(); |
||||
|
||||
IReturnType ReturnType { |
||||
get; |
||||
set; |
||||
} |
||||
|
||||
IList<ExplicitInterfaceImplementation> InterfaceImplementations { |
||||
get; |
||||
} |
||||
} |
||||
} |
||||
@ -0,0 +1,38 @@
@@ -0,0 +1,38 @@
|
||||
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
|
||||
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
|
||||
|
||||
using System; |
||||
using System.Collections.Generic; |
||||
|
||||
namespace ICSharpCode.SharpDevelop.Dom |
||||
{ |
||||
public interface IMethodOrProperty : IMember |
||||
{ |
||||
IList<IParameter> Parameters { |
||||
get; |
||||
} |
||||
|
||||
bool IsExtensionMethod { |
||||
get; |
||||
} |
||||
} |
||||
|
||||
public interface IMethod : IMethodOrProperty |
||||
{ |
||||
IList<ITypeParameter> TypeParameters { |
||||
get; |
||||
} |
||||
|
||||
bool IsConstructor { |
||||
get; |
||||
} |
||||
|
||||
IList<string> HandlesClauses { |
||||
get; |
||||
} |
||||
|
||||
bool IsOperator { |
||||
get; |
||||
} |
||||
} |
||||
} |
||||
@ -0,0 +1,53 @@
@@ -0,0 +1,53 @@
|
||||
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
|
||||
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
|
||||
|
||||
using System; |
||||
using System.Collections.Generic; |
||||
|
||||
namespace ICSharpCode.SharpDevelop.Dom |
||||
{ |
||||
|
||||
public interface IParameter : IFreezable, IComparable |
||||
{ |
||||
string Name { |
||||
get; |
||||
} |
||||
|
||||
IReturnType ReturnType { |
||||
get; |
||||
set; |
||||
} |
||||
|
||||
IList<IAttribute> Attributes { |
||||
get; |
||||
} |
||||
|
||||
ParameterModifiers Modifiers { |
||||
get; |
||||
} |
||||
|
||||
DomRegion Region { |
||||
get; |
||||
} |
||||
|
||||
string Documentation { |
||||
get; |
||||
} |
||||
|
||||
bool IsOut { |
||||
get; |
||||
} |
||||
|
||||
bool IsRef { |
||||
get; |
||||
} |
||||
|
||||
bool IsParams { |
||||
get; |
||||
} |
||||
|
||||
bool IsOptional { |
||||
get; |
||||
} |
||||
} |
||||
} |
||||
@ -0,0 +1,38 @@
@@ -0,0 +1,38 @@
|
||||
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
|
||||
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
|
||||
|
||||
using System; |
||||
|
||||
namespace ICSharpCode.SharpDevelop.Dom |
||||
{ |
||||
public interface IProperty : IMethodOrProperty |
||||
{ |
||||
DomRegion GetterRegion { |
||||
get; |
||||
} |
||||
|
||||
DomRegion SetterRegion { |
||||
get; |
||||
} |
||||
|
||||
bool CanGet { |
||||
get; |
||||
} |
||||
|
||||
bool CanSet { |
||||
get; |
||||
} |
||||
|
||||
bool IsIndexer { |
||||
get; |
||||
} |
||||
|
||||
ModifierEnum GetterModifiers { |
||||
get; |
||||
} |
||||
|
||||
ModifierEnum SetterModifiers { |
||||
get; |
||||
} |
||||
} |
||||
} |
||||
@ -0,0 +1,145 @@
@@ -0,0 +1,145 @@
|
||||
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
|
||||
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
|
||||
|
||||
using System; |
||||
using System.Collections.Generic; |
||||
|
||||
namespace ICSharpCode.SharpDevelop.Dom |
||||
{ |
||||
/// <summary>
|
||||
/// Interface for reference to types (classes).
|
||||
/// Such a reference can be direct (DefaultReturnType), lazy (SearchClassReturnType) or
|
||||
/// returns types that stand for special references (e.g. ArrayReturnType)
|
||||
/// </summary>
|
||||
public interface IReturnType : IEquatable<IReturnType> |
||||
{ |
||||
/// <summary>
|
||||
/// Gets the fully qualified name of the class the return type is pointing to.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// "System.Int32" for int[]<br/>
|
||||
/// "System.Collections.Generic.List" for List<string>
|
||||
/// </returns>
|
||||
string FullyQualifiedName { |
||||
get; |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Gets the short name of the class the return type is pointing to.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// "Int32" or "int" (depending how the return type was created) for int[]<br/>
|
||||
/// "List" for List<string>
|
||||
/// </returns>
|
||||
string Name { |
||||
get; |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Gets the namespace of the class the return type is pointing to.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// "System" for int[]<br/>
|
||||
/// "System.Collections.Generic" for List<string>
|
||||
/// </returns>
|
||||
string Namespace { |
||||
get; |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Gets the full dotnet name of the return type. The DotnetName is used for the
|
||||
/// documentation tags.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// "System.Int[]" for int[]<br/>
|
||||
/// "System.Collections.Generic.List{System.String}" for List<string>
|
||||
/// </returns>
|
||||
string DotNetName { |
||||
get; |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Gets the number of type parameters the target class should have
|
||||
/// / the number of type arguments specified by this type reference.
|
||||
/// </summary>
|
||||
int TypeArgumentCount { |
||||
get; |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Gets the underlying class of this return type. This method will return <c>null</c> for
|
||||
/// generic return types and types that cannot be resolved.
|
||||
/// </summary>
|
||||
IClass GetUnderlyingClass(); |
||||
|
||||
/// <summary>
|
||||
/// Gets all methods that can be called on this return type.
|
||||
/// </summary>
|
||||
List<IMethod> GetMethods(); |
||||
|
||||
/// <summary>
|
||||
/// Gets all properties that can be called on this return type.
|
||||
/// </summary>
|
||||
List<IProperty> GetProperties(); |
||||
|
||||
/// <summary>
|
||||
/// Gets all fields that can be called on this return type.
|
||||
/// </summary>
|
||||
List<IField> GetFields(); |
||||
|
||||
/// <summary>
|
||||
/// Gets all events that can be called on this return type.
|
||||
/// </summary>
|
||||
List<IEvent> GetEvents(); |
||||
|
||||
|
||||
/// <summary>
|
||||
/// Gets if the return type is a default type, i.e. no array, generic etc.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// True for SearchClassReturnType, GetClassReturnType and DefaultReturnType.<br/>
|
||||
/// False for ArrayReturnType, SpecificReturnType etc.
|
||||
/// </returns>
|
||||
bool IsDefaultReturnType { get; } |
||||
|
||||
/// <summary>
|
||||
/// Gets if the cast to the specified decorating return type would be valid.
|
||||
/// </summary>
|
||||
bool IsDecoratingReturnType<T>() where T : DecoratingReturnType; |
||||
|
||||
/// <summary>
|
||||
/// Casts this return type to the decorating return type specified as type parameter.
|
||||
/// This methods casts correctly even when the return type is wrapped by a ProxyReturnType.
|
||||
/// When the cast is invalid, <c>null</c> is returned.
|
||||
/// </summary>
|
||||
T CastToDecoratingReturnType<T>() where T : DecoratingReturnType; |
||||
|
||||
bool IsArrayReturnType { get; } |
||||
ArrayReturnType CastToArrayReturnType(); |
||||
|
||||
bool IsGenericReturnType { get; } |
||||
GenericReturnType CastToGenericReturnType(); |
||||
|
||||
bool IsConstructedReturnType { get; } |
||||
ConstructedReturnType CastToConstructedReturnType(); |
||||
|
||||
/// <summary>
|
||||
/// Gets whether the type is a reference type or value type.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// true, if the type is a reference type.
|
||||
/// false, if the type is a value type.
|
||||
/// null, if the type is not known (e.g. generic type argument or type not found)
|
||||
/// </returns>
|
||||
bool? IsReferenceType { get; } |
||||
|
||||
/// <summary>
|
||||
/// Gets an identical return type that binds directly to the underlying class, so
|
||||
/// that repeatedly calling methods does not cause repeated class lookups.
|
||||
/// The direct return type will always point to the old version of the class, so don't
|
||||
/// store direct return types!
|
||||
/// </summary>
|
||||
/// <returns>This method never returns null.</returns>
|
||||
IReturnType GetDirectReturnType(); |
||||
} |
||||
} |
||||
@ -0,0 +1,71 @@
@@ -0,0 +1,71 @@
|
||||
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
|
||||
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
|
||||
|
||||
using System; |
||||
using System.Collections.Generic; |
||||
|
||||
namespace ICSharpCode.SharpDevelop.Dom |
||||
{ |
||||
/// <summary>
|
||||
/// Type parameter of a generic class/method.
|
||||
/// </summary>
|
||||
public interface ITypeParameter : IFreezable |
||||
{ |
||||
/// <summary>
|
||||
/// The name of the type parameter (for example "T")
|
||||
/// </summary>
|
||||
string Name { get; } |
||||
|
||||
/// <summary>
|
||||
/// Gets the index of the type parameter in the type parameter list of the owning method/class.
|
||||
/// </summary>
|
||||
int Index { get; } |
||||
|
||||
IList<IAttribute> Attributes { get; } |
||||
|
||||
/// <summary>
|
||||
/// The method this type parameter is defined for.
|
||||
/// This property is null when the type parameter is for a class.
|
||||
/// </summary>
|
||||
IMethod Method { get; } |
||||
|
||||
/// <summary>
|
||||
/// The class this type parameter is defined for.
|
||||
/// When the type parameter is defined for a method, this is the class containing
|
||||
/// that method.
|
||||
/// </summary>
|
||||
IClass Class { get; } |
||||
|
||||
/// <summary>
|
||||
/// Gets the contraints of this type parameter.
|
||||
/// </summary>
|
||||
IList<IReturnType> Constraints { get; } |
||||
|
||||
/// <summary>
|
||||
/// Gets if the type parameter has the 'new()' constraint.
|
||||
/// </summary>
|
||||
bool HasConstructableConstraint { get; } |
||||
|
||||
/// <summary>
|
||||
/// Gets if the type parameter has the 'class' constraint.
|
||||
/// </summary>
|
||||
bool HasReferenceTypeConstraint { get; } |
||||
|
||||
/// <summary>
|
||||
/// Gets if the type parameter has the 'struct' constraint.
|
||||
/// </summary>
|
||||
bool HasValueTypeConstraint { get; } |
||||
|
||||
/// <summary>
|
||||
/// Gets the type that was used to bind this type parameter.
|
||||
/// This property returns null for generic methods/classes, it
|
||||
/// is non-null only for constructed versions of generic methods.
|
||||
/// </summary>
|
||||
IReturnType BoundTo { get; } |
||||
|
||||
/// <summary>
|
||||
/// If this type parameter was bound, returns the unbound version of it.
|
||||
/// </summary>
|
||||
ITypeParameter UnboundTypeParameter { get; } |
||||
} |
||||
} |
||||
@ -0,0 +1,41 @@
@@ -0,0 +1,41 @@
|
||||
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
|
||||
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
|
||||
|
||||
using System; |
||||
using System.Collections.Generic; |
||||
|
||||
namespace ICSharpCode.SharpDevelop.Dom |
||||
{ |
||||
public interface IUsing : IFreezable |
||||
{ |
||||
DomRegion Region { |
||||
get; |
||||
} |
||||
|
||||
IList<string> Usings { |
||||
get; |
||||
} |
||||
|
||||
bool HasAliases { get; } |
||||
|
||||
void AddAlias(string alias, IReturnType type); |
||||
|
||||
/// <summary>
|
||||
/// Gets the list of aliases. Can be null when there are no aliases!
|
||||
/// </summary>
|
||||
IDictionary<string, IReturnType> Aliases { |
||||
get; |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Returns a collection of possible types that could be meant when using this Import
|
||||
/// to search the type.
|
||||
/// Types with the incorrect type parameter count might be returned, but for each
|
||||
/// same using entry or alias entry at most one (the best matching) type should be returned.
|
||||
/// </summary>
|
||||
/// <returns>An IEnumerable with zero or more non-null return types.</returns>
|
||||
IEnumerable<IReturnType> SearchType(string partialTypeName, int typeParameterCount); |
||||
|
||||
string SearchNamespace(string partialNamespaceName); |
||||
} |
||||
} |
||||
@ -0,0 +1,42 @@
@@ -0,0 +1,42 @@
|
||||
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
|
||||
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
|
||||
|
||||
using System; |
||||
using System.Collections.Generic; |
||||
|
||||
namespace ICSharpCode.SharpDevelop.Dom |
||||
{ |
||||
/// <summary>
|
||||
/// A scope that can contain using declarations.
|
||||
/// In C#, every file is a using scope, and every "namespace" declaration inside
|
||||
/// the file is a nested using scope.
|
||||
/// </summary>
|
||||
public interface IUsingScope : IFreezable |
||||
{ |
||||
/// <summary>
|
||||
/// Gets the region of the using scope.
|
||||
/// </summary>
|
||||
DomRegion Region { get; } |
||||
|
||||
/// <summary>
|
||||
/// Gets the parent scope.
|
||||
/// Returns null if this is a root scope.
|
||||
/// </summary>
|
||||
IUsingScope Parent { get; } |
||||
|
||||
/// <summary>
|
||||
/// Gets the usings in this using scope.
|
||||
/// </summary>
|
||||
IList<IUsing> Usings { get; } |
||||
|
||||
/// <summary>
|
||||
/// Gets the list of child scopes. Child scopes usually represent "namespace" declarations.
|
||||
/// </summary>
|
||||
IList<IUsingScope> ChildScopes { get; } |
||||
|
||||
/// <summary>
|
||||
/// Gets the name of the namespace represented by the using scope.
|
||||
/// </summary>
|
||||
string NamespaceName { get; } |
||||
} |
||||
} |
||||
@ -0,0 +1,46 @@
@@ -0,0 +1,46 @@
|
||||
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
|
||||
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
|
||||
|
||||
using System; |
||||
using M = ICSharpCode.NRefactory.Ast.Modifiers; |
||||
|
||||
namespace ICSharpCode.SharpDevelop.Dom |
||||
{ |
||||
[Flags] |
||||
public enum ModifierEnum // must be the same values as NRefactories' ModifierEnum
|
||||
{ |
||||
None = 0, |
||||
|
||||
// Access
|
||||
Private = M.Private, |
||||
Internal = M.Internal, // == Friend
|
||||
Protected = M.Protected, |
||||
Public = M.Public, |
||||
Dim = M.Dim, // VB.NET SPECIFIC
|
||||
|
||||
// Scope
|
||||
Abstract = M.Abstract, // == MustOverride/MustInherit
|
||||
Virtual = M.Virtual, |
||||
Sealed = M.Sealed, |
||||
Static = M.Static, |
||||
Override = M.Override, |
||||
Readonly = M.ReadOnly, |
||||
Const = M.Const, |
||||
New = M.New, // == Shadows
|
||||
Partial = M.Partial, |
||||
|
||||
// Special
|
||||
Extern = M.Extern, |
||||
Volatile = M.Volatile, |
||||
Unsafe = M.Unsafe, |
||||
Overloads = M.Overloads, // VB specific
|
||||
WithEvents = M.WithEvents, // VB specific
|
||||
Default = M.Default, // VB specific
|
||||
Fixed = M.Fixed, |
||||
|
||||
Synthetic = M.Synthetic, |
||||
|
||||
ProtectedAndInternal = Internal | Protected, |
||||
VisibilityMask = Private | Internal | Protected | Public, |
||||
} |
||||
} |
||||
@ -0,0 +1,20 @@
@@ -0,0 +1,20 @@
|
||||
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
|
||||
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
|
||||
|
||||
using System; |
||||
|
||||
namespace ICSharpCode.SharpDevelop.Dom |
||||
{ |
||||
[Serializable] |
||||
[Flags] |
||||
public enum ParameterModifiers : byte |
||||
{ |
||||
// Values must be the same as in NRefactory's ParamModifiers
|
||||
None = 0, |
||||
In = 1, |
||||
Out = 2, |
||||
Ref = 4, |
||||
Params = 8, |
||||
Optional = 16 |
||||
} |
||||
} |
||||
@ -0,0 +1,129 @@
@@ -0,0 +1,129 @@
|
||||
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
|
||||
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
|
||||
|
||||
using System; |
||||
using Location = ICSharpCode.NRefactory.Location; |
||||
|
||||
namespace ICSharpCode.SharpDevelop.Dom |
||||
{ |
||||
[Serializable] |
||||
public struct DomRegion : IEquatable<DomRegion> |
||||
{ |
||||
readonly int beginLine; |
||||
readonly int endLine; |
||||
readonly int beginColumn; |
||||
readonly int endColumn; |
||||
|
||||
public readonly static DomRegion Empty = new DomRegion(-1, -1); |
||||
|
||||
public bool IsEmpty { |
||||
get { |
||||
return BeginLine <= 0; |
||||
} |
||||
} |
||||
|
||||
public int BeginLine { |
||||
get { |
||||
return beginLine; |
||||
} |
||||
} |
||||
|
||||
/// <value>
|
||||
/// if the end line is == -1 the end column is -1 too
|
||||
/// this stands for an unknwon end
|
||||
/// </value>
|
||||
public int EndLine { |
||||
get { |
||||
return endLine; |
||||
} |
||||
} |
||||
|
||||
public int BeginColumn { |
||||
get { |
||||
return beginColumn; |
||||
} |
||||
} |
||||
|
||||
/// <value>
|
||||
/// if the end column is == -1 the end line is -1 too
|
||||
/// this stands for an unknown end
|
||||
/// </value>
|
||||
public int EndColumn { |
||||
get { |
||||
return endColumn; |
||||
} |
||||
} |
||||
|
||||
public static DomRegion FromLocation(Location start, Location end) |
||||
{ |
||||
return new DomRegion(start.Y, start.X, end.Y, end.X); |
||||
} |
||||
|
||||
public DomRegion(int beginLine, int beginColumn, int endLine, int endColumn) |
||||
{ |
||||
this.beginLine = beginLine; |
||||
this.beginColumn = beginColumn; |
||||
this.endLine = endLine; |
||||
this.endColumn = endColumn; |
||||
} |
||||
|
||||
public DomRegion(int beginLine, int beginColumn) |
||||
{ |
||||
this.beginLine = beginLine; |
||||
this.beginColumn = beginColumn; |
||||
this.endLine = -1; |
||||
this.endColumn = -1; |
||||
} |
||||
|
||||
/// <remarks>
|
||||
/// Returns true, if the given coordinates (row, column) are in the region.
|
||||
/// This method assumes that for an unknown end the end line is == -1
|
||||
/// </remarks>
|
||||
public bool IsInside(int row, int column) |
||||
{ |
||||
if (IsEmpty) |
||||
return false; |
||||
return row >= BeginLine && |
||||
(row <= EndLine || EndLine == -1) && |
||||
(row != BeginLine || column >= BeginColumn) && |
||||
(row != EndLine || column <= EndColumn); |
||||
} |
||||
|
||||
public override string ToString() |
||||
{ |
||||
return String.Format("[Region: BeginLine = {0}, EndLine = {1}, BeginColumn = {2}, EndColumn = {3}]", |
||||
beginLine, |
||||
endLine, |
||||
beginColumn, |
||||
endColumn); |
||||
} |
||||
|
||||
public override bool Equals(object obj) |
||||
{ |
||||
return obj is DomRegion && Equals((DomRegion)obj); |
||||
} |
||||
|
||||
public override int GetHashCode() |
||||
{ |
||||
unchecked { |
||||
return BeginColumn + 1100009 * BeginLine + 1200007 * BeginColumn + 1300021 * EndColumn; |
||||
} |
||||
} |
||||
|
||||
public bool Equals(DomRegion other) |
||||
{ |
||||
return BeginLine == other.BeginLine && BeginColumn == other.BeginColumn |
||||
&& EndLine == other.EndLine && EndColumn == other.EndColumn; |
||||
} |
||||
|
||||
public static bool operator ==(DomRegion lhs, DomRegion rhs) |
||||
{ |
||||
return lhs.Equals(rhs); |
||||
} |
||||
|
||||
public static bool operator !=(DomRegion lhs, DomRegion rhs) |
||||
{ |
||||
return !lhs.Equals(rhs); |
||||
} |
||||
} |
||||
} |
||||
@ -0,0 +1,556 @@
@@ -0,0 +1,556 @@
|
||||
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
|
||||
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
|
||||
|
||||
using System; |
||||
using System.Collections.Generic; |
||||
using System.Diagnostics; |
||||
using ICSharpCode.SharpDevelop.Dom.Refactoring; |
||||
|
||||
namespace ICSharpCode.SharpDevelop.Dom |
||||
{ |
||||
public class LanguageProperties |
||||
{ |
||||
/// <summary>
|
||||
/// A case-sensitive dummy language that returns false for all Supports.. properties,
|
||||
/// uses a dummy code generator and refactoring provider and returns null for CodeDomProvider.
|
||||
/// </summary>
|
||||
public readonly static LanguageProperties None = new LanguageProperties(StringComparer.Ordinal); |
||||
|
||||
/// <summary>
|
||||
/// C# 3.0 language properties.
|
||||
/// </summary>
|
||||
public readonly static LanguageProperties CSharp = new CSharpProperties(); |
||||
|
||||
/// <summary>
|
||||
/// VB.Net 8 language properties.
|
||||
/// </summary>
|
||||
public readonly static LanguageProperties VBNet = new VBNetProperties(); |
||||
|
||||
public LanguageProperties(StringComparer nameComparer) |
||||
{ |
||||
this.nameComparer = nameComparer; |
||||
} |
||||
|
||||
#region Language-specific service providers
|
||||
readonly StringComparer nameComparer; |
||||
|
||||
public StringComparer NameComparer { |
||||
get { |
||||
return nameComparer; |
||||
} |
||||
} |
||||
|
||||
public virtual CodeGenerator CodeGenerator { |
||||
get { |
||||
return CodeGenerator.DummyCodeGenerator; |
||||
} |
||||
} |
||||
|
||||
public virtual RefactoringProvider RefactoringProvider { |
||||
get { |
||||
return RefactoringProvider.DummyProvider; |
||||
} |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Gets the ambience for this language. Because the IAmbience interface is not thread-safe, every call
|
||||
/// creates a new instance.
|
||||
/// </summary>
|
||||
public virtual IAmbience GetAmbience() |
||||
{ |
||||
return new CSharp.CSharpAmbience(); |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Gets the CodeDomProvider for this language. Can return null!
|
||||
/// </summary>
|
||||
public virtual System.CodeDom.Compiler.CodeDomProvider CodeDomProvider { |
||||
get { |
||||
return null; |
||||
} |
||||
} |
||||
|
||||
sealed class DummyCodeDomProvider : System.CodeDom.Compiler.CodeDomProvider |
||||
{ |
||||
public static readonly DummyCodeDomProvider Instance = new DummyCodeDomProvider(); |
||||
|
||||
[Obsolete("Callers should not use the ICodeGenerator interface and should instead use the methods directly on the CodeDomProvider class.")] |
||||
public override System.CodeDom.Compiler.ICodeGenerator CreateGenerator() |
||||
{ |
||||
return null; |
||||
} |
||||
|
||||
[Obsolete("Callers should not use the ICodeCompiler interface and should instead use the methods directly on the CodeDomProvider class.")] |
||||
public override System.CodeDom.Compiler.ICodeCompiler CreateCompiler() |
||||
{ |
||||
return null; |
||||
} |
||||
} |
||||
#endregion
|
||||
|
||||
#region Supports...
|
||||
/// <summary>
|
||||
/// Gets if the language supports calling C# 3-style extension methods
|
||||
/// (first parameter = instance parameter)
|
||||
/// </summary>
|
||||
public virtual bool SupportsExtensionMethods { |
||||
get { return false; } |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Gets if the language supports calling extension properties
|
||||
/// (first parameter = instance parameter)
|
||||
/// </summary>
|
||||
public virtual bool SupportsExtensionProperties { |
||||
get { return false; } |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Gets if extension methods/properties are searched in imported classes (returns true) or if
|
||||
/// only the extensions from the current class, imported classes and imported modules are used
|
||||
/// (returns false). This property has no effect if the language doesn't support extension methods or properties.
|
||||
/// </summary>
|
||||
public virtual bool SearchExtensionsInClasses { |
||||
get { return false; } |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Gets if namespaces are imported (i.e. Imports System, Dim a As Collections.ArrayList)
|
||||
/// </summary>
|
||||
public virtual bool ImportNamespaces { |
||||
get { return false; } |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Gets if modules are imported with their namespace (i.e. Microsoft.VisualBasic.Randomize()).
|
||||
/// </summary>
|
||||
public virtual bool ImportModules { |
||||
get { return false; } |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Gets if classes can be imported (i.e. Imports System.Math)
|
||||
/// </summary>
|
||||
public virtual bool CanImportClasses { |
||||
get { return false; } |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Gets if the language allows partial classes where the partial modifier is not
|
||||
/// used on any part.
|
||||
/// </summary>
|
||||
public virtual bool ImplicitPartialClasses { |
||||
get { return false; } |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Allow invoking an object constructor outside of ExpressionContext.ObjectCreation.
|
||||
/// Used for Boo, which creates instances like this: 'self.Size = Size(10, 20)'
|
||||
/// </summary>
|
||||
public virtual bool AllowObjectConstructionOutsideContext { |
||||
get { return false; } |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Gets if the language supports implicit interface implementations.
|
||||
/// </summary>
|
||||
public virtual bool SupportsImplicitInterfaceImplementation { |
||||
get { return false; } |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Gets if the language enforces that explicit interface implementations are uncallable except through
|
||||
/// the interface itself.
|
||||
/// If this property is false, code generators may assume that multiple explicit interface implementations
|
||||
/// with conflicting return types are invalid unless they are renamed.
|
||||
/// </summary>
|
||||
public virtual bool ExplicitInterfaceImplementationIsPrivateScope { |
||||
get { return false; } |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Gets if events explicitly implementing an interface require add {} remove {} regions.
|
||||
/// </summary>
|
||||
public virtual bool RequiresAddRemoveRegionInExplicitInterfaceImplementation { |
||||
get { return false; } |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Gets the start token of an indexer expression in the language. Usually '[' or '('.
|
||||
/// </summary>
|
||||
public virtual string IndexerExpressionStartToken { |
||||
get { return "["; } |
||||
} |
||||
|
||||
public virtual TextFinder GetFindClassReferencesTextFinder(IClass c) |
||||
{ |
||||
// when finding attribute references, also look for the short form of the name
|
||||
if (c.Name.Length > 9 && nameComparer.Equals(c.Name.Substring(c.Name.Length - 9), "Attribute")) { |
||||
return new CombinedTextFinder( |
||||
new WholeWordTextFinder(c.Name.Substring(0, c.Name.Length - 9), nameComparer), |
||||
new WholeWordTextFinder(c.Name, nameComparer) |
||||
); |
||||
} |
||||
return new WholeWordTextFinder(c.Name, nameComparer); |
||||
} |
||||
|
||||
public virtual TextFinder GetFindMemberReferencesTextFinder(IMember member) |
||||
{ |
||||
IProperty property = member as IProperty; |
||||
if (property != null && property.IsIndexer) { |
||||
return new IndexBeforeTextFinder(IndexerExpressionStartToken); |
||||
} else { |
||||
return new WholeWordTextFinder(member.Name, nameComparer); |
||||
} |
||||
} |
||||
|
||||
public virtual bool IsClassWithImplicitlyStaticMembers(IClass c) |
||||
{ |
||||
return false; |
||||
} |
||||
#endregion
|
||||
|
||||
#region Code-completion filters
|
||||
public virtual bool ShowInNamespaceCompletion(IClass c) |
||||
{ |
||||
return true; |
||||
} |
||||
|
||||
public virtual bool ShowMember(IMember member, bool showStatic) |
||||
{ |
||||
IProperty property = member as IProperty; |
||||
if (property != null && property.IsIndexer) { |
||||
return false; |
||||
} |
||||
IMethod method = member as IMethod; |
||||
if (method != null && (method.IsConstructor || method.IsOperator)) { |
||||
return false; |
||||
} |
||||
return member.IsStatic == showStatic; |
||||
} |
||||
|
||||
public virtual bool ShowMemberInOverrideCompletion(IMember member) |
||||
{ |
||||
return true; |
||||
} |
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// Generates the default imports statements a new application for this language should use.
|
||||
/// </summary>
|
||||
public virtual IUsing CreateDefaultImports(IProjectContent pc) |
||||
{ |
||||
return null; |
||||
} |
||||
|
||||
public override string ToString() |
||||
{ |
||||
return "[" + base.ToString() + "]"; |
||||
} |
||||
|
||||
public static LanguageProperties GetLanguage(string language) |
||||
{ |
||||
switch(language) |
||||
{ |
||||
case "VBNet": |
||||
case "VB": |
||||
return LanguageProperties.VBNet; |
||||
default: |
||||
return LanguageProperties.CSharp; |
||||
} |
||||
} |
||||
|
||||
#region CSharpProperties
|
||||
internal sealed class CSharpProperties : LanguageProperties |
||||
{ |
||||
public CSharpProperties() : base(StringComparer.Ordinal) {} |
||||
|
||||
public override RefactoringProvider RefactoringProvider { |
||||
get { |
||||
return NRefactoryRefactoringProvider.NRefactoryCSharpProviderInstance; |
||||
} |
||||
} |
||||
|
||||
public override CodeGenerator CodeGenerator { |
||||
get { |
||||
return CSharpCodeGenerator.Instance; |
||||
} |
||||
} |
||||
|
||||
public override System.CodeDom.Compiler.CodeDomProvider CodeDomProvider { |
||||
get { |
||||
return new Microsoft.CSharp.CSharpCodeProvider(); |
||||
} |
||||
} |
||||
|
||||
public override bool SupportsImplicitInterfaceImplementation { |
||||
get { return true; } |
||||
} |
||||
|
||||
public override bool ExplicitInterfaceImplementationIsPrivateScope { |
||||
get { return true; } |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Gets if events explicitly implementing an interface require add {} remove {} regions.
|
||||
/// </summary>
|
||||
public override bool RequiresAddRemoveRegionInExplicitInterfaceImplementation { |
||||
get { return true; } |
||||
} |
||||
|
||||
public override bool SupportsExtensionMethods { |
||||
get { return true; } |
||||
} |
||||
|
||||
public override bool SearchExtensionsInClasses { |
||||
get { return true; } |
||||
} |
||||
|
||||
public override string ToString() |
||||
{ |
||||
return "[LanguageProperties: C#]"; |
||||
} |
||||
|
||||
public override TextFinder GetFindMemberReferencesTextFinder(IMember member) |
||||
{ |
||||
IMethod method = member as IMethod; |
||||
if (method != null && method.IsConstructor) { |
||||
return new CombinedTextFinder( |
||||
new WholeWordTextFinder(member.DeclaringType.Name, this.NameComparer), |
||||
new WholeWordTextFinder("this", this.NameComparer), |
||||
new WholeWordTextFinder("base", this.NameComparer) |
||||
); |
||||
} else { |
||||
return base.GetFindMemberReferencesTextFinder(member); |
||||
} |
||||
} |
||||
|
||||
public override bool ShowMember(IMember member, bool showStatic) |
||||
{ |
||||
if (!base.ShowMember(member, showStatic)) |
||||
return false; |
||||
// do not show 'Finalize' methods (they are not directly callable from C#)
|
||||
IMethod method = member as IMethod; |
||||
if (method != null) { |
||||
if (method.Name == "Finalize" && method.Parameters.Count == 0) |
||||
return false; |
||||
} |
||||
return true; |
||||
} |
||||
|
||||
public override bool ShowMemberInOverrideCompletion(IMember member) |
||||
{ |
||||
IMethod method = member as IMethod; |
||||
|
||||
if (method != null) { |
||||
if (method.Name == "Finalize" && method.Parameters.Count == 0) |
||||
return false; |
||||
} |
||||
|
||||
return base.ShowMemberInOverrideCompletion(member); |
||||
} |
||||
} |
||||
#endregion
|
||||
|
||||
#region VBNetProperties
|
||||
internal sealed class VBNetProperties : LanguageProperties |
||||
{ |
||||
public VBNetProperties() : base(StringComparer.OrdinalIgnoreCase) {} |
||||
|
||||
public override bool ShowMember(IMember member, bool showStatic) |
||||
{ |
||||
if (member is ArrayReturnType.ArrayIndexer) { |
||||
return false; |
||||
} |
||||
IMethod method = member as IMethod; |
||||
if (method != null && (method.IsConstructor || method.IsOperator)) { |
||||
return false; |
||||
} |
||||
return member.IsStatic || !showStatic; |
||||
} |
||||
|
||||
public override bool ImportNamespaces { |
||||
get { |
||||
return true; |
||||
} |
||||
} |
||||
|
||||
public override bool ImportModules { |
||||
get { |
||||
return true; |
||||
} |
||||
} |
||||
|
||||
public override bool CanImportClasses { |
||||
get { |
||||
return true; |
||||
} |
||||
} |
||||
|
||||
public override bool SupportsExtensionMethods { |
||||
get { return true; } |
||||
} |
||||
|
||||
public override bool SearchExtensionsInClasses { |
||||
get { return true; } |
||||
} |
||||
|
||||
public override bool IsClassWithImplicitlyStaticMembers(IClass c) |
||||
{ |
||||
return c.ClassType == ClassType.Module; |
||||
} |
||||
|
||||
public override bool ShowInNamespaceCompletion(IClass c) |
||||
{ |
||||
foreach (IAttribute attr in c.Attributes) { |
||||
if (attr.AttributeType.FullyQualifiedName == "Microsoft.VisualBasic.HideModuleNameAttribute") |
||||
return false; |
||||
} |
||||
return base.ShowInNamespaceCompletion(c); |
||||
} |
||||
|
||||
public override IUsing CreateDefaultImports(IProjectContent pc) |
||||
{ |
||||
DefaultUsing u = new DefaultUsing(pc); |
||||
u.Usings.Add("Microsoft.VisualBasic"); |
||||
u.Usings.Add("System"); |
||||
u.Usings.Add("System.Collections"); |
||||
u.Usings.Add("System.Collections.Generic"); |
||||
u.Usings.Add("System.Drawing"); |
||||
u.Usings.Add("System.Diagnostics"); |
||||
u.Usings.Add("System.Windows.Forms"); |
||||
return u; |
||||
} |
||||
|
||||
public override RefactoringProvider RefactoringProvider { |
||||
get { |
||||
return NRefactoryRefactoringProvider.NRefactoryVBNetProviderInstance; |
||||
} |
||||
} |
||||
|
||||
public override CodeGenerator CodeGenerator { |
||||
get { |
||||
return VBNetCodeGenerator.Instance; |
||||
} |
||||
} |
||||
|
||||
public override System.CodeDom.Compiler.CodeDomProvider CodeDomProvider { |
||||
get { |
||||
return new Microsoft.VisualBasic.VBCodeProvider(); |
||||
} |
||||
} |
||||
|
||||
public override IAmbience GetAmbience() |
||||
{ |
||||
return new VBNet.VBNetAmbience(); |
||||
} |
||||
|
||||
public override string IndexerExpressionStartToken { |
||||
get { return "("; } |
||||
} |
||||
|
||||
public override string ToString() |
||||
{ |
||||
return "[LanguageProperties: VB.NET]"; |
||||
} |
||||
} |
||||
#endregion
|
||||
|
||||
#region Text Finder
|
||||
protected sealed class WholeWordTextFinder : TextFinder |
||||
{ |
||||
readonly string searchedText; |
||||
readonly bool caseInsensitive; |
||||
|
||||
public WholeWordTextFinder(string word, StringComparer nameComparer) |
||||
{ |
||||
if (word == null) word = string.Empty; |
||||
|
||||
caseInsensitive = nameComparer.Equals("a", "A"); |
||||
if (caseInsensitive) |
||||
this.searchedText = word.ToLowerInvariant(); |
||||
else |
||||
this.searchedText = word; |
||||
} |
||||
|
||||
public override string PrepareInputText(string inputText) |
||||
{ |
||||
if (caseInsensitive) |
||||
return inputText.ToLowerInvariant(); |
||||
else |
||||
return inputText; |
||||
} |
||||
|
||||
public override TextFinderMatch Find(string inputText, int startPosition) |
||||
{ |
||||
if (searchedText.Length == 0) |
||||
return TextFinderMatch.Empty; |
||||
int pos = startPosition - 1; |
||||
while ((pos = inputText.IndexOf(searchedText, pos + 1)) >= 0) { |
||||
if (pos > 0 && char.IsLetterOrDigit(inputText, pos - 1)) { |
||||
continue; // memberName is not a whole word (a.SomeName cannot reference Name)
|
||||
} |
||||
if (pos < inputText.Length - searchedText.Length - 1 |
||||
&& char.IsLetterOrDigit(inputText, pos + searchedText.Length)) |
||||
{ |
||||
continue; // memberName is not a whole word (a.Name2 cannot reference Name)
|
||||
} |
||||
return new TextFinderMatch(pos, searchedText.Length); |
||||
} |
||||
return TextFinderMatch.Empty; |
||||
} |
||||
} |
||||
|
||||
protected sealed class CombinedTextFinder : TextFinder |
||||
{ |
||||
readonly TextFinder[] finders; |
||||
|
||||
public CombinedTextFinder(params TextFinder[] finders) |
||||
{ |
||||
if (finders == null) |
||||
throw new ArgumentNullException("finders"); |
||||
if (finders.Length == 0) |
||||
throw new ArgumentException("finders.Length must be > 0"); |
||||
this.finders = finders; |
||||
} |
||||
|
||||
public override string PrepareInputText(string inputText) |
||||
{ |
||||
return finders[0].PrepareInputText(inputText); |
||||
} |
||||
|
||||
public override TextFinderMatch Find(string inputText, int startPosition) |
||||
{ |
||||
TextFinderMatch best = TextFinderMatch.Empty; |
||||
foreach (TextFinder f in finders) { |
||||
TextFinderMatch r = f.Find(inputText, startPosition); |
||||
if (r.Position >= 0 && (best.Position < 0 || r.Position < best.Position)) { |
||||
best = r; |
||||
} |
||||
} |
||||
return best; |
||||
} |
||||
} |
||||
|
||||
protected sealed class IndexBeforeTextFinder : TextFinder |
||||
{ |
||||
readonly string searchText; |
||||
|
||||
public IndexBeforeTextFinder(string searchText) |
||||
{ |
||||
this.searchText = searchText; |
||||
} |
||||
|
||||
public override TextFinderMatch Find(string inputText, int startPosition) |
||||
{ |
||||
int pos = inputText.IndexOf(searchText, startPosition); |
||||
if (pos >= 0) { |
||||
return new TextFinderMatch(pos, searchText.Length, pos - 1); |
||||
} else { |
||||
return TextFinderMatch.Empty; |
||||
} |
||||
} |
||||
} |
||||
#endregion
|
||||
} |
||||
} |
||||
@ -0,0 +1,95 @@
@@ -0,0 +1,95 @@
|
||||
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
|
||||
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
|
||||
|
||||
using System; |
||||
using System.Collections.Generic; |
||||
|
||||
namespace ICSharpCode.SharpDevelop.Dom |
||||
{ |
||||
/// <summary>
|
||||
/// A list that lazily initializes its content. The base list returned by the initializer may be
|
||||
/// modified.
|
||||
/// </summary>
|
||||
sealed class LazyList<T> : IList<T> |
||||
{ |
||||
readonly Func<IList<T>> initializer; |
||||
IList<T> innerList; |
||||
|
||||
public IList<T> InnerList { |
||||
get { |
||||
if (innerList == null) |
||||
innerList = initializer(); |
||||
return innerList; |
||||
} |
||||
} |
||||
|
||||
public LazyList(Func<IList<T>> initializer) |
||||
{ |
||||
if (initializer == null) throw new ArgumentNullException("initializer"); |
||||
this.initializer = initializer; |
||||
} |
||||
|
||||
public T this[int index] { |
||||
get { return InnerList[index]; } |
||||
set { InnerList[index] = value; } |
||||
} |
||||
|
||||
public int Count { |
||||
get { return InnerList.Count; } |
||||
} |
||||
|
||||
public bool IsReadOnly { |
||||
get { return InnerList.IsReadOnly; } |
||||
} |
||||
|
||||
public int IndexOf(T item) |
||||
{ |
||||
return InnerList.IndexOf(item); |
||||
} |
||||
|
||||
public void Insert(int index, T item) |
||||
{ |
||||
InnerList.Insert(index, item); |
||||
} |
||||
|
||||
public void RemoveAt(int index) |
||||
{ |
||||
InnerList.RemoveAt(index); |
||||
} |
||||
|
||||
public void Add(T item) |
||||
{ |
||||
InnerList.Add(item); |
||||
} |
||||
|
||||
public void Clear() |
||||
{ |
||||
InnerList.Clear(); |
||||
} |
||||
|
||||
public bool Contains(T item) |
||||
{ |
||||
return InnerList.Contains(item); |
||||
} |
||||
|
||||
public void CopyTo(T[] array, int arrayIndex) |
||||
{ |
||||
InnerList.CopyTo(array, arrayIndex); |
||||
} |
||||
|
||||
public bool Remove(T item) |
||||
{ |
||||
return InnerList.Remove(item); |
||||
} |
||||
|
||||
public IEnumerator<T> GetEnumerator() |
||||
{ |
||||
return InnerList.GetEnumerator(); |
||||
} |
||||
|
||||
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() |
||||
{ |
||||
return this.GetEnumerator(); |
||||
} |
||||
} |
||||
} |
||||
@ -0,0 +1,52 @@
@@ -0,0 +1,52 @@
|
||||
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
|
||||
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
|
||||
|
||||
using System; |
||||
using log4net; |
||||
|
||||
namespace ICSharpCode.SharpDevelop.Dom |
||||
{ |
||||
/// <summary>
|
||||
/// We don't reference ICSharpCode.Core but still need the logging interface.
|
||||
/// </summary>
|
||||
internal static class LoggingService |
||||
{ |
||||
static ILog log = LogManager.GetLogger(typeof(LoggingService)); |
||||
|
||||
public static void Debug(object message) |
||||
{ |
||||
log.Debug(message); |
||||
} |
||||
|
||||
public static void Info(object message) |
||||
{ |
||||
log.Info(message); |
||||
} |
||||
|
||||
public static void Warn(object message) |
||||
{ |
||||
log.Warn(message); |
||||
} |
||||
|
||||
public static void Warn(object message, Exception exception) |
||||
{ |
||||
log.Warn(message, exception); |
||||
} |
||||
|
||||
public static void Error(object message) |
||||
{ |
||||
log.Error(message); |
||||
} |
||||
|
||||
public static void Error(object message, Exception exception) |
||||
{ |
||||
log.Error(message, exception); |
||||
} |
||||
|
||||
public static bool IsDebugEnabled { |
||||
get { |
||||
return log.IsDebugEnabled; |
||||
} |
||||
} |
||||
} |
||||
} |
||||
@ -0,0 +1,871 @@
@@ -0,0 +1,871 @@
|
||||
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
|
||||
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
|
||||
|
||||
using System; |
||||
using System.Collections.Generic; |
||||
using System.Diagnostics; |
||||
using System.Linq; |
||||
|
||||
namespace ICSharpCode.SharpDevelop.Dom |
||||
{ |
||||
/// <summary>
|
||||
/// Class with methods to help finding the correct overload for a member.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This class does member lookup as specified by the C# spec (ECMA-334, § 14.3).
|
||||
/// Other languages might need custom lookup methods.
|
||||
/// </remarks>
|
||||
public static class MemberLookupHelper |
||||
{ |
||||
#region LookupMember / GetAccessibleMembers
|
||||
public static List<IMember> GetAllMembers(IReturnType rt) |
||||
{ |
||||
List<IMember> members = new List<IMember>(); |
||||
if (rt != null) { |
||||
rt.GetMethods().ForEach(members.Add); |
||||
rt.GetProperties().ForEach(members.Add); |
||||
rt.GetFields().ForEach(members.Add); |
||||
rt.GetEvents().ForEach(members.Add); |
||||
} |
||||
return members; |
||||
} |
||||
|
||||
public static List<IList<IMember>> LookupMember( |
||||
IReturnType type, string name, IClass callingClass, |
||||
LanguageProperties language, bool isInvocation, bool? isAccessThoughReferenceOfCurrentClass) |
||||
{ |
||||
if (language == null) |
||||
throw new ArgumentNullException("language"); |
||||
|
||||
if (isAccessThoughReferenceOfCurrentClass == null) { |
||||
isAccessThoughReferenceOfCurrentClass = false; |
||||
IClass underlyingClass = type.GetUnderlyingClass(); |
||||
if (underlyingClass != null) |
||||
isAccessThoughReferenceOfCurrentClass = underlyingClass.IsTypeInInheritanceTree(callingClass); |
||||
} |
||||
|
||||
IEnumerable<IMember> members; |
||||
if (language == LanguageProperties.VBNet && language.NameComparer.Equals(name, "New")) { |
||||
members = GetAllMembers(type).OfType<IMethod>().Where(m => m.IsConstructor).Select(m=>(IMember)m); |
||||
} else { |
||||
members = GetAllMembers(type).Where(m => language.NameComparer.Equals(m.Name, name)); |
||||
} |
||||
|
||||
return LookupMember(members, callingClass, (bool)isAccessThoughReferenceOfCurrentClass, isInvocation); |
||||
} |
||||
|
||||
sealed class InheritanceLevelComparer : IComparer<IClass> |
||||
{ |
||||
public readonly static InheritanceLevelComparer Instance = new InheritanceLevelComparer(); |
||||
|
||||
public int Compare(IClass x, IClass y) |
||||
{ |
||||
if (x == y) |
||||
return 0; |
||||
if (x.IsTypeInInheritanceTree(y)) |
||||
return 1; |
||||
else |
||||
return -1; |
||||
} |
||||
} |
||||
|
||||
public static List<IList<IMember>> LookupMember( |
||||
IEnumerable<IMember> possibleMembers, IClass callingClass, |
||||
bool isAccessThoughReferenceOfCurrentClass, bool isInvocation) |
||||
{ |
||||
// Console.WriteLine("Possible members:");
|
||||
// foreach (IMember m in possibleMembers) {
|
||||
// Console.WriteLine(" " + m.DotNetName);
|
||||
// }
|
||||
|
||||
IEnumerable<IMember> accessibleMembers = possibleMembers.Where(member => member.IsAccessible(callingClass, isAccessThoughReferenceOfCurrentClass)); |
||||
if (isInvocation) { |
||||
accessibleMembers = accessibleMembers.Where(IsInvocable); |
||||
} |
||||
|
||||
// base most member => most derived member
|
||||
//Dictionary<IMember, IMember> overrideDict = new Dictionary<IMember, IMember>();
|
||||
|
||||
ParameterListComparer parameterListComparer = new ParameterListComparer(); |
||||
HashSet<IMethod> handledMethods = new HashSet<IMethod>(parameterListComparer); |
||||
Dictionary<IMethod, IMethod> overrideMethodDict = new Dictionary<IMethod, IMethod>(parameterListComparer); |
||||
IMember nonMethodOverride = null; |
||||
|
||||
List<IList<IMember>> allResults = new List<IList<IMember>>(); |
||||
List<IMember> results = new List<IMember>(); |
||||
|
||||
foreach (var group in accessibleMembers |
||||
.GroupBy(m => m.DeclaringType.GetCompoundClass()) |
||||
.OrderByDescending(g => g.Key, InheritanceLevelComparer.Instance)) |
||||
{ |
||||
//Console.WriteLine("Member group " + group.Key);
|
||||
foreach (IMember m in group) { |
||||
//Console.WriteLine(" " + m.DotNetName);
|
||||
if (m.IsOverride) { |
||||
IMethod method = m as IMethod; |
||||
if (method != null) { |
||||
if (!overrideMethodDict.ContainsKey(method)) |
||||
overrideMethodDict[method] = method; |
||||
} else { |
||||
if (nonMethodOverride == null) |
||||
nonMethodOverride = m; |
||||
} |
||||
} else { |
||||
IMethod method = m as IMethod; |
||||
if (method != null) { |
||||
if (handledMethods.Add(method)) { |
||||
IMethod mostOverriddenMethod; |
||||
if (overrideMethodDict.TryGetValue(method, out mostOverriddenMethod)) |
||||
results.Add(mostOverriddenMethod); |
||||
else { |
||||
results.Add(method); |
||||
} |
||||
} |
||||
} else { |
||||
// non-methods are only available if they aren't hidden by something else
|
||||
if (allResults.Count == 0) { |
||||
results.Add(nonMethodOverride ?? m); |
||||
} |
||||
} |
||||
} |
||||
} |
||||
if (results.Count > 0) { |
||||
allResults.Add(results); |
||||
results = new List<IMember>(); |
||||
} |
||||
} |
||||
// Sometimes there might be 'override's without corresponding 'virtual's.
|
||||
// Ensure those get found, too.
|
||||
if (nonMethodOverride != null && allResults.Count == 0) { |
||||
results.Add(nonMethodOverride); |
||||
} |
||||
foreach (IMethod method in overrideMethodDict.Values) { |
||||
if (handledMethods.Add(method)) { |
||||
results.Add(method); |
||||
} |
||||
} |
||||
if (results.Count > 0) { |
||||
allResults.Add(results); |
||||
} |
||||
return allResults; |
||||
} |
||||
|
||||
static bool IsInvocable(IMember member) |
||||
{ |
||||
if (member == null) |
||||
throw new ArgumentNullException("member"); |
||||
if (member is IMethod || member is IEvent) |
||||
return true; |
||||
IProperty p = member as IProperty; |
||||
if (p != null && p.Parameters.Count > 0) |
||||
return true; |
||||
IReturnType returnType = member.ReturnType; |
||||
if (returnType == null) |
||||
return false; |
||||
IClass c = returnType.GetUnderlyingClass(); |
||||
return c != null && c.ClassType == ClassType.Delegate; |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Gets all accessible members, including indexers and constructors.
|
||||
/// </summary>
|
||||
public static List<IMember> GetAccessibleMembers(IReturnType rt, IClass callingClass, LanguageProperties language) |
||||
{ |
||||
bool isAccessThoughReferenceOfCurrentClass = false; |
||||
IClass underlyingClass = rt.GetUnderlyingClass(); |
||||
if (underlyingClass != null) |
||||
isAccessThoughReferenceOfCurrentClass = underlyingClass.IsTypeInInheritanceTree(callingClass); |
||||
return GetAccessibleMembers(rt, callingClass, language, isAccessThoughReferenceOfCurrentClass); |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Gets all accessible members, including indexers and constructors.
|
||||
/// </summary>
|
||||
public static List<IMember> GetAccessibleMembers(IReturnType rt, IClass callingClass, LanguageProperties language, bool isAccessThoughReferenceOfCurrentClass) |
||||
{ |
||||
if (language == null) |
||||
throw new ArgumentNullException("language"); |
||||
|
||||
List<IMember> result = new List<IMember>(); |
||||
foreach (var g in GetAllMembers(rt).GroupBy(m => m.Name, language.NameComparer).OrderBy(g2=>g2.Key)) { |
||||
foreach (var group in LookupMember(g, callingClass, isAccessThoughReferenceOfCurrentClass, false)) { |
||||
result.AddRange(group); |
||||
} |
||||
} |
||||
return result; |
||||
} |
||||
#endregion
|
||||
|
||||
#region FindOverload
|
||||
/// <summary>
|
||||
/// Finds the correct overload according to the C# specification.
|
||||
/// </summary>
|
||||
/// <param name="methods">List with the methods to check.</param>
|
||||
/// <param name="arguments">The types of the arguments passed to the method.</param>
|
||||
/// <param name="resultIsAcceptable">Out parameter. Will be true if the resulting method
|
||||
/// is an acceptable match, false if the resulting method is just a guess and will lead
|
||||
/// to a compile error.</param>
|
||||
/// <returns>The method that will be called.</returns>
|
||||
public static IMethod FindOverload(IList<IMethod> methods, IReturnType[] arguments, out bool resultIsAcceptable) |
||||
{ |
||||
if (methods == null) |
||||
throw new ArgumentNullException("methods"); |
||||
resultIsAcceptable = false; |
||||
if (methods.Count == 0) |
||||
return null; |
||||
return (IMethod)CSharp.OverloadResolution.FindOverload( |
||||
methods, |
||||
arguments, |
||||
false, |
||||
true, |
||||
out resultIsAcceptable); |
||||
} |
||||
|
||||
public static IProperty FindOverload(IList<IProperty> properties, IReturnType[] arguments) |
||||
{ |
||||
if (properties.Count == 0) |
||||
return null; |
||||
bool acceptableMatch; |
||||
return (IProperty)CSharp.OverloadResolution.FindOverload( |
||||
properties, |
||||
arguments, |
||||
false, |
||||
false, |
||||
out acceptableMatch); |
||||
} |
||||
#endregion
|
||||
|
||||
#region Type Argument Inference
|
||||
/// <summary>
|
||||
/// Infers type arguments specified by passing expectedArgument as parameter where passedArgument
|
||||
/// was expected. The resulting type arguments are written to outputArray.
|
||||
/// Returns false when expectedArgument and passedArgument are incompatible, otherwise true
|
||||
/// is returned (true is used both for successful inferring and other kind of errors).
|
||||
///
|
||||
/// Warning: This method for single-argument type inference doesn't support lambdas!
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// The C# spec (§ 25.6.4) has a bug: it says that type inference works if the passedArgument is IEnumerable{T}
|
||||
/// and the expectedArgument is an array; passedArgument and expectedArgument must be swapped here.
|
||||
/// </remarks>
|
||||
public static bool InferTypeArgument(IReturnType expectedArgument, IReturnType passedArgument, IReturnType[] outputArray) |
||||
{ |
||||
if (expectedArgument == null) return true; |
||||
if (passedArgument == null || passedArgument == NullReturnType.Instance) return true; |
||||
|
||||
if (passedArgument.IsArrayReturnType) { |
||||
IReturnType passedArrayElementType = passedArgument.CastToArrayReturnType().ArrayElementType; |
||||
if (expectedArgument.IsArrayReturnType && expectedArgument.CastToArrayReturnType().ArrayDimensions == passedArgument.CastToArrayReturnType().ArrayDimensions) { |
||||
return InferTypeArgument(expectedArgument.CastToArrayReturnType().ArrayElementType, passedArrayElementType, outputArray); |
||||
} else if (expectedArgument.IsConstructedReturnType) { |
||||
switch (expectedArgument.FullyQualifiedName) { |
||||
case "System.Collections.Generic.IList": |
||||
case "System.Collections.Generic.ICollection": |
||||
case "System.Collections.Generic.IEnumerable": |
||||
return InferTypeArgument(expectedArgument.CastToConstructedReturnType().TypeArguments[0], passedArrayElementType, outputArray); |
||||
} |
||||
} |
||||
// If P is an array type, and A is not an array type of the same rank,
|
||||
// or an instantiation of IList<>, ICollection<>, or IEnumerable<>, then
|
||||
// type inference fails for the generic method.
|
||||
return false; |
||||
} |
||||
if (expectedArgument.IsGenericReturnType) { |
||||
GenericReturnType methodTP = expectedArgument.CastToGenericReturnType(); |
||||
if (methodTP.TypeParameter.Method != null) { |
||||
if (methodTP.TypeParameter.Index < outputArray.Length) { |
||||
outputArray[methodTP.TypeParameter.Index] = passedArgument; |
||||
} |
||||
return true; |
||||
} |
||||
} |
||||
if (expectedArgument.IsConstructedReturnType) { |
||||
// The spec for this case is quite complex.
|
||||
// For our purposes, we can simplify enourmously:
|
||||
if (!passedArgument.IsConstructedReturnType) return false; |
||||
|
||||
IList<IReturnType> expectedTA = expectedArgument.CastToConstructedReturnType().TypeArguments; |
||||
IList<IReturnType> passedTA = passedArgument.CastToConstructedReturnType().TypeArguments; |
||||
|
||||
int count = Math.Min(expectedTA.Count, passedTA.Count); |
||||
for (int i = 0; i < count; i++) { |
||||
InferTypeArgument(expectedTA[i], passedTA[i], outputArray); |
||||
} |
||||
} |
||||
return true; |
||||
} |
||||
#endregion
|
||||
|
||||
#region IsApplicable
|
||||
public static bool IsApplicable(IReturnType argument, IParameter expected, IMethod targetMethod) |
||||
{ |
||||
bool parameterIsRefOrOut = expected.IsRef || expected.IsOut; |
||||
bool argumentIsRefOrOut = argument != null && argument.IsDecoratingReturnType<ReferenceReturnType>(); |
||||
if (parameterIsRefOrOut != argumentIsRefOrOut) |
||||
return false; |
||||
if (parameterIsRefOrOut) { |
||||
return object.Equals(argument, expected.ReturnType); |
||||
} else { |
||||
return IsApplicable(argument, expected.ReturnType, targetMethod); |
||||
} |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Tests whether an argument of type "argument" is valid for a parameter of type "expected" for a call
|
||||
/// to "targetMethod".
|
||||
/// targetMethod may be null, it is only used when it is a generic method and expected is (or contains) one of
|
||||
/// its type parameters.
|
||||
/// </summary>
|
||||
public static bool IsApplicable(IReturnType argument, IReturnType expected, IMethod targetMethod) |
||||
{ |
||||
return ConversionExistsInternal(argument, expected, targetMethod); |
||||
} |
||||
#endregion
|
||||
|
||||
#region Conversion exists
|
||||
/// <summary>
|
||||
/// Checks if an implicit conversion exists from <paramref name="from"/> to <paramref name="to"/>.
|
||||
/// </summary>
|
||||
public static bool ConversionExists(IReturnType from, IReturnType to) |
||||
{ |
||||
return ConversionExistsInternal(from, to, null); |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Tests if an implicit conversion exists from "from" to "to".
|
||||
/// Conversions from concrete types to generic types are only allowed when the generic type belongs to the
|
||||
/// method "allowGenericTargetsOnThisMethod".
|
||||
/// </summary>
|
||||
static bool ConversionExistsInternal(IReturnType from, IReturnType to, IMethod allowGenericTargetsOnThisMethod) |
||||
{ |
||||
// ECMA-334, § 13.1 Implicit conversions
|
||||
|
||||
// Identity conversion:
|
||||
if (from == to) return true; |
||||
if (from == null || to == null) return false; |
||||
if (from.Equals(to)) { |
||||
return true; |
||||
} |
||||
|
||||
bool fromIsDefault = from.IsDefaultReturnType; |
||||
bool toIsDefault = to.IsDefaultReturnType; |
||||
|
||||
if (fromIsDefault && toIsDefault) { |
||||
// Implicit numeric conversions:
|
||||
int f = GetPrimitiveType(from); |
||||
int t = GetPrimitiveType(to); |
||||
if (f == SByte && (t == Short || t == Int || t == Long || t == Float || t == Double || t == Decimal)) |
||||
return true; |
||||
if (f == Byte && (t == Short || t == UShort || t == Int || t == UInt || t == Long || t == ULong || t == Float || t == Double || t == Decimal)) |
||||
return true; |
||||
if (f == Short && (t == Int || t == Long || t == Float || t == Double || t == Decimal)) |
||||
return true; |
||||
if (f == UShort && (t == Int || t == UInt || t == Long || t == ULong || t == Float || t == Double || t == Decimal)) |
||||
return true; |
||||
if (f == Int && (t == Long || t == Float || t == Double || t == Decimal)) |
||||
return true; |
||||
if (f == UInt && (t == Long || t == ULong || t == Float || t == Double || t == Decimal)) |
||||
return true; |
||||
if ((f == Long || f == ULong) && (t == Float || t == Double || t == Decimal)) |
||||
return true; |
||||
if (f == Char && (t == UShort || t == Int || t == UInt || t == Long || t == ULong || t == Float || t == Double || t == Decimal)) |
||||
return true; |
||||
if (f == Float && t == Double) |
||||
return true; |
||||
} |
||||
// Implicit reference conversions:
|
||||
|
||||
if (toIsDefault && to.FullyQualifiedName == "System.Object") { |
||||
return true; // from any type to object
|
||||
} |
||||
if (from == NullReturnType.Instance) { |
||||
IClass toClass = to.GetUnderlyingClass(); |
||||
if (toClass != null) { |
||||
switch (toClass.ClassType) { |
||||
case ClassType.Class: |
||||
case ClassType.Delegate: |
||||
case ClassType.Interface: |
||||
return true; |
||||
case ClassType.Struct: |
||||
return toClass.FullyQualifiedName == "System.Nullable"; |
||||
} |
||||
} |
||||
return false; |
||||
} |
||||
|
||||
if ((toIsDefault || to.IsConstructedReturnType || to.IsGenericReturnType) |
||||
&& (fromIsDefault || from.IsArrayReturnType || from.IsConstructedReturnType)) |
||||
{ |
||||
foreach (IReturnType baseTypeOfFrom in GetTypeInheritanceTree(from)) { |
||||
if (IsConstructedConversionToGenericReturnType(baseTypeOfFrom, to, allowGenericTargetsOnThisMethod)) |
||||
return true; |
||||
} |
||||
} |
||||
|
||||
if (from.IsArrayReturnType && to.IsArrayReturnType) { |
||||
ArrayReturnType fromArt = from.CastToArrayReturnType(); |
||||
ArrayReturnType toArt = to.CastToArrayReturnType(); |
||||
// from array to other array type
|
||||
if (fromArt.ArrayDimensions == toArt.ArrayDimensions) { |
||||
return ConversionExistsInternal(fromArt.ArrayElementType, toArt.ArrayElementType, allowGenericTargetsOnThisMethod); |
||||
} |
||||
} |
||||
|
||||
if (from.IsDecoratingReturnType<AnonymousMethodReturnType>() && (toIsDefault || to.IsConstructedReturnType)) { |
||||
AnonymousMethodReturnType amrt = from.CastToDecoratingReturnType<AnonymousMethodReturnType>(); |
||||
IMethod method = CSharp.TypeInference.GetDelegateOrExpressionTreeSignature(to, amrt.CanBeConvertedToExpressionTree); |
||||
if (method != null) { |
||||
if (amrt.HasParameterList) { |
||||
if (amrt.MethodParameters.Count != method.Parameters.Count) |
||||
return false; |
||||
for (int i = 0; i < amrt.MethodParameters.Count; i++) { |
||||
if (amrt.MethodParameters[i].ReturnType != null) { |
||||
if (!object.Equals(amrt.MethodParameters[i].ReturnType, |
||||
method.Parameters[i].ReturnType)) |
||||
{ |
||||
return false; |
||||
} |
||||
} |
||||
} |
||||
} |
||||
IReturnType rt = amrt.ResolveReturnType(method.Parameters.Select(p => p.ReturnType).ToArray()); |
||||
return ConversionExistsInternal(rt, method.ReturnType, allowGenericTargetsOnThisMethod); |
||||
} |
||||
} |
||||
|
||||
return false; |
||||
} |
||||
|
||||
static bool IsConstructedConversionToGenericReturnType(IReturnType from, IReturnType to, IMethod allowGenericTargetsOnThisMethod) |
||||
{ |
||||
// null could be passed when type arguments could not be resolved/inferred
|
||||
if (from == to) // both are null or
|
||||
return true; |
||||
if (from == null || to == null) |
||||
return false; |
||||
|
||||
if (from.Equals(to)) |
||||
return true; |
||||
|
||||
if (allowGenericTargetsOnThisMethod == null) |
||||
return false; |
||||
|
||||
if (to.IsGenericReturnType) { |
||||
ITypeParameter typeParameter = to.CastToGenericReturnType().TypeParameter; |
||||
if (typeParameter.Method == allowGenericTargetsOnThisMethod) |
||||
return true; |
||||
// applicability ignores constraints
|
||||
// foreach (IReturnType constraintType in typeParameter.Constraints) {
|
||||
// if (!ConversionExistsInternal(from, constraintType, allowGenericTargetsOnThisMethod)) {
|
||||
// return false;
|
||||
// }
|
||||
// }
|
||||
return false; |
||||
} |
||||
|
||||
// for conversions like from IEnumerable<string> to IEnumerable<T>, where T is a GenericReturnType
|
||||
ConstructedReturnType cFrom = from.CastToConstructedReturnType(); |
||||
ConstructedReturnType cTo = to.CastToConstructedReturnType(); |
||||
if (cFrom != null && cTo != null) { |
||||
if (cFrom.FullyQualifiedName == cTo.FullyQualifiedName && cFrom.TypeArguments.Count == cTo.TypeArguments.Count) { |
||||
for (int i = 0; i < cFrom.TypeArguments.Count; i++) { |
||||
if (!IsConstructedConversionToGenericReturnType(cFrom.TypeArguments[i], cTo.TypeArguments[i], allowGenericTargetsOnThisMethod)) |
||||
return false; |
||||
} |
||||
return true; |
||||
} |
||||
} |
||||
return false; |
||||
} |
||||
#endregion
|
||||
|
||||
#region Better conversion
|
||||
/// <summary>
|
||||
/// Gets if the conversion from <paramref name="from"/> to <paramref name="to1"/> is better than
|
||||
/// the conversion from <paramref name="from"/> to <paramref name="to2"/>.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// 0 = neither conversion is better<br/>
|
||||
/// 1 = from -> to1 is the better conversion<br/>
|
||||
/// 2 = from -> to2 is the better conversion.
|
||||
/// </returns>
|
||||
public static int GetBetterConversion(IReturnType from, IReturnType to1, IReturnType to2) |
||||
{ |
||||
if (from == null) return 0; |
||||
if (to1 == null) return 2; |
||||
if (to2 == null) return 1; |
||||
|
||||
// See ECMA-334, § 14.4.2.3
|
||||
|
||||
// If T1 and T2 are the same type, neither conversion is better.
|
||||
if (to1.Equals(to2)) { |
||||
return 0; |
||||
} |
||||
// If S is T1, C1 is the better conversion.
|
||||
if (from.Equals(to1)) { |
||||
return 1; |
||||
} |
||||
// If S is T2, C2 is the better conversion.
|
||||
if (from.Equals(to2)) { |
||||
return 2; |
||||
} |
||||
bool canConvertFrom1To2 = ConversionExists(to1, to2); |
||||
bool canConvertFrom2To1 = ConversionExists(to2, to1); |
||||
// If an implicit conversion from T1 to T2 exists, and no implicit conversion
|
||||
// from T2 to T1 exists, C1 is the better conversion.
|
||||
if (canConvertFrom1To2 && !canConvertFrom2To1) { |
||||
return 1; |
||||
} |
||||
// If an implicit conversion from T2 to T1 exists, and no implicit conversion
|
||||
// from T1 to T2 exists, C2 is the better conversion.
|
||||
if (canConvertFrom2To1 && !canConvertFrom1To2) { |
||||
return 2; |
||||
} |
||||
if (to1.IsDefaultReturnType && to2.IsDefaultReturnType) { |
||||
return GetBetterPrimitiveConversion(to1, to2); |
||||
} |
||||
// Otherwise, neither conversion is better.
|
||||
return 0; |
||||
} |
||||
|
||||
const int Byte = 1; |
||||
const int Short = 2; |
||||
const int Int = 3; |
||||
const int Long = 4; |
||||
const int SByte = 5; |
||||
const int UShort = 6; |
||||
const int UInt = 7; |
||||
const int ULong = 8; |
||||
const int Float = 9; |
||||
const int Double = 10; |
||||
const int Char = 11; |
||||
const int Decimal= 12; |
||||
|
||||
static int GetBetterPrimitiveConversion(IReturnType to1, IReturnType to2) |
||||
{ |
||||
int t1 = GetPrimitiveType(to1); |
||||
int t2 = GetPrimitiveType(to2); |
||||
if (t1 == 0 || t2 == 0) return 0; // not primitive
|
||||
if (t1 == SByte && (t2 == Byte || t2 == UShort || t2 == UInt || t2 == ULong)) |
||||
return 1; |
||||
if (t2 == SByte && (t1 == Byte || t1 == UShort || t1 == UInt || t1 == ULong)) |
||||
return 2; |
||||
if (t1 == Short && (t2 == UShort || t2 == UInt || t2 == ULong)) |
||||
return 1; |
||||
if (t2 == Short && (t1 == UShort || t1 == UInt || t1 == ULong)) |
||||
return 2; |
||||
if (t1 == Int && (t2 == UInt || t2 == ULong)) |
||||
return 1; |
||||
if (t2 == Int && (t1 == UInt || t1 == ULong)) |
||||
return 2; |
||||
if (t1 == Long && t2 == ULong) |
||||
return 1; |
||||
if (t2 == Long && t1 == ULong) |
||||
return 2; |
||||
return 0; |
||||
} |
||||
|
||||
static int GetPrimitiveType(IReturnType t) |
||||
{ |
||||
switch (t.FullyQualifiedName) { |
||||
case "System.SByte": return SByte; |
||||
case "System.Byte": return Byte; |
||||
case "System.Int16": return Short; |
||||
case "System.UInt16": return UShort; |
||||
case "System.Int32": return Int; |
||||
case "System.UInt32": return UInt; |
||||
case "System.Int64": return Long; |
||||
case "System.UInt64": return ULong; |
||||
case "System.Single": return Float; |
||||
case "System.Double": return Double; |
||||
case "System.Char": return Char; |
||||
case "System.Decimal": return Decimal; |
||||
default: return 0; |
||||
} |
||||
} |
||||
#endregion
|
||||
|
||||
#region GetCommonType
|
||||
/// <summary>
|
||||
/// Gets the common base type of a and b.
|
||||
/// </summary>
|
||||
public static IReturnType GetCommonType(IProjectContent projectContent, IReturnType a, IReturnType b) |
||||
{ |
||||
if (projectContent == null) |
||||
throw new ArgumentNullException("projectContent"); |
||||
if (a == null) return b; |
||||
if (b == null) return a; |
||||
if (ConversionExists(a, b)) |
||||
return b; |
||||
//if (ConversionExists(b, a)) - not required because the first baseTypeOfA is a
|
||||
// return a;
|
||||
foreach (IReturnType baseTypeOfA in GetTypeInheritanceTree(a)) { |
||||
if (ConversionExists(b, baseTypeOfA)) |
||||
return baseTypeOfA; |
||||
} |
||||
return projectContent.SystemTypes.Object; |
||||
} |
||||
#endregion
|
||||
|
||||
#region GetTypeParameterPassedToBaseClass / GetTypeInheritanceTree
|
||||
/// <summary>
|
||||
/// Gets the type parameter that was passed to a certain base class.
|
||||
/// For example, when <paramref name="returnType"/> is Dictionary(of string, int)
|
||||
/// this method will return KeyValuePair(of string, int)
|
||||
/// </summary>
|
||||
public static IReturnType GetTypeParameterPassedToBaseClass(IReturnType parentType, IClass baseClass, int baseClassTypeParameterIndex) |
||||
{ |
||||
foreach (IReturnType rt in GetTypeInheritanceTree(parentType)) { |
||||
ConstructedReturnType crt = rt.CastToConstructedReturnType(); |
||||
if (crt != null && baseClass.CompareTo(rt.GetUnderlyingClass()) == 0) { |
||||
if (baseClassTypeParameterIndex < crt.TypeArguments.Count) { |
||||
return crt.TypeArguments[baseClassTypeParameterIndex]; |
||||
} |
||||
} |
||||
} |
||||
return null; |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Translates typeToTranslate using the type arguments from parentType;
|
||||
/// </summary>
|
||||
static IReturnType TranslateIfRequired(IReturnType parentType, IReturnType typeToTranslate) |
||||
{ |
||||
if (typeToTranslate == null) |
||||
return null; |
||||
ConstructedReturnType parentConstructedType = parentType.CastToConstructedReturnType(); |
||||
if (parentConstructedType != null) { |
||||
return ConstructedReturnType.TranslateType(typeToTranslate, parentConstructedType.TypeArguments, false); |
||||
} else { |
||||
return typeToTranslate; |
||||
} |
||||
} |
||||
|
||||
readonly static Dictionary<IReturnType, IEnumerable<IReturnType>> getTypeInheritanceTreeCache = new Dictionary<IReturnType, IEnumerable<IReturnType>>(); |
||||
|
||||
static void ClearGetTypeInheritanceTreeCache() |
||||
{ |
||||
lock (getTypeInheritanceTreeCache) { |
||||
getTypeInheritanceTreeCache.Clear(); |
||||
} |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Gets all types the specified type inherits from (all classes and interfaces).
|
||||
/// Unlike the class inheritance tree, this method takes care of type arguments and calculates the type
|
||||
/// arguments that are passed to base classes.
|
||||
/// </summary>
|
||||
public static IEnumerable<IReturnType> GetTypeInheritanceTree(IReturnType typeToListInheritanceTreeFor) |
||||
{ |
||||
if (typeToListInheritanceTreeFor == null) |
||||
throw new ArgumentNullException("typeToListInheritanceTreeFor"); |
||||
|
||||
lock (getTypeInheritanceTreeCache) { |
||||
IEnumerable<IReturnType> result; |
||||
if (getTypeInheritanceTreeCache.TryGetValue(typeToListInheritanceTreeFor, out result)) |
||||
return result; |
||||
} |
||||
|
||||
IClass classToListInheritanceTreeFor = typeToListInheritanceTreeFor.GetUnderlyingClass(); |
||||
if (classToListInheritanceTreeFor == null) |
||||
return new IReturnType[] { typeToListInheritanceTreeFor }; |
||||
|
||||
if (typeToListInheritanceTreeFor.IsArrayReturnType) { |
||||
IReturnType elementType = typeToListInheritanceTreeFor.CastToArrayReturnType().ArrayElementType; |
||||
List<IReturnType> resultList = new List<IReturnType>(); |
||||
resultList.Add(typeToListInheritanceTreeFor); |
||||
resultList.AddRange(GetTypeInheritanceTree( |
||||
new ConstructedReturnType( |
||||
classToListInheritanceTreeFor.ProjectContent.GetClass("System.Collections.Generic.IList", 1).DefaultReturnType, |
||||
new IReturnType[] { elementType } |
||||
) |
||||
)); |
||||
resultList.Add(classToListInheritanceTreeFor.ProjectContent.GetClass("System.Collections.IList", 0).DefaultReturnType); |
||||
resultList.Add(classToListInheritanceTreeFor.ProjectContent.GetClass("System.Collections.ICollection", 0).DefaultReturnType); |
||||
// non-generic IEnumerable is already added by generic IEnumerable
|
||||
return resultList; |
||||
} |
||||
|
||||
HashSet<IReturnType> visitedSet = new HashSet<IReturnType>(); |
||||
List<IReturnType> visitedList = new List<IReturnType>(); |
||||
Queue<IReturnType> typesToVisit = new Queue<IReturnType>(); |
||||
bool enqueuedLastBaseType = false; |
||||
|
||||
IReturnType currentType = typeToListInheritanceTreeFor; |
||||
IClass currentClass = classToListInheritanceTreeFor; |
||||
IReturnType nextType; |
||||
do { |
||||
if (currentClass != null) { |
||||
if (visitedSet.Add(currentType)) { |
||||
visitedList.Add(currentType); |
||||
foreach (IReturnType type in currentClass.BaseTypes) { |
||||
typesToVisit.Enqueue(TranslateIfRequired(currentType, type)); |
||||
} |
||||
} |
||||
} |
||||
if (typesToVisit.Count > 0) { |
||||
nextType = typesToVisit.Dequeue(); |
||||
} else { |
||||
nextType = enqueuedLastBaseType ? null : DefaultClass.GetBaseTypeByClassType(classToListInheritanceTreeFor); |
||||
enqueuedLastBaseType = true; |
||||
} |
||||
if (nextType != null) { |
||||
currentType = nextType; |
||||
currentClass = nextType.GetUnderlyingClass(); |
||||
} |
||||
} while (nextType != null); |
||||
lock (getTypeInheritanceTreeCache) { |
||||
if (getTypeInheritanceTreeCache.Count == 0) { |
||||
DomCache.RegisterForClear(ClearGetTypeInheritanceTreeCache); |
||||
} |
||||
getTypeInheritanceTreeCache[typeToListInheritanceTreeFor] = visitedList; |
||||
} |
||||
return visitedList; |
||||
} |
||||
#endregion
|
||||
|
||||
#region IsSimilarMember / FindBaseMember
|
||||
/// <summary>
|
||||
/// Gets if member1 is the same as member2 or if member1 overrides member2.
|
||||
/// </summary>
|
||||
public static bool IsSimilarMember(IMember member1, IMember member2) |
||||
{ |
||||
member1 = GetGenericMember(member1); |
||||
member2 = GetGenericMember(member2); |
||||
do { |
||||
if (IsSimilarMemberInternal(member1, member2)) |
||||
return true; |
||||
} while ((member1 = FindBaseMember(member1)) != null); |
||||
return false; |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Gets the generic member from a specialized member.
|
||||
/// Specialized members are the result of overload resolution with type substitution.
|
||||
/// </summary>
|
||||
static IMember GetGenericMember(IMember member) |
||||
{ |
||||
// e.g. member = string[] ToArray<string>(IEnumerable<string> input)
|
||||
// result = T[] ToArray<T>(IEnumerable<T> input)
|
||||
if (member != null) { |
||||
while (member.GenericMember != null) |
||||
member = member.GenericMember; |
||||
} |
||||
return member; |
||||
} |
||||
|
||||
static bool IsSimilarMemberInternal(IMember member1, IMember member2) |
||||
{ |
||||
if (member1 == member2) |
||||
return true; |
||||
if (member1 == null || member2 == null) |
||||
return false; |
||||
if (member1.FullyQualifiedName != member2.FullyQualifiedName) |
||||
return false; |
||||
if (member1.IsStatic != member2.IsStatic) |
||||
return false; |
||||
IMethodOrProperty m1 = member1 as IMethodOrProperty; |
||||
IMethodOrProperty m2 = member2 as IMethodOrProperty; |
||||
if (m1 != null || m2 != null) { |
||||
if (m1 != null && m2 != null) { |
||||
if (DiffUtility.Compare(m1.Parameters, m2.Parameters) != 0) |
||||
return false; |
||||
if (m1 is IMethod && m2 is IMethod) { |
||||
if ((m1 as IMethod).TypeParameters.Count != (m2 as IMethod).TypeParameters.Count) |
||||
return false; |
||||
} |
||||
} else { |
||||
return false; |
||||
} |
||||
} |
||||
IField f1 = member1 as IField; |
||||
IField f2 = member2 as IField; |
||||
if (f1 != null || f2 != null) { |
||||
if (f1 != null && f2 != null) { |
||||
if (f1.IsLocalVariable != f2.IsLocalVariable || f1.IsParameter != f2.IsParameter) |
||||
return false; |
||||
} else { |
||||
return false; |
||||
} |
||||
} |
||||
return true; |
||||
} |
||||
|
||||
public static IMember FindSimilarMember(IClass type, IMember member) |
||||
{ |
||||
if (type == null) |
||||
throw new ArgumentNullException("type"); |
||||
StringComparer nameComparer = member.DeclaringType.ProjectContent.Language.NameComparer; |
||||
member = GetGenericMember(member); |
||||
if (member is IMethod) { |
||||
IMethod parentMethod = (IMethod)member; |
||||
foreach (IMethod m in type.Methods) { |
||||
if (nameComparer.Equals(parentMethod.Name, m.Name)) { |
||||
if (m.IsStatic == parentMethod.IsStatic) { |
||||
if (DiffUtility.Compare(parentMethod.Parameters, m.Parameters) == 0) { |
||||
return m; |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} else if (member is IProperty) { |
||||
IProperty parentMethod = (IProperty)member; |
||||
foreach (IProperty m in type.Properties) { |
||||
if (nameComparer.Equals(parentMethod.Name, m.Name)) { |
||||
if (m.IsStatic == parentMethod.IsStatic) { |
||||
if (DiffUtility.Compare(parentMethod.Parameters, m.Parameters) == 0) { |
||||
return m; |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
return null; |
||||
} |
||||
|
||||
public static IMember FindBaseMember(IMember member) |
||||
{ |
||||
if (member == null) return null; |
||||
if (member is IMethod && (member as IMethod).IsConstructor) return null; |
||||
IClass parentClass = member.DeclaringType; |
||||
IClass baseClass = parentClass.BaseClass; |
||||
if (baseClass == null) return null; |
||||
|
||||
foreach (IClass childClass in baseClass.ClassInheritanceTree) { |
||||
IMember m = FindSimilarMember(childClass, member); |
||||
if (m != null) |
||||
return m; |
||||
} |
||||
return null; |
||||
} |
||||
#endregion
|
||||
|
||||
[System.Diagnostics.ConditionalAttribute("DEBUG")] |
||||
internal static void Log(string text) |
||||
{ |
||||
Debug.WriteLine(text); |
||||
} |
||||
|
||||
[System.Diagnostics.ConditionalAttribute("DEBUG")] |
||||
internal static void Log(string text, IEnumerable<IReturnType> types) |
||||
{ |
||||
Log(text, types.Select(t => t != null ? t.DotNetName : "<null>")); |
||||
} |
||||
|
||||
[System.Diagnostics.ConditionalAttribute("DEBUG")] |
||||
internal static void Log<T>(string text, IEnumerable<T> lines) |
||||
{ |
||||
#if DEBUG
|
||||
T[] arr = lines.ToArray(); |
||||
if (arr.Length == 0) { |
||||
Log(text + "<empty collection>"); |
||||
} else { |
||||
Log(text + arr[0]); |
||||
for (int i = 1; i < arr.Length; i++) { |
||||
Log(new string(' ', text.Length) + arr[i]); |
||||
} |
||||
} |
||||
#endif
|
||||
} |
||||
} |
||||
} |
||||
@ -0,0 +1,546 @@
@@ -0,0 +1,546 @@
|
||||
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
|
||||
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
|
||||
|
||||
using System; |
||||
using System.Linq; |
||||
using System.Collections.Generic; |
||||
using ICSharpCode.NRefactory; |
||||
using ICSharpCode.NRefactory.Ast; |
||||
using ICSharpCode.NRefactory.AstBuilder; |
||||
using ICSharpCode.NRefactory.Visitors; |
||||
using System.Runtime.InteropServices; |
||||
|
||||
namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver |
||||
{ |
||||
/// <summary>
|
||||
/// This class converts C# constructs to their VB.NET equivalents.
|
||||
/// </summary>
|
||||
public class CSharpToVBNetConvertVisitor : CSharpConstructsConvertVisitor |
||||
{ |
||||
NRefactoryResolver resolver; |
||||
ParseInformation parseInformation; |
||||
IProjectContent projectContent; |
||||
public string RootNamespaceToRemove { get; set; } |
||||
public string StartupObjectToMakePublic { get; set; } |
||||
public IList<string> DefaultImportsToRemove { get; set; } |
||||
|
||||
public CSharpToVBNetConvertVisitor(IProjectContent pc, ParseInformation parseInfo) |
||||
{ |
||||
this.resolver = new NRefactoryResolver(LanguageProperties.CSharp); |
||||
this.projectContent = pc; |
||||
this.parseInformation = parseInfo; |
||||
} |
||||
|
||||
public override object VisitCompilationUnit(CompilationUnit compilationUnit, object data) |
||||
{ |
||||
base.VisitCompilationUnit(compilationUnit, data); |
||||
ToVBNetConvertVisitor v = new ToVBNetConvertVisitor(); |
||||
compilationUnit.AcceptVisitor(v, data); |
||||
return null; |
||||
} |
||||
|
||||
IReturnType ResolveType(TypeReference typeRef) |
||||
{ |
||||
return TypeVisitor.CreateReturnType(typeRef, resolver); |
||||
} |
||||
|
||||
public override object VisitNamespaceDeclaration(NamespaceDeclaration namespaceDeclaration, object data) |
||||
{ |
||||
if (RootNamespaceToRemove != null) { |
||||
if (namespaceDeclaration.Name == RootNamespaceToRemove) { |
||||
// remove namespace declaration
|
||||
INode insertAfter = namespaceDeclaration; |
||||
foreach (INode child in namespaceDeclaration.Children) { |
||||
InsertAfterSibling(insertAfter, child); |
||||
insertAfter = child; |
||||
} |
||||
namespaceDeclaration.Children.Clear(); |
||||
RemoveCurrentNode(); |
||||
} else if (namespaceDeclaration.Name.StartsWith(RootNamespaceToRemove + ".")) { |
||||
namespaceDeclaration.Name = namespaceDeclaration.Name.Substring(RootNamespaceToRemove.Length + 1); |
||||
} |
||||
} |
||||
base.VisitNamespaceDeclaration(namespaceDeclaration, data); |
||||
return null; |
||||
} |
||||
|
||||
public override object VisitUsing(Using @using, object data) |
||||
{ |
||||
base.VisitUsing(@using, data); |
||||
if (DefaultImportsToRemove != null && !@using.IsAlias) { |
||||
if (DefaultImportsToRemove.Contains(@using.Name)) { |
||||
RemoveCurrentNode(); |
||||
} |
||||
} |
||||
return null; |
||||
} |
||||
|
||||
public override object VisitUsingDeclaration(UsingDeclaration usingDeclaration, object data) |
||||
{ |
||||
base.VisitUsingDeclaration(usingDeclaration, data); |
||||
if (usingDeclaration.Usings.Count == 0) { |
||||
RemoveCurrentNode(); |
||||
} |
||||
return null; |
||||
} |
||||
|
||||
struct BaseType |
||||
{ |
||||
internal readonly TypeReference TypeReference; |
||||
internal readonly IReturnType ReturnType; |
||||
internal readonly IClass UnderlyingClass; |
||||
|
||||
public BaseType(TypeReference typeReference, IReturnType returnType) |
||||
{ |
||||
this.TypeReference = typeReference; |
||||
this.ReturnType = returnType; |
||||
this.UnderlyingClass = returnType.GetUnderlyingClass(); |
||||
} |
||||
} |
||||
|
||||
public override object VisitMethodDeclaration(MethodDeclaration methodDeclaration, object data) |
||||
{ |
||||
// Initialize resolver for method:
|
||||
if (!methodDeclaration.Body.IsNull) { |
||||
if (resolver.Initialize(parseInformation, methodDeclaration.Body.StartLocation.Y, methodDeclaration.Body.StartLocation.X)) { |
||||
resolver.RunLookupTableVisitor(methodDeclaration); |
||||
} |
||||
} |
||||
IMethod currentMethod = resolver.CallingMember as IMethod; |
||||
CreateInterfaceImplementations(currentMethod, methodDeclaration, methodDeclaration.InterfaceImplementations); |
||||
// Make "Main" public
|
||||
if (currentMethod != null && currentMethod.Name == "Main") { |
||||
if (currentMethod.DeclaringType.FullyQualifiedName == StartupObjectToMakePublic) { |
||||
if (currentMethod.IsStatic && currentMethod.IsPrivate) { |
||||
methodDeclaration.Modifier &= ~Modifiers.Private; |
||||
methodDeclaration.Modifier |= Modifiers.Internal; |
||||
} |
||||
} |
||||
} |
||||
if (resolver.CallingClass != null && resolver.CallingClass.BaseType != null) { |
||||
// methods with the same name as a method in a base class must have 'Overloads'
|
||||
if ((methodDeclaration.Modifier & (Modifiers.Override | Modifiers.New)) == Modifiers.None) { |
||||
if (resolver.CallingClass.BaseType.GetMethods() |
||||
.Any(m => string.Equals(m.Name, methodDeclaration.Name, StringComparison.OrdinalIgnoreCase))) { |
||||
methodDeclaration.Modifier |= Modifiers.Overloads; |
||||
} |
||||
} |
||||
} |
||||
return base.VisitMethodDeclaration(methodDeclaration, data); |
||||
} |
||||
|
||||
ClassFinder CreateContext() |
||||
{ |
||||
return new ClassFinder(resolver.CallingClass, resolver.CallingMember, resolver.CaretLine, resolver.CaretColumn); |
||||
} |
||||
|
||||
void CreateInterfaceImplementations(IMember currentMember, ParametrizedNode memberDecl, List<InterfaceImplementation> interfaceImplementations) |
||||
{ |
||||
if (currentMember != null |
||||
&& (memberDecl.Modifier & Modifiers.Visibility) == Modifiers.None |
||||
&& interfaceImplementations.Count == 1) |
||||
{ |
||||
// member is explicitly implementing an interface member
|
||||
// to convert explicit interface implementations to VB, make the member private
|
||||
// and ensure its name does not collide with another member
|
||||
memberDecl.Modifier |= Modifiers.Private; |
||||
memberDecl.Name = interfaceImplementations[0].InterfaceType.Type.Replace('.', '_') + "_" + memberDecl.Name; |
||||
} |
||||
|
||||
if (currentMember != null && currentMember.IsPublic |
||||
&& currentMember.DeclaringType.ClassType != ClassType.Interface) |
||||
{ |
||||
// member could be implicitly implementing an interface member,
|
||||
// search for interfaces containing the member
|
||||
foreach (IReturnType directBaseType in currentMember.DeclaringType.GetCompoundClass().BaseTypes) { |
||||
IClass directBaseClass = directBaseType.GetUnderlyingClass(); |
||||
if (directBaseClass != null && directBaseClass.ClassType == ClassType.Interface) { |
||||
// include members inherited from other interfaces in the search:
|
||||
foreach (IReturnType baseType in MemberLookupHelper.GetTypeInheritanceTree(directBaseType)) { |
||||
IClass baseClass = baseType.GetUnderlyingClass(); |
||||
if (baseClass != null && baseClass.ClassType == ClassType.Interface) { |
||||
IMember similarMember = MemberLookupHelper.FindSimilarMember(baseClass, currentMember); |
||||
// add an interface implementation for similarMember
|
||||
// only when similarMember is not explicitly implemented by another member in this class
|
||||
if (similarMember != null && !HasExplicitImplementationFor(similarMember, baseType, memberDecl.Parent)) { |
||||
interfaceImplementations.Add(new InterfaceImplementation( |
||||
Refactoring.CodeGenerator.ConvertType(baseType, CreateContext()), |
||||
currentMember.Name)); |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
|
||||
bool HasExplicitImplementationFor(IMember interfaceMember, IReturnType interfaceReference, INode typeDecl) |
||||
{ |
||||
if (typeDecl == null) |
||||
return false; |
||||
foreach (INode node in typeDecl.Children) { |
||||
MemberNode memberNode = node as MemberNode; |
||||
if (memberNode != null && memberNode.InterfaceImplementations.Count > 0) { |
||||
foreach (InterfaceImplementation impl in memberNode.InterfaceImplementations) { |
||||
if (impl.MemberName == interfaceMember.Name |
||||
&& object.Equals(ResolveType(impl.InterfaceType), interfaceReference)) |
||||
{ |
||||
return true; |
||||
} |
||||
} |
||||
} |
||||
} |
||||
return false; |
||||
} |
||||
|
||||
public override object VisitConstructorDeclaration(ConstructorDeclaration constructorDeclaration, object data) |
||||
{ |
||||
if (!constructorDeclaration.Body.IsNull) { |
||||
if (resolver.Initialize(parseInformation, constructorDeclaration.Body.StartLocation.Y, constructorDeclaration.Body.StartLocation.X)) { |
||||
resolver.RunLookupTableVisitor(constructorDeclaration); |
||||
} |
||||
} |
||||
return base.VisitConstructorDeclaration(constructorDeclaration, data); |
||||
} |
||||
|
||||
public override object VisitPropertyDeclaration(PropertyDeclaration propertyDeclaration, object data) |
||||
{ |
||||
if (resolver.Initialize(parseInformation, propertyDeclaration.BodyStart.Y, propertyDeclaration.BodyStart.X)) { |
||||
resolver.RunLookupTableVisitor(propertyDeclaration); |
||||
} |
||||
IProperty currentProperty = resolver.CallingMember as IProperty; |
||||
CreateInterfaceImplementations(currentProperty, propertyDeclaration, propertyDeclaration.InterfaceImplementations); |
||||
return base.VisitPropertyDeclaration(propertyDeclaration, data); |
||||
} |
||||
|
||||
public override object VisitExpressionStatement(ExpressionStatement expressionStatement, object data) |
||||
{ |
||||
if (resolver.CompilationUnit == null) |
||||
return base.VisitExpressionStatement(expressionStatement, data); |
||||
|
||||
// Transform event invocations that aren't already transformed by a parent IfStatement to RaiseEvent statement
|
||||
InvocationExpression eventInvocation = expressionStatement.Expression as InvocationExpression; |
||||
if (eventInvocation != null && eventInvocation.TargetObject is IdentifierExpression) { |
||||
MemberResolveResult mrr = resolver.ResolveInternal(eventInvocation.TargetObject, ExpressionContext.Default) as MemberResolveResult; |
||||
if (mrr != null && mrr.ResolvedMember is IEvent) { |
||||
ReplaceCurrentNode(new RaiseEventStatement( |
||||
((IdentifierExpression)eventInvocation.TargetObject).Identifier, |
||||
eventInvocation.Arguments)); |
||||
} |
||||
} |
||||
base.VisitExpressionStatement(expressionStatement, data); |
||||
|
||||
HandleAssignmentStatement(expressionStatement.Expression as AssignmentExpression); |
||||
return null; |
||||
} |
||||
|
||||
public override object VisitBinaryOperatorExpression(BinaryOperatorExpression binaryOperatorExpression, object data) |
||||
{ |
||||
base.VisitBinaryOperatorExpression(binaryOperatorExpression, data); |
||||
|
||||
if (resolver.CompilationUnit == null) |
||||
return null; |
||||
|
||||
switch (binaryOperatorExpression.Op) { |
||||
case BinaryOperatorType.Equality: |
||||
case BinaryOperatorType.InEquality: |
||||
ConvertEqualityToReferenceEqualityIfRequired(binaryOperatorExpression); |
||||
break; |
||||
case BinaryOperatorType.Add: |
||||
ConvertArgumentsForStringConcatenationIfRequired(binaryOperatorExpression); |
||||
break; |
||||
case BinaryOperatorType.Divide: |
||||
ConvertDivisionToIntegerDivisionIfRequired(binaryOperatorExpression); |
||||
break; |
||||
} |
||||
return null; |
||||
} |
||||
|
||||
void ConvertEqualityToReferenceEqualityIfRequired(BinaryOperatorExpression binaryOperatorExpression) |
||||
{ |
||||
// maybe we have to convert Equality operator to ReferenceEquality
|
||||
ResolveResult left = resolver.ResolveInternal(binaryOperatorExpression.Left, ExpressionContext.Default); |
||||
ResolveResult right = resolver.ResolveInternal(binaryOperatorExpression.Right, ExpressionContext.Default); |
||||
if (left != null && right != null && left.ResolvedType != null && right.ResolvedType != null) { |
||||
IClass cLeft = left.ResolvedType.GetUnderlyingClass(); |
||||
IClass cRight = right.ResolvedType.GetUnderlyingClass(); |
||||
if (cLeft != null && cRight != null) { |
||||
if ((cLeft.ClassType != ClassType.Struct && cLeft.ClassType != ClassType.Enum) |
||||
|| (cRight.ClassType != ClassType.Struct && cRight.ClassType != ClassType.Enum)) |
||||
{ |
||||
// this is a reference comparison
|
||||
if (cLeft.FullyQualifiedName != "System.String") { |
||||
// and it's not a string comparison, so we'll use reference equality
|
||||
if (binaryOperatorExpression.Op == BinaryOperatorType.Equality) { |
||||
binaryOperatorExpression.Op = BinaryOperatorType.ReferenceEquality; |
||||
} else { |
||||
binaryOperatorExpression.Op = BinaryOperatorType.ReferenceInequality; |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
|
||||
void ConvertArgumentsForStringConcatenationIfRequired(BinaryOperatorExpression binaryOperatorExpression) |
||||
{ |
||||
ResolveResult left = resolver.ResolveInternal(binaryOperatorExpression.Left, ExpressionContext.Default); |
||||
ResolveResult right = resolver.ResolveInternal(binaryOperatorExpression.Right, ExpressionContext.Default); |
||||
|
||||
if (left != null && right != null) { |
||||
if (IsString(left.ResolvedType)) { |
||||
binaryOperatorExpression.Op = BinaryOperatorType.Concat; |
||||
if (NeedsExplicitConversionToString(right.ResolvedType)) { |
||||
binaryOperatorExpression.Right = CreateExplicitConversionToString(binaryOperatorExpression.Right); |
||||
} |
||||
} else if (IsString(right.ResolvedType)) { |
||||
binaryOperatorExpression.Op = BinaryOperatorType.Concat; |
||||
if (NeedsExplicitConversionToString(left.ResolvedType)) { |
||||
binaryOperatorExpression.Left = CreateExplicitConversionToString(binaryOperatorExpression.Left); |
||||
} |
||||
} |
||||
} |
||||
} |
||||
|
||||
void ConvertDivisionToIntegerDivisionIfRequired(BinaryOperatorExpression binaryOperatorExpression) |
||||
{ |
||||
ResolveResult left = resolver.ResolveInternal(binaryOperatorExpression.Left, ExpressionContext.Default); |
||||
ResolveResult right = resolver.ResolveInternal(binaryOperatorExpression.Right, ExpressionContext.Default); |
||||
|
||||
if (left != null && right != null) { |
||||
if (IsInteger(left.ResolvedType) && IsInteger(right.ResolvedType)) { |
||||
binaryOperatorExpression.Op = BinaryOperatorType.DivideInteger; |
||||
} |
||||
} |
||||
} |
||||
|
||||
bool IsString(IReturnType rt) |
||||
{ |
||||
return rt != null && rt.IsDefaultReturnType && rt.FullyQualifiedName == "System.String"; |
||||
} |
||||
|
||||
bool IsInteger(IReturnType rt) |
||||
{ |
||||
if (rt != null && rt.IsDefaultReturnType) { |
||||
switch (rt.FullyQualifiedName) { |
||||
case "System.Byte": |
||||
case "System.SByte": |
||||
case "System.Int16": |
||||
case "System.UInt16": |
||||
case "System.Int32": |
||||
case "System.UInt32": |
||||
case "System.Int64": |
||||
case "System.UInt64": |
||||
return true; |
||||
} |
||||
} |
||||
return false; |
||||
} |
||||
|
||||
bool IsFloatingPoint(IReturnType rt) |
||||
{ |
||||
if (rt != null && rt.IsDefaultReturnType) { |
||||
switch (rt.FullyQualifiedName) { |
||||
case "System.Single": |
||||
case "System.Double": |
||||
case "System.Decimal": |
||||
return true; |
||||
} |
||||
} |
||||
return false; |
||||
} |
||||
|
||||
bool NeedsExplicitConversionToString(IReturnType rt) |
||||
{ |
||||
if (rt != null) { |
||||
if (rt.IsDefaultReturnType) { |
||||
if (rt.FullyQualifiedName == "System.Object" |
||||
|| !TypeReference.PrimitiveTypesVBReverse.ContainsKey(rt.FullyQualifiedName)) |
||||
{ |
||||
// object and non-primitive types need explicit conversion
|
||||
return true; |
||||
} else { |
||||
// primitive types except object don't need explicit conversion
|
||||
return false; |
||||
} |
||||
} else { |
||||
return true; |
||||
} |
||||
} |
||||
return false; |
||||
} |
||||
|
||||
Expression CreateExplicitConversionToString(Expression expr) |
||||
{ |
||||
return new IdentifierExpression("Convert").Call("ToString", expr); |
||||
} |
||||
|
||||
public override object VisitIdentifierExpression(IdentifierExpression identifierExpression, object data) |
||||
{ |
||||
base.VisitIdentifierExpression(identifierExpression, data); |
||||
if (resolver.CompilationUnit == null) |
||||
return null; |
||||
|
||||
InvocationExpression parentIE = identifierExpression.Parent as InvocationExpression; |
||||
if (!(identifierExpression.Parent is AddressOfExpression) |
||||
&& (parentIE == null || parentIE.TargetObject != identifierExpression)) |
||||
{ |
||||
ResolveResult rr = resolver.ResolveInternal(identifierExpression, ExpressionContext.Default); |
||||
if (IsMethodGroup(rr)) { |
||||
ReplaceCurrentNode(new AddressOfExpression(identifierExpression)); |
||||
} |
||||
} |
||||
return null; |
||||
} |
||||
|
||||
public override object VisitMemberReferenceExpression(MemberReferenceExpression fieldReferenceExpression, object data) |
||||
{ |
||||
base.VisitMemberReferenceExpression(fieldReferenceExpression, data); |
||||
|
||||
if (resolver.CompilationUnit == null) |
||||
return null; |
||||
|
||||
InvocationExpression parentIE = fieldReferenceExpression.Parent as InvocationExpression; |
||||
if (!(fieldReferenceExpression.Parent is AddressOfExpression) |
||||
&& (parentIE == null || parentIE.TargetObject != fieldReferenceExpression)) |
||||
{ |
||||
ResolveResult rr = resolver.ResolveInternal(fieldReferenceExpression, ExpressionContext.Default); |
||||
if (IsMethodGroup(rr)) { |
||||
ReplaceCurrentNode(new AddressOfExpression(fieldReferenceExpression)); |
||||
} |
||||
} |
||||
|
||||
return null; |
||||
} |
||||
|
||||
static bool IsMethodGroup(ResolveResult rr) |
||||
{ |
||||
MethodGroupResolveResult mgrr = rr as MethodGroupResolveResult; |
||||
if (mgrr != null) { |
||||
return mgrr.Methods.Any(g=>g.Count > 0); |
||||
} |
||||
return false; |
||||
} |
||||
|
||||
void HandleAssignmentStatement(AssignmentExpression assignmentExpression) |
||||
{ |
||||
if (resolver.CompilationUnit == null || assignmentExpression == null) |
||||
return; |
||||
|
||||
if (assignmentExpression.Op == AssignmentOperatorType.Add || assignmentExpression.Op == AssignmentOperatorType.Subtract) { |
||||
ResolveResult rr = resolver.ResolveInternal(assignmentExpression.Left, ExpressionContext.Default); |
||||
if (rr is MemberResolveResult && (rr as MemberResolveResult).ResolvedMember is IEvent) { |
||||
if (assignmentExpression.Op == AssignmentOperatorType.Add) { |
||||
ReplaceCurrentNode(new AddHandlerStatement(assignmentExpression.Left, assignmentExpression.Right)); |
||||
} else { |
||||
ReplaceCurrentNode(new RemoveHandlerStatement(assignmentExpression.Left, assignmentExpression.Right)); |
||||
} |
||||
} else if (rr != null && rr.ResolvedType != null) { |
||||
IClass c = rr.ResolvedType.GetUnderlyingClass(); |
||||
if (c != null && c.ClassType == ClassType.Delegate) { |
||||
InvocationExpression invocation = |
||||
new IdentifierExpression("Delegate").Call( |
||||
assignmentExpression.Op == AssignmentOperatorType.Add ? "Combine" : "Remove", |
||||
assignmentExpression.Left); |
||||
invocation.Arguments.Add(assignmentExpression.Right); |
||||
|
||||
assignmentExpression.Op = AssignmentOperatorType.Assign; |
||||
assignmentExpression.Right = new CastExpression( |
||||
Refactoring.CodeGenerator.ConvertType(rr.ResolvedType, CreateContext()), |
||||
invocation, CastType.Cast); |
||||
} |
||||
} |
||||
} |
||||
} |
||||
|
||||
public override object VisitCastExpression(CastExpression castExpression, object data) |
||||
{ |
||||
base.VisitCastExpression(castExpression, data); |
||||
|
||||
if (resolver.CompilationUnit == null) |
||||
return null; |
||||
|
||||
IReturnType targetType = ResolveType(castExpression.CastTo); |
||||
IClass targetClass = targetType != null ? targetType.GetUnderlyingClass() : null; |
||||
if (castExpression.CastType != CastType.TryCast) { |
||||
if (targetClass != null && (targetClass.ClassType == ClassType.Struct || targetClass.ClassType == ClassType.Enum)) { |
||||
// cast to value type is a conversion
|
||||
castExpression.CastType = CastType.Conversion; |
||||
if (IsInteger(targetType)) { |
||||
ResolveResult sourceRR = resolver.ResolveInternal(castExpression.Expression, ExpressionContext.Default); |
||||
IReturnType sourceType = sourceRR != null ? sourceRR.ResolvedType : null; |
||||
if (IsFloatingPoint(sourceType)) { |
||||
// casts from float to int in C# truncate, but VB rounds
|
||||
// we'll have to introduce a call to Math.Truncate
|
||||
castExpression.Expression = ExpressionBuilder.Identifier("Math").Call("Truncate", castExpression.Expression); |
||||
} else if (sourceType != null && sourceType.FullyQualifiedName == "System.Char") { |
||||
// casts from char to int are valid in C#, but need to use AscW in VB
|
||||
castExpression.Expression = ExpressionBuilder.Identifier("AscW").Call(castExpression.Expression); |
||||
if (targetType != null && targetType.FullyQualifiedName == "System.Int32") { |
||||
// AscW already returns int, so skip the cast
|
||||
ReplaceCurrentNode(castExpression.Expression); |
||||
return null; |
||||
} |
||||
} |
||||
} |
||||
} |
||||
if (targetClass != null && targetClass.FullyQualifiedName == "System.Char") { |
||||
// C# cast to char is done using ChrW function
|
||||
ResolveResult sourceRR = resolver.ResolveInternal(castExpression.Expression, ExpressionContext.Default); |
||||
IReturnType sourceType = sourceRR != null ? sourceRR.ResolvedType : null; |
||||
if (IsInteger(sourceType)) { |
||||
ReplaceCurrentNode(new IdentifierExpression("ChrW").Call(castExpression.Expression)); |
||||
} |
||||
} |
||||
} |
||||
return null; |
||||
} |
||||
|
||||
public override object VisitUnaryOperatorExpression(UnaryOperatorExpression unaryOperatorExpression, object data) |
||||
{ |
||||
base.VisitUnaryOperatorExpression(unaryOperatorExpression, data); |
||||
switch (unaryOperatorExpression.Op) { |
||||
case UnaryOperatorType.Dereference: |
||||
ReplaceCurrentNode(unaryOperatorExpression.Expression.Member("Target")); |
||||
break; |
||||
case UnaryOperatorType.AddressOf: |
||||
ResolveResult rr = resolver.ResolveInternal(unaryOperatorExpression.Expression, ExpressionContext.Default); |
||||
if (rr != null && rr.ResolvedType != null) { |
||||
TypeReference targetType = Refactoring.CodeGenerator.ConvertType(rr.ResolvedType, CreateContext()); |
||||
TypeReference pointerType = new TypeReference("Pointer", new List<TypeReference> { targetType }); |
||||
ReplaceCurrentNode(pointerType.New(unaryOperatorExpression.Expression)); |
||||
} |
||||
break; |
||||
} |
||||
return null; |
||||
} |
||||
|
||||
public override object VisitTypeReference(TypeReference typeReference, object data) |
||||
{ |
||||
while (typeReference.PointerNestingLevel > 0) { |
||||
TypeReference tr = new TypeReference(typeReference.Type) { |
||||
IsKeyword = typeReference.IsKeyword, |
||||
IsGlobal = typeReference.IsGlobal, |
||||
}; |
||||
tr.GenericTypes.AddRange(typeReference.GenericTypes); |
||||
|
||||
typeReference = new TypeReference("Pointer") { |
||||
StartLocation = typeReference.StartLocation, |
||||
EndLocation = typeReference.EndLocation, |
||||
PointerNestingLevel = typeReference.PointerNestingLevel - 1, |
||||
GenericTypes = { tr }, |
||||
RankSpecifier = typeReference.RankSpecifier |
||||
}; |
||||
} |
||||
ReplaceCurrentNode(typeReference); |
||||
return base.VisitTypeReference(typeReference, data); |
||||
} |
||||
|
||||
public override object VisitUnsafeStatement(UnsafeStatement unsafeStatement, object data) |
||||
{ |
||||
base.VisitUnsafeStatement(unsafeStatement, data); |
||||
ReplaceCurrentNode(unsafeStatement.Block); |
||||
return null; |
||||
} |
||||
} |
||||
} |
||||
@ -0,0 +1,202 @@
@@ -0,0 +1,202 @@
|
||||
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
|
||||
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
|
||||
|
||||
using System; |
||||
using System.Collections.Generic; |
||||
using ICSharpCode.NRefactory; |
||||
using ICSharpCode.NRefactory.Ast; |
||||
using ICSharpCode.NRefactory.PrettyPrinter; |
||||
|
||||
namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver |
||||
{ |
||||
/// <summary>
|
||||
/// Allows converting code snippets between C# and VB.
|
||||
/// This class isn't used by SharpDevelop itself (because it doesn't support projects).
|
||||
/// It works by creating a dummy project for the file to convert with a set of default references.
|
||||
/// </summary>
|
||||
public class CodeSnippetConverter |
||||
{ |
||||
/// <summary>
|
||||
/// Project-wide imports to add to all files when converting VB to C#.
|
||||
/// </summary>
|
||||
public IList<string> DefaultImportsToAdd = new List<string> { "Microsoft.VisualBasic", "System", "System.Collections", "System.Collections.Generic", "System.Data", "System.Diagnostics" }; |
||||
|
||||
/// <summary>
|
||||
/// Imports to remove (because they will become project-wide imports) when converting C# to VB.
|
||||
/// </summary>
|
||||
public IList<string> DefaultImportsToRemove = new List<string> { "Microsoft.VisualBasic", "System" }; |
||||
|
||||
/// <summary>
|
||||
/// References project contents, for resolving type references during the conversion.
|
||||
/// </summary>
|
||||
public IList<IProjectContent> ReferencedContents = new List<IProjectContent>(); |
||||
|
||||
DefaultProjectContent project; |
||||
List<ISpecial> specials; |
||||
CompilationUnit compilationUnit; |
||||
ParseInformation parseInfo; |
||||
bool wasExpression; |
||||
|
||||
#region Parsing
|
||||
INode Parse(SupportedLanguage sourceLanguage, string sourceCode, out string error) |
||||
{ |
||||
project = new DefaultProjectContent(); |
||||
project.ReferencedContents.AddRange(ReferencedContents); |
||||
if (sourceLanguage == SupportedLanguage.VBNet) { |
||||
project.Language = LanguageProperties.VBNet; |
||||
project.DefaultImports = new DefaultUsing(project); |
||||
project.DefaultImports.Usings.AddRange(DefaultImportsToAdd); |
||||
} else { |
||||
project.Language = LanguageProperties.CSharp; |
||||
} |
||||
SnippetParser parser = new SnippetParser(sourceLanguage); |
||||
INode result = parser.Parse(sourceCode); |
||||
error = parser.Errors.ErrorOutput; |
||||
specials = parser.Specials; |
||||
if (parser.Errors.Count != 0) |
||||
return null; |
||||
|
||||
wasExpression = parser.SnippetType == SnippetType.Expression; |
||||
if (wasExpression) { |
||||
// Special case 'Expression': expressions may be replaced with other statements in the AST by the ConvertVisitor,
|
||||
// but we need to return a 'stable' node so that the correct transformed AST is returned.
|
||||
// Thus, we wrap any expressions into a statement block.
|
||||
result = MakeBlockFromExpression((Expression)result); |
||||
} |
||||
|
||||
// now create a dummy compilation unit around the snippet result
|
||||
switch (parser.SnippetType) { |
||||
case SnippetType.CompilationUnit: |
||||
compilationUnit = (CompilationUnit)result; |
||||
break; |
||||
case SnippetType.Expression: |
||||
case SnippetType.Statements: |
||||
compilationUnit = MakeCompilationUnitFromTypeMembers( |
||||
MakeMethodFromBlock( |
||||
(BlockStatement)result |
||||
)); |
||||
break; |
||||
case SnippetType.TypeMembers: |
||||
compilationUnit = MakeCompilationUnitFromTypeMembers(result.Children); |
||||
break; |
||||
default: |
||||
throw new NotSupportedException("Unknown snippet type: " + parser.SnippetType); |
||||
} |
||||
|
||||
// convert NRefactory CU in DOM CU
|
||||
NRefactoryASTConvertVisitor visitor = new NRefactoryASTConvertVisitor(project, sourceLanguage); |
||||
visitor.VisitCompilationUnit(compilationUnit, null); |
||||
visitor.Cu.FileName = sourceLanguage == SupportedLanguage.CSharp ? "a.cs" : "a.vb"; |
||||
|
||||
// and register the compilation unit in the DOM
|
||||
foreach (IClass c in visitor.Cu.Classes) { |
||||
project.AddClassToNamespaceList(c); |
||||
} |
||||
parseInfo = new ParseInformation(visitor.Cu); |
||||
|
||||
return result; |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Unpacks the expression from a statement block; if it was wrapped earlier.
|
||||
/// </summary>
|
||||
INode UnpackExpression(INode node) |
||||
{ |
||||
if (wasExpression) { |
||||
BlockStatement block = node as BlockStatement; |
||||
if (block != null && block.Children.Count == 1) { |
||||
ExpressionStatement es = block.Children[0] as ExpressionStatement; |
||||
if (es != null) |
||||
return es.Expression; |
||||
} |
||||
} |
||||
return node; |
||||
} |
||||
|
||||
BlockStatement MakeBlockFromExpression(Expression expr) |
||||
{ |
||||
return new BlockStatement { |
||||
Children = { |
||||
new ExpressionStatement(expr) |
||||
}, |
||||
StartLocation = expr.StartLocation, |
||||
EndLocation = expr.EndLocation |
||||
}; |
||||
} |
||||
|
||||
INode[] MakeMethodFromBlock(BlockStatement block) |
||||
{ |
||||
return new INode[] { |
||||
new MethodDeclaration { |
||||
Name = "DummyMethodForConversion", |
||||
Body = block, |
||||
StartLocation = block.StartLocation, |
||||
EndLocation = block.EndLocation |
||||
} |
||||
}; |
||||
} |
||||
|
||||
CompilationUnit MakeCompilationUnitFromTypeMembers(IList<INode> members) |
||||
{ |
||||
TypeDeclaration type = new TypeDeclaration(Modifiers.None, null) { |
||||
Name = "DummyTypeForConversion", |
||||
StartLocation = members[0].StartLocation, |
||||
EndLocation = GetEndLocation(members[members.Count - 1]) |
||||
}; |
||||
type.Children.AddRange(members); |
||||
return new CompilationUnit { |
||||
Children = { |
||||
type |
||||
} |
||||
}; |
||||
} |
||||
|
||||
Location GetEndLocation(INode node) |
||||
{ |
||||
// workaround: MethodDeclaration.EndLocation is the end of the method header,
|
||||
// but for the end of the dummy class we need the body end
|
||||
MethodDeclaration method = node as MethodDeclaration; |
||||
if (method != null && !method.Body.IsNull) |
||||
return method.Body.EndLocation; |
||||
else |
||||
return node.EndLocation; |
||||
} |
||||
#endregion
|
||||
|
||||
public string CSharpToVB(string input, out string errors) |
||||
{ |
||||
INode node = Parse(SupportedLanguage.CSharp, input, out errors); |
||||
if (node == null) |
||||
return null; |
||||
// apply conversion logic:
|
||||
compilationUnit.AcceptVisitor( |
||||
new CSharpToVBNetConvertVisitor(project, parseInfo) { |
||||
DefaultImportsToRemove = DefaultImportsToRemove, |
||||
}, |
||||
null); |
||||
PreprocessingDirective.CSharpToVB(specials); |
||||
return CreateCode(UnpackExpression(node), new VBNetOutputVisitor()); |
||||
} |
||||
|
||||
public string VBToCSharp(string input, out string errors) |
||||
{ |
||||
INode node = Parse(SupportedLanguage.VBNet, input, out errors); |
||||
if (node == null) |
||||
return null; |
||||
// apply conversion logic:
|
||||
compilationUnit.AcceptVisitor( |
||||
new VBNetToCSharpConvertVisitor(project, parseInfo), |
||||
null); |
||||
PreprocessingDirective.VBToCSharp(specials); |
||||
return CreateCode(UnpackExpression(node), new CSharpOutputVisitor()); |
||||
} |
||||
|
||||
string CreateCode(INode node, IOutputAstVisitor outputVisitor) |
||||
{ |
||||
using (SpecialNodesInserter.Install(specials, outputVisitor)) { |
||||
node.AcceptVisitor(outputVisitor, null); |
||||
} |
||||
return outputVisitor.Text; |
||||
} |
||||
} |
||||
} |
||||
@ -0,0 +1,45 @@
@@ -0,0 +1,45 @@
|
||||
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
|
||||
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
|
||||
|
||||
using System; |
||||
using ICSharpCode.NRefactory.Ast; |
||||
|
||||
namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver |
||||
{ |
||||
/// <summary>
|
||||
/// Used for the type of implicitly typed local variables in C# 3.0 or VB 9.
|
||||
/// </summary>
|
||||
public sealed class InferredReturnType : ProxyReturnType |
||||
{ |
||||
NRefactoryResolver _resolver; |
||||
Expression _expression; |
||||
IReturnType _baseType; |
||||
|
||||
internal InferredReturnType(Expression expression, NRefactoryResolver resolver) |
||||
{ |
||||
if (resolver == null) |
||||
throw new ArgumentNullException("resolver"); |
||||
|
||||
_expression = expression; |
||||
_resolver = resolver; |
||||
} |
||||
|
||||
public override IReturnType BaseType { |
||||
get { |
||||
if (_expression != null) { |
||||
// prevent infinite recursion:
|
||||
Expression expr = _expression; |
||||
_expression = null; |
||||
|
||||
ResolveResult rr = _resolver.ResolveInternal(expr, ExpressionContext.Default); |
||||
if (rr != null) { |
||||
_baseType = rr.ResolvedType; |
||||
} |
||||
|
||||
_resolver = null; |
||||
} |
||||
return _baseType; |
||||
} |
||||
} |
||||
} |
||||
} |
||||
@ -0,0 +1,65 @@
@@ -0,0 +1,65 @@
|
||||
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
|
||||
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
|
||||
|
||||
using System; |
||||
using ICSharpCode.NRefactory.Ast; |
||||
|
||||
namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver |
||||
{ |
||||
/// <summary>
|
||||
/// Description of LambdaParameterReturnType.
|
||||
/// </summary>
|
||||
public class LambdaParameterReturnType : ProxyReturnType |
||||
{ |
||||
LambdaExpression lambda; |
||||
int parameterIndex; |
||||
string parameterName; |
||||
NRefactoryResolver resolver; |
||||
|
||||
public LambdaParameterReturnType(LambdaExpression lambda, string name, NRefactoryResolver resolver) |
||||
{ |
||||
if (lambda == null) |
||||
throw new ArgumentNullException("lambda"); |
||||
if (name == null) |
||||
throw new ArgumentNullException("name"); |
||||
if (resolver == null) |
||||
throw new ArgumentNullException("resolver"); |
||||
this.lambda = lambda; |
||||
this.parameterName = name; |
||||
this.parameterIndex = lambda.Parameters.FindIndex(p => p.ParameterName == name); |
||||
this.resolver = resolver; |
||||
if (parameterIndex < 0) |
||||
throw new ArgumentException("there is no lambda parameter with that name"); |
||||
} |
||||
|
||||
IReturnType cachedType; |
||||
|
||||
public override IReturnType BaseType { |
||||
get { |
||||
NRefactoryResolver resolver = this.resolver; |
||||
LambdaExpression lambda = this.lambda; |
||||
if (resolver == null || lambda == null) |
||||
return cachedType; |
||||
|
||||
this.resolver = null; |
||||
this.lambda = null; |
||||
MemberLookupHelper.Log("Resolving " + this); |
||||
IReturnType rt = resolver.GetExpectedTypeFromContext(lambda); |
||||
MemberLookupHelper.Log("Resolving " + this + ", got delegate type " + rt); |
||||
IMethod sig = CSharp.TypeInference.GetDelegateOrExpressionTreeSignature(rt, true); |
||||
if (sig != null && parameterIndex < sig.Parameters.Count) { |
||||
MemberLookupHelper.Log("Resolving " + this + ", got type " + rt); |
||||
return cachedType = sig.Parameters[parameterIndex].ReturnType; |
||||
} |
||||
return null; |
||||
} |
||||
} |
||||
|
||||
public override string ToString() |
||||
{ |
||||
return "[LambdaParameterReturnType: " + parameterName + |
||||
(resolver != null ? " (not yet resolved)" : " (" + cachedType + ")") |
||||
+ "]"; |
||||
} |
||||
} |
||||
} |
||||
@ -0,0 +1,106 @@
@@ -0,0 +1,106 @@
|
||||
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
|
||||
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
|
||||
|
||||
using System; |
||||
using System.Collections.Generic; |
||||
using System.Linq; |
||||
using ICSharpCode.NRefactory.Visitors; |
||||
using ICSharpCode.NRefactory.Ast; |
||||
|
||||
namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver |
||||
{ |
||||
public class LambdaReturnType : AnonymousMethodReturnType |
||||
{ |
||||
NRefactoryResolver resolver; |
||||
LambdaExpression lambdaExpression; |
||||
List<Expression> returnExpressions = new List<Expression>(); |
||||
|
||||
public override bool CanBeConvertedToExpressionTree { |
||||
get { return lambdaExpression != null; } |
||||
} |
||||
|
||||
internal LambdaReturnType(LambdaExpression expression, NRefactoryResolver resolver) |
||||
: base(resolver.CompilationUnit) |
||||
{ |
||||
this.resolver = resolver; |
||||
this.lambdaExpression = expression; |
||||
|
||||
base.MethodParameters = new List<IParameter>(); |
||||
foreach (ParameterDeclarationExpression param in expression.Parameters) { |
||||
base.MethodParameters.Add(NRefactoryASTConvertVisitor.CreateParameter(param, resolver.CallingMember as IMethod, resolver.CallingClass, resolver.CompilationUnit)); |
||||
} |
||||
if (expression.ExpressionBody.IsNull) |
||||
expression.StatementBody.AcceptVisitor(new ReturnStatementFinder(returnExpressions), null); |
||||
else |
||||
returnExpressions.Add(expression.ExpressionBody); |
||||
} |
||||
|
||||
internal LambdaReturnType(AnonymousMethodExpression expression, NRefactoryResolver resolver) |
||||
: base(resolver.CompilationUnit) |
||||
{ |
||||
this.resolver = resolver; |
||||
|
||||
if (expression.HasParameterList) { |
||||
base.MethodParameters = new List<IParameter>(); |
||||
foreach (ParameterDeclarationExpression param in expression.Parameters) { |
||||
base.MethodParameters.Add(NRefactoryASTConvertVisitor.CreateParameter(param, resolver.CallingMember as IMethod, resolver.CallingClass, resolver.CompilationUnit)); |
||||
} |
||||
} |
||||
expression.Body.AcceptVisitor(new ReturnStatementFinder(returnExpressions), null); |
||||
} |
||||
|
||||
sealed class ReturnStatementFinder : AbstractAstVisitor |
||||
{ |
||||
List<Expression> returnExpressions; |
||||
|
||||
public ReturnStatementFinder(List<Expression> returnExpressions) |
||||
{ |
||||
this.returnExpressions = returnExpressions; |
||||
} |
||||
|
||||
public override object VisitReturnStatement(ReturnStatement returnStatement, object data) |
||||
{ |
||||
returnExpressions.Add(returnStatement.Expression); |
||||
return base.VisitReturnStatement(returnStatement, data); |
||||
} |
||||
|
||||
public override object VisitAnonymousMethodExpression(AnonymousMethodExpression anonymousMethodExpression, object data) |
||||
{ |
||||
return null; |
||||
} |
||||
|
||||
public override object VisitLambdaExpression(LambdaExpression lambdaExpression, object data) |
||||
{ |
||||
return null; |
||||
} |
||||
} |
||||
|
||||
public override IReturnType ResolveReturnType(IReturnType[] parameterTypes) |
||||
{ |
||||
if (lambdaExpression == null) |
||||
return ResolveReturnType(); |
||||
|
||||
try { |
||||
MemberLookupHelper.Log("LambdaReturnType: SetImplicitLambdaParameterTypes ", parameterTypes); |
||||
resolver.SetImplicitLambdaParameterTypes(lambdaExpression, parameterTypes); |
||||
return ResolveReturnType(); |
||||
} finally { |
||||
resolver.UnsetImplicitLambdaParameterTypes(lambdaExpression); |
||||
} |
||||
} |
||||
|
||||
public override IReturnType ResolveReturnType() |
||||
{ |
||||
MemberLookupHelper.Log("LambdaReturnType: ResolveReturnType"); |
||||
IReturnType result; |
||||
if (returnExpressions.Count == 0) |
||||
result = resolver.ProjectContent.SystemTypes.Void; |
||||
else |
||||
result = returnExpressions.Select(rt => resolver.ResolveInternal(rt, ExpressionContext.Default)) |
||||
.Select(rr => rr != null ? rr.ResolvedType : null) |
||||
.Aggregate((rt1, rt2) => MemberLookupHelper.GetCommonType(resolver.ProjectContent, rt1, rt2)); |
||||
MemberLookupHelper.Log("LambdaReturnType: inferred " + result); |
||||
return result; |
||||
} |
||||
} |
||||
} |
||||
@ -0,0 +1,856 @@
@@ -0,0 +1,856 @@
|
||||
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
|
||||
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
|
||||
|
||||
// created on 04.08.2003 at 17:49
|
||||
using System; |
||||
using System.Collections.Generic; |
||||
using System.Diagnostics; |
||||
using System.Text; |
||||
using System.Linq; |
||||
using ICSharpCode.NRefactory; |
||||
using ICSharpCode.NRefactory.Visitors; |
||||
using ICSharpCode.SharpDevelop.Dom.VBNet; |
||||
using AST = ICSharpCode.NRefactory.Ast; |
||||
using RefParser = ICSharpCode.NRefactory; |
||||
|
||||
namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver |
||||
{ |
||||
public class NRefactoryASTConvertVisitor : AbstractAstVisitor |
||||
{ |
||||
DefaultCompilationUnit cu; |
||||
DefaultUsingScope currentNamespace; |
||||
Stack<DefaultClass> currentClass = new Stack<DefaultClass>(); |
||||
public string VBRootNamespace { get; set; } |
||||
|
||||
public ICompilationUnit Cu { |
||||
get { |
||||
return cu; |
||||
} |
||||
} |
||||
|
||||
public NRefactoryASTConvertVisitor(IProjectContent projectContent, SupportedLanguage language) |
||||
{ |
||||
if (language == SupportedLanguage.VBNet) |
||||
cu = new VBNetCompilationUnit(projectContent); |
||||
else |
||||
cu = new DefaultCompilationUnit(projectContent); |
||||
} |
||||
|
||||
DefaultClass GetCurrentClass() |
||||
{ |
||||
return currentClass.Count == 0 ? null : currentClass.Peek(); |
||||
} |
||||
|
||||
ModifierEnum ConvertModifier(AST.Modifiers m) |
||||
{ |
||||
if (this.IsVisualBasic) |
||||
return ConvertModifier(m, ModifierEnum.Public); |
||||
else if (currentClass.Count > 0 && currentClass.Peek().ClassType == ClassType.Interface) |
||||
return ConvertModifier(m, ModifierEnum.Public); |
||||
else |
||||
return ConvertModifier(m, ModifierEnum.Private); |
||||
} |
||||
|
||||
ModifierEnum ConvertTypeModifier(AST.Modifiers m) |
||||
{ |
||||
if (this.IsVisualBasic) |
||||
return ConvertModifier(m, ModifierEnum.Public); |
||||
if (currentClass.Count > 0) |
||||
return ConvertModifier(m, ModifierEnum.Private); |
||||
else |
||||
return ConvertModifier(m, ModifierEnum.Internal); |
||||
} |
||||
|
||||
ModifierEnum ConvertModifier(AST.Modifiers m, ModifierEnum defaultVisibility) |
||||
{ |
||||
ModifierEnum r = (ModifierEnum)m; |
||||
if ((r & ModifierEnum.VisibilityMask) == ModifierEnum.None) |
||||
return r | defaultVisibility; |
||||
else |
||||
return r; |
||||
} |
||||
|
||||
List<RefParser.ISpecial> specials; |
||||
|
||||
/// <summary>
|
||||
/// Gets/Sets the list of specials used to read the documentation.
|
||||
/// The list must be sorted by the start position of the specials!
|
||||
/// </summary>
|
||||
public List<RefParser.ISpecial> Specials { |
||||
get { |
||||
return specials; |
||||
} |
||||
set { |
||||
specials = value; |
||||
} |
||||
} |
||||
|
||||
string GetDocumentation(int line, IList<AST.AttributeSection> attributes) |
||||
{ |
||||
foreach (AST.AttributeSection att in attributes) { |
||||
if (att.StartLocation.Y > 0 && att.StartLocation.Y < line) |
||||
line = att.StartLocation.Y; |
||||
} |
||||
List<string> lines = new List<string>(); |
||||
int length = 0; |
||||
while (line > 0) { |
||||
line--; |
||||
string doku = null; |
||||
bool foundPreprocessing = false; |
||||
var specialsOnLine = GetSpecialsFromLine(line); |
||||
foreach (RefParser.ISpecial special in specialsOnLine) { |
||||
RefParser.Comment comment = special as RefParser.Comment; |
||||
if (comment != null && comment.CommentType == RefParser.CommentType.Documentation) { |
||||
doku = comment.CommentText; |
||||
break; |
||||
} else if (special is RefParser.PreprocessingDirective) { |
||||
foundPreprocessing = true; |
||||
} |
||||
} |
||||
if (doku == null && !foundPreprocessing) |
||||
break; |
||||
if (doku != null) { |
||||
length += 2 + doku.Length; |
||||
lines.Add(doku); |
||||
} |
||||
} |
||||
StringBuilder b = new StringBuilder(length); |
||||
for (int i = lines.Count - 1; i >= 0; --i) { |
||||
b.AppendLine(lines[i]); |
||||
} |
||||
return b.ToString(); |
||||
} |
||||
|
||||
string GetDocumentationFromLine(int line) |
||||
{ |
||||
foreach (RefParser.ISpecial special in GetSpecialsFromLine(line)) { |
||||
RefParser.Comment comment = special as RefParser.Comment; |
||||
if (comment != null && comment.CommentType == RefParser.CommentType.Documentation) { |
||||
return comment.CommentText; |
||||
} |
||||
} |
||||
return null; |
||||
} |
||||
|
||||
IEnumerable<RefParser.ISpecial> GetSpecialsFromLine(int line) |
||||
{ |
||||
List<RefParser.ISpecial> result = new List<RefParser.ISpecial>(); |
||||
if (specials == null) return result; |
||||
if (line < 0) return result; |
||||
// specials is a sorted list: use interpolation search
|
||||
int left = 0; |
||||
int right = specials.Count - 1; |
||||
int m; |
||||
|
||||
while (left <= right) { |
||||
int leftLine = specials[left].StartPosition.Y; |
||||
if (line < leftLine) |
||||
break; |
||||
int rightLine = specials[right].StartPosition.Y; |
||||
if (line > rightLine) |
||||
break; |
||||
if (leftLine == rightLine) { |
||||
if (leftLine == line) |
||||
m = left; |
||||
else |
||||
break; |
||||
} else { |
||||
m = (int)(left + Math.BigMul((line - leftLine), (right - left)) / (rightLine - leftLine)); |
||||
} |
||||
|
||||
int mLine = specials[m].StartPosition.Y; |
||||
if (mLine < line) { // found line smaller than line we are looking for
|
||||
left = m + 1; |
||||
} else if (mLine > line) { |
||||
right = m - 1; |
||||
} else { |
||||
// correct line found,
|
||||
// look for first special in that line
|
||||
while (--m >= 0 && specials[m].StartPosition.Y == line); |
||||
// look at all specials in that line: find doku-comment
|
||||
while (++m < specials.Count && specials[m].StartPosition.Y == line) { |
||||
result.Add(specials[m]); |
||||
} |
||||
break; |
||||
} |
||||
} |
||||
return result; |
||||
} |
||||
|
||||
public override object VisitCompilationUnit(AST.CompilationUnit compilationUnit, object data) |
||||
{ |
||||
if (compilationUnit == null) { |
||||
return null; |
||||
} |
||||
currentNamespace = new DefaultUsingScope(); |
||||
if (!string.IsNullOrEmpty(VBRootNamespace)) { |
||||
foreach (string name in VBRootNamespace.Split('.')) { |
||||
currentNamespace = new DefaultUsingScope { |
||||
Parent = currentNamespace, |
||||
NamespaceName = PrependCurrentNamespace(name), |
||||
}; |
||||
currentNamespace.Parent.ChildScopes.Add(currentNamespace); |
||||
} |
||||
} |
||||
cu.UsingScope = currentNamespace; |
||||
compilationUnit.AcceptChildren(this, data); |
||||
return cu; |
||||
} |
||||
|
||||
public override object VisitUsingDeclaration(AST.UsingDeclaration usingDeclaration, object data) |
||||
{ |
||||
DefaultUsing us = new DefaultUsing(cu.ProjectContent, GetRegion(usingDeclaration.StartLocation, usingDeclaration.EndLocation)); |
||||
foreach (AST.Using u in usingDeclaration.Usings) { |
||||
u.AcceptVisitor(this, us); |
||||
} |
||||
currentNamespace.Usings.Add(us); |
||||
return data; |
||||
} |
||||
|
||||
public override object VisitUsing(AST.Using u, object data) |
||||
{ |
||||
Debug.Assert(data is DefaultUsing); |
||||
DefaultUsing us = (DefaultUsing)data; |
||||
if (u.IsAlias) { |
||||
IReturnType rt = CreateReturnType(u.Alias); |
||||
if (rt != null) { |
||||
us.AddAlias(u.Name, rt); |
||||
} |
||||
} else { |
||||
us.Usings.Add(u.Name); |
||||
} |
||||
return data; |
||||
} |
||||
|
||||
public override object VisitOptionDeclaration(ICSharpCode.NRefactory.Ast.OptionDeclaration optionDeclaration, object data) |
||||
{ |
||||
if (cu is VBNetCompilationUnit) { |
||||
VBNetCompilationUnit provider = cu as VBNetCompilationUnit; |
||||
|
||||
switch (optionDeclaration.OptionType) { |
||||
case ICSharpCode.NRefactory.Ast.OptionType.Explicit: |
||||
provider.OptionExplicit = optionDeclaration.OptionValue; |
||||
break; |
||||
case ICSharpCode.NRefactory.Ast.OptionType.Strict: |
||||
provider.OptionStrict = optionDeclaration.OptionValue; |
||||
break; |
||||
case ICSharpCode.NRefactory.Ast.OptionType.CompareBinary: |
||||
provider.OptionCompare = CompareKind.Binary; |
||||
break; |
||||
case ICSharpCode.NRefactory.Ast.OptionType.CompareText: |
||||
provider.OptionCompare = CompareKind.Text; |
||||
break; |
||||
case ICSharpCode.NRefactory.Ast.OptionType.Infer: |
||||
provider.OptionInfer = optionDeclaration.OptionValue; |
||||
break; |
||||
} |
||||
|
||||
return null; |
||||
} |
||||
|
||||
return base.VisitOptionDeclaration(optionDeclaration, data); |
||||
} |
||||
|
||||
void ConvertAttributes(AST.AttributedNode from, AbstractEntity to) |
||||
{ |
||||
if (from.Attributes.Count == 0) { |
||||
to.Attributes = DefaultAttribute.EmptyAttributeList; |
||||
} else { |
||||
ICSharpCode.NRefactory.Location location = from.Attributes[0].StartLocation; |
||||
ClassFinder context; |
||||
if (to is IClass) { |
||||
context = new ClassFinder((IClass)to, location.Line, location.Column); |
||||
} else { |
||||
context = new ClassFinder(to.DeclaringType, location.Line, location.Column); |
||||
} |
||||
to.Attributes = VisitAttributes(from.Attributes, context); |
||||
} |
||||
} |
||||
|
||||
List<IAttribute> VisitAttributes(IList<AST.AttributeSection> attributes, ClassFinder context) |
||||
{ |
||||
// TODO Expressions???
|
||||
List<IAttribute> result = new List<IAttribute>(); |
||||
foreach (AST.AttributeSection section in attributes) { |
||||
|
||||
AttributeTarget target = AttributeTarget.None; |
||||
if (section.AttributeTarget != null && section.AttributeTarget != "") { |
||||
switch (section.AttributeTarget.ToUpperInvariant()) { |
||||
case "ASSEMBLY": |
||||
target = AttributeTarget.Assembly; |
||||
break; |
||||
case "FIELD": |
||||
target = AttributeTarget.Field; |
||||
break; |
||||
case "EVENT": |
||||
target = AttributeTarget.Event; |
||||
break; |
||||
case "METHOD": |
||||
target = AttributeTarget.Method; |
||||
break; |
||||
case "MODULE": |
||||
target = AttributeTarget.Module; |
||||
break; |
||||
case "PARAM": |
||||
target = AttributeTarget.Param; |
||||
break; |
||||
case "PROPERTY": |
||||
target = AttributeTarget.Property; |
||||
break; |
||||
case "RETURN": |
||||
target = AttributeTarget.Return; |
||||
break; |
||||
case "TYPE": |
||||
target = AttributeTarget.Type; |
||||
break; |
||||
default: |
||||
target = AttributeTarget.None; |
||||
break; |
||||
|
||||
} |
||||
} |
||||
|
||||
foreach (AST.Attribute attribute in section.Attributes) { |
||||
List<object> positionalArguments = new List<object>(); |
||||
foreach (AST.Expression positionalArgument in attribute.PositionalArguments) { |
||||
positionalArguments.Add(ConvertAttributeArgument(positionalArgument)); |
||||
} |
||||
Dictionary<string, object> namedArguments = new Dictionary<string, object>(); |
||||
foreach (AST.NamedArgumentExpression namedArgumentExpression in attribute.NamedArguments) { |
||||
namedArguments.Add(namedArgumentExpression.Name, ConvertAttributeArgument(namedArgumentExpression.Expression)); |
||||
} |
||||
result.Add(new DefaultAttribute(new AttributeReturnType(context, attribute.Name), |
||||
target, positionalArguments, namedArguments) |
||||
{ |
||||
CompilationUnit = cu, |
||||
Region = GetRegion(attribute.StartLocation, attribute.EndLocation) |
||||
}); |
||||
} |
||||
} |
||||
return result; |
||||
} |
||||
|
||||
static object ConvertAttributeArgument(AST.Expression expression) |
||||
{ |
||||
AST.PrimitiveExpression pe = expression as AST.PrimitiveExpression; |
||||
if (pe != null) |
||||
return pe.Value; |
||||
else |
||||
return null; |
||||
} |
||||
|
||||
public override object VisitAttributeSection(ICSharpCode.NRefactory.Ast.AttributeSection attributeSection, object data) |
||||
{ |
||||
if (GetCurrentClass() == null) { |
||||
ClassFinder cf = new ClassFinder(new DefaultClass(cu, "DummyClass"), attributeSection.StartLocation.Line, attributeSection.StartLocation.Column); |
||||
cu.Attributes.AddRange(VisitAttributes(new[] { attributeSection }, cf)); |
||||
} |
||||
return null; |
||||
} |
||||
|
||||
string PrependCurrentNamespace(string name) |
||||
{ |
||||
if (string.IsNullOrEmpty(currentNamespace.NamespaceName)) |
||||
return name; |
||||
else |
||||
return currentNamespace.NamespaceName + "." + name; |
||||
} |
||||
|
||||
public override object VisitNamespaceDeclaration(AST.NamespaceDeclaration namespaceDeclaration, object data) |
||||
{ |
||||
DefaultUsingScope oldNamespace = currentNamespace; |
||||
foreach (string name in namespaceDeclaration.Name.Split('.')) { |
||||
currentNamespace = new DefaultUsingScope { |
||||
Parent = currentNamespace, |
||||
NamespaceName = PrependCurrentNamespace(name), |
||||
}; |
||||
currentNamespace.Parent.ChildScopes.Add(currentNamespace); |
||||
} |
||||
object ret = namespaceDeclaration.AcceptChildren(this, data); |
||||
currentNamespace = oldNamespace; |
||||
return ret; |
||||
} |
||||
|
||||
ClassType TranslateClassType(AST.ClassType type) |
||||
{ |
||||
switch (type) { |
||||
case AST.ClassType.Enum: |
||||
return ClassType.Enum; |
||||
case AST.ClassType.Interface: |
||||
return ClassType.Interface; |
||||
case AST.ClassType.Struct: |
||||
return ClassType.Struct; |
||||
case AST.ClassType.Module: |
||||
return ClassType.Module; |
||||
default: |
||||
return ClassType.Class; |
||||
} |
||||
} |
||||
|
||||
static DomRegion GetRegion(RefParser.Location start, RefParser.Location end) |
||||
{ |
||||
return DomRegion.FromLocation(start, end); |
||||
} |
||||
|
||||
public override object VisitTypeDeclaration(AST.TypeDeclaration typeDeclaration, object data) |
||||
{ |
||||
DomRegion region = GetRegion(typeDeclaration.StartLocation, typeDeclaration.EndLocation); |
||||
DomRegion bodyRegion = GetRegion(typeDeclaration.BodyStartLocation, typeDeclaration.EndLocation); |
||||
|
||||
DefaultClass c = new DefaultClass(cu, TranslateClassType(typeDeclaration.Type), ConvertTypeModifier(typeDeclaration.Modifier), region, GetCurrentClass()); |
||||
if (c.IsStatic) { |
||||
// static classes are also abstract and sealed at the same time
|
||||
c.Modifiers |= ModifierEnum.Abstract | ModifierEnum.Sealed; |
||||
} |
||||
c.BodyRegion = bodyRegion; |
||||
ConvertAttributes(typeDeclaration, c); |
||||
c.Documentation = GetDocumentation(region.BeginLine, typeDeclaration.Attributes); |
||||
|
||||
DefaultClass outerClass = GetCurrentClass(); |
||||
if (outerClass != null) { |
||||
outerClass.InnerClasses.Add(c); |
||||
c.FullyQualifiedName = outerClass.FullyQualifiedName + '.' + typeDeclaration.Name; |
||||
} else { |
||||
c.FullyQualifiedName = PrependCurrentNamespace(typeDeclaration.Name); |
||||
cu.Classes.Add(c); |
||||
} |
||||
c.UsingScope = currentNamespace; |
||||
currentClass.Push(c); |
||||
|
||||
ConvertTemplates(outerClass, typeDeclaration.Templates, c); // resolve constrains in context of the class
|
||||
// templates must be converted before base types because base types may refer to generic types
|
||||
|
||||
if (c.ClassType != ClassType.Enum && typeDeclaration.BaseTypes != null) { |
||||
foreach (AST.TypeReference type in typeDeclaration.BaseTypes) { |
||||
IReturnType rt = CreateReturnType(type, null, TypeVisitor.ReturnTypeOptions.BaseTypeReference); |
||||
if (rt != null) { |
||||
c.BaseTypes.Add(rt); |
||||
} |
||||
} |
||||
} |
||||
|
||||
object ret = typeDeclaration.AcceptChildren(this, data); |
||||
currentClass.Pop(); |
||||
|
||||
if (c.ClassType == ClassType.Module) { |
||||
foreach (DefaultField f in c.Fields) { |
||||
f.Modifiers |= ModifierEnum.Static; |
||||
} |
||||
foreach (DefaultMethod m in c.Methods) { |
||||
m.Modifiers |= ModifierEnum.Static; |
||||
} |
||||
foreach (DefaultProperty p in c.Properties) { |
||||
p.Modifiers |= ModifierEnum.Static; |
||||
} |
||||
foreach (DefaultEvent e in c.Events) { |
||||
e.Modifiers |= ModifierEnum.Static; |
||||
} |
||||
} |
||||
|
||||
return ret; |
||||
} |
||||
|
||||
void ConvertTemplates(DefaultClass outerClass, IList<AST.TemplateDefinition> templateList, DefaultClass c) |
||||
{ |
||||
int outerClassTypeParameterCount = outerClass != null ? outerClass.TypeParameters.Count : 0; |
||||
if (templateList.Count == 0 && outerClassTypeParameterCount == 0) { |
||||
c.TypeParameters = DefaultTypeParameter.EmptyTypeParameterList; |
||||
} else { |
||||
Debug.Assert(c.TypeParameters.Count == 0); |
||||
|
||||
int index = 0; |
||||
if (outerClassTypeParameterCount > 0) { |
||||
foreach (DefaultTypeParameter outerTypeParamter in outerClass.TypeParameters) { |
||||
DefaultTypeParameter p = new DefaultTypeParameter(c, outerTypeParamter.Name, index++); |
||||
p.HasConstructableConstraint = outerTypeParamter.HasConstructableConstraint; |
||||
p.HasReferenceTypeConstraint = outerTypeParamter.HasReferenceTypeConstraint; |
||||
p.HasValueTypeConstraint = outerTypeParamter.HasValueTypeConstraint; |
||||
p.Attributes.AddRange(outerTypeParamter.Attributes); |
||||
p.Constraints.AddRange(outerTypeParamter.Constraints); |
||||
c.TypeParameters.Add(p); |
||||
} |
||||
} |
||||
|
||||
foreach (AST.TemplateDefinition template in templateList) { |
||||
c.TypeParameters.Add(new DefaultTypeParameter(c, template.Name, index++)); |
||||
} |
||||
// converting the constraints requires that the type parameters are already present
|
||||
for (int i = 0; i < templateList.Count; i++) { |
||||
ConvertConstraints(templateList[i], (DefaultTypeParameter)c.TypeParameters[i + outerClassTypeParameterCount]); |
||||
} |
||||
} |
||||
} |
||||
|
||||
void ConvertTemplates(List<AST.TemplateDefinition> templateList, DefaultMethod m) |
||||
{ |
||||
int index = 0; |
||||
if (templateList.Count == 0) { |
||||
m.TypeParameters = DefaultTypeParameter.EmptyTypeParameterList; |
||||
} else { |
||||
Debug.Assert(m.TypeParameters.Count == 0); |
||||
foreach (AST.TemplateDefinition template in templateList) { |
||||
m.TypeParameters.Add(new DefaultTypeParameter(m, template.Name, index++)); |
||||
} |
||||
// converting the constraints requires that the type parameters are already present
|
||||
for (int i = 0; i < templateList.Count; i++) { |
||||
ConvertConstraints(templateList[i], (DefaultTypeParameter)m.TypeParameters[i]); |
||||
} |
||||
} |
||||
} |
||||
|
||||
void ConvertConstraints(AST.TemplateDefinition template, DefaultTypeParameter typeParameter) |
||||
{ |
||||
foreach (AST.TypeReference typeRef in template.Bases) { |
||||
if (typeRef == AST.TypeReference.NewConstraint) { |
||||
typeParameter.HasConstructableConstraint = true; |
||||
} else if (typeRef == AST.TypeReference.ClassConstraint) { |
||||
typeParameter.HasReferenceTypeConstraint = true; |
||||
} else if (typeRef == AST.TypeReference.StructConstraint) { |
||||
typeParameter.HasValueTypeConstraint = true; |
||||
} else { |
||||
IReturnType rt = CreateReturnType(typeRef, typeParameter.Method, TypeVisitor.ReturnTypeOptions.None); |
||||
if (rt != null) { |
||||
typeParameter.Constraints.Add(rt); |
||||
} |
||||
} |
||||
} |
||||
} |
||||
|
||||
public override object VisitDelegateDeclaration(AST.DelegateDeclaration delegateDeclaration, object data) |
||||
{ |
||||
DomRegion region = GetRegion(delegateDeclaration.StartLocation, delegateDeclaration.EndLocation); |
||||
DefaultClass c = new DefaultClass(cu, ClassType.Delegate, ConvertTypeModifier(delegateDeclaration.Modifier), region, GetCurrentClass()); |
||||
c.Documentation = GetDocumentation(region.BeginLine, delegateDeclaration.Attributes); |
||||
ConvertAttributes(delegateDeclaration, c); |
||||
CreateDelegate(c, delegateDeclaration.Name, delegateDeclaration.ReturnType, |
||||
delegateDeclaration.Templates, delegateDeclaration.Parameters); |
||||
return c; |
||||
} |
||||
|
||||
void CreateDelegate(DefaultClass c, string name, AST.TypeReference returnType, IList<AST.TemplateDefinition> templates, IList<AST.ParameterDeclarationExpression> parameters) |
||||
{ |
||||
c.BaseTypes.Add(c.ProjectContent.SystemTypes.MulticastDelegate); |
||||
DefaultClass outerClass = GetCurrentClass(); |
||||
if (outerClass != null) { |
||||
outerClass.InnerClasses.Add(c); |
||||
c.FullyQualifiedName = outerClass.FullyQualifiedName + '.' + name; |
||||
} else { |
||||
c.FullyQualifiedName = PrependCurrentNamespace(name); |
||||
cu.Classes.Add(c); |
||||
} |
||||
c.UsingScope = currentNamespace; |
||||
currentClass.Push(c); // necessary for CreateReturnType
|
||||
ConvertTemplates(outerClass, templates, c); |
||||
|
||||
List<IParameter> p = new List<IParameter>(); |
||||
if (parameters != null) { |
||||
foreach (AST.ParameterDeclarationExpression param in parameters) { |
||||
p.Add(CreateParameter(param)); |
||||
} |
||||
} |
||||
AnonymousMethodReturnType.AddDefaultDelegateMethod(c, CreateReturnType(returnType), p); |
||||
|
||||
currentClass.Pop(); |
||||
} |
||||
|
||||
IParameter CreateParameter(AST.ParameterDeclarationExpression par) |
||||
{ |
||||
return CreateParameter(par, null); |
||||
} |
||||
|
||||
IParameter CreateParameter(AST.ParameterDeclarationExpression par, IMethod method) |
||||
{ |
||||
return CreateParameter(par, method, GetCurrentClass(), cu); |
||||
} |
||||
|
||||
internal static IParameter CreateParameter(AST.ParameterDeclarationExpression par, IMethod method, IClass currentClass, ICompilationUnit cu) |
||||
{ |
||||
IReturnType parType = CreateReturnType(par.TypeReference, method, currentClass, cu, TypeVisitor.ReturnTypeOptions.None); |
||||
DefaultParameter p = new DefaultParameter(par.ParameterName, parType, GetRegion(par.StartLocation, par.EndLocation)); |
||||
p.Modifiers = (ParameterModifiers)par.ParamModifier; |
||||
return p; |
||||
} |
||||
|
||||
public override object VisitMethodDeclaration(AST.MethodDeclaration methodDeclaration, object data) |
||||
{ |
||||
DomRegion region = GetRegion(methodDeclaration.StartLocation, methodDeclaration.EndLocation); |
||||
DomRegion bodyRegion = GetRegion(methodDeclaration.EndLocation, methodDeclaration.Body != null ? methodDeclaration.Body.EndLocation : RefParser.Location.Empty); |
||||
DefaultClass currentClass = GetCurrentClass(); |
||||
|
||||
DefaultMethod method = new DefaultMethod(methodDeclaration.Name, null, ConvertModifier(methodDeclaration.Modifier), region, bodyRegion, currentClass); |
||||
method.Documentation = GetDocumentation(region.BeginLine, methodDeclaration.Attributes); |
||||
ConvertTemplates(methodDeclaration.Templates, method); |
||||
method.ReturnType = CreateReturnType(methodDeclaration.TypeReference, method, TypeVisitor.ReturnTypeOptions.None); |
||||
ConvertAttributes(methodDeclaration, method); |
||||
method.IsExtensionMethod = methodDeclaration.IsExtensionMethod |
||||
|| method.Attributes.Any(att => att.AttributeType != null && att.AttributeType.FullyQualifiedName == "System.Runtime.CompilerServices.ExtensionAttribute"); |
||||
if (methodDeclaration.Parameters.Count > 0) { |
||||
foreach (AST.ParameterDeclarationExpression par in methodDeclaration.Parameters) { |
||||
method.Parameters.Add(CreateParameter(par, method)); |
||||
} |
||||
} else { |
||||
method.Parameters = DefaultParameter.EmptyParameterList; |
||||
} |
||||
if (methodDeclaration.HandlesClause.Count > 0) { |
||||
foreach (string handlesClause in methodDeclaration.HandlesClause) { |
||||
if (handlesClause.ToLowerInvariant().StartsWith("me.")) |
||||
method.HandlesClauses.Add(handlesClause.Substring(3)); |
||||
else if (handlesClause.ToLowerInvariant().StartsWith("mybase.")) |
||||
method.HandlesClauses.Add(handlesClause.Substring(7)); |
||||
else |
||||
method.HandlesClauses.Add(handlesClause); |
||||
} |
||||
} else { |
||||
method.HandlesClauses = EmptyList<string>.Instance; |
||||
} |
||||
|
||||
AddInterfaceImplementations(method, methodDeclaration); |
||||
|
||||
currentClass.Methods.Add(method); |
||||
return null; |
||||
} |
||||
|
||||
public override object VisitDeclareDeclaration(AST.DeclareDeclaration declareDeclaration, object data) |
||||
{ |
||||
DefaultClass currentClass = GetCurrentClass(); |
||||
|
||||
DomRegion region = GetRegion(declareDeclaration.StartLocation, declareDeclaration.EndLocation); |
||||
DefaultMethod method = new DefaultMethod(declareDeclaration.Name, null, ConvertModifier(declareDeclaration.Modifier), region, DomRegion.Empty, currentClass); |
||||
method.Documentation = GetDocumentation(region.BeginLine, declareDeclaration.Attributes); |
||||
method.Modifiers |= ModifierEnum.Extern | ModifierEnum.Static; |
||||
|
||||
method.ReturnType = CreateReturnType(declareDeclaration.TypeReference, method, TypeVisitor.ReturnTypeOptions.None); |
||||
ConvertAttributes(declareDeclaration, method); |
||||
|
||||
foreach (AST.ParameterDeclarationExpression par in declareDeclaration.Parameters) { |
||||
method.Parameters.Add(CreateParameter(par, method)); |
||||
} |
||||
|
||||
currentClass.Methods.Add(method); |
||||
return null; |
||||
} |
||||
|
||||
public override object VisitOperatorDeclaration(AST.OperatorDeclaration operatorDeclaration, object data) |
||||
{ |
||||
DefaultClass c = GetCurrentClass(); |
||||
DomRegion region = GetRegion(operatorDeclaration.StartLocation, operatorDeclaration.EndLocation); |
||||
DomRegion bodyRegion = GetRegion(operatorDeclaration.EndLocation, operatorDeclaration.Body != null ? operatorDeclaration.Body.EndLocation : RefParser.Location.Empty); |
||||
|
||||
DefaultMethod method = new DefaultMethod(operatorDeclaration.Name, CreateReturnType(operatorDeclaration.TypeReference), ConvertModifier(operatorDeclaration.Modifier), region, bodyRegion, c); |
||||
method.Documentation = GetDocumentation(region.BeginLine, operatorDeclaration.Attributes); |
||||
ConvertAttributes(operatorDeclaration, method); |
||||
if(operatorDeclaration.Parameters != null) |
||||
{ |
||||
foreach (AST.ParameterDeclarationExpression par in operatorDeclaration.Parameters) { |
||||
method.Parameters.Add(CreateParameter(par, method)); |
||||
} |
||||
} |
||||
AddInterfaceImplementations(method, operatorDeclaration); |
||||
c.Methods.Add(method); |
||||
return null; |
||||
} |
||||
|
||||
public override object VisitConstructorDeclaration(AST.ConstructorDeclaration constructorDeclaration, object data) |
||||
{ |
||||
DomRegion region = GetRegion(constructorDeclaration.StartLocation, constructorDeclaration.EndLocation); |
||||
DomRegion bodyRegion = GetRegion(constructorDeclaration.EndLocation, constructorDeclaration.Body != null ? constructorDeclaration.Body.EndLocation : RefParser.Location.Empty); |
||||
DefaultClass c = GetCurrentClass(); |
||||
|
||||
Constructor constructor = new Constructor(ConvertModifier(constructorDeclaration.Modifier), region, bodyRegion, GetCurrentClass()); |
||||
constructor.Documentation = GetDocumentation(region.BeginLine, constructorDeclaration.Attributes); |
||||
ConvertAttributes(constructorDeclaration, constructor); |
||||
if (constructorDeclaration.Parameters != null) { |
||||
foreach (AST.ParameterDeclarationExpression par in constructorDeclaration.Parameters) { |
||||
constructor.Parameters.Add(CreateParameter(par)); |
||||
} |
||||
} |
||||
|
||||
if (constructor.Modifiers.HasFlag(ModifierEnum.Static)) |
||||
constructor.Modifiers = ConvertModifier(constructorDeclaration.Modifier, ModifierEnum.None); |
||||
|
||||
c.Methods.Add(constructor); |
||||
return null; |
||||
} |
||||
|
||||
public override object VisitDestructorDeclaration(AST.DestructorDeclaration destructorDeclaration, object data) |
||||
{ |
||||
DomRegion region = GetRegion(destructorDeclaration.StartLocation, destructorDeclaration.EndLocation); |
||||
DomRegion bodyRegion = GetRegion(destructorDeclaration.EndLocation, destructorDeclaration.Body != null ? destructorDeclaration.Body.EndLocation : RefParser.Location.Empty); |
||||
|
||||
DefaultClass c = GetCurrentClass(); |
||||
|
||||
Destructor destructor = new Destructor(region, bodyRegion, c); |
||||
ConvertAttributes(destructorDeclaration, destructor); |
||||
c.Methods.Add(destructor); |
||||
return null; |
||||
} |
||||
|
||||
bool IsVisualBasic { |
||||
get { |
||||
return cu.ProjectContent.Language == LanguageProperties.VBNet; |
||||
} |
||||
} |
||||
|
||||
public override object VisitFieldDeclaration(AST.FieldDeclaration fieldDeclaration, object data) |
||||
{ |
||||
DomRegion region = GetRegion(fieldDeclaration.StartLocation, fieldDeclaration.EndLocation); |
||||
DefaultClass c = GetCurrentClass(); |
||||
ModifierEnum modifier = ConvertModifier(fieldDeclaration.Modifier, |
||||
(c.ClassType == ClassType.Struct && this.IsVisualBasic) |
||||
? ModifierEnum.Public : ModifierEnum.Private); |
||||
string doku = GetDocumentation(region.BeginLine, fieldDeclaration.Attributes); |
||||
if (currentClass.Count > 0) { |
||||
for (int i = 0; i < fieldDeclaration.Fields.Count; ++i) { |
||||
AST.VariableDeclaration field = (AST.VariableDeclaration)fieldDeclaration.Fields[i]; |
||||
|
||||
IReturnType retType; |
||||
if (c.ClassType == ClassType.Enum) { |
||||
retType = c.DefaultReturnType; |
||||
} else { |
||||
retType = CreateReturnType(fieldDeclaration.GetTypeForField(i)); |
||||
if (!field.FixedArrayInitialization.IsNull) |
||||
retType = new ArrayReturnType(cu.ProjectContent, retType, 1); |
||||
} |
||||
DefaultField f = new DefaultField(retType, field.Name, modifier, region, c); |
||||
ConvertAttributes(fieldDeclaration, f); |
||||
f.Documentation = doku; |
||||
if (c.ClassType == ClassType.Enum) { |
||||
f.Modifiers = ModifierEnum.Const | ModifierEnum.Public; |
||||
} |
||||
|
||||
c.Fields.Add(f); |
||||
} |
||||
} |
||||
return null; |
||||
} |
||||
|
||||
public override object VisitPropertyDeclaration(AST.PropertyDeclaration propertyDeclaration, object data) |
||||
{ |
||||
DomRegion region = GetRegion(propertyDeclaration.StartLocation, propertyDeclaration.EndLocation); |
||||
DomRegion bodyRegion = GetRegion(propertyDeclaration.BodyStart, propertyDeclaration.BodyEnd); |
||||
|
||||
IReturnType type = CreateReturnType(propertyDeclaration.TypeReference); |
||||
DefaultClass c = GetCurrentClass(); |
||||
|
||||
DefaultProperty property = new DefaultProperty(propertyDeclaration.Name, type, ConvertModifier(propertyDeclaration.Modifier), region, bodyRegion, GetCurrentClass()); |
||||
if (propertyDeclaration.HasGetRegion) { |
||||
property.GetterRegion = GetRegion(propertyDeclaration.GetRegion.StartLocation, propertyDeclaration.GetRegion.EndLocation); |
||||
property.CanGet = true; |
||||
property.GetterModifiers = ConvertModifier(propertyDeclaration.GetRegion.Modifier, ModifierEnum.None); |
||||
} |
||||
if (propertyDeclaration.HasSetRegion) { |
||||
property.SetterRegion = GetRegion(propertyDeclaration.SetRegion.StartLocation, propertyDeclaration.SetRegion.EndLocation); |
||||
property.CanSet = true; |
||||
property.SetterModifiers = ConvertModifier(propertyDeclaration.SetRegion.Modifier, ModifierEnum.None); |
||||
} |
||||
property.Documentation = GetDocumentation(region.BeginLine, propertyDeclaration.Attributes); |
||||
ConvertAttributes(propertyDeclaration, property); |
||||
|
||||
property.IsIndexer = propertyDeclaration.IsIndexer; |
||||
|
||||
if (propertyDeclaration.Parameters != null) { |
||||
foreach (AST.ParameterDeclarationExpression par in propertyDeclaration.Parameters) { |
||||
property.Parameters.Add(CreateParameter(par)); |
||||
} |
||||
} |
||||
// If an IndexerNameAttribute is specified, use the specified name
|
||||
// for the indexer instead of the default name.
|
||||
IAttribute indexerNameAttribute = property.Attributes.LastOrDefault(this.IsIndexerNameAttribute); |
||||
if (indexerNameAttribute != null && indexerNameAttribute.PositionalArguments.Count > 0) { |
||||
string name = indexerNameAttribute.PositionalArguments[0] as string; |
||||
if (!String.IsNullOrEmpty(name)) { |
||||
property.FullyQualifiedName = String.Concat(property.DeclaringType.FullyQualifiedName, ".", name); |
||||
} |
||||
} |
||||
|
||||
AddInterfaceImplementations(property, propertyDeclaration); |
||||
c.Properties.Add(property); |
||||
return null; |
||||
} |
||||
|
||||
bool IsIndexerNameAttribute(IAttribute att) |
||||
{ |
||||
if (att == null || att.AttributeType == null) |
||||
return false; |
||||
string indexerNameAttributeFullName = typeof(System.Runtime.CompilerServices.IndexerNameAttribute).FullName; |
||||
IClass indexerNameAttributeClass = this.Cu.ProjectContent.GetClass(indexerNameAttributeFullName, 0, LanguageProperties.CSharp, GetClassOptions.Default | GetClassOptions.ExactMatch); |
||||
if (indexerNameAttributeClass == null) { |
||||
return String.Equals(att.AttributeType.FullyQualifiedName, indexerNameAttributeFullName, StringComparison.Ordinal); |
||||
} |
||||
return att.AttributeType.Equals(indexerNameAttributeClass.DefaultReturnType); |
||||
} |
||||
|
||||
public override object VisitEventDeclaration(AST.EventDeclaration eventDeclaration, object data) |
||||
{ |
||||
DomRegion region = GetRegion(eventDeclaration.StartLocation, eventDeclaration.EndLocation); |
||||
DomRegion bodyRegion = GetRegion(eventDeclaration.BodyStart, eventDeclaration.BodyEnd); |
||||
DefaultClass c = GetCurrentClass(); |
||||
|
||||
IReturnType type; |
||||
if (eventDeclaration.TypeReference.IsNull) { |
||||
DefaultClass del = new DefaultClass(cu, ClassType.Delegate, |
||||
ConvertModifier(eventDeclaration.Modifier), |
||||
region, c); |
||||
del.Modifiers |= ModifierEnum.Synthetic; |
||||
CreateDelegate(del, eventDeclaration.Name + "EventHandler", |
||||
new AST.TypeReference("System.Void", true), |
||||
new AST.TemplateDefinition[0], |
||||
eventDeclaration.Parameters); |
||||
type = del.DefaultReturnType; |
||||
} else { |
||||
type = CreateReturnType(eventDeclaration.TypeReference); |
||||
} |
||||
DefaultEvent e = new DefaultEvent(eventDeclaration.Name, type, ConvertModifier(eventDeclaration.Modifier), region, bodyRegion, c); |
||||
ConvertAttributes(eventDeclaration, e); |
||||
AddInterfaceImplementations(e, eventDeclaration); |
||||
c.Events.Add(e); |
||||
|
||||
e.Documentation = GetDocumentation(region.BeginLine, eventDeclaration.Attributes); |
||||
if (eventDeclaration.HasAddRegion) { |
||||
e.AddMethod = new DefaultMethod(e.DeclaringType, "add_" + e.Name) { |
||||
Parameters = { new DefaultParameter("value", e.ReturnType, DomRegion.Empty) }, |
||||
Region = GetRegion(eventDeclaration.AddRegion.StartLocation, eventDeclaration.AddRegion.EndLocation), |
||||
BodyRegion = GetRegion(eventDeclaration.AddRegion.Block.StartLocation, eventDeclaration.AddRegion.Block.EndLocation) |
||||
}; |
||||
} |
||||
if (eventDeclaration.HasRemoveRegion) { |
||||
e.RemoveMethod = new DefaultMethod(e.DeclaringType, "remove_" + e.Name) { |
||||
Parameters = { new DefaultParameter("value", e.ReturnType, DomRegion.Empty) }, |
||||
Region = GetRegion(eventDeclaration.RemoveRegion.StartLocation, eventDeclaration.RemoveRegion.EndLocation), |
||||
BodyRegion = GetRegion(eventDeclaration.RemoveRegion.Block.StartLocation, eventDeclaration.RemoveRegion.Block.EndLocation) |
||||
}; |
||||
} |
||||
return null; |
||||
} |
||||
|
||||
void AddInterfaceImplementations(AbstractMember member, AST.MemberNode memberNode) |
||||
{ |
||||
member.InterfaceImplementations.AddRange( |
||||
memberNode.InterfaceImplementations |
||||
.Select(x => new ExplicitInterfaceImplementation(CreateReturnType(x.InterfaceType), x.MemberName)) |
||||
); |
||||
if (!IsVisualBasic && member.InterfaceImplementations.Any()) { |
||||
member.Modifiers = ConvertModifier(memberNode.Modifier, ModifierEnum.None); |
||||
} |
||||
} |
||||
|
||||
IReturnType CreateReturnType(AST.TypeReference reference, IMethod method, TypeVisitor.ReturnTypeOptions options) |
||||
{ |
||||
return CreateReturnType(reference, method, GetCurrentClass(), cu, options); |
||||
} |
||||
|
||||
static IReturnType CreateReturnType(AST.TypeReference reference, IMethod method, IClass currentClass, ICompilationUnit cu, TypeVisitor.ReturnTypeOptions options) |
||||
{ |
||||
if (currentClass == null) { |
||||
return TypeVisitor.CreateReturnType(reference, new DefaultClass(cu, "___DummyClass"), method, 1, 1, cu.ProjectContent, options | TypeVisitor.ReturnTypeOptions.Lazy); |
||||
} else { |
||||
return TypeVisitor.CreateReturnType(reference, currentClass, method, currentClass.Region.BeginLine + 1, 1, cu.ProjectContent, options | TypeVisitor.ReturnTypeOptions.Lazy); |
||||
} |
||||
} |
||||
|
||||
IReturnType CreateReturnType(AST.TypeReference reference) |
||||
{ |
||||
return CreateReturnType(reference, null, TypeVisitor.ReturnTypeOptions.None); |
||||
} |
||||
} |
||||
} |
||||
@ -0,0 +1,38 @@
@@ -0,0 +1,38 @@
|
||||
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
|
||||
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
|
||||
|
||||
using System; |
||||
using ICSharpCode.NRefactory; |
||||
using ICSharpCode.NRefactory.Ast; |
||||
|
||||
namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver |
||||
{ |
||||
public class NRefactoryInformationProvider : IEnvironmentInformationProvider |
||||
{ |
||||
IProjectContent _projectContent; |
||||
|
||||
public NRefactoryInformationProvider(IProjectContent projectContent) |
||||
{ |
||||
if (projectContent == null) |
||||
throw new ArgumentNullException("projectContent"); |
||||
_projectContent = projectContent; |
||||
} |
||||
|
||||
public bool HasField(string reflectionTypeName, int typeParameterCount, string fieldName) |
||||
{ |
||||
IClass c; |
||||
if (typeParameterCount > 0) { |
||||
c = _projectContent.GetClass(reflectionTypeName, typeParameterCount); |
||||
} else { |
||||
c = _projectContent.GetClassByReflectionName(reflectionTypeName, true); |
||||
} |
||||
if (c == null) |
||||
return false; |
||||
foreach (IField field in c.DefaultReturnType.GetFields()) { |
||||
if (field.Name == fieldName) |
||||
return true; |
||||
} |
||||
return false; |
||||
} |
||||
} |
||||
} |
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue