Ticket #35: compilerDirectiveTgtDll.patch

File compilerDirectiveTgtDll.patch, 14.2 kB (added by hopscc, 5 months ago)
  • Source/Compiler.cobra

     
    8080        var _fullExeFileName as String = '' 
    8181 
    8282        var _clrTypeCache as Dictionary<of String, System.Type> 
     83        var _canRun as bool     # false if lib or module built 
    8384 
    8485 
    8586        # caches 
     
    106107                _messagesPerSourceLine = Dictionary<of String, List<of SourceException>>() 
    107108                _errors = List<of SourceException>() 
    108109                _warnings = List<of SourceException>() 
     110                _canRun = true 
    109111                _intermediateFileNames = List<of String>() 
    110112                _clrTypeCache = Dictionary<of String, System.Type>() 
    111113                if initialModules 
     
    181183        get warnings from var 
    182184 
    183185        get messages from var 
    184  
     186         
     187        get canRun from var 
     188         
    185189        pro htmlWriter from var 
    186190                """ 
    187191                Set this to support the output-html command line option. 
     
    576580 
    577581                t = System.Diagnostics.Process.getType 
    578582                .readAssembly(t.assembly) # System.dll 
    579  
     583                 
     584        def _appendLibSuffix(libName as String) as String 
     585                if not libName.endsWith('.dll') and not libName.endsWith('.exe') 
     586                        libName += '.dll' 
     587                return libName 
     588                 
    580589        def readAssemblyTypes 
    581590                references = .options.getDefault('reference', List<of String>()) to List<of String> 
    582591 
    583592                # Excluding the extension can be problematic 
    584593                i = 0 
    585594                for reference in List<of String>(references) 
    586                         if not reference.endsWith('.dll') and not reference.endsWith('.exe') 
    587                                 reference += '.dll' 
     595                        reference = _appendLibSuffix(reference) 
     596                        if reference is not references[i] 
    588597                                references[i] = reference 
    589598                        i += 1 
    590599 
     
    624633                # $sharp('curDomain.ReflectionOnlyAssemblyResolve += _resolveEvent') 
    625634 
    626635                for reference in references 
    627                         if .verbosity > 0 
    628                                 print 'Loading reference:', reference 
    629                         if false 
    630                                 # Does not work on Novell Mono. See notes above. 
    631                                 referredAss = Assembly.reflectionOnlyLoadFrom(reference) 
    632                                 # TODO: handle all the exceptions from Assembly.loadFrom 
    633                         else 
    634                                 if File.exists(reference) 
    635                                         # try current directory 
    636                                         referredAss = Assembly.loadFrom(reference) 
    637                                 else 
    638                                         # TODO: the problem with -lib: in both Cobra and C# is that it has no effect on runtime, 
    639                                         # you must still register the DLLs in the GAC or copy them into the same dir as the .exe 
    640                                         # because the -lib: paths are not passed into executable. 
    641                                         # So should Cobra copy the .dll's into the target directory (if their paths are not in MONO_PATH)? 
    642                                         searchPaths = .options.getDefault('library-directory', List<of String>()) to List<of String> 
    643                                         # 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 
    644                                         found = false 
    645                                         for searchPath in searchPaths 
    646                                                 combinedPath = Path.combine(searchPath, reference) 
    647                                                 if File.exists(combinedPath) 
    648                                                         referredAss = Assembly.loadFrom(combinedPath) 
    649                                                         found = true 
    650                                                         break 
    651                                         if not found 
    652                                                 # try system wide (GAC) 
    653                                                 if reference.endsWith('.dll') 
    654                                                         reference = reference[:-4] 
    655                                                 referredAss = Utils.loadWithPartialName(reference) 
    656                                 # TODO: handle all the exceptions from Assembly.loadFrom 
    657                         if referredAss 
    658                                 .readAssembly(referredAss, reference <> 'Cobra.Lang.dll') 
    659                         else 
    660                                 _addMessage(SourceException('Cannot locate assembly reference "[reference]".')) 
     636                        _loadAssemblyForRef(reference) 
    661637                        i += 1 
    662638 
     639        def _loadAssemblyForRef(reference as String)             
     640                if .verbosity > 0 
     641                        print 'Loading reference:', reference 
     642                if false 
     643                        # Does not work on Novell Mono. See notes above. 
     644                        referredAss = Assembly.reflectionOnlyLoadFrom(reference) 
     645                        # TODO: handle all the exceptions from Assembly.loadFrom 
     646                else 
     647                        if File.exists(reference) 
     648                                # try current directory 
     649                                referredAss = Assembly.loadFrom(reference) 
     650                        else 
     651                                # TODO: the problem with -lib: in both Cobra and C# is that it has no effect on runtime, 
     652                                # you must still register the DLLs in the GAC or copy them into the same dir as the .exe 
     653                                # because the -lib: paths are not passed into executable. 
     654                                # So should Cobra copy the .dll's into the target directory (if their paths are not in MONO_PATH)? 
     655                                searchPaths = .options.getDefault('library-directory', List<of String>()) to List<of String> 
     656                                # 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 
     657                                found = false 
     658                                for searchPath in searchPaths 
     659                                        combinedPath = Path.combine(searchPath, reference) 
     660                                        if File.exists(combinedPath) 
     661                                                referredAss = Assembly.loadFrom(combinedPath) 
     662                                                found = true 
     663                                                break 
     664                                if not found 
     665                                        # try system wide (GAC) 
     666                                        if reference.endsWith('.dll') 
     667                                                reference = reference[:-4] 
     668                                        referredAss = Utils.loadWithPartialName(reference) 
     669                        # TODO: handle all the exceptions from Assembly.loadFrom 
     670                if referredAss 
     671                        .readAssembly(referredAss, reference <> 'Cobra.Lang.dll') 
     672                else 
     673                        _addMessage(SourceException('Cannot locate assembly reference "[reference]".')) 
     674 
    663675        def refsForPackage(pkgName as String) as List<of String> 
    664676                """ 
    665677                Returns the library/DLL refs for the give package name. 
     
    11391151                else 
    11401152                        throw FallThroughException('found [name], but it is not an IType. it is [thing]') 
    11411153 
     1154        def setTarget(tgt as String) 
     1155                require tgt in ['exe', 'winexe', 'lib', 'module'] 
     1156                # override Target if not already set (fm cmdline) 
     1157                if not .options.isSpecified('target') 
     1158                        if .verbosity, print 'setTarget=[tgt]' 
     1159                        .options['target'] = tgt 
     1160                        .options.didSpecify('target') 
     1161                else     
     1162                        if .verbosity, print 'setTarget: Not set options.target to [tgt], target already set' 
     1163                         
     1164        def addDllReference(libName as String) 
     1165                if not libName.length 
     1166                        return 
     1167                if not .options.containsKey('reference') 
     1168                        .options['reference'] = List<of String>() 
     1169                        .options.didSpecify('reference') 
     1170                refs = .options['reference'] to List<of String> 
     1171                if libName not in refs 
     1172                        if .verbosity, print 'Adding reference to "[libName]"' 
     1173                        libName = _appendLibSuffix(libName) 
     1174                        refs.add(libName) 
     1175                        _loadAssemblyForRef(libName) 
     1176                else 
     1177                        if .verbosity, print 'Reference "[libName]" already in options.ref' 
     1178                         
    11421179        def suggestionFor(name as String) as String? is shared 
    11431180                require name.length 
    11441181                # CC: return _unknownSuggestions.getDefault(name, nil) 
     
    13801417                        else 
    13811418                                outName += '.exe' 
    13821419                        _fullExeFileName = outName 
     1420                        _canRun = options.getDefault('target', 'exe') in ['exe', 'winexe'] 
    13831421 
    13841422                        delaySign = options.boolValue('delay-sign') 
    13851423                        if delaySign 
     
    14651503                                cp.generateExecutable = options.getDefault('target', 'exe') in ['exe', 'winexe'] 
    14661504                                cp.outputAssembly = _fullExeFileName 
    14671505                                cp.compilerOptions = backEndOptions 
     1506                                if _verbosity >= 2 
     1507                                        print '[cp] [backEndOptions][sharpFileNameList]' 
    14681508                                #trace backEndOptions 
    14691509                                #trace sharpFileNameList 
    14701510                                cr = provider.compileAssemblyFromFile(cp, sharpFileNameList.toArray) 
     
    14981538                                        _parseSharpCompilerOutput(output) 
    14991539 
    15001540                        if .errors.count 
     1541                                _canRun = false 
    15011542                                _exitFromErrors 
    15021543 
    15031544                        # remove intermediate files such as *.cobra.cs 
  • Source/CommandLine.cobra

     
    728728                c = .doCompile(paths, false, false, false) 
    729729                if c.errors.count 
    730730                        print 'Not running due to errors above.' 
    731                 else 
     731                else if c.canRun 
    732732                        p = c.runProcess 
    733733                        if _verbosity >= 1 
    734734                                print 'Running: [p.startInfo.fileName] [p.startInfo.arguments]' 
  • Source/CobraParser.cobra

     
    533533                return _module to ! 
    534534 
    535535        def compilerDirective 
     536                compiler = .typeProvider to Compiler? 
     537                if not compiler 
     538                        trace 
     539                        .throwError("Internal: Cannot get compiler from .typeProvider") 
     540                         
    536541                .expect('PERCENTPERCENT') 
    537542                # 'stop' is already handled in main parse loop 
    538543                token = .grab 
    539544                branch token.text 
    540545                        on 'throw' 
     546                                msg = .optional('STRING_SINGLE','STRING_DOUBLE')         
     547                                if msg 
     548                                        print '%%> [msg.text]' 
     549                                        .throwError('Compilation Stopped due CompilerDirective "throw"') 
    541550                                # throw an internal error. used for testing that the compiler will catch and report these as internal errors 
    542551                                .expect('EOL') 
    543552                                # TODO: throw AssertException(SourceSite sourceSite, object[] expressions, object thiss, object info) 
     
    548557                                if typeName.text not in ['decimal', 'float', 'float32', 'float64'] 
    549558                                        .throwError('Compiler directive "number": unrecognized type "[typeName.text]". Must be one of "decimal", "float", "float32" or "float64".') 
    550559                                .expect('EOL') 
    551                                 comp = .typeProvider to Compiler? 
    552                                 if comp, comp.numberTypeName = typeName.text 
     560                                compiler.numberTypeName = typeName.text 
     561                        on 'target' or 'Target'          
     562                                # Target 'exe' | 'winexe' | 'lib' | 'module' 
     563                                tgt = .expect('ID') 
     564                                tgtVal =  tgt.text 
     565                                if tgtVal not in ['exe', 'winexe', 'lib', 'module'] 
     566                                        .throwError("Target value '[tgtVal]' not one of 'exe', 'winexe', 'lib', 'module'") 
     567                                .expect('EOL') 
     568                                compiler.setTarget(tgtVal)     
     569                        on 'reference' or 'Reference'  # pending 'use X.Y' autoref-ing X.Y.dll  
     570                                # Reference dllName     e.g reference System.Windows.Forms[.dll] 
     571                                n = .peek 
     572                                if n and n.which == 'STRING_DOUBLE'    # dbl quoted form "System.Windows.Forms" 
     573                                        id = .expect('STRING_DOUBLE') 
     574                                        dllRef = id.text[1:id.text.length-1] 
     575                                else                                                                    # dot sep IDstream System.Windows.Forms 
     576                                        names = List<of String>()     
     577                                        while true 
     578                                                id = .expect('ID') 
     579                                                names.add(id.text) 
     580                                                dot = .optional('DOT') 
     581                                                if not dot 
     582                                                        break 
     583                                        dllRef = Utils.join('.', names) 
     584                                .endOfLine 
     585                                compiler.addDllReference(dllRef) 
     586                        # ++ 'embed-run-time'   ?? 
    553587                        else 
    554                                 .throwError('Unknown compiler directive.') 
     588                                .throwError('Unknown compiler directive [token.text].') 
    555589 
    556590        def useDirective as UseDirective 
    557591                """ 
  • Tests/700-command-line/800-foolib1.cobra

     
     1# .args. -embed-run-time:no 
     2%% target lib 
     3 
     4class Foo 
     5 
     6        get one as int 
     7                return 1 
     8 
     9        get two as int 
     10                return 2 
     11 
     12        get name as String 
     13                return .getType.name 
     14 
     15        def computeString as String 
     16                return 'aoeuaoeu' 
     17 
     18        def checkInts(args as vari int) as int 
     19                for arg in args 
     20                        assert arg 
     21                return args.length 
  • Tests/700-command-line/801-reference-gac-lib.cobra

     
     1#  
     2%% reference System.Xml 
     3use System.Xml 
     4 
     5class Test 
     6 
     7        def main is shared 
     8                xDoc = XmlDocument() 
     9                #xDoc.load('filename.xml') 
     10                xDoc.loadXml('<xml> <name>Cobra</name> <url>http://Cobra-Language.com/</url> </xml>') 
     11                name = xDoc.getElementsByTagName('name') # an XmlNodeList 
     12                url = xDoc.getElementsByTagName('url') 
     13                assert name.item(0).innerText == 'Cobra' 
     14                assert url.item(0).innerText.startsWith('http://') 
  • Tests/700-command-line/404-fooprog.cobra

     
    11# .args. -embed-run-time:no -r:400-foolib 
    22 
    3 # same as other fooprog, but the -r arg does not include the ".dll" extension -- both ways should work 
     3# same as other 400-fooprog, but the -r arg does not include the ".dll" extension -- both ways should work 
    44 
    55class Program 
    66 
  • Tests/700-command-line/802-fooprog.cobra

     
     1# .args. -embed-run-time:no  
     2%% reference "800-foolib1.dll" 
     3 
     4class Program 
     5 
     6        def main is shared 
     7                f = Foo() 
     8                print f.one 
     9                print f.two 
     10                name = f.name 
     11                .checkName(name) 
     12                s = f.computeString 
     13                .checkName(s) 
     14                assert f.checkInts(2, 4, 6) == 3 
     15 
     16        def checkName(name as String) is shared 
     17                assert name.length 
  • Tests/700-command-line/804-fooprog.cobra

     
     1# .args. -embed-run-time:no 
     2%% reference "800-foolib1" 
     3 
     4# same as other 800-fooprog, but the %% reference arg does not include the ".dll" extension -- both ways should work 
     5 
     6class Program 
     7 
     8        def main is shared 
     9                f = Foo() 
     10                print f.one 
     11                print f.two 
  • Developer/IntermediateReleaseNotes.text

     
    33* Add support for commenting full blocks of lines using /# and #/. Block comments can be nested. 
    44        '/#' block comment start and  '#/' block comment end as initial chars on line 
    55 
     6* Added support for compiler directive to specify the target type same as  
     7    command line -target option 
     8    %% [Tt]arget  'exe' | 'winexe' | 'lib' | 'module' 
     9 
     10* Added support for compiler directive to add a DLL reference same as  
     11    command line -reference option 
     12    %% [Rr]eference  some.qualified.dll   and 
     13    %% [Rr]eference  "some.numbered-100.DllName" 
     14     
     15     
    616* Added support for a Cobra compiler directive to specify the type for `number` 
    717    type of number and integer literals same as command line -number option 
    818    %% number  'decimal' | 'float' | 'float32' | 'float64'