use System.Text.RegularExpressions class SharpCompilationMessage inherits SourceException test line = r"c:\Documents and Settings\Chuck\My Documents\Projects\Cobra\Workspace-New\Tests\tests\720-libraries\200-tao.cobra(11,4): error CS0246: The type or namespace name 'SDL_Event' could not be found (are you missing a using directive or an assembly reference?)" msg = SharpCompilationMessage(line, TestCompiler()) assert 'error ' in line assert msg.isError assert msg.hasSourceSite assert 'tao.cobra' in msg.fileName and 'Documents' in msg.fileName assert msg.lineNum == 11 line = "foo.cobra.cs(14,14): error CS0535: `Foo' does not implement interface member `IFoo.Baz()'" msg = SharpCompilationMessage(line, TestCompiler()) assert msg.isError assert msg.hasSourceSite assert msg.fileName == 'foo.cobra' assert msg.lineNum == 14 line = "error CS5001: Program `bugs/bugs-no-main.exe' does not contain a static `Main' method suitable for an entry point" msg = SharpCompilationMessage(line, TestCompiler()) assert msg.isError assert not msg.hasSourceSite line = "foo.cobra(15,3): warning CS1111: Blah blah" msg = SharpCompilationMessage(line, TestCompiler()) assert not msg.isError assert msg.hasSourceSite assert msg.fileName == 'foo.cobra' assert msg.lineNum == 15 assert msg.message == 'Blah blah' or msg.message == 'Blah blah (C#)' def willSkipMessage(msg as String) as bool is shared # TODO: Does mono give localized messages? Like in French. if '.dll' in msg # comes up on Novell Mono: '/Library/Frameworks/Mono.framework/Versions/1.2.4/lib/mono/2.0/mscorlib.dll (Location of the symbol related to previous error)' # TODO: try removing these if msg.endsWith(' (Location of the symbol related to previous error)') return true if msg.endsWith(' (Location of the symbol related to previous warning)') return true if msg.startsWith('Compilation succeeded') # Novell Mono gmcs ends with this. Cobra handles this itself. return true if msg.startsWith('Compilation failed') # Novell Mono gmcs ends with this. Cobra handles this itself. return true return false var _fileName as String? var _lineNum as int? var _isError as bool cue init(message as System.CodeDom.Compiler.CompilerError, compiler as Compiler) base.init('') _isError = not message.isWarning _fileName = message.fileName _lineNum = message.line text = message.errorText ? '' if compiler.verbosity or Utils.isDevMachine text += ' (C#)' # ' (C# [sharpLineNum])' ... the sharpLineNum is not useful now that #line is being generated _message = _cleanUp(text) cue init(line as String, compiler as Compiler) require not .willSkipMessage(line) # CC: # require compiler responds to (get verbosity as int) # require compiler responds to (def cobraLineNumForSharp(fileName as String, lineNum as int) as int) base.init(line) # example lines: # foo.cobra.cs(14,14): error CS0535: `Foo' does not implement interface member `IFoo.Baz()' # error CS5001: Program `bugs/bugs-no-main.exe' does not contain a static `Main' method suitable for an entry point # foo(30,30): # trace line line = line.trim _isError = 'error ' in line if line.startsWith('error CS') i = line.indexOf(': ') line = line[i+2:] else i = line.indexOf('(') if i <> -1 fileName = line[:i] if fileName.endsWith('.cs') and fileName.endsWith('.cobra.cs') # doesn't really happen since #line is generated at the top to set the filename to "Foo.cobra" fileName = fileName[:i-3] willFixLineNum = true else willFixLineNum = false j1 = line.indexOf(',', i) j2 = line.indexOf(')', i) j = if(j1 < j2, j1, j2) lineStr = line[i+1:j] try _lineNum = int.parse(lineStr) catch if compiler.verbosity or Utils.isDevMachine line += ' (C#)' success _fileName = fileName if willFixLineNum _lineNum = compiler.cobraLineNumForCurly(fileName, _lineNum to !) i = line.indexOf(':', i) if i <> -1 line = line[i+1:].trim _isError = line.startsWith('error') i = line.indexOf(':') if i <> -1 and i < line.length and i+1 < line.length and line[i+1] == ' ' line = line[i+1:].trim # add (sharp) if compiler.verbosity or Utils.isDevMachine line += ' (C#)' # ' (C# [sharpLineNum])' ... the sharpLineNum is not useful now that #line is being generated _message = _cleanUp(line) var _backTickRegEx = Regex(r"`(?\w+)'", RegexOptions(Compiled, CultureInvariant)) def _cleanUp(line as String) as String line = _backTickRegEx.replace(line, "'${word}'") for a, b in [['float', 'float32'], ['double', 'float']] line = line.replace("'[a]'", "'[b]'") line = line.replace("([a]", "([b]") line = line.replace(", [a]", ", [b]") line = line.replace('"[a]"', '"[b]"') line = line.replace("null", "nil") line = line.replace("non-static", "non-shared") line = line.replace("'ref'", "'inout'") line = line.replace("a constructor", "an initializer") line = line.replace(" constructor", " initializer") # change C#'s `funky' quotes to double quotes line = line.replace("`", '"') line = line.replace("'", '"') return line get isError as bool is override return _isError get hasSourceSite as bool is override return _fileName is not nil get fileName as String is override return _fileName to ! get lineNum as int is override return _lineNum to !