Browse Source

Improved Boo VariableLookupVisitor.

git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/branches/2.0@1278 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61
shortcuts
Daniel Grunwald 20 years ago
parent
commit
a4b35aaae6
  1. 203
      src/AddIns/BackendBindings/Boo/BooBinding/Project/Src/CodeCompletion/VariableLookupVisitor.cs

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

@ -13,64 +13,17 @@ using Boo.Lang.Compiler.Ast;
namespace Grunwald.BooBinding.CodeCompletion namespace Grunwald.BooBinding.CodeCompletion
{ {
/// <summary> public abstract class VariableLookupVisitorBase : DepthFirstVisitor
/// Finds an variable declaration in the boo AST.
/// </summary>
public class VariableLookupVisitor : DepthFirstVisitor
{ {
BooResolver resolver; protected BooResolver resolver;
string lookFor; protected bool acceptImplicit = true;
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, bool useElementType)
{
if (expr == null)
return;
if (result != null)
return;
IReturnType returnType = new InferredReturnType(expr, resolver.CallingClass);
if (useElementType)
returnType = new ElementReturnType(returnType);
result = new DefaultField.LocalVariableField(returnType, name,
new DomRegion(lexicalInfo.Line, lexicalInfo.Column),
resolver.CallingClass);
}
public override void OnDeclaration(Declaration node) protected abstract void DeclarationFound(string declarationName, TypeReference declarationType, Expression initializer, LexicalInfo lexicalInfo);
{ protected abstract void IterationDeclarationFound(string declarationName, TypeReference declarationType, Expression initializer, LexicalInfo lexicalInfo);
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) public override void OnDeclarationStatement(DeclarationStatement node)
{ {
if (node.Declaration.Name == lookFor) { DeclarationFound(node.Declaration.Name, node.Declaration.Type, node.Initializer, node.LexicalInfo);
Visit(node.Declaration);
InferResult(node.Initializer, node.Declaration.Name, node.LexicalInfo, false);
}
} }
protected override void OnError(Node node, Exception error) protected override void OnError(Node node, Exception error)
@ -84,9 +37,7 @@ namespace Grunwald.BooBinding.CodeCompletion
ReferenceExpression reference = node.Left as ReferenceExpression; ReferenceExpression reference = node.Left as ReferenceExpression;
if (node.Operator == BinaryOperatorType.Assign && reference != null) { if (node.Operator == BinaryOperatorType.Assign && reference != null) {
if (!(reference is MemberReferenceExpression)) { if (!(reference is MemberReferenceExpression)) {
if (reference.Name == lookFor) { DeclarationFound(reference.Name, null, node.Right, node.LexicalInfo);
InferResult(node.Right, reference.Name, reference.LexicalInfo, false);
}
} }
} }
} }
@ -95,18 +46,12 @@ namespace Grunwald.BooBinding.CodeCompletion
public override void OnForStatement(ForStatement node) public override void OnForStatement(ForStatement node)
{ {
if (node.LexicalInfo.Line > resolver.CaretLine || node.Block.EndSourceLocation.Line < resolver.CaretLine) if (node.LexicalInfo.Line <= resolver.CaretLine && node.Block.EndSourceLocation.Line >= resolver.CaretLine - 1) {
return; foreach (Declaration decl in node.Declarations) {
IterationDeclarationFound(decl.Name, decl.Type, node.Iterator, node.LexicalInfo);
if (node.Declarations.Count != 1) { }
// TODO: support unpacking
base.OnForStatement(node);
return;
}
if (node.Declarations[0].Name == lookFor) {
Visit(node.Declarations[0]);
InferResult(node.Iterator, node.Declarations[0].Name, node.LexicalInfo, true);
} }
base.OnForStatement(node);
} }
public override void OnGeneratorExpression(GeneratorExpression node) public override void OnGeneratorExpression(GeneratorExpression node)
@ -114,16 +59,77 @@ namespace Grunwald.BooBinding.CodeCompletion
if (node.LexicalInfo.Line != resolver.CaretLine) if (node.LexicalInfo.Line != resolver.CaretLine)
return; return;
LoggingService.Warn("GeneratorExpression: " + node.EndSourceLocation.Line); LoggingService.Warn("GeneratorExpression: " + node.EndSourceLocation.Line);
if (node.Declarations.Count != 1) { foreach (Declaration decl in node.Declarations) {
// TODO: support unpacking IterationDeclarationFound(decl.Name, decl.Type, node.Iterator, node.LexicalInfo);
base.OnGeneratorExpression(node); }
base.OnGeneratorExpression(node);
}
}
/// <summary>
/// Finds an variable declaration in the boo AST.
/// </summary>
public class VariableLookupVisitor : VariableLookupVisitorBase
{
string lookFor;
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;
}
}
protected override void IterationDeclarationFound(string declarationName, TypeReference declarationType, Expression iterator, LexicalInfo lexicalInfo)
{
if (result != null)
return; return;
if (declarationName == lookFor) {
if (declarationType != null) {
result = new DefaultField.LocalVariableField(resolver.ConvertType(declarationType),
declarationName,
new DomRegion(lexicalInfo.Line, lexicalInfo.Column),
resolver.CallingClass);
} else if (iterator != null) {
InferResult(iterator, declarationName, lexicalInfo, true);
}
} }
if (node.Declarations[0].Name == lookFor) { }
Visit(node.Declarations[0]);
InferResult(node.Iterator, node.Declarations[0].Name, node.LexicalInfo, true); protected override void DeclarationFound(string declarationName, TypeReference declarationType, Expression initializer, LexicalInfo lexicalInfo)
{
if (result != null)
return;
if (declarationName == lookFor) {
if (declarationType != null) {
result = new DefaultField.LocalVariableField(resolver.ConvertType(declarationType),
declarationName,
new DomRegion(lexicalInfo.Line, lexicalInfo.Column),
resolver.CallingClass);
} else if (initializer != null) {
InferResult(initializer, declarationName, lexicalInfo, false);
}
} }
base.OnGeneratorExpression(node); }
private void InferResult(Expression expr, string name, LexicalInfo lexicalInfo, bool useElementType)
{
if (expr == null)
return;
IReturnType returnType = new InferredReturnType(expr, resolver.CallingClass);
if (useElementType)
returnType = new ElementReturnType(returnType);
result = new DefaultField.LocalVariableField(returnType, name,
new DomRegion(lexicalInfo.Line, lexicalInfo.Column),
resolver.CallingClass);
} }
} }
@ -131,10 +137,9 @@ namespace Grunwald.BooBinding.CodeCompletion
/// Creates a hashtable name => (Expression or TypeReference) for the local /// Creates a hashtable name => (Expression or TypeReference) for the local
/// variables in the block that is visited. /// variables in the block that is visited.
/// </summary> /// </summary>
public class VariableListLookupVisitor : DepthFirstVisitor public class VariableListLookupVisitor : VariableLookupVisitorBase
{ {
List<string> knownVariableNames; List<string> knownVariableNames;
BooResolver resolver;
public VariableListLookupVisitor(List<string> knownVariableNames, BooResolver resolver) public VariableListLookupVisitor(List<string> knownVariableNames, BooResolver resolver)
{ {
@ -171,48 +176,22 @@ namespace Grunwald.BooBinding.CodeCompletion
results.Add(name, resolver.ConvertType(reference)); results.Add(name, resolver.ConvertType(reference));
} }
public override void OnDeclaration(Declaration node) protected override void DeclarationFound(string declarationName, TypeReference declarationType, Expression initializer, LexicalInfo lexicalInfo)
{ {
Add(node.Name, node.Type); if (declarationType != null) {
} Add(declarationName, declarationType);
} else if (initializer != null) {
public override void OnDeclarationStatement(DeclarationStatement node) Add(declarationName, initializer, false);
{
Visit(node.Declaration);
Add(node.Declaration.Name, node.Initializer, false);
}
protected override void OnError(Node node, Exception error)
{
MessageService.ShowError(error, "VariableListLookupVisitor: error processing " + node);
}
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, false);
}
}
}
} }
base.OnBinaryExpression(node);
} }
public override void OnForStatement(ForStatement node) protected override void IterationDeclarationFound(string declarationName, TypeReference declarationType, Expression initializer, LexicalInfo lexicalInfo)
{ {
if (node.LexicalInfo.Line > resolver.CaretLine || node.Block.EndSourceLocation.Line < resolver.CaretLine) if (declarationType != null) {
return; Add(declarationName, declarationType);
} else if (initializer != null) {
if (node.Declarations.Count != 1) { Add(declarationName, initializer, true);
// TODO: support unpacking
base.OnForStatement(node);
return;
} }
Add(node.Declarations[0].Name, node.Iterator, true);
} }
} }
} }

Loading…
Cancel
Save