Esempio n. 1
0
        private IEnumerable<FileInfo> _pathCandidates(RefSpec refSepc, CancellationToken token)
        {
            var resolvedPath = refSepc.ResolvedPath;
            if (resolvedPath != null)
                yield return resolvedPath;

            var prefixes = _copySearchPaths(token).Result;
            var rawPath = refSepc.RawPath;

            // Prefer a path, if one was provided.
            if (rawPath != null)
            {
                if (Path.IsPathRooted(rawPath))
                {
                    // Path is absolute, just try it
                    yield return _safelyCreateFileInfo(rawPath);
                }
                else
                {
                    // Path is relative. We won't try the process working directory unless
                    //  explicitly instructed to (by adding '.' to the search paths)
                    foreach (var candidate in _combineWithSearchPaths(prefixes, rawPath))
                        yield return candidate;
                }
            }

            var moduleName = refSepc.ModuleName;
            if (moduleName != null)
            {

                var splitPrefix = moduleName.Id;
                while (true) // while there are '.' in the module name...
                {
                    // ... try each search path in turn ...
                    foreach (var candidate in _combineWithSearchPaths(prefixes, splitPrefix + ".pxs"))
                        yield return candidate;

                    // ... convert the last '.' to a '/' (or platform equivalent) ...
                    var dotIndex = splitPrefix.LastIndexOf('.');
                    // Check if there is a '.' that is not the first (=0) or last character of the module name
                    if (1 <= dotIndex && dotIndex <= splitPrefix.Length - 2)
                    {
                        splitPrefix = Path.Combine(
                            splitPrefix.Substring(0, dotIndex),
                            splitPrefix.Substring(dotIndex + 1));
                    }
                    else
                    {
                        // ... or abort if all '.' have been converted ...
                        break;
                    }
                }
            }
        }
Esempio n. 2
0
        private async Task<PreflightResult> _performPreflight(RefSpec refSpec, CancellationToken token)
        // requires refSpec.Source != null
        // ensures result != null
        {
            if (refSpec.ErrorMessage != null)
                return new PreflightResult { ErrorMessage = refSpec.ErrorMessage };

            token.ThrowIfCancellationRequested();
            _trace.TraceEvent(TraceEventType.Information, 0, "Preflight parsing of {0} requested.", refSpec);

            // Make sure refSpec has a re-usable source (will have to support both preflight and actual compilation)
            var source = refSpec.Source;
            if (source == null)
                throw new ArgumentException(Resources.SelfAssemblingPlan_RefSpecMustHaveSource, "refSpec");
            var reportedPath = _getPath(source);
            if (source.IsSingleUse)
                source = await source.CacheInMemoryAsync();

            token.ThrowIfCancellationRequested();

            // Perform preflight parse
            var eng = new Engine { ExecutionProhibited = true };
            var app = new Application();
            var ldr =
                new Loader(new LoaderOptions(eng, app)
                               {
                                   // Important: Have preflight flag set
                                   PreflightModeEnabled = true,
                                   ReconstructSymbols = false,
                                   RegisterCommands = false,
                                   StoreSourceInformation = false,
                               });

            TextReader sourceReader;
            if (!source.TryOpen(out sourceReader))
            {
                var errorResult = new PreflightResult
                                      {
                                          ErrorMessage =
                                              "Failed to open " + refSpec + " for preflight parsing."
                                      };
                return errorResult;
            }
            ldr.LoadFromReader(sourceReader, refSpec.ResolvedPath != null ? refSpec.ResolvedPath.ToString() : null);

            // Extract preflight information
            ModuleName theModuleName;
            if (!ModuleName.TryParse(app.Meta[Module.NameKey], out theModuleName))
                theModuleName = app.Module.Name;

            MetaEntry noStdLibEntry;
            var result = new PreflightResult
            {
                ModuleName = theModuleName,
                SuppressStandardLibrary =
                    app.Meta.TryGetValue(Module.NoStandardLibraryKey, out noStdLibEntry) && noStdLibEntry.Switch,
                Path = reportedPath
            };

            result.References.AddRange(
                app.Meta[Module.ReferencesKey].List.Where(entry => !entry.Equals(new MetaEntry("")))
                    .Select(_parseRefSpec));
            _trace.TraceEvent(TraceEventType.Verbose, 0, "Preflight parsing of {0} finished.", refSpec);
            return result;
        }
Esempio n. 3
0
 private RefSpec _forbidFileRefSpec(RefSpec refSpec)
 {
     if (refSpec.ModuleName == null)
         refSpec.ErrorMessage = refSpec.ErrorMessage ?? Resources.SelfAssemblingPlan__forbidFileRefSpec_notallowed;
     return refSpec;
 }
Esempio n. 4
0
        private Task<PreflightResult> _orderPreflight(RefSpec refSpec, CancellationToken token)
        {
            if (refSpec.ResolvedPath == null)
                throw new ArgumentException(Resources.SelfAssemblingPlan_RefSepcMustHaveResolvedPathForPreflightOrder,
                    "refSpec");

            return _preflightCache.GetOrAdd(refSpec.ResolvedPath.FullName,
                async (path, actualToken) =>
                {
                    refSpec.Source = new FileSource(refSpec.ResolvedPath, Encoding);
                    await Task.Yield(); // Need to yield at this point to keep
                    // the critical section of the cache short
                    return await _performPreflight(refSpec, actualToken);
                }, token);
        }