[svn] r7733: nemerle/trunk: macros/Late.n
ncc/generation/ILEmitter.n ncc/generation/Typer3.n ncc/generatio...
IT
svnadmin at nemerle.org
Thu Jul 5 07:28:40 CEST 2007
Log:
Working on debugging.
Author: IT
Date: Thu Jul 5 07:28:34 2007
New Revision: 7733
Modified:
nemerle/trunk/macros/Late.n
nemerle/trunk/ncc/generation/ILEmitter.n
nemerle/trunk/ncc/generation/Typer3.n
nemerle/trunk/ncc/generation/Typer4.n
nemerle/trunk/ncc/misc/ExprWalker.n
nemerle/trunk/ncc/parsing/AST.n
nemerle/trunk/ncc/parsing/MainParser.n
nemerle/trunk/ncc/parsing/ParseTree.n
nemerle/trunk/ncc/parsing/Utility.n
nemerle/trunk/ncc/typing/TypedTree.n
nemerle/trunk/ncc/typing/Typer.n
Modified: nemerle/trunk/macros/Late.n
==============================================================================
--- nemerle/trunk/macros/Late.n (original)
+++ nemerle/trunk/macros/Late.n Thu Jul 5 07:28:34 2007
@@ -277,14 +277,14 @@
| PExpr.As(pat, name) => PExpr.As(loc, recurse(pat), name)
| PExpr.Is(pat, ty) => PExpr.Is(loc, recurse(pat), ty)
| PExpr.Where(name, fields) => PExpr.Where(loc, recurse(name), recurse(fields))
- | PExpr.Match(mexpr, cases) =>
+ | PExpr.Match(mexpr, cases, expr_loc) =>
def recurse_case(c)
def recurse_guard(g)
| PExpr.Call(<[ $("when" : dyn) ]> as w, [pat, expr]) =>
PExpr.Call(g.Location, w, [pat, recurse(expr)])
| _ => g
MatchCase(c.patterns.Map(recurse_guard), recurse(c.body), c.disable_warnings)
- PExpr.Match(loc, recurse(mexpr), cases.Map(recurse_case))
+ PExpr.Match(loc, recurse(mexpr), cases.Map(recurse_case), expr_loc)
| PExpr.Ref => expr
| PExpr.Member(obj, mem) =>
if (Macros.IsTypeName (obj))
Modified: nemerle/trunk/ncc/generation/ILEmitter.n
==============================================================================
--- nemerle/trunk/ncc/generation/ILEmitter.n (original)
+++ nemerle/trunk/ncc/generation/ILEmitter.n Thu Jul 5 07:28:34 2007
@@ -31,9 +31,11 @@
using Nemerle.Collections;
using Nemerle.Utility;
+ using System;
using System.IO;
using System.Reflection;
using System.Reflection.Emit;
+ using System.Runtime.InteropServices;
using System.Diagnostics.SymbolStore;
using Nemerle.Compiler.Typedtree;
@@ -55,7 +57,7 @@
class ILEmitter
{
private _module_builder : ModuleBuilder;
- private _ilg : ILGenerator;
+ private _ilg : NemerleGenerator;
private _parent_type_builder : NC.TypeBuilder;
private _this_is_value_type : bool;
@@ -87,7 +89,7 @@
_method_builder = method_builder;
def mbase = _method_builder.GetMethodBase ();
- _ilg = Late.late_macro (mbase.GetILGenerator () :> ILGenerator);
+ _ilg = Late.late_macro (NemerleGenerator (mbase.GetILGenerator () :> ILGenerator));
_module_builder = mbase.Module :> ModuleBuilder;
_parent_type_builder = _method_builder.DeclaringType;
@@ -109,6 +111,7 @@
when (IsDebugEnabled) {
Mark (beginLocation (_method_builder.BodyLocation));
+ //IT.TEMP
_ilg.Emit (OpCodes.Nop);
}
@@ -1651,27 +1654,24 @@
}
else
{
- def emit_debug(line, col, eline, ecol, emit_nop)
+ def emit_debug(line, col, eline, ecol)
{
_ilg.MarkSequencePoint (_debug_doc, line, col, eline, ecol);
-
- when (emit_nop)
- _ilg.Emit (OpCodes.Nop);
}
def l = di.loc;
match (di.pexpr)
{
- | Sequence => emit_debug(l.Line, l.Column, l.Line, l.Column + 1, true);
- | _ => emit_debug(l.Line, l.Column, l.EndLine, l.EndColumn, false);
+ | Sequence => emit_debug(l.Line, l.Column, l.Line, l.Column + 1);
+ | _ => emit_debug(l.Line, l.Column, l.EndLine, l.EndColumn);
}
emit(di.expr);
match (di.pexpr)
{
- | Sequence => emit_debug(l.EndLine, l.EndColumn - 1, l.EndLine, l.EndColumn, false);
+ | Sequence => emit_debug(l.EndLine, l.EndColumn - 1, l.EndLine, l.EndColumn);
| _ => ()
}
}
@@ -2273,6 +2273,86 @@
_ilg.Emit (OpCodes.Ldc_I4_1);
_ilg.MarkLabel (label_condition_not_met)
}
+
+#pragma warning disable 10003
+
+ class NemerleGenerator
+ {
+ public this(ilg : ILGenerator)
+ {
+ _ilg = ilg;
+ }
+
+ private _ilg : ILGenerator;
+
+ public BeginCatchBlock (tp : Type) : void { _ilg.BeginCatchBlock(tp) }
+ public BeginExceptFilterBlock () : void { _ilg.BeginExceptFilterBlock() }
+ public BeginExceptionBlock () : Label { _ilg.BeginExceptionBlock() }
+ public BeginFaultBlock () : void { _ilg.BeginFaultBlock() }
+ public BeginFinallyBlock () : void { _ilg.BeginFinallyBlock() }
+ public EndExceptionBlock () : void { _ilg.EndExceptionBlock() }
+
+ public ThrowException (excType : Type) : void { _ilg.ThrowException(excType) }
+
+ public BeginScope () : void { _ilg.BeginScope() }
+ public EndScope () : void { _ilg.EndScope () }
+
+ public DeclareLocal (localType : Type) : LocalBuilder { _ilg.DeclareLocal(localType) }
+ public DeclareLocal (localType : Type, pinned : bool) : LocalBuilder { _ilg.DeclareLocal(localType, pinned) }
+
+ public DefineLabel () : Label { _ilg.DefineLabel() }
+ public MarkLabel (loc : Label ) : void { _ilg.MarkLabel(loc) }
+
+ public Emit (opcode : OpCode) : void { Emited(); _ilg.Emit(opcode) }
+ public Emit (opcode : OpCode, arg : byte) : void { Emited(); _ilg.Emit(opcode, arg) }
+ public Emit (opcode : OpCode, con : ConstructorInfo) : void { Emited(); _ilg.Emit(opcode, con) }
+ public Emit (opcode : OpCode, arg : double ) : void { Emited(); _ilg.Emit(opcode, arg) }
+ public Emit (opcode : OpCode, field : FieldInfo ) : void { Emited(); _ilg.Emit(opcode, field) }
+ public Emit (opcode : OpCode, arg : float) : void { Emited(); _ilg.Emit(opcode, arg) }
+ public Emit (opcode : OpCode, arg : int) : void { Emited(); _ilg.Emit(opcode, arg) }
+ public Emit (opcode : OpCode, label : Label) : void { Emited(); _ilg.Emit(opcode, label) }
+ public Emit (opcode : OpCode, labels : array[Label]) : void { Emited(); _ilg.Emit(opcode, labels) }
+ public Emit (opcode : OpCode, local : LocalBuilder) : void { Emited(); _ilg.Emit(opcode, local) }
+ public Emit (opcode : OpCode, arg : long) : void { Emited(); _ilg.Emit(opcode, arg) }
+ public Emit (opcode : OpCode, meth : MethodInfo) : void { Emited(); _ilg.Emit(opcode, meth) }
+ public Emit (opcode : OpCode, arg : sbyte) : void { Emited(); _ilg.Emit(opcode, arg) }
+ public Emit (opcode : OpCode, arg : short) : void { Emited(); _ilg.Emit(opcode, arg) }
+ public Emit (opcode : OpCode, signature : SignatureHelper) : void { Emited(); _ilg.Emit(opcode, signature) }
+ public Emit (opcode : OpCode, str : string) : void { Emited(); _ilg.Emit(opcode, str) }
+ public Emit (opcode : OpCode, cls : Type) : void { Emited(); _ilg.Emit(opcode, cls) }
+
+ public EmitCall (opcode : OpCode, methodInfo : MethodInfo , optionalParameterTypes : array[Type]) : void
+ { _ilg.EmitCall(opcode, methodInfo, optionalParameterTypes) }
+ public EmitCalli (opcode : OpCode, unmanagedCallConv : CallingConvention, returnType : Type, parameterTypes : array[Type]) : void
+ { _ilg.EmitCalli(opcode, unmanagedCallConv, returnType, parameterTypes) }
+ public EmitCalli (opcode : OpCode, callingConvention : CallingConventions, returnType : Type, parameterTypes : array[Type], optionalParameterTypes : array[Type]) : void
+ { _ilg.EmitCalli(opcode, callingConvention, returnType, parameterTypes, optionalParameterTypes) }
+
+ public EmitWriteLine (fld : FieldInfo) : void { _ilg.EmitWriteLine(fld) }
+ public EmitWriteLine (localBuilder : LocalBuilder) : void { _ilg.EmitWriteLine(localBuilder) }
+ public EmitWriteLine (value : string) : void { _ilg.EmitWriteLine(value) }
+
+ private mutable _justMarked : bool;
+
+ public MarkSequencePoint (document : ISymbolDocumentWriter, startLine : int, startColumn : int, endLine : int, endColumn : int) : void
+ {
+ when (_justMarked)
+ Emit (OpCodes.Nop);
+
+ _ilg.MarkSequencePoint (document, startLine, startColumn, endLine, endColumn);
+ _justMarked = true;
+ }
+
+ public UsingNamespace (usingNamespace : string) : void { _ilg.UsingNamespace(usingNamespace) }
+
+ private Emited() : void
+ {
+ _justMarked = false;
+ }
+ }
+
+#pragma warning restore 10003
+
} /* end of the class */
} /* end of the namespace */
Modified: nemerle/trunk/ncc/generation/Typer3.n
==============================================================================
Modified: nemerle/trunk/ncc/generation/Typer4.n
==============================================================================
--- nemerle/trunk/ncc/generation/Typer4.n (original)
+++ nemerle/trunk/ncc/generation/Typer4.n Thu Jul 5 07:28:34 2007
@@ -302,6 +302,7 @@
else
Throws (e, allow_try, false)
+ | DebugInfo (e, _)
| MacroEnvelope (_, _, e)
| Label (_, e) =>
Throws (e, allow_try, is_top)
@@ -316,9 +317,6 @@
| None => all // ???
}
- | DebugInfo (e, _) =>
- Throws (e, allow_try, is_top)
-
| Cache
| CacheRef
| LocalFunRef
@@ -521,6 +519,7 @@
TExpr.FieldMember (obj, fld)
+ | Assign (DebugInfo (e1, _), e2)
| Assign (e1, e2) =>
e1.IsAssigned = true;
Modified: nemerle/trunk/ncc/misc/ExprWalker.n
==============================================================================
--- nemerle/trunk/ncc/misc/ExprWalker.n (original)
+++ nemerle/trunk/ncc/misc/ExprWalker.n Thu Jul 5 07:28:34 2007
@@ -380,7 +380,8 @@
}
}
- private static Sort[T] (lst : list[T]) : list[T] where T : Located
+ private static
+ Sort[T] (lst : list[T]) : list[T] where T : Located
{
lst.Sort((i1, i2) =>
{
@@ -427,7 +428,7 @@
| ParmOut (e) // { parm : PExpr; }
| Spliced (e) // { body : PExpr; }
| Ellipsis (e) => Go(e); // { body : PExpr; }
- | Match (e, cs) => Go(e); Go(cs); // { expr : PExpr; cases : list [MatchCase]; }
+ | Match (e, cs, _) => Go(e); Go(cs); // { expr : PExpr; cases : list [MatchCase]; mutable expr_loc : Location; }
| Call (e, lst) // { func : PExpr; parms : list [PExpr]; }
| GenericSpecifier(e, lst) // { func : PExpr; generic_parms : list [PExpr]; }
| Indexer (e, lst) => // { obj : PExpr; args : list [PExpr]; }
Modified: nemerle/trunk/ncc/parsing/AST.n
==============================================================================
--- nemerle/trunk/ncc/parsing/AST.n (original)
+++ nemerle/trunk/ncc/parsing/AST.n Thu Jul 5 07:28:34 2007
@@ -118,6 +118,8 @@
public IsGenerated : bool { get { _fileIndex %&& GeneratedMask } }
public MarkAsGenerated() : void { _fileIndex |= GeneratedMask; }
+ public IsGeneratedOrEmpty : bool { get { IsGenerated || IsEmpty } }
+
public IsSourceAvailable : bool { get { _line > 0 } }
public static GetFileName(index : int) : string
Modified: nemerle/trunk/ncc/parsing/MainParser.n
==============================================================================
--- nemerle/trunk/ncc/parsing/MainParser.n (original)
+++ nemerle/trunk/ncc/parsing/MainParser.n Thu Jul 5 07:28:34 2007
@@ -2196,16 +2196,20 @@
}
| Token.Keyword ("match") =>
- def expr =
+ def (expr, expr_loc) =
match (get_token ()) {
| Token.RoundGroup (group) as whole when group != null =>
loc = loc + whole.Location;
+ (
match (parse_expr_sequence (group, [])) {
| [x] => x
| [] => fatal_error (group.Location, "expecting expression inside `match (..)'");
| xs => PExpr.Tuple (loc, xs.Reverse ())
}
- | x => fatal_error (x, "expecting non-empty `(..)' after `match'");
+ ,
+ whole.Location
+ )
+ | x => (fatal_error (x, "expecting non-empty `(..)' after `match'"), Location.Default);
}
match (get_token ()) {
| Token.BracesGroup (Token.LooseGroup (Token.Operator ("..")) as group) =>
@@ -2213,11 +2217,11 @@
match (maybe_parse_ellipsis ()) {
| Some (e) =>
pop_stream ("match body");
- PExpr.Match (loc, expr, [MatchCase ([], e)]);
+ PExpr.Match (loc, expr, [MatchCase ([], e)], expr_loc);
| _ => Util.ice ()
}
| Token.BracesGroup (group) as tok =>
- PExpr.Match (loc.Combine(tok.Location), expr, process_groups (group, "match body", parse_match_case))
+ PExpr.Match (loc.Combine(tok.Location), expr, process_groups (group, "match body", parse_match_case), expr_loc)
| x => fatal_error (x, "expecting '{' after 'match (e)'");
}
Modified: nemerle/trunk/ncc/parsing/ParseTree.n
==============================================================================
--- nemerle/trunk/ncc/parsing/ParseTree.n (original)
+++ nemerle/trunk/ncc/parsing/ParseTree.n Thu Jul 5 07:28:34 2007
@@ -400,7 +400,10 @@
| As { pat : PExpr; name : Splicable; }
| Is { pat : PExpr; ty : PExpr; }
| Where { name : PExpr; fields : PExpr; }
- | Match { expr : PExpr; cases : list [MatchCase]; }
+ | Match { expr : PExpr; cases : list [MatchCase]; mutable expr_loc : Location;
+ this(loc : Location, expr : PExpr, cases : list [MatchCase]) { this(loc, expr, cases, Location.Default); }
+ this(expr : PExpr, cases : list [MatchCase]) { this(expr, cases, Location.Default); }
+ }
| Ref { name : Name; }
| Member { obj : PExpr; member : Splicable; }
Modified: nemerle/trunk/ncc/parsing/Utility.n
==============================================================================
--- nemerle/trunk/ncc/parsing/Utility.n (original)
+++ nemerle/trunk/ncc/parsing/Utility.n Thu Jul 5 07:28:34 2007
@@ -329,7 +329,8 @@
if (mng.IsIntelliSenseMode)
s [s.Count - 1].AsGenerated ()
else
- s [s.Count - 1]//IT.TEMP.AsGenerated ()
+ s [s.Count - 1]//IT.TEMP
+ .AsGenerated ()
}
}
}
Modified: nemerle/trunk/ncc/typing/TypedTree.n
==============================================================================
--- nemerle/trunk/ncc/typing/TypedTree.n (original)
+++ nemerle/trunk/ncc/typing/TypedTree.n Thu Jul 5 07:28:34 2007
@@ -586,9 +586,8 @@
}
}
- def expr = unfold (t_expr);
- ref_is =
- match (expr) {
+ def get_ref (expr : TExpr)
+ {
| LocalRef
| This
| StaticRef
@@ -609,8 +608,13 @@
| _ => Util.ice ()
}
+ | DebugInfo (e, pe) => TExpr.DebugInfo (expr.loc, null, get_ref (unfold (e)), pe)
+
| _ => Util.ice ($ "invalid cached expr: $expr")
}
+
+ def expr = unfold (t_expr);
+ ref_is = get_ref (expr);
ref_is.loc = t_expr.loc;
ref_is.ty = t_expr.ty;
body
Modified: nemerle/trunk/ncc/typing/Typer.n
==============================================================================
--- nemerle/trunk/ncc/typing/Typer.n (original)
+++ nemerle/trunk/ncc/typing/Typer.n Thu Jul 5 07:28:34 2007
@@ -644,6 +644,7 @@
e.SkipWriteCheck && mem.Attributes %&& NemerleAttributes.CompilerMutable
| TExpr.CacheRef (desc) => IsLValue (desc.TExpr, need_ref)
+ | TExpr.DebugInfo(expr, _) => IsLValue (expr, need_ref)
| TExpr.PropertyMember (_, p) when !need_ref => p.IsMutable
| TExpr.Call (TExpr.PropertyMember (_, p), _, _) when !need_ref => p.IsMutable
@@ -1059,22 +1060,20 @@
}
- public TypeExpr (e : PT.PExpr, expected : TyVar, is_toplevel_in_seq : bool) : TExpr
+ public TypeExpr (expr : PT.PExpr, expected : TyVar, is_toplevel_in_seq : bool) : TExpr
{
- log (TYPING, e.loc, $ "(typing expression: $e, exp=$expected");
+ log (TYPING, expr.loc, $ "(typing expression: $expr, exp=$expected");
- def texpr = Util.locate (e.loc, {
- def e' = InterceptSpecialMacros (e, expected);
+ def texpr = Util.locate (expr.loc, {
+ def e' = InterceptSpecialMacros (expr, expected);
def e' =
try {
if (e' != null) {
- log (TYPING, e.loc, $ "intercepted: $e'");
+ log (TYPING, expr.loc, $ "intercepted: $e'");
e'
} else {
- def orig_loc = e.Location;
-
- log (MACRO_EXPANSIONS, e.loc, $ "running expand with: $e");
- match (MacroRegistry.expand_one_macro (this, e)) {
+ log (MACRO_EXPANSIONS, expr.loc, $ "running expand with: $expr");
+ match (MacroRegistry.expand_one_macro (this, expr)) {
| (e, None) =>
log (MACRO_EXPANSIONS, e.loc, $ "after expansion: $e");
@@ -1089,13 +1088,24 @@
| (e, Some ((orig, im))) =>
log (MACRO_EXPANSIONS, e.loc, $ "after expansion: $e");
+ def debugLocation =
+ if (Manager.Options.EmitDebug && !expr.loc.IsGeneratedOrEmpty)
+ GetDebugLocation(expr);
+ else
+ Location.Default;
+
def res = TypeExpr (e, expected, is_toplevel_in_seq);
// IT: In some cases, MacroEnvelope takes e.Location without keyword location.
// For example, for (mutable i;;) {} takes e.Location without 'for'.
// The following fixes that.
- def loc = if (orig_loc.IsGenerated) res.Location else orig_loc;
- TExpr.MacroEnvelope (loc, res.Type, im, orig, res)
+ def loc = if (expr.loc.IsGeneratedOrEmpty) res.Location else expr.loc;
+ def res = TExpr.MacroEnvelope (loc, res.Type, im, orig, res);
+
+ if (debugLocation.IsEmpty)
+ res
+ else
+ TExpr.DebugInfo (debugLocation, null, res, expr);
}
}
} catch {
@@ -1112,8 +1122,8 @@
e'
});
- when (e.typed_object == null)
- e.typed_object = texpr;
+ when (expr.typed_object == null)
+ expr.typed_object = texpr;
texpr;
}
@@ -1162,10 +1172,6 @@
DoExpect (expected, actual, place, true)
}
- static _debug(obj : object) : void
- {
- _ = obj.ToString();
- }
DoType (expression : PT.PExpr, expected : TyVar, is_toplevel_in_seq : bool) : TExpr
{
@@ -1175,13 +1181,7 @@
Manager.Complete (expression, expected, this, env);
}
- def addDebugInfo(res)
- {
- //if (expression.IsGenerated || expression.loc.IsEmpty || Manager.IsIntelliSenseMode)
- res
- //else
- // TExpr.DebugInfo(expression.Location, null, res, expression);
- }
+ def debugLocation = GetDebugLocation(expression);
def texpr = match (expression)
{
@@ -1191,12 +1191,11 @@
"ref and out parameters are only allowed in function calls")
| PT.PExpr.DefMutable (x, null) =>
- DoType (PT.PExpr.DefMutable (x, <[ $(TExpr.DefaultValue (FreshTyVar ()) : typed) ]>), expected, is_toplevel_in_seq)
+ DoType (PT.PExpr.DefMutable (x, <[ $(TExpr.DefaultValue (FreshTyVar ()) : typed) ]>), expected, is_toplevel_in_seq);
| PT.PExpr.DefMutable (PT.PExpr.Ref as name, val)
| PT.PExpr.Define (PT.PExpr.Ref as name, val) =>
def is_mutable = expression is PT.PExpr.DefMutable;
- def res =
if (Expect (expected, InternalType.Void, "definition ``result''"))
if (is_toplevel_in_seq)
TypeLocalDefinition (is_mutable, name.name, name.Location, val)
@@ -1209,7 +1208,6 @@
}
else
TExpr.Error ();
- addDebugInfo(res);
| PT.PExpr.DefMutable (Tuple (Ref (first_n) :: names), Tuple (first_v :: vals)) =>
if (Expect (expected, InternalType.Void, "definition ``result''"))
@@ -1244,7 +1242,7 @@
PopLocals ()
}
else
- TExpr.Error ()
+ TExpr.Error ();
| PT.PExpr.DefMutable (TypeEnforcement (nm, ty) as te, val) =>
def nte = PT.PExpr.TypeEnforcement (ty.Location.Combine(val.Location), val, ty);
@@ -1266,7 +1264,7 @@
PopLocals ()
}
else
- TExpr.Error ()
+ TExpr.Error ();
| PT.PExpr.DefFunctions (functions) =>
@@ -1527,7 +1525,7 @@
PT.PExpr.Call (star_ref, [loop (ps), p])
| [] => assert (false)
}
- TypeExpr (loop (List.Rev (parms)), expected)
+ TypeExpr (loop (List.Rev (parms)), expected);
| <[ $("_N_ref_cache" : dyn) ($(name : name), $val) ]> =>
if (Expect (expected, InternalType.Void, "definition ``result''")) {
@@ -1549,7 +1547,7 @@
}) || fnc is <[ _ . $_ ]>)
TypeExpr (PartialApplication (expression), expected)
else
- TypeCall (fnc, parms, expected, is_property = false)
+ TypeCall (fnc, parms, expected, is_property = false);
| PT.PExpr.Assign (PT.PExpr.Tuple (vars), e2) =>
@@ -1562,14 +1560,14 @@
]>;
TypeExpr (expr, expected)
} else
- TExpr.Error ()
+ TExpr.Error ();
| PT.PExpr.Assign (PT.PExpr.Wildcard, e2) =>
if (Expect (expected, InternalType.Void, "assignment ``result''"))
TypeExpr (<[ def _ = $e2 ]>, expected)
else
- TExpr.Error ()
+ TExpr.Error ();
| PT.PExpr.Assign (e1, e2) =>
@@ -1579,7 +1577,7 @@
def e2 = TypeExpr (e2);
TExpr.Assign (e1, AddCastTo (e2, e1.Type, "assigned value"))
} else
- TExpr.Error ()
+ TExpr.Error ();
| PT.PExpr.GenericSpecifier (fnc, gen_params) =>
@@ -1648,7 +1646,7 @@
| PT.PExpr.Sequence ([]) =>
_ = Expect (expected, InternalType.Void, "empty sequence");
- addDebugInfo (VoidLiteral ())
+ VoidLiteral ()
| PT.PExpr.Sequence (l) =>
@@ -1670,7 +1668,7 @@
def res = loop ([], l);
//Message.Debug ("pop seq");
PopLocals ();
- addDebugInfo (res)
+ res
| PT.PExpr.Tuple (l) =>
@@ -1770,13 +1768,116 @@
when (expression.typed_object == null)
expression.typed_object = texpr;
+
+ if (debugLocation.IsEmpty)
texpr
+ else
+ TExpr.DebugInfo (debugLocation, null, texpr, expression)
}
- #endregion
+ private mutable debugInfos : list[Location * PT.PExpr] = [];
+
+ private GetDebugLocation(pexpr : PT.PExpr) : Location
+ {
+ def skip(l)
+ {
+ debugInfos.Exists((loc, _) => loc.Contains(l));
+ }
+ //IT.TEMP
+ _ =
+ if (!Manager.Options.EmitDebug || pexpr.loc.IsGeneratedOrEmpty || skip(pexpr.loc))
+ Location.Default
+ else
+ {
+ mutable loc = pexpr.Location;
+
+ def truncateLoc()
+ {
+ mutable isTruncated = false;
+
+ // Truncate DebugInfo location to inner exprs.
+ //
+ ExprWalker().Walk(pexpr, info =>
+ {
+ def truncate(line, col)
+ {
+ when (line < loc.EndLine || line == loc.EndLine && col < loc.EndColumn)
+ {
+ loc = Location(loc.FileIndex, loc.Line, loc.Column, line, col);
+ isTruncated = true;
+ }
+ }
+
+ match (info.Node)
+ {
+ | PT.PExpr.Sequence as s when !s.loc.IsGeneratedOrEmpty => truncate(s.loc.Line, s.loc.Column);
+ | PT.PExpr.Match(_, _, l) when !l.IsGeneratedOrEmpty => truncate(l.EndLine, l.EndColumn);
+ | _ => ()
+ }
+ });
+
+ when (isTruncated)
+ {
+ // Here we store the location of the last element,
+ // which ends on the same line where the original pexpr starts.
+ // It's used to truncate DebugInfo location to a single line.
+ //
+ mutable lastLineLoc;
+
+ // Scan inner exprs.
+ //
+ ExprWalker().Walk(pexpr, info =>
+ {
+ when (info.Node is Located)
+ {
+ def l = (info.Node :> Located).loc;
+
+ when (
+ l.EndLine == loc.Line &&
+ l.EndColumn > lastLineLoc.EndColumn &&
+ (loc.EndLine != loc.Line || l.EndColumn < loc.EndColumn))
+ {
+ lastLineLoc = l;
+ }
+ }
+ });
+
+ unless (lastLineLoc.IsEmpty)
+ loc = Location(loc.FileIndex, loc.Line, loc.Column, lastLineLoc.EndLine, lastLineLoc.EndColumn);
+ }
+ }
+
+ match (pexpr)
+ {
+ | PT.PExpr.Sequence => ()
+ | PT.PExpr.MacroCall(nm, _, _) when
+ nm.loc.IsGenerated == false &&
+ nm.loc.Line == loc.Line &&
+ nm.loc.Column == loc.Column =>
+
+ loc = nm.loc;
+
+ | _ =>
+ truncateLoc();
+ unless (loc.IsEmpty)
+ {
+ if (skip (loc))
+ loc = Location.Default;
+ else
+ debugInfos ::= (loc, pexpr);
+ }
+ }
+
+ loc;
+ }
+ Location.Default;
+ }
+
+ #endregion
#region ,,def''
+
TypeLocalDefinition (is_mutable : bool, name : PT.Name, val : PT.PExpr) : TExpr.DefValIn
{
TypeLocalDefinition (is_mutable, name, Location.Default, val)
More information about the svn
mailing list