[Laszlo-checkins] r10719 - in openlaszlo/trunk/WEB-INF/lps/server/src/org/openlaszlo: compiler sc

dda@openlaszlo.org dda at openlaszlo.org
Tue Aug 19 10:37:14 PDT 2008


Author: dda
Date: 2008-08-19 10:37:08 -0700 (Tue, 19 Aug 2008)
New Revision: 10719

Added:
   openlaszlo/trunk/WEB-INF/lps/server/src/org/openlaszlo/sc/SourceFile.java
   openlaszlo/trunk/WEB-INF/lps/server/src/org/openlaszlo/sc/SourceFileMap.java
Modified:
   openlaszlo/trunk/WEB-INF/lps/server/src/org/openlaszlo/compiler/Main.java
   openlaszlo/trunk/WEB-INF/lps/server/src/org/openlaszlo/sc/CommonGenerator.java
   openlaszlo/trunk/WEB-INF/lps/server/src/org/openlaszlo/sc/Compiler.java
   openlaszlo/trunk/WEB-INF/lps/server/src/org/openlaszlo/sc/JavascriptGenerator.java
   openlaszlo/trunk/WEB-INF/lps/server/src/org/openlaszlo/sc/ParseTreePrinter.java
   openlaszlo/trunk/WEB-INF/lps/server/src/org/openlaszlo/sc/SWF9External.java
   openlaszlo/trunk/WEB-INF/lps/server/src/org/openlaszlo/sc/SWF9Generator.java
   openlaszlo/trunk/WEB-INF/lps/server/src/org/openlaszlo/sc/SWF9ParseTreePrinter.java
   openlaszlo/trunk/WEB-INF/lps/server/src/org/openlaszlo/sc/TranslationUnit.java
Log:
Change 20080818-dda-Z by dda at lester.local on 2008-08-18 14:43:32 EDT
    in /Users/dda/laszlo/src/svn/openlaszlo/trunk-a
    for http://svn.openlaszlo.org/openlaszlo/trunk

Summary: SWF9: line number fixes for error messages

New Features:

Bugs Fixed: LPP-6834 [Line unkown compiler error]

Technical Reviewer: ptw (pending)
QA Reviewer: (pending)
Doc Reviewer: (pending)

Documentation:

Release Notes:

Details:
    Multiple fixes for line number error messages.

    First - line number information was being suppressed unless debug was on.
    This can make sense for debugging information, but some line number info
    is needed to remap error messages from generated .as files back to original
    file/line numbers.  The suppression was previously added since building LFC with
    full linenumber info can blow up memory in the unparser (the line number info in the
    unparsed strings can get very long as they are replicated over and over in the
    bottom up unparser (*)).  Now we force 'trackLines' to true when not building LFC.

    Second - we are careful when we emit: '/* -*- file: foo.lzx#123 -*- */' source locators
    that are used for the IDE debugger.  It turns out that we need to save
    additional line number information to be used for translating error messages.
    In the test program given by this Jira, the code that had the error did not
    correspond to a user input line number (it was an error in lps/components/rpc/rpc.lzx),
    the debugger was not told about that line.  But the error message still needs to be
    translated.  Now we separate the decision of whether to save line number info
    for translating error messages vs emitting line number info for the debugger.

    Third - there was a tacit assumption on my part that each .as file (i.e. class)
    generated had source mainly from a single input file.   This is not true, for
    one example, the LzApplication class can contain code from many sources.
    Now, the line number mapping in TranslationUnit contains both a source file name
    and a source file line number.  In anticipation of future work (see below), I
    encapsulated a source file name into an object along with a SourceFileMap
    that allows us to give each source file a unique index within
    the compilation.  This could make for some shorthand notations for file names
    used internally.

    (*) Potentially we could fix the out of memory errors by rewriting the unparser to not build up its result using
    Strings with 'annotated' line numbers but use a more structured output.  Possible future work.
    Or, the annotated strings could become much shorter by using our new source file indices.

    In addition, this changeset has a way to dump line number annotations, and introduces an option
    to consolidate outputs used for debugging the compiler.  Now, in addition to saving script files via
    lzc -S foo.lzx, one can use lzc -SS foo.lzx to generate several files (all named beginning with "NAME-" for
    input file "NAME.lzx") that are useful for debugging the compiler:
        
        NAME-astin-N.txt      dumped AST input to the generator (N chosen uniquely)
        NAME-astout-N.txt     dumped AST output from the generator
        NAME-lineann-N.txt    line annotations
        NAME.lzs              script file
        
    Changes by file:

    SourceFile.java
    SourceFileMap.java
        new files
        encapsulate source file names, assigning a unique index for each
    
    CommonGenerator.java
        Create a SourceFileMap to be used during the compilation
    
    SWF9Generator.java
    JavascriptGenerator.java
        Use the SourceFileMap with ParseTreePrinter
        Pass the dumpLineAnnotations option to ParseTreePrinter
        turn on trackLines appropriately (SWF9Generator.java)
    
    SWF9External.java
        Show file and line number from error mapped by TranslationUnit.
    
    TranslationUnit.java
        Track both filenames (SourceFiles) and line numbers in the
        line number mapping.
    
    compiler/Main.java
        Implement -SS option
    
    SWF9ParseTreePrinter.java
        implement dumpAnnotationsFile option
    
    ParseTreePrinter.java
        implement dumpAnnotationsFile option
        Break out the decision to emit source locations for debugger use
        and tell TranslationUnit about line number info that can be used
        for mapping error messages.
        Fixed error where 'previous' line number was given to translation unit.
    
    sc/Compiler.java
        implement unique numbered file for debug output
        e.g. -dumpASTInput='foo-*.txt' will dump to
        foo-1.txt, then foo-2.txt, etc.
        This is convenient when there are multiple calls to the compiler


Tests:
  -  Backported this change to r10708, which includes the mistake in rpc,
     and tried the test case from LPP-6834, and get the error line:
       org.openlaszlo.sc.CompilerError: rpc/rpc.lzx: 202: Error: Access of undefined property LzJavaRPCService, in line: return LzJavaRPCService
  -  Used the same test case in the current tree, but inserted an error (call to undefined 'stuff()',
     and got a valid error message and accurate file and line .
  -  Tried nexb619.lzx to verify that source locations for debugger are unaffected.

  -  smokecheck SWF8, DHTML
  -  weather+lzpix  ALL
  -  hello   SWF9



Modified: openlaszlo/trunk/WEB-INF/lps/server/src/org/openlaszlo/compiler/Main.java
===================================================================
--- openlaszlo/trunk/WEB-INF/lps/server/src/org/openlaszlo/compiler/Main.java	2008-08-19 15:26:46 UTC (rev 10718)
+++ openlaszlo/trunk/WEB-INF/lps/server/src/org/openlaszlo/compiler/Main.java	2008-08-19 17:37:08 UTC (rev 10719)
@@ -67,8 +67,10 @@
         "  Specify logfile (output still goes to console as well)",
         "--schema",
         "  Writes the schema to standard output.",
-        "--script",
-        "  Writes JavaScript to standard output."
+        "-S | --script",
+        "  Writes JavaScript to .lzs file.",
+        "-SS | --savestate",
+        "  Writes JavaScript to .lzs file, and ASTs to -astin.txt, -astout.txt"
     };
 
     private final static String MORE_HELP =
@@ -125,6 +127,7 @@
         Boolean forceTransCode = null;
         String outFileArg = null;
         boolean saveScriptOption = false;
+        boolean saveStateOption = false;
 
         for (int i = 0; i < args.length; i++) {
             String arg = args[i].intern();
@@ -172,6 +175,8 @@
                     }
                 } else if (arg == "-S" || arg == "--script") {
                     saveScriptOption = true;
+                } else if (arg == "-SS" || arg == "--scripts") {
+                    saveStateOption = true;
                 } else if (arg == "--script-cache-dir") {
                     scriptCacheDir = safeArg("--script-cache-dir", args, ++i);
                     if (scriptCacheDir == null) {
@@ -290,14 +295,29 @@
         for (Iterator iter = files.iterator(); iter.hasNext(); ) {
             String sourceName = (String) iter.next();
             String intermediateName = null;
+            String sourceNameNoExt = sourceName.endsWith(".lzx") ?
+                sourceName.substring(0, sourceName.length()-4) : sourceName;
 
-            if (saveScriptOption) {
-                if (sourceName.endsWith(".lzx")) {
-                    intermediateName = sourceName.replaceAll(".lzx$", ".lzs");
+            if (saveScriptOption || saveStateOption) {
+                intermediateName = sourceNameNoExt + ".lzs";
+            }
+            if (saveStateOption) {
+                // remove old 
+                File dir = new File(sourceName).getCanonicalFile().getParentFile();
+                final String pat = new File(sourceNameNoExt).getName() +
+                    "-ast(?:in|out)-[0-9]*.txt";
+                String[] matches = dir.list(new FilenameFilter() {
+                        public boolean accept(File dir, String name) {
+                            return name.matches(pat);
+                        }
+                    });
+                for (int i=0; i<matches.length; i++) {
+                    System.out.println("Removing " + matches[i]);
+                    new File(matches[i]).delete();
                 }
-                else {
-                    intermediateName = sourceName + ".lzs";
-                }
+                compiler.setProperty(org.openlaszlo.sc.Compiler.DUMP_AST_INPUT, sourceNameNoExt + "-astin-*.txt");
+                compiler.setProperty(org.openlaszlo.sc.Compiler.DUMP_AST_OUTPUT, sourceNameNoExt + "-astout-*.txt");
+                compiler.setProperty(org.openlaszlo.sc.Compiler.DUMP_LINE_ANNOTATIONS, sourceNameNoExt + "-lineann-*.txt");
             }
             status += compile(compiler, logger, sourceName, intermediateName, outFileName, outDir);
         }

Modified: openlaszlo/trunk/WEB-INF/lps/server/src/org/openlaszlo/sc/CommonGenerator.java
===================================================================
--- openlaszlo/trunk/WEB-INF/lps/server/src/org/openlaszlo/sc/CommonGenerator.java	2008-08-19 15:26:46 UTC (rev 10718)
+++ openlaszlo/trunk/WEB-INF/lps/server/src/org/openlaszlo/sc/CommonGenerator.java	2008-08-19 17:37:08 UTC (rev 10719)
@@ -88,6 +88,7 @@
   TranslationContext context = null;
   boolean debugVisit = false;
   InstructionCollector collector = null;
+  SourceFileMap sources = new SourceFileMap();
 
   // Used for swf8 loadable libraries, to put stuff into _level0 namespace
   String globalprefix = "";

Modified: openlaszlo/trunk/WEB-INF/lps/server/src/org/openlaszlo/sc/Compiler.java
===================================================================
--- openlaszlo/trunk/WEB-INF/lps/server/src/org/openlaszlo/sc/Compiler.java	2008-08-19 15:26:46 UTC (rev 10718)
+++ openlaszlo/trunk/WEB-INF/lps/server/src/org/openlaszlo/sc/Compiler.java	2008-08-19 17:37:08 UTC (rev 10719)
@@ -347,15 +347,15 @@
 
       String astInputFile = (String)options.get(DUMP_AST_INPUT);
       if (astInputFile != null) {
-        emitFile(astInputFile, program);
-        System.err.println("Created " + astInputFile);
+        String newname = emitFile(astInputFile, program);
+        System.err.println("Created " + newname);
       }
       profiler.phase("generate");
       SimpleNode translated = cg.translate(program);
       String astOutputFile = (String)options.get(DUMP_AST_OUTPUT);
       if (astOutputFile != null) {
-        emitFile(astOutputFile, translated);
-        System.err.println("Created " + astOutputFile);
+        String newname = emitFile(astOutputFile, translated);
+        System.err.println("Created " + newname);
       }
 
       if (isScript) {
@@ -464,6 +464,7 @@
   public static String DEBUG_EVAL = "debugEval";
   public static String DUMP_AST_INPUT = "dumpASTInput";
   public static String DUMP_AST_OUTPUT = "dumpASTOutput";
+  public static String DUMP_LINE_ANNOTATIONS = "dumpLineAnnotations";
   public static String DISABLE_CONSTANT_POOL = "disableConstantPool";
   public static String DISABLE_TRACK_LINES = "disableTrackLines";
   public static String ELIMINATE_DEAD_EXPRESSIONS = "eliminateDeadExpressions";
@@ -976,9 +977,22 @@
 
   /**
    * Emit a file using the TextEmitter as a source for the file text.
+   * The filenamePattern argument can include '*', for this a number
+   * is substituted such that the given filename does not yet exist.
+   * The filename used is returned.
    */
-  public static void emitFile(String filename, TextEmitter tw) {
+  public static String emitFile(String filenamePattern, TextEmitter tw) {
     FileWriter writer = null;
+    String filename;
+    if (filenamePattern.indexOf("*") >= 0) {
+      int index = 1;
+      while ((new File((filename = filenamePattern.replaceAll("\\*", String.valueOf(index))))).exists()) {
+        index++;
+      }
+    }
+    else {
+      filename = filenamePattern;
+    }
     try {
       File f = new File(filename);
       f.delete();
@@ -998,13 +1012,14 @@
         }
       }
     }
+    return filename;
   }
 
   /**
    * emit a file with the given String text
    */
-  public static void emitFile(String filename, final String txt) {
-    emitFile(filename, new TextEmitter() {
+  public static String emitFile(String filename, final String txt) {
+    return emitFile(filename, new TextEmitter() {
         public void emit(Writer writer)
           throws IOException {
           writer.write(txt);
@@ -1015,8 +1030,8 @@
   /**
    * emit a file with the given node (to be dumped) as the text.
    */
-  public static void emitFile(String filename, final SimpleNode node) {
-    emitFile(filename, new TextEmitter() {
+  public static String emitFile(String filename, final SimpleNode node) {
+    return emitFile(filename, new TextEmitter() {
         public void emit(Writer writer)
           throws IOException {
           nodeFileDump(writer, "", node);

Modified: openlaszlo/trunk/WEB-INF/lps/server/src/org/openlaszlo/sc/JavascriptGenerator.java
===================================================================
--- openlaszlo/trunk/WEB-INF/lps/server/src/org/openlaszlo/sc/JavascriptGenerator.java	2008-08-19 15:26:46 UTC (rev 10718)
+++ openlaszlo/trunk/WEB-INF/lps/server/src/org/openlaszlo/sc/JavascriptGenerator.java	2008-08-19 17:37:08 UTC (rev 10719)
@@ -195,7 +195,8 @@
   public List makeTranslationUnits(SimpleNode translatedNode, boolean compress, boolean obfuscate)
   {
     boolean trackLines = options.getBoolean(Compiler.TRACK_LINES);
-    return (new ParseTreePrinter(compress, obfuscate, trackLines)).makeTranslationUnits(translatedNode);
+    String dumpann = (String)options.get(Compiler.DUMP_LINE_ANNOTATIONS);
+    return (new ParseTreePrinter(compress, obfuscate, trackLines, dumpann)).makeTranslationUnits(translatedNode, sources);
   }
 
   public byte[] postProcess(List tunits) {

Modified: openlaszlo/trunk/WEB-INF/lps/server/src/org/openlaszlo/sc/ParseTreePrinter.java
===================================================================
--- openlaszlo/trunk/WEB-INF/lps/server/src/org/openlaszlo/sc/ParseTreePrinter.java	2008-08-19 15:26:46 UTC (rev 10718)
+++ openlaszlo/trunk/WEB-INF/lps/server/src/org/openlaszlo/sc/ParseTreePrinter.java	2008-08-19 17:37:08 UTC (rev 10719)
@@ -49,6 +49,7 @@
 
   boolean compress;
   boolean trackLines;
+  String dumpLineAnnotationsFile;
   String SPACE;
   String NEWLINE;
   String COMMA;
@@ -74,14 +75,15 @@
   }
 
   public ParseTreePrinter(boolean compress, boolean obfuscate) {
-    this(compress, obfuscate, false);
+    this(compress, obfuscate, false, null);
   }
 
   // TODO: [2007-11-21 dda] if compress/obfuscate are on, probably
   // can turn off generation of annotations.
-  public ParseTreePrinter(boolean compress, boolean obfuscate, boolean trackLines) {
+  public ParseTreePrinter(boolean compress, boolean obfuscate, boolean trackLines, String dumpLineAnnotationsFile) {
     this.compress = compress;
     this.trackLines = trackLines;
+    this.dumpLineAnnotationsFile = dumpLineAnnotationsFile;
     // Set whitespace
     this.SPACE = compress ? "" : " ";
     this.NEWLINE = obfuscate ? "" : "\n";
@@ -878,8 +880,8 @@
     return "throw" + delimit(children[0]);
   }
   
-  public List makeTranslationUnits(SimpleNode node) {
-    return makeTranslationUnits(visit(node));
+  public List makeTranslationUnits(SimpleNode node, SourceFileMap sources) {
+    return makeTranslationUnits(visit(node), sources);
   }
 
   public static String unparse(SimpleNode node) {
@@ -1197,20 +1199,34 @@
     return lnstate;
   }
 
-  public List makeTranslationUnits(String annotated) {
+  public List makeTranslationUnits(String annotated, final SourceFileMap sources) {
+    if (dumpLineAnnotationsFile != null) {
+      Compiler.emitFile(dumpLineAnnotationsFile, printableAnnotations(annotated));
+      System.err.println("Created " + dumpLineAnnotationsFile);
+    }
+    if (DEBUG_NODE_OUTPUT) {
+      System.out.println("ANNOTATED OUTPUT:\n" + printableAnnotations(annotated));
+    }
+
     final ArrayList tunits = new ArrayList();
     final TranslationUnit defaulttu = new TranslationUnit(true);
 
     tunits.add(defaulttu);
 
-    if (DEBUG_NODE_OUTPUT)
-      System.out.println("ANNOTATED OUTPUT:\n" + printableAnnotations(annotated));
-
     AnnotationProcessor ap = new AnnotationProcessor() {
         TranslationUnit curtu = defaulttu;
         boolean atBol = true;
         LineNumberState curLstate = new LineNumberState();
 
+        /** source locations are recorded to show error messages.
+         * We want to err on the side of recording more, not less.
+         */
+        public boolean shouldRecordSourceLocation(LineNumberState state) {
+          return (state.hasfile && state.linenum != Integer.MIN_VALUE);
+        }
+
+        /** source locations that are shown are used by the debugger.
+         */
         public boolean shouldShowSourceLocation(LineNumberState os,
                                                 LineNumberState ns,
                                                 char op,
@@ -1312,6 +1328,9 @@
           case ANNOTATE_OP_FILE_LINENUM:
             LineNumberState newLstate = getLineNumberState(curtu, operand);
 
+            if (shouldRecordSourceLocation(newLstate)) {
+              curtu.setInputLineNumber(newLstate.linenum, sources.byName(newLstate.filename));
+            }
             if (shouldShowSourceLocation(curLstate, newLstate, op, atBol)) {
               String srcloc = atBol ? "" : "\n";
               if (op == ANNOTATE_OP_FILE_LINENUM_FORCE) {
@@ -1325,7 +1344,6 @@
                 srcloc += "/* -*- file: " + operand + " -*- */\n";
               }
               curtu.addText(srcloc);
-              curtu.setInputLineNumber(curLstate.linenum);
               newLstate.linediff++; // compensate for line just added
               curLstate = newLstate;
             }

Modified: openlaszlo/trunk/WEB-INF/lps/server/src/org/openlaszlo/sc/SWF9External.java
===================================================================
--- openlaszlo/trunk/WEB-INF/lps/server/src/org/openlaszlo/sc/SWF9External.java	2008-08-19 15:26:46 UTC (rev 10718)
+++ openlaszlo/trunk/WEB-INF/lps/server/src/org/openlaszlo/sc/SWF9External.java	2008-08-19 17:37:08 UTC (rev 10719)
@@ -506,7 +506,7 @@
           ExternalCompilerError err = (ExternalCompilerError)iter.next();
           TranslationUnit tunit = err.getTranslationUnit();
           String srcLineStr;
-          int srcLine;
+          TranslationUnit.SourceFileLine srcFileLine;
 
           // actualSrcLine is the name/linenumber of the actual files
           // used in compilation, not the original sources.
@@ -522,12 +522,14 @@
 
           String actualSrcLine = "[" + actualSrcFile + ": " + err.getLineNumber() + "] ";
 
-          if (tunit == null ||
-              ((srcLine = tunit.originalLineNumber(err.getLineNumber())) <= 0)) {
+          if (tunit == null) {
+            srcLineStr = "tunit/line unknown: ";
+          }
+          else if ((srcFileLine = tunit.originalLineNumber(err.getLineNumber())) == null) {
             srcLineStr = "line unknown: ";
           }
           else {
-            srcLineStr = "line " + String.valueOf(srcLine) + ": ";
+            srcLineStr = srcFileLine.sourcefile.name + ": " + srcFileLine.line + ": ";
           }
           System.err.println(actualSrcLine + srcLineStr + err.getErrorString());
 

Modified: openlaszlo/trunk/WEB-INF/lps/server/src/org/openlaszlo/sc/SWF9Generator.java
===================================================================
--- openlaszlo/trunk/WEB-INF/lps/server/src/org/openlaszlo/sc/SWF9Generator.java	2008-08-19 15:26:46 UTC (rev 10718)
+++ openlaszlo/trunk/WEB-INF/lps/server/src/org/openlaszlo/sc/SWF9Generator.java	2008-08-19 17:37:08 UTC (rev 10719)
@@ -673,9 +673,11 @@
       mainClass = SWF9Generator.MAIN_LIB_CLASSNAME;
     } else {
       mainClass = debugEval ? SWF9Generator.DEBUG_EVAL_CLASSNAME : SWF9Generator.MAIN_APP_CLASSNAME;
+      trackLines = true;        // needed to get error messages that relate to original source
     }
 
-    return (new SWF9ParseTreePrinter(compress, obfuscate, mainClass, buildSharedLibrary, trackLines)).makeTranslationUnits(translatedNode);
+    String dumpann = (String)options.get(Compiler.DUMP_LINE_ANNOTATIONS);
+    return (new SWF9ParseTreePrinter(compress, obfuscate, mainClass, buildSharedLibrary, trackLines, dumpann)).makeTranslationUnits(translatedNode, sources);
   }
 
   /** Implements CodeGenerator.

Modified: openlaszlo/trunk/WEB-INF/lps/server/src/org/openlaszlo/sc/SWF9ParseTreePrinter.java
===================================================================
--- openlaszlo/trunk/WEB-INF/lps/server/src/org/openlaszlo/sc/SWF9ParseTreePrinter.java	2008-08-19 15:26:46 UTC (rev 10718)
+++ openlaszlo/trunk/WEB-INF/lps/server/src/org/openlaszlo/sc/SWF9ParseTreePrinter.java	2008-08-19 17:37:08 UTC (rev 10719)
@@ -66,20 +66,20 @@
   }
   
   public SWF9ParseTreePrinter() {
-    this(false, false, null, false, false);
+    this(false, false, null, false, false, null);
   }
   
   public SWF9ParseTreePrinter(boolean compress) {
-    this(compress, false, null, false, false);
+    this(compress, false, null, false, false, null);
   }
   
   public SWF9ParseTreePrinter(boolean compress, boolean obfuscate) {
-    this(compress, obfuscate, null, false, false);
+    this(compress, obfuscate, null, false, false, null);
   }
 
-  public SWF9ParseTreePrinter(boolean compress, boolean obfuscate, String mainClassName, boolean sharedLibrary, boolean trackLines) {
+  public SWF9ParseTreePrinter(boolean compress, boolean obfuscate, String mainClassName, boolean sharedLibrary, boolean trackLines, String dumpAnnotationsFile) {
     // never compress or obfuscate
-    super(false, false, trackLines);
+    super(false, false, trackLines, dumpAnnotationsFile);
     this.mainClassName = mainClassName;
     this.islib = sharedLibrary;
   }
@@ -111,8 +111,8 @@
   // application or the LFC, we have a 'main' class that must
   // be present to accept these statements.
   //
-  public List makeTranslationUnits(String annotated) {
-    List result = super.makeTranslationUnits(annotated);
+  public List makeTranslationUnits(String annotated, SourceFileMap sources) {
+    List result = super.makeTranslationUnits(annotated, sources);
     TranslationUnit defaultTunit = null;
     TranslationUnit mainTunit = null;
     for (Iterator iter = result.iterator(); iter.hasNext(); ) {

Added: openlaszlo/trunk/WEB-INF/lps/server/src/org/openlaszlo/sc/SourceFile.java


Property changes on: openlaszlo/trunk/WEB-INF/lps/server/src/org/openlaszlo/sc/SourceFile.java
___________________________________________________________________
Name: svn:mime-type
   + text/plain
Name: svn:eol-style
   + native

Added: openlaszlo/trunk/WEB-INF/lps/server/src/org/openlaszlo/sc/SourceFileMap.java


Property changes on: openlaszlo/trunk/WEB-INF/lps/server/src/org/openlaszlo/sc/SourceFileMap.java
___________________________________________________________________
Name: svn:mime-type
   + text/plain
Name: svn:eol-style
   + native

Modified: openlaszlo/trunk/WEB-INF/lps/server/src/org/openlaszlo/sc/TranslationUnit.java
===================================================================
--- openlaszlo/trunk/WEB-INF/lps/server/src/org/openlaszlo/sc/TranslationUnit.java	2008-08-19 15:26:46 UTC (rev 10718)
+++ openlaszlo/trunk/WEB-INF/lps/server/src/org/openlaszlo/sc/TranslationUnit.java	2008-08-19 17:37:08 UTC (rev 10719)
@@ -35,6 +35,14 @@
   public static final String INSERT_STREAM_MARK = "#insertStream(";
   public static final String INSERT_END_MARK = ")";
 
+  public class SourceFileLine {
+    SourceFile sourcefile;
+    int line;
+    public String toString() {
+      return sourcefile.toString() + ": " + line;
+    }
+  }
+
   public String getName() {
     return name;
   }
@@ -129,12 +137,21 @@
     return cur;
   }
 
-  public void setInputLineNumber(int inputLinenum) {
+  public void setInputLineNumber(int inputLinenum, SourceFile srcf) {
     Integer key = new Integer(linenum);
-    // we want the least value in the mapping
-    Integer cur = (Integer)lnums.get(key);
-    if (cur == null || inputLinenum < cur.intValue())
-      lnums.put(key, new Integer(inputLinenum));
+    SourceFileLine cur = (SourceFileLine)lnums.get(key);
+    if (cur == null) {
+      cur = new SourceFileLine();
+      cur.sourcefile = srcf;
+      cur.line = inputLinenum;
+      lnums.put(key, cur);
+    }
+    // if the source file changed, we'll just use the first one.
+    // otherwise, we want the smallest input line in the mapping.
+    else if (cur.sourcefile.equals(srcf) && inputLinenum < cur.line) {
+      cur.line = inputLinenum;
+      lnums.put(key, cur);
+    }
   }
 
   public static int countOccurence(String s, char c) {
@@ -168,15 +185,15 @@
     }
   }
 
-  public int originalLineNumber(int num) {
+  public SourceFileLine originalLineNumber(int num) {
     num -= lineOffset;
     SortedMap nextLineNumber = lnums.tailMap(new Integer(num));
     if (nextLineNumber.size() == 0)
-      return -1;
+      return null;
     Object key = nextLineNumber.firstKey();
     if (key == null)
-      return -1;
-    return ((Integer)lnums.get(key)).intValue();
+      return null;
+    return (SourceFileLine)lnums.get(key);
   }
 }
 



More information about the Laszlo-checkins mailing list