Browse Source

Added support for local variables and simple type inference to BooBinding.

git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/trunk@545 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61
shortcuts
Daniel Grunwald 20 years ago
parent
commit
6b4df3a30e
  1. 5
      src/AddIns/BackendBindings/Boo/BooBinding/Project/BooBinding.csproj
  2. 6
      src/AddIns/BackendBindings/Boo/BooBinding/Project/Src/AssemblyInfo.cs
  3. 54
      src/AddIns/BackendBindings/Boo/BooBinding/Project/Src/CodeCompletion/BooResolver.cs
  4. 14
      src/AddIns/BackendBindings/Boo/BooBinding/Project/Src/CodeCompletion/ConvertVisitor.cs
  5. 47
      src/AddIns/BackendBindings/Boo/BooBinding/Project/Src/CodeCompletion/InferredReturnType.cs
  6. 18
      src/AddIns/BackendBindings/Boo/BooBinding/Project/Src/CodeCompletion/ResolveVisitor.cs
  7. 153
      src/AddIns/BackendBindings/Boo/BooBinding/Project/Src/CodeCompletion/VariableLookupVisitor.cs
  8. 8
      src/AddIns/BackendBindings/Boo/NRefactoryToBooConverter/Project/AssemblyInfo.cs
  9. 2
      src/AddIns/BackendBindings/Boo/StandaloneConverter/AssemblyInfo.cs

5
src/AddIns/BackendBindings/Boo/BooBinding/Project/BooBinding.csproj

@ -34,6 +34,8 @@ @@ -34,6 +34,8 @@
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Xml" />
<Reference Include="System.Drawing" />
<Reference Include="System.Windows.Forms" />
<Reference Include="Boo.Lang.Compiler">
<HintPath>..\..\RequiredLibraries\Boo.Lang.Compiler.dll</HintPath>
<SpecificVersion>False</SpecificVersion>
@ -46,7 +48,6 @@ @@ -46,7 +48,6 @@
<HintPath>..\..\RequiredLibraries\Boo.Lang.Parser.dll</HintPath>
<SpecificVersion>False</SpecificVersion>
</Reference>
<Reference Include="System.Windows.Forms" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="Resources\Boo.xshd">
@ -63,6 +64,8 @@ @@ -63,6 +64,8 @@
<Compile Include="Src\CodeCompletion\ResolveVisitor.cs" />
<Compile Include="Src\CodeCompletion\CompletionBinding.cs" />
<Compile Include="Src\BooLanguageProperties.cs" />
<Compile Include="Src\CodeCompletion\VariableLookupVisitor.cs" />
<Compile Include="Src\CodeCompletion\InferredReturnType.cs" />
</ItemGroup>
<ItemGroup>
<Content Include="BooBinding.addin">

6
src/AddIns/BackendBindings/Boo/BooBinding/Project/Src/AssemblyInfo.cs

@ -24,9 +24,3 @@ using System.Runtime.CompilerServices; @@ -24,9 +24,3 @@ using System.Runtime.CompilerServices;
// numbers with the '*' character (the default):
[assembly: AssemblyVersion("2.0.0.1")]
// The following attributes specify the key for the sign of your assembly. See the
// .NET Framework documentation for more information about signing.
// This is not required, if you don't want signing let these attributes like they're.
[assembly: AssemblyDelaySign(false)]
[assembly: AssemblyKeyFile("")]

54
src/AddIns/BackendBindings/Boo/BooBinding/Project/Src/CodeCompletion/BooResolver.cs

@ -117,6 +117,30 @@ namespace Grunwald.BooBinding.CodeCompletion @@ -117,6 +117,30 @@ namespace Grunwald.BooBinding.CodeCompletion
}
#endregion
#region GetTypeOfExpression
public IReturnType GetTypeOfExpression(AST.Expression expr)
{
if (!Initialize(expr.LexicalInfo.FileName, expr.LexicalInfo.Line, expr.LexicalInfo.Column))
return null;
ResolveVisitor visitor = new ResolveVisitor(this);
visitor.Visit(expr);
if (visitor.ResolveResult == null)
return null;
else
return visitor.ResolveResult.ResolvedType;
}
#endregion
#region GetCurrentBooMethod
AST.Node GetCurrentBooMethod()
{
if (callingMember == null)
return null;
// TODO: don't save boo's AST in userdata, but parse fileContent here
return callingMember.UserData as AST.Node;
}
#endregion
#region Resolve
public ResolveResult Resolve(ExpressionResult expressionResult,
int caretLineNumber, int caretColumn,
@ -131,6 +155,19 @@ namespace Grunwald.BooBinding.CodeCompletion @@ -131,6 +155,19 @@ namespace Grunwald.BooBinding.CodeCompletion
visitor.Visit(expr);
return visitor.ResolveResult;
}
public IReturnType ConvertType(AST.TypeReference typeRef)
{
return ConvertVisitor.CreateReturnType(typeRef, callingClass, callingMember,
caretLine, caretColumn, pc, false);
}
public IField FindLocalVariable(string name, bool acceptImplicit)
{
VariableLookupVisitor vlv = new VariableLookupVisitor(this, name, acceptImplicit);
vlv.Visit(GetCurrentBooMethod());
return vlv.Result;
}
#endregion
#region CtrlSpace
@ -162,6 +199,23 @@ namespace Grunwald.BooBinding.CodeCompletion @@ -162,6 +199,23 @@ namespace Grunwald.BooBinding.CodeCompletion
NRResolver.AddContentsFromCalling(result, callingClass, callingMember);
ArrayList knownVariableNames = new ArrayList();
foreach (object o in result) {
IMember m = o as IMember;
if (m != null) {
knownVariableNames.Add(m.Name);
}
}
VariableListLookupVisitor vllv = new VariableListLookupVisitor(knownVariableNames);
vllv.Visit(GetCurrentBooMethod());
foreach (DictionaryEntry entry in vllv.Results) {
IReturnType type;
if (entry.Value is AST.TypeReference) {
type = ConvertType((AST.TypeReference)entry.Value);
result.Add(new DefaultField.LocalVariableField(type, (string)entry.Key, DomRegion.Empty, callingClass));
}
}
return result;
}

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

@ -220,11 +220,18 @@ namespace Grunwald.BooBinding.CodeCompletion @@ -220,11 +220,18 @@ namespace Grunwald.BooBinding.CodeCompletion
{
return ReflectionReturnType.CreatePrimitive(type);
}
// TODO: Type inference
IReturnType CreateReturnType(AST.Field field)
{
return CreateReturnType(field.Type);
if (field.Type == null) {
if (field.Initializer != null)
return new InferredReturnType(field.Initializer);
else
return ReflectionReturnType.Object;
} else {
return CreateReturnType(field.Type);
}
}
// TODO: Type inference
IReturnType CreateReturnType(AST.Method node, IMethod method)
{
return CreateReturnType(node.ReturnType, method);
@ -349,6 +356,7 @@ namespace Grunwald.BooBinding.CodeCompletion @@ -349,6 +356,7 @@ namespace Grunwald.BooBinding.CodeCompletion
method.ReturnType = CreateReturnType(node, method);
ConvertParameters(node.Parameters, method);
_currentClass.Peek().Methods.Add(method);
method.UserData = node;
}
public override void OnConstructor(AST.Constructor node)
@ -358,6 +366,7 @@ namespace Grunwald.BooBinding.CodeCompletion @@ -358,6 +366,7 @@ namespace Grunwald.BooBinding.CodeCompletion
ConvertAttributes(node, ctor);
ConvertParameters(node.Parameters, ctor);
_currentClass.Peek().Methods.Add(ctor);
ctor.UserData = node;
}
public override void OnEnumMember(AST.EnumMember node)
@ -388,6 +397,7 @@ namespace Grunwald.BooBinding.CodeCompletion @@ -388,6 +397,7 @@ namespace Grunwald.BooBinding.CodeCompletion
ConvertAttributes(node, property);
ConvertParameters(node.Parameters, property);
OuterClass.Properties.Add(property);
property.UserData = node;
}
}
}

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

@ -0,0 +1,47 @@ @@ -0,0 +1,47 @@
// <file>
// <copyright see="prj:///doc/copyright.txt">2002-2005 AlphaSierraPapa</copyright>
// <license see="prj:///doc/license.txt">GNU General Public License</license>
// <owner name="Daniel Grunwald" email="daniel@danielgrunwald.de"/>
// <version>$Revision$</version>
// </file>
using System;
using ICSharpCode.Core;
using ICSharpCode.SharpDevelop.Dom;
using Boo.Lang.Compiler.Ast;
namespace Grunwald.BooBinding.CodeCompletion
{
/// <summary>
/// Return type that is inferred from an expression.
/// </summary>
public class InferredReturnType : ProxyReturnType
{
Expression expression;
public InferredReturnType(Expression expression)
{
this.expression = expression;
}
bool needInfer = true;
IReturnType cachedType;
public override IReturnType BaseType {
get {
if (needInfer) {
needInfer = false;
cachedType = new BooResolver().GetTypeOfExpression(expression);
}
return cachedType;
}
}
public override bool IsDefaultReturnType {
get {
IReturnType baseType = BaseType;
return (baseType != null) ? baseType.IsDefaultReturnType : false;
}
}
}
}

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

@ -137,9 +137,14 @@ namespace Grunwald.BooBinding.CodeCompletion @@ -137,9 +137,14 @@ namespace Grunwald.BooBinding.CodeCompletion
bool ResolveIdentifier(string identifier)
{
IField local;
resolveResult = null;
if (resolver.CallingMember != null) {
// TODO: Search local variables
local = resolver.FindLocalVariable(identifier, false);
if (local != null) {
MakeResult(local);
return true;
}
IMethodOrProperty method = resolver.CallingMember as IMethodOrProperty;
if (method != null) {
@ -185,6 +190,13 @@ namespace Grunwald.BooBinding.CodeCompletion @@ -185,6 +190,13 @@ namespace Grunwald.BooBinding.CodeCompletion
return true;
}
}
local = resolver.FindLocalVariable(identifier, true);
if (local != null) {
MakeResult(local);
return true;
}
return false;
}
#endregion
@ -466,9 +478,7 @@ namespace Grunwald.BooBinding.CodeCompletion @@ -466,9 +478,7 @@ namespace Grunwald.BooBinding.CodeCompletion
IReturnType ConvertType(TypeReference typeRef)
{
return ConvertVisitor.CreateReturnType(typeRef, callingClass, resolver.CallingMember,
resolver.CaretLine, resolver.CaretColumn,
projectContent, false);
return resolver.ConvertType(typeRef);
}
}
}

153
src/AddIns/BackendBindings/Boo/BooBinding/Project/Src/CodeCompletion/VariableLookupVisitor.cs

@ -0,0 +1,153 @@ @@ -0,0 +1,153 @@
// <file>
// <copyright see="prj:///doc/copyright.txt">2002-2005 AlphaSierraPapa</copyright>
// <license see="prj:///doc/license.txt">GNU General Public License</license>
// <owner name="Daniel Grunwald" email="daniel@danielgrunwald.de"/>
// <version>$Revision$</version>
// </file>
using System;
using System.Collections;
using ICSharpCode.SharpDevelop.Dom;
using Boo.Lang.Compiler.Ast;
namespace Grunwald.BooBinding.CodeCompletion
{
/// <summary>
/// Finds an variable declaration in the boo AST.
/// </summary>
public class VariableLookupVisitor : DepthFirstVisitor
{
BooResolver resolver;
string lookFor;
bool acceptImplicit;
public VariableLookupVisitor(BooResolver resolver, string lookFor, bool acceptImplicit)
{
this.resolver = resolver;
this.lookFor = lookFor;
this.acceptImplicit = acceptImplicit;
}
IField result;
public IField Result {
get {
return result;
}
}
private void InferResult(Expression expr, string name, LexicalInfo lexicalInfo)
{
if (expr == null)
return;
if (result != null)
return;
result = new DefaultField.LocalVariableField(new InferredReturnType(expr), name,
new DomRegion(lexicalInfo.Line, lexicalInfo.Column),
resolver.CallingClass);
}
public override void OnDeclaration(Declaration node)
{
if (result != null)
return;
if (node.Name == lookFor) {
if (node.Type != null) {
result = new DefaultField.LocalVariableField(resolver.ConvertType(node.Type),
node.Name,
new DomRegion(node.LexicalInfo.Line, node.LexicalInfo.Column),
resolver.CallingClass);
}
}
}
public override void OnDeclarationStatement(DeclarationStatement node)
{
if (node.Declaration.Name == lookFor) {
Visit(node.Declaration);
InferResult(node.Initializer, node.Declaration.Name, node.LexicalInfo);
}
}
public override void OnBinaryExpression(BinaryExpression node)
{
if (acceptImplicit) {
ReferenceExpression reference = node.Left as ReferenceExpression;
if (node.Operator == BinaryOperatorType.Assign && reference != null) {
if (!(reference is MemberReferenceExpression)) {
if (reference.Name == lookFor) {
InferResult(node.Right, reference.Name, reference.LexicalInfo);
}
}
}
}
base.OnBinaryExpression(node);
}
}
/// <summary>
/// Creates a hashtable name => (Expression or TypeReference) for the local
/// variables in the block that is visited.
/// </summary>
public class VariableListLookupVisitor : DepthFirstVisitor
{
ArrayList knownVariableNames;
public VariableListLookupVisitor(ArrayList knownVariableNames)
{
this.knownVariableNames = knownVariableNames;
}
Hashtable results = new Hashtable();
public Hashtable Results {
get {
return results;
}
}
private void Add(string name, Expression expr)
{
if (name == null || expr == null)
return;
if (results.ContainsKey(name))
return;
results.Add(name, expr);
}
private void Add(string name, TypeReference reference)
{
if (name == null || reference == null)
return;
if (results.ContainsKey(name))
return;
results.Add(name, reference);
}
public override void OnDeclaration(Declaration node)
{
Add(node.Name, node.Type);
}
public override void OnDeclarationStatement(DeclarationStatement node)
{
Visit(node.Declaration);
Add(node.Declaration.Name, node.Initializer);
}
public override void OnBinaryExpression(BinaryExpression node)
{
if (node.Operator == BinaryOperatorType.Assign && node.Left is ReferenceExpression) {
ReferenceExpression reference = node.Left as ReferenceExpression;
if (node.Operator == BinaryOperatorType.Assign && reference != null) {
if (!(reference is MemberReferenceExpression)) {
if (!knownVariableNames.Contains(reference.Name)) {
Add(reference.Name, node.Right);
}
}
}
}
base.OnBinaryExpression(node);
}
}
}

8
src/AddIns/BackendBindings/Boo/NRefactoryToBooConverter/Project/AssemblyInfo.cs

@ -41,10 +41,4 @@ using System.Runtime.CompilerServices; @@ -41,10 +41,4 @@ using System.Runtime.CompilerServices;
//
// You can specify all values by your own or you can build default build and revision
// numbers with the '*' character (the default):
[assembly: AssemblyVersion(NRefactoryToBooConverter.VersionInfo.VersionNumber)]
namespace NRefactoryToBooConverter {
public static class VersionInfo {
public const string VersionNumber = "0.1.*";
}
}
[assembly: AssemblyVersion("2.0.0.1")]

2
src/AddIns/BackendBindings/Boo/StandaloneConverter/AssemblyInfo.cs

@ -42,5 +42,5 @@ using System.Runtime.CompilerServices; @@ -42,5 +42,5 @@ using System.Runtime.CompilerServices;
// You can specify all values by your own or you can build default build and revision
// numbers with the '*' character (the default):
[assembly: AssemblyVersion(NRefactoryToBooConverter.VersionInfo.VersionNumber)]
[assembly: AssemblyVersion("2.0.0.1")]

Loading…
Cancel
Save