283 changed files with 25126 additions and 16164 deletions
@ -1,189 +0,0 @@
@@ -1,189 +0,0 @@
|
||||
// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy of this
|
||||
// software and associated documentation files (the "Software"), to deal in the Software
|
||||
// without restriction, including without limitation the rights to use, copy, modify, merge,
|
||||
// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
|
||||
// to whom the Software is furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all copies or
|
||||
// substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
||||
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
|
||||
// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
|
||||
// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
|
||||
using System; |
||||
using System.Collections.Generic; |
||||
using System.Linq; |
||||
using ICSharpCode.NRefactory; |
||||
using ICSharpCode.NRefactory.TypeSystem; |
||||
using Mono.Cecil; |
||||
|
||||
namespace ICSharpCode.Decompiler.Ast |
||||
{ |
||||
/// <summary>
|
||||
/// ITypeResolveContext implementation that lazily loads types from Cecil.
|
||||
/// </summary>
|
||||
public class CecilTypeResolveContext : AbstractAnnotatable, ISynchronizedTypeResolveContext, IProjectContent |
||||
{ |
||||
readonly ModuleDefinition module; |
||||
readonly string[] namespaces; |
||||
readonly CecilLoader loader; |
||||
Dictionary<TypeDefinition, WeakReference> dict = new Dictionary<TypeDefinition, WeakReference>(); |
||||
int countUntilNextCleanup = 4; |
||||
|
||||
public CecilTypeResolveContext(ModuleDefinition module) |
||||
{ |
||||
this.loader = new CecilLoader(); |
||||
this.loader.IncludeInternalMembers = true; |
||||
this.module = module; |
||||
this.namespaces = module.Types.Select(t => t.Namespace).Distinct().ToArray(); |
||||
|
||||
List<IAttribute> assemblyAttributes = new List<IAttribute>(); |
||||
foreach (var attr in module.Assembly.CustomAttributes) { |
||||
assemblyAttributes.Add(loader.ReadAttribute(attr)); |
||||
} |
||||
this.AssemblyAttributes = assemblyAttributes.AsReadOnly(); |
||||
} |
||||
|
||||
ITypeDefinition GetClass(TypeDefinition cecilType) |
||||
{ |
||||
lock (dict) { |
||||
WeakReference wr; |
||||
ITypeDefinition type; |
||||
if (dict.TryGetValue(cecilType, out wr)) { |
||||
type = (ITypeDefinition)wr.Target; |
||||
} else { |
||||
wr = null; |
||||
type = null; |
||||
} |
||||
if (type == null) { |
||||
type = loader.LoadType(cecilType, this); |
||||
} |
||||
if (wr == null) { |
||||
if (--countUntilNextCleanup <= 0) |
||||
CleanupDict(); |
||||
wr = new WeakReference(type); |
||||
dict.Add(cecilType, wr); |
||||
} else { |
||||
wr.Target = type; |
||||
} |
||||
return type; |
||||
} |
||||
} |
||||
|
||||
void CleanupDict() |
||||
{ |
||||
List<TypeDefinition> deletedKeys = new List<TypeDefinition>(); |
||||
foreach (var pair in dict) { |
||||
if (!pair.Value.IsAlive) { |
||||
deletedKeys.Add(pair.Key); |
||||
} |
||||
} |
||||
foreach (var key in deletedKeys) { |
||||
dict.Remove(key); |
||||
} |
||||
countUntilNextCleanup = dict.Count + 4; |
||||
} |
||||
|
||||
public string AssemblyName { |
||||
get { return module.Assembly.Name.Name; } |
||||
} |
||||
|
||||
public IList<IAttribute> ModuleAttributes { get; private set; } |
||||
|
||||
public IList<IAttribute> AssemblyAttributes { get; private set; } |
||||
|
||||
public ITypeDefinition GetTypeDefinition(string nameSpace, string name, int typeParameterCount, StringComparer nameComparer) |
||||
{ |
||||
if (typeParameterCount > 0) |
||||
name = name + "`" + typeParameterCount.ToString(); |
||||
if (nameComparer == StringComparer.Ordinal) { |
||||
TypeDefinition cecilType = module.GetType(nameSpace, name); |
||||
if (cecilType != null) |
||||
return GetClass(cecilType); |
||||
else |
||||
return null; |
||||
} |
||||
foreach (TypeDefinition cecilType in module.Types) { |
||||
if (nameComparer.Equals(name, cecilType.Name) |
||||
&& nameComparer.Equals(nameSpace, cecilType.Namespace) |
||||
&& cecilType.GenericParameters.Count == typeParameterCount) |
||||
{ |
||||
return GetClass(cecilType); |
||||
} |
||||
} |
||||
return null; |
||||
} |
||||
|
||||
public ITypeDefinition GetKnownTypeDefinition(TypeCode typeCode) |
||||
{ |
||||
return GetTypeDefinition("System", ReflectionHelper.GetShortNameByTypeCode(typeCode), 0, StringComparer.Ordinal); |
||||
} |
||||
|
||||
public IEnumerable<ITypeDefinition> GetTypes() |
||||
{ |
||||
foreach (TypeDefinition cecilType in module.Types) { |
||||
yield return GetClass(cecilType); |
||||
} |
||||
} |
||||
|
||||
public IEnumerable<ITypeDefinition> GetTypes(string nameSpace, StringComparer nameComparer) |
||||
{ |
||||
foreach (TypeDefinition cecilType in module.Types) { |
||||
if (nameComparer.Equals(nameSpace, cecilType.Namespace)) |
||||
yield return GetClass(cecilType); |
||||
} |
||||
} |
||||
|
||||
public IEnumerable<string> GetNamespaces() |
||||
{ |
||||
return namespaces; |
||||
} |
||||
|
||||
public string GetNamespace(string nameSpace, StringComparer nameComparer) |
||||
{ |
||||
foreach (string ns in namespaces) { |
||||
if (nameComparer.Equals(ns, nameSpace)) |
||||
return ns; |
||||
} |
||||
return null; |
||||
} |
||||
|
||||
ICSharpCode.NRefactory.Utils.CacheManager ITypeResolveContext.CacheManager { |
||||
get { |
||||
// We don't support caching
|
||||
return null; |
||||
} |
||||
} |
||||
|
||||
ISynchronizedTypeResolveContext ITypeResolveContext.Synchronize() |
||||
{ |
||||
// This class is logically immutable
|
||||
return this; |
||||
} |
||||
|
||||
void IDisposable.Dispose() |
||||
{ |
||||
// exit from Synchronize() block
|
||||
} |
||||
|
||||
IEnumerable<IParsedFile> IProjectContent.Files { |
||||
get { return new IParsedFile[0]; } |
||||
} |
||||
|
||||
void IProjectContent.UpdateProjectContent(IParsedFile oldFile, IParsedFile newFile) |
||||
{ |
||||
throw new NotSupportedException(); |
||||
} |
||||
|
||||
IParsedFile IProjectContent.GetFile(string fileName) |
||||
{ |
||||
return null; |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,117 @@
@@ -0,0 +1,117 @@
|
||||
//
|
||||
// PreProcessorDirective.cs
|
||||
//
|
||||
// Author:
|
||||
// Mike Krüger <mkrueger@xamarin.com>
|
||||
//
|
||||
// Copyright (c) 2011 Xamarin Inc.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
using System; |
||||
|
||||
namespace ICSharpCode.NRefactory.CSharp |
||||
{ |
||||
public enum PreProcessorDirectiveType : byte |
||||
{ |
||||
Invalid = 0, |
||||
Region = 1, |
||||
Endregion = 2, |
||||
|
||||
If = 3, |
||||
Endif = 4, |
||||
Elif = 5, |
||||
Else = 6, |
||||
|
||||
Define = 7, |
||||
Undef = 8, |
||||
Error = 9, |
||||
Warning = 10, |
||||
Pragma = 11, |
||||
Line = 12 |
||||
} |
||||
|
||||
public class PreProcessorDirective : AstNode, IRelocatable |
||||
{ |
||||
public override NodeType NodeType { |
||||
get { |
||||
return NodeType.Whitespace; |
||||
} |
||||
} |
||||
|
||||
public PreProcessorDirectiveType Type { |
||||
get; |
||||
set; |
||||
} |
||||
|
||||
public string Argument { |
||||
get; |
||||
set; |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// For an '#if' directive, specifies whether the condition evaluated to true.
|
||||
/// </summary>
|
||||
public bool Take { |
||||
get; |
||||
set; |
||||
} |
||||
|
||||
TextLocation startLocation; |
||||
public override TextLocation StartLocation { |
||||
get { |
||||
return startLocation; |
||||
} |
||||
} |
||||
|
||||
TextLocation endLocation; |
||||
public override TextLocation EndLocation { |
||||
get { |
||||
return endLocation; |
||||
} |
||||
} |
||||
|
||||
public PreProcessorDirective (PreProcessorDirectiveType type, TextLocation startLocation, TextLocation endLocation) |
||||
{ |
||||
this.Type = type; |
||||
this.startLocation = startLocation; |
||||
this.endLocation = endLocation; |
||||
} |
||||
|
||||
#region IRelocationable implementation
|
||||
void IRelocatable.SetStartLocation (TextLocation startLocation) |
||||
{ |
||||
int lineDelta = startLocation.Line - this.startLocation.Line; |
||||
endLocation = new TextLocation (endLocation.Line + lineDelta, lineDelta != 0 ? endLocation.Column : endLocation.Column + startLocation.Column - this.startLocation.Column); |
||||
this.startLocation = startLocation; |
||||
} |
||||
#endregion
|
||||
|
||||
public override S AcceptVisitor<T, S> (IAstVisitor<T, S> visitor, T data = default(T)) |
||||
{ |
||||
return visitor.VisitPreProcessorDirective (this, data); |
||||
} |
||||
|
||||
protected internal override bool DoMatch(AstNode other, PatternMatching.Match match) |
||||
{ |
||||
PreProcessorDirective o = other as PreProcessorDirective; |
||||
return o != null && Type == o.Type && MatchString(Argument, o.Argument); |
||||
} |
||||
} |
||||
} |
||||
|
@ -0,0 +1,170 @@
@@ -0,0 +1,170 @@
|
||||
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy of this
|
||||
// software and associated documentation files (the "Software"), to deal in the Software
|
||||
// without restriction, including without limitation the rights to use, copy, modify, merge,
|
||||
// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
|
||||
// to whom the Software is furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all copies or
|
||||
// substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
||||
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
|
||||
// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
|
||||
// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
|
||||
using System; |
||||
using System.Collections.Generic; |
||||
using System.Linq; |
||||
using System.Runtime.Serialization; |
||||
using ICSharpCode.NRefactory.CSharp.TypeSystem; |
||||
using ICSharpCode.NRefactory.TypeSystem; |
||||
using ICSharpCode.NRefactory.TypeSystem.Implementation; |
||||
using ICSharpCode.NRefactory.Utils; |
||||
|
||||
namespace ICSharpCode.NRefactory.CSharp |
||||
{ |
||||
[Serializable] |
||||
public class CSharpProjectContent : IProjectContent |
||||
{ |
||||
string assemblyName; |
||||
Dictionary<string, IParsedFile> parsedFiles; |
||||
List<IAssemblyReference> assemblyReferences; |
||||
|
||||
public CSharpProjectContent() |
||||
{ |
||||
this.assemblyName = string.Empty; |
||||
this.parsedFiles = new Dictionary<string, IParsedFile>(Platform.FileNameComparer); |
||||
this.assemblyReferences = new List<IAssemblyReference>(); |
||||
} |
||||
|
||||
protected CSharpProjectContent(CSharpProjectContent pc) |
||||
{ |
||||
this.assemblyName = pc.assemblyName; |
||||
this.parsedFiles = new Dictionary<string, IParsedFile>(pc.parsedFiles); |
||||
this.assemblyReferences = new List<IAssemblyReference>(pc.assemblyReferences); |
||||
} |
||||
|
||||
public IEnumerable<IParsedFile> Files { |
||||
get { return parsedFiles.Values; } |
||||
} |
||||
|
||||
public IEnumerable<IAssemblyReference> AssemblyReferences { |
||||
get { return assemblyReferences; } |
||||
} |
||||
|
||||
public string AssemblyName { |
||||
get { return assemblyName; } |
||||
} |
||||
|
||||
public IEnumerable<IUnresolvedAttribute> AssemblyAttributes { |
||||
get { |
||||
return this.Files.SelectMany(f => f.AssemblyAttributes); |
||||
} |
||||
} |
||||
|
||||
public IEnumerable<IUnresolvedAttribute> ModuleAttributes { |
||||
get { |
||||
return this.Files.SelectMany(f => f.ModuleAttributes); |
||||
} |
||||
} |
||||
|
||||
public IEnumerable<IUnresolvedTypeDefinition> TopLevelTypeDefinitions { |
||||
get { |
||||
return this.Files.SelectMany(f => f.TopLevelTypeDefinitions); |
||||
} |
||||
} |
||||
|
||||
public IParsedFile GetFile(string fileName) |
||||
{ |
||||
IParsedFile file; |
||||
if (parsedFiles.TryGetValue(fileName, out file)) |
||||
return file; |
||||
else |
||||
return null; |
||||
} |
||||
|
||||
public ICompilation CreateCompilation() |
||||
{ |
||||
var solutionSnapshot = new DefaultSolutionSnapshot(); |
||||
ICompilation compilation = new SimpleCompilation(solutionSnapshot, this, assemblyReferences); |
||||
solutionSnapshot.AddCompilation(this, compilation); |
||||
return compilation; |
||||
} |
||||
|
||||
public ICompilation CreateCompilation(ISolutionSnapshot solutionSnapshot) |
||||
{ |
||||
return new SimpleCompilation(solutionSnapshot, this, assemblyReferences); |
||||
} |
||||
|
||||
public IProjectContent SetAssemblyName(string newAssemblyName) |
||||
{ |
||||
CSharpProjectContent pc = new CSharpProjectContent(this); |
||||
pc.assemblyName = newAssemblyName; |
||||
return pc; |
||||
} |
||||
|
||||
public IProjectContent AddAssemblyReferences(IEnumerable<IAssemblyReference> references) |
||||
{ |
||||
CSharpProjectContent pc = new CSharpProjectContent(this); |
||||
pc.assemblyReferences.AddRange(references); |
||||
return pc; |
||||
} |
||||
|
||||
public IProjectContent RemoveAssemblyReferences(IEnumerable<IAssemblyReference> references) |
||||
{ |
||||
CSharpProjectContent pc = new CSharpProjectContent(this); |
||||
pc.assemblyReferences.RemoveAll(r => references.Contains(r)); |
||||
return pc; |
||||
} |
||||
|
||||
public IProjectContent UpdateProjectContent(IParsedFile oldFile, IParsedFile newFile) |
||||
{ |
||||
if (oldFile == null && newFile == null) |
||||
return this; |
||||
if (oldFile != null && newFile != null) { |
||||
if (!Platform.FileNameComparer.Equals(oldFile.FileName, newFile.FileName)) |
||||
throw new ArgumentException("When both oldFile and newFile are specified, they must use the same file name."); |
||||
} |
||||
CSharpProjectContent pc = new CSharpProjectContent(this); |
||||
if (newFile == null) |
||||
pc.parsedFiles.Remove(oldFile.FileName); |
||||
else |
||||
pc.parsedFiles[newFile.FileName] = newFile; |
||||
return pc; |
||||
} |
||||
|
||||
public IProjectContent UpdateProjectContent(IEnumerable<IParsedFile> oldFiles, IEnumerable<IParsedFile> newFiles) |
||||
{ |
||||
CSharpProjectContent pc = new CSharpProjectContent(this); |
||||
if (oldFiles != null) { |
||||
foreach (var oldFile in oldFiles) { |
||||
pc.parsedFiles.Remove(oldFile.FileName); |
||||
} |
||||
} |
||||
if (newFiles != null) { |
||||
foreach (var newFile in newFiles) { |
||||
pc.parsedFiles.Add(newFile.FileName, newFile); |
||||
} |
||||
} |
||||
return pc; |
||||
} |
||||
|
||||
IAssembly IAssemblyReference.Resolve(ITypeResolveContext context) |
||||
{ |
||||
if (context == null) |
||||
throw new ArgumentNullException("context"); |
||||
var cache = context.Compilation.CacheManager; |
||||
IAssembly asm = (IAssembly)cache.GetShared(this); |
||||
if (asm != null) { |
||||
return asm; |
||||
} else { |
||||
asm = new CSharpAssembly(context.Compilation, this); |
||||
return (IAssembly)cache.GetOrAddShared(this, asm); |
||||
} |
||||
} |
||||
} |
||||
} |
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,448 @@
@@ -0,0 +1,448 @@
|
||||
//
|
||||
// CSharpCompletionEngineBase.cs
|
||||
//
|
||||
// Author:
|
||||
// Mike Krüger <mkrueger@xamarin.com>
|
||||
//
|
||||
// Copyright (c) 2011 Xamarin Inc. (http://xamarin.com)
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
using System; |
||||
using System.Collections.Generic; |
||||
using System.Linq; |
||||
using System.Text; |
||||
|
||||
using ICSharpCode.NRefactory.CSharp.Resolver; |
||||
using ICSharpCode.NRefactory.Editor; |
||||
using ICSharpCode.NRefactory.TypeSystem; |
||||
using ICSharpCode.NRefactory.Semantics; |
||||
using ICSharpCode.NRefactory.TypeSystem.Implementation; |
||||
using ICSharpCode.NRefactory.CSharp.TypeSystem; |
||||
|
||||
namespace ICSharpCode.NRefactory.CSharp.Completion |
||||
{ |
||||
/// <summary>
|
||||
/// Acts as a common base between code completion and parameter completion.
|
||||
/// </summary>
|
||||
public class CSharpCompletionEngineBase |
||||
{ |
||||
protected IDocument document; |
||||
protected int offset; |
||||
protected TextLocation location; |
||||
protected IUnresolvedTypeDefinition currentType; |
||||
protected IUnresolvedMember currentMember; |
||||
|
||||
#region Input properties
|
||||
public CSharpTypeResolveContext ctx { get; set; } |
||||
|
||||
public CompilationUnit Unit { get; set; } |
||||
|
||||
public CSharpParsedFile CSharpParsedFile { get; set; } |
||||
|
||||
public IProjectContent ProjectContent { get; set; } |
||||
|
||||
ICompilation compilation; |
||||
protected ICompilation Compilation { |
||||
get { |
||||
if (compilation == null) |
||||
compilation = ProjectContent.Resolve (ctx).Compilation; |
||||
return compilation; |
||||
} |
||||
} |
||||
|
||||
#endregion
|
||||
|
||||
protected void SetOffset (int offset) |
||||
{ |
||||
Reset (); |
||||
|
||||
this.offset = offset; |
||||
this.location = document.GetLocation (offset); |
||||
|
||||
this.currentType = CSharpParsedFile.GetInnermostTypeDefinition (location); |
||||
this.currentMember = null; |
||||
if (this.currentType != null) { |
||||
foreach (var member in currentType.Members) { |
||||
if (member.Region.Begin < location && (currentMember == null || currentMember.Region.Begin < member.Region.Begin)) |
||||
currentMember = member; |
||||
} |
||||
} |
||||
var stack = GetBracketStack (GetMemberTextToCaret ().Item1); |
||||
if (stack.Count == 0) |
||||
currentMember = null; |
||||
} |
||||
|
||||
#region Context helper methods
|
||||
protected bool IsInsideCommentOrString () |
||||
{ |
||||
var text = GetMemberTextToCaret (); |
||||
bool inSingleComment = false, inString = false, inVerbatimString = false, inChar = false, inMultiLineComment = false; |
||||
|
||||
for (int i = 0; i < text.Item1.Length - 1; i++) { |
||||
char ch = text.Item1 [i]; |
||||
char nextCh = text.Item1 [i + 1]; |
||||
|
||||
switch (ch) { |
||||
case '/': |
||||
if (inString || inChar || inVerbatimString) |
||||
break; |
||||
if (nextCh == '/') { |
||||
i++; |
||||
inSingleComment = true; |
||||
} |
||||
if (nextCh == '*') |
||||
inMultiLineComment = true; |
||||
break; |
||||
case '*': |
||||
if (inString || inChar || inVerbatimString || inSingleComment) |
||||
break; |
||||
if (nextCh == '/') { |
||||
i++; |
||||
inMultiLineComment = false; |
||||
} |
||||
break; |
||||
case '@': |
||||
if (inString || inChar || inVerbatimString || inSingleComment || inMultiLineComment) |
||||
break; |
||||
if (nextCh == '"') { |
||||
i++; |
||||
inVerbatimString = true; |
||||
} |
||||
break; |
||||
case '\n': |
||||
case '\r': |
||||
inSingleComment = false; |
||||
inString = false; |
||||
inChar = false; |
||||
break; |
||||
case '\\': |
||||
if (inString || inChar) |
||||
i++; |
||||
break; |
||||
case '"': |
||||
if (inSingleComment || inMultiLineComment || inChar) |
||||
break; |
||||
if (inVerbatimString) { |
||||
if (nextCh == '"') { |
||||
i++; |
||||
break; |
||||
} |
||||
inVerbatimString = false; |
||||
break; |
||||
} |
||||
inString = !inString; |
||||
break; |
||||
case '\'': |
||||
if (inSingleComment || inMultiLineComment || inString || inVerbatimString) |
||||
break; |
||||
inChar = !inChar; |
||||
break; |
||||
} |
||||
} |
||||
|
||||
return inSingleComment || inString || inVerbatimString || inChar || inMultiLineComment; |
||||
} |
||||
|
||||
protected bool IsInsideComment (int offset) |
||||
{ |
||||
var loc = document.GetLocation (offset); |
||||
return Unit.GetNodeAt<ICSharpCode.NRefactory.CSharp.Comment> (loc.Line, loc.Column) != null; |
||||
} |
||||
|
||||
protected bool IsInsideDocComment () |
||||
{ |
||||
var loc = document.GetLocation (offset); |
||||
var cmt = Unit.GetNodeAt<ICSharpCode.NRefactory.CSharp.Comment> (loc.Line, loc.Column - 1); |
||||
return cmt != null && cmt.CommentType == CommentType.Documentation; |
||||
} |
||||
|
||||
protected bool IsInsideString (int offset) |
||||
{ |
||||
|
||||
var loc = document.GetLocation (offset); |
||||
var expr = Unit.GetNodeAt<PrimitiveExpression> (loc.Line, loc.Column); |
||||
return expr != null && expr.Value is string; |
||||
} |
||||
#endregion
|
||||
|
||||
#region Basic parsing/resolving functions
|
||||
Stack<Tuple<char, int>> GetBracketStack (string memberText) |
||||
{ |
||||
var bracketStack = new Stack<Tuple<char, int>> (); |
||||
|
||||
bool isInString = false, isInChar = false; |
||||
bool isInLineComment = false, isInBlockComment = false; |
||||
|
||||
for (int pos = 0; pos < memberText.Length; pos++) { |
||||
char ch = memberText [pos]; |
||||
switch (ch) { |
||||
case '(': |
||||
case '[': |
||||
case '{': |
||||
if (!isInString && !isInChar && !isInLineComment && !isInBlockComment) |
||||
bracketStack.Push (Tuple.Create (ch, pos)); |
||||
break; |
||||
case ')': |
||||
case ']': |
||||
case '}': |
||||
if (!isInString && !isInChar && !isInLineComment && !isInBlockComment) |
||||
if (bracketStack.Count > 0) |
||||
bracketStack.Pop (); |
||||
break; |
||||
case '\r': |
||||
case '\n': |
||||
isInLineComment = false; |
||||
break; |
||||
case '/': |
||||
if (isInBlockComment) { |
||||
if (pos > 0 && memberText [pos - 1] == '*') |
||||
isInBlockComment = false; |
||||
} else if (!isInString && !isInChar && pos + 1 < memberText.Length) { |
||||
char nextChar = memberText [pos + 1]; |
||||
if (nextChar == '/') |
||||
isInLineComment = true; |
||||
if (!isInLineComment && nextChar == '*') |
||||
isInBlockComment = true; |
||||
} |
||||
break; |
||||
case '"': |
||||
if (!(isInChar || isInLineComment || isInBlockComment)) |
||||
isInString = !isInString; |
||||
break; |
||||
case '\'': |
||||
if (!(isInString || isInLineComment || isInBlockComment)) |
||||
isInChar = !isInChar; |
||||
break; |
||||
default : |
||||
break; |
||||
} |
||||
} |
||||
return bracketStack; |
||||
} |
||||
|
||||
protected void AppendMissingClosingBrackets (StringBuilder wrapper, string memberText, bool appendSemicolon) |
||||
{ |
||||
var bracketStack = GetBracketStack (memberText); |
||||
bool didAppendSemicolon = !appendSemicolon; |
||||
char lastBracket = '\0'; |
||||
while (bracketStack.Count > 0) { |
||||
var t = bracketStack.Pop (); |
||||
switch (t.Item1) { |
||||
case '(': |
||||
wrapper.Append (')'); |
||||
didAppendSemicolon = false; |
||||
lastBracket = ')'; |
||||
break; |
||||
case '[': |
||||
wrapper.Append (']'); |
||||
didAppendSemicolon = false; |
||||
lastBracket = ']'; |
||||
break; |
||||
case '<': |
||||
wrapper.Append ('>'); |
||||
didAppendSemicolon = false; |
||||
lastBracket = '>'; |
||||
break; |
||||
case '{': |
||||
int o = t.Item2 - 1; |
||||
if (!didAppendSemicolon) { |
||||
didAppendSemicolon = true; |
||||
wrapper.Append (';'); |
||||
} |
||||
|
||||
bool didAppendCatch = false; |
||||
while (o >= "try".Length) { |
||||
char ch = memberText [o]; |
||||
if (!char.IsWhiteSpace (ch)) { |
||||
if (ch == 'y' && memberText [o - 1] == 'r' && memberText [o - 2] == 't') { |
||||
wrapper.Append ("} catch {}"); |
||||
didAppendCatch = true; |
||||
} |
||||
break; |
||||
} |
||||
o--; |
||||
} |
||||
if (!didAppendCatch) |
||||
wrapper.Append ('}'); |
||||
break; |
||||
} |
||||
} |
||||
if (currentMember == null && lastBracket == ']') { |
||||
// attribute context
|
||||
wrapper.Append ("class GenAttr {}"); |
||||
} else { |
||||
if (!didAppendSemicolon) |
||||
wrapper.Append (';'); |
||||
} |
||||
} |
||||
|
||||
protected CompilationUnit ParseStub (string continuation, bool appendSemicolon = true) |
||||
{ |
||||
var mt = GetMemberTextToCaret (); |
||||
if (mt == null) |
||||
return null; |
||||
|
||||
string memberText = mt.Item1; |
||||
bool wrapInClass = mt.Item2; |
||||
|
||||
var wrapper = new StringBuilder (); |
||||
|
||||
if (wrapInClass) { |
||||
/* foreach (var child in Unit.Children) { |
||||
if (child is UsingDeclaration) { |
||||
var offset = document.GetOffset (child.StartLocation); |
||||
wrapper.Append (document.GetText (offset, document.GetOffset (child.EndLocation) - offset)); |
||||
} |
||||
}*/ |
||||
wrapper.Append ("class Stub {"); |
||||
wrapper.AppendLine (); |
||||
} |
||||
|
||||
wrapper.Append (memberText); |
||||
wrapper.Append (continuation); |
||||
AppendMissingClosingBrackets (wrapper, memberText, appendSemicolon); |
||||
|
||||
if (wrapInClass) |
||||
wrapper.Append ('}'); |
||||
|
||||
TextLocation memberLocation; |
||||
if (currentMember != null && currentType.Kind != TypeKind.Enum) { |
||||
memberLocation = currentMember.Region.Begin; |
||||
} else if (currentType != null) { |
||||
memberLocation = currentType.Region.Begin; |
||||
} else { |
||||
memberLocation = new TextLocation (1, 1); |
||||
} |
||||
using (var stream = new System.IO.StringReader (wrapper.ToString ())) { |
||||
try { |
||||
var parser = new CSharpParser (); |
||||
return parser.Parse (stream, "stub.cs" , wrapInClass ? memberLocation.Line - 2 : 0); |
||||
} catch (Exception){ |
||||
Console.WriteLine ("------"); |
||||
Console.WriteLine (wrapper); |
||||
throw; |
||||
} |
||||
} |
||||
} |
||||
|
||||
string cachedText = null; |
||||
|
||||
protected virtual void Reset () |
||||
{ |
||||
cachedText = null; |
||||
} |
||||
|
||||
protected Tuple<string, bool> GetMemberTextToCaret () |
||||
{ |
||||
int startOffset; |
||||
if (currentMember != null && currentType.Kind != TypeKind.Enum) { |
||||
startOffset = document.GetOffset (currentMember.Region.BeginLine, currentMember.Region.BeginColumn); |
||||
} else if (currentType != null) { |
||||
startOffset = document.GetOffset (currentType.Region.BeginLine, currentType.Region.BeginColumn); |
||||
} else { |
||||
startOffset = 0; |
||||
} |
||||
while (startOffset > 0) { |
||||
char ch = document.GetCharAt (startOffset - 1); |
||||
if (ch != ' ' && ch != '\t') |
||||
break; |
||||
--startOffset; |
||||
} |
||||
if (cachedText == null) |
||||
cachedText = document.GetText (startOffset, offset - startOffset); |
||||
|
||||
return Tuple.Create (cachedText, startOffset != 0); |
||||
} |
||||
|
||||
protected Tuple<CSharpParsedFile, AstNode, CompilationUnit> GetInvocationBeforeCursor (bool afterBracket) |
||||
{ |
||||
CompilationUnit baseUnit; |
||||
if (currentMember == null) { |
||||
baseUnit = ParseStub ("", false); |
||||
var section = baseUnit.GetNodeAt<AttributeSection> (location.Line, location.Column - 2); |
||||
var attr = section != null ? section.Attributes.LastOrDefault () : null; |
||||
if (attr != null) { |
||||
// insert target type into compilation unit, to respect the
|
||||
attr.Remove (); |
||||
var node = Unit.GetNodeAt (location) ?? Unit; |
||||
node.AddChild (attr, AttributeSection.AttributeRole); |
||||
return Tuple.Create (CSharpParsedFile, (AstNode)attr, Unit); |
||||
} |
||||
} |
||||
|
||||
if (currentMember == null && currentType == null) { |
||||
return null; |
||||
} |
||||
baseUnit = ParseStub (afterBracket ? "" : "x"); |
||||
|
||||
var memberLocation = currentMember != null ? currentMember.Region.Begin : currentType.Region.Begin; |
||||
var mref = baseUnit.GetNodeAt (location.Line, location.Column - 1, n => n is InvocationExpression || n is ObjectCreateExpression); |
||||
AstNode expr; |
||||
if (mref is InvocationExpression) { |
||||
expr = ((InvocationExpression)mref).Target; |
||||
} else if (mref is ObjectCreateExpression) { |
||||
expr = mref; |
||||
} else { |
||||
return null; |
||||
} |
||||
var member = Unit.GetNodeAt<AttributedNode> (memberLocation); |
||||
var member2 = baseUnit.GetNodeAt<AttributedNode> (memberLocation); |
||||
member2.Remove (); |
||||
member.ReplaceWith (member2); |
||||
var tsvisitor = new TypeSystemConvertVisitor (CSharpParsedFile.FileName); |
||||
Unit.AcceptVisitor (tsvisitor, null); |
||||
return Tuple.Create (tsvisitor.ParsedFile, (AstNode)expr, Unit); |
||||
} |
||||
|
||||
protected Tuple<ResolveResult, CSharpResolver> ResolveExpression (CSharpParsedFile file, AstNode expr, CompilationUnit unit) |
||||
{ |
||||
if (expr == null) |
||||
return null; |
||||
AstNode resolveNode; |
||||
if (expr is Expression || expr is AstType) { |
||||
resolveNode = expr; |
||||
} else if (expr is VariableDeclarationStatement) { |
||||
resolveNode = ((VariableDeclarationStatement)expr).Type; |
||||
} else { |
||||
resolveNode = expr; |
||||
} |
||||
|
||||
// var newContent = ProjectContent.UpdateProjectContent (CSharpParsedFile, file);
|
||||
|
||||
var csResolver = new CSharpResolver (ctx); |
||||
|
||||
var navigator = new NodeListResolveVisitorNavigator (new[] { resolveNode }); |
||||
var visitor = new ResolveVisitor (csResolver, CSharpParsedFile, navigator); |
||||
|
||||
visitor.Scan (unit); |
||||
var state = visitor.GetResolverStateBefore (resolveNode); |
||||
var result = visitor.GetResolveResult (resolveNode); |
||||
return Tuple.Create (result, state); |
||||
} |
||||
|
||||
protected static void Print (AstNode node) |
||||
{ |
||||
var v = new CSharpOutputVisitor (Console.Out, new CSharpFormattingOptions ()); |
||||
node.AcceptVisitor (v, null); |
||||
} |
||||
|
||||
#endregion
|
||||
} |
||||
} |
@ -0,0 +1,326 @@
@@ -0,0 +1,326 @@
|
||||
//
|
||||
// CSharpParameterCompletionEngine.cs
|
||||
//
|
||||
// Author:
|
||||
// Mike Krüger <mkrueger@xamarin.com>
|
||||
//
|
||||
// Copyright (c) 2011 Xamarin Inc. (http://xamarin.com)
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
using System; |
||||
using ICSharpCode.NRefactory.Editor; |
||||
using ICSharpCode.NRefactory.Completion; |
||||
using System.Collections.Generic; |
||||
using ICSharpCode.NRefactory.Semantics; |
||||
using ICSharpCode.NRefactory.TypeSystem; |
||||
using ICSharpCode.NRefactory.CSharp.Resolver; |
||||
using ICSharpCode.NRefactory.CSharp.TypeSystem; |
||||
|
||||
namespace ICSharpCode.NRefactory.CSharp.Completion |
||||
{ |
||||
public class CSharpParameterCompletionEngine : CSharpCompletionEngineBase |
||||
{ |
||||
internal IParameterCompletionDataFactory factory; |
||||
|
||||
public CSharpParameterCompletionEngine (IDocument document, IParameterCompletionDataFactory factory) |
||||
{ |
||||
this.document = document; |
||||
this.factory = factory; |
||||
} |
||||
|
||||
public Tuple<CSharpParsedFile, AstNode, CompilationUnit> GetIndexerBeforeCursor () |
||||
{ |
||||
CompilationUnit baseUnit; |
||||
if (currentMember == null && currentType == null) |
||||
return null; |
||||
baseUnit = ParseStub ("x] = a[1"); |
||||
|
||||
var memberLocation = currentMember != null ? currentMember.Region.Begin : currentType.Region.Begin; |
||||
var mref = baseUnit.GetNodeAt (location, n => n is IndexerExpression); |
||||
Print (baseUnit); |
||||
AstNode expr; |
||||
if (mref is IndexerExpression) { |
||||
expr = ((IndexerExpression)mref).Target; |
||||
} else { |
||||
return null; |
||||
} |
||||
|
||||
var member = Unit.GetNodeAt<AttributedNode> (memberLocation); |
||||
var member2 = baseUnit.GetNodeAt<AttributedNode> (memberLocation); |
||||
member2.Remove (); |
||||
member.ReplaceWith (member2); |
||||
var tsvisitor = new TypeSystemConvertVisitor (CSharpParsedFile.FileName); |
||||
Unit.AcceptVisitor (tsvisitor, null); |
||||
return Tuple.Create (tsvisitor.ParsedFile, (AstNode)expr, Unit); |
||||
} |
||||
|
||||
public IParameterDataProvider GetParameterDataProvider (int offset, char completionChar) |
||||
{ |
||||
if (offset <= 0) |
||||
return null; |
||||
if (completionChar != '(' && completionChar != '<' && completionChar != '[' && completionChar != ',') |
||||
return null; |
||||
|
||||
SetOffset (offset); |
||||
if (IsInsideCommentOrString ()) |
||||
return null; |
||||
|
||||
var invoke = GetInvocationBeforeCursor (true) ?? GetIndexerBeforeCursor (); |
||||
if (invoke == null) |
||||
return null; |
||||
|
||||
ResolveResult resolveResult; |
||||
switch (completionChar) { |
||||
case '(': |
||||
if (invoke.Item2 is ObjectCreateExpression) { |
||||
var createType = ResolveExpression (invoke.Item1, ((ObjectCreateExpression)invoke.Item2).Type, invoke.Item3); |
||||
return factory.CreateConstructorProvider (createType.Item1.Type); |
||||
} |
||||
|
||||
if (invoke.Item2 is ICSharpCode.NRefactory.CSharp.Attribute) { |
||||
var attribute = ResolveExpression (invoke.Item1, invoke.Item2, invoke.Item3); |
||||
if (attribute == null || attribute.Item1 == null) |
||||
return null; |
||||
return factory.CreateConstructorProvider (attribute.Item1.Type); |
||||
} |
||||
var invocationExpression = ResolveExpression (invoke.Item1, invoke.Item2, invoke.Item3); |
||||
if (invocationExpression == null || invocationExpression.Item1 == null || invocationExpression.Item1.IsError) |
||||
return null; |
||||
resolveResult = invocationExpression.Item1; |
||||
if (resolveResult is MethodGroupResolveResult) |
||||
return factory.CreateMethodDataProvider (resolveResult as MethodGroupResolveResult); |
||||
if (resolveResult is MemberResolveResult) { |
||||
var mr = resolveResult as MemberResolveResult; |
||||
if (mr.Member is IMethod) |
||||
return factory.CreateMethodDataProvider ((IMethod)mr.Member); |
||||
} |
||||
|
||||
if (resolveResult.Type.Kind == TypeKind.Delegate) |
||||
return factory.CreateDelegateDataProvider (resolveResult.Type); |
||||
|
||||
//
|
||||
// if (result.ExpressionContext == ExpressionContext.BaseConstructorCall) {
|
||||
// if (resolveResult is ThisResolveResult)
|
||||
// return new NRefactoryParameterDataProvider (textEditorData, resolver, resolveResult as ThisResolveResult);
|
||||
// if (resolveResult is BaseResolveResult)
|
||||
// return new NRefactoryParameterDataProvider (textEditorData, resolver, resolveResult as BaseResolveResult);
|
||||
// }
|
||||
// IType resolvedType = resolver.SearchType (resolveResult.ResolvedType);
|
||||
// if (resolvedType != null && resolvedType.ClassType == ClassType.Delegate) {
|
||||
// return new NRefactoryParameterDataProvider (textEditorData, result.Expression, resolvedType);
|
||||
// }
|
||||
break; |
||||
case ',': |
||||
if (invoke.Item2 is ObjectCreateExpression) { |
||||
var createType = ResolveExpression (invoke.Item1, ((ObjectCreateExpression)invoke.Item2).Type, invoke.Item3); |
||||
return factory.CreateConstructorProvider (createType.Item1.Type); |
||||
} |
||||
|
||||
if (invoke.Item2 is ICSharpCode.NRefactory.CSharp.Attribute) { |
||||
var attribute = ResolveExpression (invoke.Item1, invoke.Item2, invoke.Item3); |
||||
if (attribute == null || attribute.Item1 == null) |
||||
return null; |
||||
return factory.CreateConstructorProvider (attribute.Item1.Type); |
||||
} |
||||
|
||||
invocationExpression = ResolveExpression (invoke.Item1, invoke.Item2, invoke.Item3); |
||||
|
||||
if (invocationExpression == null || invocationExpression.Item1 == null || invocationExpression.Item1.IsError) |
||||
return null; |
||||
|
||||
resolveResult = invocationExpression.Item1; |
||||
if (resolveResult is MethodGroupResolveResult) |
||||
return factory.CreateMethodDataProvider (resolveResult as MethodGroupResolveResult); |
||||
if (resolveResult is MemberResolveResult) { |
||||
if (resolveResult.Type.Kind == TypeKind.Delegate) |
||||
return factory.CreateDelegateDataProvider (resolveResult.Type); |
||||
var mr = resolveResult as MemberResolveResult; |
||||
if (mr.Member is IMethod) |
||||
return factory.CreateMethodDataProvider ((IMethod)mr.Member); |
||||
} |
||||
if (resolveResult != null) |
||||
return factory.CreateIndexerParameterDataProvider (resolveResult.Type, invoke.Item2); |
||||
break; |
||||
// case '<':
|
||||
// if (string.IsNullOrEmpty (result.Expression))
|
||||
// return null;
|
||||
// return new NRefactoryTemplateParameterDataProvider (textEditorData, resolver, GetUsedNamespaces (), result, new TextLocation (completionContext.TriggerLine, completionContext.TriggerLineOffset));
|
||||
|
||||
case '[': |
||||
var indexerExpression = ResolveExpression (invoke.Item1, invoke.Item2, invoke.Item3); |
||||
if (indexerExpression == null || indexerExpression.Item1 == null || indexerExpression.Item1.IsError) |
||||
return null; |
||||
return factory.CreateIndexerParameterDataProvider (indexerExpression.Item1.Type, invoke.Item2); |
||||
} |
||||
return null; |
||||
} |
||||
|
||||
List<string> GetUsedNamespaces () |
||||
{ |
||||
var scope = CSharpParsedFile.GetUsingScope (location); |
||||
var result = new List<string> (); |
||||
var resolver = new CSharpResolver (ctx); |
||||
while (scope != null) { |
||||
result.Add (scope.NamespaceName); |
||||
|
||||
foreach (var u in scope.Usings) { |
||||
var ns = u.ResolveNamespace (resolver); |
||||
if (ns == null) |
||||
continue; |
||||
result.Add (ns.FullName); |
||||
} |
||||
scope = scope.Parent; |
||||
} |
||||
return result; |
||||
} |
||||
|
||||
public int GetCurrentParameterIndex (int triggerOffset) |
||||
{ |
||||
SetOffset (triggerOffset); |
||||
var text = GetMemberTextToCaret (); |
||||
if (text.Item1.EndsWith ("(")) |
||||
return 0; |
||||
var parameter = new Stack<int> (); |
||||
|
||||
bool inSingleComment = false, inString = false, inVerbatimString = false, inChar = false, inMultiLineComment = false; |
||||
|
||||
for (int i = 0; i < text.Item1.Length; i++) { |
||||
char ch = text.Item1 [i]; |
||||
char nextCh = i + 1 < text.Item1.Length ? text.Item1 [i + 1] : '\0'; |
||||
|
||||
switch (ch) { |
||||
case '(': |
||||
if (inString || inChar || inVerbatimString || inSingleComment || inMultiLineComment) |
||||
break; |
||||
parameter.Push (0); |
||||
break; |
||||
case ')': |
||||
if (inString || inChar || inVerbatimString || inSingleComment || inMultiLineComment) |
||||
break; |
||||
if (parameter.Count > 0) |
||||
parameter.Pop (); |
||||
break; |
||||
case ',': |
||||
if (inString || inChar || inVerbatimString || inSingleComment || inMultiLineComment) |
||||
break; |
||||
if (parameter.Count > 0) |
||||
parameter.Push (parameter.Pop () + 1); |
||||
break; |
||||
case '/': |
||||
if (inString || inChar || inVerbatimString) |
||||
break; |
||||
if (nextCh == '/') { |
||||
i++; |
||||
inSingleComment = true; |
||||
} |
||||
if (nextCh == '*') |
||||
inMultiLineComment = true; |
||||
break; |
||||
case '*': |
||||
if (inString || inChar || inVerbatimString || inSingleComment) |
||||
break; |
||||
if (nextCh == '/') { |
||||
i++; |
||||
inMultiLineComment = false; |
||||
} |
||||
break; |
||||
case '@': |
||||
if (inString || inChar || inVerbatimString || inSingleComment || inMultiLineComment) |
||||
break; |
||||
if (nextCh == '"') { |
||||
i++; |
||||
inVerbatimString = true; |
||||
} |
||||
break; |
||||
case '\n': |
||||
case '\r': |
||||
inSingleComment = false; |
||||
inString = false; |
||||
inChar = false; |
||||
break; |
||||
case '\\': |
||||
if (inString || inChar) |
||||
i++; |
||||
break; |
||||
case '"': |
||||
if (inSingleComment || inMultiLineComment || inChar) |
||||
break; |
||||
if (inVerbatimString) { |
||||
if (nextCh == '"') { |
||||
i++; |
||||
break; |
||||
} |
||||
inVerbatimString = false; |
||||
break; |
||||
} |
||||
inString = !inString; |
||||
break; |
||||
case '\'': |
||||
if (inSingleComment || inMultiLineComment || inString || inVerbatimString) |
||||
break; |
||||
inChar = !inChar; |
||||
break; |
||||
} |
||||
} |
||||
if (parameter.Count == 0) |
||||
return -1; |
||||
return parameter.Pop () + 1; |
||||
} |
||||
|
||||
/* |
||||
public override bool GetParameterCompletionCommandOffset (out int cpos) |
||||
{ |
||||
// Start calculating the parameter offset from the beginning of the
|
||||
// current member, instead of the beginning of the file.
|
||||
cpos = textEditorData.Caret.Offset - 1; |
||||
var parsedDocument = Document.ParsedDocument; |
||||
if (parsedDocument == null) |
||||
return false; |
||||
IMember mem = currentMember; |
||||
if (mem == null || (mem is IType)) |
||||
return false; |
||||
int startPos = textEditorData.LocationToOffset (mem.Region.BeginLine, mem.Region.BeginColumn); |
||||
int parenDepth = 0; |
||||
int chevronDepth = 0; |
||||
while (cpos > startPos) { |
||||
char c = textEditorData.GetCharAt (cpos); |
||||
if (c == ')') |
||||
parenDepth++; |
||||
if (c == '>') |
||||
chevronDepth++; |
||||
if (parenDepth == 0 && c == '(' || chevronDepth == 0 && c == '<') { |
||||
int p = MethodParameterDataProvider.GetCurrentParameterIndex (CompletionWidget, cpos + 1, startPos); |
||||
if (p != -1) { |
||||
cpos++; |
||||
return true; |
||||
} else { |
||||
return false; |
||||
} |
||||
} |
||||
if (c == '(') |
||||
parenDepth--; |
||||
if (c == '<') |
||||
chevronDepth--; |
||||
cpos--; |
||||
} |
||||
return false; |
||||
}*/ |
||||
} |
||||
} |
||||
|
@ -0,0 +1,237 @@
@@ -0,0 +1,237 @@
|
||||
//
|
||||
// CompletionDataWrapper.cs
|
||||
//
|
||||
// Author:
|
||||
// Mike Krüger <mkrueger@xamarin.com>
|
||||
//
|
||||
// Copyright (c) 2011 Xamarin Inc. (http://xamarin.com)
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
using System; |
||||
using System.Collections.Generic; |
||||
using ICSharpCode.NRefactory.Completion; |
||||
using ICSharpCode.NRefactory.TypeSystem; |
||||
|
||||
namespace ICSharpCode.NRefactory.CSharp.Completion |
||||
{ |
||||
class CompletionDataWrapper |
||||
{ |
||||
CSharpCompletionEngine completion; |
||||
List<ICompletionData> result = new List<ICompletionData> (); |
||||
|
||||
public List<ICompletionData> Result { |
||||
get { |
||||
return result; |
||||
} |
||||
} |
||||
|
||||
ICompletionDataFactory Factory { |
||||
get { |
||||
return completion.factory; |
||||
} |
||||
} |
||||
|
||||
public CompletionDataWrapper (CSharpCompletionEngine completion) |
||||
{ |
||||
this.completion = completion; |
||||
} |
||||
|
||||
public void Add (ICompletionData data) |
||||
{ |
||||
result.Add (data); |
||||
} |
||||
|
||||
public void AddCustom (string displayText, string description = null, string completionText = null) |
||||
{ |
||||
result.Add (Factory.CreateLiteralCompletionData (displayText, description, completionText)); |
||||
} |
||||
|
||||
HashSet<string> usedNamespaces = new HashSet<string> (); |
||||
|
||||
public void AddNamespace (string name) |
||||
{ |
||||
if (string.IsNullOrEmpty (name) || usedNamespaces.Contains (name)) |
||||
return; |
||||
usedNamespaces.Add (name); |
||||
result.Add (Factory.CreateNamespaceCompletionData (name)); |
||||
} |
||||
|
||||
HashSet<string> usedTypes = new HashSet<string> (); |
||||
|
||||
public void AddType (IType type, string shortType) |
||||
{ |
||||
if (type == null || string.IsNullOrEmpty (shortType) || usedTypes.Contains (shortType)) |
||||
return; |
||||
usedTypes.Add (shortType); |
||||
result.Add (Factory.CreateTypeCompletionData (type, shortType)); |
||||
} |
||||
|
||||
public void AddType (IUnresolvedTypeDefinition type, string shortType) |
||||
{ |
||||
if (type == null || string.IsNullOrEmpty (shortType) || usedTypes.Contains (shortType)) |
||||
return; |
||||
usedTypes.Add (shortType); |
||||
result.Add (Factory.CreateTypeCompletionData (type, shortType)); |
||||
} |
||||
|
||||
Dictionary<string, List<ICompletionData>> data = new Dictionary<string, List<ICompletionData>> (); |
||||
|
||||
public void AddVariable (IVariable variable) |
||||
{ |
||||
if (data.ContainsKey (variable.Name)) |
||||
return; |
||||
data [variable.Name] = new List<ICompletionData> (); |
||||
result.Add (Factory.CreateVariableCompletionData (variable)); |
||||
} |
||||
|
||||
public void AddTypeParameter (IUnresolvedTypeParameter variable) |
||||
{ |
||||
if (data.ContainsKey (variable.Name)) |
||||
return; |
||||
data [variable.Name] = new List<ICompletionData> (); |
||||
result.Add (Factory.CreateVariableCompletionData (variable)); |
||||
} |
||||
|
||||
public ICompletionData AddMember (IUnresolvedMember member) |
||||
{ |
||||
var newData = Factory.CreateEntityCompletionData (member); |
||||
|
||||
// newData.HideExtensionParameter = HideExtensionParameter;
|
||||
string memberKey = newData.DisplayText; |
||||
if (memberKey == null) |
||||
return null; |
||||
if (member is IMember) { |
||||
newData.CompletionCategory = GetCompletionCategory (member.DeclaringTypeDefinition.Resolve (completion.ctx)); |
||||
} |
||||
List<ICompletionData> existingData; |
||||
data.TryGetValue (memberKey, out existingData); |
||||
|
||||
if (existingData != null) { |
||||
var a = member as IEntity; |
||||
foreach (var d in existingData) { |
||||
if (!(d is IEntityCompletionData)) |
||||
continue; |
||||
var b = ((IEntityCompletionData)d).Entity; |
||||
if (a == null || b == null || a.EntityType == b.EntityType) { |
||||
d.AddOverload (newData); |
||||
return d; |
||||
} |
||||
} |
||||
if (newData != null) { |
||||
result.Add (newData); |
||||
data [memberKey].Add (newData); |
||||
} |
||||
} else { |
||||
result.Add (newData); |
||||
data [memberKey] = new List<ICompletionData> (); |
||||
data [memberKey].Add (newData); |
||||
} |
||||
return newData; |
||||
} |
||||
|
||||
public ICompletionData AddMember (IMember member) |
||||
{ |
||||
var newData = Factory.CreateEntityCompletionData (member); |
||||
|
||||
// newData.HideExtensionParameter = HideExtensionParameter;
|
||||
string memberKey = newData.DisplayText; |
||||
if (memberKey == null) |
||||
return null; |
||||
if (member is IMember) { |
||||
newData.CompletionCategory = GetCompletionCategory (member.DeclaringTypeDefinition); |
||||
} |
||||
List<ICompletionData> existingData; |
||||
data.TryGetValue (memberKey, out existingData); |
||||
|
||||
if (existingData != null) { |
||||
var a = member as IEntity; |
||||
foreach (var d in existingData) { |
||||
if (!(d is IEntityCompletionData)) |
||||
continue; |
||||
var b = ((IEntityCompletionData)d).Entity; |
||||
if (a == null || b == null || a.EntityType == b.EntityType) { |
||||
d.AddOverload (newData); |
||||
return d; |
||||
} |
||||
} |
||||
if (newData != null) { |
||||
result.Add (newData); |
||||
data [memberKey].Add (newData); |
||||
} |
||||
} else { |
||||
result.Add (newData); |
||||
data [memberKey] = new List<ICompletionData> (); |
||||
data [memberKey].Add (newData); |
||||
} |
||||
return newData; |
||||
} |
||||
|
||||
internal CompletionCategory GetCompletionCategory (IType type) |
||||
{ |
||||
if (type == null) |
||||
return null; |
||||
if (!completionCategories.ContainsKey (type)) |
||||
completionCategories [type] = new TypeCompletionCategory (type); |
||||
return completionCategories [type]; |
||||
} |
||||
|
||||
Dictionary<IType, CompletionCategory> completionCategories = new Dictionary<IType, CompletionCategory> (); |
||||
class TypeCompletionCategory : CompletionCategory |
||||
{ |
||||
public IType Type { |
||||
get; |
||||
private set; |
||||
} |
||||
|
||||
public TypeCompletionCategory (IType type) : base (type.FullName, null) |
||||
{ |
||||
this.Type = type; |
||||
} |
||||
|
||||
public override int CompareTo (CompletionCategory other) |
||||
{ |
||||
var compareCategory = other as TypeCompletionCategory; |
||||
if (compareCategory == null) |
||||
return 1; |
||||
|
||||
if (Type.ReflectionName == compareCategory.Type.ReflectionName) |
||||
return 0; |
||||
|
||||
// System.Object is always the smallest
|
||||
if (Type.ReflectionName == "System.Object") |
||||
return -1; |
||||
if (compareCategory.Type.ReflectionName == "System.Object") |
||||
return 1; |
||||
|
||||
/* if (Type.GetProjectContent () != null) { |
||||
if (Type.GetProjectContent ().GetInheritanceTree (Type).Any (t => t != null && t.DecoratedFullName == compareCategory.Type.DecoratedFullName)) |
||||
return 1; |
||||
return -1; |
||||
} |
||||
|
||||
// source project dom == null - try to make the opposite comparison
|
||||
if (compareCategory.Type.GetProjectContent () != null && compareCategory.Type.GetProjectContent ().GetInheritanceTree (Type).Any (t => t != null && t.DecoratedFullName == Type.DecoratedFullName)) |
||||
return -1;*/ |
||||
return 1; |
||||
} |
||||
} |
||||
} |
||||
} |
||||
|
||||
|
@ -0,0 +1,71 @@
@@ -0,0 +1,71 @@
|
||||
//
|
||||
// ICompletionDataFactory.cs
|
||||
//
|
||||
// Author:
|
||||
// Mike Krüger <mkrueger@xamarin.com>
|
||||
//
|
||||
// Copyright (c) 2011 Xamarin Inc. (http://xamarin.com)
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
using System; |
||||
using System.Collections.Generic; |
||||
using ICSharpCode.NRefactory.TypeSystem; |
||||
using ICSharpCode.NRefactory.Completion; |
||||
|
||||
namespace ICSharpCode.NRefactory.CSharp.Completion |
||||
{ |
||||
public interface ICompletionDataFactory |
||||
{ |
||||
ICompletionData CreateEntityCompletionData (IUnresolvedEntity entity); |
||||
ICompletionData CreateEntityCompletionData (IUnresolvedEntity entity, string text); |
||||
ICompletionData CreateEntityCompletionData (IEntity entity); |
||||
ICompletionData CreateEntityCompletionData (IEntity entity, string text); |
||||
|
||||
ICompletionData CreateTypeCompletionData (IType type, string shortType); |
||||
ICompletionData CreateTypeCompletionData (IUnresolvedTypeDefinition type, string shortType); |
||||
|
||||
/// <summary>
|
||||
/// Creates a generic completion data.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// The title of the completion data
|
||||
/// </param>
|
||||
/// <param name='description'>
|
||||
/// The description of the literal.
|
||||
/// </param>
|
||||
/// <param name='insertText'>
|
||||
/// The insert text. If null, title is taken.
|
||||
/// </param>
|
||||
ICompletionData CreateLiteralCompletionData (string title, string description = null, string insertText = null); |
||||
|
||||
ICompletionData CreateNamespaceCompletionData (string name); |
||||
|
||||
ICompletionData CreateVariableCompletionData (IVariable variable); |
||||
|
||||
ICompletionData CreateVariableCompletionData (IUnresolvedTypeParameter parameter); |
||||
|
||||
ICompletionData CreateEventCreationCompletionData (string varName, IType delegateType, IEvent evt, string parameterDefinition, IUnresolvedMember currentMember, IUnresolvedTypeDefinition currentType); |
||||
|
||||
ICompletionData CreateNewOverrideCompletionData (int declarationBegin, IUnresolvedTypeDefinition type, IMember m); |
||||
|
||||
IEnumerable<ICompletionData> CreateCodeTemplateCompletionData (); |
||||
|
||||
IEnumerable<ICompletionData> CreatePreProcessorDefinesCompletionData (); |
||||
} |
||||
} |
@ -0,0 +1,46 @@
@@ -0,0 +1,46 @@
|
||||
//
|
||||
// IParameterCopmletionFactory.cs
|
||||
//
|
||||
// Author:
|
||||
// Mike Krüger <mkrueger@xamarin.com>
|
||||
//
|
||||
// Copyright (c) 2011 Xamarin Inc. (http://xamarin.com)
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
using System; |
||||
using ICSharpCode.NRefactory.TypeSystem; |
||||
using ICSharpCode.NRefactory.Completion; |
||||
using ICSharpCode.NRefactory.CSharp.Resolver; |
||||
|
||||
namespace ICSharpCode.NRefactory.CSharp.Completion |
||||
{ |
||||
public interface IParameterCompletionDataFactory |
||||
{ |
||||
IParameterDataProvider CreateConstructorProvider (IType type); |
||||
|
||||
IParameterDataProvider CreateMethodDataProvider (MethodGroupResolveResult par1); |
||||
|
||||
IParameterDataProvider CreateMethodDataProvider (IMethod method); |
||||
|
||||
IParameterDataProvider CreateDelegateDataProvider (IType type); |
||||
|
||||
IParameterDataProvider CreateIndexerParameterDataProvider (IType type, AstNode resolvedNode); |
||||
} |
||||
|
||||
} |
@ -0,0 +1,239 @@
@@ -0,0 +1,239 @@
|
||||
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy of this
|
||||
// software and associated documentation files (the "Software"), to deal in the Software
|
||||
// without restriction, including without limitation the rights to use, copy, modify, merge,
|
||||
// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
|
||||
// to whom the Software is furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all copies or
|
||||
// substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
||||
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
|
||||
// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
|
||||
// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
|
||||
using System; |
||||
using System.IO; |
||||
using ICSharpCode.NRefactory.CSharp.Refactoring; |
||||
using ICSharpCode.NRefactory.TypeSystem; |
||||
using ICSharpCode.NRefactory.TypeSystem.Implementation; |
||||
|
||||
namespace ICSharpCode.NRefactory.CSharp |
||||
{ |
||||
/// <summary>
|
||||
/// C# ambience.
|
||||
/// </summary>
|
||||
public class CSharpAmbience : IAmbience |
||||
{ |
||||
public ConversionFlags ConversionFlags { get; set; } |
||||
|
||||
#region ConvertEntity
|
||||
public string ConvertEntity(IEntity e) |
||||
{ |
||||
StringWriter writer = new StringWriter(); |
||||
|
||||
if (e.EntityType == EntityType.TypeDefinition) { |
||||
ConvertTypeDeclaration((ITypeDefinition)e, writer); |
||||
} else { |
||||
ConvertMember((IMember)e, writer); |
||||
} |
||||
|
||||
return writer.ToString().TrimEnd(); |
||||
} |
||||
|
||||
void ConvertMember(IMember member, StringWriter writer) |
||||
{ |
||||
TypeSystemAstBuilder astBuilder = CreateAstBuilder(); |
||||
astBuilder.ShowParameterNames = (ConversionFlags & ConversionFlags.ShowParameterNames) == ConversionFlags.ShowParameterNames; |
||||
|
||||
AttributedNode node = (AttributedNode)astBuilder.ConvertEntity(member); |
||||
PrintModifiers(node.Modifiers, writer); |
||||
|
||||
if ((ConversionFlags & ConversionFlags.ShowReturnType) == ConversionFlags.ShowReturnType) { |
||||
var rt = node.GetChildByRole(AstNode.Roles.Type); |
||||
if (rt != AstNode.Roles.Type.NullObject) { |
||||
writer.Write(rt.AcceptVisitor(CreatePrinter(writer), null)); |
||||
writer.Write(' '); |
||||
} |
||||
} |
||||
|
||||
WriteMemberDeclarationName(member, writer); |
||||
|
||||
if ((ConversionFlags & ConversionFlags.ShowParameterList) == ConversionFlags.ShowParameterList |
||||
&& member is IParameterizedMember && member.EntityType != EntityType.Property) { |
||||
writer.Write((node is IndexerDeclaration) ? '[' : '('); |
||||
bool first = true; |
||||
foreach (var param in node.GetChildrenByRole(AstNode.Roles.Parameter)) { |
||||
if (first) |
||||
first = false; |
||||
else |
||||
writer.Write(", "); |
||||
param.AcceptVisitor(CreatePrinter(writer), null); |
||||
} |
||||
writer.Write((node is IndexerDeclaration) ? ']' : ')'); |
||||
} |
||||
if ((ConversionFlags & ConversionFlags.ShowBody) == ConversionFlags.ShowBody) { |
||||
IProperty property = member as IProperty; |
||||
if (property != null) { |
||||
writer.Write(" { "); |
||||
if (property.CanGet) |
||||
writer.Write("get; "); |
||||
if (property.CanSet) |
||||
writer.Write("set; "); |
||||
writer.Write('}'); |
||||
} else { |
||||
writer.Write(';'); |
||||
} |
||||
} |
||||
} |
||||
|
||||
TypeSystemAstBuilder CreateAstBuilder() |
||||
{ |
||||
TypeSystemAstBuilder astBuilder = new TypeSystemAstBuilder(); |
||||
astBuilder.ShowModifiers = (ConversionFlags & ConversionFlags.ShowModifiers) == ConversionFlags.ShowModifiers; |
||||
astBuilder.ShowAccessibility = (ConversionFlags & ConversionFlags.ShowAccessibility) == ConversionFlags.ShowAccessibility; |
||||
astBuilder.AlwaysUseShortTypeNames = (ConversionFlags & ConversionFlags.UseFullyQualifiedTypeNames) != ConversionFlags.UseFullyQualifiedTypeNames; |
||||
return astBuilder; |
||||
} |
||||
|
||||
void ConvertTypeDeclaration(ITypeDefinition typeDef, StringWriter writer) |
||||
{ |
||||
TypeSystemAstBuilder astBuilder = CreateAstBuilder(); |
||||
TypeDeclaration typeDeclaration = (TypeDeclaration)astBuilder.ConvertEntity(typeDef); |
||||
PrintModifiers(typeDeclaration.Modifiers, writer); |
||||
if ((ConversionFlags & ConversionFlags.ShowDefinitionKeyWord) == ConversionFlags.ShowDefinitionKeyWord) { |
||||
switch (typeDeclaration.ClassType) { |
||||
case ClassType.Class: |
||||
writer.Write("class"); |
||||
break; |
||||
case ClassType.Struct: |
||||
writer.Write("struct"); |
||||
break; |
||||
case ClassType.Interface: |
||||
writer.Write("interface"); |
||||
break; |
||||
case ClassType.Enum: |
||||
writer.Write("enum"); |
||||
break; |
||||
default: |
||||
throw new Exception("Invalid value for ClassType"); |
||||
} |
||||
writer.Write(' '); |
||||
} |
||||
WriteTypeDeclarationName(typeDef, writer); |
||||
} |
||||
|
||||
void WriteTypeDeclarationName(ITypeDefinition typeDef, StringWriter writer) |
||||
{ |
||||
TypeSystemAstBuilder astBuilder = CreateAstBuilder(); |
||||
if (typeDef.DeclaringTypeDefinition != null) { |
||||
WriteTypeDeclarationName(typeDef.DeclaringTypeDefinition, writer); |
||||
writer.Write('.'); |
||||
} else if ((ConversionFlags & ConversionFlags.UseFullyQualifiedMemberNames) == ConversionFlags.UseFullyQualifiedMemberNames) { |
||||
writer.Write(typeDef.Namespace); |
||||
writer.Write('.'); |
||||
} |
||||
writer.Write(typeDef.Name); |
||||
if ((ConversionFlags & ConversionFlags.ShowTypeParameterList) == ConversionFlags.ShowTypeParameterList) { |
||||
CreatePrinter(writer).WriteTypeParameters(((TypeDeclaration)astBuilder.ConvertEntity(typeDef)).TypeParameters); |
||||
} |
||||
} |
||||
|
||||
void WriteMemberDeclarationName(IMember member, StringWriter writer) |
||||
{ |
||||
TypeSystemAstBuilder astBuilder = CreateAstBuilder(); |
||||
if ((ConversionFlags & ConversionFlags.UseFullyQualifiedMemberNames) == ConversionFlags.UseFullyQualifiedMemberNames) { |
||||
writer.Write(ConvertType(member.DeclaringType)); |
||||
writer.Write('.'); |
||||
} |
||||
switch (member.EntityType) { |
||||
case EntityType.Indexer: |
||||
writer.Write("this"); |
||||
break; |
||||
case EntityType.Constructor: |
||||
writer.Write(member.DeclaringType.Name); |
||||
break; |
||||
case EntityType.Destructor: |
||||
writer.Write('~'); |
||||
writer.Write(member.DeclaringType.Name); |
||||
break; |
||||
case EntityType.Operator: |
||||
switch (member.Name) { |
||||
case "op_Implicit": |
||||
writer.Write("implicit operator "); |
||||
writer.Write(ConvertType(member.ReturnType)); |
||||
break; |
||||
case "op_Explicit": |
||||
writer.Write("explicit operator "); |
||||
writer.Write(ConvertType(member.ReturnType)); |
||||
break; |
||||
default: |
||||
writer.Write("operator "); |
||||
var operatorType = OperatorDeclaration.GetOperatorType(member.Name); |
||||
if (operatorType.HasValue) |
||||
writer.Write(OperatorDeclaration.GetToken(operatorType.Value)); |
||||
else |
||||
writer.Write(member.Name); |
||||
break; |
||||
} |
||||
break; |
||||
default: |
||||
writer.Write(member.Name); |
||||
break; |
||||
} |
||||
if ((ConversionFlags & ConversionFlags.ShowTypeParameterList) == ConversionFlags.ShowTypeParameterList && member.EntityType == EntityType.Method) { |
||||
CreatePrinter(writer).WriteTypeParameters(astBuilder.ConvertEntity(member).GetChildrenByRole(AstNode.Roles.TypeParameter)); |
||||
} |
||||
} |
||||
|
||||
CSharpOutputVisitor CreatePrinter(StringWriter writer) |
||||
{ |
||||
return new CSharpOutputVisitor(writer, new CSharpFormattingOptions()); |
||||
} |
||||
|
||||
void PrintModifiers(Modifiers modifiers, StringWriter writer) |
||||
{ |
||||
foreach (var m in CSharpModifierToken.AllModifiers) { |
||||
if ((modifiers & m) == m) { |
||||
writer.Write(CSharpModifierToken.GetModifierName(m)); |
||||
writer.Write(' '); |
||||
} |
||||
} |
||||
} |
||||
#endregion
|
||||
|
||||
public string ConvertVariable(IVariable v) |
||||
{ |
||||
TypeSystemAstBuilder astBuilder = CreateAstBuilder(); |
||||
AstNode astNode = astBuilder.ConvertVariable(v); |
||||
CSharpFormattingOptions formatting = new CSharpFormattingOptions(); |
||||
StringWriter writer = new StringWriter(); |
||||
astNode.AcceptVisitor(new CSharpOutputVisitor(writer, formatting), null); |
||||
return writer.ToString().TrimEnd(';', '\r', '\n'); |
||||
} |
||||
|
||||
public string ConvertType(IType type) |
||||
{ |
||||
TypeSystemAstBuilder astBuilder = CreateAstBuilder(); |
||||
AstType astType = astBuilder.ConvertType(type); |
||||
CSharpFormattingOptions formatting = new CSharpFormattingOptions(); |
||||
StringWriter writer = new StringWriter(); |
||||
astType.AcceptVisitor(new CSharpOutputVisitor(writer, formatting), null); |
||||
return writer.ToString(); |
||||
} |
||||
|
||||
public string WrapAttribute(string attribute) |
||||
{ |
||||
return "[" + attribute + "]"; |
||||
} |
||||
|
||||
public string WrapComment(string comment) |
||||
{ |
||||
return "// " + comment; |
||||
} |
||||
} |
||||
} |
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue