/// <summary> /// Reads an AbsolutePath (which may have been added after the serialization of the path table) /// </summary> public override AbsolutePath ReadAbsolutePath() { var absolutePathType = (BinaryLogger.AbsolutePathType)ReadByte(); switch (absolutePathType) { case BinaryLogger.AbsolutePathType.Invalid: return(AbsolutePath.Invalid); case BinaryLogger.AbsolutePathType.Static: return(base.ReadAbsolutePath()); case BinaryLogger.AbsolutePathType.Dynamic: return(LogReader.m_capturedPaths[(uint)ReadInt32Compact()]); default: throw Contract.AssertFailure($"Unrecognized path type: {absolutePathType}. The XLG file format has potentially changed."); } }
/// <summary> /// Use an existing resource if possible, else create a new one. /// </summary> /// <param name="key">Key to lookup an exisiting resource, if one exists.</param> public async Task <ResourceWrapper <TObject> > CreateAsync(TKey key) { ResourceWrapper <TObject> returnWrapper; using (Counter[ResourcePoolCounters.CreationTime].Start()) { // Attempt to reuse an existing resource if it has been instantiated. if (_resourceDict.TryGetValue(key, out ResourceWrapper <TObject> existingWrappedResource) && existingWrappedResource.IsValueCreated && existingWrappedResource.TryAcquire(out var reused)) { returnWrapper = existingWrappedResource; } else { var count = Interlocked.Increment(ref _resourceCount); // Start resource "GC" if the cache is full and it isn't already running if (count >= _maxResourceCount) { await EnqueueCleanupAsync(force : true, numberToRelease : 1); } returnWrapper = _resourceDict.GetOrAdd( key, (k, resourceFactory) => new ResourceWrapper <TObject>(() => resourceFactory(k), _context), _resourceFactory); if (_resourceDict.Count > _maxResourceCount) { _resourceDict.TryRemove(key, out _); throw new CacheException($"Attempting to create resource to increase cached count above maximum allowed ({_maxResourceCount})"); } if (!returnWrapper.TryAcquire(out reused)) { throw Contract.AssertFailure($"Resource was marked for shutdown before acquired."); } } Counter[reused ? ResourcePoolCounters.Reused : ResourcePoolCounters.Created].Increment(); } return(returnWrapper); }
private static Dictionary <AbsolutePath, SpecFileWithMetadata> CreateSpecsFromModules(IReadOnlyCollection <ParsedModule> modules, bool allowDoubleOwnership) { var result = new Dictionary <AbsolutePath, SpecFileWithMetadata>(); foreach (var m in modules) { foreach (var spec in m.Specs) { var added = result.TryAdd(spec.Key, SpecFileWithMetadata.CreateNew(m, spec.Value)); // It shouldn't happen that the spec was already present when we don't allow double ownership (currently we only allow it for configuration parsing) if (!added && !allowDoubleOwnership) { throw Contract.AssertFailure($"Spec with path {spec.Key} from module '{m.Descriptor.Name}' is already owned by module '{result[spec.Key].OwningModule.Descriptor.Name}'."); } } } return(result); }
/// <summary> /// Advances state under big lock after chain has been computed. /// </summary> private bool ValuePromiseChainComputed(EdgeSet edgeSet) { lock (m_pendingEdgeSets) { switch (edgeSet.State) { case EdgeSetState.Adding: edgeSet.State = EdgeSetState.Added; return(true); case EdgeSetState.Abandoned: edgeSet.State = EdgeSetState.Invalid; Interlocked.Increment(ref m_statistics.CycleDetectionChainsAbandonedWhileProcessing); return(false); default: throw Contract.AssertFailure("unexpected edge set state"); } } }
/// <summary> /// Converts a single-artifact origin to an overall pip result. This makes sense for pips with a single output. /// </summary> public static PipResultStatus ToPipResult(this PipOutputOrigin origin) { switch (origin) { case PipOutputOrigin.Produced: return(PipResultStatus.Succeeded); case PipOutputOrigin.UpToDate: return(PipResultStatus.UpToDate); case PipOutputOrigin.DeployedFromCache: return(PipResultStatus.DeployedFromCache); case PipOutputOrigin.NotMaterialized: return(PipResultStatus.NotMaterialized); default: throw Contract.AssertFailure("Unhandled PipOutputOrigin"); } }
private IExpression Generate(PipFragment fragment) { switch (fragment.FragmentType) { case PipFragmentType.Invalid: return(Identifier.CreateUndefined()); case PipFragmentType.StringLiteral: return(Generate(fragment.GetStringIdValue())); case PipFragmentType.AbsolutePath: return(Generate(fragment.GetPathValue())); case PipFragmentType.NestedFragment: return(Generate(fragment.GetNestedFragmentValue())); default: throw Contract.AssertFailure($"Unexpected PipFragmentType from PipFragment.FragmentType: {fragment.FragmentType}"); } }
public static bool IsTerminal(this PipState current) { switch (current) { case PipState.Ignored: case PipState.Waiting: case PipState.Ready: case PipState.Running: return(false); case PipState.Skipped: case PipState.Failed: case PipState.Done: case PipState.Canceled: return(true); default: throw Contract.AssertFailure("Unhandled Pip State"); } }
/// <nodoc /> public static ReparsePointType ToReparsePointType(this BondReparsePointType reparsePointType) { switch (reparsePointType) { case BondReparsePointType.None: return(ReparsePointType.None); case BondReparsePointType.SymLink: return(ReparsePointType.SymLink); case BondReparsePointType.MountPoint: return(ReparsePointType.MountPoint); case BondReparsePointType.NonActionable: return(ReparsePointType.NonActionable); default: throw Contract.AssertFailure("Cannot convert BondReparsePointType to ReparsePointType"); } }
/// <summary> /// Use an existing resource if possible, else create a new one. /// </summary> /// <param name="key">Key to lookup an exisiting resource, if one exists.</param> public async Task <ResourceWrapper <TObject> > CreateAsync(TKey key) { ResourceWrapper <TObject> returnWrapper; using (var sw = Counter[ResourcePoolCounters.CreationTime].Start()) { // Attempt to reuse an existing resource if it has been instantiated. if (_resourceDict.TryGetValue(key, out ResourceWrapper <TObject> existingWrappedResource) && existingWrappedResource.IsValueCreated && existingWrappedResource.TryAcquire(out var reused)) { returnWrapper = existingWrappedResource; } else { // Start resource "GC" if the cache is full and it isn't already running await EnsureCapacityAsync(); returnWrapper = _resourceDict.GetOrAdd(key, k => { return(new ResourceWrapper <TObject>(() => _resourceFactory(k))); }); if (_resourceDict.Count > _maxResourceCount) { _resourceDict.TryRemove(key, out _); throw new CacheException($"Attempting to create resource to increase cached count above maximum allowed ({_maxResourceCount})"); } if (!returnWrapper.TryAcquire(out reused)) { throw Contract.AssertFailure($"Resource was marked for shutdown before acquired."); } } ResourcePoolCounters counter = reused ? ResourcePoolCounters.Reused : ResourcePoolCounters.Created; Counter[counter].Increment(); _context.Debug($"{nameof(ResourcePool<TKey, TObject>)}.{nameof(CreateAsync)} {(reused ? "reused" : "created")} a resource with {returnWrapper.Uses} from a pool of {_resourceDict.Count}"); } return(returnWrapper); }
/// <summary> /// Indicates if there is a valid state transition from <paramref name="current"/> to <paramref name="target"/>. /// </summary> public static bool CanTransitionTo(this PipState current, PipState target) { switch (target) { case PipState.Ignored: return(false); // Entry state. case PipState.Waiting: // Initial state on pip addition / explicit scheduling. return(current == PipState.Ignored || /* fail establish pip fingerprint */ current == PipState.Running); case PipState.Ready: // Pending pips are the staging area on the way to being queued - they may have unsatisfied dependencies return(current == PipState.Waiting); case PipState.Running: // Queued pips can be run when they reach the queue head. return(current == PipState.Ready); case PipState.Skipped: return // Skipping (due to failure of pre-requirements) can occur so long as the pip still has pre-requirements (i.e., Pending), // or if we tentatively skipped a filter-failing pip (that was later scheduled due to a filter change). (current == PipState.Waiting || // The pip may also transition from Running to Skipped if using /cacheonly mode and the pip was not a cache hit. current == PipState.Running); case PipState.Canceled: // Completion / failure is the consequence of actual execution. return(current == PipState.Running); case PipState.Failed: case PipState.Done: // Completion. return(current == PipState.Running); default: throw Contract.AssertFailure("Unhandled Pip State"); } }
/// <summary> /// Reports an access that - ignoring whitelisting - was unexpected. This can be due to a manifest-side or BuildXL-side denial decision. /// </summary> private FileAccessWhitelist.MatchType MatchAndReportUnexpectedFileAccess(ReportedFileAccess unexpectedFileAccess) { if (m_fileAccessWhitelist != null && m_fileAccessWhitelist.HasEntries) { Contract.Assert( m_config.FailUnexpectedFileAccesses == false, "Having a file-access whitelist requires that Detours failure injection is off."); FileAccessWhitelist.MatchType matchType = m_fileAccessWhitelist.Matches(m_loggingContext, unexpectedFileAccess, m_pip); switch (matchType) { case FileAccessWhitelist.MatchType.NoMatch: AddUnexpectedFileAccessNotWhitelisted(unexpectedFileAccess); ReportUnexpectedFileAccessNotWhitelisted(unexpectedFileAccess); break; case FileAccessWhitelist.MatchType.MatchesButNotCacheable: AddUnexpectedFileAccessWhitelisted(unexpectedFileAccess); m_numWhitelistedButNotCacheableFileAccessViolations++; ReportWhitelistedFileAccessNonCacheable(unexpectedFileAccess); break; case FileAccessWhitelist.MatchType.MatchesAndCacheable: AddUnexpectedFileAccessWhitelisted(unexpectedFileAccess); m_numWhitelistedAndCacheableFileAccessViolations++; ReportWhitelistedFileAccessCacheable(unexpectedFileAccess); break; default: throw Contract.AssertFailure("Unknown whitelist-match type."); } return(matchType); } else { AddUnexpectedFileAccessNotWhitelisted(unexpectedFileAccess); ReportUnexpectedFileAccessNotWhitelisted(unexpectedFileAccess); return(FileAccessWhitelist.MatchType.NoMatch); } }
/// <nodoc /> public AmbientContext(PrimitiveTypes knownTypes) : base(ContextName, knownTypes) { var currentHost = Host.Current; var osName = SymbolAtom.Create(StringTable, "os"); string osValue = currentHost.CurrentOS.GetDScriptValue(); if (string.IsNullOrEmpty(osValue)) { throw Contract.AssertFailure("Unhandled HostOS Type"); } var cpuName = SymbolAtom.Create(StringTable, "cpuArchitecture"); string cpuValue; switch (currentHost.CpuArchitecture) { case HostCpuArchitecture.X86: cpuValue = "x86"; break; case HostCpuArchitecture.X64: cpuValue = "x64"; break; default: throw Contract.AssertFailure("Unhandled CpuArchitecture Type"); } var isElevatedName = SymbolAtom.Create(StringTable, "isElevated"); var isElevatedValue = CurrentProcess.IsElevated; m_currentHost = ObjectLiteral.Create( new Binding(osName, osValue, default(LineInfo)), new Binding(cpuName, cpuValue, default(LineInfo)), new Binding(isElevatedName, isElevatedValue, default(LineInfo)) ); MountNameObject = Symbol("name"); MountPathObject = Symbol("path"); }
internal IEnumerable <MemberDeclarationSyntax> CreateSerializers(IEnumerable <INamedTypeSymbol> typesToSerialize) { var classMembers = new List <MemberDeclarationSyntax>(); var registrationCalls = new List <StatementSyntax>(); foreach (var group in typesToSerialize.GroupBy(type => type.TypeKind)) { switch (group.Key) { case TypeKind.Enum: classMembers.Add(CreateEnumSerializers(group)); registrationCalls.Add(InvocationStatement(ReactNativeNames.CreateEnumSerializers)); break; case TypeKind.Class: case TypeKind.Struct: classMembers.Add(CreateObjectSerializers(group)); registrationCalls.Add(InvocationStatement(ReactNativeNames.CreateObjectSerializers)); break; default: throw Contract.AssertFailure("Unexpected type to serialize"); } } // Generates: // internal void CreateSerializers() // { // ... registrationCalls (ses above) // } classMembers.Add(MethodDeclaration( PredefinedType(Token(SyntaxKind.VoidKeyword)), ReactNativeNames.CreateSerializers) .AddModifiers( Token(SyntaxKind.InternalKeyword)) .WithBody( Block( registrationCalls))); return(classMembers); }
private bool IsSupportedPipType(PipType pipType) { switch (pipType) { case PipType.WriteFile: case PipType.CopyFile: case PipType.Process: case PipType.Ipc: case PipType.SealDirectory: return(true); case PipType.Value: case PipType.SpecFile: case PipType.Module: case PipType.HashSourceFile: return(false); default: throw Contract.AssertFailure($"Unknown pip type: {pipType}"); } }
/// <summary> /// Constructs a PathFixer object /// </summary> /// <param name="lowerCaseDirectories">Whether or not to lowercase directory segments in the path</param> /// <param name="slashType">The slash type to validate/normalize to</param> public PathFixer(bool lowerCaseDirectories, SlashType slashType) { switch (slashType) { case SlashType.Default: case SlashType.Unix: ExpectedPathSeparator = '/'; IllegalPathSeparator = '\\'; break; case SlashType.Windows: ExpectedPathSeparator = '\\'; IllegalPathSeparator = '/'; break; default: throw Contract.AssertFailure("Unexpected enum value for SlashType"); } LowerCaseDirectories = lowerCaseDirectories; }
/// <summary> /// Starts a background operation. This causes the <see cref="internalBuffer"/> to fill or flush. /// It must be ensured that no other background operation will be in progress, and that the stream is still usable after it. /// - First start an operation with <see cref="StartNewOperation"/>; this reserves the right to start the next background operation. /// - Then, wait for the current background operation, if any. We've established another one will not follow it due to the prior point. /// - Then, respond to the current stream usability (EOF, broken, etc.) as updated by the prior operation. /// </summary> private unsafe void StartBackgroundOperation(BackgroundOperationSlot slot, StreamBackgroundOperation nextOperation) { Contract.Requires(nextOperation != StreamBackgroundOperation.None); Analysis.IgnoreArgument(slot); lock (m_backgroundOperationLock) { if (m_usability != StreamUsability.Usable) { Contract.Assume(false, "Attempting to start a background operation on an unusable stream: " + m_usability.ToString("G")); } Contract.Assume( m_currentBackgroundOperation == StreamBackgroundOperation.None, "Background operation already in progress; wait on it first?"); Contract.Assume(m_currentBackgroundOperationCompletionSource == null); m_currentBackgroundOperation = nextOperation; } // Now actually start the async operation. // Note that the callback to 'this' (IIOCompletionTarget) can happen on this same stack byte *pinnedBuffer; int operationLength; switch (nextOperation) { case StreamBackgroundOperation.Fill: internalBuffer.LockForFill(out pinnedBuffer, out operationLength); m_file.ReadOverlapped(this, pinnedBuffer, operationLength, m_bufferPosition); break; case StreamBackgroundOperation.Flush: internalBuffer.LockForFlush(out pinnedBuffer, out operationLength); m_file.WriteOverlapped(this, pinnedBuffer, operationLength, m_bufferPosition); break; default: throw Contract.AssertFailure("Unhandled StreamBackgroundOperation"); } }
/// <summary> /// Use an existing resource if possible, else create a new one. /// </summary> /// <param name="key">Key to lookup an existing resource, if one exists.</param> /// <exception cref="ObjectDisposedException">If the pool has already been disposed</exception> public async Task <ResourceWrapper <TObject> > CreateAsync(TKey key) { if (_disposed) { throw new ObjectDisposedException(objectName: _tracer.Name, message: "Attempt to obtain resource after dispose"); } using (Counter[ResourcePoolCounters.CreationTime].Start()) { // NOTE: if dispose has happened at this point, we will fail to take the semaphore using (await _mutex.WaitTokenAsync()) { // Remove anything that has expired or been invalidated. await CleanupAsync(); ResourceWrapper <TObject> returnWrapper; // Attempt to reuse an existing resource if it has been instantiated. if (_resourceDict.TryGetValue(key, out var existingWrappedResource)) { returnWrapper = existingWrappedResource; } else { returnWrapper = CreateResourceWrapper(key); _resourceDict.Add(key, returnWrapper); } if (!returnWrapper.TryAcquire(out var reused, _clock)) { // Should be impossible throw Contract.AssertFailure($"Failed to acquire resource. LastUseTime={returnWrapper.LastUseTime}, Uses={returnWrapper.Uses}"); } Counter[reused ? ResourcePoolCounters.Reused : ResourcePoolCounters.Created].Increment(); return(returnWrapper); } } }
internal DisplayStackTraceEntry CreateDisplayStackTraceEntry(ImmutableContextBase context, LineInfo lastCallSite) { if (m_ambientCall != null) { var loc = new Location { File = "[ambient call]", Line = -1, Position = -1 }; var functionName = m_ambientCall.Functor.ToDisplayString(context); return(new DisplayStackTraceEntry(loc, functionName, this)); } if (Lambda != null) { var location = lastCallSite.AsLoggingLocation(Env, context); SymbolAtom?methodName = Lambda?.Name; var functionName = methodName?.IsValid == true?methodName.Value.ToString(context.StringTable) : "<lambda>"; return(new DisplayStackTraceEntry(location, functionName, this)); } throw Contract.AssertFailure("The code is effectively unreacheable."); }
private static EvaluationResult GetPathValues(Context context, EvaluationStackFrame args, Type type) { var name = Args.AsString(args, 0); var separator = Args.AsString(args, 1); string strValue = GetRawValue(context, name); var entry = context.TopStack; if (string.IsNullOrWhiteSpace(strValue)) { return(EvaluationResult.Create(ArrayLiteral.CreateWithoutCopy(CollectionUtilities.EmptyArray <EvaluationResult>(), entry.InvocationLocation, entry.Path))); } var values = separator.Length == 0 ? new[] { strValue } : strValue.Split(new[] { separator }, StringSplitOptions.RemoveEmptyEntries); var pathsOrFiles = new List <EvaluationResult>(); for (int i = 0; i < values.Length; ++i) { if (!string.IsNullOrWhiteSpace(values[i])) { AbsolutePath path = ParsePath(context, name, values[i], 1); EvaluationResult result = type == typeof(AbsolutePath) ? EvaluationResult.Create(path) : type == typeof(FileArtifact) ? EvaluationResult.Create(FileArtifact.CreateSourceFile(path)) : type == typeof(DirectoryArtifact) ? EvaluationResult.Create(DirectoryArtifact.CreateWithZeroPartialSealId(path)) : EvaluationResult.Undefined; if (result.IsUndefined) { throw Contract.AssertFailure(I($"Cannot convert paths to typeof({type.Name})")); } pathsOrFiles.Add(result); } } return(EvaluationResult.Create(ArrayLiteral.CreateWithoutCopy(pathsOrFiles.ToArray(), entry.InvocationLocation, entry.Path))); }
/// <summary> /// Attempt to reserve the resource. Fails if marked for shutdown. /// </summary> /// <param name="reused">Whether the resource has been used previously.</param> /// <returns>Whether the resource is approved for use.</returns> public bool TryAcquire(out bool reused) { lock (this) { if (_resource.IsValueCreated && _resource.Value.ShutdownStarted) { throw Contract.AssertFailure($"Found resource which has already begun shutdown"); } _uses++; reused = _lastUseTime != DateTime.MinValue; if (_uses > 0) { _lastUseTime = DateTime.UtcNow; return(true); } } reused = false; return(false); }
/// <summary> /// <see cref="Stream.Seek(long, SeekOrigin)"/> /// </summary> public override long Seek(long offset, SeekOrigin origin) { using (StreamOperationToken token = StartNewOperation(StreamOperation.Seek)) { BackgroundOperationSlot slot = token.WaitForBackgroundOperationSlot(); if (slot.Usability == StreamUsability.Broken) { throw slot.ThrowExceptionForBrokenStream(); } long offsetFromStart; switch (origin) { case SeekOrigin.Begin: Contract.Assume(offset >= 0, "Attempted to seek to a negative offset"); offsetFromStart = offset; break; case SeekOrigin.Current: Contract.Assume(m_position >= offset, "Attempted to seek (relative to current) to a negative offset"); offsetFromStart = m_position + offset; break; case SeekOrigin.End: throw new NotSupportedException("Seeking relative to stream end is not supported"); default: throw Contract.AssertFailure("Unknwon SeekOrigin"); } if (m_position != offsetFromStart) { FlushOrDiscardBufferAndResetPositionAsync(token, slot, offsetFromStart).GetAwaiter().GetResult(); } return(offsetFromStart); } }
/// <inheritdoc/> protected override EvaluationResult DoEval(Context context, ModuleLiteral env, EvaluationStackFrame frame) { var result = m_expression.Eval(context, env, frame); if (result.IsErrorValue) { return(result); } if (!(result.Value is ModuleLiteral module)) { var thisNodeType = nameof(ModuleToObjectLiteral); throw Contract.AssertFailure( $"AstConverter should never create a '{thisNodeType}' node that wraps an expression that evaluates to something other than {nameof(ModuleLiteral)}. " + $"Instead, this '{thisNodeType}' wraps an expression of type '{m_expression.GetType().Name}' which evaluated to an instance of type '{result.Value?.GetType().Name}'."); } var bindings = module .GetAllBindings(context) .Where(kvp => kvp.Key != Constants.Names.RuntimeRootNamespaceAlias) .Select(kvp => { var name = SymbolAtom.Create(context.StringTable, kvp.Key); var location = kvp.Value.Location; var evalResult = module.GetOrEvalFieldBinding(context, name, kvp.Value, location); return(new Binding(name, evalResult.Value, location)); }) .ToArray(); if (bindings.Any(b => b.Body.IsErrorValue())) { return(EvaluationResult.Error); } var objectLiteral = ObjectLiteral.Create(bindings); return(EvaluationResult.Create(objectLiteral)); }
/// <summary> /// Returns a RetryInfo object with the default location for the given RetryReason. /// </summary> public static RetryInfo GetDefault(RetryReason reason) { switch (reason) { case RetryReason.ResourceExhaustion: case RetryReason.ProcessStartFailure: case RetryReason.TempDirectoryCleanupFailure: case RetryReason.StoppedWorker: return(RetryOnDifferentWorker(reason)); case RetryReason.OutputWithNoFileAccessFailed: case RetryReason.MismatchedMessageCount: case RetryReason.AzureWatsonExitCode: case RetryReason.UserSpecifiedExitCode: return(RetryOnSameWorker(reason)); case RetryReason.VmExecutionError: return(RetryOnSameAndDifferentWorkers(reason)); default: throw Contract.AssertFailure("Default not defined for RetryReason: " + reason.ToString()); } }
/// <summary> /// Analyze the <paramref name="sourceFile"/>. /// </summary> /// <remarks> /// This method will compute the type of the file and will call appropriate analisys function. /// </remarks> public void AnalyzeFile(ISourceFile sourceFile, Logger logger, LoggingContext loggingContext, PathTable pathTable, Workspace workspace) { var scope = GetFileScope(sourceFile); switch (scope) { case RuleAnalysisScope.BuildListFile: case RuleAnalysisScope.SpecFile: AnalyzeSpecFile(sourceFile, logger, loggingContext, pathTable, workspace); break; case RuleAnalysisScope.RootConfig: AnalyzeRootConfigurationFile(sourceFile, logger, loggingContext, pathTable); break; case RuleAnalysisScope.PackageConfig: AnalyzePackageConfigurationFile(sourceFile, logger, loggingContext, pathTable); break; default: throw Contract.AssertFailure($"Unknown file scope '{scope}'."); } }
/// <summary> /// Indicates that edge set should no longer be considered for cycle detection, and advances state under big lock accordingly. /// </summary> private void Remove(EdgeSet edgeSet) { lock (m_pendingEdgeSets) { switch (edgeSet.State) { case EdgeSetState.PendingAdd: edgeSet.State = EdgeSetState.Invalid; Contract.Assume(edgeSet.PendingEdgeSetNode != null); m_pendingEdgeSets.Remove(edgeSet.PendingEdgeSetNode); Interlocked.Increment(ref m_statistics.CycleDetectionChainsRemovedBeforeProcessing); break; case EdgeSetState.Adding: edgeSet.State = EdgeSetState.Abandoned; break; case EdgeSetState.Added: edgeSet.State = EdgeSetState.PendingRemove; m_pendingEdgeSets.AddFirst(edgeSet); // We don't need to set EdgeSet.PendingEdgeSetNode, as the edge set will now eventually be processed for removal, and it will never be dropped from the middle of m_pendingEdgeSets. Interlocked.Increment(ref m_statistics.CycleDetectionChainsRemovedAfterProcessing); break; case EdgeSetState.Invalid: case EdgeSetState.Abandoned: case EdgeSetState.PendingRemove: // could happen if edge set gets disposed multiple times break; default: throw Contract.AssertFailure("unexpected edge set state"); } } }
public static bool IndicatesFailure(this PipState current) { Contract.Ensures(ContractUtilities.Static(IsTerminal(current))); switch (current) { case PipState.Ignored: case PipState.Waiting: case PipState.Ready: case PipState.Running: return(false); // Non-terminal case PipState.Done: return(false); // Terminal but successful case PipState.Skipped: case PipState.Failed: case PipState.Canceled: return(true); // Oh no! default: throw Contract.AssertFailure("Unhandled Pip State"); } }
public static PipExecutionLevel ToExecutionLevel(this PipResultStatus result) { Contract.Requires(result.IndicatesExecution()); switch (result) { case PipResultStatus.Succeeded: return(PipExecutionLevel.Executed); case PipResultStatus.Failed: case PipResultStatus.Canceled: return(PipExecutionLevel.Failed); case PipResultStatus.DeployedFromCache: case PipResultStatus.NotMaterialized: // TODO: This is misleading; should account for eventual materialization. return(PipExecutionLevel.Cached); case PipResultStatus.UpToDate: return(PipExecutionLevel.UpToDate); default: throw Contract.AssertFailure("Unhandled Pip Result that indicates execution"); } }
private SymbolAtom GetConfigKeyword(ISourceFile sourceFile) { string configKeywordString = sourceFile.Statements[0].TryGetFunctionNameInCallExpression(); Contract.Assert(configKeywordString != null, I($"Configuration validation for '{Kind}' should have caught that the first statement is not a call expression")); switch (Kind) { case ConfigurationKind.PrimaryConfig: Contract.Assert( configKeywordString == Script.Constants.Names.ConfigurationFunctionCall, I($"Configuration validation for '{Kind}' should have caught that a wrong configuration keyword was used ('{configKeywordString}' instead of '{Script.Constants.Names.ConfigurationFunctionCall}')")); return(SymbolAtom.Create(Context.StringTable, configKeywordString)); case ConfigurationKind.ModuleConfig: Contract.Assert( configKeywordString == Script.Constants.Names.ModuleConfigurationFunctionCall || configKeywordString == Script.Constants.Names.LegacyModuleConfigurationFunctionCall, I($"Configuration validation for '{Kind}' should have caught that a wrong configuration keyword was used ('{configKeywordString}' instead of either '{Script.Constants.Names.ModuleConfigurationFunctionCall}' or '{Script.Constants.Names.LegacyModuleConfigurationFunctionCall}')")); return(SymbolAtom.Create(Context.StringTable, configKeywordString)); default: throw Contract.AssertFailure(UnimplementedOperationForConfigKindErrorMessage); } }
void IIOCompletionTarget.OnCompletion(FileAsyncIOResult result) { // Note that this may be called on the same stack as StartBackgroundOperation (sync completion), Contract.Assume(result.Status != FileAsyncIOStatus.Pending); bool failed = result.Status == FileAsyncIOStatus.Failed; if (!failed) { // Note, that FileAsyncIOResult constructor can't enforce this check because in some other cases // 0 transfered bytes is ok for a successful IO operation. Contract.Assert(result.BytesTransferred > 0, "Zero bytes transferred is a failure indication (otherwise can be confused with EOF)"); } TaskCompletionSource <BackgroundOperationSlot> completionSource; lock (m_backgroundOperationLock) { // Capture the completion source to use outside of the lock. completionSource = m_currentBackgroundOperationCompletionSource; switch (m_currentBackgroundOperation) { case StreamBackgroundOperation.Fill: m_bufferPosition += result.BytesTransferred; internalBuffer.FinishFillAndUnlock(numberOfBytesFilled: result.BytesTransferred); break; case StreamBackgroundOperation.Flush: m_bufferPosition += result.BytesTransferred; internalBuffer.FinishFlushAndUnlock(numberOfBytesFlushed: result.BytesTransferred); break; case StreamBackgroundOperation.None: Contract.Assume(false, "Unexpected I/O completion (no background operation in progress)"); throw new InvalidOperationException("Unreachable"); default: throw Contract.AssertFailure("Unhandled StreamBackgroundOperation"); } if (failed) { StreamUsability newUsability; if (result.ErrorIndicatesEndOfFile) { newUsability = StreamUsability.EndOfFileReached; } else { newUsability = StreamUsability.Broken; m_brokenStreamException = new IOException( "An error occurred while reading or writing to a file stream. The stream will no longer be usable.", new NativeWin32Exception(result.Error)); } m_usability = newUsability; } else { Contract.Assume(m_usability == StreamUsability.Usable); } m_currentBackgroundOperation = StreamBackgroundOperation.None; m_currentBackgroundOperationCompletionSource = null; } // Since the lock is no longer held, it is safe to resume any waiters (note that they may run on this stack). if (completionSource != null) { completionSource.SetResult(new BackgroundOperationSlot(this)); } }
/// <summary> /// Dynamically inspects the object and returns the RuntimeTypeId /// </summary> public static RuntimeTypeId ComputeTypeOfKind(object value) { Contract.Assume(value != null); // In the future we'd like to use C# 7's Switch statements with patterns https://blogs.msdn.microsoft.com/dotnet/2016/08/24/whats-new-in-csharp-7-0/ // Checking runtime type per pattern of: https://blogs.msdn.microsoft.com/vancem/2006/10/01/drilling-into-net-runtime-microbenchmarks-typeof-optimizations/ if (value == UndefinedValue.Instance) { return(RuntimeTypeId.Undefined); } var runtimeType = value.GetType(); // Need to handle both cases: ArrayLiteral itself, and generic version. // In latter case, checking that runtimeType is assignable to ArrayLiteral. if (runtimeType == typeof(ArrayLiteral) || typeof(ArrayLiteral).IsAssignableFrom(runtimeType)) { return(RuntimeTypeId.Array); } if (runtimeType.IsObjectLikeLiteralType()) { return(RuntimeTypeId.Object); } if (runtimeType.IsModuleLiteral()) { // We want to expand this to proper namespace node in the future when we deprecate moduleliteral return(RuntimeTypeId.ModuleLiteral); } if (runtimeType == typeof(AbsolutePath)) { return(RuntimeTypeId.Path); } if (runtimeType == typeof(FileArtifact)) { return(RuntimeTypeId.File); } if (runtimeType == typeof(DirectoryArtifact)) { return(RuntimeTypeId.Directory); } if (runtimeType == typeof(StaticDirectory)) { return(GetRuntimeTypeForStaticDirectory(value as StaticDirectory)); } if (runtimeType == typeof(RelativePath)) { return(RuntimeTypeId.RelativePath); } if (runtimeType == typeof(PathAtom)) { return(RuntimeTypeId.PathAtom); } if (runtimeType == typeof(string)) { return(RuntimeTypeId.String); } if (runtimeType == typeof(bool)) { return(RuntimeTypeId.Boolean); } if (runtimeType == typeof(int)) { // We only support integers during evaluation, we'll have to expand this when we support more. return(RuntimeTypeId.Number); } if (runtimeType == typeof(Closure)) { return(RuntimeTypeId.Function); } if (runtimeType == typeof(EnumValue)) { return(RuntimeTypeId.Enum); } if (runtimeType == typeof(OrderedSet)) { return(RuntimeTypeId.Set); } if (runtimeType == typeof(OrderedMap)) { return(RuntimeTypeId.Map); } throw Contract.AssertFailure(I($"Unexpected runtime value with type '{runtimeType}' encountered.")); }