internal void SetPEEntryPoint(IMethodSymbolInternal method, DiagnosticBag diagnostics) { Debug.Assert(method == null || IsSourceDefinition(method)); Debug.Assert(OutputKind.IsApplication()); PEEntryPoint = Translate(method, diagnostics, needDeclaration: true); }
internal sealed override Cci.IMethodReference Translate( IMethodSymbolInternal symbol, DiagnosticBag diagnostics, bool needDeclaration ) { return(Translate((TMethodSymbol)symbol, diagnostics, needDeclaration)); }
private void ReportMissingStateMachineAttribute(DiagnosticBag diagnostics, IMethodSymbolInternal method, string stateMachineAttributeFullName) { diagnostics.Add(MessageProvider.CreateDiagnostic( MessageProvider.ERR_EncUpdateFailedMissingAttribute, method.Locations.First(), MessageProvider.GetErrorDisplayString(method.GetISymbol()), stateMachineAttributeFullName)); }
public MappedMethod( IMethodSymbolInternal previousMethod, Func <SyntaxNode, SyntaxNode?>?syntaxMap ) { PreviousMethod = previousMethod; SyntaxMap = syntaxMap; }
private static string GetMethodName(IMethodSymbolInternal methodSymbol) { IMethodSymbol iMethod = (IMethodSymbol)methodSymbol.GetISymbol(); var format = (iMethod.MethodKind == MethodKind.UserDefinedOperator) ? _testDataOperatorKeyFormat : _testDataKeyFormat; return(iMethod.ToDisplayString(format)); }
public void SetMethodBody(IMethodSymbolInternal methodSymbol, Cci.IMethodBody body) { Debug.Assert(methodSymbol.ContainingModule == CommonSourceModule); Debug.Assert(methodSymbol.IsDefinition); Debug.Assert(((IMethodSymbol)methodSymbol.GetISymbol()).PartialDefinitionPart == null); // Must be definition. Debug.Assert(body == null || (object)methodSymbol == body.MethodDefinition); _methodBodyMap.Add(methodSymbol, body); }
public EncVariableSlotAllocator( SymbolMatcher symbolMap, Func <SyntaxNode, SyntaxNode?>?syntaxMap, IMethodSymbolInternal previousTopLevelMethod, DebugId methodId, ImmutableArray <EncLocalInfo> previousLocals, IReadOnlyDictionary <int, KeyValuePair <DebugId, int> >?lambdaMap, IReadOnlyDictionary <int, DebugId>?closureMap, string?stateMachineTypeName, int hoistedLocalSlotCount, IReadOnlyDictionary <EncHoistedLocalInfo, int>?hoistedLocalSlots, int awaiterCount, IReadOnlyDictionary <Cci.ITypeReference, int>?awaiterMap, IReadOnlyDictionary <int, int>?stateMachineStateMap, int?firstUnusedIncreasingStateMachineState, int?firstUnusedDecreasingStateMachineState, LambdaSyntaxFacts lambdaSyntaxFacts) { Debug.Assert(!previousLocals.IsDefault); _symbolMap = symbolMap; _syntaxMap = syntaxMap; _previousLocals = previousLocals; _previousTopLevelMethod = previousTopLevelMethod; _methodId = methodId; _hoistedLocalSlots = hoistedLocalSlots; _hoistedLocalSlotCount = hoistedLocalSlotCount; _stateMachineTypeName = stateMachineTypeName; _awaiterCount = awaiterCount; _awaiterMap = awaiterMap; _stateMachineStateMap = stateMachineStateMap; _lambdaMap = lambdaMap; _closureMap = closureMap; _lambdaSyntaxFacts = lambdaSyntaxFacts; _firstUnusedIncreasingStateMachineState = firstUnusedIncreasingStateMachineState; _firstUnusedDecreasingStateMachineState = firstUnusedDecreasingStateMachineState; // Create a map from local info to slot. var previousLocalInfoToSlot = new Dictionary <EncLocalInfo, int>(); for (int slot = 0; slot < previousLocals.Length; slot++) { var localInfo = previousLocals[slot]; Debug.Assert(!localInfo.IsDefault); if (localInfo.IsUnused) { // Unrecognized or deleted local. continue; } previousLocalInfoToSlot.Add(localInfo, slot); } _previousLocalSlots = previousLocalInfoToSlot; }
private readonly IReadOnlyDictionary <int, DebugId> _closureMapOpt; // SyntaxOffset -> Id public EncVariableSlotAllocator( CommonMessageProvider messageProvider, SymbolMatcher symbolMap, Func <SyntaxNode, SyntaxNode> syntaxMapOpt, IMethodSymbolInternal previousTopLevelMethod, DebugId methodId, ImmutableArray <EncLocalInfo> previousLocals, IReadOnlyDictionary <int, KeyValuePair <DebugId, int> > lambdaMapOpt, IReadOnlyDictionary <int, DebugId> closureMapOpt, string stateMachineTypeNameOpt, int hoistedLocalSlotCount, IReadOnlyDictionary <EncHoistedLocalInfo, int> hoistedLocalSlotsOpt, int awaiterCount, IReadOnlyDictionary <Cci.ITypeReference, int> awaiterMapOpt) { Debug.Assert(messageProvider != null); Debug.Assert(symbolMap != null); Debug.Assert(previousTopLevelMethod != null); Debug.Assert(!previousLocals.IsDefault); _messageProvider = messageProvider; _symbolMap = symbolMap; _syntaxMapOpt = syntaxMapOpt; _previousLocals = previousLocals; _previousTopLevelMethod = previousTopLevelMethod; _methodId = methodId; _hoistedLocalSlotsOpt = hoistedLocalSlotsOpt; _hoistedLocalSlotCount = hoistedLocalSlotCount; _stateMachineTypeNameOpt = stateMachineTypeNameOpt; _awaiterCount = awaiterCount; _awaiterMapOpt = awaiterMapOpt; _lambdaMapOpt = lambdaMapOpt; _closureMapOpt = closureMapOpt; // Create a map from local info to slot. var previousLocalInfoToSlot = new Dictionary <EncLocalInfo, int>(); for (int slot = 0; slot < previousLocals.Length; slot++) { var localInfo = previousLocals[slot]; Debug.Assert(!localInfo.IsDefault); if (localInfo.IsUnused) { // Unrecognized or deleted local. continue; } previousLocalInfoToSlot.Add(localInfo, slot); } _previousLocalSlots = previousLocalInfoToSlot; }
public EncVariableSlotAllocator( CommonMessageProvider messageProvider, SymbolMatcher symbolMap, Func<SyntaxNode, SyntaxNode> syntaxMapOpt, IMethodSymbolInternal previousTopLevelMethod, DebugId methodId, ImmutableArray<EncLocalInfo> previousLocals, IReadOnlyDictionary<int, KeyValuePair<DebugId, int>> lambdaMapOpt, IReadOnlyDictionary<int, DebugId> closureMapOpt, string stateMachineTypeNameOpt, int hoistedLocalSlotCount, IReadOnlyDictionary<EncHoistedLocalInfo, int> hoistedLocalSlotsOpt, int awaiterCount, IReadOnlyDictionary<Cci.ITypeReference, int> awaiterMapOpt) { Debug.Assert(messageProvider != null); Debug.Assert(symbolMap != null); Debug.Assert(previousTopLevelMethod != null); Debug.Assert(!previousLocals.IsDefault); _messageProvider = messageProvider; _symbolMap = symbolMap; _syntaxMapOpt = syntaxMapOpt; _previousLocals = previousLocals; _previousTopLevelMethod = previousTopLevelMethod; _methodId = methodId; _hoistedLocalSlotsOpt = hoistedLocalSlotsOpt; _hoistedLocalSlotCount = hoistedLocalSlotCount; _stateMachineTypeNameOpt = stateMachineTypeNameOpt; _awaiterCount = awaiterCount; _awaiterMapOpt = awaiterMapOpt; _lambdaMapOpt = lambdaMapOpt; _closureMapOpt = closureMapOpt; // Create a map from local info to slot. var previousLocalInfoToSlot = new Dictionary<EncLocalInfo, int>(); for (int slot = 0; slot < previousLocals.Length; slot++) { var localInfo = previousLocals[slot]; Debug.Assert(!localInfo.IsDefault); if (localInfo.IsUnused) { // Unrecognized or deleted local. continue; } previousLocalInfoToSlot.Add(localInfo, slot); } _previousLocalSlots = previousLocalInfoToSlot; }
internal Cci.IMethodBody GetMethodBody(IMethodSymbolInternal methodSymbol) { Debug.Assert(methodSymbol.ContainingModule == CommonSourceModule); Debug.Assert(methodSymbol.IsDefinition); Debug.Assert(((IMethodSymbol)methodSymbol.GetISymbol()).PartialDefinitionPart == null); // Must be definition. Cci.IMethodBody body; if (_methodBodyMap.TryGetValue(methodSymbol, out body)) { return(body); } return(null); }
public MappedMethod(IMethodSymbolInternal previousMethodOpt, Func<SyntaxNode, SyntaxNode> syntaxMap) { this.PreviousMethod = previousMethodOpt; this.SyntaxMap = syntaxMap; }
public MethodUpdate(IMethodSymbolInternal previousMethod, bool preserveLocalVariables, Func <SyntaxNode, SyntaxNode> syntaxMap) { this.PreviousMethod = previousMethod; this.PreserveLocalVariables = preserveLocalVariables; this.SyntaxMap = syntaxMap; }
public MethodUpdate(IMethodSymbolInternal previousMethod, bool preserveLocalVariables, Func<SyntaxNode, SyntaxNode> syntaxMap) { this.PreviousMethod = previousMethod; this.PreserveLocalVariables = preserveLocalVariables; this.SyntaxMap = syntaxMap; }
public MappedMethod(IMethodSymbolInternal previousMethodOpt, Func <SyntaxNode, SyntaxNode> syntaxMap) { this.PreviousMethod = previousMethodOpt; this.SyntaxMap = syntaxMap; }
public MethodData(ILBuilder ilBuilder, IMethodSymbolInternal method) { this.ILBuilder = ilBuilder; this.Method = method; }
private bool IsSourceDefinition(IMethodSymbolInternal method) { return(method.ContainingModule == CommonSourceModule && method.IsDefinition); }
internal VariableSlotAllocator?TryCreateVariableSlotAllocator(EmitBaseline baseline, Compilation compilation, IMethodSymbolInternal method, IMethodSymbolInternal topLevelMethod, DiagnosticBag diagnostics) { // Top-level methods are always included in the semantic edit list. Lambda methods are not. if (!mappedMethods.TryGetValue(topLevelMethod, out var mappedMethod)) { return(null); } // TODO (bug https://github.com/dotnet/roslyn/issues/2504): // Handle cases when the previous method doesn't exist. if (!TryGetMethodHandle(baseline, (Cci.IMethodDefinition)method.GetCciAdapter(), out var previousHandle)) { // Unrecognized method. Must have been added in the current compilation. return(null); } ImmutableArray <EncLocalInfo> previousLocals; IReadOnlyDictionary <EncHoistedLocalInfo, int>? hoistedLocalMap = null; IReadOnlyDictionary <Cci.ITypeReference, int>? awaiterMap = null; IReadOnlyDictionary <int, KeyValuePair <DebugId, int> >?lambdaMap = null; IReadOnlyDictionary <int, DebugId>?closureMap = null; IReadOnlyDictionary <int, int>? stateMachineStateMap = null; int?firstUnusedIncreasingStateMachineState = null; int?firstUnusedDecreasingStateMachineState = null; int hoistedLocalSlotCount = 0; int awaiterSlotCount = 0; string? stateMachineTypeName = null; SymbolMatcher symbolMap; int methodIndex = MetadataTokens.GetRowNumber(previousHandle); DebugId methodId; // Check if method has changed previously. If so, we already have a map. if (baseline.AddedOrChangedMethods.TryGetValue(methodIndex, out var addedOrChangedMethod)) { methodId = addedOrChangedMethod.MethodId; MakeLambdaAndClosureMaps(addedOrChangedMethod.LambdaDebugInfo, addedOrChangedMethod.ClosureDebugInfo, out lambdaMap, out closureMap); MakeStateMachineStateMap(addedOrChangedMethod.StateMachineStates.States, out stateMachineStateMap); firstUnusedIncreasingStateMachineState = addedOrChangedMethod.StateMachineStates.FirstUnusedIncreasingStateMachineState; firstUnusedDecreasingStateMachineState = addedOrChangedMethod.StateMachineStates.FirstUnusedDecreasingStateMachineState; if (addedOrChangedMethod.StateMachineTypeName != null) { // method is async/iterator kickoff method GetStateMachineFieldMapFromPreviousCompilation( addedOrChangedMethod.StateMachineHoistedLocalSlotsOpt, addedOrChangedMethod.StateMachineAwaiterSlotsOpt, out hoistedLocalMap, out awaiterMap); hoistedLocalSlotCount = addedOrChangedMethod.StateMachineHoistedLocalSlotsOpt.Length; awaiterSlotCount = addedOrChangedMethod.StateMachineAwaiterSlotsOpt.Length; // Kickoff method has no interesting locals on its own. // We use the EnC method debug information for hoisted locals. previousLocals = ImmutableArray <EncLocalInfo> .Empty; stateMachineTypeName = addedOrChangedMethod.StateMachineTypeName; } else { previousLocals = addedOrChangedMethod.Locals; } // All types that AddedOrChangedMethodInfo refers to have been mapped to the previous generation. // Therefore we don't need to fall back to metadata if we don't find the type reference, like we do in DefinitionMap.MapReference. symbolMap = MapToPreviousSymbolMatcher; } else { // Method has not changed since initial generation. Generate a map // using the local names provided with the initial metadata. EditAndContinueMethodDebugInformation debugInfo; StandaloneSignatureHandle localSignature; try { debugInfo = baseline.DebugInformationProvider(previousHandle); localSignature = baseline.LocalSignatureProvider(previousHandle); } catch (Exception e) when(e is InvalidDataException || e is IOException) { diagnostics.Add(MessageProvider.CreateDiagnostic( MessageProvider.ERR_InvalidDebugInfo, method.Locations.First(), method, MetadataTokens.GetToken(previousHandle), method.ContainingAssembly )); return(null); } methodId = new DebugId(debugInfo.MethodOrdinal, 0); if (!debugInfo.Lambdas.IsDefaultOrEmpty) { MakeLambdaAndClosureMaps(debugInfo.Lambdas, debugInfo.Closures, out lambdaMap, out closureMap); } MakeStateMachineStateMap(debugInfo.StateMachineStates, out stateMachineStateMap); if (!debugInfo.StateMachineStates.IsDefaultOrEmpty) { firstUnusedIncreasingStateMachineState = debugInfo.StateMachineStates.Max(s => s.StateNumber) + 1; firstUnusedDecreasingStateMachineState = debugInfo.StateMachineStates.Min(s => s.StateNumber) - 1; } ITypeSymbolInternal?stateMachineType = TryGetStateMachineType(previousHandle); if (stateMachineType != null) { // method is async/iterator kickoff method var localSlotDebugInfo = debugInfo.LocalSlots.NullToEmpty(); GetStateMachineFieldMapFromMetadata(stateMachineType, localSlotDebugInfo, out hoistedLocalMap, out awaiterMap, out awaiterSlotCount); hoistedLocalSlotCount = localSlotDebugInfo.Length; // Kickoff method has no interesting locals on its own. // We use the EnC method debug information for hoisted locals. previousLocals = ImmutableArray <EncLocalInfo> .Empty; stateMachineTypeName = stateMachineType.Name; } else { // If the current method is async/iterator then either the previous method wasn't declared as async/iterator and it's updated to be one, // or it was but is not marked by the corresponding state machine attribute because it was missing in the compilation. // In the later case we need to report an error since we don't known how to map to the previous state machine. // The IDE already checked that the attribute type is present in the base compilation, but didn't validate that it is well-formed. // We don't have the base compilation to directly query for the attribute, only the source compilation. // But since constructor signatures can't be updated during EnC we can just check the current compilation. if (method.IsAsync) { if (compilation.CommonGetWellKnownTypeMember(WellKnownMember.System_Runtime_CompilerServices_AsyncStateMachineAttribute__ctor) == null) { ReportMissingStateMachineAttribute(diagnostics, method, AttributeDescription.AsyncStateMachineAttribute.FullName); return(null); } } else if (method.IsIterator) { if (compilation.CommonGetWellKnownTypeMember(WellKnownMember.System_Runtime_CompilerServices_IteratorStateMachineAttribute__ctor) == null) { ReportMissingStateMachineAttribute(diagnostics, method, AttributeDescription.IteratorStateMachineAttribute.FullName); return(null); } } try { previousLocals = localSignature.IsNil ? ImmutableArray <EncLocalInfo> .Empty : GetLocalSlotMapFromMetadata(localSignature, debugInfo); } catch (Exception e) when(e is UnsupportedSignatureContent || e is BadImageFormatException || e is IOException) { diagnostics.Add(MessageProvider.CreateDiagnostic( MessageProvider.ERR_InvalidDebugInfo, method.Locations.First(), method, MetadataTokens.GetToken(localSignature), method.ContainingAssembly )); return(null); } } symbolMap = MapToMetadataSymbolMatcher; } return(new EncVariableSlotAllocator( symbolMap, mappedMethod.SyntaxMap, mappedMethod.PreviousMethod, methodId, previousLocals, lambdaMap, closureMap, stateMachineTypeName, hoistedLocalSlotCount, hoistedLocalMap, awaiterSlotCount, awaiterMap, stateMachineStateMap, firstUnusedIncreasingStateMachineState, firstUnusedDecreasingStateMachineState, GetLambdaSyntaxFacts())); }
internal void SetMethodTestData(IMethodSymbolInternal method, ILBuilder builder) { TestData.Add(method, new CompilationTestData.MethodData(builder, method)); }
internal abstract Cci.IMethodReference Translate(IMethodSymbolInternal symbol, DiagnosticBag diagnostics, bool needDeclaration);