From 5260725be5d420dc78e2a49fc8640a60f143f2bf Mon Sep 17 00:00:00 2001 From: neoeinstein Date: Fri, 11 Apr 2008 06:45:13 +0000 Subject: [PATCH] BOO-503: Some love for compiler-generated callable definition names so that they provide some context based on where they were created to bring them on par with closure-naming. Also made SourceLocation Equatable and Comparable. git-svn-id: https://svn.codehaus.org/boo/boo/trunk@2921 2c1201b4-01cd-e047-a400-b836ae1fbc61 --- src/Boo.Lang.Compiler/Ast/LexicalInfo.cs | 44 +++++++++++++++++++++- src/Boo.Lang.Compiler/Ast/Node.cs | 6 ++- .../Steps/ForeignReferenceCollector.cs | 3 +- .../Steps/GeneratorExpressionProcessor.cs | 2 +- src/Boo.Lang.Compiler/Steps/ProcessClosures.cs | 8 ++-- .../TypeSystem/AnonymousCallablesManager.cs | 19 +++++++++- 6 files changed, 72 insertions(+), 10 deletions(-) diff --git a/src/Boo.Lang.Compiler/Ast/LexicalInfo.cs b/src/Boo.Lang.Compiler/Ast/LexicalInfo.cs index 65348d2e..3480ef92 100644 --- a/src/Boo.Lang.Compiler/Ast/LexicalInfo.cs +++ b/src/Boo.Lang.Compiler/Ast/LexicalInfo.cs @@ -30,7 +30,7 @@ using System; namespace Boo.Lang.Compiler.Ast { - public class SourceLocation + public class SourceLocation : IComparable, IEquatable { protected int _line; @@ -70,9 +70,29 @@ namespace Boo.Lang.Compiler.Ast { return string.Format("({0},{1})", _line, _column); } + + public int CompareTo(SourceLocation other) + { + int comp = _line.CompareTo(other._line); + if(comp != 0) + { + return comp; + } + comp = _column.CompareTo(other._column); + if(comp != 0) + { + return comp; + } + return 0; + } + + public bool Equals(SourceLocation other) + { + return CompareTo(other) == 0; + } } - public class LexicalInfo : SourceLocation + public class LexicalInfo : SourceLocation, IEquatable, IComparable { public static readonly LexicalInfo Empty = new LexicalInfo(null, -1, -1); @@ -132,5 +152,25 @@ namespace Boo.Lang.Compiler.Ast } return fname; } + + public int CompareTo(LexicalInfo other) + { + int comp = base.CompareTo(other); + if(comp != 0) + { + return comp; + } + comp = string.Compare(_filename, other._filename); + if(comp != 0) + { + return comp; + } + return 0; + } + + public bool Equals(LexicalInfo other) + { + return CompareTo(other) == 0; + } } } diff --git a/src/Boo.Lang.Compiler/Ast/Node.cs b/src/Boo.Lang.Compiler/Ast/Node.cs index 7ca638d3..a396d0ed 100644 --- a/src/Boo.Lang.Compiler/Ast/Node.cs +++ b/src/Boo.Lang.Compiler/Ast/Node.cs @@ -208,7 +208,11 @@ namespace Boo.Lang.Compiler.Ast public LexicalInfo LexicalInfo { get - { + { + if(_lexicalInfo.Equals(LexicalInfo.Empty) && null != ParentNode && null != ParentNode.LexicalInfo) + { + _lexicalInfo = ParentNode.LexicalInfo; + } return _lexicalInfo; } diff --git a/src/Boo.Lang.Compiler/Steps/ForeignReferenceCollector.cs b/src/Boo.Lang.Compiler/Steps/ForeignReferenceCollector.cs index 303fb106..d5a82471 100644 --- a/src/Boo.Lang.Compiler/Steps/ForeignReferenceCollector.cs +++ b/src/Boo.Lang.Compiler/Steps/ForeignReferenceCollector.cs @@ -167,10 +167,11 @@ namespace Boo.Lang.Compiler.Steps _referencedEntities.Clear(); } - public BooClassBuilder CreateSkeletonClass(string name) + public BooClassBuilder CreateSkeletonClass(string name, LexicalInfo lexicalInfo) { BooClassBuilder builder = CodeBuilder.CreateClass(name); builder.Modifiers |= TypeMemberModifiers.Internal; + builder.LexicalInfo = lexicalInfo; builder.AddBaseType(CodeBuilder.TypeSystemServices.ObjectType); DeclareFieldsAndConstructor(builder); diff --git a/src/Boo.Lang.Compiler/Steps/GeneratorExpressionProcessor.cs b/src/Boo.Lang.Compiler/Steps/GeneratorExpressionProcessor.cs index f80dd5b0..66734819 100755 --- a/src/Boo.Lang.Compiler/Steps/GeneratorExpressionProcessor.cs +++ b/src/Boo.Lang.Compiler/Steps/GeneratorExpressionProcessor.cs @@ -92,7 +92,7 @@ namespace Boo.Lang.Compiler.Steps _resultItemType = (IType)_generator["GeneratorItemType"]; _resultEnumeratorType = TypeSystemServices.IEnumeratorGenericType.GenericInfo.ConstructType(_resultItemType); - _enumerator = _collector.CreateSkeletonClass("Enumerator"); + _enumerator = _collector.CreateSkeletonClass("Enumerator",_generator.LexicalInfo); // use a generic enumerator for the source type if possible _sourceItemType = TypeSystemServices.GetGenericEnumerableItemType(_generator.Iterator.ExpressionType); diff --git a/src/Boo.Lang.Compiler/Steps/ProcessClosures.cs b/src/Boo.Lang.Compiler/Steps/ProcessClosures.cs index b99533ab..7fed1721 100755 --- a/src/Boo.Lang.Compiler/Steps/ProcessClosures.cs +++ b/src/Boo.Lang.Compiler/Steps/ProcessClosures.cs @@ -36,8 +36,8 @@ namespace Boo.Lang.Compiler.Steps override public void Run() { Visit(CompileUnit); - } - + } + override public void LeaveBlockExpression(BlockExpression node) { InternalMethod closureEntity = (InternalMethod)GetEntity(node); @@ -52,6 +52,7 @@ namespace Boo.Lang.Compiler.Steps if (collector.ContainsForeignLocalReferences) { BooClassBuilder closureClass = CreateClosureClass(collector, closureEntity); + closureClass.ClassDefinition.LexicalInfo = node.LexicalInfo; collector.AdjustReferences(); ReplaceCurrentNode( @@ -63,6 +64,7 @@ namespace Boo.Lang.Compiler.Steps else { Expression expression = CodeBuilder.CreateMemberReference(closureEntity); + expression.LexicalInfo = node.LexicalInfo; TypeSystemServices.GetConcreteExpressionType(expression); ReplaceCurrentNode(expression); } @@ -75,7 +77,7 @@ namespace Boo.Lang.Compiler.Steps TypeDefinition parent = method.DeclaringType; parent.Members.Remove(method); - BooClassBuilder builder = collector.CreateSkeletonClass(closure.Name); + BooClassBuilder builder = collector.CreateSkeletonClass(closure.Name, method.LexicalInfo); parent.Members.Add(builder.ClassDefinition); builder.ClassDefinition.Members.Add(method); method.Name = "Invoke"; diff --git a/src/Boo.Lang.Compiler/TypeSystem/AnonymousCallablesManager.cs b/src/Boo.Lang.Compiler/TypeSystem/AnonymousCallablesManager.cs index f8c07307..58ff083a 100644 --- a/src/Boo.Lang.Compiler/TypeSystem/AnonymousCallablesManager.cs +++ b/src/Boo.Lang.Compiler/TypeSystem/AnonymousCallablesManager.cs @@ -98,8 +98,23 @@ namespace Boo.Lang.Compiler.TypeSystem private IType CreateConcreteCallableType(Node sourceNode, AnonymousCallableType anonymousType) { Module module = TypeSystemServices.GetCompilerGeneratedTypesModule(); - - string name = string.Format("___callable{0}", module.Members.Count); + + TypeMember enclosing = (sourceNode.GetAncestor(NodeType.ClassDefinition) ?? sourceNode.GetAncestor(NodeType.Module)) as TypeMember; + string prefix = "__$"; + string postfix = "$__"; + if(enclosing != null) + { + prefix += enclosing.Name + "$"; + } + else if (!sourceNode.LexicalInfo.Equals(LexicalInfo.Empty)) + { + prefix += System.IO.Path.GetFileNameWithoutExtension(sourceNode.LexicalInfo.FileName) + "$"; + } + if(!sourceNode.LexicalInfo.Equals(LexicalInfo.Empty)) + { + postfix = "$" + sourceNode.LexicalInfo.Line + "_" + sourceNode.LexicalInfo.Column + postfix; + } + string name = prefix + "callable" + module.Members.Count + postfix; ClassDefinition cd = TypeSystemServices.CreateCallableDefinition(name); cd.Modifiers |= TypeMemberModifiers.Public; cd.LexicalInfo = sourceNode.LexicalInfo; -- 2.11.4.GIT