📄 resolvevisitor.cs
字号:
#endregion
#region Resolve Method Invocation
public override void OnMethodInvocationExpression(MethodInvocationExpression node)
{
ClearResult();
node.Target.Accept(this);
if (resolveResult is MixedResolveResult) {
MixedResolveResult mixed = (MixedResolveResult)resolveResult;
resolveResult = mixed.TypeResult;
foreach (ResolveResult rr in mixed.Results) {
if (rr is MethodResolveResult) {
resolveResult = rr;
break;
}
}
}
if (resolveResult == null)
return;
if (resolveResult is MethodResolveResult) {
// normal method call
string methodName = ((MethodResolveResult)resolveResult).Name;
IReturnType containingType = ((MethodResolveResult)resolveResult).ContainingType;
ResolveMethodInType(containingType, methodName, node.Arguments);
} else if (resolveResult is TypeResolveResult) {
TypeResolveResult trr = (TypeResolveResult)resolveResult;
if (trr.ResolvedClass != null) {
if (trr.ResolvedClass.FullyQualifiedName == "array") {
ResolveArrayCreation(node.Arguments);
return;
}
List<IMethod> methods = new List<IMethod>();
bool isClassInInheritanceTree = false;
if (callingClass != null)
isClassInInheritanceTree = callingClass.IsTypeInInheritanceTree(trr.ResolvedClass);
foreach (IMethod m in trr.ResolvedClass.Methods) {
if (m.IsConstructor && !m.IsStatic
&& m.IsAccessible(callingClass, isClassInInheritanceTree))
{
methods.Add(m);
}
}
if (methods.Count == 0) {
methods.Add(ICSharpCode.SharpDevelop.Dom.Constructor.CreateDefault(trr.ResolvedClass));
}
ResolveInvocation(methods, node.Arguments);
if (resolveResult != null)
resolveResult.ResolvedType = trr.ResolvedType;
} else {
ClearResult();
}
} else if (resolveResult.ResolvedType != null) {
// maybe event or callable call or call on System.Type -> constructor by reflection
IClass c = resolveResult.ResolvedType.GetUnderlyingClass();
if (c != null) {
if (c.ClassType == ClassType.Delegate) {
// find the delegate's invoke method
IMethod invoke = c.Methods.Find(delegate(IMethod innerMethod) { return innerMethod.Name == "Invoke"; });
if (invoke != null) {
resolveResult.ResolvedType = invoke.ReturnType;
}
} else if (c.FullyQualifiedName == "System.Type") {
resolveResult.ResolvedType = ReflectionReturnType.Object;
} else {
ClearResult();
}
} else {
ClearResult();
}
} else {
ClearResult();
}
}
void ResolveArrayCreation(ExpressionCollection arguments)
{
if (arguments.Count == 2) {
ClearResult();
arguments[0].Accept(this);
TypeResolveResult trr = resolveResult as TypeResolveResult;
if (trr != null) {
MakeResult(new ArrayReturnType(trr.ResolvedType, 1));
}
} else {
ResolveMethodInType(new GetClassReturnType(projectContent, "Boo.Lang.Builtins", 0),
"array", arguments);
}
}
void ResolveMethodInType(IReturnType containingType, string methodName, ExpressionCollection arguments)
{
List<IMethod> methods = new List<IMethod>();
bool isClassInInheritanceTree = false;
if (callingClass != null)
isClassInInheritanceTree = callingClass.IsTypeInInheritanceTree(containingType.GetUnderlyingClass());
foreach (IMethod m in containingType.GetMethods()) {
if (IsSameName(m.Name, methodName)
&& m.IsAccessible(callingClass, isClassInInheritanceTree)
) {
methods.Add(m);
}
}
if (methods.Count == 0) {
ArrayList list = new ArrayList();
ResolveResult.AddExtensions(callingClass.ProjectContent.Language, list, callingClass, containingType);
foreach (IMethodOrProperty mp in list) {
if (IsSameName(mp.Name, methodName) && mp is IMethod) {
IMethod m = (IMethod)mp.Clone();
m.Parameters.RemoveAt(0);
methods.Add(m);
}
}
}
ResolveInvocation(methods, arguments);
}
void ResolveInvocation(List<IMethod> methods, ExpressionCollection arguments)
{
ClearResult();
if (methods.Count == 0) {
return;
}
// MemberLookupHelper does type argument inference and type substitution for us
IReturnType[] types = new IReturnType[arguments.Count];
for (int i = 0; i < types.Length; ++i) {
arguments[i].Accept(this);
types[i] = (resolveResult != null) ? resolveResult.ResolvedType : null;
ClearResult();
}
MakeResult(MemberLookupHelper.FindOverload(methods, new IReturnType[0], types));
}
#endregion
#region Resolve Slice Expression
public override void OnSlicingExpression(SlicingExpression node)
{
ClearResult();
Visit(node.Target);
if (node.Indices.Count > 0) {
Slice slice = node.Indices[0];
if (slice.End != null) {
// Boo slice, returns a part of the source -> same type as source
return;
}
}
IReturnType rt = (resolveResult != null) ? resolveResult.ResolvedType : null;
if (rt == null) {
ClearResult();
return;
}
List<IProperty> indexers = rt.GetProperties();
// remove non-indexers:
for (int i = 0; i < indexers.Count; i++) {
if (!indexers[i].IsIndexer)
indexers.RemoveAt(i--);
}
IReturnType[] parameters = new IReturnType[node.Indices.Count];
for (int i = 0; i < parameters.Length; i++) {
Expression expr = node.Indices[i].Begin as Expression;
if (expr != null) {
ClearResult();
Visit(expr);
parameters[i] = (resolveResult != null) ? resolveResult.ResolvedType : null;
}
}
MakeResult(MemberLookupHelper.FindOverload(indexers.ToArray(), parameters));
}
#endregion
public override void OnGeneratorExpression(GeneratorExpression node)
{
ClearResult();
node.Expression.Accept(this);
if (resolveResult != null) {
IClass enumerable = ProjectContentRegistry.Mscorlib.GetClass("System.Collections.Generic.IEnumerable", 1);
MakeResult(new ConstructedReturnType(enumerable.DefaultReturnType, new IReturnType[] { resolveResult.ResolvedType }));
} else {
MakeResult(new GetClassReturnType(projectContent, "System.Collections.IEnumerable", 0));
}
}
public override void OnBinaryExpression(BinaryExpression node)
{
switch (node.Operator) {
case BinaryOperatorType.GreaterThan:
case BinaryOperatorType.GreaterThanOrEqual:
case BinaryOperatorType.Equality:
case BinaryOperatorType.Inequality:
case BinaryOperatorType.LessThan:
case BinaryOperatorType.LessThanOrEqual:
case BinaryOperatorType.Match:
case BinaryOperatorType.Member:
case BinaryOperatorType.NotMatch:
case BinaryOperatorType.NotMember:
case BinaryOperatorType.ReferenceEquality:
case BinaryOperatorType.ReferenceInequality:
case BinaryOperatorType.TypeTest:
MakeResult(ReflectionReturnType.Bool);
break;
default:
if (node.Left == null) {
if (node.Right == null) {
ClearResult();
} else {
node.Right.Accept(this);
}
return;
} else if (node.Right == null) {
node.Left.Accept(this);
return;
}
node.Left.Accept(this);
IReturnType left = (resolveResult != null) ? resolveResult.ResolvedType : null;
node.Right.Accept(this);
IReturnType right = (resolveResult != null) ? resolveResult.ResolvedType : null;
MakeResult(MemberLookupHelper.GetCommonType(left, right));
break;
}
}
protected override void OnError(Node node, Exception error)
{
MessageService.ShowError(error, "ResolveVisitor: error processing " + node);
}
public override void OnCallableBlockExpression(CallableBlockExpression node)
{
AnonymousMethodReturnType amrt = new AnonymousMethodReturnType(cu);
if (node.ReturnType != null) {
amrt.MethodReturnType = ConvertType(node.ReturnType);
} else {
amrt.MethodReturnType = new InferredReturnType(node.Body, resolver.CallingClass,
node.ContainsAnnotation("inline"));
}
ConvertVisitor.AddParameters(node.Parameters, amrt.MethodParameters, resolver.CallingMember, resolver.CallingClass ?? new DefaultClass(resolver.CompilationUnit, "__Dummy"));
MakeResult(amrt);
}
public override void OnCallableTypeReference(CallableTypeReference node)
{
MakeTypeResult(ConvertType(node));
}
public override void OnRELiteralExpression(RELiteralExpression node)
{
MakeLiteralResult("System.Text.RegularExpressions.Regex");
}
public override void OnCharLiteralExpression(CharLiteralExpression node)
{
MakeLiteralResult("System.Char");
}
public override void OnArrayLiteralExpression(ArrayLiteralExpression node)
{
if (node.Type != null) {
MakeResult(ConvertType(node.Type));
return;
}
IReturnType elementType = null;
foreach (Expression expr in node.Items) {
ClearResult();
expr.Accept(this);
IReturnType thisType = (resolveResult != null) ? resolveResult.ResolvedType : null;
if (elementType == null)
elementType = thisType;
else if (thisType != null)
elementType = MemberLookupHelper.GetCommonType(elementType, thisType);
}
if (elementType == null)
elementType = ReflectionReturnType.Object;
MakeResult(new ArrayReturnType(elementType, 1));
}
public override void OnTryCastExpression(TryCastExpression node)
{
MakeResult(ConvertType(node.Type));
}
public override void OnCastExpression(CastExpression node)
{
MakeResult(ConvertType(node.Type));
}
public override void OnBoolLiteralExpression(BoolLiteralExpression node)
{
MakeResult(ReflectionReturnType.Bool);
}
public override void OnDoubleLiteralExpression(DoubleLiteralExpression node)
{
if (node.IsSingle)
MakeLiteralResult("System.Single");
else
MakeLiteralResult("System.Double");
}
public override void OnListLiteralExpression(ListLiteralExpression node)
{
MakeLiteralResult("Boo.Lang.List");
}
public override void OnHashLiteralExpression(HashLiteralExpression node)
{
MakeLiteralResult("Boo.Lang.Hash");
}
public override void OnIntegerLiteralExpression(IntegerLiteralExpression node)
{
if (node.IsLong)
MakeLiteralResult("System.Int64");
else
MakeResult(ReflectionReturnType.Int);
}
public override void OnNullLiteralExpression(NullLiteralExpression node)
{
MakeResult(NullReturnType.Instance);
}
public override void OnSelfLiteralExpression(SelfLiteralExpression node)
{
if (callingClass == null)
ClearResult();
else
MakeResult(callingClass.DefaultReturnType);
}
public override void OnSuperLiteralExpression(SuperLiteralExpression node)
{
if (callingClass == null)
ClearResult();
else
MakeResult(callingClass.BaseType);
}
public override void OnSimpleTypeReference(SimpleTypeReference node)
{
MakeTypeResult(ConvertType(node));
}
public override void OnStringLiteralExpression(StringLiteralExpression node)
{
MakeResult(ReflectionReturnType.String);
}
public override void OnTimeSpanLiteralExpression(TimeSpanLiteralExpression node)
{
MakeLiteralResult("System.TimeSpan");
}
public override void OnTypeofExpression(TypeofExpression node)
{
MakeLiteralResult("System.Type");
}
IReturnType ConvertType(TypeReference typeRef)
{
return resolver.ConvertType(typeRef);
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -