/// <summary> /// 获取类的所有Property信息 /// </summary> /// <param name="codeClass"></param> /// <param name="isRecursive">是否递归获取父类的信息</param> /// <returns></returns> public static List <CodeProperty2> GetCodeProperty2s(CodeClass2 codeClass, bool isRecursive = false) { List <CodeProperty2> list = new List <CodeProperty2>(); //获取基类的属性信息 if (isRecursive && codeClass.Bases.Count > 0) { var baseElements = codeClass.Bases as CodeElements; if (baseElements != null) { CodeClass2 clazz = GetCodeClass2(baseElements); list.AddRange(GetCodeProperty2s(clazz)); } } //获取当前类的属性 foreach (CodeElement prop in codeClass.Members) { if (prop.Kind == vsCMElement.vsCMElementProperty) { CodeProperty2 p = prop as CodeProperty2; list.Add(p); } else if (prop.Kind == vsCMElement.vsCMElementVariable) { CodeVariable2 v = prop as CodeVariable2; } else { Console.WriteLine("" + prop.Kind); } } return(list); }
public CodeMember(CodeElement2 element, CodeElement2 type, Language language) { this.element = element; this.TypeElement = type; this.language = language; this.Name = element.Name; this.RequiresSeparatorLine = element.Kind != vsCMElement.vsCMElementVariable; switch (element.Kind) { case vsCMElement.vsCMElementFunction: CodeFunction2 function = (CodeFunction2)element; MemberKind kind; switch (function.FunctionKind) { case vsCMFunction.vsCMFunctionConstructor: kind = MemberKind.Constructor; break; case vsCMFunction.vsCMFunctionDestructor: kind = MemberKind.Destructor; break; case vsCMFunction.vsCMFunctionOperator: kind = MemberKind.Operator; break; default: kind = MemberKind.Function; break; } this.Initialize( kind, function.Access, function.IsShared, function.OverrideKind, functionKind: function.FunctionKind, parameters: function.Parameters); break; case vsCMElement.vsCMElementProperty: CodeProperty2 property = (CodeProperty2)element; this.Initialize(MemberKind.Property, property.Access, property.IsShared, property.OverrideKind, parameters: property.Parameters); break; case vsCMElement.vsCMElementVariable: CodeVariable2 variable = (CodeVariable2)element; this.Initialize(MemberKind.Variable, variable.Access, variable.IsShared, constKind: variable.ConstKind); break; case vsCMElement.vsCMElementEvent: CodeEvent evt = (CodeEvent)element; this.Initialize(MemberKind.Event, evt.Access, evt.IsShared, evt.OverrideKind); break; default: throw new NotSupportedException("Unsupported element kind: " + element.Kind); } }
public void initialize_constructor() { TextSelection selection = studio.ActiveDocument.Selection as TextSelection; CodeClass2 class_object = (CodeClass2)selection.ActivePoint.get_CodeElement(vsCMElement.vsCMElementClass); CodeFunction2 constructor = class_object.AddFunction(class_object.Name, vsCMFunction.vsCMFunctionConstructor, vsCMTypeRef.vsCMTypeRefVoid, -1, vsCMAccess.vsCMAccessPublic, 0) as CodeFunction2; string text = ""; foreach (CodeElement2 member in class_object.Members) { if (member.Kind == vsCMElement.vsCMElementVariable) { CodeVariable2 variable = member as CodeVariable2; CodeParameter2 parameter = constructor.AddParameter("new_" + variable.Name, variable.Type, -1) as CodeParameter2; text += "\r\n" + variable.Name + " = " + parameter.Name + ";"; } else if (member.Kind == vsCMElement.vsCMElementProperty) { var variable = member as CodeProperty; // CodeTypeRef new_type = CodeParameter2 parameter = constructor.AddParameter("new_" + variable.Name, variable.Type, -1) as CodeParameter2; text += "\r\n" + variable.Name + " = " + parameter.Name + ";"; } } EditPoint2 point = constructor.EndPoint.CreateEditPoint() as EditPoint2; point.LineUp(1); point.Insert(text); selection.MoveToPoint(constructor.StartPoint, false); selection.MoveToPoint(constructor.EndPoint, true); selection.SmartFormat(); selection.MoveToPoint(point, false); }
/// <summary> /// Implements the variable. /// </summary> /// <param name="instance">The instance.</param> /// <param name="name">The name.</param> /// <param name="type">The type.</param> /// <param name="isReadOnly">if set to <c>true</c> [is read only].</param> /// <returns>The Code Variable. </returns> public static CodeVariable ImplementVariable( this CodeClass instance, string name, string type, bool isReadOnly) { TraceService.WriteLine("CodeClassExtensions::ImplementVariable name=" + name + " type=" + type); CodeVariable codeVariable = instance.AddVariable(name, type, 0, vsCMAccess.vsCMAccessPrivate, 0); codeVariable.DocComment = "<doc><summary>\r\nBacking field for " + name + ".\r\n</summary></doc>"; codeVariable.GetEndPoint().CreateEditPoint().InsertNewLine(); if (isReadOnly) { CodeVariable2 codeVariable2 = codeVariable as CodeVariable2; if (codeVariable2 != null) { codeVariable2.ConstKind = vsCMConstKind.vsCMConstKindReadOnly; } } return(codeVariable); }
/// <summary> /// Returns class, struct or module, where given variable in defined /// </summary> public static CodeElement2 GetClass(this CodeVariable2 codeVariable) { if (codeVariable == null) { throw new ArgumentNullException("codeVariable"); } CodeElement2 parent = codeVariable.Parent as CodeElement2; return(GetClassInternal(parent)); }
/// <summary> /// Obtains a reflection wrapper for a field. /// </summary> /// <param name="target">The field, or null if none.</param> /// <returns>The reflection wrapper, or null if none.</returns> public StaticFieldWrapper Wrap(CodeVariable2 target) { if (target == null) { return(null); } StaticDeclaredTypeWrapper declaringType = MakeDeclaredType(GetContainingType((CodeElement)target)); return(new StaticFieldWrapper(this, target, declaringType, declaringType)); }
public static void GeneratePropertyFromVariable(CodeVariable2 variable, bool generateGetter, bool generateSetter, bool generateComments) { CodeClass2 codeClass = variable.Collection.Parent as CodeClass2; CodeGenerator codeGenerator = CreateCodeGenerator(codeClass.Language); string propertyName = ConvertVariableNameToPropertyName(variable.Name); if (!ContainsMember(codeClass, propertyName)) { string getterName = String.Empty; string setterName = String.Empty; if (generateGetter) { getterName = propertyName; } if (generateSetter) { setterName = propertyName; } CodeProperty property = (CodeProperty)codeClass.AddProperty(getterName, setterName, variable.Type, -1, vsCMAccess.vsCMAccessPublic, null); if (generateComments) { StringBuilder sb = new StringBuilder(); sb.AppendLine("<doc>"); sb.AppendLine("<summary>"); sb.AppendLine(); sb.AppendLine("</summary>"); sb.Append("</doc>"); property.DocComment = sb.ToString(); } if (generateGetter) { EditPoint2 editPoint = (EditPoint2)property.Getter.GetStartPoint(vsCMPart.vsCMPartBody).CreateEditPoint(); editPoint.EndOfLine(); int position = editPoint.LineCharOffset; editPoint.StartOfLine(); editPoint.Delete(position); editPoint.Insert(codeGenerator.GenerateReturnStatement(variable.Name)); editPoint.SmartFormat(editPoint); } if (generateSetter) { EditPoint2 editPoint = (EditPoint2)property.Setter.GetStartPoint(vsCMPart.vsCMPartBody).CreateEditPoint(); editPoint.Insert(codeGenerator.GenerateAssignStatement(variable.Name, "value")); editPoint.SmartFormat(editPoint); } } }
private CodeDomConstantMetadata(CodeVariable2 codeVariable, CodeDomFileMetadata file) : base(codeVariable, file) { var initValue = codeVariable.InitExpression.ToString(); var value = initValue == "null" ? string.Empty : initValue; if (value.Length >= 2 && value.StartsWith("\"") && value.EndsWith("\"")) { Value = value.Substring(1, value.Length - 2).Replace("\\\"", "\""); } else { Value = value; } }
public static CodeVariable2[] GetVariables(CodeClass2 codeClass) { List <CodeVariable2> codeVariables = new List <CodeVariable2>(); foreach (CodeElement codeElement in codeClass.Members) { if (codeElement.Kind == vsCMElement.vsCMElementVariable) { CodeVariable2 codeVariable = codeElement as CodeVariable2; if (codeVariable != null && codeVariable.ConstKind == vsCMConstKind.vsCMConstKindNone) { codeVariables.Add(codeVariable); } } } return(codeVariables.ToArray()); }
/// <summary> /// Implements the variable. /// </summary> /// <param name="instance">The instance.</param> /// <param name="name">The name.</param> /// <param name="type">The type.</param> /// <param name="isReadOnly">if set to <c>true</c> [is read only].</param> /// <returns>The Code Variable. </returns> public static CodeVariable ImplementVariable( this CodeClass instance, string name, string type, bool isReadOnly) { TraceService.WriteLine("CodeClassExtensions::ImplementVariable name=" + name + " type=" + type); string variableName = name; bool placeHolderVariable = false; //// are we a place holder variable (used in snippets!) if (variableName.Contains("%")) { variableName = variableName.Replace("%", string.Empty); placeHolderVariable = true; } CodeVariable codeVariable = instance.AddVariable(variableName, type, 0, vsCMAccess.vsCMAccessPrivate, 0); codeVariable.DocComment = "<doc><summary>" + "\r\nBacking field for " + name + ".\r\n</summary></doc>"; codeVariable.GetEndPoint().CreateEditPoint().InsertNewLine(); if (isReadOnly) { CodeVariable2 codeVariable2 = codeVariable as CodeVariable2; if (codeVariable2 != null) { codeVariable2.ConstKind = vsCMConstKind.vsCMConstKindReadOnly; } } if (placeHolderVariable) { EditPoint startPoint = codeVariable.StartPoint.CreateEditPoint(); EditPoint endPoint = codeVariable.EndPoint.CreateEditPoint(); string text = startPoint.GetText(endPoint); string newText = text.Replace(variableName, name); startPoint.ReplaceText(endPoint, newText, 0); } return(codeVariable); }
public static void PrintVariable2Info(CodeVariable2 item) { return; Debug.WriteLine("--------PrintVariable2Info--------"); Debug.WriteLine("Rename Method.FullName:" + item.FullName); Debug.WriteLine("Rename Method.ConstKind :" + item.ConstKind); Debug.WriteLine("Rename Method.DocComment :" + item.DocComment); Debug.WriteLine("Rename Method.IsCodeType :" + item.IsCodeType); Debug.WriteLine("Rename Method.IsConstant :" + item.IsConstant); Debug.WriteLine("Rename Method.IsGeneric :" + item.IsGeneric); Debug.WriteLine("Rename Method.IsShared :" + item.IsShared); Debug.WriteLine("Rename Method.Kind :" + item.Kind); Debug.WriteLine("Rename Method.Prototype :" + item.Prototype); Debug.WriteLine("Rename Method.Type :" + item.Type); Debug.WriteLine("Rename Method.Name :" + item.Name); Debug.WriteLine("-----------------------------------"); }
public Dictionary <string, int> collectFields(CodeClass2 classItem) { Microsoft.VisualStudio.Shell.ThreadHelper.ThrowIfNotOnUIThread(); Dictionary <string, int> dict = new Dictionary <string, int>() { { "public", 0 }, { "private", 0 }, { "protected", 0 } }; debugPane.OutputString("\nClass fields: " + classItem.FullName + "\n"); foreach (CodeElement2 field in classItem.Members) { if (field.Kind == vsCMElement.vsCMElementVariable) { CodeVariable2 codeVariable = field as CodeVariable2; if (codeVariable.Access == vsCMAccess.vsCMAccessPublic) { debugPane.OutputString("\tpublic: \n"); debugPane.OutputString("\t\t " + codeVariable.FullName + "\n"); dict["public"]++; } else if (codeVariable.Access == vsCMAccess.vsCMAccessPrivate) { debugPane.OutputString("\tprivate: \n"); debugPane.OutputString("\t\t " + codeVariable.FullName + "\n"); dict["private"]++; } else if (codeVariable.Access == vsCMAccess.vsCMAccessProtected) { debugPane.OutputString("\tprotected: \n"); debugPane.OutputString("\t\t " + codeVariable.FullName + "\n"); dict["protected"]++; } } } return(dict); }
/// <summary> /// Returns inner text of the variable (modifiers, name and initializer) /// </summary> public static string GetText(this CodeVariable2 codeVariable) { if (codeVariable == null) { throw new ArgumentNullException("codeVariable"); } TextPoint startPoint = codeVariable.StartPoint; TextPoint endPoint = codeVariable.EndPoint; EditPoint ep = startPoint.CreateEditPoint(); if (ep == null) { return(null); } else { return(ep.GetText(endPoint)); } }
/// <summary> /// Explores given variable initializer using C# lookuper /// </summary> protected virtual void Explore(AbstractBatchCommand parentCommand, CodeVariable2 codeVariable, CodeNamespace parentNamespace, CodeElement2 codeClassOrStruct, Predicate <CodeElement> exploreable, bool isLocalizableFalse) { if (codeVariable.InitExpression == null) { return; // variable must have an initializer } if (codeClassOrStruct.Kind == vsCMElement.vsCMElementStruct && !codeVariable.IsShared) { return; // instance variable of structs cannot have initializers } if (!exploreable(codeVariable as CodeElement)) { return; // predicate must evaluate to true } string initExpression = codeVariable.GetText(); // get text of initializer if (string.IsNullOrEmpty(initExpression)) { return; } TextPoint startPoint = codeVariable.StartPoint; // is variable decorated with Localizable(false) bool variableLocalizableFalse = (codeVariable as CodeElement).HasLocalizableFalseAttribute(); // run lookuper using parent command var list = parentCommand.LookupInCSharp(initExpression, startPoint, parentNamespace, codeClassOrStruct, null, codeVariable.Name, isLocalizableFalse || variableLocalizableFalse); // add context to result items (surounding few lines of code) EditPoint2 editPoint = (EditPoint2)startPoint.CreateEditPoint(); foreach (AbstractResultItem item in list) { item.IsConst = codeVariable.ConstKind == vsCMConstKind.vsCMConstKindConst; item.CodeModelSource = codeVariable; AddContextToItem(item, editPoint); } }
/// <inheritdoc /> protected override FieldAttributes GetFieldAttributes(StaticFieldWrapper field) { CodeVariable2 fieldHandle = (CodeVariable2)field.Handle; // FIXME: Don't know how to handle vsCMAccessWithEvents FieldAttributes flags = 0; switch (fieldHandle.Access) { case vsCMAccess.vsCMAccessPublic: flags |= FieldAttributes.Public; break; case vsCMAccess.vsCMAccessPrivate: flags |= FieldAttributes.Private; break; case vsCMAccess.vsCMAccessDefault: case vsCMAccess.vsCMAccessProject: flags |= FieldAttributes.Assembly; break; case vsCMAccess.vsCMAccessProtected: flags |= FieldAttributes.Family; break; case vsCMAccess.vsCMAccessAssemblyOrFamily: case vsCMAccess.vsCMAccessProjectOrProtected: flags |= FieldAttributes.FamORAssem; break; } ReflectorFlagsUtils.AddFlagIfTrue(ref flags, FieldAttributes.Static, fieldHandle.IsShared); ReflectorFlagsUtils.AddFlagIfTrue(ref flags, FieldAttributes.InitOnly, fieldHandle.ConstKind == vsCMConstKind.vsCMConstKindReadOnly); ReflectorFlagsUtils.AddFlagIfTrue(ref flags, FieldAttributes.Literal, fieldHandle.ConstKind == vsCMConstKind.vsCMConstKindConst); return(flags); }
public static bool IsCodeElementPrivate(CodeElement codeElement) { switch (codeElement.Kind) { case vsCMElement.vsCMElementVariable: CodeVariable2 codeVariable = (CodeVariable2)codeElement; if (codeVariable.Access == vsCMAccess.vsCMAccessPrivate) { return(true); } break; case vsCMElement.vsCMElementFunction: CodeFunction2 codeFunction = (CodeFunction2)codeElement; if (codeFunction.Access == vsCMAccess.vsCMAccessPrivate) { return(true); } break; case vsCMElement.vsCMElementProperty: CodeProperty codeProperty = (CodeProperty)codeElement; if (codeProperty.Access == vsCMAccess.vsCMAccessPrivate) { return(true); } break; case vsCMElement.vsCMElementClass: CodeClass2 codeClass = (CodeClass2)codeElement; if (codeClass.Access == vsCMAccess.vsCMAccessPrivate) { return(true); } break; case vsCMElement.vsCMElementDelegate: CodeDelegate2 codeDelegate = (CodeDelegate2)codeElement; if (codeDelegate.Access == vsCMAccess.vsCMAccessPrivate) { return(true); } break; case vsCMElement.vsCMElementEvent: CodeEvent codeEvent = (CodeEvent)codeElement; if (codeEvent.Access == vsCMAccess.vsCMAccessPrivate) { return(true); } break; case vsCMElement.vsCMElementInterface: CodeInterface2 codeInterface = (CodeInterface2)codeElement; if (codeInterface.Access == vsCMAccess.vsCMAccessPrivate) { return(true); } break; case vsCMElement.vsCMElementStruct: CodeStruct2 codeStruct = (CodeStruct2)codeElement; if (codeStruct.Access == vsCMAccess.vsCMAccessPrivate) { return(true); } break; } return(false); }
/// <summary> /// Returns a flag indicating whether a CodeElement is a generic, /// and also returns the element's generic name. /// </summary> /// <param name="element">The CodeElement to test.</param> /// <param name="name">The returned generic name.</param> /// <returns>true if the delegate is a generic, otherwise false.</returns> public static bool IsGeneric(CodeElement element, out string name) { bool isGen = false; string postfix = null; if (element == null) { throw new ArgumentNullException("element"); } switch (element.Kind) { case vsCMElement.vsCMElementClass: CodeClass2 codeClass = element as CodeClass2; if ((codeClass != null) && codeClass.IsGeneric) { isGen = true; } break; //union declaration is used to represent variant types case vsCMElement.vsCMElementUnion: CodeClass2 codeVariant = element as CodeClass2; if ((codeVariant != null) && codeVariant.IsGeneric) { isGen = true; } break; case vsCMElement.vsCMElementInterface: CodeInterface2 codeInterface = element as CodeInterface2; if ((codeInterface != null) && codeInterface.IsGeneric) { isGen = true; } break; case vsCMElement.vsCMElementFunction: CodeFunction2 codeFunction = element as CodeFunction2; if ((codeFunction != null) && codeFunction.IsGeneric) { // Get information about the parameters, which is appended to the function name later. postfix = ExtractMethodParameters(codeFunction); isGen = true; } break; case vsCMElement.vsCMElementProperty: CodeProperty2 codeProperty = element as CodeProperty2; if ((codeProperty != null) && codeProperty.IsGeneric) { isGen = true; } break; case vsCMElement.vsCMElementVariable: CodeVariable2 codeVariable = element as CodeVariable2; if ((codeVariable != null) && codeVariable.IsGeneric) { isGen = true; } break; case vsCMElement.vsCMElementDelegate: CodeDelegate2 codeDelegate = element as CodeDelegate2; if ((codeDelegate != null) && codeDelegate.IsGeneric) { isGen = true; } break; } if (isGen) { // postfix is not null if the CodeElement is a generic function. name = ExtractGenericNameFromFullName(element) + postfix; } else { name = null; } return(isGen); }
public CodeVariableNodeFactory(CodeVariable2 element) : base(element as CodeElement) { _element = element; }
internal ShellCodeVariable(CodeVariable2 variable) : base(variable as CodeElement2) { _variable = variable; }
private CodeDomConstantMetadata(CodeVariable2 codeVariable, CodeDomFileMetadata file) : base(codeVariable, file) { }
public static ITypeMetadata FromCodeElement(CodeVariable2 codeVariable, CodeDomFileMetadata file) { return GetType(codeVariable, file); }
protected CodeDomFieldMetadata(CodeVariable2 codeVariable, CodeDomFileMetadata file) { this.codeVariable = codeVariable; this.file = file; }
public void Move(List <CodeStringResultItem> dataList, ref int errorRows) { // sort according to position dataList.Sort(new ResultItemsPositionCompararer <CodeStringResultItem>()); for (int i = dataList.Count - 1; i >= 0; i--) { try { // initialization of data CodeStringResultItem resultItem = dataList[i]; string path = resultItem.SourceItem.GetFullPath(); ReferenceString referenceText = null; bool addUsingBlock = false; CONTAINS_KEY_RESULT keyConflict = CONTAINS_KEY_RESULT.DOESNT_EXIST; if (resultItem.MoveThisItem) // row was checked in the toolwindow { Validate(resultItem); // check that key, value and destination item was specifed and that row has no errors if (!resultItem.DestinationItem.IsLoaded) { resultItem.DestinationItem.Load(); } if (!loadedResxItems.Contains(resultItem.DestinationItem)) { loadedResxItems.Add(resultItem.DestinationItem); } // check if such item already exists in destination file keyConflict = resultItem.DestinationItem.GetKeyConflictType(resultItem.Key, resultItem.Value, true); if (keyConflict == CONTAINS_KEY_RESULT.EXISTS_WITH_DIFF_VALUE) { throw new InvalidOperationException(string.Format("Key \"{0}\" already exists with different value.", resultItem.Key)); } resultItem.Key = resultItem.DestinationItem.GetRealKey(resultItem.Key); // if key already exists, return its name (solves case-sensitivity problems) NamespacesList usedNamespaces = GetUsedNamespacesFor(resultItem); if (UseFullName || resultItem.MustUseFullName || (resultItem.Language == LANGUAGE.VB && resultItem.DestinationItem.IsProjectDefault(resultItem.SourceItem.ContainingProject))) // reference will contain namespace { referenceText = new ReferenceString(resultItem.DestinationItem.Namespace, resultItem.DestinationItem.Class, resultItem.Key); addUsingBlock = false; // no using block will be added } else { // use resolver whether it is ok to add using block addUsingBlock = usedNamespaces.ResolveNewElement(resultItem.DestinationItem.Namespace, resultItem.DestinationItem.Class, resultItem.Key, resultItem.SourceItem.ContainingProject, out referenceText); } if (addUsingBlock) // new using block will be added { if (!usedNamespacesCache.ContainsKey(resultItem.SourceItem)) { usedNamespacesCache.Add(resultItem.SourceItem, new NamespacesList()); } foreach (var pair in usedNamespacesCache) { if (!pair.Value.ContainsNamespace(resultItem.DestinationItem.Namespace)) { pair.Value.Add(resultItem.DestinationItem.Namespace, null, true); } } } } if (RDTManager.IsFileOpen(path) && RDTManager.IsFileVisible(path)) // file is open { if (resultItem.MoveThisItem || (MarkUncheckedStringsWithComment && !resultItem.IsMarkedWithUnlocalizableComment)) // string literal in text will be modified (referenced or marked with comment) { if (!buffersCache.ContainsKey(path)) { // load file's buffer IVsTextLines textLines = DocumentViewsManager.GetTextLinesForFile(path, false); buffersCache.Add(path, textLines); IOleUndoManager m; // get file's undo manager int hr = textLines.GetUndoManager(out m); Marshal.ThrowExceptionForHR(hr); undoManagersCache.Add(path, m); } } if (resultItem.MoveThisItem) { // perform the text replacement MoveToResource(buffersCache[path], resultItem, referenceText); if (resultItem.IsConst && resultItem.CodeModelSource is CodeVariable2) { CodeVariable2 codeVar = (CodeVariable2)resultItem.CodeModelSource; codeVar.ConstKind = vsCMConstKind.vsCMConstKindNone; } if (addUsingBlock) { // add using block to the source file int beforeLines, afterLines; buffersCache[path].GetLineCount(out beforeLines); resultItem.AddUsingBlock(buffersCache[path]); buffersCache[path].GetLineCount(out afterLines); int diff = afterLines - beforeLines; // because of the previous step, it is necessary to adjust position of all not-yet referenced result items for (int j = i; j >= 0; j--) { var item = dataList[j]; if (item.SourceItem == resultItem.SourceItem) { TextSpan ts = new TextSpan(); ts.iEndIndex = item.ReplaceSpan.iEndIndex; ts.iEndLine = item.ReplaceSpan.iEndLine + diff; ts.iStartIndex = item.ReplaceSpan.iStartIndex; ts.iStartLine = item.ReplaceSpan.iStartLine + diff; item.ReplaceSpan = ts; } } } // previous step (replace and possibly new using block) caused undo unit to be added - remove it int unitsToRemoveCount = (resultItem.IsConst && addUsingBlock ? 3 : (resultItem.IsConst || addUsingBlock ? 2 : 1)); List <IOleUndoUnit> units = undoManagersCache[path].RemoveTopFromUndoStack(unitsToRemoveCount); // and add custom undo unit AbstractUndoUnit newUnit = null; if (keyConflict == CONTAINS_KEY_RESULT.DOESNT_EXIST) { newUnit = new MoveToResourcesUndoUnit(resultItem.Key, resultItem.Value, resultItem.DestinationItem); } else if (keyConflict == CONTAINS_KEY_RESULT.EXISTS_WITH_SAME_VALUE) { newUnit = new MoveToResourcesReferenceUndoUnit(resultItem.Key); } newUnit.AppendUnits.AddRange(units); undoManagersCache[path].Add(newUnit); } else if (MarkUncheckedStringsWithComment && !resultItem.IsMarkedWithUnlocalizableComment) // string literal should be marked with comment { AspNetStringResultItem aitem = resultItem as AspNetStringResultItem; // this operation is only possible if string literal comes from C# code if (resultItem is CSharpStringResultItem || (aitem != null && aitem.ComesFromCodeBlock && aitem.Language == LANGUAGE.CSHARP)) { // add the comment int c = MarkAsNoLoc(buffersCache[path], resultItem); // add undo unit List <IOleUndoUnit> units = undoManagersCache[path].RemoveTopFromUndoStack(1); MarkAsNotLocalizedStringUndoUnit newUnit = new MarkAsNotLocalizedStringUndoUnit(resultItem.Value); newUnit.AppendUnits.AddRange(units); undoManagersCache[path].Add(newUnit); } } } else // file is closed // same as with open file, only operating with text, not buffers { if (resultItem.MoveThisItem || (MarkUncheckedStringsWithComment && !resultItem.IsMarkedWithUnlocalizableComment)) // string literal will be modified // load file's text into the cache { if (!filesCache.ContainsKey(path)) { filesCache.Add(path, new StringBuilder(File.ReadAllText(path))); } } if (resultItem.IsConst && resultItem.CodeModelSource is CodeVariable2) { CodeVariable2 codeVar = (CodeVariable2)resultItem.CodeModelSource; fieldsToRemoveConst.Add(codeVar); } if (resultItem.MoveThisItem) { StringBuilder b = filesCache[path]; // perform the replacement string insertText = resultItem.GetReferenceText(referenceText); b.Remove(resultItem.AbsoluteCharOffset, resultItem.AbsoluteCharLength); b.Insert(resultItem.AbsoluteCharOffset, insertText); if (addUsingBlock) { // add using block if (!newUsingsPlan.ContainsKey(path)) { newUsingsPlan.Add(path, new List <string>()); } newUsingsPlan[path].Add(resultItem.DestinationItem.Namespace); } } else if (MarkUncheckedStringsWithComment && !resultItem.IsMarkedWithUnlocalizableComment) { AspNetStringResultItem aitem = resultItem as AspNetStringResultItem; if (resultItem is CSharpStringResultItem || (aitem != null && aitem.ComesFromCodeBlock && aitem.Language == LANGUAGE.CSHARP)) { StringBuilder b = filesCache[path]; b.Insert(resultItem.AbsoluteCharOffset, resultItem.NoLocalizationComment); } } } if (resultItem.MoveThisItem && keyConflict == CONTAINS_KEY_RESULT.DOESNT_EXIST) { if (!resultItem.DestinationItem.IsInBatchMode) { resultItem.DestinationItem.BeginBatch(); } // add the key to the ResX file resultItem.DestinationItem.AddString(resultItem.Key, resultItem.Value); } } catch (Exception ex) { errorRows++; VLOutputWindow.VisualLocalizerPane.WriteException(ex); } } // add using blocks to closed files texts foreach (var pair in newUsingsPlan) { foreach (string nmspc in pair.Value) { AddUsingBlockTo(pair.Key, nmspc); } } // flush closed files texts foreach (var pair in filesCache) { if (RDTManager.IsFileOpen(pair.Key)) { RDTManager.SetIgnoreFileChanges(pair.Key, true); File.WriteAllText(pair.Key, pair.Value.ToString()); RDTManager.SetIgnoreFileChanges(pair.Key, false); RDTManager.SilentlyReloadFile(pair.Key); } else { File.WriteAllText(pair.Key, pair.Value.ToString()); } } // remove 'const' modifier from fields in closed files HashSet <ProjectItem> itemsToSave = new HashSet <ProjectItem>(); foreach (CodeVariable2 codeVar in fieldsToRemoveConst) { codeVar.ConstKind = vsCMConstKind.vsCMConstKindNone; itemsToSave.Add(codeVar.ProjectItem); } foreach (ProjectItem item in itemsToSave) { item.Save(null); } foreach (ResXProjectItem item in loadedResxItems) { if (item.IsInBatchMode) { item.EndBatch(); } item.Unload(); } if (errorRows > 0) { throw new Exception("Error occured while processing some rows - see Output window for details."); } }
/// <summary> /// Used by C# ad-hoc methods (move and inline) to get information about the block of code, where right-click was performed. /// This methods makes use of document's FileCodeModel, which is not available for ASP .NET files - these files are thus /// handled by their own parser. /// </summary> /// <param name="text">Text of the block (e.g. code of a method, declaration of a variable...)</param> /// <param name="startPoint">Beginning of the text</param> /// <param name="codeFunctionName">Name of the function, where right-click was performed, null if right-click was performed on a variable.</param> /// <param name="codeVariableName">Name of the variable, where right-click was performed, null otherwise.</param> /// <param name="codeClass">Name of the class, where the code block is located.</param> /// <param name="selectionSpan">Current selection span.</param> /// <returns>True, if all necessary information was succesfully obtained, false otherwise.</returns> protected bool GetCodeBlockFromSelection(out string text, out TextPoint startPoint, out string codeFunctionName, out string codeVariableName, out CodeElement2 codeClass, out TextSpan selectionSpan, out bool isConst, out object codeModelSource) { // get current selection span TextSpan[] spans = new TextSpan[1]; int hr = textView.GetSelectionSpan(spans); Marshal.ThrowExceptionForHR(hr); selectionSpan = spans[0]; object o; hr = textLines.CreateTextPoint(selectionSpan.iStartLine, selectionSpan.iStartIndex, out o); Marshal.ThrowExceptionForHR(hr); TextPoint selectionPoint = (TextPoint)o; startPoint = null; text = null; bool ok = false; codeFunctionName = null; codeVariableName = null; codeClass = null; isConst = false; codeModelSource = null; // It is impossible to find out the code block, where right-click was performed. Following code // assumes that valid string literals or references can only be found in a method, in a class variable (as initializers) // or in a property code. C# syntax permits more locations (attributes, default argument values in .NET 4+) but we can ignore // these, because they are all evaluated at compile-time, making resource references impossible. // assume we are in a function (method) try { CodeFunction2 codeFunction = (CodeFunction2)currentCodeModel.CodeElementFromPoint(selectionPoint, vsCMElement.vsCMElementFunction); codeFunctionName = codeFunction.Name; codeClass = codeFunction.GetClass(); // extension codeModelSource = codeFunction; text = codeFunction.GetText(); if (!string.IsNullOrEmpty(text)) { startPoint = codeFunction.GetStartPoint(vsCMPart.vsCMPartBody); ok = true; } } catch (Exception) { // it's not a method - maybe a property? try { CodeProperty codeProperty = (CodeProperty)currentCodeModel.CodeElementFromPoint(selectionPoint, vsCMElement.vsCMElementProperty); codeFunctionName = codeProperty.Name; codeClass = codeProperty.GetClass(); codeModelSource = codeProperty; text = codeProperty.GetText(); if (!string.IsNullOrEmpty(text)) { startPoint = codeProperty.GetStartPoint(vsCMPart.vsCMPartBody); ok = true; } } catch (Exception) { // not a property, either. It must be a variable - or there's no valid code block try { CodeVariable2 codeVariable = (CodeVariable2)currentCodeModel.CodeElementFromPoint(selectionPoint, vsCMElement.vsCMElementVariable); if (codeVariable.InitExpression != null) { codeVariableName = codeVariable.Name; codeClass = codeVariable.GetClass(); isConst = codeVariable.ConstKind == vsCMConstKind.vsCMConstKindConst; codeModelSource = codeVariable; startPoint = codeVariable.StartPoint; text = codeVariable.GetText(); if ((codeClass.Kind == vsCMElement.vsCMElementStruct && codeVariable.IsShared) || (codeClass.Kind == vsCMElement.vsCMElementClass || codeClass.Kind == vsCMElement.vsCMElementModule) && !string.IsNullOrEmpty(text)) { ok = true; } } } catch (Exception) { return(false); } } } return(ok); }
private static void GetPropertiesInfo(CodeClass2 codeClass, string modelName, ref string sql, ref string keyConstrait, ref string descriptions) { //获取基类信息 if (codeClass.Bases.Count > 0) { var baseElements = codeClass.Bases as CodeElements; if (baseElements != null) { foreach (CodeElement2 baseEle in baseElements) { //查找命名空间 if (baseEle.Kind == vsCMElement.vsCMElementClass) { CodeClass2 clazz = baseEle as CodeClass2; GetPropertiesInfo(clazz, modelName, ref sql, ref keyConstrait, ref descriptions); } } } } //定位到属性 foreach (CodeElement prop in codeClass.Members) { if (prop.Kind == vsCMElement.vsCMElementProperty) { //去掉需要忽略的列 if (IgnoreFieldList.Any(t => t == prop.Name)) { continue; } CodeProperty2 p = prop as CodeProperty2; string rawTypeName = p.Type.AsFullName; string rawDocComment = p.DocComment; //描述信息 bool isPrimaryKey = false; //是否需要跳过 bool isSkipProperty = false; // 字段描述 string desc = ""; int maxLength = DefaultStringLength; int maxAttrLen = DefaultStringLength; int minAttrLen = DefaultStringLength; int maxStrLen = DefaultStringLength; int minStrLen = DefaultStringLength; //定位自定义属性信息 foreach (CodeAttribute2 attr in p.Attributes) { //属性是否有标记最大或者最小长度、字符串长度 if (attr.Name == "MaxLength") { //500, ErrorMessage = "最大长度是500啊" foreach (CodeAttributeArgument attrArg in attr.Arguments) { if (attrArg.Name == "" || attrArg.Name == "MaximumLength") { //第一个没有名称的参数为最大长度 maxAttrLen = Convert.ToInt32(attrArg.Value); } else if (attrArg.Name == "ErrorMessage") { //错误描述 } } } else if (attr.Name == "MinLength") { foreach (CodeAttributeArgument attrArg in attr.Arguments) { if (attrArg.Name == "" || attrArg.Name == "MinimumLength") { //第一个没有名称的参数为最小长度 minAttrLen = Convert.ToInt32(attrArg.Value); } else if (attrArg.Name == "ErrorMessage") { //错误描述 } } } else if (attr.Name == "StringLength") { foreach (CodeAttributeArgument attrArg in attr.Arguments) { if (attrArg.Name == "" || attrArg.Name == "MaximumLength") { //第一个没有名称的参数为最大长度 maxStrLen = Convert.ToInt32(attrArg.Value); } else if (attrArg.Name == "MinimumLength") { //第一个没有名称的参数为最大长度 minStrLen = Convert.ToInt32(attrArg.Value); } else if (attrArg.Name == "ErrorMessage") { //错误描述 } } } else if (attr.Name == "Display") { foreach (CodeAttributeArgument attrArg in attr.Arguments) { if (attrArg.Name == "Name") { desc = attrArg.Value.Trim('"'); break; } } } else if (IgnoreAttributeList.Any(x => x == attr.Name)) { //如果是需要忽略的字段,则跳过 isSkipProperty = true; break; } else if (attr.Name == "Key") { //如果是Key属性,则认为其是主键 isPrimaryKey = true; keyConstrait = @" CONSTRAINT [PK_" + prop.Name + @"] PRIMARY KEY CLUSTERED" + "(" + " [" + prop.Name + @"] ASC" + " )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]"; } } //如果需要跳过,则跳过 if (isSkipProperty) { continue; } //根据长度约束条件获取最大长度 maxLength = Math.Max(maxStrLen, Math.Max(minAttrLen, maxLength)); //描述信息以Display为准 desc = string.IsNullOrEmpty(desc) ? Utility.GetCommentFromXMLString(rawDocComment) : desc; desc = isPrimaryKey ? "主键 " + desc : desc; //属性名称 sql += " [" + prop.Name + "] " + GetSQLType(rawTypeName, maxLength) + "," + Environment.NewLine; //如果描述信息不为空,则添加描述信息 if (!string.IsNullOrEmpty(desc)) { descriptions += (Environment.NewLine + @"EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'" + desc + "' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'" + modelName + "', @level2type=N'COLUMN',@level2name=N'" + prop.Name + "'") + Environment.NewLine + "GO"; } } else if (prop.Kind == vsCMElement.vsCMElementVariable) { CodeVariable2 v = prop as CodeVariable2; } else { Console.WriteLine("" + prop.Kind); } } }
/// <inheritdoc /> protected override StaticTypeWrapper GetFieldType(StaticFieldWrapper field) { CodeVariable2 fieldHandle = (CodeVariable2)field.Handle; return(MakeType(fieldHandle.Type)); }
private string RenameAttr(CodeElement item) { //var sb = new StringBuilder(); //try //{ if (item.Kind == vsCMElement.vsCMElementVariable || item.Kind == vsCMElement.vsCMElementParameter || item.Kind == vsCMElement.vsCMElementProperty) { if (item.Name.Contains(alien)) { PrintDetial("AttrNameHasAlien :" + item.Name); return(""); } if (item.Name.Contains(stringThis)) { PrintDetial("AttrNameHasThis :" + item.Name); return(""); } if (item.Name.Contains(stringGlobal)) { PrintDetial("GlobalAttr :" + item.Name); return(""); } if (interFaceFunction.Contains(item.Name)) { PrintDetial("InterFaceAttr :" + item.Name); return(""); } CodeProperty2 CodeProperty = item as CodeProperty2; if (CodeProperty != null && CodeProperty.OverrideKind != null && (CodeProperty.OverrideKind == vsCMOverrideKind.vsCMOverrideKindOverride || CodeProperty.OverrideKind == vsCMOverrideKind.vsCMOverrideKindNew || CodeProperty.OverrideKind == vsCMOverrideKind.vsCMOverrideKindAbstract || CodeProperty.OverrideKind == vsCMOverrideKind.vsCMOverrideKindVirtual)) { PrintDetial("AttrIsSpecial :" + item.Name); return(""); } CodeVariable2 codeVariable = item as CodeVariable2; if ((CodeProperty != null && CodeProperty.IsShared) || (codeVariable != null && codeVariable.IsShared)) { PrintDetial("StaticAttr :" + item.Name); return(""); } try { CodeElement2 code2 = item as CodeElement2; var one = nameCounter++; var alien2 = alien + nameCounter++; var three = nameCounter++; PrintDetial("RenameAttribute :" + item.Name); var randomOne = GetRandomName(3, 5, useUpper: true); var randomThree = GetRandomName(3, 5, useUpper: true); var replacement = string.Format("{0}{1}{2}{3}{4}", randomOne, one, item.Name.Insert(item.Name.Length / 2, alien2), randomThree, three); code2.RenameSymbol(replacement); } catch (Exception ex) { except += " error: " + ex.Message + "\n" + item.Name; PrintProperty2Info(CodeProperty); } //sb += (" " + code.Name + " " + code.IsCodeType + " " + code.Kind + "\n"); } else { } return(""); }
public static ITypeMetadata FromCodeElement(CodeVariable2 codeVariable, CodeDomFileMetadata file) { return(GetType(codeVariable, file)); }
private CodeDomEnumValueMetadata(CodeVariable2 codeVariable, CodeDomFileMetadata file, int value) { this.codeVariable = codeVariable; this.file = file; this.value = value; }
/// <summary> /// Called on click - when overriden, finds object in current selection and displayes dialog offering to move it. /// </summary> public override void Process() { base.Process(); // initialize basic variables T resultItem = GetReplaceStringItem(); // get result item (language specific) if (resultItem != null) // result item found and ok - proceed { TextSpan replaceSpan = resultItem.ReplaceSpan; string referencedCodeText = resultItem.Value; resultItem.SourceItem = currentDocument.ProjectItem; // set origin project item of the result item // display dialog enabling user to modify resource key, select destination resource file etc. // also enables user to resolve conflicts (duplicate key entries) SelectResourceFileForm f = new SelectResourceFileForm(currentDocument.ProjectItem, resultItem); System.Windows.Forms.DialogResult result = f.ShowDialog(); resultItem.DestinationItem = f.SelectedItem; // set destination project item - ResX file if (result == System.Windows.Forms.DialogResult.OK) { bool removeConst = false; if (resultItem.IsConst) { var deleteConst = VisualLocalizer.Library.Components.MessageBox.Show("This field is marked as 'const'. In order to continue with this operation, this modifier must be removed. Continue?", "Const", OLEMSGBUTTON.OLEMSGBUTTON_YESNO, OLEMSGDEFBUTTON.OLEMSGDEFBUTTON_FIRST, OLEMSGICON.OLEMSGICON_WARNING); if (deleteConst == DialogResult.Yes) { removeConst = true; } else { return; } } bool unitsFromStackRemoved = false; bool unitMovedToResource = false; ReferenceString referenceText; bool addUsing = false; // Now we must resolve the namespaces issue. If user selected the "use full name" in previous dialog, // there's no trouble. Otherwise we must find out, if necessary namespace has already been included (using) // and if not, create new using block with the namespace name. try { resultItem.DestinationItem = f.SelectedItem; if (resultItem.DestinationItem == null) { throw new InvalidOperationException("Destination item must be selected."); } if (resultItem.DestinationItem.InternalProjectItem == null) { throw new InvalidOperationException("Destination item must be selected."); } if (!File.Exists(resultItem.DestinationItem.InternalProjectItem.GetFullPath())) { throw new InvalidOperationException("Destination item file does not exist."); } if (f.UsingFullName || resultItem.MustUseFullName || (resultItem.Language == LANGUAGE.VB && resultItem.DestinationItem.IsProjectDefault(resultItem.SourceItem.ContainingProject))) { referenceText = new ReferenceString(f.SelectedItem.Namespace, f.SelectedItem.Class, f.Key); addUsing = false; } else { NamespacesList usedNamespaces = resultItem.GetUsedNamespaces(); addUsing = usedNamespaces.ResolveNewElement(f.SelectedItem.Namespace, f.SelectedItem.Class, f.Key, currentDocument.ProjectItem.ContainingProject, out referenceText); } string newText = resultItem.GetReferenceText(referenceText); // perform actual replace int hr = textLines.ReplaceLines(replaceSpan.iStartLine, replaceSpan.iStartIndex, replaceSpan.iEndLine, replaceSpan.iEndIndex, Marshal.StringToBSTR(newText), newText.Length, new TextSpan[] { replaceSpan }); Marshal.ThrowExceptionForHR(hr); // set selection to the new text hr = textView.SetSelection(replaceSpan.iStartLine, replaceSpan.iStartIndex, replaceSpan.iStartLine, replaceSpan.iStartIndex + newText.Length); Marshal.ThrowExceptionForHR(hr); if (removeConst) { CodeVariable2 codeVar = (CodeVariable2)resultItem.CodeModelSource; codeVar.ConstKind = vsCMConstKind.vsCMConstKindNone; } if (addUsing) { resultItem.AddUsingBlock(textLines); } if (f.Result == SELECT_RESOURCE_FILE_RESULT.INLINE) { // conflict -> user chooses to reference existing key unitsFromStackRemoved = CreateMoveToResourcesReferenceUndoUnit(f.Key, addUsing, removeConst); } else if (f.Result == SELECT_RESOURCE_FILE_RESULT.OVERWRITE) { // conflict -> user chooses to overwrite existing key and reference the new one f.SelectedItem.AddString(f.Key, f.Value); unitMovedToResource = true; unitsFromStackRemoved = CreateMoveToResourcesOverwriteUndoUnit(f.Key, f.Value, f.OverwrittenValue, f.SelectedItem, addUsing, removeConst); } else { // no conflict occured f.SelectedItem.AddString(f.Key, f.Value); unitMovedToResource = true; unitsFromStackRemoved = CreateMoveToResourcesUndoUnit(f.Key, f.Value, f.SelectedItem, addUsing, removeConst); } } catch (Exception) { // exception occured - rollback all already performed actions in order to restore original state VLOutputWindow.VisualLocalizerPane.WriteLine("Exception caught, rolling back..."); if (!unitsFromStackRemoved) { int unitsToRemoveCount = (addUsing && removeConst) ? 3 : (addUsing || removeConst ? 2 : 1); List <IOleUndoUnit> units = undoManager.RemoveTopFromUndoStack(unitsToRemoveCount); foreach (var unit in units) { unit.Do(undoManager); } undoManager.RemoveTopFromUndoStack(units.Count); if (unitMovedToResource) { f.SelectedItem.RemoveKey(f.Key); } } else { AbstractUndoUnit unit = (AbstractUndoUnit)undoManager.RemoveTopFromUndoStack(1)[0]; int unitsToRemove = unit.AppendUnits.Count + 1; unit.Do(undoManager); undoManager.RemoveTopFromUndoStack(unitsToRemove); } throw; } } } else { throw new Exception("This part of code cannot be referenced"); } }
private CodeDomEnumValueMetadata(CodeVariable2 codeVariable, CodeDomFileMetadata file, long value) { this.codeVariable = codeVariable; this.file = file; this.value = value; }
private Field ParseField(CodeVariable2 codeVariable, string currentFile) { WriteLine("ParseField" + " " + codeVariable.Name + " " + codeVariable.Type.AsString); var field = new Field {Name = codeVariable.Name, Type = codeVariable.Type.AsString, Access = codeVariable.Access.Convert(), FileName = currentFile}; foreach (CodeAttribute2 attribute in codeVariable.Attributes) { ParseAttribute(attribute, field, currentFile); } return field; }