You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
298 lines
9.0 KiB
298 lines
9.0 KiB
// <file> |
|
// <copyright see="prj:///doc/copyright.txt"/> |
|
// <license see="prj:///doc/license.txt"/> |
|
// <owner name="Daniel Grunwald" email="daniel@danielgrunwald.de"/> |
|
// <version>$Revision$</version> |
|
// </file> |
|
|
|
using System; |
|
using System.Collections.Generic; |
|
using Boo.Lang.Compiler; |
|
using ICSharpCode.NRefactory; |
|
using ICSharpCode.NRefactory.Ast; |
|
using B = Boo.Lang.Compiler.Ast; |
|
|
|
namespace NRefactoryToBooConverter |
|
{ |
|
public sealed partial class ConvertVisitor : IAstVisitor |
|
{ |
|
string fileName; |
|
CompilerErrorCollection errors; |
|
CompilerWarningCollection warnings; |
|
StringComparer nameComparer; |
|
ConverterSettings settings; |
|
|
|
B.Module module; |
|
|
|
public ConvertVisitor(ConverterSettings settings) |
|
{ |
|
this.settings = settings; |
|
this.fileName = settings.FileName; |
|
this.errors = settings.Errors; |
|
this.warnings = settings.Warnings; |
|
this.nameComparer = settings.NameComparer; |
|
} |
|
|
|
int generatedNameNumber; |
|
|
|
string GenerateName() |
|
{ |
|
return settings.NameGenerationPrefix + (++generatedNameNumber).ToString(System.Globalization.NumberFormatInfo.InvariantInfo); |
|
} |
|
|
|
B.LexicalInfo lastLexicalInfo; |
|
|
|
B.LexicalInfo GetLexicalInfo(INode node) |
|
{ |
|
if (node == null) |
|
return new B.LexicalInfo(fileName); |
|
Location point = node.StartLocation; |
|
if (!point.IsEmpty) { |
|
lastLexicalInfo = new B.LexicalInfo(fileName, point.Y, point.X); |
|
} |
|
if (lastLexicalInfo == null) { |
|
lastLexicalInfo = new B.LexicalInfo(fileName); |
|
} |
|
return lastLexicalInfo; |
|
} |
|
|
|
void AddError(B.LexicalInfo lex, string errorMessage) |
|
{ |
|
errors.Add(new CompilerError(lex, errorMessage)); |
|
} |
|
|
|
void AddError(INode node, string errorMessage) |
|
{ |
|
AddError(GetLexicalInfo(node), errorMessage); |
|
} |
|
|
|
void AddWarning(B.LexicalInfo lex, string warningMessage) |
|
{ |
|
warnings.Add(new CompilerWarning(lex, warningMessage)); |
|
} |
|
|
|
void AddWarning(INode node, string warningMessage) |
|
{ |
|
AddWarning(GetLexicalInfo(node), warningMessage); |
|
} |
|
|
|
B.SourceLocation GetEndLocation(INode node) |
|
{ |
|
return GetLocation(node.EndLocation); |
|
} |
|
|
|
B.SourceLocation GetLocation(Location point) |
|
{ |
|
return new B.SourceLocation(point.Y, point.X); |
|
} |
|
|
|
B.TypeMemberModifiers ConvertModifier(AttributedNode node, B.TypeMemberModifiers defaultVisibility) |
|
{ |
|
Modifiers m = node.Modifier; |
|
B.TypeMemberModifiers r = B.TypeMemberModifiers.None; |
|
if ((m & Modifiers.Private) != 0) |
|
r |= B.TypeMemberModifiers.Private; |
|
if ((m & Modifiers.Internal) != 0) |
|
r |= B.TypeMemberModifiers.Internal; |
|
if ((m & Modifiers.Public) != 0) |
|
r |= B.TypeMemberModifiers.Public; |
|
if ((m & Modifiers.Protected) != 0) |
|
r |= B.TypeMemberModifiers.Protected; |
|
if (r == B.TypeMemberModifiers.None) |
|
r = defaultVisibility; |
|
|
|
if ((m & Modifiers.Abstract) != 0) |
|
r |= B.TypeMemberModifiers.Abstract; |
|
if ((m & Modifiers.Virtual) != 0) |
|
r |= B.TypeMemberModifiers.Virtual; |
|
if ((m & Modifiers.Sealed) != 0) |
|
r |= B.TypeMemberModifiers.Final; |
|
if ((m & Modifiers.Static) != 0) { |
|
r |= B.TypeMemberModifiers.Static; |
|
} else if (currentType != null && currentType.IsStatic) { |
|
if (!(node is TypeDeclaration)) |
|
r |= B.TypeMemberModifiers.Static; |
|
} |
|
if ((m & Modifiers.Override) != 0) |
|
r |= B.TypeMemberModifiers.Override; |
|
if ((m & Modifiers.ReadOnly) != 0 && !(node is PropertyDeclaration)) { |
|
r |= B.TypeMemberModifiers.Final; |
|
} |
|
if ((m & Modifiers.Const) != 0) { |
|
r |= B.TypeMemberModifiers.Final | B.TypeMemberModifiers.Static; |
|
} |
|
if ((m & Modifiers.New) != 0) { |
|
AddError(node, "shadowing is not supported"); |
|
} |
|
if ((m & Modifiers.Partial) != 0) { |
|
r |= B.TypeMemberModifiers.Partial; |
|
} |
|
if ((m & Modifiers.Extern) != 0) { |
|
// not necessary in Boo |
|
} |
|
if ((m & Modifiers.Volatile) != 0) { |
|
AddError(node, "Volatile modifier is not supported"); |
|
} |
|
if ((m & Modifiers.Unsafe) != 0) { |
|
AddError(node, "Unsafe modifier is not supported"); |
|
} |
|
if ((m & Modifiers.Overloads) != 0) { |
|
// not necessary in Boo |
|
} |
|
if ((m & Modifiers.WithEvents) != 0) { |
|
// not necessary in Boo |
|
} |
|
return r; |
|
} |
|
|
|
B.Attribute MakeAttribute(string name, params B.Expression[] arguments) |
|
{ |
|
B.Attribute a = new B.Attribute(lastLexicalInfo, name); |
|
foreach (B.Expression arg in arguments) { |
|
a.Arguments.Add(arg); |
|
} |
|
return a; |
|
} |
|
|
|
void ConvertTypeReferences(List<TypeReference> input, B.TypeReferenceCollection output) |
|
{ |
|
foreach (TypeReference t in input) { |
|
B.TypeReference r = ConvertTypeReference(t); |
|
if (r != null) { |
|
output.Add(r); |
|
} |
|
} |
|
} |
|
|
|
Dictionary<string, string> intrinsicTypeDictionary; |
|
|
|
class BooTypeSystemServices : Boo.Lang.Compiler.TypeSystem.TypeSystemServices |
|
{ |
|
public System.Collections.Hashtable Primitives { |
|
get { |
|
return _primitives; |
|
} |
|
} |
|
} |
|
|
|
string GetIntrinsicTypeName(string typeName) |
|
{ |
|
if (settings.SimplifyTypeNames) { |
|
if (intrinsicTypeDictionary == null) { |
|
intrinsicTypeDictionary = new Dictionary<string, string>(); |
|
intrinsicTypeDictionary.Add("System.Void", "void"); |
|
intrinsicTypeDictionary.Add("System.Object", "object"); |
|
intrinsicTypeDictionary.Add("System.Boolean", "bool"); |
|
intrinsicTypeDictionary.Add("System.Byte", "byte"); |
|
intrinsicTypeDictionary.Add("System.SByte", "sbyte"); |
|
intrinsicTypeDictionary.Add("System.Char", "char"); |
|
intrinsicTypeDictionary.Add("System.Int16", "short"); |
|
intrinsicTypeDictionary.Add("System.Int32", "int"); |
|
intrinsicTypeDictionary.Add("System.Int64", "long"); |
|
intrinsicTypeDictionary.Add("System.UInt16", "ushort"); |
|
intrinsicTypeDictionary.Add("System.UInt32", "uint"); |
|
intrinsicTypeDictionary.Add("System.UInt64", "ulong"); |
|
intrinsicTypeDictionary.Add("System.Single", "single"); |
|
intrinsicTypeDictionary.Add("System.Double", "double"); |
|
intrinsicTypeDictionary.Add("System.Decimal", "decimal"); |
|
intrinsicTypeDictionary.Add("System.String", "string"); |
|
intrinsicTypeDictionary.Add("System.DateTime", "date"); |
|
intrinsicTypeDictionary.Add("System.TimeSpan", "timespan"); |
|
intrinsicTypeDictionary.Add("System.Type", "type"); |
|
intrinsicTypeDictionary.Add("System.Array", "array"); |
|
intrinsicTypeDictionary.Add("System.Text.RegularExpressions.Regex", "regex"); |
|
} |
|
string result; |
|
if (intrinsicTypeDictionary.TryGetValue(typeName, out result)) |
|
return result; |
|
} |
|
return typeName; |
|
} |
|
|
|
B.TypeReference ConvertTypeReference(TypeReference t) |
|
{ |
|
if (t == null || t.IsNull) |
|
return null; |
|
B.TypeReference r; |
|
if (t.GenericTypes.Count > 0) { |
|
r = new B.GenericTypeReference(GetLexicalInfo(t), GetIntrinsicTypeName(t.Type)); |
|
foreach (TypeReference ta in t.GenericTypes) { |
|
((B.GenericTypeReference)r).GenericArguments.Add(ConvertTypeReference(ta)); |
|
} |
|
} else { |
|
r = new B.SimpleTypeReference(GetLexicalInfo(t), GetIntrinsicTypeName(t.Type)); |
|
} |
|
if (t.IsArrayType) { |
|
for (int i = t.RankSpecifier.Length - 1; i >= 0; --i) { |
|
r = new B.ArrayTypeReference(GetLexicalInfo(t), r, new B.IntegerLiteralExpression(t.RankSpecifier[i] + 1)); |
|
} |
|
} |
|
if (t.PointerNestingLevel != 0) { |
|
AddError(t, "Pointers are not supported by boo."); |
|
} |
|
return r; |
|
} |
|
|
|
B.TypeReference ConvertTypeReference(B.Expression expr) |
|
{ |
|
B.TypeofExpression te = expr as B.TypeofExpression; |
|
if (te != null) |
|
return te.Type; |
|
if (expr is B.ReferenceExpression) { |
|
return new B.SimpleTypeReference(expr.ToCodeString()); |
|
} |
|
AddError(expr.LexicalInfo, "Expected type, but found expression."); |
|
return null; |
|
} |
|
|
|
public object VisitTypeReference(TypeReference typeReference, object data) |
|
{ |
|
return ConvertTypeReference(typeReference); |
|
} |
|
|
|
public object VisitInnerClassTypeReference(InnerClassTypeReference typeReference, object data) |
|
{ |
|
return ConvertTypeReference(typeReference); |
|
} |
|
|
|
public object VisitCollectionRangeVariable(CollectionRangeVariable collectionRangeVariable, object data) |
|
{ |
|
throw new NotImplementedException(); |
|
} |
|
|
|
public object VisitMemberInitializerExpression(MemberInitializerExpression memberInitializerExpression, object data) |
|
{ |
|
throw new NotImplementedException(); |
|
} |
|
|
|
public object VisitXmlAttribute(XmlAttribute xmlAttribute, object data) |
|
{ |
|
throw new NotImplementedException(); |
|
} |
|
|
|
public object VisitXmlContentExpression(XmlContentExpression xmlContentExpression, object data) |
|
{ |
|
throw new NotImplementedException(); |
|
} |
|
|
|
public object VisitXmlElementExpression(XmlElementExpression xmlElementExpression, object data) |
|
{ |
|
throw new NotImplementedException(); |
|
} |
|
|
|
public object VisitXmlEmbeddedExpression(XmlEmbeddedExpression xmlEmbeddedExpression, object data) |
|
{ |
|
throw new NotImplementedException(); |
|
} |
|
|
|
public object VisitXmlLiteralExpression(XmlLiteralExpression xmlLiteralExpression, object data) |
|
{ |
|
throw new NotImplementedException(); |
|
} |
|
|
|
public object VisitXmlMemberAccessExpression(XmlMemberAccessExpression xmlMemberAccessExpression, object data) |
|
{ |
|
throw new NotImplementedException(); |
|
} |
|
} |
|
}
|
|
|