コード例 #1
0
        public static string IsTypeMovedToNamespaceError(CompilationUnit cu, int line, int column)
        {
            var self = new InvalidTypeOrNamespaceErrorTypeMapper(line, column);

            cu.AcceptVisitor(self, null);

            return(self.Found);
        }
コード例 #2
0
        // C# compiler does not emmit the full qualified type name when it fails to resolve a 'theorically', fully qualified type reference
        // for instance, if 'NSBar', a namespace gets renamed to 'NSBar2', a refernce to 'NSFoo.NSBar.TypeBaz' will emit an error
        // with only NSBar and NSFoo in the message. In this case we use NRefactory to dive in to the code, looking for type references
        // in the reported error line/column
        private static Type FindTypeMatchingMovedTypeBasedOnNamespaceFromError(IEnumerable <string> lines)
        {
            var value = GetValueFromNormalizedMessage(lines, "Line=");
            var line  = (value != null) ? Int32.Parse(value) : -1;

            value = GetValueFromNormalizedMessage(lines, "Column=");
            var column = (value != null) ? Int32.Parse(value) : -1;

            var script = GetValueFromNormalizedMessage(lines, "Script=");

            if (line == -1 || column == -1 || script == null)
            {
                return(null);
            }

            try
            {
                using (var scriptStream = File.Open(script, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
                {
                    var parser = ParserFactory.CreateParser(ICSharpCode.NRefactory.SupportedLanguage.CSharp, new StreamReader(scriptStream));
                    parser.Lexer.EvaluateConditionalCompilation = false;
                    parser.Parse();

                    var typeNotFound = InvalidTypeOrNamespaceErrorTypeMapper.IsTypeMovedToNamespaceError(parser.CompilationUnit, line, column);
                    if (typeNotFound == null)
                    {
                        return(null);
                    }

                    return(FindExactTypeMatchingMovedType(typeNotFound));
                }
            }
            catch (FileNotFoundException)
            {
                return(null);
            }
        }
コード例 #3
0
        // C# compiler does not emit the full qualified type name when it fails to resolve a 'theoretically', fully qualified type reference
        // for instance, if 'NSBar', a namespace gets renamed to 'NSBar2', a reference to 'NSFoo.NSBar.TypeBaz' will emit an error
        // with only NSBar and NSFoo in the message. In this case we use NRefactory to dive in to the code, looking for type references
        // in the reported error line/column
        static Type FindTypeMatchingMovedTypeBasedOnNamespaceFromError(IEnumerable <string> lines)
        {
            var value = GetValueFromNormalizedMessage(lines, "Line=");
            var line  = (value != null) ? Int32.Parse(value) : -1;

            value = GetValueFromNormalizedMessage(lines, "Column=");
            var column = (value != null) ? Int32.Parse(value) : -1;

            var script = GetValueFromNormalizedMessage(lines, "Script=");

            if (line == -1 || column == -1 || script == null)
            {
                return(null);
            }

            var entityName = GetValueFromNormalizedMessage(lines, "EntityName=");

            try
            {
                using (var scriptStream = File.Open(script, System.IO.FileMode.Open, FileAccess.Read, FileShare.ReadWrite | FileShare.Delete))
                {
                    var parser = ParserFactory.CreateParser(ICSharpCode.NRefactory.SupportedLanguage.CSharp, new StreamReader(scriptStream));
                    parser.Lexer.EvaluateConditionalCompilation = false;
                    parser.Parse();

                    var self = new InvalidTypeOrNamespaceErrorTypeMapper(line, column, entityName);
                    parser.CompilationUnit.AcceptVisitor(self, null);

                    if (self.identifiers.Count == 0)
                    {
                        return(null);
                    }

                    var availableTypes = TypeCache.GetTypesWithAttribute(typeof(MovedFromAttribute));
                    foreach (var ns in self.NamespacesInScope)
                    {
                        foreach (var i in self.identifiers)
                        {
                            foreach (var t in availableTypes)
                            {
                                var @namespace = ns;
                                foreach (var part in i.parts)
                                {
                                    //If the usage + any of the candidate namespaces matches a real type, this usage is valid and does not need to be updated
                                    //this is required to avoid false positives when a type that exists on *editor* (and is marked as moved) is used in a platform that
                                    //does not support it. If we don't check the namespaces in scope we'll flag this as an error due to the type being moved (and
                                    //whence, trigger the updater, whereas the real problem is that the type is not supported in the platform (see issue #96123)
                                    //whence this is indeed a programing error that the user needs to fix.
                                    if (t.Name == part && t.Namespace == @namespace)
                                    {
                                        return(null);
                                    }

                                    if (t.Name == part && NamespaceHasChanged(t, @namespace))
                                    {
                                        return(t);
                                    }

                                    if (string.IsNullOrEmpty(@namespace))
                                    {
                                        @namespace = part;
                                    }
                                    else
                                    {
                                        @namespace = @namespace + "." + part;
                                    }
                                }
                            }
                        }
                    }
                    return(null);
                }
            }
            catch (FileNotFoundException)
            {
                return(null);
            }
        }
コード例 #4
0
        // C# compiler does not emmit the full qualified type name when it fails to resolve a 'theorically', fully qualified type reference
        // for instance, if 'NSBar', a namespace gets renamed to 'NSBar2', a refernce to 'NSFoo.NSBar.TypeBaz' will emit an error
        // with only NSBar and NSFoo in the message. In this case we use NRefactory to dive in to the code, looking for type references
        // in the reported error line/column
        private static Type FindTypeMatchingMovedTypeBasedOnNamespaceFromError(IEnumerable <string> lines)
        {
            var value = GetValueFromNormalizedMessage(lines, "Line=");
            var line  = (value != null) ? Int32.Parse(value) : -1;

            value = GetValueFromNormalizedMessage(lines, "Column=");
            var column = (value != null) ? Int32.Parse(value) : -1;

            var script = GetValueFromNormalizedMessage(lines, "Script=");

            if (line == -1 || column == -1 || script == null)
            {
                return(null);
            }

            try
            {
                using (var scriptStream = File.Open(script, System.IO.FileMode.Open, FileAccess.Read, FileShare.ReadWrite | FileShare.Delete))
                {
                    var parser = ParserFactory.CreateParser(ICSharpCode.NRefactory.SupportedLanguage.CSharp, new StreamReader(scriptStream));
                    parser.Lexer.EvaluateConditionalCompilation = false;
                    parser.Parse();

                    var self = new InvalidTypeOrNamespaceErrorTypeMapper(line, column);
                    parser.CompilationUnit.AcceptVisitor(self, null);

                    if (self.identifierParts.Count == 0)
                    {
                        return(null);
                    }

                    List <string>     candidateNamespaces          = new List <string>(self.usings.Where(u => !u.IsAlias).Select(u => u.Name));
                    List <Identifier> candidateFullyQualifiedNames =
                        candidateNamespaces.Select(ns => new Identifier {
                        @namespace = ns, name = self.identifierParts[0]
                    }).ToList();

                    string @namespace = string.Empty;
                    foreach (var identifier in self.identifierParts)
                    {
                        candidateFullyQualifiedNames.Add(new Identifier {
                            name = identifier, @namespace = @namespace
                        });
                        if (@namespace != string.Empty)
                        {
                            @namespace += ".";
                        }

                        @namespace += identifier;
                    }

                    //If the usage + any of the candidate namespaces matches a real type, this usage is valid and does not need to be updated
                    if (FindTypeInLoadedAssemblies(t => candidateFullyQualifiedNames.Contains(new Identifier {
                        name = t.Name, @namespace = t.Namespace
                    })) != null)
                    {
                        return(null);
                    }

                    return(FindTypeInLoadedAssemblies(t =>
                                                      candidateFullyQualifiedNames.Any(id => id.name == t.Name && NamespaceHasChanged(t, id.@namespace))));
                }
            }
            catch (FileNotFoundException)
            {
                return(null);
            }
        }