Fix server.go

server.go processed Typesript output incorrectly when multiple
lines are concatenated together.

Change-Id: Id2af52df8edf702214aeeab1bae0242d3077c616
This commit is contained in:
Dmitrii Filippov
2020-10-05 16:30:32 +02:00
parent fa5a425991
commit 5a2334ed69

View File

@@ -527,38 +527,56 @@ var (
) )
type typescriptLogWriter struct { type typescriptLogWriter struct {
logger *log.Logger unfinishedLine string
logger *log.Logger
// when WaitGroup counter is 0 the compilation is complete // when WaitGroup counter is 0 the compilation is complete
compilationDoneWaiter *sync.WaitGroup compilationDoneWaiter *sync.WaitGroup
} }
func newTypescriptLogWriter(compilationCompleteWaiter *sync.WaitGroup) *typescriptLogWriter { func newTypescriptLogWriter(compilationCompleteWaiter *sync.WaitGroup) *typescriptLogWriter {
return &typescriptLogWriter{ return &typescriptLogWriter{
unfinishedLine: "",
logger: log.New(log.Writer(), "TSC - ", log.Flags()), logger: log.New(log.Writer(), "TSC - ", log.Flags()),
compilationDoneWaiter: compilationCompleteWaiter, compilationDoneWaiter: compilationCompleteWaiter,
} }
} }
func (lw typescriptLogWriter) Write(p []byte) (n int, err error) { func (lw typescriptLogWriter) Write(p []byte) (n int, err error) {
text := strings.TrimSpace(string(p)) // The input p can contain several lines and/or the partial line
if strings.HasSuffix(text, tsFileChangeDetectedMsg) || // Code splits the input by EOL marker (\n) and stores the unfinished line
strings.HasSuffix(text, tsStartingCompilation) { // for the next call to Write.
lw.compilationDoneWaiter.Add(1) partialText := lw.unfinishedLine + string(p)
lines := strings.Split(partialText, "\n")
fullLines := lines
if strings.HasSuffix(partialText, "\n") {
lw.unfinishedLine = ""
} else {
fullLines = lines[:len(lines)-1]
lw.unfinishedLine = lines[len(lines)-1]
} }
if tsStartWatchingMsg.MatchString(text) { for _, fullLine := range fullLines {
// A source code can be changed while previous compiler run is in progress. text := strings.TrimSpace(fullLine)
// In this case typescript reruns compilation again almost immediately if text == "" {
// after the previous run finishes. To detect this situation, we are continue
// waiting waitForNextChangeInterval before decreasing the counter. }
// If another compiler run is started in this interval, we will wait if strings.HasSuffix(text, tsFileChangeDetectedMsg) ||
// again until it finishes. strings.HasSuffix(text, tsStartingCompilation) {
go func() { lw.compilationDoneWaiter.Add(1)
time.Sleep(waitForNextChangeInterval) }
lw.compilationDoneWaiter.Add(-1) if tsStartWatchingMsg.MatchString(text) {
}() // A source code can be changed while previous compiler run is in progress.
// In this case typescript reruns compilation again almost immediately
// after the previous run finishes. To detect this situation, we are
// waiting waitForNextChangeInterval before decreasing the counter.
// If another compiler run is started in this interval, we will wait
// again until it finishes.
go func() {
time.Sleep(waitForNextChangeInterval)
lw.compilationDoneWaiter.Add(-1)
}()
}
lw.logger.Print(text)
} }
lw.logger.Print(text)
return len(p), nil return len(p), nil
} }