Wiki

Ticket #35: compilerDirectiveTgtDll.patch

File compilerDirectiveTgtDll.patch, 14.2 KB (added by hopscc, 16 years 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'