📄 convertvisitor.cs
字号:
// <file>
// <copyright see="prj:///doc/copyright.txt"/>
// <license see="prj:///doc/license.txt"/>
// <owner name="Daniel Grunwald" email="daniel@danielgrunwald.de"/>
// <version>$Revision: 1379 $</version>
// </file>
using System;
using System.Collections.Generic;
using ICSharpCode.Core;
using ICSharpCode.SharpDevelop.Dom;
using Boo.Lang.Compiler;
using AST = Boo.Lang.Compiler.Ast;
using Boo.Lang.Compiler.IO;
using Boo.Lang.Compiler.Steps;
namespace Grunwald.BooBinding.CodeCompletion
{
public class ConvertVisitor : AbstractVisitorCompilerStep
{
int[] _lineLength;
public ConvertVisitor(int[] _lineLength, IProjectContent pc)
{
this._lineLength = _lineLength;
this._cu = new DefaultCompilationUnit(pc);
}
DefaultCompilationUnit _cu;
public DefaultCompilationUnit Cu {
get {
return _cu;
}
}
Stack<DefaultClass> _currentClass = new Stack<DefaultClass>();
bool _firstModule = true;
public override void Run()
{
try {
Visit(CompileUnit);
} catch (Exception ex) {
MessageService.ShowError(ex);
}
}
protected override void OnError(AST.Node node, Exception error)
{
MessageService.ShowError(error, "error processing " + node.ToCodeString());
}
private ModifierEnum GetModifier(AST.TypeMember m)
{
ModifierEnum r = ModifierEnum.None;
if (m.IsPublic) r |= ModifierEnum.Public;
if (m.IsProtected) r |= ModifierEnum.Protected;
if (m.IsPrivate) r |= ModifierEnum.Private;
if (m.IsInternal) r |= ModifierEnum.Internal;
if (!m.IsVisibilitySet) {
if (m is AST.Field)
r |= ModifierEnum.Protected;
else
r |= ModifierEnum.Public;
}
if (m.IsStatic) r |= ModifierEnum.Static;
if (m is AST.Field) {
if (m.IsFinal) r |= ModifierEnum.Readonly;
} else {
if (m.IsFinal) r |= ModifierEnum.Sealed;
}
if (m.IsAbstract) r |= ModifierEnum.Abstract;
if (m.IsOverride) r |= ModifierEnum.Override;
if (m.IsSynthetic) r |= ModifierEnum.Synthetic;
if (m.IsPartial) r |= ModifierEnum.Partial;
if (m.LexicalInfo.IsValid && m.DeclaringType != null
&& m.LexicalInfo.Line < m.DeclaringType.LexicalInfo.Line)
{ // member added through attribute
r |= ModifierEnum.Synthetic;
}
return r;
}
private int GetLineEnd(int line)
{
if (_lineLength == null || line < 1 || line > _lineLength.Length)
return 0;
else
return _lineLength[line - 1] + 1;
}
private DomRegion GetRegion(AST.Node m)
{
AST.LexicalInfo l = m.LexicalInfo;
if (l.Line < 0)
return DomRegion.Empty;
else
return new DomRegion(l.Line, 0 /*l.Column*/, l.Line, GetLineEnd(l.Line));
}
private DomRegion GetClientRegion(AST.Node m)
{
AST.LexicalInfo l = m.LexicalInfo;
if (l.Line < 0)
return DomRegion.Empty;
AST.SourceLocation l2;
if (m is AST.Method) {
l2 = ((AST.Method)m).Body.EndSourceLocation;
} else if (m is AST.Property) {
AST.Property p = (AST.Property)m;
if (p.Getter != null && p.Getter.Body != null) {
l2 = p.Getter.Body.EndSourceLocation;
if (p.Setter != null && p.Setter.Body != null) {
if (p.Setter.Body.EndSourceLocation.Line > l2.Line)
l2 = p.Setter.Body.EndSourceLocation;
}
} else if (p.Setter != null && p.Setter.Body != null) {
l2 = p.Setter.Body.EndSourceLocation;
} else {
l2 = p.EndSourceLocation;
}
} else {
l2 = m.EndSourceLocation;
}
if (l2 == null || l2.Line < 0 || l.Line == l2.Line)
return DomRegion.Empty;
// TODO: use l.Column / l2.Column when the tab-bug has been fixed
return new DomRegion(l.Line, GetLineEnd(l.Line), l2.Line, GetLineEnd(l2.Line));
}
public override void OnImport(AST.Import p)
{
DefaultUsing u = new DefaultUsing(_cu.ProjectContent);
if (p.Alias == null)
u.Usings.Add(p.Namespace);
else
u.AddAlias(p.Alias.Name, new GetClassReturnType(_cu.ProjectContent, p.Namespace, 0));
_cu.Usings.Add(u);
}
private IClass OuterClass {
get {
if (_currentClass.Count > 0)
return _currentClass.Peek();
else
return null;
}
}
void ConvertTemplates(AST.Node node, DefaultClass c)
{
c.TypeParameters = DefaultTypeParameter.EmptyTypeParameterList;
}
void ConvertTemplates(AST.Node node, DefaultMethod m)
{
m.TypeParameters = DefaultTypeParameter.EmptyTypeParameterList;
}
void ConvertAttributes(AST.TypeMember node, AbstractDecoration c)
{
if (node.Attributes.Count == 0) {
c.Attributes = DefaultAttribute.EmptyAttributeList;
} else {
foreach (AST.Attribute a in node.Attributes) {
c.Attributes.Add(new DefaultAttribute(a.Name));
}
}
c.Documentation = node.Documentation;
}
void ConvertParameters(AST.ParameterDeclarationCollection parameters, DefaultMethod m)
{
if (parameters == null || parameters.Count == 0) {
m.Parameters = DefaultParameter.EmptyParameterList;
} else {
AddParameters(parameters, m.Parameters, m, m.DeclaringType);
}
}
void ConvertParameters(AST.ParameterDeclarationCollection parameters, DefaultProperty p)
{
if (parameters == null || parameters.Count == 0) {
p.Parameters = DefaultParameter.EmptyParameterList;
} else {
AddParameters(parameters, p.Parameters, p, p.DeclaringType);
}
}
internal static void AddParameters(AST.ParameterDeclarationCollection parameters, IList<IParameter> output, IMethodOrProperty method, IClass c)
{
if (c == null) throw new ArgumentNullException("c");
DefaultParameter p = null;
foreach (AST.ParameterDeclaration par in parameters) {
p = new DefaultParameter(par.Name,
CreateReturnType(par.Type, c, method as IMethod, c.Region.BeginLine + 1, 1, c.ProjectContent),
new DomRegion(par.LexicalInfo.Line, par.LexicalInfo.Column));
if (par.IsByRef) p.Modifiers |= ParameterModifiers.Ref;
output.Add(p);
}
if (parameters.VariableNumber) {
p.Modifiers |= ParameterModifiers.Params;
}
}
IReturnType CreateReturnType(AST.TypeReference reference, IMethod method)
{
IClass c = OuterClass;
if (c == null) {
return CreateReturnType(reference, new DefaultClass(_cu, "___DummyClass"), method, 1, 1, _cu.ProjectContent);
} else {
return CreateReturnType(reference, c, method, c.Region.BeginLine + 1, 1, _cu.ProjectContent);
}
}
internal static IReturnType GetDefaultReturnType(IProjectContent projectContent)
{
BooProject project = projectContent.Project as BooProject;
if (project != null && project.Ducky)
return new BooResolver.DuckClass(new DefaultCompilationUnit(projectContent)).DefaultReturnType;
else
return ReflectionReturnType.Object;
}
public static IReturnType CreateReturnType(AST.TypeReference reference, IClass callingClass,
IMethodOrProperty callingMember, int caretLine, int caretColumn,
IProjectContent projectContent)
{
System.Diagnostics.Debug.Assert(projectContent != null);
if (reference == null) {
return GetDefaultReturnType(projectContent);
}
if (reference is AST.ArrayTypeReference) {
AST.ArrayTypeReference arr = (AST.ArrayTypeReference)reference;
return new ArrayReturnType(CreateReturnType(arr.ElementType, callingClass, callingMember,
caretLine, caretColumn, projectContent),
(arr.Rank != null) ? (int)arr.Rank.Value : 1);
} else if (reference is AST.SimpleTypeReference) {
string name = ((AST.SimpleTypeReference)reference).Name;
IReturnType rt;
int typeParameterCount = (reference is AST.GenericTypeReference) ? ((AST.GenericTypeReference)reference).GenericArguments.Count : 0;
if (name == "duck")
rt = new BooResolver.DuckClass(new DefaultCompilationUnit(projectContent)).DefaultReturnType;
else if (BooAmbience.ReverseTypeConversionTable.ContainsKey(name))
rt = new GetClassReturnType(projectContent, BooAmbience.ReverseTypeConversionTable[name], typeParameterCount);
else
rt = new SearchClassReturnType(projectContent, callingClass, caretLine, caretColumn,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -