[svn] r6902: vs-plugin/trunk/Nemerle.Compiler.Utils:
Nemerle.Completion2/CodeModel/ExprFinder.n Nemerle.Co...
phantom
svnadmin at nemerle.org
Wed Nov 15 15:47:48 CET 2006
Log:
Author: phantom
Date: Wed Nov 15 15:47:46 2006
New Revision: 6902
Modified:
vs-plugin/trunk/Nemerle.Compiler.Utils/Nemerle.Completion2/CodeModel/ExprFinder.n
vs-plugin/trunk/Nemerle.Compiler.Utils/Nemerle.Completion2/CodeModel/Project.Type.n
vs-plugin/trunk/Nemerle.Compiler.Utils/Utils.n
Modified: vs-plugin/trunk/Nemerle.Compiler.Utils/Nemerle.Completion2/CodeModel/ExprFinder.n
==============================================================================
--- vs-plugin/trunk/Nemerle.Compiler.Utils/Nemerle.Completion2/CodeModel/ExprFinder.n (original)
+++ vs-plugin/trunk/Nemerle.Compiler.Utils/Nemerle.Completion2/CodeModel/ExprFinder.n Wed Nov 15 15:47:46 2006
@@ -69,6 +69,59 @@
}
}
+ mutable localValue : LocalValue;
+ mutable localValueEntries : list[Location];
+ mutable definitionFound : bool;
+
+ // TODO: think about (dis)advantages of switching to a parsed tree walking
+ ProcessNodeInFindLocalValueEntries(exprWalkInfo: ExprWalkInfo) : void
+ {
+ def node = exprWalkInfo.Node;
+ Debug.WriteLine($"processing node: $(node.ToString().Brief())");
+ when (node is TExpr)
+ {
+ def node = node :> TExpr;
+ Debug.WriteLine($"(location: $(node.Location)");
+ when (localValue.Location.NotStrictlyBefore(node.Location))
+ {
+ //Debug.WriteLine("located after definition or is definition");
+ Debug.WriteLine($" type of node: $(node.GetType())");
+ def processLocalValueEntry(entry, definition = false)
+ {
+ Debug.WriteLine($" contains $entry");
+ when (entry.Name == localValue.Name)
+ {
+ Debug.WriteLine($" has the same name: $(entry.Name)");
+ // TODO: check the if it is really in the same scope
+ // TODO: walk around LocalValue.Location incorrect value
+ if (definition)
+ {
+ if (definitionFound)
+ exprWalkInfo.Stop();
+ else
+ {
+ definitionFound = true;
+ Debug.WriteLine($" it's a definition! (location: $(entry.Location))");
+ localValueEntries ::= node.Location;
+ }
+ }
+ else
+ {
+ Debug.WriteLine($" it's a reference! (location: $(entry.Location))");
+ localValueEntries ::= node.Location;
+ }
+ }
+ }
+ match (node)
+ {
+ | DefValIn(entry, _, _) => processLocalValueEntry(entry, true);
+ | LocalRef(entry) => processLocalValueEntry(entry);
+ | _ => ();
+ }
+ }
+ }
+ }
+
GetPattern(pattern : Pattern) : object
{
| Application(name, _) => // { name : TypeInfo; arg : Pattern; }
@@ -273,6 +326,19 @@
(Location.Default, null, null)
}
+ public FindLocalValueEntries(typedExpressionRoot : TExpr, localValue: LocalValue) : list[Location]
+ {
+ this.localValue = localValue;
+ localValueEntries = [];
+ definitionFound = false;
+ ExprWalker().Walk(typedExpressionRoot, ProcessNodeInFindLocalValueEntries);
+ def entries = localValueEntries.Reverse();
+ Debug.WriteLine($"Found $(entries.Length) entries:");
+ // why it doesn't guess about type?
+ entries.Iter(location : Location => Debug.WriteLine(location));
+ entries
+ }
+
Init(line : int, col : int) : void
{
#if PRINT_AST
Modified: vs-plugin/trunk/Nemerle.Compiler.Utils/Nemerle.Completion2/CodeModel/Project.Type.n
==============================================================================
--- vs-plugin/trunk/Nemerle.Compiler.Utils/Nemerle.Completion2/CodeModel/Project.Type.n (original)
+++ vs-plugin/trunk/Nemerle.Compiler.Utils/Nemerle.Completion2/CodeModel/Project.Type.n Wed Nov 15 15:47:46 2006
@@ -252,64 +252,6 @@
}
// TODO: implement get usages behaviour, this is a stub yet
- private FindUsages(
- typeDecl : Decl.Type,
- fileIndex : int,
- line : int,
- col : int
- )
- : list [GotoInfo]
- {
- def (_, _, declarationObject) = FindObject(typeDecl, fileIndex, line, col);
-
- // TODO: use lexer output for quick search, cache it if it is not cached yet
- //VladD2:  ëåñ lexer. Ïîèñê ïî èñõîäíèêàì áîëåå ÷åì äîñòàòî÷åí äëÿ
- // òîãî ÷òîáû íàéòè íóæíûå ìåòîäû.
- def findPossibleUsages(name)
- {
- def entries = SCG.List();
- def projSources = _engine.ProjectSources;
-
- foreach (fileIndex in _engine.Sources.GetFileIndices())
- {
- def source = projSources.GetSource(fileIndex); // get ISource
- def code = source.GetText(); // get code as text
- def findEntry(startPos)
- {
- def pos = code.OrdinalIndexOf(name, startPos);
- when (pos >= 0) // we found entry...
- {
- def (line, ch) = source.GetLineIndexOfPosition(pos);
- def loc = Location(fileIndex, line, ch, line, ch + name.Length);
- entries.Add(loc);
- Debug.WriteLine($"\t$(loc.File)($(loc.Line),$(loc.Column)): ...");
- findEntry(pos + name.Length); // try again...
- }
- }
-
- Debug.WriteLine($"Try finde name '$name'");
-
- findEntry(0); // find from start of file
-
- Debug.WriteLine($"End: Try finde name '$name'");
- }
-
- entries
- }
-
- // TODO: check the symbol found
- def isRealUsages(_)
- {
- true
- }
-
- // TODO: implement other type usages finding, not only variables
- match (declarationObject)
- {
- | localValue is LocalValue => // try find only on method body!
- [GotoInfo(localValue)] //TODO: find entry of local value
-
- | member is IMember =>
// Ïðèìåðíîå îïèñàíèå àëãîðèòìà ïîèñêà ÷ëåíà êëàññà:
// 1. Íàõîäèì âñå ññûëêè íà äàííûé ÷ëåí â äåðåâå òèïîâ.
// Ýòî ìîæíî ñäåëàòü ïðîñêàíèðîâàâ TypeBuilder-û.
@@ -340,12 +282,68 @@
// (It may be done by GetAllMetodsDefinedInFile(fileIndex : int) : SCG.List[MethodBuilder])
// If lacations from step 2 intersect with method try find entries
// in it method.
+ private FindUsages(type' : Decl.Type, fileIndex : int, line : int, column : int) : list [GotoInfo]
+ {
+ def (_, _, declarationObject) = FindObject(type', fileIndex, line, column);
- // Èç âûøå ñêàçàííîãî ÿñíî, ÷òî äàííûé êîä íå âåðíûé, òàê íî ïîêà õîòü òàê...
- $[GotoInfo(x) | x in findPossibleUsages(member.Name), isRealUsages(x)]
+ // TODO: for rename refactoring, we should know all usages, including generated
+ // However, this implementation neglects generated usages
+ def findPossibleUsages(name)
+ {
+ mutable entries = [];
+ def sources = _engine.ProjectSources;
+ foreach (fileIndex in _engine.Sources.GetFileIndices())
+ {
+ def source = sources.GetSource(fileIndex);
+ def code = source.GetText();
+ def findEntry(startPos)
+ {
+ def position = code.OrdinalIndexOf(name, startPos);
+ unless (position < 0)
+ {
+ def (line, column) = source.GetLineIndexOfPosition(position);
+ def location = Location(fileIndex, line, column, line, column + name.Length);
+ entries ::= location;
+ findEntry(position + name.Length);
+ }
+ }
+ findEntry(0);
+ }
+
+ entries
+ }
+
+ def findInMethod(localValueDeclaration)
+ {
+ def member = type'.Builder.GetActiveMember(fileIndex, line, column);
+ Debug.WriteLine($"searching for $localValueDeclaration");
+ Debug.WriteLine($"enclosing member:\n $member");
+ match (member)
+ {
+ | method is MethodBuilder =>
+ Debug.WriteLine("parsed tree:");
+ Debug.WriteLine(PrettyPrint.SprintExpr(None(), method.BodyParsed));
+ Debug.WriteLine("typed tree:");
+ Debug.WriteLine(PrettyPrint.SprintTyExpr(method.BodyTyped));
+ ExprFinder().FindLocalValueEntries(method.BodyTyped, localValueDeclaration);
+ | _ => []
+ }
+ }
+
+ def isRealUsage(_)
+ {
+ true
+ }
+
+ def locations = match (declarationObject)
+ {
+ | localValue is LocalValue => findInMethod(localValue)
+ | member is IMember =>
+ $[x | x in findPossibleUsages(member.Name), isRealUsage(x)]
| _ => [] //TODO: May be it wrong!
}
+ locations.Map(GotoInfo(_))
}
GetMethodTip(
Modified: vs-plugin/trunk/Nemerle.Compiler.Utils/Utils.n
==============================================================================
--- vs-plugin/trunk/Nemerle.Compiler.Utils/Utils.n (original)
+++ vs-plugin/trunk/Nemerle.Compiler.Utils/Utils.n Wed Nov 15 15:47:46 2006
@@ -18,6 +18,32 @@
InvariantCultureCompareInfo : CompareInfo
= CultureInfo.InvariantCulture.CompareInfo;
+ // Returns (non-strictly) whether the first location is before the second
+ public NotStrictlyBefore(this firstLocation : Location, secondLocation: Location) : bool
+ {
+ if (firstLocation.Line < secondLocation.Line)
+ true
+ else if (firstLocation.Line > secondLocation.Line)
+ false
+ else if (firstLocation.Column < secondLocation.Column)
+ true
+ else if (firstLocation.Column > secondLocation.Column)
+ false
+ else
+ true
+ }
+
+ // For debug purposes, brief output
+ public Brief(this output : string, maximalLength : int = 100) : string
+ {
+ def ellipsis = "...";
+ def s = output.Replace('\n', ' ');
+ if (s.Length > maximalLength)
+ s.Substring(0, maximalLength - ellipsis.Length) + ellipsis;
+ else
+ s
+ }
+
/// Fast find index of substing.
public OrdinalIndexOf(this source : string, value : string, startIndex : int) : int
{
More information about the svn
mailing list