public NSObjectInfoService (string wrapperRoot) { this.WrapperRoot = wrapperRoot; var typeNamespace = wrapperRoot + ".Foundation"; connectAttType = new GetClassTypeReference (typeNamespace, "ConnectAttribute"); exportAttType = new GetClassTypeReference (typeNamespace, "ExportAttribute"); iboutletAttType = new GetClassTypeReference (typeNamespace, "OutletAttribute"); ibactionAttType = new GetClassTypeReference (typeNamespace, "ActionAttribute"); registerAttType = new GetClassTypeReference (typeNamespace, "RegisterAttribute"); modelAttType = new GetClassTypeReference (typeNamespace, "ModelAttribute"); nsobjectType = new GetClassTypeReference (typeNamespace, "NSObject"); }
public string GetShortType (string ns, string name, int typeArguments = 0) { if (Document == null || Document.ParsedDocument == null) return ns + "." + name; var typeDef = new GetClassTypeReference (ns, name, typeArguments).Resolve (Document.Compilation.TypeResolveContext); if (typeDef == null) return ns + "." + name; var file = Document.ParsedDocument.ParsedFile as CSharpUnresolvedFile; var csResolver = file.GetResolver (Document.Compilation, Document.Editor.Caret.Location); var builder = new ICSharpCode.NRefactory.CSharp.Refactoring.TypeSystemAstBuilder (csResolver); return OutputNode (Document, builder.ConvertType (typeDef)); }
protected override string GenerateCode(ITypeDefinition currentClass) { bool implementInterface = this.implementInterface.IsChecked == true; bool hasOnPropertyChanged = HasOnPropertyChanged(currentClass); bool useEventArgs = false; AstNode insertionAnchorElement = refactoringContext.GetNode(); if ((insertionAnchorElement == null) || !(insertionAnchorElement.Parent is TypeDeclaration)) { return null; } NewLineNode newLineNode = insertionAnchorElement as NewLineNode; while (insertionAnchorElement.PrevSibling is NewLineNode) insertionAnchorElement = insertionAnchorElement.PrevSibling ?? insertionAnchorElement; using (Script script = refactoringContext.StartScript()) { TypeDeclaration currentClassDeclaration = insertionAnchorElement.Parent as TypeDeclaration; if (implementInterface && !currentClass.IsStatic) { if (!hasOnPropertyChanged) { var nodes = new List<AstNode>(); if (!currentClass.GetAllBaseTypeDefinitions().Any(bt => bt.FullName == "System.ComponentModel.INotifyPropertyChanged")) { AstNode nodeBeforeClassBlock = currentClassDeclaration.LBraceToken; if (nodeBeforeClassBlock.PrevSibling is NewLineNode) { // There's a new line before the brace, insert before it! nodeBeforeClassBlock = nodeBeforeClassBlock.PrevSibling; } int insertion = editor.Document.GetOffset(nodeBeforeClassBlock.StartLocation); AstType interfaceTypeNode = refactoringContext.CreateShortType("System.ComponentModel", "INotifyPropertyChanged", 0); var directBaseTypes = currentClass.DirectBaseTypes.Where(t => t.FullName != "System.Object"); if (currentClassDeclaration.BaseTypes.Count > 0) { script.InsertText(insertion, ", " + interfaceTypeNode + " "); } else { script.InsertText(insertion, " : " + interfaceTypeNode + " "); } } var rt = new GetClassTypeReference("System.ComponentModel", "INotifyPropertyChanged", 0); var rtResolved = rt.Resolve(refactoringContext.Compilation); var ev = rtResolved.GetEvents().First(e => e.Name == "PropertyChanged"); EventDeclaration propertyChangedEvent = new EventDeclaration(); propertyChangedEvent.Variables.Add(new VariableInitializer(ev.Name)); propertyChangedEvent.Modifiers = Modifiers.Public; propertyChangedEvent.ReturnType = refactoringContext.CreateShortType(ev.ReturnType); nodes.Add(propertyChangedEvent); MethodDeclaration onEvent = CreateOnEventMethod(ev, currentClass); nodes.Add(onEvent); foreach (var node in nodes) { script.InsertAfter(insertionAnchorElement, node); AppendNewLine(script, insertionAnchorElement, newLineNode); } useEventArgs = false; } else { useEventArgs = currentClass.GetMethods().First(m => m.Name == "OnPropertyChanged").Parameters[0].Type.FullName != "System.String"; } } foreach (FieldWrapper field in fields.Where(f => f.IsIncluded)) { var prop = CreateProperty(field.Field, true, field.AddSetter); if (!field.Field.IsStatic && !currentClass.IsStatic && field.AddSetter && implementInterface) { var invocation = new ExpressionStatement(CreateInvocation(field.PropertyName, useEventArgs)); var assignment = prop.Setter.Body.Children.ElementAt(0) as Statement; prop.Setter.Body = new BlockStatement(); BlockStatement elseBlock = new BlockStatement(); elseBlock.Add(assignment.Clone()); elseBlock.Add(invocation); prop.Setter.Body.Add( new IfElseStatement( new BinaryOperatorExpression(new IdentifierExpression(field.MemberName), BinaryOperatorType.InEquality, new IdentifierExpression("value")), elseBlock ) ); } script.InsertAfter(insertionAnchorElement, prop); AppendNewLine(script, insertionAnchorElement, newLineNode); } } return null; }
bool ISupportsInterning.EqualsForInterning(ISupportsInterning other) { GetClassTypeReference o = other as GetClassTypeReference; return(o != null && assembly == o.assembly && name == o.name && nameSpace == o.nameSpace && typeParameterCount == o.typeParameterCount); }
/// <summary> /// Resolves the type by mapping the known Objective-C type information to .NET types. /// </summary> /// <returns> /// The number of unresolved types still remaining. /// </returns> /// <param name='type'> /// The NSObjectTypeInfo that contains the known Objective-C type information. /// Typically this will be the result of NSObjectInfoService.ParseHeader(). /// </param> /// <param name='provider'> /// A CodeDom provider which is used to make sure type names don't conflict with language keywords. /// </param> /// <param name='defaultNamespace'> /// The default namespace used when forcing type resolution. /// </param> public void ResolveObjcToCli (IProgressMonitor monitor, NSObjectTypeInfo type, CodeDomProvider provider, string defaultNamespace) { NSObjectTypeInfo resolved; // Resolve our base type if (type.BaseCliType == null) { if (TryResolveObjcToCli (type.BaseObjCType, out resolved)) { type.BaseCliType = resolved.CliName; } else { var reference = new GetClassTypeReference (defaultNamespace, provider.CreateValidIdentifier (type.BaseObjCType)); type.BaseCliType = reference.Resolve (dom.Compilation).ReflectionName; var message = string.Format ("Failed to resolve Objective-C type '{0}' to a type in the current solution.", type.BaseObjCType); message += string.Format (" Adding a [Register (\"{0}\")] attribute to the class which corresponds to this will allow it to be synced to Objective-C.", type.BaseObjCType); monitor.ReportError (null, new UserException ("Error while syncing", message)); } } // Resolve [Outlet] types foreach (var outlet in type.Outlets) { if (outlet.CliType != null) continue; if (TryResolveObjcToCli (outlet.ObjCType, out resolved)) { outlet.CliType = resolved.CliName; } else { outlet.CliType = defaultNamespace + "." + provider.CreateValidIdentifier (outlet.ObjCType); var message = string.Format ("Failed to resolve Objective-C outlet '{0}' of type '{1}' to a type in the current solution.", outlet.ObjCName, outlet.ObjCType); message += string.Format (" Adding a [Register (\"{0}\")] attribute to the class which corresponds to this will allow it to be synced to Objective-C.", outlet.ObjCType); monitor.ReportError (null, new UserException ("Error while syncing", message)); } } // Resolve [Action] param types foreach (var action in type.Actions) { foreach (var param in action.Parameters) { if (param.CliType != null) continue; if (TryResolveObjcToCli (param.ObjCType, out resolved)) { param.CliType = resolved.CliName; } else { param.CliType = defaultNamespace + "." + provider.CreateValidIdentifier (param.ObjCType); var message = string.Format ("Failed to resolve paramater '{0}' of type '{2}' on Objective-C action '{1}' to a type in the current solution.", param.Name, action.ObjCName, param.ObjCType); message += string.Format (" Adding a [Register (\"{0}\")] attribute to the class which corresponds to this will allow it to be synced to Objective-C.", param.ObjCType); monitor.ReportError (null, new UserException ("Error while syncing", message)); } } } }
public static void Main(string[] args) { if (args.Length != 4) { Console.WriteLine("use: RenameClass.exe <SolutionPath> <ClassNamespace> <CurrentClassName> <NewClassName>"); return; } var solutionFile = args[0]; // "C:\\Users\\v-ezeqs\\Documents\\Visual Studio 2010\\Projects\\Application36\\Application36.sln" var classNamespace = args[1]; // "Application36.WebHost" var className = args[2]; // "SiteMaster" var classNewName = args[3]; // "SiteMaster2" if (!File.Exists(solutionFile)) { Console.WriteLine("Solution not found at {0}", solutionFile); return; } Console.WriteLine("Loading solution..."); // Loading Solution in Memory Solution solution = new Solution(solutionFile); Console.WriteLine("Finding references..."); // Define which Type I'm looking for var typeReference = new GetClassTypeReference(classNamespace, className) as ITypeReference; // Try to find the Type definition in solution's projects foreach (var proj in solution.Projects) { var type = typeReference.Resolve(proj.Compilation); if (type.Kind != TypeKind.Unknown) { SetSearchedMembers(new List<object>() { type }); } } if (searchedMembers == null) { Console.WriteLine("Not References found. Refactoring Done."); return; } // Find all related members related with the Type (like Members, Methods, etc) ICSharpCode.NRefactory.CSharp.Resolver.FindReferences refFinder = new ICSharpCode.NRefactory.CSharp.Resolver.FindReferences(); var scopes = searchedMembers.Select (e => refFinder.GetSearchScopes (e as IEntity)); // Finding references to the Type on the one of the different Solution files refs = new List<dynamic>(); foreach (var file in solution.AllFiles.Distinct (new CSharpFileEqualityComparer())) { foreach (var scope in scopes) { refFinder.FindReferencesInFile( scope, file.UnresolvedTypeSystemForFile, file.SyntaxTree, file.Project.Compilation, (astNode, result) => { var newRef = GetReference(result, astNode, file); if (newRef == null || refs.Any(r => r.File.FileName == newRef.File.FileName && r.Region == newRef.Region)) return; refs.Add(newRef); }, CancellationToken.None ); } } Console.WriteLine("Refactoring {0} places in {1} files...", refs.Count(), refs.Select(x => x.File.FileName).Distinct().Count()); // Perform replace for each of the References found foreach (var r in refs) { // DocumentScript expects the the AST to stay unmodified (so that it fits // to the document state at the time of the DocumentScript constructor call), // so we call Freeze() to prevent accidental modifications (e.g. forgetting a Clone() call). r.File.SyntaxTree.Freeze(); // Create a document containing the file content: var fileText = File.ReadAllText(r.File.FileName); var document = new StringBuilderDocument(fileText); using (var script = new DocumentScript(document, FormattingOptionsFactory.CreateAllman(), new TextEditorOptions())) { // Alternative 1: clone a portion of the AST and modify it //var copy = (InvocationExpression)expr.Clone(); //copy.Arguments.Add(stringComparisonAst.Member("Ordinal")); //script.Replace(expr, copy); // Alternative 2: perform direct text insertion / replace int offset = script.GetCurrentOffset(r.Region.Begin); var length = r.Region.End.Column - r.Region.Begin.Column; script.Replace(offset, length, classNewName); } File.WriteAllText(r.File.FileName, document.Text); } Console.WriteLine("Refactoring Done."); }
bool ISupportsInterning.EqualsForInterning(ISupportsInterning other) { GetClassTypeReference o = other as GetClassTypeReference; return(o != null && assembly == o.assembly && fullTypeName == o.fullTypeName); }
static ITypeReference ParseReflectionName(string reflectionTypeName, ref int pos, IEntity entity) { if (pos == reflectionTypeName.Length) throw new ReflectionNameParseException(pos, "Unexpected end"); if (reflectionTypeName[pos] == '`') { // type parameter reference pos++; if (pos == reflectionTypeName.Length) throw new ReflectionNameParseException(pos, "Unexpected end"); if (reflectionTypeName[pos] == '`') { // method type parameter reference pos++; int index = ReadTypeParameterCount(reflectionTypeName, ref pos); IMethod method = entity as IMethod; if (method != null && index >= 0 && index < method.TypeParameters.Count) return method.TypeParameters[index]; else return SharedTypes.UnknownType; } else { // class type parameter reference int index = ReadTypeParameterCount(reflectionTypeName, ref pos); ITypeDefinition c = (entity as ITypeDefinition) ?? (entity != null ? entity.DeclaringTypeDefinition : null); if (c != null && index >= 0 && index < c.TypeParameters.Count) return c.TypeParameters[index]; else return SharedTypes.UnknownType; } } // not a type parameter reference: read the actual type name int tpc; string typeName = ReadTypeName(reflectionTypeName, ref pos, out tpc); ITypeReference reference = new GetClassTypeReference(typeName, tpc); // read type suffixes while (pos < reflectionTypeName.Length) { switch (reflectionTypeName[pos++]) { case '+': typeName = ReadTypeName(reflectionTypeName, ref pos, out tpc); reference = new NestedTypeReference(reference, typeName, tpc); break; case '*': reference = new PointerTypeReference(reference); break; case '&': reference = new ByReferenceTypeReference(reference); break; case '[': // this might be an array or a generic type if (pos == reflectionTypeName.Length) throw new ReflectionNameParseException(pos, "Unexpected end"); if (reflectionTypeName[pos] == '[') { // it's a generic type List<ITypeReference> typeArguments = new List<ITypeReference>(tpc); pos++; typeArguments.Add(ParseReflectionName(reflectionTypeName, ref pos, entity)); if (pos < reflectionTypeName.Length && reflectionTypeName[pos] == ']') pos++; else throw new ReflectionNameParseException(pos, "Expected end of type argument"); while (pos < reflectionTypeName.Length && reflectionTypeName[pos] == ',') { pos++; if (pos < reflectionTypeName.Length && reflectionTypeName[pos] == '[') pos++; else throw new ReflectionNameParseException(pos, "Expected another type argument"); typeArguments.Add(ParseReflectionName(reflectionTypeName, ref pos, entity)); if (pos < reflectionTypeName.Length && reflectionTypeName[pos] == ']') pos++; else throw new ReflectionNameParseException(pos, "Expected end of type argument"); } if (pos < reflectionTypeName.Length && reflectionTypeName[pos] == ']') { pos++; reference = new ParameterizedTypeReference(reference, typeArguments); } else { throw new ReflectionNameParseException(pos, "Expected end of generic type"); } } else { // it's an array int dimensions = 1; while (pos < reflectionTypeName.Length && reflectionTypeName[pos] == ',') { dimensions++; pos++; } if (pos < reflectionTypeName.Length && reflectionTypeName[pos] == ']') { pos++; // end of array reference = new ArrayTypeReference(reference, dimensions); } else { throw new ReflectionNameParseException(pos, "Invalid array modifier"); } } break; case ',': // assembly qualified name, ignore everything up to the end/next ']' while (pos < reflectionTypeName.Length && reflectionTypeName[pos] != ']') pos++; break; default: pos--; // reset pos to the character we couldn't read if (reflectionTypeName[pos] == ']') return reference; // return from a nested generic else throw new ReflectionNameParseException(pos, "Unexpected character: '" + reflectionTypeName[pos] + "'"); } } return reference; }
public IUnresolvedAssembly LoadAssembly(Assembly assembly) { if (assembly == null) throw new ArgumentNullException ("assembly"); // Read assembly and module attributes IList<IUnresolvedAttribute> assemblyAttributes = new List<IUnresolvedAttribute>(); IList<IUnresolvedAttribute> moduleAttributes = new List<IUnresolvedAttribute>(); AddAttributes(assembly, assemblyAttributes); AddAttributes(assembly.ManifestModule, moduleAttributes); assemblyAttributes = interningProvider.InternList(assemblyAttributes); moduleAttributes = interningProvider.InternList(moduleAttributes); currentAssemblyDefinition = assembly; currentAssembly = new IkvmUnresolvedAssembly (assembly.FullName, DocumentationProvider); currentAssembly.Location = assembly.Location; currentAssembly.AssemblyAttributes.AddRange(assemblyAttributes); currentAssembly.ModuleAttributes.AddRange(moduleAttributes); // Register type forwarders: foreach (var type in assembly.ManifestModule.__GetExportedTypes ()) { if (type.Assembly != assembly) { int typeParameterCount; string ns = type.Namespace; string name = ReflectionHelper.SplitTypeParameterCountFromReflectionName(type.Name, out typeParameterCount); ns = interningProvider.Intern(ns); name = interningProvider.Intern(name); var typeRef = new GetClassTypeReference(GetAssemblyReference(type.Assembly), ns, name, typeParameterCount); typeRef = interningProvider.Intern(typeRef); var key = new TopLevelTypeName(ns, name, typeParameterCount); currentAssembly.AddTypeForwarder(key, typeRef); } } // Create and register all types: var ikvmTypeDefs = new List<IKVM.Reflection.Type>(); var typeDefs = new List<DefaultUnresolvedTypeDefinition>(); foreach (var td in assembly.GetTypes ()) { if (td.DeclaringType != null) continue; CancellationToken.ThrowIfCancellationRequested(); if (IncludeInternalMembers || td.IsPublic) { string name = td.Name; if (name.Length == 0) continue; var t = CreateTopLevelTypeDefinition(td); ikvmTypeDefs.Add(td); typeDefs.Add(t); currentAssembly.AddTypeDefinition(t); // The registration will happen after the members are initialized } } // Initialize the type's members: for (int i = 0; i < typeDefs.Count; i++) { InitTypeDefinition(ikvmTypeDefs[i], typeDefs[i]); } // Freezing the assembly here is important: // otherwise it will be frozen when a compilation is first created // from it. But freezing has the effect of changing some collection instances // (to ReadOnlyCollection). This hidden mutation was causing a crash // when the FastSerializer was saving the assembly at the same time as // the first compilation was created from it. // By freezing the assembly now, we ensure it is usable on multiple // threads without issues. currentAssembly.Freeze(); var result = currentAssembly; currentAssembly = null; return result; }
public string GetSimpleTypeName (string fullTypeName) { if (CurrentContext.ParsedDocument == null) return fullTypeName.Replace ("#", "."); string ns = ""; string name = ""; string member = ""; int idx = fullTypeName.IndexOf ('#'); if (idx < 0) { name = fullTypeName; } else { ns = fullTypeName.Substring (0, idx); name = fullTypeName.Substring (idx + 1); } idx = name.IndexOf ('.'); if (idx >= 0) { member = name.Substring (idx); name = name.Substring (0, idx); } var type = new GetClassTypeReference (ns, name, 0).Resolve ( CurrentContext.Document.ParsedDocument.GetTypeResolveContext ( CurrentContext.Document.Compilation, CurrentContext.Document.Editor.Caret.Location ) ); bool stripAttribute = false; if (type == null || type.Kind == TypeKind.Unknown) { type = new GetClassTypeReference (ns, name + "Attribute", 0).Resolve ( CurrentContext.Document.ParsedDocument.GetTypeResolveContext ( CurrentContext.Document.Compilation, CurrentContext.Document.Editor.Caret.Location ) ); stripAttribute = true; } if (type == null || type.Kind == TypeKind.Unknown) return fullTypeName.Replace ("#", "."); var generator = CodeGenerator.CreateGenerator (CurrentContext.Document); if (generator != null) { var result = generator.GetShortTypeString (CurrentContext.Document, type) + member; if (stripAttribute && result.EndsWith ("Attribute", StringComparison.Ordinal)) result = result.Substring (0, result.Length - "Attribute".Length); return result; } return fullTypeName.Replace ("#", "."); }
ICodeContext CreateContext(ITextEditor editor) { var compilation = SD.ParserService.GetCompilationForFile(editor.FileName); var project = SD.ProjectService.FindProjectContainingFile(editor.FileName); var resolveContext = new SimpleTypeResolveContext(compilation.MainAssembly); var currentTypeDefinition = new DefaultUnresolvedTypeDefinition(project.RootNamespace, Path.GetFileNameWithoutExtension(editor.FileName)); ITypeReference baseTypeReference = new GetClassTypeReference("System.Web.Mvc", "WebViewPage", 1); baseTypeReference = new ParameterizedTypeReference(baseTypeReference, new[] { FindModelType(editor) }); currentTypeDefinition.BaseTypes.Add(baseTypeReference); var currentMethod = new DefaultUnresolvedMethod(currentTypeDefinition, "__ContextStub__"); currentMethod.ReturnType = KnownTypeReference.Void; currentTypeDefinition.Members.Add(currentMethod); var currentResolvedTypeDef = new DefaultResolvedTypeDefinition(resolveContext, currentTypeDefinition); var projectContent = compilation.MainAssembly.UnresolvedAssembly as IProjectContent; var currentFile = new CSharpUnresolvedFile(); currentFile.RootUsingScope.AddSimpleUsing("System.Web.Mvc"); currentFile.RootUsingScope.AddSimpleUsing("System.Web.Mvc.Ajax"); currentFile.RootUsingScope.AddSimpleUsing("System.Web.Mvc.Html"); currentFile.RootUsingScope.AddSimpleUsing("System.Web.Routing"); currentFile.TopLevelTypeDefinitions.Add(currentTypeDefinition); if (projectContent != null) { compilation = projectContent.AddOrUpdateFiles(currentFile).CreateCompilation(SD.ParserService.GetCurrentSolutionSnapshot()); } var context = new CSharpTypeResolveContext(compilation.MainAssembly, currentFile.RootUsingScope.Resolve(compilation), currentResolvedTypeDef, currentMethod.CreateResolved(resolveContext.WithCurrentTypeDefinition(currentResolvedTypeDef))); return new CSharpResolver(context); }