Ticket #35: compDirArgOpts.patch
| File compDirArgOpts.patch, 50.3 kB (added by hopscc, 4 months ago) |
|---|
-
Source/Compiler.cobra
55 55 56 56 var _globalNS as NameSpace 57 57 var _modules as List<of Module> 58 var _parsedModules as List<of Module>? # accumulated as files parsed 58 59 var _firstFileName as String? 59 60 60 61 var _curModule as Module? # set during bindInt and bindImp … … 224 225 Related resources such as CobraLang.cs reside there. 225 226 """ 226 227 return Path.getDirectoryName(Assembly.getEntryAssembly.location) to ! # actually could be nil: if you stuck Cobra in the root dir, the .getDirectoryName docs say it will return nil 227 228 228 229 def compileFilesNamed(paths as IList<of String>) 229 230 .compileFilesNamed(paths) 230 231 … … 285 286 .options = options 286 287 bar = '----------------------------------------------------------------------------------------------------' 287 288 .parseFilesNamed(fileNames) 289 288 290 assert .modules.count 289 291 if verbose 290 292 .dumpModulesForTestify(resultsWriter, 'Modules after parsing') … … 318 320 .printMessages 319 321 print bar 320 322 323 def _addRuntimeRef(opts as Options) 324 if not opts.containsKey('reference') 325 opts['reference'] = List<of String>() 326 refs = opts['reference'] to List<of String> 327 libName = 'Cobra.Lang.dll' 328 if libName not in refs 329 if .verbosity, print 'Adding reference to [libName]' 330 refs.add(libName) 331 321 332 def parseFilesNamed(filenames as IList<of String>) as List<of Module> 322 333 """ 323 334 Returns the modules for the newly parsed files. … … 333 344 embedRunTime = .options.boolValue('embed-run-time') 334 345 335 346 if not embedRunTime 336 # then reference it 337 if not .options.containsKey('reference') 338 .options['reference'] = List<of String>() 339 refs = .options['reference'] to List<of String> 340 libName = 'Cobra.Lang.dll' 341 if libName not in refs 342 if .verbosity, print 'Adding reference to [libName]' 343 refs.add(libName) 347 _addRuntimeRef(.options) # then reference runtime dll 344 348 345 349 Node.setCompiler(this) 346 350 try 347 351 if _modules.count == 0 # attempt at caching modules during testify. incomplete. 348 352 .writeSharpInfoClass 349 353 .readSystemTypes 350 .readAssemblyTypes 354 .readAssemblyTypes(.options) 351 355 352 356 if true # _modules.count == 0 353 357 path = Path.combine(.cobraExeDir, 'CobraInfo.cs') … … 368 372 filenames.insert(3, path) 369 373 370 374 modules = List<of Module>() 375 _parsedModules = modules 371 376 for filename in filenames 372 377 if filename.endsWith('.cs') 373 378 if _verbosity … … 396 401 else 397 402 assert modules.count 398 403 _modules.addRange(modules) 404 _parsedModules = nil 399 405 return modules 400 406 407 def augmentOptions(opts as Options) 408 """ 409 Update Options and accumulator lists generated from it with additional options settings. 410 Used from inside parseFiles for args compilerDirective handling 411 """ 412 if .verbosity 413 print 'preAugment Options Dictionary' 414 .options.print 415 416 # special cases 417 _fixupLibRefs(opts) 418 _fixupEmbedRunTime(opts) # need this after fixup libs 419 420 .options.combineNew(opts) 421 v = .options.getDefault('verbosity', 0) to int 422 if v > _verbosity, _verbosity = v 423 if .verbosity 424 print 'postAugment Options Dictionary' 425 .options.print 426 427 428 def _fixupEmbedRunTime(opts as Options) 429 #print 'before', _parsedModules 430 if opts.boolValue('embed-run-time') <> .options.boolValue('embed-run-time') 431 if not opts.boolValue('embed-run-time') # changed True to false 432 # remove parsed rtSrc modules 433 rl = for m in _parsedModules where m.isCobraLibrary and not m.fileName.endsWith('.dll') 434 for m in rl 435 _parsedModules.remove(m) 436 _addRuntimeRef(opts) # add ref to runtime dll 437 else 438 opts['embed-run-time'] = .options['embed-run-time'] 439 #errchannel.throwError('Cannot switch -ert:no to -ert:yes in compilerDirective') 440 # To support this need to determine where/what recorded for Cobra.dll 441 # ref,clear it out and insert rtl src to be parsed AFTER finish current file 442 #print 'after fixup', _parsedModules 443 444 def _fixupLibRefs(opts as Options) 445 haveRefs = false 446 for key in ['library-directory', 'pkg', 'reference'] 447 if opts.containsKey(key) 448 if key == 'reference' 449 references = opts.getDefaultLOStr('reference') 450 _fixupLibSuffix(references) 451 if not .options.containsKey(key) 452 .options[key] = List<of String>() 453 existList = .options[key] to List<of String> 454 augList = opts[key] to List<of String> 455 dupCount = 0 456 for item in augList 457 if item not in existList 458 if .verbosity, print 'Adding [key] "[item]"' 459 existList.add(item) 460 else 461 if .verbosity, print '[key] "[item]" already in options.[key]' 462 dupCount += 1 # augList.remove(item) 463 if not haveRefs 464 haveRefs = key <> 'library-directory' and augList.count - dupCount >0 465 .options.didSpecify(key) # so not overwrite when combine 466 467 if haveRefs 468 .readAssemblyTypes(opts) 469 if .verbosity > 1 470 references = .options.getDefaultLOStr('reference') 471 _printRefs(references) 472 473 401 474 def runProcess as Process 402 475 """ 403 476 Returns a new Process with startInfo.fileName and p.startInfo.arguments set appropriately … … 587 660 t = System.Diagnostics.Process.getType 588 661 .readAssembly(t.assembly) # System.dll 589 662 590 def readAssemblyTypes 591 references = .options.getDefault('reference', List<of String>()) to List<of String> 592 593 # Excluding the extension can be problematic 663 def _fixupLibSuffix(references as List<of String>) 594 664 i = 0 595 665 for reference in List<of String>(references) 596 666 if not reference.endsWith('.dll') and not reference.endsWith('.exe') 597 667 reference += '.dll' 598 668 references[i] = reference 599 669 i += 1 670 671 def _printRefs(references as List<of String>) 672 if references.count == 0 673 print 'No additional assembly references.' 674 else 675 print 'Final assembly reference list:' 676 i = 0 677 for refPath in references 678 print '[i]. [refPath]' 679 i += 1 680 681 def readAssemblyTypes(options as Options) 682 references = options.getDefaultLOStr('reference') 600 683 684 # Excluding the extension can be problematic 685 _fixupLibSuffix(references) 686 601 687 # now that references are fixed, make a copy so that .options['references'] is not modified further 602 688 references = List<of String>(references) 603 689 604 if .options.containsKey('pkg')605 for pkgName in .options['pkg'] to List<of String>690 if options.containsKey('pkg') 691 for pkgName in options['pkg'] to List<of String> 606 692 references.addRange(.refsForPackage(pkgName)) 607 693 608 if .verbosity > 1 609 if references.count == 0 610 print 'No additional assembly references.' 611 else 612 print 'Final assembly reference list:' 613 i = 0 614 for refPath in references 615 print '[i]. [refPath]' 616 i += 1 694 if .verbosity > 1 695 _printRefs(references) 617 696 618 697 # Here be "reflectionOnlyLoad" code... which does not work on Mono 1.2.4 619 698 # The run-time error message says: … … 634 713 # $sharp('curDomain.ReflectionOnlyAssemblyResolve += _resolveEvent') 635 714 636 715 for reference in references 637 if .verbosity > 0 638 print 'Loading reference:', reference 639 if false 640 # Does not work on Novell Mono. See notes above. 641 referredAss = Assembly.reflectionOnlyLoadFrom(reference) 642 # TODO: handle all the exceptions from Assembly.loadFrom 716 _loadAssemblyForRef(reference) 717 718 def _loadAssemblyForRef(reference as String) 719 if .verbosity > 0 720 print 'Loading reference:', reference 721 if false 722 # Does not work on Novell Mono. See notes above. 723 referredAss = Assembly.reflectionOnlyLoadFrom(reference) 724 # TODO: handle all the exceptions from Assembly.loadFrom 725 else 726 if File.exists(reference) 727 # try current directory 728 referredAss = Assembly.loadFrom(reference) 643 729 else 644 if File.exists(reference) 645 # try current directory 646 referredAss = Assembly.loadFrom(reference) 647 else 648 # TODO: the problem with -lib: in both Cobra and C# is that it has no effect on runtime, 649 # you must still register the DLLs in the GAC or copy them into the same dir as the .exe 650 # because the -lib: paths are not passed into executable. 651 # So should Cobra copy the .dll's into the target directory (if their paths are not in MONO_PATH)? 652 searchPaths = .options.getDefault('library-directory', List<of String>()) to List<of String> 653 # TODO: ?: searchPaths.add(Path.getDirectoryName(Assembly.getExecutingAssembly.location)) # try Cobra's directory - also should be added to .options.'library-directory' not to a local var 654 found = false 655 for searchPath in searchPaths 656 combinedPath = Path.combine(searchPath, reference) 657 if File.exists(combinedPath) 658 referredAss = Assembly.loadFrom(combinedPath) 659 found = true 660 break 661 if not found 662 # try system wide (GAC) 663 if reference.endsWith('.dll') 664 reference = reference[:-4] 665 referredAss = Utils.loadWithPartialName(reference) 666 # TODO: handle all the exceptions from Assembly.loadFrom 667 if referredAss 668 .readAssembly(referredAss, reference <> 'Cobra.Lang.dll') 669 else 670 _addMessage(SourceException('Cannot locate assembly reference "[reference]".')) 671 i += 1 672 730 # TODO: the problem with -lib: in both Cobra and C# is that it has no effect on runtime, 731 # you must still register the DLLs in the GAC or copy them into the same dir as the .exe 732 # because the -lib: paths are not passed into executable. 733 # So should Cobra copy the .dll's into the target directory (if their paths are not in MONO_PATH)? 734 searchPaths = .options.getDefaultLOStr('library-directory') 735 # TODO: ?: searchPaths.add(Path.getDirectoryName(Assembly.getExecutingAssembly.location)) # try Cobra's directory - also should be added to .options.'library-directory' not to a local var 736 found = false 737 for searchPath in searchPaths 738 combinedPath = Path.combine(searchPath, reference) 739 if File.exists(combinedPath) 740 referredAss = Assembly.loadFrom(combinedPath) 741 found = true 742 break 743 if not found 744 # try system wide (GAC) 745 if reference.endsWith('.dll') 746 reference = reference[:-4] 747 referredAss = Utils.loadWithPartialName(reference) 748 # TODO: handle all the exceptions from Assembly.loadFrom 749 if referredAss 750 .readAssembly(referredAss, reference <> 'Cobra.Lang.dll') 751 else 752 _addMessage(SourceException('Cannot locate assembly reference "[reference]".')) 753 673 754 def refsForPackage(pkgName as String) as List<of String> 674 755 """ 675 756 Returns the library/DLL refs for the give package name. … … 1414 1495 if optimize 1415 1496 backEndOptions += ' [optChar]optimize+' 1416 1497 1417 thing = options.getDefault ('reference', List<of String>()) to List<of String>1498 thing = options.getDefaultLOStr('reference') 1418 1499 for refer in thing 1419 1500 backEndOptions += ' "[optChar]r:[refer]"' 1420 1501 … … 1448 1529 sharpArgs = sharpArgs[1:-1] 1449 1530 backEndOptions += ' ' + sharpArgs 1450 1531 1451 for libPath in .options.getDefault ('library-directory', [])1532 for libPath in .options.getDefaultLOStr('library-directory') 1452 1533 backEndOptions += ' ' + '-lib:"[libPath]"' 1453 1534 1454 for pkgName in .options.getDefault ('pkg', [])1535 for pkgName in .options.getDefaultLOStr('pkg') 1455 1536 backEndOptions += ' ' + '-pkg:[pkgName]' 1456 1537 1457 1538 # .cs files … … 1482 1563 cp.generateExecutable = options.getDefault('target', 'exe') in ['exe', 'winexe'] 1483 1564 cp.outputAssembly = _fullExeFileName 1484 1565 cp.compilerOptions = backEndOptions 1566 if _verbosity > 2 1567 print 'CodeProvider [backEndOptions] [cp.referencedAssemblies]' 1485 1568 #trace backEndOptions 1486 1569 #trace sharpFileNameList 1487 1570 cr = provider.compileAssemblyFromFile(cp, sharpFileNameList.toArray) -
Source/CommandLine.cobra
32 32 # not the current Source directory. And Snapshot can be a final release such as '0.7.4' for a 33 33 # period of time where this Cobra source represents an svn-post-RELEASE. 34 34 return '0.8.0 post-release' 35 36 var _optionSpecs as List<of Dictionary<of String, Object>> 37 35 38 36 var _rawOptionSpecs = [ 39 37 { 40 38 'name': 'about', … … 201 199 }, 202 200 { 203 201 'name': 'reference', 204 'synonyms': ['r'], 202 'synonyms': ['r'], # TODO: lose 'r' ->'Ref', 'R', something else 205 203 'isAccumulator': true, 206 204 'description': 'Add a DLL reference.', 207 205 'args': 'Some.dll', … … 220 218 # 'args': ':Qualified.Type.Name', 221 219 # }, 222 220 { 223 'name': 'run', 221 'name': 'run', # TODO: Synonym 'r' after change 'reference' switch 224 222 'description': 'Runs the Cobra program. This is the default behavior if specify any Cobra source files.', 225 223 'type': 'main', 226 224 }, … … 281 279 'type': 'main', 282 280 }, 283 281 ] 282 284 283 285 284 var _startTime as DateTime 286 285 var _verbosity = 0 … … 290 289 var _htmlWriter as HtmlWriter? 291 290 292 291 var _compiler as Compiler? 293 292 var _argParser as ArgParser 293 294 294 def init 295 295 _startTime = DateTime.now 296 # prep the option specs 297 _optionSpecs = List<of Dictionary<of String, Object>>() 298 for specObj in _rawOptionSpecs 299 # since some _optionSpecs are Dictionary<of String, Object> and others are 300 # Dictionary<of String, String> then _optionSpecs ends up being 301 # Dictionary<of String, Object> 296 _argParser = ArgParser(.versionString, _rawOptionSpecs) 302 297 303 if specObj inherits Dictionary<of String, Object>304 d = specObj305 else if specObj inherits Dictionary<of String, String>306 d = Dictionary<of String, Object>()307 for key in specObj.keys308 d[key] = specObj[key]309 else310 throw FallThroughException(specObj.getType)311 _optionSpecs.add(d)312 313 298 get compiler from var 314 299 315 300 get options from var … … 324 309 get verbosity as int 325 310 return _verbosity 326 311 312 def parseArgs(args as IList<of String>, options as out Options?, paths as out List<of String>?) 313 _argParser.parseArgs(args, out options, out paths) 314 _verbosity = _argParser.verbosity 315 CobraMain.willTimeIt = _argParser.willTimeIt 316 327 317 def run 328 318 """ 329 319 Run the command line using the command line arguments. … … 339 329 .doAbout 340 330 return 341 331 .parseArgs(args, out _options, out _pathList) 332 342 333 if _options.boolValue('output-html') 343 334 _htmlWriter = HtmlWriter(Console.out) 344 335 dest = _htmlWriter to TextWriter … … 389 380 if _htmlWriter 390 381 _htmlWriter.writeHtml('</body></html>[_htmlWriter.newLine]') 391 382 392 def isOptionSpecRestrictionViolated(optionSpec as Dictionary<of String, Object>) as bool393 """394 Returns true if the option spec has a 'restriction' key and the check against that restriction is true.395 """396 if optionSpec.containsKey('restriction')397 branch optionSpec['restriction'] to String398 on 'mono-only'399 return not CobraCore.isRunningOnMono400 return false401 402 def parseArgs(args as IList<of String>, options as out Options?, paths as out List<of String>?)403 """404 Parse command line arguments.405 The `args` should include only the arguments and not the executable/program name.406 """407 ensure408 options409 paths410 body411 optionPrefix = '-'412 valuePrefix = c':'413 if not args.count414 options = Options()415 options.add('help', true)416 paths = List<of String>()417 return418 419 specDict = Dictionary<of String, Dictionary<of String, Object>>()420 # ^ will contain keys for all spec names and their synonyms421 synToName = Dictionary<of String, String>()422 # ^ maps synonyms to their full names423 synList = List<of String>()424 for d in _optionSpecs425 if .isOptionSpecRestrictionViolated(d)426 continue427 specDict[d['name'] to String] = d428 if d.containsKey('synonyms')429 syns = d['synonyms'] to System.Collections.IList430 for syn as String in syns431 assert not specDict.containsKey(syn)432 specDict[syn] = d433 synToName[syn] = d['name'] to String434 synList.add(syn)435 if not d.containsKey('type')436 d.add('type', 'string')437 438 # set up initial valueDict439 valueDict = Dictionary<of String, Object>()440 if Utils.isDevMachine441 valueDict['reveal-internal-exceptions'] = true # this is a specially computed default, but can still be overridden on the command line442 443 fileList = List<of String>()444 value = 'no-value' to dynamic445 mainOptions = List<of String>()446 didSpecify = Dictionary<of String, bool>() # CC: could just be a Set447 for arg in args448 if arg.trim.length == 0449 continue450 if arg.startsWith(optionPrefix)451 isOption = true452 while arg.startsWith(optionPrefix)453 arg = arg[1:]454 else455 isOption = false456 if isOption457 parts = arg.split(@[valuePrefix], 2)458 if parts.length == 1459 name = parts[0]460 if name.endsWith('+')461 name = name[:-1]462 valueStr = 'on'463 else if name.endsWith('-')464 name = name[:-1]465 valueStr = 'off'466 else467 valueStr = 'on'468 else469 assert parts.length == 2470 name = parts[0]471 valueStr = parts[1]472 assert name.length, parts473 name = Utils.getSS(synToName to passthrough, name, name) to !474 if not specDict.containsKey(name)475 msg = 'No such option "[name]".'476 if name.contains('=')477 msg += ' If you meant to specify an option value, use colon (:) instead of equals (=).'478 .error(msg)479 spec = specDict[name]480 if Utils.getSB(spec to passthrough, 'isAccumulator', false)481 # accumulators are always treated as strings. TODO: assert that482 if valueDict.containsKey(name)483 (valueDict[name] to System.Collections.IList).add(valueStr to passthrough)484 else485 valueDict[name] = [valueStr]486 didSpecify[name] = true487 else488 cannotProcess = false489 if name=='debug'490 # special case491 if valueStr=='pdbonly' or valueStr=='full'492 value = valueStr493 else494 try495 value = .boolForString(valueStr)496 catch FormatException497 cannotProcess = true498
