diff --git a/ICSharpCode.NRefactory.CSharp/Analysis/ControlFlow.cs b/ICSharpCode.NRefactory.CSharp/Analysis/ControlFlow.cs index d5463020f5..8d58a944c7 100644 --- a/ICSharpCode.NRefactory.CSharp/Analysis/ControlFlow.cs +++ b/ICSharpCode.NRefactory.CSharp/Analysis/ControlFlow.cs @@ -21,10 +21,10 @@ using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Threading; - using ICSharpCode.NRefactory.CSharp.Resolver; using ICSharpCode.NRefactory.Semantics; using ICSharpCode.NRefactory.TypeSystem; +using ICSharpCode.NRefactory.TypeSystem.Implementation; namespace ICSharpCode.NRefactory.CSharp.Analysis { @@ -145,36 +145,35 @@ namespace ICSharpCode.NRefactory.CSharp.Analysis protected virtual ControlFlowNode CreateNode(Statement previousStatement, Statement nextStatement, ControlFlowNodeType type) { + cancellationToken.ThrowIfCancellationRequested(); return new ControlFlowNode(previousStatement, nextStatement, type); } protected virtual ControlFlowEdge CreateEdge(ControlFlowNode from, ControlFlowNode to, ControlFlowEdgeType type) { + cancellationToken.ThrowIfCancellationRequested(); return new ControlFlowEdge(from, to, type); } Statement rootStatement; - ResolveVisitor resolveVisitor; + CSharpAstResolver resolver; List nodes; Dictionary labels; List gotoStatements; + CancellationToken cancellationToken; - public IList BuildControlFlowGraph(Statement statement) + public IList BuildControlFlowGraph(Statement statement, CancellationToken cancellationToken = default(CancellationToken)) { - return BuildControlFlowGraph(statement, CancellationToken.None); + CSharpResolver r = new CSharpResolver(MinimalCorlib.Instance.CreateCompilation()); + return BuildControlFlowGraph(statement, new CSharpAstResolver(r, statement), cancellationToken); } - public IList BuildControlFlowGraph(Statement statement, CancellationToken cancellationToken) - { - throw new NotImplementedException(); - } - - internal IList BuildControlFlowGraph(Statement statement, ResolveVisitor resolveVisitor) + public IList BuildControlFlowGraph(Statement statement, CSharpAstResolver resolver, CancellationToken cancellationToken = default(CancellationToken)) { if (statement == null) throw new ArgumentNullException("statement"); - if (resolveVisitor == null) - throw new ArgumentNullException("resolveVisitor"); + if (resolver == null) + throw new ArgumentNullException("resolver"); NodeCreationVisitor nodeCreationVisitor = new NodeCreationVisitor(); nodeCreationVisitor.builder = this; @@ -183,7 +182,9 @@ namespace ICSharpCode.NRefactory.CSharp.Analysis this.labels = new Dictionary(); this.gotoStatements = new List(); this.rootStatement = statement; - this.resolveVisitor = resolveVisitor; + this.resolver = resolver; + this.cancellationToken = cancellationToken; + ControlFlowNode entryPoint = CreateStartNode(statement); statement.AcceptVisitor(nodeCreationVisitor, entryPoint); @@ -203,7 +204,8 @@ namespace ICSharpCode.NRefactory.CSharp.Analysis this.labels = null; this.gotoStatements = null; this.rootStatement = null; - this.resolveVisitor = null; + this.resolver = null; + this.cancellationToken = CancellationToken.None; } } @@ -280,13 +282,13 @@ namespace ICSharpCode.NRefactory.CSharp.Analysis /// Evaluates an expression. /// /// The constant value of the expression; or null if the expression is not a constant. - ConstantResolveResult EvaluateConstant(Expression expr) + ResolveResult EvaluateConstant(Expression expr) { if (EvaluateOnlyPrimitiveConstants) { if (!(expr is PrimitiveExpression || expr is NullReferenceExpression)) return null; } - return resolveVisitor.Resolve(expr) as ConstantResolveResult; + return resolver.Resolve(expr, cancellationToken); } /// @@ -295,21 +297,20 @@ namespace ICSharpCode.NRefactory.CSharp.Analysis /// The value of the constant boolean expression; or null if the value is not a constant boolean expression. bool? EvaluateCondition(Expression expr) { - ConstantResolveResult rr = EvaluateConstant(expr); - if (rr != null) + ResolveResult rr = EvaluateConstant(expr); + if (rr != null && rr.IsCompileTimeConstant) return rr.ConstantValue as bool?; else return null; } - bool AreEqualConstants(ConstantResolveResult c1, ConstantResolveResult c2) + bool AreEqualConstants(ResolveResult c1, ResolveResult c2) { - if (c1 == null || c2 == null) + if (c1 == null || c2 == null || !c1.IsCompileTimeConstant || !c2.IsCompileTimeConstant) return false; - throw new NotImplementedException(); - /*CSharpResolver r = new CSharpResolver(resolveVisitor.TypeResolveContext, resolveVisitor.CancellationToken); + CSharpResolver r = new CSharpResolver(resolver.TypeResolveContext); ResolveResult c = r.ResolveBinaryOperator(BinaryOperatorType.Equality, c1, c2); - return c.IsCompileTimeConstant && (c.ConstantValue as bool?) == true;*/ + return c.IsCompileTimeConstant && (c.ConstantValue as bool?) == true; } #endregion @@ -421,7 +422,7 @@ namespace ICSharpCode.NRefactory.CSharp.Analysis public override ControlFlowNode VisitSwitchStatement(SwitchStatement switchStatement, ControlFlowNode data) { // First, figure out which switch section will get called (if the expression is constant): - ConstantResolveResult constant = builder.EvaluateConstant(switchStatement.Expression); + ResolveResult constant = builder.EvaluateConstant(switchStatement.Expression); SwitchSection defaultSection = null; SwitchSection sectionMatchedByConstant = null; foreach (SwitchSection section in switchStatement.SwitchSections) { @@ -429,13 +430,13 @@ namespace ICSharpCode.NRefactory.CSharp.Analysis if (label.Expression.IsNull) { defaultSection = section; } else if (constant != null) { - ConstantResolveResult labelConstant = builder.EvaluateConstant(label.Expression); + ResolveResult labelConstant = builder.EvaluateConstant(label.Expression); if (builder.AreEqualConstants(constant, labelConstant)) sectionMatchedByConstant = section; } } } - if (constant != null && sectionMatchedByConstant == null) + if (constant.IsCompileTimeConstant && sectionMatchedByConstant == null) sectionMatchedByConstant = defaultSection; int gotoCaseOrDefaultInOuterScope = gotoCaseOrDefault.Count; diff --git a/ICSharpCode.NRefactory.CSharp/Analysis/DefiniteAssignmentAnalysis.cs b/ICSharpCode.NRefactory.CSharp/Analysis/DefiniteAssignmentAnalysis.cs index 834ed1f166..8d0832bed8 100644 --- a/ICSharpCode.NRefactory.CSharp/Analysis/DefiniteAssignmentAnalysis.cs +++ b/ICSharpCode.NRefactory.CSharp/Analysis/DefiniteAssignmentAnalysis.cs @@ -81,52 +81,42 @@ namespace ICSharpCode.NRefactory.CSharp.Analysis } } - readonly DerivedControlFlowGraphBuilder cfgBuilder = new DerivedControlFlowGraphBuilder(); readonly DefiniteAssignmentVisitor visitor = new DefiniteAssignmentVisitor(); readonly List allNodes = new List(); readonly Dictionary beginNodeDict = new Dictionary(); readonly Dictionary endNodeDict = new Dictionary(); readonly Dictionary conditionNodeDict = new Dictionary(); - readonly ResolveVisitor resolveVisitor; - readonly CancellationToken cancellationToken; + readonly CSharpAstResolver resolver; Dictionary edgeStatus = new Dictionary(); string variableName; List unassignedVariableUses = new List(); int analyzedRangeStart, analyzedRangeEnd; + CancellationToken analysisCancellationToken; Queue nodesWithModifiedInput = new Queue(); - public DefiniteAssignmentAnalysis(Statement rootStatement) - : this(rootStatement, CancellationToken.None) - { - } - - - [ObsoleteAttribute] - public DefiniteAssignmentAnalysis(params object[] args) - { - throw new NotImplementedException(); - } public DefiniteAssignmentAnalysis(Statement rootStatement, CancellationToken cancellationToken) + : this(rootStatement, + new CSharpAstResolver(new CSharpResolver(MinimalCorlib.Instance.CreateCompilation()), rootStatement), + cancellationToken) { - throw new NotImplementedException(); } - /* - public DefiniteAssignmentAnalysis(Statement rootStatement, ResolveVisitor resolveVisitor) + public DefiniteAssignmentAnalysis(Statement rootStatement, CSharpAstResolver resolver, CancellationToken cancellationToken) { if (rootStatement == null) throw new ArgumentNullException("rootStatement"); - if (resolveVisitor == null) - throw new ArgumentNullException("resolveVisitor"); - this.resolveVisitor = resolveVisitor; - this.cancellationToken = resolveVisitor.CancellationToken; + if (resolver == null) + throw new ArgumentNullException("resolver"); + this.resolver = resolver; + visitor.analysis = this; - if (resolveVisitor.TypeResolveContext is MinimalResolveContext) { + DerivedControlFlowGraphBuilder cfgBuilder = new DerivedControlFlowGraphBuilder(); + if (resolver.TypeResolveContext.Compilation.MainAssembly.UnresolvedAssembly is MinimalCorlib) { cfgBuilder.EvaluateOnlyPrimitiveConstants = true; } - allNodes.AddRange(cfgBuilder.BuildControlFlowGraph(rootStatement, resolveVisitor).Cast()); + allNodes.AddRange(cfgBuilder.BuildControlFlowGraph(rootStatement, resolver, cancellationToken).Cast()); for (int i = 0; i < allNodes.Count; i++) { DefiniteAssignmentNode node = allNodes[i]; node.Index = i; // assign numbers to the nodes @@ -134,7 +124,7 @@ namespace ICSharpCode.NRefactory.CSharp.Analysis // Anonymous methods have separate control flow graphs, but we also need to analyze those. // Iterate backwards so that anonymous methods are inserted in the correct order for (AstNode child = node.NextStatement.LastChild; child != null; child = child.PrevSibling) { - InsertAnonymousMethods(i + 1, child); + InsertAnonymousMethods(i + 1, child, cfgBuilder, cancellationToken); } } // Now register the node in the dictionaries: @@ -153,27 +143,27 @@ namespace ICSharpCode.NRefactory.CSharp.Analysis this.analyzedRangeStart = 0; this.analyzedRangeEnd = allNodes.Count - 1; - }*/ + } - void InsertAnonymousMethods(int insertPos, AstNode node) + void InsertAnonymousMethods(int insertPos, AstNode node, ControlFlowGraphBuilder cfgBuilder, CancellationToken cancellationToken) { // Ignore any statements, as those have their own ControlFlowNode and get handled separately if (node is Statement) return; AnonymousMethodExpression ame = node as AnonymousMethodExpression; if (ame != null) { - allNodes.InsertRange(insertPos, cfgBuilder.BuildControlFlowGraph(ame.Body, resolveVisitor).Cast()); + allNodes.InsertRange(insertPos, cfgBuilder.BuildControlFlowGraph(ame.Body, resolver, cancellationToken).Cast()); return; } LambdaExpression lambda = node as LambdaExpression; if (lambda != null && lambda.Body is Statement) { - allNodes.InsertRange(insertPos, cfgBuilder.BuildControlFlowGraph((Statement)lambda.Body, resolveVisitor).Cast()); + allNodes.InsertRange(insertPos, cfgBuilder.BuildControlFlowGraph((Statement)lambda.Body, resolver, cancellationToken).Cast()); return; } // Descend into child expressions // Iterate backwards so that anonymous methods are inserted in the correct order for (AstNode child = node.LastChild; child != null; child = child.PrevSibling) { - InsertAnonymousMethods(insertPos, child); + InsertAnonymousMethods(insertPos, child, cfgBuilder, cancellationToken); } } @@ -205,26 +195,32 @@ namespace ICSharpCode.NRefactory.CSharp.Analysis this.analyzedRangeEnd = endIndex; } - public void Analyze(string variable, DefiniteAssignmentStatus initialStatus = DefiniteAssignmentStatus.PotentiallyAssigned) + public void Analyze(string variable, DefiniteAssignmentStatus initialStatus = DefiniteAssignmentStatus.PotentiallyAssigned, CancellationToken cancellationToken = default(CancellationToken)) { + this.analysisCancellationToken = cancellationToken; this.variableName = variable; - // Reset the status: - unassignedVariableUses.Clear(); - foreach (DefiniteAssignmentNode node in allNodes) { - node.NodeStatus = DefiniteAssignmentStatus.CodeUnreachable; - foreach (ControlFlowEdge edge in node.Outgoing) - edgeStatus[edge] = DefiniteAssignmentStatus.CodeUnreachable; - } - - ChangeNodeStatus(allNodes[analyzedRangeStart], initialStatus); - // Iterate as long as the input status of some nodes is changing: - while (nodesWithModifiedInput.Count > 0) { - DefiniteAssignmentNode node = nodesWithModifiedInput.Dequeue(); - DefiniteAssignmentStatus inputStatus = DefiniteAssignmentStatus.CodeUnreachable; - foreach (ControlFlowEdge edge in node.Incoming) { - inputStatus = MergeStatus(inputStatus, edgeStatus[edge]); + try { + // Reset the status: + unassignedVariableUses.Clear(); + foreach (DefiniteAssignmentNode node in allNodes) { + node.NodeStatus = DefiniteAssignmentStatus.CodeUnreachable; + foreach (ControlFlowEdge edge in node.Outgoing) + edgeStatus[edge] = DefiniteAssignmentStatus.CodeUnreachable; + } + + ChangeNodeStatus(allNodes[analyzedRangeStart], initialStatus); + // Iterate as long as the input status of some nodes is changing: + while (nodesWithModifiedInput.Count > 0) { + DefiniteAssignmentNode node = nodesWithModifiedInput.Dequeue(); + DefiniteAssignmentStatus inputStatus = DefiniteAssignmentStatus.CodeUnreachable; + foreach (ControlFlowEdge edge in node.Incoming) { + inputStatus = MergeStatus(inputStatus, edgeStatus[edge]); + } + ChangeNodeStatus(node, inputStatus); } - ChangeNodeStatus(node, inputStatus); + } finally { + this.analysisCancellationToken = CancellationToken.None; + this.variableName = null; } } @@ -410,9 +406,9 @@ namespace ICSharpCode.NRefactory.CSharp.Analysis /// Evaluates an expression. /// /// The constant value of the expression; or null if the expression is not a constant. - ConstantResolveResult EvaluateConstant(Expression expr) + ResolveResult EvaluateConstant(Expression expr) { - return resolveVisitor.Resolve(expr) as ConstantResolveResult; + return resolver.Resolve(expr, analysisCancellationToken); } /// @@ -421,8 +417,8 @@ namespace ICSharpCode.NRefactory.CSharp.Analysis /// The value of the constant boolean expression; or null if the value is not a constant boolean expression. bool? EvaluateCondition(Expression expr) { - ConstantResolveResult rr = EvaluateConstant(expr); - if (rr != null) + ResolveResult rr = EvaluateConstant(expr); + if (rr != null && rr.IsCompileTimeConstant) return rr.ConstantValue as bool?; else return null; @@ -449,6 +445,8 @@ namespace ICSharpCode.NRefactory.CSharp.Analysis Debug.Assert(data == CleanSpecialValues(data)); DefiniteAssignmentStatus status = data; foreach (AstNode child in node.Children) { + analysis.analysisCancellationToken.ThrowIfCancellationRequested(); + Debug.Assert(!(child is Statement)); // statements are visited with the CFG, not with the visitor pattern status = child.AcceptVisitor(this, status); status = CleanSpecialValues(status); @@ -561,6 +559,7 @@ namespace ICSharpCode.NRefactory.CSharp.Analysis } #endregion + #region Expressions public override DefiniteAssignmentStatus VisitDirectionExpression(DirectionExpression directionExpression, DefiniteAssignmentStatus data) { if (directionExpression.FieldDirection == FieldDirection.Out) { @@ -670,8 +669,8 @@ namespace ICSharpCode.NRefactory.CSharp.Analysis return DefiniteAssignmentStatus.PotentiallyAssigned; } else if (binaryOperatorExpression.Operator == BinaryOperatorType.NullCoalescing) { // C# 4.0 spec: ยง5.3.3.27 Definite assignment for ?? expressions - ConstantResolveResult crr = analysis.EvaluateConstant(binaryOperatorExpression.Left); - if (crr != null && crr.ConstantValue == null) + ResolveResult crr = analysis.EvaluateConstant(binaryOperatorExpression.Left); + if (crr != null && crr.IsCompileTimeConstant && crr.ConstantValue == null) return binaryOperatorExpression.Right.AcceptVisitor(this, data); DefiniteAssignmentStatus status = CleanSpecialValues(binaryOperatorExpression.Left.AcceptVisitor(this, data)); binaryOperatorExpression.Right.AcceptVisitor(this, status); @@ -755,6 +754,7 @@ namespace ICSharpCode.NRefactory.CSharp.Analysis } return data; } + #endregion } } } diff --git a/ICSharpCode.NRefactory.CSharp/OutputVisitor/CodeDomConvertVisitor.cs b/ICSharpCode.NRefactory.CSharp/OutputVisitor/CodeDomConvertVisitor.cs index 040d02608d..56d3116e44 100644 --- a/ICSharpCode.NRefactory.CSharp/OutputVisitor/CodeDomConvertVisitor.cs +++ b/ICSharpCode.NRefactory.CSharp/OutputVisitor/CodeDomConvertVisitor.cs @@ -39,7 +39,7 @@ namespace ICSharpCode.NRefactory.CSharp public class CodeDomConvertVisitor : IAstVisitor { //ICompilation compilation = MinimalResolveContext.Instance; - ResolveVisitor resolveVisitor; + CSharpAstResolver resolver; bool useFullyQualifiedTypeNames; /// @@ -60,23 +60,17 @@ namespace ICSharpCode.NRefactory.CSharp /// /// This conversion process requires a resolver because it needs to distinguish field/property/event references etc. /// - public CodeCompileUnit Convert(CompilationUnit compilationUnit, ICompilation compilation) + public CodeCompileUnit Convert(ICompilation compilation, CompilationUnit compilationUnit, CSharpParsedFile parsedFile) { if (compilationUnit == null) throw new ArgumentNullException("compilationUnit"); if (compilation == null) throw new ArgumentNullException("compilation"); - throw new NotImplementedException(); - /* - using (var ctx = context.Synchronize()) { - ResolveVisitor resolveVisitor = new ResolveVisitor(new CSharpResolver(ctx), parsedFile); - resolveVisitor.Scan(compilationUnit); - return (CodeCompileUnit)Convert(compilationUnit, resolveVisitor); - }*/ + CSharpAstResolver resolver = new CSharpAstResolver(compilation, compilationUnit, parsedFile); + return (CodeCompileUnit)Convert(compilationUnit, resolver); } - /* /// /// Converts a C# AST node to CodeDom. /// @@ -87,29 +81,26 @@ namespace ICSharpCode.NRefactory.CSharp /// /// This conversion process requires a resolver because it needs to distinguish field/property/event references etc. /// - public CodeObject Convert(AstNode node, ResolveVisitor resolveVisitor) + public CodeObject Convert(AstNode node, CSharpAstResolver resolver) { if (node == null) throw new ArgumentNullException("node"); - if (resolveVisitor == null) - throw new ArgumentNullException("resolveVisitor"); + if (resolver == null) + throw new ArgumentNullException("resolver"); try { - this.resolveVisitor = resolveVisitor; - this.context = resolveVisitor.TypeResolveContext; + this.resolver = resolver; return node.AcceptVisitor(this); } finally { - this.resolveVisitor = null; - this.context = MinimalResolveContext.Instance; + this.resolver = null; } } - */ ResolveResult Resolve(AstNode node) { - if (resolveVisitor == null) + if (resolver == null) return ErrorResolveResult.UnknownError; else - return resolveVisitor.GetResolveResult(node); + return resolver.Resolve(node); } CodeExpression Convert(Expression expr) diff --git a/ICSharpCode.NRefactory.CSharp/Resolver/CSharpAstResolver.cs b/ICSharpCode.NRefactory.CSharp/Resolver/CSharpAstResolver.cs index 94cb773c89..d7b6f3d2f6 100644 --- a/ICSharpCode.NRefactory.CSharp/Resolver/CSharpAstResolver.cs +++ b/ICSharpCode.NRefactory.CSharp/Resolver/CSharpAstResolver.cs @@ -17,6 +17,7 @@ // DEALINGS IN THE SOFTWARE. using System; +using System.Threading; using ICSharpCode.NRefactory.CSharp.TypeSystem; using ICSharpCode.NRefactory.Semantics; using ICSharpCode.NRefactory.TypeSystem; @@ -73,13 +74,20 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver this.parsedFile = parsedFile; } + /// + /// Gets the type resolve context for the root resolver. + /// + public CSharpTypeResolveContext TypeResolveContext { + get { return initialResolverState.CurrentTypeResolveContext; } + } + /// /// Applies a resolver navigator. This will resolve the nodes requested by the navigator, and will inform the /// navigator of the results. /// This method must be called as the first operation on the CSharpAstResolver, it is invalid to apply a navigator /// after a portion of the file was already resolved. /// - public void ApplyNavigator(IResolveVisitorNavigator navigator) + public void ApplyNavigator(IResolveVisitorNavigator navigator, CancellationToken cancellationToken = default(CancellationToken)) { if (resolveVisitor != null) throw new InvalidOperationException("Applying a navigator is only valid as the first operation on the CSharpAstResolver."); @@ -91,7 +99,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver /// /// Resolves the specified node. /// - public ResolveResult Resolve(AstNode node) + public ResolveResult Resolve(AstNode node, CancellationToken cancellationToken = default(CancellationToken)) { if (resolveVisitor == null) { resolveVisitor = new ResolveVisitor(initialResolverState, parsedFile); @@ -104,7 +112,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver /// /// Gets the expected type for the specified node. This is the type being that a node is being converted to. /// - public IType GetExpectedType(Expression expr) + public IType GetExpectedType(Expression expr, CancellationToken cancellationToken = default(CancellationToken)) { throw new NotImplementedException(); } @@ -112,7 +120,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver /// /// Gets the conversion that is being applied to the specified expression. /// - public Conversion GetConversion(Expression expr) + public Conversion GetConversion(Expression expr, CancellationToken cancellationToken = default(CancellationToken)) { throw new NotImplementedException(); } diff --git a/ICSharpCode.NRefactory.CSharp/Resolver/ResolveVisitor.cs b/ICSharpCode.NRefactory.CSharp/Resolver/ResolveVisitor.cs index 0ddcbbe87e..6bfb09fcf7 100644 --- a/ICSharpCode.NRefactory.CSharp/Resolver/ResolveVisitor.cs +++ b/ICSharpCode.NRefactory.CSharp/Resolver/ResolveVisitor.cs @@ -97,7 +97,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver { if (resolver == null) throw new ArgumentNullException("resolver"); - this.resolver = resolver; + this.resolver = resolver.Clone(); this.parsedFile = parsedFile; this.navigator = navigator ?? new ConstantModeResolveVisitorNavigator(ResolveVisitorNavigationMode.Skip, null); this.voidResult = new ResolveResult(resolver.Compilation.FindType(KnownTypeCode.Void)); @@ -461,7 +461,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver ResolvedUsingScope previousUsingScope = resolver.CurrentUsingScope; try { if (parsedFile != null) - resolver.CurrentUsingScope = parsedFile.RootUsingScope.Resolve(resolver.CurrentTypeResolveContext); + resolver.CurrentUsingScope = parsedFile.RootUsingScope.Resolve(resolver.Compilation); ScanChildren(unit); return voidResult; } finally { @@ -474,7 +474,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver ResolvedUsingScope previousUsingScope = resolver.CurrentUsingScope; try { if (parsedFile != null) { - resolver.CurrentUsingScope = parsedFile.GetUsingScope(namespaceDeclaration.StartLocation).Resolve(resolver.CurrentTypeResolveContext); + resolver.CurrentUsingScope = parsedFile.GetUsingScope(namespaceDeclaration.StartLocation).Resolve(resolver.Compilation); } ScanChildren(namespaceDeclaration); // merge undecided lambdas before leaving the using scope so that diff --git a/ICSharpCode.NRefactory.CSharp/TypeSystem/CSharpAssembly.cs b/ICSharpCode.NRefactory.CSharp/TypeSystem/CSharpAssembly.cs index 379ebe2eeb..36d573460c 100644 --- a/ICSharpCode.NRefactory.CSharp/TypeSystem/CSharpAssembly.cs +++ b/ICSharpCode.NRefactory.CSharp/TypeSystem/CSharpAssembly.cs @@ -75,7 +75,7 @@ namespace ICSharpCode.NRefactory.CSharp.TypeSystem result = new List(); foreach (var parsedFile in projectContent.Files.OfType()) { var attributes = assemblyAttributes ? parsedFile.AssemblyAttributes : parsedFile.ModuleAttributes; - var context = new CSharpTypeResolveContext(this, parsedFile.RootUsingScope.Resolve(new CSharpTypeResolveContext(this))); + var context = new CSharpTypeResolveContext(this, parsedFile.RootUsingScope.Resolve(compilation)); foreach (var unresolvedAttr in attributes) { result.Add(unresolvedAttr.CreateResolvedAttribute(context)); } diff --git a/ICSharpCode.NRefactory.CSharp/TypeSystem/CSharpUnresolvedTypeDefinition.cs b/ICSharpCode.NRefactory.CSharp/TypeSystem/CSharpUnresolvedTypeDefinition.cs index bae8105e21..58c0015a62 100644 --- a/ICSharpCode.NRefactory.CSharp/TypeSystem/CSharpUnresolvedTypeDefinition.cs +++ b/ICSharpCode.NRefactory.CSharp/TypeSystem/CSharpUnresolvedTypeDefinition.cs @@ -43,7 +43,7 @@ namespace ICSharpCode.NRefactory.CSharp.TypeSystem public override ITypeResolveContext CreateResolveContext(ITypeResolveContext parentContext) { - return new CSharpTypeResolveContext(parentContext.CurrentAssembly, usingScope.Resolve(parentContext), parentContext.CurrentTypeDefinition); + return new CSharpTypeResolveContext(parentContext.CurrentAssembly, usingScope.Resolve(parentContext.Compilation), parentContext.CurrentTypeDefinition); } } } diff --git a/ICSharpCode.NRefactory.CSharp/TypeSystem/UsingScope.cs b/ICSharpCode.NRefactory.CSharp/TypeSystem/UsingScope.cs index 565dfce584..7b4d33a188 100644 --- a/ICSharpCode.NRefactory.CSharp/TypeSystem/UsingScope.cs +++ b/ICSharpCode.NRefactory.CSharp/TypeSystem/UsingScope.cs @@ -160,13 +160,12 @@ namespace ICSharpCode.NRefactory.CSharp.TypeSystem /// /// Resolves the namespace represented by this using scope. /// - public ResolvedUsingScope Resolve(ITypeResolveContext context) + public ResolvedUsingScope Resolve(ICompilation compilation) { - ICompilation compilation = context.Compilation; CacheManager cache = compilation.CacheManager; ResolvedUsingScope resolved = (ResolvedUsingScope)cache.GetShared(this); if (resolved == null) { - var csContext = new CSharpTypeResolveContext(compilation.MainAssembly, parent != null ? parent.Resolve(context) : null); + var csContext = new CSharpTypeResolveContext(compilation.MainAssembly, parent != null ? parent.Resolve(compilation) : null); resolved = (ResolvedUsingScope)cache.GetOrAddShared(this, new ResolvedUsingScope(csContext, this)); } return resolved; diff --git a/ICSharpCode.NRefactory.Tests/CSharp/Analysis/DefiniteAssignmentTests.cs b/ICSharpCode.NRefactory.Tests/CSharp/Analysis/DefiniteAssignmentTests.cs index dc4bf55f8f..9790990709 100644 --- a/ICSharpCode.NRefactory.Tests/CSharp/Analysis/DefiniteAssignmentTests.cs +++ b/ICSharpCode.NRefactory.Tests/CSharp/Analysis/DefiniteAssignmentTests.cs @@ -18,7 +18,10 @@ using System; using System.Linq; +using System.Threading; +using ICSharpCode.NRefactory.CSharp.Resolver; using ICSharpCode.NRefactory.TypeSystem; +using ICSharpCode.NRefactory.TypeSystem.Implementation; using NUnit.Framework; namespace ICSharpCode.NRefactory.CSharp.Analysis @@ -26,6 +29,12 @@ namespace ICSharpCode.NRefactory.CSharp.Analysis [TestFixture] public class DefiniteAssignmentTests { + DefiniteAssignmentAnalysis CreateDefiniteAssignmentAnalysis(Statement rootStatement) + { + var resolver = new CSharpAstResolver(new CSharpResolver(new SimpleCompilation(CecilLoaderTests.Mscorlib)), rootStatement); + return new DefiniteAssignmentAnalysis(rootStatement, resolver, CancellationToken.None); + } + [Test] public void TryFinally() { @@ -55,7 +64,7 @@ namespace ICSharpCode.NRefactory.CSharp.Analysis Statement stmt5 = tryCatchStatement.FinallyBlock.Statements.Single(); LabelStatement label = (LabelStatement)block.Statements.ElementAt(1); - DefiniteAssignmentAnalysis da = new DefiniteAssignmentAnalysis(block, CecilLoaderTests.Mscorlib); + DefiniteAssignmentAnalysis da = CreateDefiniteAssignmentAnalysis(block); da.Analyze("i"); Assert.AreEqual(0, da.UnassignedVariableUses.Count); Assert.AreEqual(DefiniteAssignmentStatus.PotentiallyAssigned, da.GetStatusBefore(tryCatchStatement)); @@ -105,7 +114,7 @@ namespace ICSharpCode.NRefactory.CSharp.Analysis TrueStatement = new BlockStatement(), FalseStatement = new BlockStatement() }; - DefiniteAssignmentAnalysis da = new DefiniteAssignmentAnalysis(ifStmt, CecilLoaderTests.Mscorlib); + DefiniteAssignmentAnalysis da = CreateDefiniteAssignmentAnalysis(ifStmt); da.Analyze("i"); Assert.AreEqual(0, da.UnassignedVariableUses.Count); Assert.AreEqual(DefiniteAssignmentStatus.PotentiallyAssigned, da.GetStatusBefore(ifStmt)); @@ -136,7 +145,7 @@ namespace ICSharpCode.NRefactory.CSharp.Analysis TrueStatement = new BlockStatement(), FalseStatement = new BlockStatement() }; - DefiniteAssignmentAnalysis da = new DefiniteAssignmentAnalysis(ifStmt, CecilLoaderTests.Mscorlib); + DefiniteAssignmentAnalysis da = CreateDefiniteAssignmentAnalysis(ifStmt); da.Analyze("i"); Assert.AreEqual(0, da.UnassignedVariableUses.Count); Assert.AreEqual(DefiniteAssignmentStatus.PotentiallyAssigned, da.GetStatusBefore(ifStmt)); @@ -155,7 +164,7 @@ namespace ICSharpCode.NRefactory.CSharp.Analysis new BreakStatement() } }; - DefiniteAssignmentAnalysis da = new DefiniteAssignmentAnalysis(loop, CecilLoaderTests.Mscorlib); + DefiniteAssignmentAnalysis da = CreateDefiniteAssignmentAnalysis(loop); da.Analyze("i"); Assert.AreEqual(0, da.UnassignedVariableUses.Count); Assert.AreEqual(DefiniteAssignmentStatus.PotentiallyAssigned, da.GetStatusBefore(loop)); @@ -187,7 +196,7 @@ namespace ICSharpCode.NRefactory.CSharp.Analysis new AssignmentExpression(new IdentifierExpression("j"), new IdentifierExpression("i")) )}; - DefiniteAssignmentAnalysis da = new DefiniteAssignmentAnalysis(loop, CecilLoaderTests.Mscorlib); + DefiniteAssignmentAnalysis da = CreateDefiniteAssignmentAnalysis(loop); da.Analyze("i"); Assert.AreEqual(0, da.UnassignedVariableUses.Count); Assert.AreEqual(DefiniteAssignmentStatus.PotentiallyAssigned, da.GetStatusBefore(loop)); diff --git a/ICSharpCode.NRefactory.Tests/CSharp/CodeDomConvertVisitorTests.cs b/ICSharpCode.NRefactory.Tests/CSharp/CodeDomConvertVisitorTests.cs index 3f59c3665f..82117603c3 100644 --- a/ICSharpCode.NRefactory.Tests/CSharp/CodeDomConvertVisitorTests.cs +++ b/ICSharpCode.NRefactory.Tests/CSharp/CodeDomConvertVisitorTests.cs @@ -17,8 +17,15 @@ // DEALINGS IN THE SOFTWARE. using System; +using System.CodeDom; +using System.CodeDom.Compiler; +using System.IO; +using System.Text.RegularExpressions; using ICSharpCode.NRefactory.CSharp.Resolver; using ICSharpCode.NRefactory.CSharp.TypeSystem; +using ICSharpCode.NRefactory.TypeSystem; +using ICSharpCode.NRefactory.TypeSystem.Implementation; +using Microsoft.CSharp; using NUnit.Framework; namespace ICSharpCode.NRefactory.CSharp @@ -27,33 +34,31 @@ namespace ICSharpCode.NRefactory.CSharp public class CodeDomConvertVisitorTests : ResolverTestBase { CodeDomConvertVisitor convertVisitor; - CSharpResolver resolver; + CSharpParsedFile parsedFile; public override void SetUp() { base.SetUp(); - resolver = new CSharpResolver(compilation); - throw new NotImplementedException(); - /*resolver.CurrentUsingScope = new UsingScope(); - resolver.CurrentUsingScope.Usings.Add(MakeReference("System")); - resolver.CurrentUsingScope.Usings.Add(MakeReference("System.Collections.Generic")); - resolver.CurrentUsingScope.Usings.Add(MakeReference("System.Linq")); - */ + parsedFile = new CSharpParsedFile("test.cs", new UsingScope()); + parsedFile.RootUsingScope.Usings.Add(MakeReference("System")); + parsedFile.RootUsingScope.Usings.Add(MakeReference("System.Collections.Generic")); + parsedFile.RootUsingScope.Usings.Add(MakeReference("System.Linq")); + convertVisitor = new CodeDomConvertVisitor(); convertVisitor.UseFullyQualifiedTypeNames = true; } string Convert(Expression expr) { - throw new NotImplementedException(); - /* - ResolveVisitor rv = new ResolveVisitor(resolver, null); - rv.Scan(expr); - var codeExpr = (CodeExpression)convertVisitor.Convert(expr, rv); + CSharpResolver resolver = new CSharpResolver(compilation); + resolver.CurrentUsingScope = parsedFile.RootUsingScope.Resolve(compilation); + resolver.CurrentTypeDefinition = compilation.FindType(KnownTypeCode.Object).GetDefinition(); + var codeExpr = (CodeExpression)convertVisitor.Convert(expr, new CSharpAstResolver(resolver, expr, parsedFile)); + StringWriter writer = new StringWriter(); writer.NewLine = " "; new CSharpCodeProvider().GenerateCodeFromExpression(codeExpr, writer, new CodeGeneratorOptions { IndentString = " " }); - return Regex.Replace(writer.ToString(), @"\s+", " ");*/ + return Regex.Replace(writer.ToString(), @"\s+", " "); } [Test] diff --git a/ICSharpCode.NRefactory.Tests/CSharp/Refactoring/TypeSystemAstBuilderTests.cs b/ICSharpCode.NRefactory.Tests/CSharp/Refactoring/TypeSystemAstBuilderTests.cs index 4288448785..8a9a260e92 100644 --- a/ICSharpCode.NRefactory.Tests/CSharp/Refactoring/TypeSystemAstBuilderTests.cs +++ b/ICSharpCode.NRefactory.Tests/CSharp/Refactoring/TypeSystemAstBuilderTests.cs @@ -80,7 +80,7 @@ namespace OtherNS { UsingScope usingScope = currentTypeDef != null ? parsedFile.GetUsingScope(currentTypeDef.Region.Begin) : parsedFile.RootUsingScope; return new TypeSystemAstBuilder( new CSharpResolver(compilation) { - CurrentUsingScope = usingScope.Resolve(compilation.TypeResolveContext), + CurrentUsingScope = usingScope.Resolve(compilation), CurrentTypeDefinition = currentTypeDef }); } diff --git a/ICSharpCode.NRefactory.Tests/CSharp/Resolver/NameLookupTests.cs b/ICSharpCode.NRefactory.Tests/CSharp/Resolver/NameLookupTests.cs index c009ba327d..cbb455c971 100644 --- a/ICSharpCode.NRefactory.Tests/CSharp/Resolver/NameLookupTests.cs +++ b/ICSharpCode.NRefactory.Tests/CSharp/Resolver/NameLookupTests.cs @@ -40,16 +40,6 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver resolver.CurrentUsingScope = MakeUsingScope(string.Empty); } - TypeOrNamespaceReference MakeReference(string namespaceName) - { - string[] nameParts = namespaceName.Split('.'); - TypeOrNamespaceReference r = new SimpleTypeOrNamespaceReference(nameParts[0], new ITypeReference[0], SimpleNameLookupMode.TypeInUsingDeclaration); - for (int i = 1; i < nameParts.Length; i++) { - r = new MemberTypeOrNamespaceReference(r, nameParts[i], new ITypeReference[0]); - } - return r; - } - ResolvedUsingScope MakeUsingScope(string namespaceName = "", string[] usings = null, KeyValuePair[] usingAliases = null) { UsingScope usingScope = new UsingScope(); @@ -66,7 +56,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver foreach (var pair in usingAliases) usingScope.UsingAliases.Add(new KeyValuePair(pair.Key, MakeReference(pair.Value))); } - return usingScope.Resolve(resolver.CurrentTypeResolveContext); + return usingScope.Resolve(resolver.Compilation); } [Test] @@ -145,7 +135,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver mainUsingScope.Usings.Add(MakeReference("System")); UsingScope nestedUsingScope = new UsingScope(mainUsingScope, "SomeNamespace"); nestedUsingScope.UsingAliases.Add(new KeyValuePair("x", MakeReference("String"))); - resolver.CurrentUsingScope = nestedUsingScope.Resolve(compilation.TypeResolveContext); + resolver.CurrentUsingScope = nestedUsingScope.Resolve(compilation); TypeResolveResult trr = (TypeResolveResult)resolver.ResolveSimpleName("x", new IType[0]); Assert.AreEqual("System.String", trr.Type.FullName); diff --git a/ICSharpCode.NRefactory.Tests/CSharp/Resolver/ResolverTestBase.cs b/ICSharpCode.NRefactory.Tests/CSharp/Resolver/ResolverTestBase.cs index 49f282b1a1..214a1413a8 100644 --- a/ICSharpCode.NRefactory.Tests/CSharp/Resolver/ResolverTestBase.cs +++ b/ICSharpCode.NRefactory.Tests/CSharp/Resolver/ResolverTestBase.cs @@ -69,6 +69,16 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver return new ResolveResult(ResolveType(type)); } + protected static TypeOrNamespaceReference MakeReference(string namespaceName) + { + string[] nameParts = namespaceName.Split('.'); + TypeOrNamespaceReference r = new SimpleTypeOrNamespaceReference(nameParts[0], new ITypeReference[0], SimpleNameLookupMode.TypeInUsingDeclaration); + for (int i = 1; i < nameParts.Length; i++) { + r = new MemberTypeOrNamespaceReference(r, nameParts[i], new ITypeReference[0]); + } + return r; + } + protected void AssertConstant(object expectedValue, ResolveResult rr) { Assert.IsFalse(rr.IsError, rr.ToString() + " is an error"); diff --git a/ICSharpCode.NRefactory/ICSharpCode.NRefactory.csproj b/ICSharpCode.NRefactory/ICSharpCode.NRefactory.csproj index 7c3473ddf4..652afb3ace 100644 --- a/ICSharpCode.NRefactory/ICSharpCode.NRefactory.csproj +++ b/ICSharpCode.NRefactory/ICSharpCode.NRefactory.csproj @@ -154,7 +154,7 @@ - + diff --git a/ICSharpCode.NRefactory/TypeSystem/Implementation/MinimalCorlib.cs b/ICSharpCode.NRefactory/TypeSystem/Implementation/MinimalCorlib.cs new file mode 100644 index 0000000000..1b8ac45dd6 --- /dev/null +++ b/ICSharpCode.NRefactory/TypeSystem/Implementation/MinimalCorlib.cs @@ -0,0 +1,68 @@ +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team +// +// Permission is hereby granted, free of charge, to any person obtaining a copy of this +// software and associated documentation files (the "Software"), to deal in the Software +// without restriction, including without limitation the rights to use, copy, modify, merge, +// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons +// to whom the Software is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all copies or +// substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, +// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE +// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS IN THE SOFTWARE. + +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Linq; + +namespace ICSharpCode.NRefactory.TypeSystem.Implementation +{ + /// + /// Resolve context represents the minimal mscorlib required for evaluating constants. + /// This contains all known types () and no other types. + /// + public sealed class MinimalCorlib : DefaultUnresolvedAssembly + { + static readonly Lazy instance = new Lazy(() => new MinimalCorlib()); + + public static MinimalCorlib Instance { + get { return instance.Value; } + } + + public ICompilation CreateCompilation() + { + return new SimpleCompilation(this); + } + + private MinimalCorlib() : base("corlib") + { + var types = new DefaultUnresolvedTypeDefinition[KnownTypeReference.KnownTypeCodeCount]; + for (int i = 0; i < types.Length; i++) { + var typeRef = KnownTypeReference.Get((KnownTypeCode)i); + if (typeRef != null) { + types[i] = new DefaultUnresolvedTypeDefinition(typeRef.Namespace, typeRef.Name); + for (int j = 0; j < typeRef.TypeParameterCount; j++) { + types[i].TypeParameters.Add(new DefaultUnresolvedTypeParameter(EntityType.TypeDefinition, j)); + } + AddTypeDefinition(types[i]); + } + } + for (int i = 0; i < types.Length; i++) { + var typeRef = KnownTypeReference.Get((KnownTypeCode)i); + if (typeRef != null && typeRef.baseType != KnownTypeCode.None) { + types[i].BaseTypes.Add(types[(int)typeRef.baseType]); + if (typeRef.baseType == KnownTypeCode.ValueType && i != (int)KnownTypeCode.Enum) { + types[i].Kind = TypeKind.Struct; + } + } + } + Freeze(); + } + } +} diff --git a/ICSharpCode.NRefactory/TypeSystem/Implementation/MinimalResolveContext.cs b/ICSharpCode.NRefactory/TypeSystem/Implementation/MinimalResolveContext.cs deleted file mode 100644 index 4c73c719da..0000000000 --- a/ICSharpCode.NRefactory/TypeSystem/Implementation/MinimalResolveContext.cs +++ /dev/null @@ -1,182 +0,0 @@ -// Copyright (c) AlphaSierraPapa for the SharpDevelop Team -// -// Permission is hereby granted, free of charge, to any person obtaining a copy of this -// software and associated documentation files (the "Software"), to deal in the Software -// without restriction, including without limitation the rights to use, copy, modify, merge, -// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons -// to whom the Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all copies or -// substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, -// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE -// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. - -using System; -using System.Collections.Generic; -using System.Collections.ObjectModel; -using System.Linq; - -namespace ICSharpCode.NRefactory.TypeSystem.Implementation -{ - /* - /// - /// Resolve context represents the minimal mscorlib required for evaluating constants. - /// - public sealed class MinimalResolveContext : AbstractAnnotatable, IProjectContent, ISynchronizedTypeResolveContext - { - static readonly Lazy instance = new Lazy(() => new MinimalResolveContext()); - - public static MinimalResolveContext Instance { - get { return instance.Value; } - } - - readonly ReadOnlyCollection namespaces = Array.AsReadOnly(new string[] { "System" }); - readonly ITypeDefinition systemObject, systemValueType; - readonly ReadOnlyCollection types; - - private MinimalResolveContext() - { - List types = new List(); - - systemObject = new DefaultTypeDefinition(this, "System", "Object") { - Accessibility = Accessibility.Public - }; - systemValueType = new DefaultTypeDefinition(this, "System", "ValueType") { - Accessibility = Accessibility.Public, - BaseTypes = { systemObject } - }; - // TypeCode.Empty = void - types.Add(new VoidTypeDefinition(this)); - // types are added in the order they are defined in the TypeCode enum - types.Add(systemObject); - types.Add(CreateClass("System", "DBNull")); - types.Add(CreateStruct("System", "Boolean")); - types.Add(CreateStruct("System", "Char")); - types.Add(CreateStruct("System", "SByte")); - types.Add(CreateStruct("System", "Byte")); - types.Add(CreateStruct("System", "Int16")); - types.Add(CreateStruct("System", "UInt16")); - types.Add(CreateStruct("System", "Int32")); - types.Add(CreateStruct("System", "UInt32")); - types.Add(CreateStruct("System", "Int64")); - types.Add(CreateStruct("System", "UInt64")); - types.Add(CreateStruct("System", "Single")); - types.Add(CreateStruct("System", "Double")); - types.Add(CreateStruct("System", "Decimal")); - types.Add(CreateStruct("System", "DateTime")); - types.Add(systemValueType); // misuse unused enum value (TypeCode)17 for System.ValueType - types.Add(CreateClass("System", "String")); - foreach (ITypeDefinition type in types) - type.Freeze(); - this.types = types.AsReadOnly(); - } - - ITypeDefinition CreateClass(string nameSpace, string name) - { - return new DefaultTypeDefinition(this, nameSpace, name) { - Kind = TypeKind.Class, - Accessibility = Accessibility.Public, - BaseTypes = { systemObject } - }; - } - - ITypeDefinition CreateStruct(string nameSpace, string name) - { - return new DefaultTypeDefinition(this, nameSpace, name) { - Kind = TypeKind.Struct, - Accessibility = Accessibility.Public, - BaseTypes = { systemValueType } - }; - } - - public ITypeDefinition GetTypeDefinition(string nameSpace, string name, int typeParameterCount, StringComparer nameComparer) - { - foreach (ITypeDefinition type in types) { - if (nameComparer.Equals(type.Name, name) && nameComparer.Equals(type.Namespace, nameSpace) && type.TypeParameterCount == typeParameterCount) - return type; - } - return null; - } - - public ITypeDefinition GetKnownTypeDefinition(TypeCode typeCode) - { - return types[(int)typeCode]; - } - - public IEnumerable GetTypes() - { - return types; - } - - public IEnumerable GetTypes(string nameSpace, StringComparer nameComparer) - { - return types.Where(t => nameComparer.Equals(t.Namespace, nameSpace)); - } - - public IEnumerable GetNamespaces() - { - return namespaces; - } - - public string GetNamespace(string nameSpace, StringComparer nameComparer) - { - foreach (string ns in namespaces) { - if (nameComparer.Equals(ns, nameSpace)) - return ns; - } - return null; - } - - IList IProjectContent.AssemblyAttributes { - get { return EmptyList.Instance; } - } - - IList IProjectContent.ModuleAttributes { - get { return EmptyList.Instance; } - } - - ICSharpCode.NRefactory.Utils.CacheManager ITypeResolveContext.CacheManager { - get { - // We don't support caching - return null; - } - } - - ISynchronizedTypeResolveContext ITypeResolveContext.Synchronize() - { - // This class is immutable - return this; - } - - void IDisposable.Dispose() - { - // exit from Synchronize() block - } - - IParsedFile IProjectContent.GetFile(string fileName) - { - return null; - } - - IEnumerable IProjectContent.Files { - get { - return EmptyList.Instance; - } - } - - void IProjectContent.UpdateProjectContent(IParsedFile oldFile, IParsedFile newFile) - { - throw new NotSupportedException(); - } - - public string AssemblyName { - get { return "MinimalResolveContext"; } - } - } - */ -} diff --git a/ICSharpCode.NRefactory/TypeSystem/KnownTypeReference.cs b/ICSharpCode.NRefactory/TypeSystem/KnownTypeReference.cs index cb819bd282..d38149ea15 100644 --- a/ICSharpCode.NRefactory/TypeSystem/KnownTypeReference.cs +++ b/ICSharpCode.NRefactory/TypeSystem/KnownTypeReference.cs @@ -123,22 +123,22 @@ namespace ICSharpCode.NRefactory.TypeSystem static readonly KnownTypeReference[] knownTypeReferences = new KnownTypeReference[KnownTypeCodeCount] { null, // None - new KnownTypeReference(KnownTypeCode.Object, "System", "Object"), + new KnownTypeReference(KnownTypeCode.Object, "System", "Object", baseType: KnownTypeCode.None), new KnownTypeReference(KnownTypeCode.DBNull, "System", "DBNull"), - new KnownTypeReference(KnownTypeCode.Boolean, "System", "Boolean"), - new KnownTypeReference(KnownTypeCode.Char, "System", "Char"), - new KnownTypeReference(KnownTypeCode.SByte, "System", "SByte"), - new KnownTypeReference(KnownTypeCode.Byte, "System", "Byte"), - new KnownTypeReference(KnownTypeCode.Int16, "System", "Int16"), - new KnownTypeReference(KnownTypeCode.UInt16, "System", "UInt16"), - new KnownTypeReference(KnownTypeCode.Int32, "System", "Int32"), - new KnownTypeReference(KnownTypeCode.UInt32, "System", "UInt32"), - new KnownTypeReference(KnownTypeCode.Int64, "System", "Int64"), - new KnownTypeReference(KnownTypeCode.UInt64, "System", "UInt64"), - new KnownTypeReference(KnownTypeCode.Single, "System", "Single"), - new KnownTypeReference(KnownTypeCode.Double, "System", "Double"), - new KnownTypeReference(KnownTypeCode.Decimal, "System", "Decimal"), - new KnownTypeReference(KnownTypeCode.DateTime, "System", "DateTime"), + new KnownTypeReference(KnownTypeCode.Boolean, "System", "Boolean", baseType: KnownTypeCode.ValueType), + new KnownTypeReference(KnownTypeCode.Char, "System", "Char", baseType: KnownTypeCode.ValueType), + new KnownTypeReference(KnownTypeCode.SByte, "System", "SByte", baseType: KnownTypeCode.ValueType), + new KnownTypeReference(KnownTypeCode.Byte, "System", "Byte", baseType: KnownTypeCode.ValueType), + new KnownTypeReference(KnownTypeCode.Int16, "System", "Int16", baseType: KnownTypeCode.ValueType), + new KnownTypeReference(KnownTypeCode.UInt16, "System", "UInt16", baseType: KnownTypeCode.ValueType), + new KnownTypeReference(KnownTypeCode.Int32, "System", "Int32", baseType: KnownTypeCode.ValueType), + new KnownTypeReference(KnownTypeCode.UInt32, "System", "UInt32", baseType: KnownTypeCode.ValueType), + new KnownTypeReference(KnownTypeCode.Int64, "System", "Int64", baseType: KnownTypeCode.ValueType), + new KnownTypeReference(KnownTypeCode.UInt64, "System", "UInt64", baseType: KnownTypeCode.ValueType), + new KnownTypeReference(KnownTypeCode.Single, "System", "Single", baseType: KnownTypeCode.ValueType), + new KnownTypeReference(KnownTypeCode.Double, "System", "Double", baseType: KnownTypeCode.ValueType), + new KnownTypeReference(KnownTypeCode.Decimal, "System", "Decimal", baseType: KnownTypeCode.ValueType), + new KnownTypeReference(KnownTypeCode.DateTime, "System", "DateTime", baseType: KnownTypeCode.ValueType), null, new KnownTypeReference(KnownTypeCode.String, "System", "String"), new KnownTypeReference(KnownTypeCode.Void, "System", "Void"), @@ -146,21 +146,21 @@ namespace ICSharpCode.NRefactory.TypeSystem new KnownTypeReference(KnownTypeCode.Array, "System", "Array"), new KnownTypeReference(KnownTypeCode.Attribute, "System", "Attribute"), new KnownTypeReference(KnownTypeCode.ValueType, "System", "ValueType"), - new KnownTypeReference(KnownTypeCode.Enum, "System", "Enum"), + new KnownTypeReference(KnownTypeCode.Enum, "System", "Enum", baseType: KnownTypeCode.ValueType), new KnownTypeReference(KnownTypeCode.Delegate, "System", "Delegate"), - new KnownTypeReference(KnownTypeCode.MulticastDelegate, "System", "MulticastDelegate"), + new KnownTypeReference(KnownTypeCode.MulticastDelegate, "System", "MulticastDelegate", baseType: KnownTypeCode.Delegate), new KnownTypeReference(KnownTypeCode.Exception, "System", "Exception"), - new KnownTypeReference(KnownTypeCode.IntPtr, "System", "IntPtr"), - new KnownTypeReference(KnownTypeCode.UIntPtr, "System", "UIntPtr"), + new KnownTypeReference(KnownTypeCode.IntPtr, "System", "IntPtr", baseType: KnownTypeCode.ValueType), + new KnownTypeReference(KnownTypeCode.UIntPtr, "System", "UIntPtr", baseType: KnownTypeCode.ValueType), new KnownTypeReference(KnownTypeCode.IEnumerable, "System.Collections", "IEnumerable"), new KnownTypeReference(KnownTypeCode.IEnumerator, "System.Collections", "IEnumerator"), new KnownTypeReference(KnownTypeCode.IEnumerableOfT, "System.Collections.Generic", "IEnumerable", 1), new KnownTypeReference(KnownTypeCode.IEnumeratorOfT, "System.Collections.Generic", "IEnumerator", 1), new KnownTypeReference(KnownTypeCode.IListOfT, "System.Collections.Generic", "IList", 1), new KnownTypeReference(KnownTypeCode.Task, "System.Threading.Tasks", "Task"), - new KnownTypeReference(KnownTypeCode.TaskOfT, "System.Threading.Tasks", "Task", 1), - new KnownTypeReference(KnownTypeCode.NullableOfT, "System", "Nullable", 1), - new KnownTypeReference(KnownTypeCode.IDisposable, "System", "IDispoable"), + new KnownTypeReference(KnownTypeCode.TaskOfT, "System.Threading.Tasks", "Task", 1, baseType: KnownTypeCode.Task), + new KnownTypeReference(KnownTypeCode.NullableOfT, "System", "Nullable", 1, baseType: KnownTypeCode.ValueType), + new KnownTypeReference(KnownTypeCode.IDisposable, "System", "IDisposable"), }; /// @@ -366,13 +366,15 @@ namespace ICSharpCode.NRefactory.TypeSystem readonly string namespaceName; readonly string name; readonly int typeParameterCount; + internal readonly KnownTypeCode baseType; - private KnownTypeReference(KnownTypeCode knownTypeCode, string namespaceName, string name, int typeParameterCount = 0) + private KnownTypeReference(KnownTypeCode knownTypeCode, string namespaceName, string name, int typeParameterCount = 0, KnownTypeCode baseType = KnownTypeCode.Object) { this.knownTypeCode = knownTypeCode; this.namespaceName = namespaceName; this.name = name; this.typeParameterCount = typeParameterCount; + this.baseType = baseType; } public KnownTypeCode KnownTypeCode {