internal EnvDTE.CodeParameter AddParameter(EnvDTE.CodeElement parent, SyntaxNode containerNode, string name, object type, object position) { var typeSymbol = CodeModelService.GetTypeSymbol(type, this.GetSemanticModel(), containerNode.SpanStart); var typeName = typeSymbol.GetEscapedFullName(); var parameterNode = CodeModelService.CreateParameterNode(CodeModelService.GetUnescapedName(name), typeName); var insertionIndex = CodeModelService.PositionVariantToParameterInsertionIndex(position, containerNode, fileCodeModel: this); var newNode = InsertParameter(containerNode, parameterNode, insertionIndex); // Since parameters form part of the NodeKey for functions, delegates, and indexers, // creating a CodeParameter hooked up to the correct parent is a little tricky. After // the call to InsertParameter, the syntax tree has been updated, but not the NodeKey // map or the NodeKey in the parent CodeParameter. If we delegate the creation of the // CodeParameter to CodeModelService.CreateInternalCodeElement, it will attempt to // look up an element in the NodeKey map based on the new syntax tree. This will fail, // causing it to create a new, duplicate element for the parent. Later, when we // reacquire the NodeKeys, the original element will get the proper NodeKey, while the // duplicate will be updated to a meaningless NodeKey. Since the duplicate is the one // being used by the CodeParameter, most operations on it will then fail. // Instead, we need to have the parent passed in to us. var parentObj = ComAggregate.GetManagedObject <AbstractCodeMember>(parent); return(CodeParameter.Create(this.State, parentObj, CodeModelService.GetParameterName(newNode))); }