Browse Source

BooBinding: Implemented inferring the return type from the "return" statement.

git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/trunk@578 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61
shortcuts
Daniel Grunwald 20 years ago
parent
commit
0b29102431
  1. 4
      src/AddIns/BackendBindings/Boo/BooBinding/Project/Src/CodeCompletion/ConvertVisitor.cs
  2. 63
      src/AddIns/BackendBindings/Boo/BooBinding/Project/Src/CodeCompletion/InferredReturnType.cs
  3. 40
      src/AddIns/BackendBindings/Boo/BooBinding/Project/Src/CodeCompletion/ResolveVisitor.cs
  4. 2
      src/Main/Base/Project/Src/Dom/Implementations/NullReturnType.cs
  5. 14
      src/Main/Base/Project/Src/Dom/MemberLookupHelper.cs
  6. 3
      src/Main/Base/Project/Src/Dom/NRefactoryResolver/TypeVisitor.cs

4
src/AddIns/BackendBindings/Boo/BooBinding/Project/Src/CodeCompletion/ConvertVisitor.cs

@ -234,10 +234,14 @@ namespace Grunwald.BooBinding.CodeCompletion @@ -234,10 +234,14 @@ namespace Grunwald.BooBinding.CodeCompletion
// TODO: Type inference
IReturnType CreateReturnType(AST.Method node, IMethod method)
{
if (node.ReturnType == null)
return new InferredReturnType(node.Body);
return CreateReturnType(node.ReturnType, method);
}
IReturnType CreateReturnType(AST.Property property)
{
if (property.Type == null && property.Getter != null && property.Getter.Body != null)
return new InferredReturnType(property.Getter.Body);
return CreateReturnType(property.Type);
}

63
src/AddIns/BackendBindings/Boo/BooBinding/Project/Src/CodeCompletion/InferredReturnType.cs

@ -18,29 +18,76 @@ namespace Grunwald.BooBinding.CodeCompletion @@ -18,29 +18,76 @@ namespace Grunwald.BooBinding.CodeCompletion
public class InferredReturnType : ProxyReturnType
{
Expression expression;
Block block;
IReturnType cachedType;
public InferredReturnType(Expression expression)
{
if (expression == null) throw new ArgumentNullException("expression");
this.expression = expression;
}
bool needInfer = true;
IReturnType cachedType;
public InferredReturnType(Block block)
{
if (block == null) throw new ArgumentNullException("block");
this.block = block;
}
public override bool IsDefaultReturnType {
get {
IReturnType baseType = BaseType;
return (baseType != null) ? baseType.IsDefaultReturnType : false;
}
}
public override IReturnType BaseType {
get {
if (needInfer) {
needInfer = false;
// clear up references to method/expression after the type has been resolved
if (block != null) {
GetReturnTypeVisitor v = new GetReturnTypeVisitor();
v.Visit(block);
block = null;
if (v.noReturnStatement)
cachedType = ReflectionReturnType.Void;
else if (v.result is NullReturnType)
cachedType = ReflectionReturnType.Object;
else
cachedType = v.result;
} else if (expression != null) {
cachedType = new BooResolver().GetTypeOfExpression(expression);
expression = null;
}
return cachedType;
}
}
public override bool IsDefaultReturnType {
get {
IReturnType baseType = BaseType;
return (baseType != null) ? baseType.IsDefaultReturnType : false;
class GetReturnTypeVisitor : DepthFirstVisitor
{
public IReturnType result;
public bool noReturnStatement = true;
public override void OnReturnStatement(ReturnStatement node)
{
noReturnStatement = false;
if (node.Expression == null) {
result = ReflectionReturnType.Void;
} else {
result = new BooResolver().GetTypeOfExpression(node.Expression);
}
}
public override void OnYieldStatement(YieldStatement node)
{
noReturnStatement = false;
result = ReflectionReturnType.CreatePrimitive(typeof(System.Collections.IEnumerable));
}
public override bool Visit(Node node)
{
if (result != null && !(result is NullReturnType))
return false;
else
return base.Visit(node);
}
}
}

40
src/AddIns/BackendBindings/Boo/BooBinding/Project/Src/CodeCompletion/ResolveVisitor.cs

@ -369,6 +369,46 @@ namespace Grunwald.BooBinding.CodeCompletion @@ -369,6 +369,46 @@ namespace Grunwald.BooBinding.CodeCompletion
}
#endregion
public override void OnBinaryExpression(BinaryExpression node)
{
switch (node.Operator) {
case BinaryOperatorType.GreaterThan:
case BinaryOperatorType.GreaterThanOrEqual:
case BinaryOperatorType.Inequality:
case BinaryOperatorType.LessThan:
case BinaryOperatorType.LessThanOrEqual:
case BinaryOperatorType.Match:
case BinaryOperatorType.Member:
case BinaryOperatorType.NotMatch:
case BinaryOperatorType.NotMember:
case BinaryOperatorType.Or:
case BinaryOperatorType.And:
case BinaryOperatorType.ReferenceEquality:
case BinaryOperatorType.ReferenceInequality:
case BinaryOperatorType.TypeTest:
MakeResult(ReflectionReturnType.Bool);
break;
default:
if (node.Left == null) {
if (node.Right == null) {
resolveResult = null;
} 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);

2
src/Main/Base/Project/Src/Dom/Implementations/NullReturnType.cs

@ -11,8 +11,8 @@ using ICSharpCode.Core; @@ -11,8 +11,8 @@ using ICSharpCode.Core;
namespace ICSharpCode.SharpDevelop.Dom
{
/// <summary>The type of the 'null'/'nothing' literal.</summary>
[Serializable]
/// <summary>The type of the 'null'/'nothing' literal.</summary>
public sealed class NullReturnType : AbstractReturnType
{
public static readonly NullReturnType Instance = new NullReturnType();

14
src/Main/Base/Project/Src/Dom/MemberLookupHelper.cs

@ -671,5 +671,19 @@ namespace ICSharpCode.SharpDevelop.Dom @@ -671,5 +671,19 @@ namespace ICSharpCode.SharpDevelop.Dom
}
}
#endregion
/// <summary>
/// Gets the common base type of a and b.
/// </summary>
public static IReturnType GetCommonType(IReturnType a, IReturnType b)
{
if (a == null) return b;
if (b == null) return a;
if (ConversionExists(a, b))
return b;
if (ConversionExists(b, a))
return a;
return ReflectionReturnType.Object;
}
}
}

3
src/Main/Base/Project/Src/Dom/NRefactoryResolver/TypeVisitor.cs

@ -60,7 +60,8 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver @@ -60,7 +60,8 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver
case BinaryOperatorType.GreaterThanOrEqual:
return ReflectionReturnType.Bool;
default:
return binaryOperatorExpression.Left.AcceptVisitor(this, data);
return MemberLookupHelper.GetCommonType(binaryOperatorExpression.Left.AcceptVisitor(this, data) as IReturnType,
binaryOperatorExpression.Right.AcceptVisitor(this, data) as IReturnType);
}
}

Loading…
Cancel
Save