Ticket #35: compDirArgOpts.patch

File compDirArgOpts.patch, 50.3 kB (added by hopscc, 4 months ago)
  • Source/Compiler.cobra

     
    5555 
    5656        var _globalNS as NameSpace 
    5757        var _modules as List<of Module> 
     58        var _parsedModules as List<of Module>? # accumulated as files parsed 
    5859        var _firstFileName as String? 
    5960 
    6061        var _curModule as Module?  # set during bindInt and bindImp 
     
    224225                Related resources such as CobraLang.cs reside there. 
    225226                """ 
    226227                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                 
    228229        def compileFilesNamed(paths as IList<of String>) 
    229230                .compileFilesNamed(paths) 
    230231 
     
    285286                .options = options 
    286287                bar = '----------------------------------------------------------------------------------------------------' 
    287288                .parseFilesNamed(fileNames) 
     289 
    288290                assert .modules.count 
    289291                if verbose 
    290292                        .dumpModulesForTestify(resultsWriter, 'Modules after parsing') 
     
    318320                .printMessages 
    319321                print bar 
    320322 
     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 
    321332        def parseFilesNamed(filenames as IList<of String>) as List<of Module> 
    322333                """ 
    323334                Returns the modules for the newly parsed files. 
     
    333344                        embedRunTime = .options.boolValue('embed-run-time') 
    334345 
    335346                        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 
    344348 
    345349                        Node.setCompiler(this) 
    346350                        try 
    347351                                if _modules.count == 0  # attempt at caching modules during testify. incomplete. 
    348352                                        .writeSharpInfoClass 
    349353                                        .readSystemTypes 
    350                                         .readAssemblyTypes 
     354                                        .readAssemblyTypes(.options) 
    351355 
    352356                                if true # _modules.count == 0 
    353357                                        path = Path.combine(.cobraExeDir, 'CobraInfo.cs') 
     
    368372                                                filenames.insert(3, path) 
    369373 
    370374                                modules = List<of Module>() 
     375                                _parsedModules = modules 
    371376                                for filename in filenames 
    372377                                        if filename.endsWith('.cs') 
    373378                                                if _verbosity 
     
    396401                        else 
    397402                                assert modules.count 
    398403                                _modules.addRange(modules) 
     404                                _parsedModules = nil 
    399405                        return modules 
    400406 
     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                         
    401474        def runProcess as Process 
    402475                """ 
    403476                Returns a new Process with startInfo.fileName and p.startInfo.arguments set appropriately 
     
    587660                t = System.Diagnostics.Process.getType 
    588661                .readAssembly(t.assembly) # System.dll 
    589662 
    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>) 
    594664                i = 0 
    595665                for reference in List<of String>(references) 
    596666                        if not reference.endsWith('.dll') and not reference.endsWith('.exe') 
    597667                                reference += '.dll' 
    598668                                references[i] = reference 
    599669                        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') 
    600683 
     684                # Excluding the extension can be problematic 
     685                _fixupLibSuffix(references) 
     686 
    601687                # now that references are fixed, make a copy so that .options['references'] is not modified further 
    602688                references = List<of String>(references) 
    603689 
    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> 
    606692                                references.addRange(.refsForPackage(pkgName)) 
    607693 
    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) 
    617696 
    618697                # Here be "reflectionOnlyLoad" code... which does not work on Mono 1.2.4 
    619698                # The run-time error message says: 
     
    634713                # $sharp('curDomain.ReflectionOnlyAssemblyResolve += _resolveEvent') 
    635714 
    636715                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) 
    643729                        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                                 
    673754        def refsForPackage(pkgName as String) as List<of String> 
    674755                """ 
    675756                Returns the library/DLL refs for the give package name. 
     
    14141495                        if optimize 
    14151496                                backEndOptions += ' [optChar]optimize+' 
    14161497 
    1417                         thing = options.getDefault('reference', List<of String>()) to List<of String> 
     1498                        thing = options.getDefaultLOStr('reference') 
    14181499                        for refer in thing 
    14191500                                backEndOptions += ' "[optChar]r:[refer]"' 
    14201501 
     
    14481529                                        sharpArgs = sharpArgs[1:-1] 
    14491530                                backEndOptions += ' ' + sharpArgs 
    14501531 
    1451                         for libPath in .options.getDefault('library-directory', []) 
     1532                        for libPath in .options.getDefaultLOStr('library-directory') 
    14521533                                backEndOptions += ' ' + '-lib:"[libPath]"' 
    14531534 
    1454                         for pkgName in .options.getDefault('pkg', []) 
     1535                        for pkgName in .options.getDefaultLOStr('pkg') 
    14551536                                backEndOptions += ' ' + '-pkg:[pkgName]' 
    14561537 
    14571538                        # .cs files 
     
    14821563                                cp.generateExecutable = options.getDefault('target', 'exe') in ['exe', 'winexe'] 
    14831564                                cp.outputAssembly = _fullExeFileName 
    14841565                                cp.compilerOptions = backEndOptions 
     1566                                if _verbosity > 2 
     1567                                        print 'CodeProvider [backEndOptions] [cp.referencedAssemblies]' 
    14851568                                #trace backEndOptions 
    14861569                                #trace sharpFileNameList 
    14871570                                cr = provider.compileAssemblyFromFile(cp, sharpFileNameList.toArray) 
  • Source/CommandLine.cobra

     
    3232                # not the current Source directory. And Snapshot can be a final release such as '0.7.4' for a 
    3333                # period of time where this Cobra source represents an svn-post-RELEASE. 
    3434                return '0.8.0 post-release' 
    35  
    36         var _optionSpecs as List<of Dictionary<of String, Object>> 
    37  
     35                 
    3836        var _rawOptionSpecs = [ 
    3937                { 
    4038                        'name': 'about', 
     
    201199                }, 
    202200                { 
    203201                        'name': 'reference', 
    204                         'synonyms': ['r'], 
     202                        'synonyms': ['r'], # TODO: lose 'r' ->'Ref', 'R', something else 
    205203                        'isAccumulator': true, 
    206204                        'description': 'Add a DLL reference.', 
    207205                        'args': 'Some.dll', 
     
    220218#                       'args': ':Qualified.Type.Name', 
    221219#               }, 
    222220                { 
    223                         'name': 'run', 
     221                        'name': 'run',  # TODO: Synonym 'r' after change 'reference' switch 
    224222                        'description': 'Runs the Cobra program. This is the default behavior if specify any Cobra source files.', 
    225223                        'type': 'main', 
    226224                }, 
     
    281279                        'type': 'main', 
    282280                }, 
    283281        ] 
     282                 
    284283 
    285284        var _startTime as DateTime 
    286285        var _verbosity = 0 
     
    290289        var _htmlWriter as HtmlWriter? 
    291290 
    292291        var _compiler as Compiler? 
    293  
     292        var _argParser as ArgParser 
     293         
    294294        def init 
    295295                _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) 
    302297 
    303                         if specObj inherits Dictionary<of String, Object> 
    304                                 d = specObj 
    305                         else if specObj inherits Dictionary<of String, String> 
    306                                 d = Dictionary<of String, Object>() 
    307                                 for key in specObj.keys 
    308                                         d[key] = specObj[key] 
    309                         else 
    310                                 throw FallThroughException(specObj.getType) 
    311                         _optionSpecs.add(d) 
    312  
    313298        get compiler from var 
    314299 
    315300        get options from var 
     
    324309        get verbosity as int 
    325310                return _verbosity 
    326311 
     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                 
    327317        def run 
    328318                """ 
    329319                Run the command line using the command line arguments. 
     
    339329                        .doAbout 
    340330                        return 
    341331                .parseArgs(args, out _options, out _pathList) 
     332         
    342333                if _options.boolValue('output-html') 
    343334                        _htmlWriter = HtmlWriter(Console.out) 
    344335                        dest = _htmlWriter to TextWriter 
     
    389380                if _htmlWriter 
    390381                        _htmlWriter.writeHtml('</body></html>[_htmlWriter.newLine]') 
    391382 
    392         def isOptionSpecRestrictionViolated(optionSpec as Dictionary<of String, Object>) as bool 
    393                 """ 
    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 String 
    398                                 on 'mono-only' 
    399                                         return not CobraCore.isRunningOnMono 
    400                 return false 
    401  
    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                 ensure 
    408                         options 
    409                         paths 
    410                 body 
    411                         optionPrefix = '-' 
    412                         valuePrefix = c':' 
    413                         if not args.count 
    414                                 options = Options() 
    415                                 options.add('help', true) 
    416                                 paths = List<of String>() 
    417                                 return 
    418  
    419                         specDict = Dictionary<of String, Dictionary<of String, Object>>() 
    420                                 # ^ will contain keys for all spec names and their synonyms 
    421                         synToName = Dictionary<of String, String>() 
    422                                 # ^ maps synonyms to their full names 
    423                         synList = List<of String>() 
    424                         for d in _optionSpecs 
    425                                 if .isOptionSpecRestrictionViolated(d) 
    426                                         continue 
    427                                 specDict[d['name'] to String] = d 
    428                                 if d.containsKey('synonyms') 
    429                                         syns = d['synonyms'] to System.Collections.IList 
    430                                         for syn as String in syns 
    431                                                 assert not specDict.containsKey(syn) 
    432                                                 specDict[syn] = d 
    433                                                 synToName[syn] = d['name'] to String 
    434                                                 synList.add(syn) 
    435                                 if not d.containsKey('type') 
    436                                         d.add('type', 'string') 
    437  
    438                         # set up initial valueDict 
    439                         valueDict = Dictionary<of String, Object>() 
    440                         if Utils.isDevMachine 
    441                                 valueDict['reveal-internal-exceptions'] = true  # this is a specially computed default, but can still be overridden on the command line 
    442  
    443                         fileList = List<of String>() 
    444                         value = 'no-value' to dynamic 
    445                         mainOptions = List<of String>() 
    446                         didSpecify = Dictionary<of String, bool>()  # CC: could just be a Set 
    447                         for arg in args 
    448                                 if arg.trim.length == 0 
    449                                         continue 
    450                                 if arg.startsWith(optionPrefix) 
    451                                         isOption = true 
    452                                         while arg.startsWith(optionPrefix) 
    453                                                 arg = arg[1:] 
    454                                 else 
    455                                         isOption = false 
    456                                 if isOption 
    457                                         parts = arg.split(@[valuePrefix], 2) 
    458                                         if parts.length == 1 
    459                                                 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                                                 else 
    467                                                         valueStr = 'on' 
    468                                         else 
    469                                                 assert parts.length == 2 
    470                                                 name = parts[0] 
    471                                                 valueStr = parts[1] 
    472                                         assert name.length, parts 
    473                                         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 that 
    482                                                 if valueDict.containsKey(name) 
    483                                                         (valueDict[name] to System.Collections.IList).add(valueStr to passthrough) 
    484                                                 else 
    485                                                         valueDict[name] = [valueStr] 
    486                                                         didSpecify[name] = true 
    487                                         else 
    488                                                 cannotProcess = false 
    489                                                 if name=='debug' 
    490                                                         # special case 
    491                                                         if valueStr=='pdbonly' or valueStr=='full' 
    492                                                                 value = valueStr 
    493                                                         else 
    494                                                                 try 
    495                                                                         value = .boolForString(valueStr) 
    496                                                                 catch FormatException 
    497                                                                         cannotProcess = true 
    498