Esempio n. 1
0
    SourceChangeList ConstructSourceChangeList()
    {
        SourceChangeList result = new SourceChangeList();
        int lastPos             = 0;

        do
        {
            int    beforeLine = this.lineCounter;
            string beforeText = this.ReadString();
            if (this.inputLine != "after")
            {
                throw new MalformedSuiteException("Line " + this.lineCounter + ": Expected an 'after' line");
            }
            string       afterText = this.ReadString();
            SourceChange sc        = new SourceChange();
            sc.ChangedText   = afterText;
            sc.SourceContext = this.compilationUnit.SourceContext;
            int beforePos = this.currentDocument.Text.Source.IndexOf(beforeText, lastPos);
            if (beforePos < 0)
            {
                throw new MalformedSuiteException("Line " + beforeLine + ": before text not found");
            }
            sc.SourceContext.StartPos = beforePos;
            sc.SourceContext.EndPos   = lastPos = beforePos + beforeText.Length;
            result.Add(sc);
        }while (this.inputLine == "before");
        return(result);
    }
Esempio n. 2
0
    void PerformIncrementalUpdate()
    {
        SourceChangeList changes        = this.ConstructSourceChangeList();
        string           expectedOutput = this.GetExpectedOutput();
        //perform update
        Document originalDocument = this.compilationUnit.SourceContext.Document;
        Document changedDocument  = this.currentDocument = this.GetChangedDocument(this.currentDocument, changes);

        lock (this){ //prevent asynchronous symbol table update event handler from producing output until after CheckUpdatedCompilation has run
            Compilation updatedCompilation = this.compiler.UpdateSymbolTable(this.compilation, originalDocument, changedDocument, changes, this.errors);
            this.CheckUpdatedCompilation(this.compilation, updatedCompilation);
            this.compilation = updatedCompilation;
        }
        //Give asynchronous symbol table update events time to complete
        Thread.Sleep(20);
        //Get actual output and compare with expected output
        string actualOutput = this.output.ToString();

        if (expectedOutput != actualOutput)
        {
            Console.SetOut(this.savedConsoleOut);
            Console.WriteLine("Test {0} line {1} failed", this.testName, this.lineCounter - 1);
            Console.WriteLine("Actual output:");
            Console.Write(actualOutput);
            Console.WriteLine("Expected output:");
            Console.Write(expectedOutput);
            this.failures++;
        }
        Console.SetOut(new StringWriter(this.output = new StringBuilder()));
        System.Diagnostics.Debug.Listeners.Remove(this.traceListener);
        this.traceListener = new System.Diagnostics.TextWriterTraceListener(System.Console.Out);
        System.Diagnostics.Debug.Listeners.Add(this.traceListener);
    }
Esempio n. 3
0
    Document GetChangedDocument(Document originalDocument, SourceChangeList changes)
    {
        string        originalString = originalDocument.Text.Source;
        StringBuilder sb             = new StringBuilder();
        int           lastPos        = 0;

        for (int i = 0, n = changes.Count; i < n; i++)
        {
            SourceChange sc = changes[i];
            sb.Append(originalString, lastPos, sc.SourceContext.StartPos - lastPos);
            sb.Append(sc.ChangedText);
            lastPos = sc.SourceContext.EndPos;
        }
        sb.Append(originalString, lastPos, originalString.Length - lastPos);
        return(this.compiler.CreateDocument(this.compilationUnit.SourceContext.Document.Name, 1, sb.ToString()));
    }
Esempio n. 4
0
 Document GetChangedDocument(Document originalDocument, SourceChangeList changes){
   string originalString = originalDocument.Text.Source;
   StringBuilder sb = new StringBuilder();
   int lastPos = 0;
   for (int i = 0, n = changes.Count; i < n; i++){
     SourceChange sc = changes[i];
     sb.Append(originalString, lastPos, sc.SourceContext.StartPos-lastPos);
     sb.Append(sc.ChangedText);
     lastPos = sc.SourceContext.EndPos;
   }
   sb.Append(originalString, lastPos, originalString.Length-lastPos);
   return this.compiler.CreateDocument(this.compilationUnit.SourceContext.Document.Name, 1, sb.ToString());
 }
Esempio n. 5
0
 SourceChangeList ConstructSourceChangeList(){
   SourceChangeList result = new SourceChangeList();
   int lastPos = 0;
   do{
     int beforeLine = this.lineCounter;
     string beforeText = this.ReadString();
     if (this.inputLine != "after") 
       throw new MalformedSuiteException("Line "+this.lineCounter+": Expected an 'after' line");
     string afterText = this.ReadString();
     SourceChange sc = new SourceChange();
     sc.ChangedText = afterText;
     sc.SourceContext = this.compilationUnit.SourceContext;
     int beforePos = this.currentDocument.Text.Source.IndexOf(beforeText, lastPos);
     if (beforePos < 0) 
       throw new MalformedSuiteException("Line "+beforeLine+": before text not found");
     sc.SourceContext.StartPos = beforePos;
     sc.SourceContext.EndPos = lastPos = beforePos + beforeText.Length;
     result.Add(sc);
   }while (this.inputLine == "before");
   return result;
 }
 /// <summary>
 /// Updates the specified symbol table, substituting changedDocument for originalDocument.
 /// Fires the OnSymbolTableUpdate event before returning (provided that changes occurred to member signatures).
 /// </summary>
 /// <param name="symbolTable">The symbol table to update or replace.</param>
 /// <param name="originalDocument">The document of a CompilationUnit instance in compilation.</param>
 /// <param name="changedDocument">A new version of originalDocument.</param>
 /// <param name="changes">A list of the changes made to orignalDocument in order to derive changedDocument.</param>
 /// <param name="errors">A list to which errors detected during the update must be added.</param>
 /// <returns>The given symbol table instance, suitably updated, or a new symbol table that replaces the given table.</returns>
 public virtual Compilation UpdateSymbolTable(Compilation symbolTable, Document originalDocument, Document changedDocument, SourceChangeList changes,
   ErrorNodeList errors){
   if (symbolTable == null || symbolTable.TargetModule == null || originalDocument == null || changedDocument == null || changes == null){
     Debug.Assert(false); return null;
   }
   int changeInLength;
   SourceContext spanningContextForChanges = this.GetSpanningContext(changes, out changeInLength);
   CompilationUnitSnippet compilationUnit = null;      
   for (int i = 0, n = symbolTable.CompilationUnits == null ? 0 : symbolTable.CompilationUnits.Count; i < n; i++){
     CompilationUnitSnippet cu = symbolTable.CompilationUnits[i] as CompilationUnitSnippet;
     if (cu != null && cu.SourceContext.Document == originalDocument){
       compilationUnit = cu;
       break;
     }
   }
   if (compilationUnit == null){Debug.Assert(false); return null;}
   Method meth = compilationUnit.ChangedMethod;
   if (meth != null){
     if (meth.Body != null && meth.Body.SourceContext.Encloses(spanningContextForChanges)){
       SourceContext newCtx = this.GetMethodBodyContextInNewDocument(changedDocument, meth.Body.SourceContext, 
         spanningContextForChanges, changeInLength);
       //Now update the original document so that all nodes that follow method in the source will report their source lines relative to the changedDocument
       int oldNumLines = meth.Body.SourceContext.EndLine - meth.Body.SourceContext.StartLine;
       int newNumLines = newCtx.EndLine - newCtx.StartLine;
       compilationUnit.SourceContext.Document.InsertOrDeleteLines(compilationUnit.OriginalEndPosOfChangedMethod, newNumLines-oldNumLines);
       //Replace the method body context with the new context
       meth.Body.SourceContext = newCtx;
       //Get rid of the body statements (if present) that was constructed from the old context
       meth.Body.Statements = null;
       return symbolTable;
     }
     return this.FullSymbolTableUpdate(symbolTable, originalDocument, changedDocument, errors);
   }
   MemberFinder memFinder = this.CreateMemberFinder(spanningContextForChanges);
   memFinder.Visit(compilationUnit);
   meth = memFinder.Member as Method;
   if (meth != null && meth.Body != null && meth.Body.SourceContext.Encloses(spanningContextForChanges))
     return this.IncrementalSymbolTableUpdate(symbolTable, compilationUnit, changedDocument, meth, spanningContextForChanges, changeInLength);
   else
     return this.FullSymbolTableUpdate(symbolTable, originalDocument, changedDocument, errors);
 }
 public virtual SourceContext GetSpanningContext(SourceChangeList changes, out int changedLength){
   changedLength = 0;
   int startPos = int.MaxValue;
   int endPos = int.MinValue;
   SourceContext result = new SourceContext();
   if (changes == null || changes.Count == 0) return result;
   result = changes[0].SourceContext;
   for (int i = 0, n = changes.Count; i < n; i++){
     SourceContext ctx = changes[i].SourceContext;
     if (ctx.StartPos < startPos) startPos = ctx.StartPos;
     if (ctx.EndPos > endPos) endPos = ctx.EndPos;          
     int originalLength = ctx.EndPos - ctx.StartPos;
     int newLength = changes[i].ChangedText == null ? 0 : changes[i].ChangedText.Length;
     changedLength += newLength - originalLength;
   }
   result.StartPos = startPos;
   result.EndPos = endPos;
   return result;
 }