Browse Source

Squashed 'NRefactory/' changes from 180a690..e2eef88

e2eef88 Add 'HasBody' property to IMethod. Closes #100.
2ed6497 Merge pull request #101 from mono-soc-2012/mansheng
aedf4e2 [CodeActions] ConvertImplicitToExplicitImplementationAction: removed a redundant test
1d3c30b Merge remote-tracking branch 'upstream/master' into mansheng
612ab59 Merge pull request #99 from mono-soc-2012/simonl
2a45c1e Merge branch 'master' into simonl
aa55c20 Add AbstractUnresolvedEntity.Clone() method.
e975667 [Formatting] Fixed wrong default option.
4945fa5 [CodeIssues] MultipleEnumerationIssue: added documentation
dc7fa56 [CodeIssue] RedundantAssignmentIssue: fixed a bug in issue finding
b7f6501 [CodeIssues] Improve ParameterCanBeDemotedIssue.
408b298 [TypeSystem] Don't consider non-public members for interface implementors.
79b4c25 [CodeIssues] ParameterCanBeDemotedIssue: Add Criterions for suitable indexer members and for array types. Also start resolving the method with the new type to check for errors.
458bd90 [CodeIssues] Add incomplete dependency tracking to VariableDeclaredInWideScopeIssue.
a27b051 [CodeIssues] ConstantConditionIssue: check if condition is compile time constant to avoid fake warnings
352dcce [CodeIssues] CompareBooleanWithTrueOrFalseIssue: check if the expression being compared is of boolean type
588b127 [CodeIssues] MethodNeverReturnsIssue: handle 'throw' case
71e42df [CodeActions] Moved GetDefaultValueExpression back to CreateOverloadWithoutParameterAction class
6f063c6 [CodeIssues] RedundantFieldInitializerIssue: handle some number type initializer cases
c403f38 Move the fix for #94 into CSharpConversions.IsConstraintConvertible.
40bbafd Set NET_4_0 preprocessor symbol for mcs. Rename "NET45" to "NET_4_5" to be consistent with mcs and Mono.Cecil.
284a4cc Fix InvalidCastException in MemberLookup.RemoveInterfaceMembersHiddenByClassMembers
8ede23f Merge pull request #94 from erik-kallen/InvokeGenericMethodWithNullableTypeArgument
eb4de73 Merge pull request #93 from erik-kallen/DuplicateUsingsIssue
740a30c [Completion] CreateNamespace completion data now takes a INamespace instead of a string.
f3ae264 [Demo] Reverted an unnecessary change
f5c370a [CodeIssues] MethodOverloadHidesOptionalParameterIssue: fixed namespace
8d77f4b [CodeIssues] Removed some unused usings
f1dad51 [CodeActions] CreateCustomEventImplementationAction: removed TODO which is already done.
11b9fd1 [CodeActions]ConvertLambdaBodyExpressionToStatementAction: removed unused usings
c461c7b [CodeActions] ConvertConditionalToIfAction: check context location
0140f2d [CodeActions] ConvertCastToAsAction: fixed tests
90356ad [CodeActions] ConvertCastToAsAction: check context location. Reorganized code.
f2b8be7 [CodeAction] ConvertAsToCastAction: check context location
9c521f8 Fixed issue with nullable types not being usable as generic arguments.
a00495c Test that demonstrates that a generic method cannot be invoked with a nullable type argument.
a9e0bd9 [CodeIssues] IncorrectCallTogetHashCodeIssue: Only look at calls to members of 'base' or 'this'.
5b29f2b Fixed issue with duplicate using directives.
d857a8b Test demonstrating issue with duplicate using directive.
821e157 [CodeIssues] VariableDeclaredInWideScopeIssue: Handle nested scopes that are not BlockStatements and don't suggest moving declarations into closures
713b88f [CodeIssues] Don't consider empty catches redundant.
611cc25 Merge remote-tracking branch 'upstream/master' into mansheng
c63f65a [CodeIssue] Added MethodOverloadHidesOptionalParameterIssue
810c03a NRefactory 5.2.0 release
76670db [CodeActions] Add ConvertLambdaToAnonymousDelegateAction.
1797fa2 [CodeActions] Add convertAnonymousDelegateToLambdaAction.
0b56b42 Remove redundant call to ValidateMethodConstraints(). Fix demo application.
eeb5c3f Added unit test to check completion in #if regions.
d2038a4 [Completion] Added conditional symbols to the completion engine context.
ddd341b [CodeActions] Fixed bug in create backing store.
19815e8 Merge branch 'master' into simonl
352b20c [CodeIssue] Added RedundantObjectCreationArgumentListIssue
9a8d671 [CodeIssue] RedundantObjectOrCollectionInitializerIssue: added some tests
c0870db [CodeIssue] Added RedundantObjectOrCollectionInitializerIssue
4af1379 [CodeIssue] Added RedundantCaseLabelIssue
b5bd89b [Refactoring] track renaming of ParsedFile to UnresolvedFile
7a2d9f8 Merge remote-tracking branch 'upstream/master' into mansheng
c3a31c9 Fix #92: The resolver does not check type constraints on calls to generic methods
1f6c4f0 Update solution-loading logic in ConsistencyCheck.
2c24a05 Merge branch 'master' into simonl
86e4d9a [CodeIssue] Added CastExpressionOfIncompatibleTypeIssue
16aa0c6 Rename IParsedFile -> IUnresolvedFile to make clear it belongs to the unresolved type system.
4a6a43d Change output path - build everything into \bin\Debug in NRefactory directory (not into ICSharpCode.NRefactory subdirectory).
7a3b25b Add WriteTextTo() method to ITextSource.
9a9485a Add ProjectReference class to NRefactory to simplify creating the type system for a solution with multiple projects.
5241e34 Merge pull request #91 from mono-soc-2012/simonl-attributesection-fix
ea49b1a [CodeIssues] Add StaticFieldInGenericTypeIssue.
7c19dfa [Parser] Set locations of AttributeSections correctly.
4424f0e [Parser] Add failing unit tests for AttributeSections with multiple attributes.
e5f5d6c [CodeIssues] Add ThreadStaticOnInstanceFieldsIssue.
fec84f8 Implemented missing operation on new SeekableStreamReader
699d841 Merge pull request #90 from erik-kallen/FixOrderByParsing
7794385 Enabled query expander tests now that multiple orderings are supported.
32d43b2 Fixed query orderings when ordering by more than one expression.
cdfde8b [CodeActions] Greatly improved OptionalParameterCouldBeSkippedIssue.
8635a6f Merge remote-tracking branch 'upstream/master' into mansheng
d9dbd25 [CodeIssue] Added RedundantArrayInitializerCommaIssue
62a8b20 Fix icsharpcode/NRefactory#89: explicit conversion of array to generic IList fails when array covariance is used.
82ab94f [CodeIssues] OptionalParameterCouldBeSkippedIssue: Check for unmappable arguments.
d69abea [CodeActions] Handle resolution errors in IterateViaForeachAction.
1371e6d [CodeIssues] Fix bugs in RedundantCatchIssue.
d6054d1 [CodeIssues] Add ExceptionRethrowIssue
78cf6b1 Merge remote-tracking branch 'upstream/master' into mansheng
e97b6b2 [Parser] Fixed some optional comma bugs.
ff4b265 [CodeIssue] Added MethodNeverReturnsIssue
087aee7 Simplify parser API.
83776a1 [CodeIssue] Added RedundantAttributeParenthesesIssue
34932ef [Parser] Hacked work around for parser error.
29c686a [CodeIssue] Added DoubleNegationIssue
f81ecd7 [Parser] Implemented own seekable stream reader.
102ce25 Merge pull request #87 from erik-kallen/DynamicExpressionsUseNamedArgumentResolveResult
927f263 Merge pull request #85 from erik-kallen/QueryExpressionExpander
26409db Implemented explicit conversions - invalid casts now resolve to Conversion.None.
73b80fc [CodeIssues] CallToObjectViaBaseIssue: Ignore calls which do not target members of 'base'.
eaba979 Rename 'cu' to 'syntaxTree'.
979fa91 Fix icsharpcode/NRefactory#88: implicit conversion between type parameters.
7038892 Ensure that named argument instances are unique for dynamic invocations.
273178a Rename CompilationUnit to SyntaxTree.
93940f8 [CodeIssue] RedundantToStringIssue: Don't crash on parameter with declaration-less types.
7375967 Merge remote-tracking branch 'upstream/master' into mansheng
0af0137 Use NamedArgumentResolveResult for dynamic invocations.
7ece3ce Statements ending in select (i) now acts as if the statement was not parenthesized.
9a53205 Merge remote-tracking branch 'upstream/master' into simonl
17cdd1f [CodeAction] Add ConvertInitializerToExplicitInitializationsAction.
35475a2 [Refactoring] Make NamingHelper less horrible and remove the helper from RefactoringContext.
cc37a71 TypeSystemAstBuilder: do not specify accessibility on accessors unless necessary.
4717de9 Optimized the AstNode.Descendants property.
07fb368 Add visitor benchmark.
359fdd2 Provide both Enter and Leave events in ObservableAstVisitor.
d4372bf Add DefaultAttribute.
fb44364 Remove outdated code contracts.
d6b4420 Introduced NamedArgumentResolveResult.
6bd0bfc Add failing unit test for CompilationUnit.ConditionalSymbols.
8728c08 Add project configurations for .NET 4.5.
3f782ce Add ITypeDefinition.GetInterfaceImplementation().
0f82920 GenerateProperty: do not propose to generate a setter if the field is readonly.
f4e5cbd Merge remote-tracking branch 'upstream/master' into mansheng
574b3d2 [CodeIssue] CompareFloatWithEqualityOperator: handle a failed test case
0ee9c33 [CodeIssue] Added ReferenceEqualsCalledWithValueTypeIssue
10fc738 [CodeIssue] Added ExpressionIsNeverOfProvidedTypeIssue
0ba24d9 [CodeIssue] Added ExpressionIsAlwaysOfProvidedTypeIssue
60607bc Fix icsharpcode/NRefactory#86: method declaration with attributes fails to resolve since 2926e24.
7d5f1e0 Make CecilResolvedAttribute.DecodeBlob() more robust.
522d6c6 [CodeActions] Fix bugs in ConvertToInitializer.
88d89e7 [CodeActions] ConvertToInitializer: Handle collections with Add() calls taking multiple arguments.
903e46d [CodeActions] Cleanups in StatementsToInitializerConverter.
2426d1e Rename method ExpandQueryExpression to ExpandQueryExpressions.
e384bfb [CodeActons] Handle more edge cases in ConvertToInitializer.
0deb852 Report parameter instead of its name token in the result map, unpack parenthesized expressions.
4dbac01 [CodeActions] Fix bugs in ConvertToInitializerAction.
40b8ce5 [CodeIssues] Converted IgnoreConstructors to a property.
0eaf61e [Completion] Fixed wrong delegate signature.
99de4e1 Updated mcs.
bf69983 Merge remote-tracking branch 'upstream/master' into mansheng
384e0b6 [CodeIssue] CompareFloatWithEqualityOperatorIssue: fixed 'NaN' issue
47f2531 [CodeIssue] ConstantConditionIssue: use a better title
5c4a2da [CodeAction] NegateRelationalExpressionAction: fixed title
f5d0318 [CodeAction] JoinStringAction: handle the case when left operand is a BinaryOperatorExpression
b0f16b2 Test to ensure that range variables are not in scope for join equals expression, renamed method.
40266d1 Inherit QueryExpressionExpander from DepthFirstAstVisitor.
2926e24 C# type system convert visitor: do not include attributes in IEntity.Region
e83d77a Ignore redundant 'this' in constructors.
7db1cbe Merge NRefactory changes from SharpDevelop repository:
cb034bd Implemented QueryExpressionExpander.
b8b2c61 [CodeIssue] Added CompareBooleanWithTrueOrFalseIssue
93fae44 [CodeAction] Added JoinDeclarationAndAssignmentAction
580fa30 Merge remote-tracking branch 'upstream/master' into mansheng
f47fd76 [CodeIssues] RedundantToStringIssue: Also check formatting calls.
23d282d [Completion] Only check browsable attribute inside the same assembly.
a08bde6 Fixed tests.
5418c1c [NRefactory] Removed Browsable Attribute from GetEditorBrowsableState - that attribute should not affect completion, only design time editors.
6575de9 [Completion] Moved the browsable check helper methods to nrefactory. The browsable state is a .NET feature and not C# specific.
a747e47 [CodeIssues] Use IsKnownType in more places.
8dc6911 [Completion] Generalized browsable state method.
bea810b [Completion] Recognized browsable attributes / streamlined completion API a bit.
c60e01e [Completion] Show synthetic members again.
56114fe Simplify ImplementInterfaceAction by using the TypeSystemAstBuilder.
264c4c1 [CodeIssues] Use IsKnownType to check for System.Object.
b0e12f0 Merge remote-tracking branch 'upstream/master' into mansheng
3ef7fd7 Merge remote-tracking branch 'upstream/master' into simonl
b14db35 [CodeIssue] CompareFloatWithEqualityOperatorIssue: handle double.NaN case
3be1ef1 [CodeIssue] NegativeRelationalExpressionIssue: no longer report issues for floating-point operations
dbdb7c7 [CodeIssues] Handle non-object base classes in IncorrentCallTogetHashCodeIssue and CallToObjectEqualsViaBaseIssue.
80d02a5 [CodeIssues] RedundantTypeCastIssue: use .Equals() for comparing types
519dc12 Add IsKnownType() extension method.
58fea52 [Completion] Added more synthetic member checks/added forgotton accessible check for nested types.
40ba86a [Completion] Added some synthetic member checks.
c954742 Merge remote-tracking branch 'upstream/master' into simonl
ecf167d [CodeIssues] Add IncorrectCalltoGetHashCodeIssue.
f7a0fb5 Merge remote-tracking branch 'upstream/master' into mansheng
0cf2d39 [CodeIssue] Renamed DoubleNegationExpressionIssue to NegativeRelationalExpressionIssue
5307b16 [CodeAction] Added JoinStringAction
783a79c [CodeIssues] Add CallToObjectEqualsViaBaseIssue.
444ecf7 [CodeIssues] Add RedundantToStringIssue.
a3534f2 Add INamespace.ContributingAssemblies.
144ddcd [CodeIssue] Added DoubleNegationExpressionIssue
c71b3fa [CodeAction] NegateRelationalExpressionAction: improved tests
c9612ed [CodeAction] NegateRelationalExpressionAction: use CSharpUtil.NegateRelationalOperator
0b81174 [Ast] CSharpUtil: extract negating a relational operator into a method
8b026d4 Script.Link() dummy implementation: return a completed task instead of null.
fa9d5ac [CodeAction] Added NegateRelationalExpressionAction
79ae62a Merge remote-tracking branch 'upstream/master' into mansheng
bfe463b NRefactory 5.1.0
4513b6e Avoid NullReferenceExceptions now that MethodGroupResolveResult.TargetResult can be null.
41b7775 Merge pull request #80 from erik-kallen/DynamicImprovementsNewTry
3ddf30c Fix icsharpcode/NRefactory#71: entity type for indexers (explicit interface implementations)
acb1218 Test demonstrating issue with EntityType for indexers that explicitly implement interface members.
65097ed Add unit test for named attribute argument.
dfbca85 Add (failing) unit test for icsharpcode/NRefactory#56.
a15921d Merge pull request #81 from erik-kallen/IsConstantExpressionConversion
f3d13ee Added property Conversion.IsConstantExpressionConversion
916cc2a Fixed issues pointed out by Daniel.
6192d7a Documentation for MethodListWithDeclaringType
d7ebf92 Add (failing) unit tests for icsharpcode/NRefactory#45
9e84873 Change "string[] Conditionals" to "IList<string> ConditionalSymbols"
ecd3de7 Implementation of feature
ce5a42c Tests for the improved dynamic handling.
13dce76 Add Conversion.IsNullLiteralConversion (icsharpcode/NRefactory#59)
ea5e36c Fix icsharpcode/NRefactory#60: Implicit type parameter conversion
b656371 Implemented C# cref parser.
90c1b11 [CodeIssue] ConstantConditionIssue: use 'true'/'false' instead of 'True'/'False' in title
6c33cf8 [CodeIssue] IdenticalConditionalBranchIssue: use a better title
dab4b01 [CodeIssue] AssignmentMadeToSameVariableIssue: use a better title
3d74abb Use directly specific corlib implementation for GetAllBaseTypesTest so that the tests don't fail if interfaces are added to .NET BCL types.
9640abd Add (failing) unit test for icsharpcode/NRefactory#73.
0e7fe7a Merge pull request #77 from erik-kallen/MembersInDerivedInterfacesShouldNotImplementBaseMembers
93e2def Fix #75: conversion between delegate types
32ee4d4 Fix icsharpcode/NRefactory#76: definite assignment analysis ignores false part of conditional expressions.
dd07a77 CSharpParser: when parsing part of a compilation unit, detach the resulting nodes from the dummy compilation.
ad46ffd Merge remote-tracking branch 'upstream/master' into mansheng
209d3f0 [CodeIssue] Added RedundantTypeCastIssue
e71a8fd Fixed conditional symbol bug.
d1f0807 Use location from Cecil instead of providing it as an extra parameter to LoadAssembly().
5a1f7d7 Fixed issues with CecilLoader.LazyLoad=true.
ed0e4c5 Fixed conversions from "dynamic" - these only exist from expressions, not from the type (this was causing subtle issues with type inference).
8090455 [Parser] Added conditional symbols to the compilation unit.
5f60958 [TypeSystem] Cecil loader can now take the loaded assembly location.
14addf4 [TypeSystem] Added SetLocation to IProjectContent.
be9a3ed [Completion] Fixed get extension method call in parameter completion.
c032382 [TypeSystem] Added location property to IAssembly.
1146033 Fixed get extension method call.
1d499ae [CodeIssues] Remove unused field.
58d7ac0 Improved ToString() for methods.
5592e88 Fixed bug when passing an extension method as a method group to a generic function.
cc35fcc Revert f01a4b2 and 58c4ec8. Fixed small issue in CSharpResolver.GetExtensionMethods: when type parameters are provided explicitly, use the specialized method for the eligibility check.
0a7fdcd [CodeCompletion] No longer show static enum members on enum types (even if the call is theoretical valid).
247d588 [CodeIssues] Fix some false suggestions in VariableDeclaredInWideScopeIssue.
c2b1946 [CodeIssue]RedundantElseIssue: changed Severity to Warning
54fbfc8 [CodeIssue] Added ConstantConditionIssue
092a18f [CodeIssues] Check redundant optional arguments of constructors.
342c87a [Utils] Don't allow escape sequences in numeric fields of format items.
1e561dd [CodeIssues] Be more allowing when picking format string arguments in FormatStringIssue.
58c4ec8 [Resolver] Fixed type inference use case. Daniel: The fix may not be correct - it's hard to tell which side effects that change will cause.
c7de3da [CodeAction] Fixed getter/setters of the implemented interface/abstract class properties & indexers.
4f70f16 [CodeActions] Implemented abstract members action/Improved implement interface action & fixed unit tests.
2154c15 Merge remote-tracking branch 'upstream/master' into mansheng
4acb9b8 [Resolver] Don't check the location of value parameters in accessors. (Revert remaining parts of revision e60567ab869d59e74397c34cd994b2c732c615f4)
ebfd941 [CodeIssues] Fix ValueParameterUnusedIssue.
b375e1f [CodeIssues] Add RedundantCatchIssue.
77fd14e [CodeIssue] Added IdenticalConditionalBranchIssue
1863ed6 [CodeAction] Implement interface now tends to implement the more specialized members non explicit.
fea0060 [CodeIssue] Added AssignmentMadeToSameVariableIssue
286091b [CodeActions] Finished first implement interface implementation.
cbf1bdf Merge remote-tracking branch 'upstream/master' into mansheng
a4344c8 Checked for possible null refrence exception.
461d5da [Completion] Fixed completion bug.
d4209d0 [CodeAction] Fixed extract method unit test.
4a5d1e8 [CodeAction] Fixed most extract method tests.
61faaca [CodeIssue] RedundantAssignmentIssue: fixed incorrect text marking
f9aa82c Merge remote-tracking branch 'upstream/master' into mansheng
63a8ca1 [CodeIssue] Added RedundantAssignmentIssue
e6abbcb [CodeIssue] Added MultipleEnumerationIssue
c37d18a [CodeIssue] ParameterNotUsedIssue: only check parameters of methods
21a87ec [CodeIssue] VariableOnlyAssignedIssue: out argument should be considered as assignment
2c98a2c [Completion] Filter out System.Void type
3963b40 Fix
0bc0d09 Failing test.
cf69275 [Completion] Fix enum method list.
f01a4b2 [Resolver] Interfere extension method type arguments from the target type if no parameter is given.
62283e2 [TypeSystem] Made error message more verbose.
68aa35a [Ast] Added MemberNameToken property for pointer reference expressions.
53d9b6e [CodeIssues] Fix some false positives in ParameterCanBeDemotedIssue.
dc1e33d [CodeIssue] ParameterHidesMemberIssue and LocalVariableHidesMemberIssue now distinguish static and non-static members
35179fd [CodeIssues] Remove leftover Console.WriteLine().
865c288 [CodeIssues] OptionalParameterCouldBeSkippedIssue: Add null check.
3ae6b9f [CodeIssues] FormatStringIssue: Handle extra arguments that do not have a matching formal parameter.
e5f346b [CodeIssues] Add OptionalParameterCouldBeSkippedIssue.
3757871 [CodeIssues] FormatStringIssue: Show errors in TextSegments too.
101294e [Utils] CompositeFormatStringParser: More error handling + refactoring of the code.
927c388 [CodeIssue] Added UnreachableCodeIssue
ef6302d [Utils] CompositeFormatStringParser: Handle unclosed format items better
900aec2 [CodeIssues] Add FormatStringIssue.
d2474e5 [Utils] Make CompositeFormatStringParser.Parse() wrap the segments in a class instead of just returning an IEnumerable.
185779b [Utils] Add more error checks to CompositeFormatStringParser.
af7d214 [Utils] Some CompositeFormatStringParser cleanups.
7edf902 [Utils] More error handling in CompositeFormatStringParser.
1b96e9b [Utils] Add lots of error checks to CompositeFormatStringParser.
11c428e [Utils] Add CompositeFormatStringParser and related classes.
23c7dc0 [Tests] Added helper methods for checking a specific fix to InspectionActionTestBase
1133382 [CodeIssues] Add missing class IsTypeCriterion.
2307bcb [CodeIssues] ParameterCanBeDemotedTests: Add checks for what types variables are used as.
03ea217 [CodeIssues] Rename CallToStaticMemberViaDerivedTypeIssue to ReferenceToStaticMemberViaDerivedTypeIssue.
a3e6c14 [CodeIssues] Handle members in CallToStaticMemberViaDerivedTypeIssue.
a1cbcc2 Merge remote-tracking branch 'upstream/master' into mansheng
7a9fdf4 [CodeIssues] Make CallToVirtualFunctionFromConstructorIssue less whiny.
1a7d2e1 [CodeIssues] CallToStaticMemberViaDerivedTypeIssue: Ignore member methods of the current class.
6f2aed1 [CodeIssues] ParamaterCanBeDemotedIssue: Don't crash on parameters that aren't used.
db8e971 [CodeAction] Add ContextAction attribute to MoveToOuterScopeAction.
ce1e2ee [CodeIssues] Fix crashes in VariableDeclaredInWideScopeIssue.
f33aa32 Merge remote-tracking branch 'upstream/master' into simonl
008aaa1 [CodeIssues] Factor out some type restriction finding infrastructure.
e62a046 Fixed resolving compile-time operations on enum types with an underlying type smaller than int. (always use unchecked context for the cast back to enum)
459a2ef Fixed bug resolving indexer parameter declarations (was introduced with #66 [9476183]).
807e9c5 Allow multiple occurrences of UnknownError.
0aa37bc Add lazy-loading support to CecilLoader.
164592f [CodeIssue] Added CompareFloatWithEqualityOperatorIssue
aff3328 [CodeIssue] Added BitwiseOperationOnNonFlagsEnumIssue
3372603 [CodeIssue] Added ForControlVariableNotModifiedIssue
7f7fcec [CodeIssue] Added RedundantElseIssue
5f6f274 Merge pull request #70 from erik-kallen/DynamicResolveResults
a7816c2 Fixed handling of user-defined conversions between primitive types.
8426277 Merge remote-tracking branch 'upstream/master' into mansheng
fca3cfe [CodeIssue] Added RedundantFieldInitializerIssue
5c1418e [CodeAction] Moved GetDefaultValueExpression to BaseRefactoringContext
be0d89c [CodeIssues] Improve ParameterCouldBeDemotedIssue.
61044a8 [CodeIssues] Add initial version of ParameterCanBeDemotedIssue.
8a80ae0 [Completion] Added pointer reference completion.
77c9ccb [CodeIssues] Rename VariableDeclaredInWideScopeIssue => VariableDeclaredInWideScopeTests in the test project.
5720dc7 [CodeActions] MoveToOuterScopeAction: Handle lambdas.
4bae4ed [CodeIssues] Add VariableDeclaredInWideScopeIssue.
774c707 [CodeIssues] Change the namespace on IncorrectExceptionParameterOrderingIssue.
ac2e8ef [CodeActions] Don't crash on null accessors in ValueParameterUnusedIssue.
3ec073f [CodeActions] Add MoveToOuterScopeAction.
2de5021 Fixed failing unit test.
4a3192d [CodeIssues] Add CallToStaticMemberViaDerivedTypeIssue.
9d5a384 [CodeActions] Add ConvertToInitializerAction.
73530de [CodeIssue] Added VariableHidesMemberIssue
c1db937 Merge remote-tracking branch 'upstream/master' into mansheng
7354574 [CodeAction] ConvertIfToConditionalTests: fixed a test
754adbc AccessToModifiedClosureIssue: always use "var" keyword to avoid some null type issues, fixed "fails for field declaration" issue.
9d37b9a GatherVisitor: make sure base visit methods are always called
549d6bb ExtractAnonymousMethodAction: Fixed "fails to insert generated method when anonymous method is not in a method" issue
bd1f050 GatherVisitor: added calls to base methods
0bf9891 ResolveResults for dynamic expressions
cf08a17 AccessToClosureIssue: fixed some constructor issues
77283dc Merge minor changes from SharpDevelop repository (mostly additional documentation for ResolveResults).
2b41cda Simplify Demo app.
4ff155e Merge remote-tracking branch 'upstream/master' into mansheng
5d2fee1 Add CompilerSettings class instead of using the one from Mono.CSharp.
e7a902b Merge remote-tracking branch 'upstream/master' into mansheng
b37dedf [CodeIssue] Added LocalVariableOnlyAssignedIssue and ParameterOnlyAssignedIssue
6ba62c6 [Formatting] Fixed override.
3e2fe59 [CodeActions] Added Task async excecution for insertion & link modes.
8e02a17 Merge remote-tracking branch 'upstream/master' into mansheng
585ae50 CSharpAstResolver: don't return the same ResolveResult for two different nodes.
08636db [Completion] Fixed named argument completion bug.
fbc1cfd Fixed some failing unit tests.
6e5b973 [ContextAction] Added null check to create method.
1c0a730 [CodeIssue] TypeParameterNotUsedIssue: removed the fix because it may introduce errors.
454bfe5 [CodeIssue] LocalVariableNotUsedIssue: Find unused foreach variable
e2221f2 Merge remote-tracking branch 'upstream/master' into mansheng
ca048e6 [CodeIssue] Added VariableNotUsedIssue, ParameterNotUsedIssue and TypeParameterNotUsedIssue
fadffd3 [Completion] Improved the closing tag insertion (xml documentation).
3dc4463 [Resolver] Array initalizers no longer show up in ResolveAtLocation.
84c092c Merge pull request #67 from erik-kallen/UserDefinedExplicitConversionBetweenReferenceTypes
25cf612 Merge pull request #66 from erik-kallen/ParameterIdentity
951d9a6 Fix for the issue that user-defined explicit conversions don't work.
0fec8d3 Failing test that demonstrates that explicit user-defined conversions don't work.
e058d61 [Completion] Improved xml document completion.
95bc695 [Completion] Be more general when providing type level keywords in members.
839b19e [TyeSystem] Fixed bug in nested type property.
d8aac6d Merge remote-tracking branch 'upstream/master' into mansheng
4ac7fec [Refactoring] Don't suggest names that are used in a parent scope when falling back to numbered names.
3ded985 [Formatting] Fixed overlapping changes issue.
d355b0f [CodeIssues] Added indexer case.
da2eea8 [CodeIssues] Improved naming check (skipp overriden members).
4c87520 [CodeAction] Create field now works on member reference expressions with 'this.' target.
9476183 Fix for the parameter identity in accessors issue.
1363faf Tests demonstrating issues with parameter identity in accessors.
806869e Add IType.GetAccessors(). Accessors now use EntityType.Accessor instead of EntityType.Method. Added accessors support to DefaultMemberReference and ExplicitInterfaceImplementationMemberReference. Removed hacky code from CecilLoader - we now allow IsExplicitInterfaceImplementation=true on accessors.
13ca351 [CodeActions] Make IterateViaForeachAction use names based on their type and add handling of using and for statements.
da5bbf3 [Refactoring, Competion] Add NamingHelper, use it from CSharpCompletionEngine and add convenience functions to RefactoringContext.
98674db Merge remote-tracking branch 'upstream/master' into mansheng
99c34cb Merge pull request #65 from erik-kallen/ImplementedInterfaceMembersForPropertyAccessors
728bf05 [CodeIssue] Added AccessToModifiedClosureIssue and AccessToDisposedClosureIssue
2a7c0cb Merge pull request #64 from erik-kallen/IsOverrideFlag
bf89323 Add missing fields in KnownTypeReference.
cdaf575 Implement AnonymousType.ToTypeReference().
74adaba Test demonstrating problem with nesting anonymous objects.
c6d8b93 Move SimpleTypeResolveContext out of Implementation namespace.
d46cbdb Don't report a member as implementing an interface member if there is another explicit implementation of that interface member.
da0feac Another one of those x.IsOverride = y.IsOverridable issues.
4813979 Support explicitly implemented events in the CecilLoader.
8431aa0 Fixed bugs with events: 1) Assignment of IsOverride to IsOverridable, and 2) AccessorOwner not being set for auto-events.
7640141 Added support for explicit method and property implementations to the cecil loader.
18995bd Fixed InheritanceHelper to support explicit interface implementation of base accessors.
4d868ba Failing test with explicit indexer implementation
4bc84b0 Merge remote-tracking branch 'upstream/master' into mansheng
fd39748 (Rather ugly) fix for indexer accessor's ImplementedInterfaceMembers.
7e2a5a3 Tests for ImplementedInterfaceMembers for indexer accessors.
7ce5de3 (Rather ugly) fix ensure that accessor method are reported as implementing the corresponding accessor methods from interfaces.
baad38a Tests demonstrating that the accessors for a property that implements an interface property do not have any ImplementedInterfaceMembers.
7f6620e Merge branch 'master' into soc-master
a2a0975 Fixes IsOverridable flag for accessors
840cde9 Failing test for IsOverride flag of accessors.
4d60290 [CodeAction] IterateViaForeachAction: Add tests for slightly invalid expression statements and use Script.InsertAfter() to avoid problematic formatting.
97185cf [Refactoring] Add optional parameter expectErrors = false to ContextActonTestBase.Test().
9b256fb [Completion] Only show public enum members.
68e12e4 [Completion] Filtered double added enums.
a4d5b7a [Refactoring] Add Script.InsertAfter().
0c9704d [Parser] Give ExpressionStatements with an invalid expression a semicolon if there was one in the file.
80c3b8d [Formatter] The formatting visitor can now take a region to format.
b5b1bd1 [CodeActions] Ignore whitespace tests for now.
c45b646 [CodeActions] Handle AssignmentExpressions differently in IterateViaForeachAction.
a546a8f [CodeActions] Rename SetterDoesNotUseValueParameterAction to ValueParameterUnusedAction and generalize it to include event accessors as well.
c8f36ae [CodeActions] Handle auto-setters and missing setters in SetterDoesNotUseValueParameterIssue.
f562e97 Merge branch 'master' into soc-master
f99663b [CodeActions] Add IterateViaForeachAction.
1e63663 [CodeActions] Add failing unit tests for whitespace preservation in in AddCatchTypeAction and RemoveRedundantCatchTypeAction.
eea162a [CodeIssues] Update some strings to be more inline with the rest of the issues (and more informative too).
05f8cfe [CodeActions] Don't return a convert to extension method call code action if the call is already using extension method syntax.
94e43f2 [CodeActions] Add the ContextAction attribute to the static method call <=> extension method call converters.
bf6217d Improved CodeDomConvertVisitor.
d6ed3b7 Fixed resolving accessors.
cd9c948 Add ICollection, ICollection<T> and IList to KnownTypeReference.
a9d8769 Implemented CSharpResolver.ResolveConditionFalse() for resolving operator false() calls. Add message to ErrorResolveResult. Expose CSharpOutputVisitor.PrintPrimitiveValue and CSharpConversions.IsImplicitReferenceConversion/IsBoxingConversion.
a77fa31 Add IMethod.AccessorOwner.
731ddf7 Add ConversionResolveResult.CheckForOverflow
79f634c Change TextChangeEventArgs.InsertedText and RemovedText from string to ITextSource.
c8f2115 [CodeAction] Added ExtractAnonymousMethodAction
d1388d5 Merge remote-tracking branch 'upstream/master' into mansheng
b304675 Merge branch 'master' into soc-master
00d5de8 [CodeIssues] Optimized word break algorithm.
81c7daa [Completion] Renamed IMemberProvider -> ICompletionContextProvider.
6cbda46 [Completion] It's no longer needed to specify a parsed file for the completion engine.
33efe34 [Documentation] Added support for relative redirection targets.
4ca0f1d [CodeAction] Add code actions for converting between static method calls and extension method calls.
3597535 [CodeAction] Added ConvertConditionalToIfAction and ConvertIfToConditionalAction
c9d2776 [Completion] Added GetMemberTextToCaret interface method.
1a33039 [Completion] Use getstate to get the current resolver state.
a8e702b [Completion] Lowered parsed file usages.
39ac51c [Completion] Made API a bit simpler.
d60aaeb [Completion] Member provider now needs to be given in the constructor.
aa59c76 Merge remote-tracking branch 'upstream/master' into mansheng
f198d68 [CodeAction] Fixed bug in create property action.
4e44369 [CodeIssues] Fdg rules now apply only to public & protected entities. (The Fdg rules only apply to that, we were more restrictive).
b0c73cc [CodeIssues] Fixed fdg naming rules.
6c36d6e Merge pull request #58 from mono-soc-2012/simonl-newline-fix
513ffec Merge pull request #51 from nieve/ExtractFieldAction
eb41192 Fix unit test failing on .NET 4.5 RC.
0500351 Simplify API for retrieving compiler errors/warnings.
e914c9e [CodeIssue,CodeAction] Use the FindReferences class instead of custom visitors to find variable references.
e60567a [Resolver] Give the value parameter a domregion close to the setter or adder.
75f65da Fixed typo.
ad0ef5d [CodeIssue] Remove stray exception creation.
47da624 [CodeIssue] Add CallToVirtualFunctionFromConstructorIssue.
8d46989 [Formatter] Avoid newlines between multiline arguments and the ending parenthesis in function calls.
8e94126 [CodeIssue] Add IncorrectExceptionParameterOrderingIssue.
2396e99 [CodeIssue] Add SetterDoesNotUseValueParameterIssue.
b6203ac [CodeAction] Add AddCatchTypeAction.
e2ff414 [Code Action] Only show MergeNestedIfAction on 'if' token
712102c [Code Action] Only show ConvertSwitchToIfAction on 'switch' token
4da8bc8 [Code Action] Only show ConvertIfToSwitchAction on 'if' token
b8c6547 Merge remote-tracking branch 'upstream/master' into mansheng
73a44b2 [NRefactory] Be more verbose on cecil load error.
44eff13 Add RemoveRedundantCatchTypeAction.
875d509 Merge remote-tracking branch 'upstream/master' into mansheng
4bfa589 [CodeAction] Added ConvertLambdaBodyExpressionToStatementAction and ConvertLambdaBodyStatementToExpressionAction
0f01589 [CodeAction] Added UseStringFormatAction
7fb257f Fixed completion bug.
5fe3dbd [UnitTest] Added test case for parser bug.
d29d429 [CSharp] Updated mcs.
f934c9a [CodeAction] ConvertExplicitToImplicitImplementation: make implicit implementation public
bfa89c7 [CodeAction] Added ConvertExplicitToImplicitImplementationAction and ConvertImplicitToExplicitImplementationAction
1066186 [CodeAction] Added PutInsideUsingAction
d01ed9e Merge remote-tracking branch 'upstream/master' into mansheng
33cc204 [CodeAction] Added MergeNestedIfAction
5bc69fd [CodeActions] Fixed remove braces whitespace removal.
38c8028 [CodeAction] SplitDeclarationList: Corrected a test
9c078eb Merge remote-tracking branch 'upstream/master' into mansheng
16a84b9 [CodeAction] Added SplitDeclarationListAction
1911868 [NRefactory] Removed extra new line for fields.
4433ab1 [Ast] Added IdentifierToken property to IdentifierExpression.
88c1287 [CodeAction] Added CreateCustomEventImplementationAction
fc6c24c [CodeAction] Added CreateOverloadWithoutParameterAction
b5843ad [CodeAction] Added ConvertAsToCastAction and ConvertCastToAsAction
5afae04 Merge remote-tracking branch 'upstream/master' into mansheng
2786d0c [Formatting] Set wrap options to do not change.
a362d45 Merge remote-tracking branch 'upstream/master' into mansheng
5823267 [CodeAction]Added ConvertSwitchToIfAction
c93ef39 [CodeAction]ConvertIfToSwitchAction: avoid generating redundant default section.
d061eaa [CodeAction]Added ConvertIfToSwitchAction
2e4a497 [Completion] Fixed GetLineIndent method.
0cc7a4e [Completion] Fixed delegate context bug.
1c0b3b5 [Completion] Filter inaccessible classes in completion lookup.
7b21777 [Completion] Fixed 'this' keyword for extension method declarations.
9e7c9be [Completion] Fixed enum completion bug.
a1e4b07 [Completion] Fixed enum completion in binary operator expressions.
5587b77 [Analysis] Fixed control flow generation for null embedded statement (for statement).
7e3e016 Add back WinForms-based NRefactory.Demo.
1640cb8 Set version number to 5.0.1; fixed some compiler warnings.
cbb1fe5 Fixed some issues resolving members.
c93aca4 Fixed failing unit test.
180ed85 Implemented IUnresolvedMember.Resolve().
4b3bb7e Fixed completion bug.
e0e30ae [Completion] Improved object initializer case.
a270f6a [Resolver] ResolveAtLocation can now postpone the creation of compilations.
293af2e [Resolver] Fixed resolve at location bug.
f197829 [Formatter] Fixed failing unit tests.
4add679 [TypeSystem] Cecil loader no longer crashes loading gtk-sharp.dll on windows.
282d3c3 Fix icsharpcode/NRefactory#32: ResolveResult for anonymous type creation
4d07b33 CSharpAstResolver now can resolve type members even when no parsedFile is specified.
3745ade Merge pull request #54 from Duikmeester/patch-1
6f9065e "__StackĄlloc" corrected in "__StackAlloc"
7d89302 [Tests] Added test case for a parser bug.
ff1118a [Formatter] Fixed bug where keywords were put into comments.
99b856a added extract field code action
9b7c635 Merge pull request #50 from riviti/enh-genprop
7a3e68f [TypeSystem] All attributes from partial method declarations are now merged.
a300c56 GeneratePropertyAction: Handle fields named like properties by renaming them before creating the property.
b9780fb [CodeAction] Fixed check if parameter is null bug.
75c3a07 [Formatting] Fixed overlapping change bug.
7a03092 [Completion] Fixed parameter completion for static methods.
1852a3d [Refactoring] Fixed some bugs in create code actions in conjunction with enums.
d888899 Solution: Set correct indent width.
57d4bd4 [TypeSystem] UsingScope now uses as operator for casts.
8305999 [TypeSystem] Added default parameter for GetClassTypeReference typeParameterCount.
bb6660e [TypeSystem] Added TypeReference.Resolve (Compilation) extension method.
8c8e6cf [Parser] Merged mcs.
49e1b67 [Completion] GetParameterCompletionCommandOffset is now reusable/removed code duplication of GetCurrentParameterIndex.
bcb45ff [Refactoring] Better use of the text editor options class in the script node output (output formatter should maybe use the formatting indent class).
ad0ae7a [Completion] Improved handling of named parameters.
8722483 [Formatting] Fixed using alias declarations.
5a53174 [Formatting] Guard against empty changes.
73396ed Improved named parameter completion case.
cff1fb2 [Completion] Fixed member lookup.
14ed907 [Formatting] Wrapping is now an intrusive task.
570c4d8 Fixed bug in completion.
8ff1e4c Fixed completion bug.
1ade7c4 [Resolver] Fixed using statement.
93f0d71 Fixed completion bug.
bc77559 [Completion] Fixed catch context completion.
8523068 [Completion] Fixed object initializer unit tests.
c32e988 [Completion] Fixed unit test.
4fe7c72 Fixed context for determining accessibility of protected inner classes when resolving a base type reference (NameLookupTests.InheritFromProtectedInnerClassTest)
f7fb298 Implemented better solution for the array initializer workaround hack.
121c786 Removed duplicate unit test.
f5b7f57 [UnitTest] Added failing unit test.
7bf1b4a Added some unit tests.
d9113f3 [CodeAction] Fixed possible null reference.
63009ac Fixed 'Bug 4604 - [Resolver] Attribute Properties are not offered valid autocomplete choices'.
89be9aa [UnitTest] Enabled broken unit test.
7a69c65 Fixed Issue #38: Parser Regression in ObjectCreate initialization
6f1325d Fixed Issue #44: The ending TextLocation of an ArrayCreateExpression is incorrect when the array is initialized with zero elements
6a45cef Updated mcs.
ef726be [UnitTests] Disabled broken tests.
a93372d Removed some files that shouldn't be in the repository
cdd492e Merge pull request #36 from awatertree/master
0179c76 Merge pull request #43 from turbanoff/patch-1
c06cfed Fix icsharpcode/NRefactory#42: const IField returns IsStatic=false
76e3cb4 Fixed output visitor inserting too many newlines in SwitchSection.
1077aa9 Add .jay to symbol package.
5239719 Fixed property formatting bug.
24f1637 remove redundant check
5b83b2d Only wrap arguments that are longer than 1.
c4b9519 [CodeAction] Convert foreach to for now preserves old block.
94a8fde Added unit test for Bug 4525 - Unexpected code completion exception
56bfccb Fixed possible null ref exception
cf9d360 [CodeActions] Worked on implement interface.
0581a41 Ignored failing unit test.
bfdaaad Fixed declaration parameter formatting bugs.
6126d9b [Formatting] Fixed some formatting bugs.
805e072 Started implement interface/abstract members code action.
da56a5b Fixed completion bug.
1a1487f [Formatting] Checked token for null, before using the parent.
6d1e90b [Formatting] Added null check.
2aec1be Improved the handling of delegate contexts.
c773b58 Fixed formatting unit tests.
2eb61ac Added failing unit test. I assume that the problem is that B has a inner lass B.Foo - sicne it works when Foobar inherits just from 'Foo'.
e8a5226 Changed formatting policy.
063d0f5 Renamed named expression identifier -> name.
5dbe365 [Ast] Renamed named argument expression identifier -> name.
98b2dfa Fixed unit tests.
aa111ad Added completion categories for derived types.
45c8d0e Fixed object creation completion issue.
29ec90e changed method call wrap default.
04127ad [Formatting] Improved the wrap if too long option.
639f6b9 Updated formatting factory options.
e308e3d Added more formatting styles.
c2e912a [Completion] Fixed bug in pre processor directive context detection.
c8f8dc7 [CodeIssue] removed '.' in name.
c36be0b Fixed some add another accessor issues.
1704bd0 [Formatting] Implemented parameter wrapping.
95b0c25 [Formatting] New line placement is now a 3 state.
ecbc616 Added unit test for bug report. (use case already works)
198c085 Added some formatting options.
a4064df Added indexer argument wrapping options.
debc7a0 Added method call wrapping options.
fa4f2e0 Added chained method call wrapping option.
62f621e Merge branch 'master' of github.com:icsharpcode/NRefactory
e912bdf Fixed possible cast exception.
658cb4b patched up handling indexing issue
aff71a5 try revert critical method
9d29131 merge
a34aaa8 project compilation
18d7ca4 failing tests for issue 35
c189c5d failing tests for issue 35
3f465c6 failing tests for issue 35

git-subtree-dir: NRefactory
git-subtree-split: e2eef883e176bb5017a9fdfc7afe9113e7448c27
pull/384/head
Daniel Grunwald 13 years ago
parent
commit
349d49546d
  1. 5
      .gitignore
  2. 3
      ICSharpCode.NRefactory.CSharp.AstVerifier/.gitignore
  3. 116
      ICSharpCode.NRefactory.CSharp.AstVerifier/ICSharpCode.NRefactory.CSharp.AstVerifier.csproj
  4. 2
      ICSharpCode.NRefactory.CSharp.AstVerifier/Main.cs
  5. 3
      ICSharpCode.NRefactory.CSharp/.gitignore
  6. 3
      ICSharpCode.NRefactory.CSharp/Analysis/ControlFlow.cs
  7. 4
      ICSharpCode.NRefactory.CSharp/Analysis/DefiniteAssignmentAnalysis.cs
  8. 77
      ICSharpCode.NRefactory.CSharp/Ast/AstNode.cs
  9. 16
      ICSharpCode.NRefactory.CSharp/Ast/AstNodeCollection.cs
  10. 6
      ICSharpCode.NRefactory.CSharp/Ast/AstType.cs
  11. 50
      ICSharpCode.NRefactory.CSharp/Ast/CSharpUtil.cs
  12. 2
      ICSharpCode.NRefactory.CSharp/Ast/ComposedType.cs
  13. 8
      ICSharpCode.NRefactory.CSharp/Ast/DepthFirstAstVisitor.cs
  14. 79
      ICSharpCode.NRefactory.CSharp/Ast/Expressions/ArrayInitializerExpression.cs
  15. 11
      ICSharpCode.NRefactory.CSharp/Ast/Expressions/IdentifierExpression.cs
  16. 12
      ICSharpCode.NRefactory.CSharp/Ast/Expressions/MemberReferenceExpression.cs
  17. 10
      ICSharpCode.NRefactory.CSharp/Ast/Expressions/NamedArgumentExpression.cs
  18. 10
      ICSharpCode.NRefactory.CSharp/Ast/Expressions/NamedExpression.cs
  19. 15
      ICSharpCode.NRefactory.CSharp/Ast/Expressions/PointerReferenceExpression.cs
  20. 2
      ICSharpCode.NRefactory.CSharp/Ast/GeneralScope/NamespaceDeclaration.cs
  21. 10
      ICSharpCode.NRefactory.CSharp/Ast/GeneralScope/PreProcessorDirective.cs
  22. 6
      ICSharpCode.NRefactory.CSharp/Ast/IAstVisitor.cs
  23. 4
      ICSharpCode.NRefactory.CSharp/Ast/MemberType.cs
  24. 1292
      ICSharpCode.NRefactory.CSharp/Ast/ObservableAstVisitor.cs
  25. 2
      ICSharpCode.NRefactory.CSharp/Ast/PrimitiveType.cs
  26. 4
      ICSharpCode.NRefactory.CSharp/Ast/SimpleType.cs
  27. 34
      ICSharpCode.NRefactory.CSharp/Ast/Statements/TryCatchStatement.cs
  28. 85
      ICSharpCode.NRefactory.CSharp/Ast/SyntaxTree.cs
  29. 13
      ICSharpCode.NRefactory.CSharp/Ast/TypeMembers/IndexerDeclaration.cs
  30. 1201
      ICSharpCode.NRefactory.CSharp/Ast/old_ObservableAstVisitor.cs
  31. 134
      ICSharpCode.NRefactory.CSharp/CSharpProjectContent.cs
  32. 1771
      ICSharpCode.NRefactory.CSharp/Completion/CSharpCompletionEngine.cs
  33. 419
      ICSharpCode.NRefactory.CSharp/Completion/CSharpCompletionEngineBase.cs
  34. 184
      ICSharpCode.NRefactory.CSharp/Completion/CSharpParameterCompletionEngine.cs
  35. 158
      ICSharpCode.NRefactory.CSharp/Completion/CompletionDataWrapper.cs
  36. 213
      ICSharpCode.NRefactory.CSharp/Completion/ICompletionContextProvider.cs
  37. 9
      ICSharpCode.NRefactory.CSharp/Completion/ICompletionDataFactory.cs
  38. 393
      ICSharpCode.NRefactory.CSharp/Formatter/AstFormattingVisitor.cs
  39. 81
      ICSharpCode.NRefactory.CSharp/Formatter/CSharpFormattingOptions.cs
  40. 138
      ICSharpCode.NRefactory.CSharp/Formatter/FormattingOptionsFactory.cs
  41. 6
      ICSharpCode.NRefactory.CSharp/Formatter/GeneratedCodeSettings.cs
  42. 14
      ICSharpCode.NRefactory.CSharp/Formatter/Indent.cs
  43. 10
      ICSharpCode.NRefactory.CSharp/Formatter/TextEditorOptions.cs
  44. 159
      ICSharpCode.NRefactory.CSharp/ICSharpCode.NRefactory.CSharp.csproj
  45. 2
      ICSharpCode.NRefactory.CSharp/NameLookupMode.cs
  46. 26
      ICSharpCode.NRefactory.CSharp/OutputVisitor/CSharpOutputVisitor.cs
  47. 143
      ICSharpCode.NRefactory.CSharp/OutputVisitor/CodeDomConvertVisitor.cs
  48. 963
      ICSharpCode.NRefactory.CSharp/Parser/CSharpParser.cs
  49. 151
      ICSharpCode.NRefactory.CSharp/Parser/CompilerSettings.cs
  50. 103
      ICSharpCode.NRefactory.CSharp/Parser/SeekableStreamReader.cs
  51. 2
      ICSharpCode.NRefactory.CSharp/Parser/mcs/MonoSymbolFile.cs
  52. 81
      ICSharpCode.NRefactory.CSharp/Parser/mcs/MonoSymbolTable.cs
  53. 4
      ICSharpCode.NRefactory.CSharp/Parser/mcs/SourceMethodBuilder.cs
  54. 82
      ICSharpCode.NRefactory.CSharp/Parser/mcs/anonymous.cs
  55. 16
      ICSharpCode.NRefactory.CSharp/Parser/mcs/argument.cs
  56. 13
      ICSharpCode.NRefactory.CSharp/Parser/mcs/assembly.cs
  57. 16
      ICSharpCode.NRefactory.CSharp/Parser/mcs/assign.cs
  58. 14
      ICSharpCode.NRefactory.CSharp/Parser/mcs/async.cs
  59. 45
      ICSharpCode.NRefactory.CSharp/Parser/mcs/attribute.cs
  60. 40
      ICSharpCode.NRefactory.CSharp/Parser/mcs/cfold.cs
  61. 52
      ICSharpCode.NRefactory.CSharp/Parser/mcs/class.cs
  62. 16
      ICSharpCode.NRefactory.CSharp/Parser/mcs/codegen.cs
  63. 2
      ICSharpCode.NRefactory.CSharp/Parser/mcs/const.cs
  64. 25
      ICSharpCode.NRefactory.CSharp/Parser/mcs/context.cs
  65. 3
      ICSharpCode.NRefactory.CSharp/Parser/mcs/convert.cs
  66. 9494
      ICSharpCode.NRefactory.CSharp/Parser/mcs/cs-parser.cs
  67. 230
      ICSharpCode.NRefactory.CSharp/Parser/mcs/cs-parser.jay
  68. 284
      ICSharpCode.NRefactory.CSharp/Parser/mcs/cs-tokenizer.cs
  69. 11
      ICSharpCode.NRefactory.CSharp/Parser/mcs/decl.cs
  70. 5
      ICSharpCode.NRefactory.CSharp/Parser/mcs/delegate.cs
  71. 14
      ICSharpCode.NRefactory.CSharp/Parser/mcs/doc.cs
  72. 75
      ICSharpCode.NRefactory.CSharp/Parser/mcs/driver.cs
  73. 2
      ICSharpCode.NRefactory.CSharp/Parser/mcs/dynamic.cs
  74. 465
      ICSharpCode.NRefactory.CSharp/Parser/mcs/ecore.cs
  75. 11
      ICSharpCode.NRefactory.CSharp/Parser/mcs/eval.cs
  76. 74
      ICSharpCode.NRefactory.CSharp/Parser/mcs/expression.cs
  77. 5
      ICSharpCode.NRefactory.CSharp/Parser/mcs/field.cs
  78. 84
      ICSharpCode.NRefactory.CSharp/Parser/mcs/generic.cs
  79. 71
      ICSharpCode.NRefactory.CSharp/Parser/mcs/import.cs
  80. 4
      ICSharpCode.NRefactory.CSharp/Parser/mcs/iterators.cs
  81. 54
      ICSharpCode.NRefactory.CSharp/Parser/mcs/location.cs
  82. 7
      ICSharpCode.NRefactory.CSharp/Parser/mcs/membercache.cs
  83. 90
      ICSharpCode.NRefactory.CSharp/Parser/mcs/method.cs
  84. 2
      ICSharpCode.NRefactory.CSharp/Parser/mcs/module.cs
  85. 161
      ICSharpCode.NRefactory.CSharp/Parser/mcs/namespace.cs
  86. 12
      ICSharpCode.NRefactory.CSharp/Parser/mcs/nullable.cs
  87. 40
      ICSharpCode.NRefactory.CSharp/Parser/mcs/outline.cs
  88. 28
      ICSharpCode.NRefactory.CSharp/Parser/mcs/property.cs
  89. 16
      ICSharpCode.NRefactory.CSharp/Parser/mcs/report.cs
  90. 93
      ICSharpCode.NRefactory.CSharp/Parser/mcs/settings.cs
  91. 99
      ICSharpCode.NRefactory.CSharp/Parser/mcs/statement.cs
  92. 14
      ICSharpCode.NRefactory.CSharp/Parser/mcs/support.cs
  93. 38
      ICSharpCode.NRefactory.CSharp/Parser/mcs/typemanager.cs
  94. 46
      ICSharpCode.NRefactory.CSharp/Parser/mcs/typespec.cs
  95. 7
      ICSharpCode.NRefactory.CSharp/Parser/mcs/visit.cs
  96. 357
      ICSharpCode.NRefactory.CSharp/QueryExpressionExpander.cs
  97. 30
      ICSharpCode.NRefactory.CSharp/Refactoring/BaseRefactoringContext.cs
  98. 4
      ICSharpCode.NRefactory.CSharp/Refactoring/CodeActions/AddAnotherAccessorAction.cs
  99. 59
      ICSharpCode.NRefactory.CSharp/Refactoring/CodeActions/AddCatchTypeAction.cs
  100. 14
      ICSharpCode.NRefactory.CSharp/Refactoring/CodeActions/CheckIfParameterIsNullAction.cs
  101. Some files were not shown because too many files have changed in this diff Show More

5
.gitignore vendored

@ -1,2 +1,5 @@ @@ -1,2 +1,5 @@
bin
obj
/lib/*.dll
/ICSharpCode.NRefactory.Tests/PartCover/*
/ICSharpCode.NRefactory.Tests/PartCover/*
_ReSharper*/*

3
ICSharpCode.NRefactory.CSharp.AstVerifier/.gitignore vendored

@ -1,3 +0,0 @@ @@ -1,3 +0,0 @@
bin/
obj/

116
ICSharpCode.NRefactory.CSharp.AstVerifier/ICSharpCode.NRefactory.CSharp.AstVerifier.csproj

@ -1,49 +1,69 @@ @@ -1,49 +1,69 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProductVersion>10.0.0</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{961DADFA-7CE6-429F-BC22-47630D6DB826}</ProjectGuid>
<OutputType>Exe</OutputType>
<RootNamespace>ICSharpCode.NRefactory.CSharp.AstVerifier</RootNamespace>
<AssemblyName>AstVerifier</AssemblyName>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug</OutputPath>
<DefineConstants>DEBUG;</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<Externalconsole>true</Externalconsole>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>none</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Release</OutputPath>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<Externalconsole>true</Externalconsole>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
</ItemGroup>
<ItemGroup>
<Compile Include="Main.cs" />
<Compile Include="AssemblyInfo.cs" />
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<ItemGroup>
<ProjectReference Include="..\ICSharpCode.NRefactory.CSharp\ICSharpCode.NRefactory.CSharp.csproj">
<Project>{53DCA265-3C3C-42F9-B647-F72BA678122B}</Project>
<Name>ICSharpCode.NRefactory.CSharp</Name>
</ProjectReference>
<ProjectReference Include="..\ICSharpCode.NRefactory\ICSharpCode.NRefactory.csproj">
<Project>{3B2A5653-EC97-4001-BB9B-D90F1AF2C371}</Project>
<Name>ICSharpCode.NRefactory</Name>
</ProjectReference>
</ItemGroup>
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProductVersion>10.0.0</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{961DADFA-7CE6-429F-BC22-47630D6DB826}</ProjectGuid>
<OutputType>Exe</OutputType>
<RootNamespace>ICSharpCode.NRefactory.CSharp.AstVerifier</RootNamespace>
<AssemblyName>AstVerifier</AssemblyName>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug</OutputPath>
<DefineConstants>DEBUG;</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<Externalconsole>true</Externalconsole>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>none</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Release</OutputPath>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<Externalconsole>true</Externalconsole>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'net_4_5_Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug</OutputPath>
<DefineConstants>DEBUG;</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<Externalconsole>true</Externalconsole>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'net_4_5_Release|AnyCPU' ">
<DebugType>none</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Release</OutputPath>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<Externalconsole>true</Externalconsole>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
</ItemGroup>
<ItemGroup>
<Compile Include="Main.cs" />
<Compile Include="AssemblyInfo.cs" />
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<ItemGroup>
<ProjectReference Include="..\ICSharpCode.NRefactory.CSharp\ICSharpCode.NRefactory.CSharp.csproj">
<Project>{53DCA265-3C3C-42F9-B647-F72BA678122B}</Project>
<Name>ICSharpCode.NRefactory.CSharp</Name>
</ProjectReference>
<ProjectReference Include="..\ICSharpCode.NRefactory\ICSharpCode.NRefactory.csproj">
<Project>{3B2A5653-EC97-4001-BB9B-D90F1AF2C371}</Project>
<Name>ICSharpCode.NRefactory</Name>
</ProjectReference>
</ItemGroup>
</Project>

2
ICSharpCode.NRefactory.CSharp.AstVerifier/Main.cs

@ -59,7 +59,7 @@ namespace ICSharpCode.NRefactory.CSharp.AstVerifier @@ -59,7 +59,7 @@ namespace ICSharpCode.NRefactory.CSharp.AstVerifier
if (!file.EndsWith (".cs"))
continue;
string text = File.ReadAllText (file);
var unit = CompilationUnit.Parse (text, file);
var unit = SyntaxTree.Parse (text, file);
if (unit == null)
continue;
string generated = unit.GetText ();

3
ICSharpCode.NRefactory.CSharp/.gitignore vendored

@ -1,3 +0,0 @@ @@ -1,3 +0,0 @@
bin/
obj/

3
ICSharpCode.NRefactory.CSharp/Analysis/ControlFlow.cs

@ -599,7 +599,8 @@ namespace ICSharpCode.NRefactory.CSharp.Analysis @@ -599,7 +599,8 @@ namespace ICSharpCode.NRefactory.CSharp.Analysis
ControlFlowNode bodyStart = builder.CreateStartNode(forStatement.EmbeddedStatement);
ControlFlowNode bodyEnd = forStatement.EmbeddedStatement.AcceptVisitor(this, bodyStart);
Connect(bodyEnd, iteratorStart);
if (bodyEnd != null)
Connect(bodyEnd, iteratorStart);
breakTargets.Pop();
continueTargets.Pop();

4
ICSharpCode.NRefactory.CSharp/Analysis/DefiniteAssignmentAnalysis.cs

@ -443,7 +443,7 @@ namespace ICSharpCode.NRefactory.CSharp.Analysis @@ -443,7 +443,7 @@ namespace ICSharpCode.NRefactory.CSharp.Analysis
// the special values are valid as output only, not as input
Debug.Assert(data == CleanSpecialValues(data));
DefiniteAssignmentStatus status = data;
foreach (AstNode child in node.Children) {
for (AstNode child = node.FirstChild; child != null; child = child.NextSibling) {
analysis.analysisCancellationToken.ThrowIfCancellationRequested();
Debug.Assert(!(child is Statement)); // statements are visited with the CFG, not with the visitor pattern
@ -721,7 +721,7 @@ namespace ICSharpCode.NRefactory.CSharp.Analysis @@ -721,7 +721,7 @@ namespace ICSharpCode.NRefactory.CSharp.Analysis
}
DefiniteAssignmentStatus afterTrue = conditionalExpression.TrueExpression.AcceptVisitor(this, beforeTrue);
DefiniteAssignmentStatus afterFalse = conditionalExpression.TrueExpression.AcceptVisitor(this, beforeFalse);
DefiniteAssignmentStatus afterFalse = conditionalExpression.FalseExpression.AcceptVisitor(this, beforeFalse);
return MergeStatus(CleanSpecialValues(afterTrue), CleanSpecialValues(afterFalse));
}
}

77
ICSharpCode.NRefactory.CSharp/Ast/AstNode.cs

@ -1,4 +1,4 @@ @@ -1,4 +1,4 @@
//
//
// AstNode.cs
//
// Author:
@ -23,6 +23,7 @@ @@ -23,6 +23,7 @@
// 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;
using System.Collections.Generic;
@ -194,13 +195,13 @@ namespace ICSharpCode.NRefactory.CSharp @@ -194,13 +195,13 @@ namespace ICSharpCode.NRefactory.CSharp
/// <summary>
/// Gets the region from StartLocation to EndLocation for this node.
/// The file name of the region is set based on the parent CompilationUnit's file name.
/// The file name of the region is set based on the parent SyntaxTree's file name.
/// If this node is not connected to a whole compilation, the file name will be null.
/// </summary>
public ICSharpCode.NRefactory.TypeSystem.DomRegion GetRegion()
{
var cu = (this.Ancestors.LastOrDefault() ?? this) as CompilationUnit;
string fileName = (cu != null ? cu.FileName : null);
var syntaxTree = (this.Ancestors.LastOrDefault() ?? this) as SyntaxTree;
string fileName = (syntaxTree != null ? syntaxTree.FileName : null);
return new ICSharpCode.NRefactory.TypeSystem.DomRegion(fileName, this.StartLocation, this.EndLocation);
}
@ -288,17 +289,31 @@ namespace ICSharpCode.NRefactory.CSharp @@ -288,17 +289,31 @@ namespace ICSharpCode.NRefactory.CSharp
/// Gets all descendants of this node (excluding this node itself).
/// </summary>
public IEnumerable<AstNode> Descendants {
get {
return Utils.TreeTraversal.PreOrder (this.Children, n => n.Children);
}
get { return GetDescendants(false); }
}
/// <summary>
/// Gets all descendants of this node (including this node itself).
/// </summary>
public IEnumerable<AstNode> DescendantsAndSelf {
get {
return Utils.TreeTraversal.PreOrder (this, n => n.Children);
get { return GetDescendants(true); }
}
IEnumerable<AstNode> GetDescendants(bool includeSelf)
{
if (includeSelf)
yield return this;
Stack<AstNode> nextStack = new Stack<AstNode>();
nextStack.Push(null);
AstNode pos = firstChild;
while (pos != null) {
if (pos.nextSibling != null)
nextStack.Push(pos.nextSibling);
yield return pos;
if (pos.firstChild != null)
pos = pos.firstChild;
else
pos = nextStack.Pop();
}
}
@ -322,7 +337,7 @@ namespace ICSharpCode.NRefactory.CSharp @@ -322,7 +337,7 @@ namespace ICSharpCode.NRefactory.CSharp
{
return Ancestors.OfType<T>().FirstOrDefault();
}
public AstNodeCollection<T> GetChildrenByRole<T> (Role<T> role) where T : AstNode
{
return new AstNodeCollection<T> (this, role);
@ -367,13 +382,6 @@ namespace ICSharpCode.NRefactory.CSharp @@ -367,13 +382,6 @@ namespace ICSharpCode.NRefactory.CSharp
}
}
public void InsertChildsBefore<T>(AstNode nextSibling, Role<T> role, params T[] child) where T : AstNode
{
foreach (var cur in child) {
InsertChildBefore(nextSibling, cur, role);
}
}
public void InsertChildBefore<T> (AstNode nextSibling, T child, Role<T> role) where T : AstNode
{
if (role == null)
@ -483,25 +491,24 @@ namespace ICSharpCode.NRefactory.CSharp @@ -483,25 +491,24 @@ namespace ICSharpCode.NRefactory.CSharp
newNode.SetRole(this.Role);
newNode.prevSibling = prevSibling;
newNode.nextSibling = nextSibling;
if (parent != null) {
if (prevSibling != null) {
Debug.Assert (prevSibling.nextSibling == this);
prevSibling.nextSibling = newNode;
} else {
Debug.Assert (parent.firstChild == this);
parent.firstChild = newNode;
}
if (nextSibling != null) {
Debug.Assert (nextSibling.prevSibling == this);
nextSibling.prevSibling = newNode;
} else {
Debug.Assert (parent.lastChild == this);
parent.lastChild = newNode;
}
parent = null;
prevSibling = null;
nextSibling = null;
if (prevSibling != null) {
Debug.Assert (prevSibling.nextSibling == this);
prevSibling.nextSibling = newNode;
} else {
Debug.Assert (parent.firstChild == this);
parent.firstChild = newNode;
}
if (nextSibling != null) {
Debug.Assert (nextSibling.prevSibling == this);
nextSibling.prevSibling = newNode;
} else {
Debug.Assert (parent.lastChild == this);
parent.lastChild = newNode;
}
parent = null;
prevSibling = null;
nextSibling = null;
}
public AstNode ReplaceWith (Func<AstNode, AstNode> replaceFunction)

16
ICSharpCode.NRefactory.CSharp/Ast/AstNodeCollection.cs

@ -204,5 +204,21 @@ namespace ICSharpCode.NRefactory.CSharp @@ -204,5 +204,21 @@ namespace ICSharpCode.NRefactory.CSharp
{
node.InsertChildBefore(existingItem, newItem, role);
}
/// <summary>
/// Applies the <paramref name="visitor"/> to all nodes in this collection.
/// </summary>
public void AcceptVisitor(IAstVisitor visitor)
{
AstNode next;
for (AstNode cur = node.FirstChild; cur != null; cur = next) {
Debug.Assert(cur.Parent == node);
// Remember next before yielding cur.
// This allows removing/replacing nodes while iterating through the list.
next = cur.NextSibling;
if (cur.Role == role)
cur.AcceptVisitor(visitor);
}
}
}
}

6
ICSharpCode.NRefactory.CSharp/Ast/AstType.cs

@ -58,7 +58,7 @@ namespace ICSharpCode.NRefactory.CSharp @@ -58,7 +58,7 @@ namespace ICSharpCode.NRefactory.CSharp
return other == null || other.IsNull;
}
public override ITypeReference ToTypeReference(SimpleNameLookupMode lookupMode)
public override ITypeReference ToTypeReference(NameLookupMode lookupMode)
{
return SpecialType.UnknownType;
}
@ -99,7 +99,7 @@ namespace ICSharpCode.NRefactory.CSharp @@ -99,7 +99,7 @@ namespace ICSharpCode.NRefactory.CSharp
return visitor.VisitPatternPlaceholder (this, child, data);
}
public override ITypeReference ToTypeReference(SimpleNameLookupMode lookupMode)
public override ITypeReference ToTypeReference(NameLookupMode lookupMode)
{
throw new NotSupportedException();
}
@ -135,7 +135,7 @@ namespace ICSharpCode.NRefactory.CSharp @@ -135,7 +135,7 @@ namespace ICSharpCode.NRefactory.CSharp
/// For resolving simple names, the current namespace and usings from the CurrentUsingScope
/// (on CSharpTypeResolveContext only) is used.
/// </remarks>
public abstract ITypeReference ToTypeReference(SimpleNameLookupMode lookupMode = SimpleNameLookupMode.Type);
public abstract ITypeReference ToTypeReference(NameLookupMode lookupMode = NameLookupMode.Type);
/// <summary>
/// Creates a pointer type from this type by nesting it in a <see cref="ComposedType"/>.

50
ICSharpCode.NRefactory.CSharp/Ast/CSharpUtil.cs

@ -51,28 +51,11 @@ namespace ICSharpCode.NRefactory.CSharp @@ -51,28 +51,11 @@ namespace ICSharpCode.NRefactory.CSharp
if (condition is BinaryOperatorExpression) {
var bOp = (BinaryOperatorExpression)condition;
switch (bOp.Operator) {
case BinaryOperatorType.GreaterThan:
bOp.Operator = BinaryOperatorType.LessThanOrEqual;
return bOp;
case BinaryOperatorType.GreaterThanOrEqual:
bOp.Operator = BinaryOperatorType.LessThan;
return bOp;
case BinaryOperatorType.Equality:
bOp.Operator = BinaryOperatorType.InEquality;
return bOp;
case BinaryOperatorType.InEquality:
bOp.Operator = BinaryOperatorType.Equality;
return bOp;
case BinaryOperatorType.LessThan:
bOp.Operator = BinaryOperatorType.GreaterThanOrEqual;
return bOp;
case BinaryOperatorType.LessThanOrEqual:
bOp.Operator = BinaryOperatorType.GreaterThan;
return bOp;
default:
var negatedOp = NegateRelationalOperator (bOp.Operator);
if (negatedOp == BinaryOperatorType.Any)
return new UnaryOperatorExpression (UnaryOperatorType.Not, new ParenthesizedExpression (condition));
}
bOp.Operator = negatedOp;
return bOp;
}
if (condition is ConditionalExpression) {
var cEx = condition as ConditionalExpression;
@ -88,6 +71,31 @@ namespace ICSharpCode.NRefactory.CSharp @@ -88,6 +71,31 @@ namespace ICSharpCode.NRefactory.CSharp
return new UnaryOperatorExpression (UnaryOperatorType.Not, condition);
}
/// <summary>
/// Get negation of the specified relational operator
/// </summary>
/// <returns>
/// negation of the specified relational operator, or BinaryOperatorType.Any if it's not a relational operator
/// </returns>
public static BinaryOperatorType NegateRelationalOperator (BinaryOperatorType op)
{
switch (op) {
case BinaryOperatorType.GreaterThan:
return BinaryOperatorType.LessThanOrEqual;
case BinaryOperatorType.GreaterThanOrEqual:
return BinaryOperatorType.LessThan;
case BinaryOperatorType.Equality:
return BinaryOperatorType.InEquality;
case BinaryOperatorType.InEquality:
return BinaryOperatorType.Equality;
case BinaryOperatorType.LessThan:
return BinaryOperatorType.GreaterThanOrEqual;
case BinaryOperatorType.LessThanOrEqual:
return BinaryOperatorType.GreaterThan;
}
return BinaryOperatorType.Any;
}
}
}

2
ICSharpCode.NRefactory.CSharp/Ast/ComposedType.cs

@ -126,7 +126,7 @@ namespace ICSharpCode.NRefactory.CSharp @@ -126,7 +126,7 @@ namespace ICSharpCode.NRefactory.CSharp
return this;
}
public override ITypeReference ToTypeReference(SimpleNameLookupMode lookupMode = SimpleNameLookupMode.Type)
public override ITypeReference ToTypeReference(NameLookupMode lookupMode = NameLookupMode.Type)
{
ITypeReference t = this.BaseType.ToTypeReference(lookupMode);
if (this.HasNullableSpecifier) {

8
ICSharpCode.NRefactory.CSharp/Ast/DepthFirstAstVisitor.cs

@ -44,9 +44,9 @@ namespace ICSharpCode.NRefactory.CSharp @@ -44,9 +44,9 @@ namespace ICSharpCode.NRefactory.CSharp
}
}
public virtual void VisitCompilationUnit (CompilationUnit unit)
public virtual void VisitSyntaxTree (SyntaxTree syntaxTree)
{
VisitChildren (unit);
VisitChildren (syntaxTree);
}
public virtual void VisitComment(Comment comment)
@ -642,7 +642,7 @@ namespace ICSharpCode.NRefactory.CSharp @@ -642,7 +642,7 @@ namespace ICSharpCode.NRefactory.CSharp
return default (T);
}
public virtual T VisitCompilationUnit (CompilationUnit unit)
public virtual T VisitSyntaxTree (SyntaxTree unit)
{
return VisitChildren (unit);
}
@ -1240,7 +1240,7 @@ namespace ICSharpCode.NRefactory.CSharp @@ -1240,7 +1240,7 @@ namespace ICSharpCode.NRefactory.CSharp
return default (S);
}
public virtual S VisitCompilationUnit (CompilationUnit unit, T data)
public virtual S VisitSyntaxTree (SyntaxTree unit, T data)
{
return VisitChildren (unit, data);
}

79
ICSharpCode.NRefactory.CSharp/Ast/Expressions/ArrayInitializerExpression.cs

@ -33,6 +33,18 @@ namespace ICSharpCode.NRefactory.CSharp @@ -33,6 +33,18 @@ namespace ICSharpCode.NRefactory.CSharp
/// </summary>
public class ArrayInitializerExpression : Expression
{
/// <summary>
/// For ease of use purposes in the resolver the ast representation
/// of { a, b, c } is { {a}, {b}, {c} }.
/// If IsSingleElement is true then this array initializer expression is a generated one.
/// That has no meaning in the source code (and contains no brace tokens).
/// </summary>
public virtual bool IsSingleElement {
get {
return false;
}
}
public ArrayInitializerExpression()
{
}
@ -61,7 +73,7 @@ namespace ICSharpCode.NRefactory.CSharp @@ -61,7 +73,7 @@ namespace ICSharpCode.NRefactory.CSharp
public override void AcceptVisitor (IAstVisitor visitor)
{
}
public override T AcceptVisitor<T> (IAstVisitor<T> visitor)
{
return default (T);
@ -95,7 +107,7 @@ namespace ICSharpCode.NRefactory.CSharp @@ -95,7 +107,7 @@ namespace ICSharpCode.NRefactory.CSharp
{
visitor.VisitArrayInitializerExpression (this);
}
public override T AcceptVisitor<T> (IAstVisitor<T> visitor)
{
return visitor.VisitArrayInitializerExpression (this);
@ -111,6 +123,69 @@ namespace ICSharpCode.NRefactory.CSharp @@ -111,6 +123,69 @@ namespace ICSharpCode.NRefactory.CSharp
ArrayInitializerExpression o = other as ArrayInitializerExpression;
return o != null && this.Elements.DoMatch(o.Elements, match);
}
public static ArrayInitializerExpression CreateSingleElementInitializer ()
{
return new SingleArrayInitializerExpression();
}
/// <summary>
/// Single elements in array initializers are represented with this special class.
/// </summary>
class SingleArrayInitializerExpression : ArrayInitializerExpression
{
public override bool IsSingleElement {
get {
return true;
}
}
}
#region PatternPlaceholder
public static implicit operator ArrayInitializerExpression(PatternMatching.Pattern pattern)
{
return pattern != null ? new PatternPlaceholder(pattern) : null;
}
sealed class PatternPlaceholder : ArrayInitializerExpression, PatternMatching.INode
{
readonly PatternMatching.Pattern child;
public PatternPlaceholder(PatternMatching.Pattern child)
{
this.child = child;
}
public override NodeType NodeType {
get { return NodeType.Pattern; }
}
public override void AcceptVisitor (IAstVisitor visitor)
{
visitor.VisitPatternPlaceholder(this, child);
}
public override T AcceptVisitor<T> (IAstVisitor<T> visitor)
{
return visitor.VisitPatternPlaceholder(this, child);
}
public override S AcceptVisitor<T, S>(IAstVisitor<T, S> visitor, T data)
{
return visitor.VisitPatternPlaceholder(this, child, data);
}
protected internal override bool DoMatch(AstNode other, PatternMatching.Match match)
{
return child.DoMatch(other, match);
}
bool PatternMatching.INode.DoMatchCollection(Role role, PatternMatching.INode pos, PatternMatching.Match match, PatternMatching.BacktrackingInfo backtrackingInfo)
{
return child.DoMatchCollection(role, pos, match, backtrackingInfo);
}
}
#endregion
}
}

11
ICSharpCode.NRefactory.CSharp/Ast/Expressions/IdentifierExpression.cs

@ -55,7 +55,16 @@ namespace ICSharpCode.NRefactory.CSharp @@ -55,7 +55,16 @@ namespace ICSharpCode.NRefactory.CSharp
SetChildByRole(Roles.Identifier, CSharp.Identifier.Create (value));
}
}
public Identifier IdentifierToken {
get {
return GetChildByRole (Roles.Identifier);
}
set {
SetChildByRole (Roles.Identifier, value);
}
}
public AstNodeCollection<AstType> TypeArguments {
get { return GetChildrenByRole (Roles.TypeArgument); }
}

12
ICSharpCode.NRefactory.CSharp/Ast/Expressions/MemberReferenceExpression.cs

@ -34,8 +34,16 @@ namespace ICSharpCode.NRefactory.CSharp @@ -34,8 +34,16 @@ namespace ICSharpCode.NRefactory.CSharp
public class MemberReferenceExpression : Expression
{
public Expression Target {
get { return GetChildByRole (Roles.TargetExpression); }
set { SetChildByRole(Roles.TargetExpression, value); }
get {
return GetChildByRole(Roles.TargetExpression);
}
set {
SetChildByRole(Roles.TargetExpression, value);
}
}
public CSharpTokenNode DotToken {
get { return GetChildByRole (Roles.Dot); }
}
public string MemberName {

10
ICSharpCode.NRefactory.CSharp/Ast/Expressions/NamedArgumentExpression.cs

@ -30,13 +30,13 @@ namespace ICSharpCode.NRefactory.CSharp @@ -30,13 +30,13 @@ namespace ICSharpCode.NRefactory.CSharp
{
}
public NamedArgumentExpression(string identifier, Expression expression)
public NamedArgumentExpression(string name, Expression expression)
{
this.Identifier = identifier;
this.Name = name;
this.Expression = expression;
}
public string Identifier {
public string Name {
get {
return GetChildByRole (Roles.Identifier).Name;
}
@ -45,7 +45,7 @@ namespace ICSharpCode.NRefactory.CSharp @@ -45,7 +45,7 @@ namespace ICSharpCode.NRefactory.CSharp
}
}
public Identifier IdentifierToken {
public Identifier NameToken {
get {
return GetChildByRole (Roles.Identifier);
}
@ -81,7 +81,7 @@ namespace ICSharpCode.NRefactory.CSharp @@ -81,7 +81,7 @@ namespace ICSharpCode.NRefactory.CSharp
protected internal override bool DoMatch(AstNode other, PatternMatching.Match match)
{
NamedArgumentExpression o = other as NamedArgumentExpression;
return o != null && MatchString(this.Identifier, o.Identifier) && this.Expression.DoMatch(o.Expression, match);
return o != null && MatchString(this.Name, o.Name) && this.Expression.DoMatch(o.Expression, match);
}
}
}

10
ICSharpCode.NRefactory.CSharp/Ast/Expressions/NamedExpression.cs

@ -40,13 +40,13 @@ namespace ICSharpCode.NRefactory.CSharp @@ -40,13 +40,13 @@ namespace ICSharpCode.NRefactory.CSharp
{
}
public NamedExpression (string identifier, Expression expression)
public NamedExpression (string name, Expression expression)
{
this.Identifier = identifier;
this.Name = name;
this.Expression = expression;
}
public string Identifier {
public string Name {
get {
return GetChildByRole (Roles.Identifier).Name;
}
@ -55,7 +55,7 @@ namespace ICSharpCode.NRefactory.CSharp @@ -55,7 +55,7 @@ namespace ICSharpCode.NRefactory.CSharp
}
}
public Identifier IdentifierToken {
public Identifier NameToken {
get {
return GetChildByRole (Roles.Identifier);
}
@ -91,7 +91,7 @@ namespace ICSharpCode.NRefactory.CSharp @@ -91,7 +91,7 @@ namespace ICSharpCode.NRefactory.CSharp
protected internal override bool DoMatch(AstNode other, PatternMatching.Match match)
{
var o = other as NamedExpression;
return o != null && MatchString(this.Identifier, o.Identifier) && this.Expression.DoMatch(o.Expression, match);
return o != null && MatchString(this.Name, o.Name) && this.Expression.DoMatch(o.Expression, match);
}
}
}

15
ICSharpCode.NRefactory.CSharp/Ast/Expressions/PointerReferenceExpression.cs

@ -43,13 +43,22 @@ namespace ICSharpCode.NRefactory.CSharp @@ -43,13 +43,22 @@ namespace ICSharpCode.NRefactory.CSharp
public CSharpTokenNode ArrowToken {
get { return GetChildByRole (ArrowRole); }
}
public string MemberName {
get {
return GetChildByRole (Roles.Identifier).Name;
}
set {
SetChildByRole(Roles.Identifier, Identifier.Create (value));
SetChildByRole(Roles.Identifier, Identifier.Create (value));
}
}
public Identifier MemberNameToken {
get {
return GetChildByRole (Roles.Identifier);
}
set {
SetChildByRole (Roles.Identifier, value);
}
}
@ -61,7 +70,7 @@ namespace ICSharpCode.NRefactory.CSharp @@ -61,7 +70,7 @@ namespace ICSharpCode.NRefactory.CSharp
{
visitor.VisitPointerReferenceExpression (this);
}
public override T AcceptVisitor<T> (IAstVisitor<T> visitor)
{
return visitor.VisitPointerReferenceExpression (this);

2
ICSharpCode.NRefactory.CSharp/Ast/GeneralScope/NamespaceDeclaration.cs

@ -35,7 +35,7 @@ namespace ICSharpCode.NRefactory.CSharp @@ -35,7 +35,7 @@ namespace ICSharpCode.NRefactory.CSharp
/// </summary>
public class NamespaceDeclaration : AstNode
{
public static readonly Role<AstNode> MemberRole = CompilationUnit.MemberRole;
public static readonly Role<AstNode> MemberRole = SyntaxTree.MemberRole;
public override NodeType NodeType {
get {

10
ICSharpCode.NRefactory.CSharp/Ast/GeneralScope/PreProcessorDirective.cs

@ -86,13 +86,19 @@ namespace ICSharpCode.NRefactory.CSharp @@ -86,13 +86,19 @@ namespace ICSharpCode.NRefactory.CSharp
}
}
public PreProcessorDirective (PreProcessorDirectiveType type, TextLocation startLocation, TextLocation endLocation)
public PreProcessorDirective(PreProcessorDirectiveType type, TextLocation startLocation, TextLocation endLocation)
{
this.Type = type;
this.startLocation = startLocation;
this.endLocation = endLocation;
}
public PreProcessorDirective(PreProcessorDirectiveType type, string argument = null)
{
this.Type = type;
this.Argument = argument;
}
public override void AcceptVisitor (IAstVisitor visitor)
{
visitor.VisitPreProcessorDirective (this);

6
ICSharpCode.NRefactory.CSharp/Ast/IAstVisitor.cs

@ -129,7 +129,7 @@ namespace ICSharpCode.NRefactory.CSharp @@ -129,7 +129,7 @@ namespace ICSharpCode.NRefactory.CSharp
void VisitFixedFieldDeclaration(FixedFieldDeclaration fixedFieldDeclaration);
void VisitFixedVariableInitializer(FixedVariableInitializer fixedVariableInitializer);
void VisitCompilationUnit(CompilationUnit compilationUnit);
void VisitSyntaxTree(SyntaxTree syntaxTree);
void VisitSimpleType(SimpleType simpleType);
void VisitMemberType(MemberType memberType);
void VisitComposedType(ComposedType composedType);
@ -260,7 +260,7 @@ namespace ICSharpCode.NRefactory.CSharp @@ -260,7 +260,7 @@ namespace ICSharpCode.NRefactory.CSharp
S VisitFixedFieldDeclaration(FixedFieldDeclaration fixedFieldDeclaration);
S VisitFixedVariableInitializer(FixedVariableInitializer fixedVariableInitializer);
S VisitCompilationUnit(CompilationUnit compilationUnit);
S VisitSyntaxTree(SyntaxTree syntaxTree);
S VisitSimpleType(SimpleType simpleType);
S VisitMemberType(MemberType memberType);
S VisitComposedType(ComposedType composedType);
@ -391,7 +391,7 @@ namespace ICSharpCode.NRefactory.CSharp @@ -391,7 +391,7 @@ namespace ICSharpCode.NRefactory.CSharp
S VisitFixedFieldDeclaration(FixedFieldDeclaration fixedFieldDeclaration, T data);
S VisitFixedVariableInitializer(FixedVariableInitializer fixedVariableInitializer, T data);
S VisitCompilationUnit(CompilationUnit compilationUnit, T data);
S VisitSyntaxTree(SyntaxTree syntaxTree, T data);
S VisitSimpleType(SimpleType simpleType, T data);
S VisitMemberType(MemberType memberType, T data);
S VisitComposedType(ComposedType composedType, T data);

4
ICSharpCode.NRefactory.CSharp/Ast/MemberType.cs

@ -135,7 +135,7 @@ namespace ICSharpCode.NRefactory.CSharp @@ -135,7 +135,7 @@ namespace ICSharpCode.NRefactory.CSharp
return b.ToString();
}
public override ITypeReference ToTypeReference(SimpleNameLookupMode lookupMode = SimpleNameLookupMode.Type)
public override ITypeReference ToTypeReference(NameLookupMode lookupMode = NameLookupMode.Type)
{
TypeOrNamespaceReference t;
if (this.IsDoubleColon) {
@ -154,7 +154,7 @@ namespace ICSharpCode.NRefactory.CSharp @@ -154,7 +154,7 @@ namespace ICSharpCode.NRefactory.CSharp
foreach (var ta in this.TypeArguments) {
typeArguments.Add(ta.ToTypeReference(lookupMode));
}
return new MemberTypeOrNamespaceReference(t, this.MemberName, typeArguments);
return new MemberTypeOrNamespaceReference(t, this.MemberName, typeArguments, lookupMode);
}
}
}

1292
ICSharpCode.NRefactory.CSharp/Ast/ObservableAstVisitor.cs

File diff suppressed because it is too large Load Diff

2
ICSharpCode.NRefactory.CSharp/Ast/PrimitiveType.cs

@ -103,7 +103,7 @@ namespace ICSharpCode.NRefactory.CSharp @@ -103,7 +103,7 @@ namespace ICSharpCode.NRefactory.CSharp
return Keyword;
}
public override ITypeReference ToTypeReference(SimpleNameLookupMode lookupMode = SimpleNameLookupMode.Type)
public override ITypeReference ToTypeReference(NameLookupMode lookupMode = NameLookupMode.Type)
{
KnownTypeCode typeCode = GetTypeCodeForPrimitiveType(this.Keyword);
if (typeCode == KnownTypeCode.None)

4
ICSharpCode.NRefactory.CSharp/Ast/SimpleType.cs

@ -66,7 +66,7 @@ namespace ICSharpCode.NRefactory.CSharp @@ -66,7 +66,7 @@ namespace ICSharpCode.NRefactory.CSharp
return other == null || other.IsNull;
}
public override ITypeReference ToTypeReference(SimpleNameLookupMode lookupMode)
public override ITypeReference ToTypeReference(NameLookupMode lookupMode)
{
return SpecialType.UnknownType;
}
@ -158,7 +158,7 @@ namespace ICSharpCode.NRefactory.CSharp @@ -158,7 +158,7 @@ namespace ICSharpCode.NRefactory.CSharp
return b.ToString();
}
public override ITypeReference ToTypeReference(SimpleNameLookupMode lookupMode = SimpleNameLookupMode.Type)
public override ITypeReference ToTypeReference(NameLookupMode lookupMode = NameLookupMode.Type)
{
var typeArguments = new List<ITypeReference>();
foreach (var ta in this.TypeArguments) {

34
ICSharpCode.NRefactory.CSharp/Ast/Statements/TryCatchStatement.cs

@ -36,7 +36,7 @@ namespace ICSharpCode.NRefactory.CSharp @@ -36,7 +36,7 @@ namespace ICSharpCode.NRefactory.CSharp
{
public static readonly TokenRole TryKeywordRole = new TokenRole ("try");
public static readonly Role<BlockStatement> TryBlockRole = new Role<BlockStatement>("TryBlock", BlockStatement.Null);
public static readonly Role<CatchClause> CatchClauseRole = new Role<CatchClause>("CatchClause");
public static readonly Role<CatchClause> CatchClauseRole = new Role<CatchClause>("CatchClause", CatchClause.Null);
public static readonly TokenRole FinallyKeywordRole = new TokenRole ("finally");
public static readonly Role<BlockStatement> FinallyBlockRole = new Role<BlockStatement>("FinallyBlock", BlockStatement.Null);
@ -90,7 +90,39 @@ namespace ICSharpCode.NRefactory.CSharp @@ -90,7 +90,39 @@ namespace ICSharpCode.NRefactory.CSharp
public class CatchClause : AstNode
{
public static readonly TokenRole CatchKeywordRole = new TokenRole ("catch");
#region Null
public new static readonly CatchClause Null = new NullCatchClause ();
sealed class NullCatchClause : CatchClause
{
public override bool IsNull {
get {
return true;
}
}
public override void AcceptVisitor (IAstVisitor visitor)
{
}
public override T AcceptVisitor<T> (IAstVisitor<T> visitor)
{
return default (T);
}
public override S AcceptVisitor<T, S> (IAstVisitor<T, S> visitor, T data)
{
return default (S);
}
protected internal override bool DoMatch(AstNode other, PatternMatching.Match match)
{
return other == null || other.IsNull;
}
}
#endregion
#region PatternPlaceholder
public static implicit operator CatchClause(PatternMatching.Pattern pattern)
{

85
ICSharpCode.NRefactory.CSharp/Ast/CompilationUnit.cs → ICSharpCode.NRefactory.CSharp/Ast/SyntaxTree.cs

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
//
// CompilationUnit.cs
// SyntaxTree.cs
//
// Author:
// Mike Krüger <mkrueger@novell.com>
@ -23,6 +23,7 @@ @@ -23,6 +23,7 @@
// 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 ICSharpCode.NRefactory.CSharp.Resolver;
@ -35,7 +36,10 @@ using ICSharpCode.NRefactory.Editor; @@ -35,7 +36,10 @@ using ICSharpCode.NRefactory.Editor;
namespace ICSharpCode.NRefactory.CSharp
{
public class CompilationUnit : AstNode
[Obsolete("CompilationUnit was renamed to SyntaxTree", true)]
public class CompilationUnit {}
public class SyntaxTree : AstNode
{
public static readonly Role<AstNode> MemberRole = new Role<AstNode>("Member", AstNode.Null);
@ -48,7 +52,7 @@ namespace ICSharpCode.NRefactory.CSharp @@ -48,7 +52,7 @@ namespace ICSharpCode.NRefactory.CSharp
string fileName;
/// <summary>
/// Gets/Sets the file name of this compilation unit.
/// Gets/Sets the file name of this syntax tree.
/// </summary>
public string FileName {
get { return fileName; }
@ -61,26 +65,43 @@ namespace ICSharpCode.NRefactory.CSharp @@ -61,26 +65,43 @@ namespace ICSharpCode.NRefactory.CSharp
public AstNodeCollection<AstNode> Members {
get { return GetChildrenByRole(MemberRole); }
}
IList<string> conditionalSymbols = null;
List<Error> errors = new List<Error> ();
public List<Error> Errors {
get { return errors; }
}
/// <summary>
/// Gets the conditional symbols used to parse the source file. Note that this list contains
/// the conditional symbols at the start of the first token in the file - including the ones defined
/// in the source file.
/// </summary>
public IList<string> ConditionalSymbols {
get {
return conditionalSymbols ?? EmptyList<string>.Instance;
}
internal set {
conditionalSymbols = value;
}
}
/// <summary>
/// Gets the expression that was on top of the parse stack.
/// This is the only way to get an expression that isn't part of a statment.
/// (eg. when an error follows an expression).
///
/// This is used for code completion to 'get the expression before a token - like ., <, ('.
/// This is used for code completion to 'get the expression before a token - like ., &lt;, ('.
/// </summary>
public AstNode TopExpression {
get;
internal set;
}
public CompilationUnit ()
public SyntaxTree ()
{
}
@ -103,67 +124,59 @@ namespace ICSharpCode.NRefactory.CSharp @@ -103,67 +124,59 @@ namespace ICSharpCode.NRefactory.CSharp
protected internal override bool DoMatch(AstNode other, PatternMatching.Match match)
{
CompilationUnit o = other as CompilationUnit;
SyntaxTree o = other as SyntaxTree;
return o != null && GetChildrenByRole(MemberRole).DoMatch(o.GetChildrenByRole(MemberRole), match);
}
public override void AcceptVisitor (IAstVisitor visitor)
{
visitor.VisitCompilationUnit (this);
visitor.VisitSyntaxTree (this);
}
public override T AcceptVisitor<T> (IAstVisitor<T> visitor)
{
return visitor.VisitCompilationUnit (this);
return visitor.VisitSyntaxTree (this);
}
public override S AcceptVisitor<T, S> (IAstVisitor<T, S> visitor, T data)
{
return visitor.VisitCompilationUnit (this, data);
return visitor.VisitSyntaxTree (this, data);
}
/// <summary>
/// Converts this compilation unit into a parsed file that can be stored in the type system.
/// Converts this syntax tree into a parsed file that can be stored in the type system.
/// </summary>
public CSharpParsedFile ToTypeSystem ()
public CSharpUnresolvedFile ToTypeSystem ()
{
if (string.IsNullOrEmpty (this.FileName))
throw new InvalidOperationException ("Cannot use ToTypeSystem() on a compilation unit without file name.");
throw new InvalidOperationException ("Cannot use ToTypeSystem() on a syntax tree without file name.");
var v = new TypeSystemConvertVisitor (this.FileName);
v.VisitCompilationUnit (this);
return v.ParsedFile;
v.VisitSyntaxTree (this);
return v.UnresolvedFile;
}
public static CompilationUnit Parse (string text, string fileName = "", CompilerSettings settings = null, CancellationToken cancellationToken = default (CancellationToken))
public static SyntaxTree Parse (string program, string fileName = "", CompilerSettings settings = null, CancellationToken cancellationToken = default (CancellationToken))
{
var parser = new CSharpParser ();
if (settings != null)
parser.CompilerSettings = settings;
return parser.Parse (text, fileName);
var parser = new CSharpParser (settings);
return parser.Parse (program, fileName);
}
public static CompilationUnit Parse (TextReader reader, string fileName = "", CompilerSettings settings = null, CancellationToken cancellationToken = default (CancellationToken))
public static SyntaxTree Parse (TextReader reader, string fileName = "", CompilerSettings settings = null, CancellationToken cancellationToken = default (CancellationToken))
{
var parser = new CSharpParser ();
if (settings != null)
parser.CompilerSettings = settings;
return parser.Parse (reader, fileName, 0);
var parser = new CSharpParser (settings);
return parser.Parse (reader, fileName);
}
public static CompilationUnit Parse (Stream stream, string fileName = "", CompilerSettings settings = null, CancellationToken cancellationToken = default (CancellationToken))
public static SyntaxTree Parse (Stream stream, string fileName = "", CompilerSettings settings = null, CancellationToken cancellationToken = default (CancellationToken))
{
var parser = new CSharpParser ();
if (settings != null)
parser.CompilerSettings = settings;
return parser.Parse (stream, fileName, 0);
var parser = new CSharpParser (settings);
return parser.Parse (stream, fileName);
}
public static CompilationUnit Parse (ITextSource textSource, string fileName = "", CompilerSettings settings = null, CancellationToken cancellationToken = default (CancellationToken))
public static SyntaxTree Parse (ITextSource textSource, string fileName = "", CompilerSettings settings = null, CancellationToken cancellationToken = default (CancellationToken))
{
var parser = new CSharpParser ();
if (settings != null)
parser.CompilerSettings = settings;
return parser.Parse (textSource, fileName, 0);
var parser = new CSharpParser (settings);
return parser.Parse (textSource, fileName);
}
}
}

13
ICSharpCode.NRefactory.CSharp/Ast/TypeMembers/IndexerDeclaration.cs

@ -24,6 +24,7 @@ @@ -24,6 +24,7 @@
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
using System;
using ICSharpCode.NRefactory.TypeSystem;
namespace ICSharpCode.NRefactory.CSharp
@ -47,6 +48,16 @@ namespace ICSharpCode.NRefactory.CSharp @@ -47,6 +48,16 @@ namespace ICSharpCode.NRefactory.CSharp
set { SetChildByRole (PrivateImplementationTypeRole, value); }
}
public override string Name {
get { return "Item"; }
set { throw new NotSupportedException(); }
}
public override Identifier NameToken {
get { return Identifier.Null; }
set { throw new NotSupportedException(); }
}
public CSharpTokenNode LBracketToken {
get { return GetChildByRole (Roles.LBracket); }
}
@ -95,7 +106,7 @@ namespace ICSharpCode.NRefactory.CSharp @@ -95,7 +106,7 @@ namespace ICSharpCode.NRefactory.CSharp
protected internal override bool DoMatch(AstNode other, PatternMatching.Match match)
{
IndexerDeclaration o = other as IndexerDeclaration;
return o != null && MatchString(this.Name, o.Name)
return o != null
&& this.MatchAttributesAndModifiers(o, match) && this.ReturnType.DoMatch(o.ReturnType, match)
&& this.PrivateImplementationType.DoMatch(o.PrivateImplementationType, match)
&& this.Parameters.DoMatch(o.Parameters, match)

1201
ICSharpCode.NRefactory.CSharp/Ast/old_ObservableAstVisitor.cs

File diff suppressed because it is too large Load Diff

134
ICSharpCode.NRefactory.CSharp/CSharpProjectContent.cs

@ -31,34 +31,57 @@ namespace ICSharpCode.NRefactory.CSharp @@ -31,34 +31,57 @@ namespace ICSharpCode.NRefactory.CSharp
public class CSharpProjectContent : IProjectContent
{
string assemblyName;
Dictionary<string, IParsedFile> parsedFiles;
string projectFileName;
string location;
Dictionary<string, IUnresolvedFile> unresolvedFiles;
List<IAssemblyReference> assemblyReferences;
CompilerSettings compilerSettings;
public CSharpProjectContent()
{
this.assemblyName = string.Empty;
this.parsedFiles = new Dictionary<string, IParsedFile>(Platform.FileNameComparer);
this.unresolvedFiles = new Dictionary<string, IUnresolvedFile>(Platform.FileNameComparer);
this.assemblyReferences = new List<IAssemblyReference>();
this.compilerSettings = new CompilerSettings();
compilerSettings.Freeze();
}
protected CSharpProjectContent(CSharpProjectContent pc)
{
this.assemblyName = pc.assemblyName;
this.parsedFiles = new Dictionary<string, IParsedFile>(pc.parsedFiles, Platform.FileNameComparer);
this.projectFileName = pc.projectFileName;
this.location = pc.location;
this.unresolvedFiles = new Dictionary<string, IUnresolvedFile>(pc.unresolvedFiles, Platform.FileNameComparer);
this.assemblyReferences = new List<IAssemblyReference>(pc.assemblyReferences);
this.compilerSettings = pc.compilerSettings;
}
public IEnumerable<IParsedFile> Files {
get { return parsedFiles.Values; }
public IEnumerable<IUnresolvedFile> Files {
get { return unresolvedFiles.Values; }
}
public IEnumerable<IAssemblyReference> AssemblyReferences {
get { return assemblyReferences; }
}
public string ProjectFileName {
get { return projectFileName; }
}
public string AssemblyName {
get { return assemblyName; }
}
public string Location {
get { return location; }
}
public CompilerSettings CompilerSettings {
get { return compilerSettings; }
}
object IProjectContent.CompilerSettings {
get { return compilerSettings; }
}
public IEnumerable<IUnresolvedAttribute> AssemblyAttributes {
get {
@ -78,10 +101,10 @@ namespace ICSharpCode.NRefactory.CSharp @@ -78,10 +101,10 @@ namespace ICSharpCode.NRefactory.CSharp
}
}
public IParsedFile GetFile(string fileName)
public IUnresolvedFile GetFile(string fileName)
{
IParsedFile file;
if (parsedFiles.TryGetValue(fileName, out file))
IUnresolvedFile file;
if (unresolvedFiles.TryGetValue(fileName, out file))
return file;
else
return null;
@ -112,7 +135,36 @@ namespace ICSharpCode.NRefactory.CSharp @@ -112,7 +135,36 @@ namespace ICSharpCode.NRefactory.CSharp
return pc;
}
public IProjectContent SetProjectFileName(string newProjectFileName)
{
CSharpProjectContent pc = Clone();
pc.projectFileName = newProjectFileName;
return pc;
}
public IProjectContent SetLocation(string newLocation)
{
CSharpProjectContent pc = Clone();
pc.location = newLocation;
return pc;
}
public IProjectContent SetCompilerSettings(object compilerSettings)
{
if (!(compilerSettings is CompilerSettings))
throw new ArgumentException("Settings must be an instance of " + typeof(CompilerSettings).FullName, "compilerSettings");
CSharpProjectContent pc = Clone();
pc.compilerSettings = (CompilerSettings)compilerSettings;
pc.compilerSettings.Freeze();
return pc;
}
public IProjectContent AddAssemblyReferences(IEnumerable<IAssemblyReference> references)
{
return AddAssemblyReferences(references.ToArray());
}
public IProjectContent AddAssemblyReferences(params IAssemblyReference[] references)
{
CSharpProjectContent pc = Clone();
pc.assemblyReferences.AddRange(references);
@ -120,13 +172,62 @@ namespace ICSharpCode.NRefactory.CSharp @@ -120,13 +172,62 @@ namespace ICSharpCode.NRefactory.CSharp
}
public IProjectContent RemoveAssemblyReferences(IEnumerable<IAssemblyReference> references)
{
return RemoveAssemblyReferences(references.ToArray());
}
public IProjectContent RemoveAssemblyReferences(params IAssemblyReference[] references)
{
CSharpProjectContent pc = Clone();
foreach (var r in references)
pc.assemblyReferences.Remove(r);
return pc;
}
/// <summary>
/// Adds the specified files to the project content.
/// If a file with the same name already exists, updated the existing file.
/// </summary>
public IProjectContent AddOrUpdateFiles(IEnumerable<IUnresolvedFile> newFiles)
{
CSharpProjectContent pc = Clone();
pc.assemblyReferences.RemoveAll(r => references.Contains(r));
foreach (var file in newFiles) {
pc.unresolvedFiles[file.FileName] = file;
}
return pc;
}
public IProjectContent UpdateProjectContent(IParsedFile oldFile, IParsedFile newFile)
/// <summary>
/// Adds the specified files to the project content.
/// If a file with the same name already exists, this method updates the existing file.
/// </summary>
public IProjectContent AddOrUpdateFiles(params IUnresolvedFile[] newFiles)
{
return AddOrUpdateFiles((IEnumerable<IUnresolvedFile>)newFiles);
}
/// <summary>
/// Removes the files with the specified names.
/// </summary>
public IProjectContent RemoveFiles(IEnumerable<string> fileNames)
{
CSharpProjectContent pc = Clone();
foreach (var fileName in fileNames) {
pc.unresolvedFiles.Remove(fileName);
}
return pc;
}
/// <summary>
/// Removes the files with the specified names.
/// </summary>
public IProjectContent RemoveFiles(params string[] fileNames)
{
return RemoveFiles((IEnumerable<string>)fileNames);
}
[Obsolete("Use RemoveFiles/AddOrUpdateFiles instead")]
public IProjectContent UpdateProjectContent(IUnresolvedFile oldFile, IUnresolvedFile newFile)
{
if (oldFile == null && newFile == null)
return this;
@ -136,23 +237,24 @@ namespace ICSharpCode.NRefactory.CSharp @@ -136,23 +237,24 @@ namespace ICSharpCode.NRefactory.CSharp
}
CSharpProjectContent pc = Clone();
if (newFile == null)
pc.parsedFiles.Remove(oldFile.FileName);
pc.unresolvedFiles.Remove(oldFile.FileName);
else
pc.parsedFiles[newFile.FileName] = newFile;
pc.unresolvedFiles[newFile.FileName] = newFile;
return pc;
}
public IProjectContent UpdateProjectContent(IEnumerable<IParsedFile> oldFiles, IEnumerable<IParsedFile> newFiles)
[Obsolete("Use RemoveFiles/AddOrUpdateFiles instead")]
public IProjectContent UpdateProjectContent(IEnumerable<IUnresolvedFile> oldFiles, IEnumerable<IUnresolvedFile> newFiles)
{
CSharpProjectContent pc = Clone();
if (oldFiles != null) {
foreach (var oldFile in oldFiles) {
pc.parsedFiles.Remove(oldFile.FileName);
pc.unresolvedFiles.Remove(oldFile.FileName);
}
}
if (newFiles != null) {
foreach (var newFile in newFiles) {
pc.parsedFiles.Add(newFile.FileName, newFile);
pc.unresolvedFiles.Add(newFile.FileName, newFile);
}
}
return pc;

1771
ICSharpCode.NRefactory.CSharp/Completion/CSharpCompletionEngine.cs

File diff suppressed because it is too large Load Diff

419
ICSharpCode.NRefactory.CSharp/Completion/CSharpCompletionEngineBase.cs

@ -51,10 +51,6 @@ namespace ICSharpCode.NRefactory.CSharp.Completion @@ -51,10 +51,6 @@ namespace ICSharpCode.NRefactory.CSharp.Completion
#region Input properties
public CSharpTypeResolveContext ctx { get; private set; }
public CompilationUnit Unit { get; private set; }
public CSharpParsedFile CSharpParsedFile { get; private set; }
public IProjectContent ProjectContent { get; private set; }
ICompilation compilation;
@ -68,40 +64,36 @@ namespace ICSharpCode.NRefactory.CSharp.Completion @@ -68,40 +64,36 @@ namespace ICSharpCode.NRefactory.CSharp.Completion
}
#endregion
protected CSharpCompletionEngineBase (IProjectContent content, CSharpTypeResolveContext ctx, CompilationUnit unit, CSharpParsedFile parsedFile)
protected CSharpCompletionEngineBase(IProjectContent content, ICompletionContextProvider completionContextProvider, CSharpTypeResolveContext ctx)
{
if (content == null)
throw new ArgumentNullException ("content");
throw new ArgumentNullException("content");
if (ctx == null)
throw new ArgumentNullException ("ctx");
if (unit == null)
throw new ArgumentNullException ("unit");
if (parsedFile == null)
throw new ArgumentNullException ("parsedFile");
throw new ArgumentNullException("ctx");
if (completionContextProvider == null)
throw new ArgumentNullException("completionContextProvider");
this.ProjectContent = content;
this.CompletionContextProvider = completionContextProvider;
this.ctx = ctx;
this.Unit = unit;
this.CSharpParsedFile = parsedFile;
}
public IMemberProvider MemberProvider {
public ICompletionContextProvider CompletionContextProvider {
get;
set;
private set;
}
protected void SetOffset (int offset)
public void SetOffset (int offset)
{
Reset ();
this.offset = offset;
this.location = document.GetLocation (offset);
var provider = MemberProvider ?? new DefaultMemberProvider (this);
provider.GetCurrentMembers (offset, out currentType, out currentMember);
CompletionContextProvider.GetCurrentMembers (offset, out currentType, out currentMember);
}
protected bool GetParameterCompletionCommandOffset(out int cpos)
public bool GetParameterCompletionCommandOffset (out int cpos)
{
// Start calculating the parameter offset from the beginning of the
// current member, instead of the beginning of the file.
@ -110,12 +102,12 @@ namespace ICSharpCode.NRefactory.CSharp.Completion @@ -110,12 +102,12 @@ namespace ICSharpCode.NRefactory.CSharp.Completion
if (mem == null || (mem is IType)) {
return false;
}
int startPos = document.GetOffset(mem.Region.BeginLine, mem.Region.BeginColumn);
int startPos = document.GetOffset (mem.Region.BeginLine, mem.Region.BeginColumn);
int parenDepth = 0;
int chevronDepth = 0;
Stack<int> indexStack = new Stack<int>();
Stack<int> indexStack = new Stack<int> ();
while (cpos > startPos) {
char c = document.GetCharAt(cpos);
char c = document.GetCharAt (cpos);
if (c == ')') {
parenDepth++;
}
@ -124,14 +116,14 @@ namespace ICSharpCode.NRefactory.CSharp.Completion @@ -124,14 +116,14 @@ namespace ICSharpCode.NRefactory.CSharp.Completion
}
if (c == '}') {
if (indexStack.Count > 0) {
parenDepth = indexStack.Pop();
parenDepth = indexStack.Pop ();
} else {
parenDepth = 0;
}
chevronDepth = 0;
}
if (indexStack.Count == 0 && (parenDepth == 0 && c == '(' || chevronDepth == 0 && c == '<')) {
int p = GetCurrentParameterIndex (cpos + 1, startPos);
int p = GetCurrentParameterIndex (startPos, cpos + 1);
if (p != -1) {
cpos++;
return true;
@ -154,94 +146,144 @@ namespace ICSharpCode.NRefactory.CSharp.Completion @@ -154,94 +146,144 @@ namespace ICSharpCode.NRefactory.CSharp.Completion
return false;
}
protected int GetCurrentParameterIndex (int offset, int memberStart)
public int GetCurrentParameterIndex (int triggerOffset, int endOffset)
{
int cursor = this.offset;
int i = offset;
if (i > cursor) {
return -1;
}
if (i == cursor) {
return 1;
char lastChar = document.GetCharAt (endOffset - 1);
if (lastChar == '(' || lastChar == '<') {
return 0;
}
// parameters are 1 based
int index = memberStart + 1;
int parentheses = 0;
int bracket = 0;
bool insideQuote = false, insideString = false, insideSingleLineComment = false, insideMultiLineComment = false;
Stack<int> indexStack = new Stack<int> ();
do {
char c = document.GetCharAt (i - 1);
switch (c) {
case '\\':
if (insideString || insideQuote) {
i++;
var parameter = new Stack<int> ();
var bracketStack = new Stack<Stack<int>> ();
bool inSingleComment = false, inString = false, inVerbatimString = false, inChar = false, inMultiLineComment = false;
for (int i = triggerOffset; i < endOffset; i++) {
char ch = document.GetCharAt (i);
char nextCh = i + 1 < document.TextLength ? document.GetCharAt (i + 1) : '\0';
switch (ch) {
case '{':
if (inString || inChar || inVerbatimString || inSingleComment || inMultiLineComment) {
break;
}
bracketStack.Push (parameter);
parameter = new Stack<int> ();
break;
case '\'':
if (!insideString && !insideSingleLineComment && !insideMultiLineComment) {
insideQuote = !insideQuote;
case '[':
case '(':
if (inString || inChar || inVerbatimString || inSingleComment || inMultiLineComment) {
break;
}
parameter.Push (0);
break;
case '"':
if (!insideQuote && !insideSingleLineComment && !insideMultiLineComment) {
insideString = !insideString;
case '}':
if (inString || inChar || inVerbatimString || inSingleComment || inMultiLineComment) {
break;
}
if (bracketStack.Count > 0) {
parameter = bracketStack.Pop ();
} else {
return -1;
}
break;
case ']':
case ')':
if (inString || inChar || inVerbatimString || inSingleComment || inMultiLineComment) {
break;
}
if (parameter.Count > 0) {
parameter.Pop ();
} else {
return -1;
}
break;
case '<':
if (inString || inChar || inVerbatimString || inSingleComment || inMultiLineComment) {
break;
}
parameter.Push (0);
break;
case '>':
if (inString || inChar || inVerbatimString || inSingleComment || inMultiLineComment) {
break;
}
if (parameter.Count > 0) {
parameter.Pop ();
}
break;
case ',':
if (inString || inChar || inVerbatimString || inSingleComment || inMultiLineComment) {
break;
}
if (parameter.Count > 0) {
parameter.Push (parameter.Pop () + 1);
}
break;
case '/':
if (!insideQuote && !insideString && !insideMultiLineComment) {
if (document.GetCharAt (i) == '/') {
insideSingleLineComment = true;
}
if (document.GetCharAt (i) == '*') {
insideMultiLineComment = true;
}
if (inString || inChar || inVerbatimString) {
break;
}
if (nextCh == '/') {
i++;
inSingleComment = true;
}
if (nextCh == '*') {
inMultiLineComment = true;
}
break;
case '*':
if (insideMultiLineComment && document.GetCharAt (i) == '/') {
insideMultiLineComment = false;
if (inString || inChar || inVerbatimString || inSingleComment) {
break;
}
if (nextCh == '/') {
i++;
inMultiLineComment = false;
}
break;
case '@':
if (inString || inChar || inVerbatimString || inSingleComment || inMultiLineComment) {
break;
}
if (nextCh == '"') {
i++;
inVerbatimString = true;
}
break;
case '\n':
case '\r':
insideSingleLineComment = false;
break;
case '{':
if (!insideQuote && !insideString && !insideSingleLineComment && !insideMultiLineComment) {
bracket++;
indexStack.Push (index);
}
inSingleComment = false;
inString = false;
inChar = false;
break;
case '}':
if (!insideQuote && !insideString && !insideSingleLineComment && !insideMultiLineComment) {
bracket--;
if (indexStack.Count > 0)
index = indexStack.Pop ();
case '\\':
if (inString || inChar) {
i++;
}
break;
case '(':
if (!insideQuote && !insideString && !insideSingleLineComment && !insideMultiLineComment) {
parentheses++;
case '"':
if (inSingleComment || inMultiLineComment || inChar) {
break;
}
break;
case ')':
if (!insideQuote && !insideString && !insideSingleLineComment && !insideMultiLineComment) {
parentheses--;
if (inVerbatimString) {
if (nextCh == '"') {
i++;
break;
}
inVerbatimString = false;
break;
}
inString = !inString;
break;
case ',':
if (!insideQuote && !insideString && !insideSingleLineComment && !insideMultiLineComment && parentheses == 1 && bracket == 0) {
index++;
case '\'':
if (inSingleComment || inMultiLineComment || inString || inVerbatimString) {
break;
}
inChar = !inChar;
break;
}
i++;
} while (i <= cursor && parentheses >= 0);
Console.WriteLine (indexStack.Count >= 0 || parentheses != 1 || bracket > 0 ? -1 : index);
return indexStack.Count >= 0 || parentheses != 1 || bracket > 0 ? -1 : index;
}
if (parameter.Count == 0 || bracketStack.Count > 0) {
return -1;
}
return parameter.Pop() + 1;
}
#region Context helper methods
@ -309,6 +351,7 @@ namespace ICSharpCode.NRefactory.CSharp.Completion @@ -309,6 +351,7 @@ namespace ICSharpCode.NRefactory.CSharp.Completion
IsInString = false;
IsInChar = false;
IsFistNonWs = true;
IsInPreprocessorDirective = false;
break;
case '\\':
if (IsInString || IsInChar)
@ -340,6 +383,21 @@ namespace ICSharpCode.NRefactory.CSharp.Completion @@ -340,6 +383,21 @@ namespace ICSharpCode.NRefactory.CSharp.Completion
}
}
protected bool IsInsideCommentStringOrDirective(int offset)
{
var lexer = new MiniLexer(document.Text);
lexer.Parse(0, offset);
return
lexer.IsInSingleComment ||
lexer.IsInString ||
lexer.IsInVerbatimString ||
lexer.IsInChar ||
lexer.IsInMultiLineComment ||
lexer.IsInPreprocessorDirective;
}
protected bool IsInsideCommentStringOrDirective()
{
var text = GetMemberTextToCaret();
@ -436,13 +494,13 @@ namespace ICSharpCode.NRefactory.CSharp.Completion @@ -436,13 +494,13 @@ namespace ICSharpCode.NRefactory.CSharp.Completion
state.CurrentMember = currentMember;
state.CurrentTypeDefinition = currentType;
state.CurrentUsingScope = CSharpParsedFile.GetUsingScope (location);
state.CurrentUsingScope = CSharpUnresolvedFile.GetUsingScope (location);
if (state.CurrentMember != null) {
var node = Unit.GetNodeAt (location);
if (node == null)
return state;
var navigator = new NodeListResolveVisitorNavigator (new[] { node });
var visitor = new ResolveVisitor (state, CSharpParsedFile, navigator);
var visitor = new ResolveVisitor (state, CSharpUnresolvedFile, navigator);
Unit.AcceptVisitor (visitor, null);
try {
var newState = visitor.GetResolverStateBefore (node);
@ -597,7 +655,7 @@ namespace ICSharpCode.NRefactory.CSharp.Completion @@ -597,7 +655,7 @@ namespace ICSharpCode.NRefactory.CSharp.Completion
wrapper.Append (';');
}
protected CompilationUnit ParseStub(string continuation, bool appendSemicolon = true, string afterContinuation = null)
protected SyntaxTree ParseStub(string continuation, bool appendSemicolon = true, string afterContinuation = null)
{
var mt = GetMemberTextToCaret();
if (mt == null) {
@ -623,52 +681,29 @@ namespace ICSharpCode.NRefactory.CSharp.Completion @@ -623,52 +681,29 @@ namespace ICSharpCode.NRefactory.CSharp.Completion
if (closingBrackets > 0) {
wrapper.Append(new string('}', closingBrackets));
}
using (var stream = new System.IO.StringReader (wrapper.ToString ())) {
try {
var parser = new CSharpParser ();
var result = parser.Parse(stream, "stub.cs", memberLocation.Line - 1 - generatedLines);
return result;
} catch (Exception) {
Console.WriteLine("------");
Console.WriteLine(wrapper);
throw;
}
}
var parser = new CSharpParser ();
foreach (var sym in CompletionContextProvider.ConditionalSymbols)
parser.CompilerSettings.ConditionalSymbols.Add (sym);
parser.InitialLocation = new TextLocation(memberLocation.Line - generatedLines, 1);
var result = parser.Parse(wrapper.ToString ());
return result;
}
string cachedText = null;
// string cachedText = null;
protected virtual void Reset ()
{
cachedText = null;
// cachedText = null;
}
protected Tuple<string, TextLocation> GetMemberTextToCaret()
{
int startOffset;
if (currentMember != null && currentType != null && currentType.Kind != TypeKind.Enum) {
startOffset = document.GetOffset(currentMember.Region.Begin);
} else if (currentType != null) {
startOffset = document.GetOffset(currentType.Region.Begin);
} else {
startOffset = 0;
}
while (startOffset > 0) {
char ch = document.GetCharAt(startOffset - 1);
if (ch != ' ' && ch != '\t') {
break;
}
--startOffset;
}
if (cachedText == null)
cachedText = document.GetText (startOffset, offset - startOffset);
return Tuple.Create (cachedText, document.GetLocation (startOffset));
return CompletionContextProvider.GetMemberTextToCaret(offset, currentType, currentMember);
}
protected ExpressionResult GetInvocationBeforeCursor(bool afterBracket)
{
CompilationUnit baseUnit;
SyntaxTree baseUnit;
baseUnit = ParseStub("a", false);
var section = baseUnit.GetNodeAt<AttributeSection>(location.Line, location.Column - 2);
@ -723,10 +758,10 @@ namespace ICSharpCode.NRefactory.CSharp.Completion @@ -723,10 +758,10 @@ namespace ICSharpCode.NRefactory.CSharp.Completion
public class ExpressionResult
{
public AstNode Node { get; private set; }
public CompilationUnit Unit { get; private set; }
public SyntaxTree Unit { get; private set; }
public ExpressionResult (AstNode item2, CompilationUnit item3)
public ExpressionResult (AstNode item2, SyntaxTree item3)
{
this.Node = item2;
this.Unit = item3;
@ -740,10 +775,10 @@ namespace ICSharpCode.NRefactory.CSharp.Completion @@ -740,10 +775,10 @@ namespace ICSharpCode.NRefactory.CSharp.Completion
protected Tuple<ResolveResult, CSharpResolver> ResolveExpression (ExpressionResult tuple)
{
return ResolveExpression (tuple.Node, tuple.Unit);
return ResolveExpression (tuple.Node);
}
protected Tuple<ResolveResult, CSharpResolver> ResolveExpression(AstNode expr, CompilationUnit unit)
protected Tuple<ResolveResult, CSharpResolver> ResolveExpression(AstNode expr)
{
if (expr == null) {
return null;
@ -757,12 +792,13 @@ namespace ICSharpCode.NRefactory.CSharp.Completion @@ -757,12 +792,13 @@ namespace ICSharpCode.NRefactory.CSharp.Completion
resolveNode = expr;
}
try {
var ctx = CSharpParsedFile.GetResolver(Compilation, location);
var root = expr.AncestorsAndSelf.FirstOrDefault(n => n is EntityDeclaration || n is CompilationUnit);
var root = expr.AncestorsAndSelf.FirstOrDefault(n => n is EntityDeclaration || n is SyntaxTree);
if (root == null) {
return null;
}
var csResolver = new CSharpAstResolver (ctx, root, CSharpParsedFile);
if (root is Accessor)
root = root.Parent;
var csResolver = CompletionContextProvider.GetResolver (GetState(), root);
var result = csResolver.Resolve(resolveNode);
var state = csResolver.GetResolverStateBefore(resolveNode);
return Tuple.Create(result, state);
@ -773,128 +809,5 @@ namespace ICSharpCode.NRefactory.CSharp.Completion @@ -773,128 +809,5 @@ namespace ICSharpCode.NRefactory.CSharp.Completion
}
#endregion
class DefaultMemberProvider : IMemberProvider
{
CSharpCompletionEngineBase engine;
public DefaultMemberProvider (CSharpCompletionEngineBase engine)
{
this.engine = engine;
}
public void GetCurrentMembers (int offset, out IUnresolvedTypeDefinition currentType, out IUnresolvedMember currentMember)
{
//var document = engine.document;
var location = engine.location;
currentType = null;
foreach (var type in engine.CSharpParsedFile.TopLevelTypeDefinitions) {
if (type.Region.Begin < location)
currentType = type;
}
currentType = FindInnerType (currentType, location);
// location is beyond last reported end region, now we need to check, if the end region changed
if (currentType != null && currentType.Region.End < location) {
if (!IsInsideType (currentType, location))
currentType = null;
}
currentMember = null;
if (currentType != null) {
foreach (var member in currentType.Members) {
if (member.Region.Begin < location && (currentMember == null || currentMember.Region.Begin < member.Region.Begin))
currentMember = member;
}
}
// location is beyond last reported end region, now we need to check, if the end region changed
// NOTE: Enums are a special case, there the "last" field needs to be treated as current member
if (currentMember != null && currentMember.Region.End < location && currentType.Kind != TypeKind.Enum) {
if (!IsInsideType (currentMember, location))
currentMember = null;
}
var stack = GetBracketStack (engine.GetMemberTextToCaret ().Item1);
if (stack.Count == 0)
currentMember = null;
}
IUnresolvedTypeDefinition FindInnerType (IUnresolvedTypeDefinition parent, TextLocation location)
{
if (parent == null)
return null;
var currentType = parent;
foreach (var type in parent.NestedTypes) {
if (type.Region.Begin < location && location < type.Region.End)
currentType = FindInnerType (type, location);
}
return currentType;
}
bool IsInsideType (IUnresolvedEntity currentType, TextLocation location)
{
var document = engine.document;
int startOffset = document.GetOffset (currentType.Region.Begin);
int endOffset = document.GetOffset (location);
//bool foundEndBracket = false;
var bracketStack = new Stack<char> ();
bool isInString = false, isInChar = false;
bool isInLineComment = false, isInBlockComment = false;
for (int i = startOffset; i < endOffset; i++) {
char ch = document.GetCharAt (i);
switch (ch) {
case '(':
case '[':
case '{':
if (!isInString && !isInChar && !isInLineComment && !isInBlockComment)
bracketStack.Push (ch);
break;
case ')':
case ']':
case '}':
if (!isInString && !isInChar && !isInLineComment && !isInBlockComment)
if (bracketStack.Count > 0)
bracketStack.Pop ();
break;
case '\r':
case '\n':
isInLineComment = false;
break;
case '/':
if (isInBlockComment) {
if (i > 0 && document.GetCharAt (i - 1) == '*')
isInBlockComment = false;
} else if (!isInString && !isInChar && i + 1 < document.TextLength) {
char nextChar = document.GetCharAt (i + 1);
if (nextChar == '/')
isInLineComment = true;
if (!isInLineComment && nextChar == '*')
isInBlockComment = true;
}
break;
case '"':
if (!(isInChar || isInLineComment || isInBlockComment))
isInString = !isInString;
break;
case '\'':
if (!(isInString || isInLineComment || isInBlockComment))
isInChar = !isInChar;
break;
default :
break;
}
}
return bracketStack.Any (t => t == '{');
}
}
}
}

184
ICSharpCode.NRefactory.CSharp/Completion/CSharpParameterCompletionEngine.cs

@ -1,4 +1,4 @@ @@ -1,4 +1,4 @@
//
//
// CSharpParameterCompletionEngine.cs
//
// Author:
@ -39,7 +39,7 @@ namespace ICSharpCode.NRefactory.CSharp.Completion @@ -39,7 +39,7 @@ namespace ICSharpCode.NRefactory.CSharp.Completion
{
internal IParameterCompletionDataFactory factory;
public CSharpParameterCompletionEngine(IDocument document, IParameterCompletionDataFactory factory, IProjectContent content, CSharpTypeResolveContext ctx, CompilationUnit unit, CSharpParsedFile parsedFile) : base (content, ctx, unit, parsedFile)
public CSharpParameterCompletionEngine(IDocument document, ICompletionContextProvider completionContextProvider, IParameterCompletionDataFactory factory, IProjectContent content, CSharpTypeResolveContext ctx) : base (content, completionContextProvider, ctx)
{
if (document == null) {
throw new ArgumentNullException("document");
@ -53,13 +53,10 @@ namespace ICSharpCode.NRefactory.CSharp.Completion @@ -53,13 +53,10 @@ namespace ICSharpCode.NRefactory.CSharp.Completion
public ExpressionResult GetIndexerBeforeCursor()
{
CompilationUnit baseUnit;
SyntaxTree baseUnit;
if (currentMember == null && currentType == null) {
return null;
}
if (Unit == null) {
return null;
}
baseUnit = ParseStub("x] = a[1");
//var memberLocation = currentMember != null ? currentMember.Region.Begin : currentType.Region.Begin;
@ -76,13 +73,10 @@ namespace ICSharpCode.NRefactory.CSharp.Completion @@ -76,13 +73,10 @@ namespace ICSharpCode.NRefactory.CSharp.Completion
public ExpressionResult GetConstructorInitializerBeforeCursor()
{
CompilationUnit baseUnit;
SyntaxTree baseUnit;
if (currentMember == null && currentType == null) {
return null;
}
if (Unit == null) {
return null;
}
baseUnit = ParseStub("a) {}", false);
var expr = baseUnit.GetNodeAt <ConstructorInitializer>(location);
@ -94,13 +88,10 @@ namespace ICSharpCode.NRefactory.CSharp.Completion @@ -94,13 +88,10 @@ namespace ICSharpCode.NRefactory.CSharp.Completion
public ExpressionResult GetTypeBeforeCursor()
{
CompilationUnit baseUnit;
SyntaxTree baseUnit;
if (currentMember == null && currentType == null) {
return null;
}
if (Unit == null) {
return null;
}
baseUnit = ParseStub("x> a");
//var memberLocation = currentMember != null ? currentMember.Region.Begin : currentType.Region.Begin;
@ -113,25 +104,24 @@ namespace ICSharpCode.NRefactory.CSharp.Completion @@ -113,25 +104,24 @@ namespace ICSharpCode.NRefactory.CSharp.Completion
IEnumerable<IMethod> CollectMethods(AstNode resolvedNode, MethodGroupResolveResult resolveResult)
{
// var lookup = new MemberLookup (ctx.CurrentTypeDefinition, Compilation.MainAssembly);
var lookup = new MemberLookup(ctx.CurrentTypeDefinition, Compilation.MainAssembly);
bool onlyStatic = false;
if (resolvedNode is IdentifierExpression && currentMember != null && currentMember.IsStatic) {
if (resolvedNode is IdentifierExpression && currentMember != null && currentMember.IsStatic || resolveResult.TargetResult is TypeResolveResult) {
onlyStatic = true;
}
foreach (var method in resolveResult.Methods) {
if (method.IsConstructor) {
continue;
}
// if (!lookup.IsAccessible (member, true))
// continue;
if (!lookup.IsAccessible (method, true))
continue;
if (onlyStatic && !method.IsStatic) {
continue;
}
yield return method;
}
foreach (var extMethods in resolveResult.GetExtensionMethods ()) {
foreach (var extMethods in resolveResult.GetEligibleExtensionMethods (true)) {
foreach (var method in extMethods) {
yield return method;
}
@ -172,7 +162,7 @@ namespace ICSharpCode.NRefactory.CSharp.Completion @@ -172,7 +162,7 @@ namespace ICSharpCode.NRefactory.CSharp.Completion
}
}
if (invoke.Node is ObjectCreateExpression) {
var createType = ResolveExpression(((ObjectCreateExpression)invoke.Node).Type, invoke.Unit);
var createType = ResolveExpression(((ObjectCreateExpression)invoke.Node).Type);
if (createType.Item1.Type.Kind == TypeKind.Unknown)
return null;
return factory.CreateConstructorProvider(document.GetOffset(invoke.Node.StartLocation), createType.Item1.Type);
@ -235,7 +225,7 @@ namespace ICSharpCode.NRefactory.CSharp.Completion @@ -235,7 +225,7 @@ namespace ICSharpCode.NRefactory.CSharp.Completion
if (GetCurrentParameterIndex(document.GetOffset(invoke.Node.StartLocation), offset) < 0)
return null;
if (invoke.Node is ObjectCreateExpression) {
var createType = ResolveExpression(((ObjectCreateExpression)invoke.Node).Type, invoke.Unit);
var createType = ResolveExpression(((ObjectCreateExpression)invoke.Node).Type);
return factory.CreateConstructorProvider(document.GetOffset(invoke.Node.StartLocation), createType.Item1.Type);
}
@ -317,17 +307,12 @@ namespace ICSharpCode.NRefactory.CSharp.Completion @@ -317,17 +307,12 @@ namespace ICSharpCode.NRefactory.CSharp.Completion
List<string> GetUsedNamespaces()
{
var scope = CSharpParsedFile.GetUsingScope(location);
var scope = ctx.CurrentUsingScope;
var result = new List<string>();
var resolver = new CSharpResolver(ctx);
while (scope != null) {
result.Add(scope.NamespaceName);
result.Add(scope.Namespace.FullName);
foreach (var u in scope.Usings) {
var ns = u.ResolveNamespace(resolver);
if (ns == null) {
continue;
}
foreach (var ns in scope.Usings) {
result.Add(ns.FullName);
}
scope = scope.Parent;
@ -335,144 +320,7 @@ namespace ICSharpCode.NRefactory.CSharp.Completion @@ -335,144 +320,7 @@ namespace ICSharpCode.NRefactory.CSharp.Completion
return result;
}
public int GetCurrentParameterIndex(int triggerOffset, int endOffset)
{
char lastChar = document.GetCharAt(endOffset - 1);
if (lastChar == '(' || lastChar == '<') {
return 0;
}
var parameter = new Stack<int>();
var bracketStack = new Stack<Stack<int>>();
bool inSingleComment = false, inString = false, inVerbatimString = false, inChar = false, inMultiLineComment = false;
for (int i = triggerOffset; i < endOffset; i++) {
char ch = document.GetCharAt(i);
char nextCh = i + 1 < document.TextLength ? document.GetCharAt(i + 1) : '\0';
switch (ch) {
case '{':
if (inString || inChar || inVerbatimString || inSingleComment || inMultiLineComment) {
break;
}
bracketStack.Push(parameter);
parameter = new Stack<int>();
break;
case '[':
case '(':
if (inString || inChar || inVerbatimString || inSingleComment || inMultiLineComment) {
break;
}
parameter.Push(0);
break;
case '}':
if (inString || inChar || inVerbatimString || inSingleComment || inMultiLineComment) {
break;
}
if (bracketStack.Count > 0) {
parameter = bracketStack.Pop();
} else {
return -1;
}
break;
case ']':
case ')':
if (inString || inChar || inVerbatimString || inSingleComment || inMultiLineComment) {
break;
}
if (parameter.Count > 0) {
parameter.Pop();
} else {
return -1;
}
break;
case '<':
if (inString || inChar || inVerbatimString || inSingleComment || inMultiLineComment) {
break;
}
parameter.Push(0);
break;
case '>':
if (inString || inChar || inVerbatimString || inSingleComment || inMultiLineComment) {
break;
}
if (parameter.Count > 0) {
parameter.Pop();
}
break;
case ',':
if (inString || inChar || inVerbatimString || inSingleComment || inMultiLineComment) {
break;
}
if (parameter.Count > 0) {
parameter.Push(parameter.Pop() + 1);
}
break;
case '/':
if (inString || inChar || inVerbatimString) {
break;
}
if (nextCh == '/') {
i++;
inSingleComment = true;
}
if (nextCh == '*') {
inMultiLineComment = true;
}
break;
case '*':
if (inString || inChar || inVerbatimString || inSingleComment) {
break;
}
if (nextCh == '/') {
i++;
inMultiLineComment = false;
}
break;
case '@':
if (inString || inChar || inVerbatimString || inSingleComment || inMultiLineComment) {
break;
}
if (nextCh == '"') {
i++;
inVerbatimString = true;
}
break;
case '\n':
case '\r':
inSingleComment = false;
inString = false;
inChar = false;
break;
case '\\':
if (inString || inChar) {
i++;
}
break;
case '"':
if (inSingleComment || inMultiLineComment || inChar) {
break;
}
if (inVerbatimString) {
if (nextCh == '"') {
i++;
break;
}
inVerbatimString = false;
break;
}
inString = !inString;
break;
case '\'':
if (inSingleComment || inMultiLineComment || inString || inVerbatimString) {
break;
}
inChar = !inChar;
break;
}
}
if (parameter.Count == 0 || bracketStack.Count > 0) {
return -1;
}
return parameter.Pop() + 1;
}
}
}

158
ICSharpCode.NRefactory.CSharp/Completion/CompletionDataWrapper.cs

@ -28,6 +28,7 @@ using System.Collections.Generic; @@ -28,6 +28,7 @@ using System.Collections.Generic;
using ICSharpCode.NRefactory.Completion;
using ICSharpCode.NRefactory.TypeSystem;
using System.Linq;
using ICSharpCode.NRefactory.CSharp.Resolver;
namespace ICSharpCode.NRefactory.CSharp.Completion
{
@ -35,7 +36,7 @@ namespace ICSharpCode.NRefactory.CSharp.Completion @@ -35,7 +36,7 @@ namespace ICSharpCode.NRefactory.CSharp.Completion
{
CSharpCompletionEngine completion;
List<ICompletionData> result = new List<ICompletionData> ();
public List<ICompletionData> Result {
get {
return result;
@ -47,119 +48,109 @@ namespace ICSharpCode.NRefactory.CSharp.Completion @@ -47,119 +48,109 @@ namespace ICSharpCode.NRefactory.CSharp.Completion
return completion.factory;
}
}
public CompletionDataWrapper (CSharpCompletionEngine completion)
{
this.completion = completion;
}
public void Add (ICompletionData data)
{
result.Add (data);
}
public void AddCustom (string displayText, string description = null, string completionText = null)
{
result.Add (Factory.CreateLiteralCompletionData (displayText, description, completionText));
}
HashSet<string> usedNamespaces = new HashSet<string> ();
public void AddNamespace (string name)
public void AddNamespace (INamespace ns)
{
if (string.IsNullOrEmpty (name) || usedNamespaces.Contains (name))
if (usedNamespaces.Contains (ns.Name))
return;
usedNamespaces.Add (name);
result.Add (Factory.CreateNamespaceCompletionData (name));
usedNamespaces.Add (ns.Name);
result.Add (Factory.CreateNamespaceCompletionData (ns));
}
HashSet<string> usedTypes = new HashSet<string> ();
public void AddType (IType type, string shortType)
public void AddAlias(string alias)
{
if (type == null || string.IsNullOrEmpty (shortType) || usedTypes.Contains (shortType))
return;
usedTypes.Add (shortType);
result.Add (Factory.CreateTypeCompletionData (type, shortType));
result.Add (Factory.CreateLiteralCompletionData (alias));
}
public void AddType (IUnresolvedTypeDefinition type, string shortType)
HashSet<string> usedTypes = new HashSet<string> ();
public ICompletionData AddType(IType type, string shortType)
{
if (type == null || string.IsNullOrEmpty (shortType) || usedTypes.Contains (shortType))
return;
usedTypes.Add (shortType);
result.Add (Factory.CreateTypeCompletionData (type, shortType));
if (type == null || string.IsNullOrEmpty(shortType) || usedTypes.Contains(shortType))
return null;
if (type.Name == "Void" && type.Namespace == "System")
return null;
var def = type.GetDefinition ();
if (def != null && def.ParentAssembly != completion.ctx.CurrentAssembly && !def.IsBrowsable ())
return null;
usedTypes.Add(shortType);
var iCompletionData = Factory.CreateTypeCompletionData(type, shortType);
result.Add(iCompletionData);
return iCompletionData;
}
Dictionary<string, List<ICompletionData>> data = new Dictionary<string, List<ICompletionData>> ();
public void AddVariable (IVariable variable)
public ICompletionData AddVariable(IVariable variable)
{
if (data.ContainsKey (variable.Name))
return;
data [variable.Name] = new List<ICompletionData> ();
result.Add (Factory.CreateVariableCompletionData (variable));
if (data.ContainsKey(variable.Name))
return null;
data [variable.Name] = new List<ICompletionData>();
var cd = Factory.CreateVariableCompletionData(variable);
result.Add(cd);
return cd;
}
public ICompletionData AddNamedParameterVariable(IVariable variable)
{
var name = variable.Name + ":";
if (data.ContainsKey(name))
return null;
data [name] = new List<ICompletionData>();
public void AddTypeParameter (IUnresolvedTypeParameter variable)
var cd = Factory.CreateVariableCompletionData(variable);
cd.CompletionText += ":";
cd.DisplayText += ":";
result.Add(cd);
return cd;
}
public void AddTypeParameter (ITypeParameter variable)
{
if (data.ContainsKey (variable.Name))
return;
data [variable.Name] = new List<ICompletionData> ();
result.Add (Factory.CreateVariableCompletionData (variable));
}
public ICompletionData AddMember (IUnresolvedMember member)
{
var newData = Factory.CreateEntityCompletionData (member);
// newData.HideExtensionParameter = HideExtensionParameter;
string memberKey = newData.DisplayText;
if (memberKey == null)
return null;
if (member is IMember) {
newData.CompletionCategory = GetCompletionCategory (member.DeclaringTypeDefinition.Resolve (completion.ctx));
}
List<ICompletionData> existingData;
data.TryGetValue (memberKey, out existingData);
if (existingData != null) {
var a = member as IEntity;
foreach (var d in existingData) {
if (!(d is IEntityCompletionData))
continue;
var b = ((IEntityCompletionData)d).Entity;
if (a == null || b == null || a.EntityType == b.EntityType) {
d.AddOverload (newData);
return d;
}
}
if (newData != null) {
result.Add (newData);
data [memberKey].Add (newData);
}
} else {
result.Add (newData);
data [memberKey] = new List<ICompletionData> ();
data [memberKey].Add (newData);
}
return newData;
}
public ICompletionData AddMember (IMember member)
{
var newData = Factory.CreateEntityCompletionData (member);
// newData.HideExtensionParameter = HideExtensionParameter;
if (member.ParentAssembly != completion.ctx.CurrentAssembly && !member.IsBrowsable ())
return null;
string memberKey = newData.DisplayText;
if (memberKey == null)
return null;
if (member is IMember) {
newData.CompletionCategory = GetCompletionCategory (member.DeclaringTypeDefinition);
}
List<ICompletionData> existingData;
data.TryGetValue (memberKey, out existingData);
if (existingData != null) {
var a = member as IEntity;
foreach (var d in existingData) {
@ -182,7 +173,7 @@ namespace ICSharpCode.NRefactory.CSharp.Completion @@ -182,7 +173,7 @@ namespace ICSharpCode.NRefactory.CSharp.Completion
}
return newData;
}
internal CompletionCategory GetCompletionCategory (IType type)
{
if (type == null)
@ -191,7 +182,7 @@ namespace ICSharpCode.NRefactory.CSharp.Completion @@ -191,7 +182,7 @@ namespace ICSharpCode.NRefactory.CSharp.Completion
completionCategories [type] = new TypeCompletionCategory (type);
return completionCategories [type];
}
Dictionary<IType, CompletionCategory> completionCategories = new Dictionary<IType, CompletionCategory> ();
class TypeCompletionCategory : CompletionCategory
{
@ -210,15 +201,34 @@ namespace ICSharpCode.NRefactory.CSharp.Completion @@ -210,15 +201,34 @@ namespace ICSharpCode.NRefactory.CSharp.Completion
var compareCategory = other as TypeCompletionCategory;
if (compareCategory == null)
return -1;
if (Type.ReflectionName == compareCategory.Type.ReflectionName)
return 0;
if (Type.GetAllBaseTypes ().Any (t => t.ReflectionName == compareCategory.Type.ReflectionName))
return -1;
return 1;
}
}
HashSet<IType> addedEnums = new HashSet<IType> ();
public void AddEnumMembers (IType resolvedType, CSharpResolver state, string typeString)
{
if (addedEnums.Contains (resolvedType))
return;
addedEnums.Add (resolvedType);
if (typeString.Contains(".")) {
AddType(resolvedType, typeString);
}
foreach (var field in resolvedType.GetFields ()) {
if (field.IsPublic && (field.IsConst || field.IsStatic)) {
Result.Add(Factory.CreateEntityCompletionData(
field,
typeString + "." + field.Name
)
);
}
}
}
}
}

213
ICSharpCode.NRefactory.CSharp/Completion/ICompletionContextProvider.cs

@ -0,0 +1,213 @@ @@ -0,0 +1,213 @@
//
// IMemberProvider.cs
//
// Author:
// Mike Krüger <mkrueger@xamarin.com>
//
// Copyright (c) 2012 Xamarin Inc.
//
// 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 ICSharpCode.NRefactory.TypeSystem;
using ICSharpCode.NRefactory.Editor;
using ICSharpCode.NRefactory.CSharp.TypeSystem;
using System.Linq;
using ICSharpCode.NRefactory.CSharp.Resolver;
namespace ICSharpCode.NRefactory.CSharp.Completion
{
public interface ICompletionContextProvider
{
IList<string> ConditionalSymbols {
get;
}
void GetCurrentMembers (int offset, out IUnresolvedTypeDefinition currentType, out IUnresolvedMember currentMember);
Tuple<string, TextLocation> GetMemberTextToCaret(int caretOffset, IUnresolvedTypeDefinition currentType, IUnresolvedMember currentMember);
CSharpAstResolver GetResolver (CSharpResolver resolver, AstNode rootNode);
}
public class DefaultCompletionContextProvider : ICompletionContextProvider
{
readonly IDocument document;
readonly CSharpUnresolvedFile unresolvedFile;
readonly List<string> symbols = new List<string> ();
public IList<string> ConditionalSymbols {
get {
return symbols;
}
}
public DefaultCompletionContextProvider (IDocument document, CSharpUnresolvedFile unresolvedFile)
{
if (document == null)
throw new ArgumentNullException("document");
if (unresolvedFile == null)
throw new ArgumentNullException("unresolvedFile");
this.document = document;
this.unresolvedFile = unresolvedFile;
}
public void AddSymbol (string sym)
{
symbols.Add (sym);
}
public void GetCurrentMembers(int offset, out IUnresolvedTypeDefinition currentType, out IUnresolvedMember currentMember)
{
//var document = engine.document;
var location = document.GetLocation(offset);
currentType = null;
foreach (var type in unresolvedFile.TopLevelTypeDefinitions) {
if (type.Region.Begin < location)
currentType = type;
}
currentType = FindInnerType (currentType, location);
// location is beyond last reported end region, now we need to check, if the end region changed
if (currentType != null && currentType.Region.End < location) {
if (!IsInsideType (currentType, location))
currentType = null;
}
currentMember = null;
if (currentType != null) {
foreach (var member in currentType.Members) {
if (member.Region.Begin < location && (currentMember == null || currentMember.Region.Begin < member.Region.Begin))
currentMember = member;
}
}
// location is beyond last reported end region, now we need to check, if the end region changed
// NOTE: Enums are a special case, there the "last" field needs to be treated as current member
if (currentMember != null && currentMember.Region.End < location && currentType.Kind != TypeKind.Enum) {
if (!IsInsideType (currentMember, location))
currentMember = null;
}/*
var stack = GetBracketStack (engine.GetMemberTextToCaret ().Item1);
if (stack.Count == 0)
currentMember = null;*/
}
IUnresolvedTypeDefinition FindInnerType (IUnresolvedTypeDefinition parent, TextLocation location)
{
if (parent == null)
return null;
var currentType = parent;
foreach (var type in parent.NestedTypes) {
if (type.Region.Begin < location && location < type.Region.End)
currentType = FindInnerType (type, location);
}
return currentType;
}
bool IsInsideType (IUnresolvedEntity currentType, TextLocation location)
{
int startOffset = document.GetOffset (currentType.Region.Begin);
int endOffset = document.GetOffset (location);
//bool foundEndBracket = false;
var bracketStack = new Stack<char> ();
bool isInString = false, isInChar = false;
bool isInLineComment = false, isInBlockComment = false;
for (int i = startOffset; i < endOffset; i++) {
char ch = document.GetCharAt (i);
switch (ch) {
case '(':
case '[':
case '{':
if (!isInString && !isInChar && !isInLineComment && !isInBlockComment)
bracketStack.Push (ch);
break;
case ')':
case ']':
case '}':
if (!isInString && !isInChar && !isInLineComment && !isInBlockComment)
if (bracketStack.Count > 0)
bracketStack.Pop ();
break;
case '\r':
case '\n':
isInLineComment = false;
break;
case '/':
if (isInBlockComment) {
if (i > 0 && document.GetCharAt (i - 1) == '*')
isInBlockComment = false;
} else if (!isInString && !isInChar && i + 1 < document.TextLength) {
char nextChar = document.GetCharAt (i + 1);
if (nextChar == '/')
isInLineComment = true;
if (!isInLineComment && nextChar == '*')
isInBlockComment = true;
}
break;
case '"':
if (!(isInChar || isInLineComment || isInBlockComment))
isInString = !isInString;
break;
case '\'':
if (!(isInString || isInLineComment || isInBlockComment))
isInChar = !isInChar;
break;
default :
break;
}
}
return bracketStack.Any (t => t == '{');
}
public Tuple<string, TextLocation> GetMemberTextToCaret(int caretOffset, IUnresolvedTypeDefinition currentType, IUnresolvedMember currentMember)
{
int startOffset;
if (currentMember != null && currentType != null && currentType.Kind != TypeKind.Enum) {
startOffset = document.GetOffset(currentMember.Region.Begin);
} else if (currentType != null) {
startOffset = document.GetOffset(currentType.Region.Begin);
} else {
startOffset = 0;
}
while (startOffset > 0) {
char ch = document.GetCharAt(startOffset - 1);
if (ch != ' ' && ch != '\t') {
break;
}
--startOffset;
}
return Tuple.Create (document.GetText (startOffset, caretOffset - startOffset), document.GetLocation (startOffset));
}
public CSharpAstResolver GetResolver (CSharpResolver resolver, AstNode rootNode)
{
return new CSharpAstResolver (resolver, rootNode, unresolvedFile);
}
}
}

9
ICSharpCode.NRefactory.CSharp/Completion/ICompletionDataFactory.cs

@ -32,14 +32,11 @@ namespace ICSharpCode.NRefactory.CSharp.Completion @@ -32,14 +32,11 @@ namespace ICSharpCode.NRefactory.CSharp.Completion
{
public interface ICompletionDataFactory
{
ICompletionData CreateEntityCompletionData (IUnresolvedEntity entity);
ICompletionData CreateEntityCompletionData (IUnresolvedEntity entity, string text);
ICompletionData CreateEntityCompletionData (IEntity entity);
ICompletionData CreateEntityCompletionData (IEntity entity, string text);
ICompletionData CreateTypeCompletionData (IType type, string shortType);
ICompletionData CreateTypeCompletionData (IUnresolvedTypeDefinition type, string shortType);
/// <summary>
/// Creates a generic completion data.
/// </summary>
@ -54,11 +51,11 @@ namespace ICSharpCode.NRefactory.CSharp.Completion @@ -54,11 +51,11 @@ namespace ICSharpCode.NRefactory.CSharp.Completion
/// </param>
ICompletionData CreateLiteralCompletionData (string title, string description = null, string insertText = null);
ICompletionData CreateNamespaceCompletionData (string name);
ICompletionData CreateNamespaceCompletionData (INamespace name);
ICompletionData CreateVariableCompletionData (IVariable variable);
ICompletionData CreateVariableCompletionData (IUnresolvedTypeParameter parameter);
ICompletionData CreateVariableCompletionData (ITypeParameter parameter);
ICompletionData CreateEventCreationCompletionData (string varName, IType delegateType, IEvent evt, string parameterDefinition, IUnresolvedMember currentMember, IUnresolvedTypeDefinition currentType);

393
ICSharpCode.NRefactory.CSharp/Formatter/AstFormattingVisitor.cs

@ -1,4 +1,4 @@ @@ -1,4 +1,4 @@
//
//
// AstFormattingVisitor.cs
//
// Author:
@ -97,6 +97,11 @@ namespace ICSharpCode.NRefactory.CSharp @@ -97,6 +97,11 @@ namespace ICSharpCode.NRefactory.CSharp
get;
set;
}
public DomRegion FormattingRegion {
get;
set;
}
public AstFormattingVisitor(CSharpFormattingOptions policy, IDocument document, TextEditorOptions options = null)
{
@ -111,6 +116,22 @@ namespace ICSharpCode.NRefactory.CSharp @@ -111,6 +116,22 @@ namespace ICSharpCode.NRefactory.CSharp
this.options = options ?? TextEditorOptions.Default;
curIndent = new Indent(this.options);
}
protected override void VisitChildren (AstNode node)
{
if (!FormattingRegion.IsEmpty) {
if (node.EndLocation < FormattingRegion.Begin || node.StartLocation > FormattingRegion.End)
return;
}
AstNode next;
for (var child = node.FirstChild; child != null; child = next) {
// Store next to allow the loop to continue
// if the visitor removes/replaces child.
next = child.NextSibling;
child.AcceptVisitor (this);
}
}
/// <summary>
/// Applies the changes to the input document.
@ -152,10 +173,10 @@ namespace ICSharpCode.NRefactory.CSharp @@ -152,10 +173,10 @@ namespace ICSharpCode.NRefactory.CSharp
}
if (change.Offset < previousChange.Offset + previousChange.RemovalLength) {
#if DEBUG
Console.WriteLine ("change 1:" + change);
Console.WriteLine ("change 1:" + change + " at " + document.GetLocation (change.Offset));
Console.WriteLine (change.StackTrace);
Console.WriteLine ("change 2:" + change);
Console.WriteLine ("change 2:" + previousChange + " at " + document.GetLocation (previousChange.Offset));
Console.WriteLine (previousChange.StackTrace);
#endif
throw new InvalidOperationException ("Detected overlapping changes " + change + "/" + previousChange);
@ -178,9 +199,9 @@ namespace ICSharpCode.NRefactory.CSharp @@ -178,9 +199,9 @@ namespace ICSharpCode.NRefactory.CSharp
changes.Clear();
}
public override void VisitCompilationUnit(CompilationUnit unit)
public override void VisitSyntaxTree(SyntaxTree unit)
{
base.VisitCompilationUnit(unit);
base.VisitSyntaxTree(unit);
}
public void EnsureBlankLinesAfter(AstNode node, int blankLines)
@ -228,26 +249,32 @@ namespace ICSharpCode.NRefactory.CSharp @@ -228,26 +249,32 @@ namespace ICSharpCode.NRefactory.CSharp
for (int i = 0; i < blankLines; i++) {
sb.Append(this.options.EolMarker);
}
if (end - start == 0 && sb.Length == 0)
return;
AddChange(start, end - start, sb.ToString());
}
public override void VisitUsingDeclaration(UsingDeclaration usingDeclaration)
{
if (!(usingDeclaration.PrevSibling is UsingDeclaration || usingDeclaration.PrevSibling is UsingAliasDeclaration)) {
if (usingDeclaration.PrevSibling != null && !(usingDeclaration.PrevSibling is UsingDeclaration || usingDeclaration.PrevSibling is UsingAliasDeclaration)) {
EnsureBlankLinesBefore(usingDeclaration, policy.BlankLinesBeforeUsings);
}
if (!(usingDeclaration.NextSibling is UsingDeclaration || usingDeclaration.NextSibling is UsingAliasDeclaration)) {
} else if (!(usingDeclaration.NextSibling is UsingDeclaration || usingDeclaration.NextSibling is UsingAliasDeclaration)) {
FixIndentationForceNewLine(usingDeclaration.StartLocation);
EnsureBlankLinesAfter(usingDeclaration, policy.BlankLinesAfterUsings);
} else {
FixIndentationForceNewLine(usingDeclaration.StartLocation);
}
}
public override void VisitUsingAliasDeclaration(UsingAliasDeclaration usingDeclaration)
{
if (!(usingDeclaration.PrevSibling is UsingDeclaration || usingDeclaration.PrevSibling is UsingAliasDeclaration)) {
if (usingDeclaration.PrevSibling != null && !(usingDeclaration.PrevSibling is UsingDeclaration || usingDeclaration.PrevSibling is UsingAliasDeclaration)) {
EnsureBlankLinesBefore(usingDeclaration, policy.BlankLinesBeforeUsings);
}
if (!(usingDeclaration.NextSibling is UsingDeclaration || usingDeclaration.NextSibling is UsingAliasDeclaration)) {
} else if (!(usingDeclaration.NextSibling is UsingDeclaration || usingDeclaration.NextSibling is UsingAliasDeclaration)) {
FixIndentationForceNewLine(usingDeclaration.StartLocation);
EnsureBlankLinesAfter(usingDeclaration, policy.BlankLinesAfterUsings);
} else {
FixIndentationForceNewLine(usingDeclaration.StartLocation);
}
}
@ -445,7 +472,7 @@ namespace ICSharpCode.NRefactory.CSharp @@ -445,7 +472,7 @@ namespace ICSharpCode.NRefactory.CSharp
return i;
}
int ForceSpacesBeforeRemoveNewLines(AstNode n)
int ForceSpacesBeforeRemoveNewLines(AstNode n, bool forceSpace = true)
{
if (n == null || n.IsNull) {
return 0;
@ -459,7 +486,7 @@ namespace ICSharpCode.NRefactory.CSharp @@ -459,7 +486,7 @@ namespace ICSharpCode.NRefactory.CSharp
i--;
}
var length = System.Math.Max(0, (offset - 1) - i);
AddChange(i + 1, length, " ");
AddChange(i + 1, length, forceSpace ? " " : "");
return i;
}
@ -470,12 +497,22 @@ namespace ICSharpCode.NRefactory.CSharp @@ -470,12 +497,22 @@ namespace ICSharpCode.NRefactory.CSharp
switch (policy.PropertyFormatting) {
case PropertyFormatting.AllowOneLine:
bool isSimple = IsSimpleAccessor(propertyDeclaration.Getter) && IsSimpleAccessor(propertyDeclaration.Setter);
if (!isSimple || propertyDeclaration.LBraceToken.StartLocation.Line != propertyDeclaration.RBraceToken.StartLocation.Line) {
int accessorLine = propertyDeclaration.RBraceToken.StartLocation.Line;
if (!propertyDeclaration.Getter.IsNull && propertyDeclaration.Setter.IsNull) {
accessorLine = propertyDeclaration.Getter.StartLocation.Line;
} else if (propertyDeclaration.Getter.IsNull && !propertyDeclaration.Setter.IsNull) {
accessorLine = propertyDeclaration.Setter.StartLocation.Line;
} else {
var acc = propertyDeclaration.Getter.StartLocation < propertyDeclaration.Setter.StartLocation ?
propertyDeclaration.Getter : propertyDeclaration.Setter;
accessorLine = acc.StartLocation.Line;
}
if (!isSimple || propertyDeclaration.LBraceToken.StartLocation.Line != accessorLine) {
EnforceBraceStyle(policy.PropertyBraceStyle, propertyDeclaration.LBraceToken, propertyDeclaration.RBraceToken);
} else {
ForceSpacesBefore(propertyDeclaration.Getter, true);
ForceSpacesBefore(propertyDeclaration.Setter, true);
ForceSpacesBefore(propertyDeclaration.RBraceToken, true);
ForceSpacesBeforeRemoveNewLines(propertyDeclaration.RBraceToken, true);
oneLine = true;
}
break;
@ -574,11 +611,9 @@ namespace ICSharpCode.NRefactory.CSharp @@ -574,11 +611,9 @@ namespace ICSharpCode.NRefactory.CSharp
{
ForceSpacesBefore(indexerDeclaration.LBracketToken, policy.SpaceBeforeIndexerDeclarationBracket);
ForceSpacesAfter(indexerDeclaration.LBracketToken, policy.SpaceWithinIndexerDeclarationBracket);
ForceSpacesBefore(indexerDeclaration.RBracketToken, policy.SpaceWithinIndexerDeclarationBracket);
FormatCommas(indexerDeclaration, policy.SpaceBeforeIndexerDeclarationParameterComma, policy.SpaceAfterIndexerDeclarationParameterComma);
FormatParameters(indexerDeclaration);
FormatAttributedNode(indexerDeclaration);
EnforceBraceStyle(policy.PropertyBraceStyle, indexerDeclaration.LBraceToken, indexerDeclaration.RBraceToken);
if (policy.IndentPropertyBody) {
@ -785,7 +820,120 @@ namespace ICSharpCode.NRefactory.CSharp @@ -785,7 +820,120 @@ namespace ICSharpCode.NRefactory.CSharp
FixIndentationForceNewLine(child.StartLocation);
}
}
void FormatParameters(AstNode node)
{
Wrapping methodCallArgumentWrapping;
bool newLineAferMethodCallOpenParentheses;
bool methodClosingParenthesesOnNewLine;
bool spaceWithinMethodCallParentheses;
bool spaceAfterMethodCallParameterComma;
bool spaceBeforeMethodCallParameterComma;
CSharpTokenNode rParToken;
AstNodeCollection<ParameterDeclaration> parameters;
var constructorDeclaration = node as ConstructorDeclaration;
if (constructorDeclaration != null) {
methodCallArgumentWrapping = policy.MethodDeclarationParameterWrapping;
newLineAferMethodCallOpenParentheses = policy.NewLineAferMethodDeclarationOpenParentheses;
methodClosingParenthesesOnNewLine = policy.MethodDeclarationClosingParenthesesOnNewLine;
spaceWithinMethodCallParentheses = policy.SpaceWithinConstructorDeclarationParentheses;
spaceAfterMethodCallParameterComma = policy.SpaceAfterConstructorDeclarationParameterComma;
spaceBeforeMethodCallParameterComma = policy.SpaceBeforeConstructorDeclarationParameterComma;
rParToken = constructorDeclaration.RParToken;
parameters = constructorDeclaration.Parameters;
} else if (node is IndexerDeclaration) {
var indexer = (IndexerDeclaration)node;
methodCallArgumentWrapping = policy.IndexerDeclarationParameterWrapping;
newLineAferMethodCallOpenParentheses = policy.NewLineAferIndexerDeclarationOpenBracket;
methodClosingParenthesesOnNewLine = policy.IndexerDeclarationClosingBracketOnNewLine;
spaceWithinMethodCallParentheses = policy.SpaceWithinIndexerDeclarationBracket;
spaceAfterMethodCallParameterComma = policy.SpaceAfterIndexerDeclarationParameterComma;
spaceBeforeMethodCallParameterComma = policy.SpaceBeforeIndexerDeclarationParameterComma;
rParToken = indexer.RBracketToken;
parameters = indexer.Parameters;
} else if (node is OperatorDeclaration) {
var op = (OperatorDeclaration)node;
methodCallArgumentWrapping = policy.MethodDeclarationParameterWrapping;
newLineAferMethodCallOpenParentheses = policy.NewLineAferMethodDeclarationOpenParentheses;
methodClosingParenthesesOnNewLine = policy.MethodDeclarationClosingParenthesesOnNewLine;
spaceWithinMethodCallParentheses = policy.SpaceWithinMethodDeclarationParentheses;
spaceAfterMethodCallParameterComma = policy.SpaceAfterMethodDeclarationParameterComma;
spaceBeforeMethodCallParameterComma = policy.SpaceBeforeMethodDeclarationParameterComma;
rParToken = op.RParToken;
parameters = op.Parameters;
} else {
var methodDeclaration = node as MethodDeclaration;
methodCallArgumentWrapping = policy.MethodDeclarationParameterWrapping;
newLineAferMethodCallOpenParentheses = policy.NewLineAferMethodDeclarationOpenParentheses;
methodClosingParenthesesOnNewLine = policy.MethodDeclarationClosingParenthesesOnNewLine;
spaceWithinMethodCallParentheses = policy.SpaceWithinMethodDeclarationParentheses;
spaceAfterMethodCallParameterComma = policy.SpaceAfterMethodDeclarationParameterComma;
spaceBeforeMethodCallParameterComma = policy.SpaceBeforeMethodDeclarationParameterComma;
rParToken = methodDeclaration.RParToken;
parameters = methodDeclaration.Parameters;
}
if (FormattingMode == ICSharpCode.NRefactory.CSharp.FormattingMode.OnTheFly)
methodCallArgumentWrapping = Wrapping.DoNotChange;
bool wrapMethodCall = DoWrap(methodCallArgumentWrapping, rParToken, parameters.Count);
if (wrapMethodCall && parameters.Any()) {
if (newLineAferMethodCallOpenParentheses) {
curIndent.Push(IndentType.Continuation);
foreach (var arg in parameters) {
FixStatementIndentation(arg.StartLocation);
}
curIndent.Pop();
} else {
int extraSpaces = parameters.First().StartLocation.Column - 1 - curIndent.IndentString.Length;
curIndent.ExtraSpaces += extraSpaces;
foreach (var arg in parameters.Skip(1)) {
FixStatementIndentation(arg.StartLocation);
}
curIndent.ExtraSpaces -= extraSpaces;
}
if (!rParToken.IsNull) {
if (methodClosingParenthesesOnNewLine) {
FixStatementIndentation(rParToken.StartLocation);
} else {
ForceSpacesBeforeRemoveNewLines(rParToken, spaceWithinMethodCallParentheses);
}
}
} else {
foreach (var arg in parameters) {
if (arg.PrevSibling != null) {
if (methodCallArgumentWrapping == Wrapping.DoNotWrap) {
ForceSpacesBeforeRemoveNewLines(arg, spaceAfterMethodCallParameterComma && arg.PrevSibling.Role == Roles.Comma);
} else {
ForceSpacesBefore(arg, spaceAfterMethodCallParameterComma && arg.PrevSibling.Role == Roles.Comma);
}
}
arg.AcceptVisitor(this);
}
if (!rParToken.IsNull) {
if (methodCallArgumentWrapping == Wrapping.DoNotWrap) {
ForceSpacesBeforeRemoveNewLines(rParToken, spaceWithinMethodCallParentheses);
} else {
bool sameLine = rParToken.GetPrevNode().StartLocation.Line == rParToken.StartLocation.Line;
if (sameLine) {
ForceSpacesBeforeRemoveNewLines(rParToken, spaceWithinMethodCallParentheses);
} else {
FixStatementIndentation(rParToken.StartLocation);
}
}
}
}
if (!rParToken.IsNull) {
foreach (CSharpTokenNode comma in rParToken.Parent.Children.Where(n => n.Role == Roles.Comma)) {
ForceSpacesBefore(comma, spaceBeforeMethodCallParameterComma);
}
}
}
public override void VisitMethodDeclaration(MethodDeclaration methodDeclaration)
{
FormatAttributedNode(methodDeclaration);
@ -793,12 +941,11 @@ namespace ICSharpCode.NRefactory.CSharp @@ -793,12 +941,11 @@ namespace ICSharpCode.NRefactory.CSharp
ForceSpacesBefore(methodDeclaration.LParToken, policy.SpaceBeforeMethodDeclarationParentheses);
if (methodDeclaration.Parameters.Any()) {
ForceSpacesAfter(methodDeclaration.LParToken, policy.SpaceWithinMethodDeclarationParentheses);
ForceSpacesBefore(methodDeclaration.RParToken, policy.SpaceWithinMethodDeclarationParentheses);
FormatParameters(methodDeclaration);
} else {
ForceSpacesAfter(methodDeclaration.LParToken, policy.SpaceBetweenEmptyMethodDeclarationParentheses);
ForceSpacesBefore(methodDeclaration.RParToken, policy.SpaceBetweenEmptyMethodDeclarationParentheses);
}
FormatCommas(methodDeclaration, policy.SpaceBeforeMethodDeclarationParameterComma, policy.SpaceAfterMethodDeclarationParameterComma);
if (!methodDeclaration.Body.IsNull) {
EnforceBraceStyle(policy.MethodBraceStyle, methodDeclaration.Body.LBraceToken, methodDeclaration.Body.RBraceToken);
@ -816,12 +963,11 @@ namespace ICSharpCode.NRefactory.CSharp @@ -816,12 +963,11 @@ namespace ICSharpCode.NRefactory.CSharp
ForceSpacesBefore(operatorDeclaration.LParToken, policy.SpaceBeforeMethodDeclarationParentheses);
if (operatorDeclaration.Parameters.Any()) {
ForceSpacesAfter(operatorDeclaration.LParToken, policy.SpaceWithinMethodDeclarationParentheses);
ForceSpacesBefore(operatorDeclaration.RParToken, policy.SpaceWithinMethodDeclarationParentheses);
FormatParameters(operatorDeclaration);
} else {
ForceSpacesAfter(operatorDeclaration.LParToken, policy.SpaceBetweenEmptyMethodDeclarationParentheses);
ForceSpacesBefore(operatorDeclaration.RParToken, policy.SpaceBetweenEmptyMethodDeclarationParentheses);
}
FormatCommas(operatorDeclaration, policy.SpaceBeforeMethodDeclarationParameterComma, policy.SpaceAfterMethodDeclarationParameterComma);
if (!operatorDeclaration.Body.IsNull) {
EnforceBraceStyle(policy.MethodBraceStyle, operatorDeclaration.Body.LBraceToken, operatorDeclaration.Body.RBraceToken);
@ -839,13 +985,12 @@ namespace ICSharpCode.NRefactory.CSharp @@ -839,13 +985,12 @@ namespace ICSharpCode.NRefactory.CSharp
ForceSpacesBefore(constructorDeclaration.LParToken, policy.SpaceBeforeConstructorDeclarationParentheses);
if (constructorDeclaration.Parameters.Any()) {
ForceSpacesAfter(constructorDeclaration.LParToken, policy.SpaceWithinConstructorDeclarationParentheses);
ForceSpacesBefore(constructorDeclaration.RParToken, policy.SpaceWithinConstructorDeclarationParentheses);
FormatParameters(constructorDeclaration);
} else {
ForceSpacesAfter(constructorDeclaration.LParToken, policy.SpaceBetweenEmptyConstructorDeclarationParentheses);
ForceSpacesBefore(constructorDeclaration.RParToken, policy.SpaceBetweenEmptyConstructorDeclarationParentheses);
}
FormatCommas(constructorDeclaration, policy.SpaceBeforeConstructorDeclarationParameterComma, policy.SpaceAfterConstructorDeclarationParameterComma);
if (!constructorDeclaration.Body.IsNull) {
EnforceBraceStyle(policy.ConstructorBraceStyle, constructorDeclaration.Body.LBraceToken, constructorDeclaration.Body.RBraceToken);
VisitBlockWithoutFixingBraces(constructorDeclaration.Body, policy.IndentMethodBody);
@ -1174,6 +1319,8 @@ namespace ICSharpCode.NRefactory.CSharp @@ -1174,6 +1319,8 @@ namespace ICSharpCode.NRefactory.CSharp
TextReplaceAction AddChange(int offset, int removedChars, string insertedText)
{
if (removedChars == 0 && string.IsNullOrEmpty (insertedText))
return null;
var action = new TextReplaceAction (offset, removedChars, insertedText);
changes.Add(action);
return action;
@ -1283,11 +1430,14 @@ namespace ICSharpCode.NRefactory.CSharp @@ -1283,11 +1430,14 @@ namespace ICSharpCode.NRefactory.CSharp
}
if (!ifElseStatement.FalseStatement.IsNull) {
PlaceOnNewLine(policy.PlaceElseOnNewLine || !(ifElseStatement.TrueStatement is BlockStatement) && policy.IfElseBraceForcement != BraceForcement.AddBraces, ifElseStatement.ElseToken);
var placeElseOnNewLine = policy.ElseNewLinePlacement;
if (!(ifElseStatement.TrueStatement is BlockStatement) && policy.IfElseBraceForcement != BraceForcement.AddBraces)
placeElseOnNewLine = NewLinePlacement.NewLine;
PlaceOnNewLine(placeElseOnNewLine, ifElseStatement.ElseToken);
var forcement = policy.IfElseBraceForcement;
if (ifElseStatement.FalseStatement is IfElseStatement) {
forcement = BraceForcement.DoNotChange;
PlaceOnNewLine(policy.PlaceElseIfOnNewLine, ((IfElseStatement)ifElseStatement.FalseStatement).IfToken);
PlaceOnNewLine(policy.ElseIfNewLinePlacement, ((IfElseStatement)ifElseStatement.FalseStatement).IfToken);
}
FixEmbeddedStatment(policy.StatementBraceStyle, forcement, ifElseStatement.ElseToken, policy.AllowIfBlockInline, ifElseStatement.FalseStatement, ifElseStatement.FalseStatement is IfElseStatement);
}
@ -1378,7 +1528,7 @@ namespace ICSharpCode.NRefactory.CSharp @@ -1378,7 +1528,7 @@ namespace ICSharpCode.NRefactory.CSharp
}
foreach (CatchClause clause in tryCatchStatement.CatchClauses) {
PlaceOnNewLine(policy.PlaceCatchOnNewLine, clause.CatchToken);
PlaceOnNewLine(policy.CatchNewLinePlacement, clause.CatchToken);
if (!clause.LParToken.IsNull) {
ForceSpacesBefore(clause.LParToken, policy.SpaceBeforeCatchParentheses);
@ -1389,7 +1539,7 @@ namespace ICSharpCode.NRefactory.CSharp @@ -1389,7 +1539,7 @@ namespace ICSharpCode.NRefactory.CSharp
}
if (!tryCatchStatement.FinallyBlock.IsNull) {
PlaceOnNewLine(policy.PlaceFinallyOnNewLine, tryCatchStatement.FinallyToken);
PlaceOnNewLine(policy.FinallyNewLinePlacement, tryCatchStatement.FinallyToken);
FixEmbeddedStatment(policy.StatementBraceStyle, BraceForcement.DoNotChange, tryCatchStatement.FinallyBlock);
}
@ -1443,7 +1593,7 @@ namespace ICSharpCode.NRefactory.CSharp @@ -1443,7 +1593,7 @@ namespace ICSharpCode.NRefactory.CSharp
public override void VisitDoWhileStatement(DoWhileStatement doWhileStatement)
{
PlaceOnNewLine(policy.PlaceWhileOnNewLine, doWhileStatement.WhileToken);
PlaceOnNewLine(policy.WhileNewLinePlacement, doWhileStatement.WhileToken);
FixEmbeddedStatment(policy.StatementBraceStyle, policy.WhileBraceForcement, doWhileStatement.EmbeddedStatement);
}
@ -1495,6 +1645,8 @@ namespace ICSharpCode.NRefactory.CSharp @@ -1495,6 +1645,8 @@ namespace ICSharpCode.NRefactory.CSharp
{
if (!anonymousMethodExpression.Body.IsNull) {
EnforceBraceStyle(policy.AnonymousMethodBraceStyle, anonymousMethodExpression.Body.LBraceToken, anonymousMethodExpression.Body.RBraceToken);
VisitBlockWithoutFixingBraces(anonymousMethodExpression.Body, policy.IndentBlocks);
return;
}
base.VisitAnonymousMethodExpression(anonymousMethodExpression);
}
@ -1600,29 +1752,156 @@ namespace ICSharpCode.NRefactory.CSharp @@ -1600,29 +1752,156 @@ namespace ICSharpCode.NRefactory.CSharp
}
}
bool DoWrap (Wrapping wrapping, AstNode wrapNode, int argumentCount)
{
return wrapping == Wrapping.WrapAlways ||
options.WrapLineLength > 0 && argumentCount > 1 && wrapping == Wrapping.WrapIfTooLong && wrapNode.StartLocation.Column >= options.WrapLineLength;
}
void FormatArguments(AstNode node)
{
Wrapping methodCallArgumentWrapping;
bool newLineAferMethodCallOpenParentheses;
bool methodClosingParenthesesOnNewLine;
bool spaceWithinMethodCallParentheses;
bool spaceAfterMethodCallParameterComma;
bool spaceBeforeMethodCallParameterComma;
CSharpTokenNode rParToken;
AstNodeCollection<Expression> arguments;
var indexer = node as IndexerExpression;
if (indexer != null) {
methodCallArgumentWrapping = policy.IndexerArgumentWrapping;
newLineAferMethodCallOpenParentheses = policy.NewLineAferIndexerOpenBracket;
methodClosingParenthesesOnNewLine = policy.IndexerClosingBracketOnNewLine;
spaceWithinMethodCallParentheses = policy.SpacesWithinBrackets;
spaceAfterMethodCallParameterComma = policy.SpaceAfterBracketComma;
spaceBeforeMethodCallParameterComma = policy.SpaceBeforeBracketComma;
rParToken = indexer.RBracketToken;
arguments = indexer.Arguments;
} else if (node is ObjectCreateExpression) {
var oce = node as ObjectCreateExpression;
methodCallArgumentWrapping = policy.MethodCallArgumentWrapping;
newLineAferMethodCallOpenParentheses = policy.NewLineAferMethodCallOpenParentheses;
methodClosingParenthesesOnNewLine = policy.MethodCallClosingParenthesesOnNewLine;
spaceWithinMethodCallParentheses = policy.SpacesWithinNewParentheses;
spaceAfterMethodCallParameterComma = policy.SpaceAfterNewParameterComma;
spaceBeforeMethodCallParameterComma = policy.SpaceBeforeNewParameterComma;
rParToken = oce.RParToken;
arguments = oce.Arguments;
} else {
InvocationExpression invocationExpression = node as InvocationExpression;
methodCallArgumentWrapping = policy.MethodCallArgumentWrapping;
newLineAferMethodCallOpenParentheses = policy.NewLineAferMethodCallOpenParentheses;
methodClosingParenthesesOnNewLine = policy.MethodCallClosingParenthesesOnNewLine;
spaceWithinMethodCallParentheses = policy.SpaceWithinMethodCallParentheses;
spaceAfterMethodCallParameterComma = policy.SpaceAfterMethodCallParameterComma;
spaceBeforeMethodCallParameterComma = policy.SpaceBeforeMethodCallParameterComma;
rParToken = invocationExpression.RParToken;
arguments = invocationExpression.Arguments;
}
if (FormattingMode == ICSharpCode.NRefactory.CSharp.FormattingMode.OnTheFly)
methodCallArgumentWrapping = Wrapping.DoNotChange;
bool wrapMethodCall = DoWrap(methodCallArgumentWrapping, rParToken, arguments.Count);
if (wrapMethodCall && arguments.Any()) {
if (newLineAferMethodCallOpenParentheses) {
curIndent.Push(IndentType.Continuation);
foreach (var arg in arguments) {
FixStatementIndentation(arg.StartLocation);
}
curIndent.Pop();
} else {
int extraSpaces = arguments.First().StartLocation.Column - 1 - curIndent.IndentString.Length;
curIndent.ExtraSpaces += extraSpaces;
foreach (var arg in arguments.Skip(1)) {
FixStatementIndentation(arg.StartLocation);
}
curIndent.ExtraSpaces -= extraSpaces;
}
if (!rParToken.IsNull) {
if (methodClosingParenthesesOnNewLine) {
FixStatementIndentation(rParToken.StartLocation);
} else {
ForceSpacesBeforeRemoveNewLines(rParToken, spaceWithinMethodCallParentheses);
}
}
} else {
foreach (var arg in arguments) {
if (arg.PrevSibling != null) {
if (methodCallArgumentWrapping == Wrapping.DoNotWrap) {
ForceSpacesBeforeRemoveNewLines(arg, spaceAfterMethodCallParameterComma && arg.PrevSibling.Role == Roles.Comma);
} else {
ForceSpacesBefore(arg, spaceAfterMethodCallParameterComma && arg.PrevSibling.Role == Roles.Comma);
}
}
arg.AcceptVisitor(this);
}
if (!rParToken.IsNull) {
if (methodCallArgumentWrapping == Wrapping.DoNotWrap) {
ForceSpacesBeforeRemoveNewLines(rParToken, spaceWithinMethodCallParentheses);
} else {
bool sameLine = rParToken.GetPrevNode().EndLocation.Line == rParToken.StartLocation.Line;
if (sameLine) {
ForceSpacesBeforeRemoveNewLines(rParToken, spaceWithinMethodCallParentheses);
} else {
FixStatementIndentation(rParToken.StartLocation);
}
}
}
}
if (!rParToken.IsNull) {
foreach (CSharpTokenNode comma in rParToken.Parent.Children.Where(n => n.Role == Roles.Comma)) {
ForceSpacesBefore(comma, spaceBeforeMethodCallParameterComma);
}
}
}
public override void VisitInvocationExpression(InvocationExpression invocationExpression)
{
ForceSpacesBefore(invocationExpression.LParToken, policy.SpaceBeforeMethodCallParentheses);
if (invocationExpression.Arguments.Any()) {
ForceSpacesAfter(invocationExpression.LParToken, policy.SpaceWithinMethodCallParentheses);
ForceSpacesBefore(invocationExpression.RParToken, policy.SpaceWithinMethodCallParentheses);
} else {
ForceSpacesAfter(invocationExpression.LParToken, policy.SpaceBetweenEmptyMethodCallParentheses);
ForceSpacesBefore(invocationExpression.RParToken, policy.SpaceBetweenEmptyMethodCallParentheses);
}
FormatCommas(invocationExpression, policy.SpaceBeforeMethodCallParameterComma, policy.SpaceAfterMethodCallParameterComma);
base.VisitInvocationExpression(invocationExpression);
if (!invocationExpression.Target.IsNull)
invocationExpression.Target.AcceptVisitor(this);
if (invocationExpression.Target is MemberReferenceExpression) {
var mt = (MemberReferenceExpression)invocationExpression.Target;
if (mt.Target is InvocationExpression) {
if (DoWrap(policy.ChainedMethodCallWrapping, mt.DotToken, 2)) {
curIndent.Push(IndentType.Continuation);
FixStatementIndentation(mt.DotToken.StartLocation);
curIndent.Pop();
} else {
if (policy.ChainedMethodCallWrapping == Wrapping.DoNotWrap)
ForceSpacesBeforeRemoveNewLines(mt.DotToken, false);
}
}
}
FormatArguments(invocationExpression);
}
public override void VisitIndexerExpression(IndexerExpression indexerExpression)
{
ForceSpacesBefore(indexerExpression.LBracketToken, policy.SpacesBeforeBrackets);
ForceSpacesAfter(indexerExpression.LBracketToken, policy.SpacesWithinBrackets);
ForceSpacesBefore(indexerExpression.RBracketToken, policy.SpacesWithinBrackets);
FormatCommas(indexerExpression, policy.SpaceBeforeBracketComma, policy.SpaceAfterBracketComma);
base.VisitIndexerExpression(indexerExpression);
if (!indexerExpression.Target.IsNull)
indexerExpression.Target.AcceptVisitor(this);
FormatArguments(indexerExpression);
}
public override void VisitParenthesizedExpression(ParenthesizedExpression parenthesizedExpression)
@ -1667,23 +1946,18 @@ namespace ICSharpCode.NRefactory.CSharp @@ -1667,23 +1946,18 @@ namespace ICSharpCode.NRefactory.CSharp
ForceSpacesBefore(objectCreateExpression.LParToken, policy.SpaceBeforeNewParentheses);
if (objectCreateExpression.Arguments.Any()) {
if (!objectCreateExpression.LParToken.IsNull) {
if (!objectCreateExpression.LParToken.IsNull)
ForceSpacesAfter(objectCreateExpression.LParToken, policy.SpacesWithinNewParentheses);
}
if (!objectCreateExpression.RParToken.IsNull) {
ForceSpacesBefore(objectCreateExpression.RParToken, policy.SpacesWithinNewParentheses);
}
} else {
if (!objectCreateExpression.LParToken.IsNull) {
if (!objectCreateExpression.LParToken.IsNull)
ForceSpacesAfter(objectCreateExpression.LParToken, policy.SpacesBetweenEmptyNewParentheses);
}
if (!objectCreateExpression.RParToken.IsNull) {
ForceSpacesBefore(objectCreateExpression.RParToken, policy.SpacesBetweenEmptyNewParentheses);
}
}
FormatCommas(objectCreateExpression, policy.SpaceBeforeNewParameterComma, policy.SpaceAfterNewParameterComma);
base.VisitObjectCreateExpression(objectCreateExpression);
if (!objectCreateExpression.Type.IsNull)
objectCreateExpression.Type.AcceptVisitor(this);
FormatArguments(objectCreateExpression);
}
public override void VisitArrayCreateExpression(ArrayCreateExpression arrayObjectCreateExpression)
@ -1694,7 +1968,7 @@ namespace ICSharpCode.NRefactory.CSharp @@ -1694,7 +1968,7 @@ namespace ICSharpCode.NRefactory.CSharp
public override void VisitArrayInitializerExpression(ArrayInitializerExpression arrayInitializerExpression)
{
if (policy.ArrayInitializerWrapping == Wrapping.WrapAlways) {
if (DoWrap(policy.ArrayInitializerWrapping, arrayInitializerExpression.RBraceToken, arrayInitializerExpression.Elements.Count)) {
EnforceBraceStyle(policy.ArrayInitializerBraceStyle, arrayInitializerExpression.LBraceToken, arrayInitializerExpression.RBraceToken);
curIndent.Push(IndentType.Block);
foreach (var init in arrayInitializerExpression.Elements) {
@ -1728,6 +2002,12 @@ namespace ICSharpCode.NRefactory.CSharp @@ -1728,6 +2002,12 @@ namespace ICSharpCode.NRefactory.CSharp
base.VisitNamedArgumentExpression(namedArgumentExpression);
}
public override void VisitMemberReferenceExpression(MemberReferenceExpression memberReferenceExpression)
{
ForceSpacesAfter(memberReferenceExpression.DotToken, false);
base.VisitMemberReferenceExpression(memberReferenceExpression);
}
#endregion
void ForceSpaceBefore(int offset, bool forceSpace)
@ -1804,15 +2084,20 @@ namespace ICSharpCode.NRefactory.CSharp @@ -1804,15 +2084,20 @@ namespace ICSharpCode.NRefactory.CSharp
}
}
void PlaceOnNewLine(bool newLine, AstNode keywordNode)
void PlaceOnNewLine(NewLinePlacement newLine, AstNode keywordNode)
{
if (keywordNode == null) {
if (keywordNode == null || newLine == NewLinePlacement.DoNotCare) {
return;
}
var prev = keywordNode.GetPrevNode ();
if (prev is Comment || prev is PreProcessorDirective)
return;
int offset = document.GetOffset(keywordNode.StartLocation);
int whitespaceStart = SearchWhitespaceStart(offset);
string indentString = newLine ? this.options.EolMarker + this.curIndent.IndentString : " ";
string indentString = newLine == NewLinePlacement.NewLine ? this.options.EolMarker + this.curIndent.IndentString : " ";
AddChange(whitespaceStart, offset - whitespaceStart, indentString);
}

81
ICSharpCode.NRefactory.CSharp/Formatter/CSharpFormattingOptions.cs

@ -56,11 +56,18 @@ namespace ICSharpCode.NRefactory.CSharp @@ -56,11 +56,18 @@ namespace ICSharpCode.NRefactory.CSharp
}
public enum Wrapping {
DoNotChange,
DoNotWrap,
WrapAlways,
WrapIfTooLong
}
public enum NewLinePlacement {
DoNotCare,
NewLine,
SameLine
}
public class CSharpFormattingOptions
{
public string Name {
@ -298,27 +305,27 @@ namespace ICSharpCode.NRefactory.CSharp @@ -298,27 +305,27 @@ namespace ICSharpCode.NRefactory.CSharp
#endregion
#region NewLines
public bool PlaceElseOnNewLine { // tested
public NewLinePlacement ElseNewLinePlacement { // tested
get;
set;
}
public bool PlaceElseIfOnNewLine { // tested
public NewLinePlacement ElseIfNewLinePlacement { // tested
get;
set;
}
public bool PlaceCatchOnNewLine { // tested
public NewLinePlacement CatchNewLinePlacement { // tested
get;
set;
}
public bool PlaceFinallyOnNewLine { // tested
public NewLinePlacement FinallyNewLinePlacement { // tested
get;
set;
}
public bool PlaceWhileOnNewLine { // tested
public NewLinePlacement WhileNewLinePlacement { // tested
get;
set;
}
@ -786,6 +793,70 @@ namespace ICSharpCode.NRefactory.CSharp @@ -786,6 +793,70 @@ namespace ICSharpCode.NRefactory.CSharp
set;
}
public Wrapping ChainedMethodCallWrapping {
get;
set;
}
public Wrapping MethodCallArgumentWrapping {
get;
set;
}
public bool NewLineAferMethodCallOpenParentheses {
get;
set;
}
public bool MethodCallClosingParenthesesOnNewLine {
get;
set;
}
public Wrapping IndexerArgumentWrapping {
get;
set;
}
public bool NewLineAferIndexerOpenBracket {
get;
set;
}
public bool IndexerClosingBracketOnNewLine {
get;
set;
}
public Wrapping MethodDeclarationParameterWrapping {
get;
set;
}
public bool NewLineAferMethodDeclarationOpenParentheses {
get;
set;
}
public bool MethodDeclarationClosingParenthesesOnNewLine {
get;
set;
}
public Wrapping IndexerDeclarationParameterWrapping {
get;
set;
}
public bool NewLineAferIndexerDeclarationOpenBracket {
get;
set;
}
public bool IndexerDeclarationClosingBracketOnNewLine {
get;
set;
}
#endregion
internal CSharpFormattingOptions()

138
ICSharpCode.NRefactory.CSharp/Formatter/FormattingOptionsFactory.cs

@ -43,9 +43,9 @@ namespace ICSharpCode.NRefactory.CSharp @@ -43,9 +43,9 @@ namespace ICSharpCode.NRefactory.CSharp
/// <summary>
/// Creates mono indent style CSharpFormatting options.
/// </summary>
public static CSharpFormattingOptions CreateMono()
public static CSharpFormattingOptions CreateMono ()
{
return new CSharpFormattingOptions() {
return new CSharpFormattingOptions () {
IndentNamespaceBody = true,
IndentClassBody = true,
IndentInterfaceBody = true,
@ -81,10 +81,10 @@ namespace ICSharpCode.NRefactory.CSharp @@ -81,10 +81,10 @@ namespace ICSharpCode.NRefactory.CSharp
AllowEventRemoveBlockInline = true,
StatementBraceStyle = BraceStyle.EndOfLine,
PlaceElseOnNewLine = false,
PlaceCatchOnNewLine = false,
PlaceFinallyOnNewLine = false,
PlaceWhileOnNewLine = false,
ElseNewLinePlacement = NewLinePlacement.SameLine,
CatchNewLinePlacement = NewLinePlacement.SameLine,
FinallyNewLinePlacement = NewLinePlacement.SameLine,
WhileNewLinePlacement = NewLinePlacement.SameLine,
ArrayInitializerWrapping = Wrapping.WrapIfTooLong,
ArrayInitializerBraceStyle = BraceStyle.EndOfLine,
@ -94,7 +94,7 @@ namespace ICSharpCode.NRefactory.CSharp @@ -94,7 +94,7 @@ namespace ICSharpCode.NRefactory.CSharp
SpaceBeforeDelegateDeclarationParentheses = true,
SpaceAfterMethodCallParameterComma = true,
SpaceAfterConstructorDeclarationParameterComma = true,
SpaceBeforeNewParentheses = true,
SpacesWithinNewParentheses = false,
SpacesBetweenEmptyNewParentheses = false,
@ -152,6 +152,7 @@ namespace ICSharpCode.NRefactory.CSharp @@ -152,6 +152,7 @@ namespace ICSharpCode.NRefactory.CSharp
PropertyFormatting = PropertyFormatting.AllowOneLine,
SpaceBeforeMethodDeclarationParameterComma = false,
SpaceAfterMethodDeclarationParameterComma = true,
SpaceAfterDelegateDeclarationParameterComma = true,
SpaceBeforeFieldDeclarationComma = false,
SpaceAfterFieldDeclarationComma = true,
SpaceBeforeLocalVariableDeclarationComma = false,
@ -175,6 +176,21 @@ namespace ICSharpCode.NRefactory.CSharp @@ -175,6 +176,21 @@ namespace ICSharpCode.NRefactory.CSharp
BlankLinesBetweenMembers = 1,
KeepCommentsAtFirstColumn = true,
ChainedMethodCallWrapping = Wrapping.DoNotChange,
MethodCallArgumentWrapping = Wrapping.DoNotChange,
NewLineAferMethodCallOpenParentheses = true,
MethodCallClosingParenthesesOnNewLine = true,
IndexerArgumentWrapping = Wrapping.DoNotChange,
NewLineAferIndexerOpenBracket = false,
IndexerClosingBracketOnNewLine = false,
IfElseBraceForcement = BraceForcement.DoNotChange,
ForBraceForcement = BraceForcement.DoNotChange,
ForEachBraceForcement = BraceForcement.DoNotChange,
WhileBraceForcement = BraceForcement.DoNotChange,
UsingBraceForcement = BraceForcement.DoNotChange,
FixedBraceForcement = BraceForcement.DoNotChange
};
}
@ -183,7 +199,23 @@ namespace ICSharpCode.NRefactory.CSharp @@ -183,7 +199,23 @@ namespace ICSharpCode.NRefactory.CSharp
/// </summary>
public static CSharpFormattingOptions CreateSharpDevelop()
{
return new CSharpFormattingOptions() {
var baseOptions = CreateKRStyle();
baseOptions.IfElseBraceForcement = BraceForcement.AddBraces;
baseOptions.ForBraceForcement = BraceForcement.AddBraces;
baseOptions.ForEachBraceForcement = BraceForcement.AddBraces;
baseOptions.WhileBraceForcement = BraceForcement.AddBraces;
baseOptions.UsingBraceForcement = BraceForcement.AddBraces;
baseOptions.FixedBraceForcement = BraceForcement.AddBraces;
return baseOptions;
}
/// <summary>
/// The K&R style, so named because it was used in Kernighan and Ritchie's book The C Programming Language,
/// is commonly used in C. It is less common for C++, C#, and others.
/// </summary>
public static CSharpFormattingOptions CreateKRStyle ()
{
return new CSharpFormattingOptions () {
IndentNamespaceBody = true,
IndentClassBody = true,
IndentInterfaceBody = true,
@ -219,10 +251,10 @@ namespace ICSharpCode.NRefactory.CSharp @@ -219,10 +251,10 @@ namespace ICSharpCode.NRefactory.CSharp
AllowEventRemoveBlockInline = true,
StatementBraceStyle = BraceStyle.EndOfLine,
PlaceElseOnNewLine = false,
PlaceCatchOnNewLine = false,
PlaceFinallyOnNewLine = false,
PlaceWhileOnNewLine = false,
ElseNewLinePlacement = NewLinePlacement.SameLine,
CatchNewLinePlacement = NewLinePlacement.SameLine,
FinallyNewLinePlacement = NewLinePlacement.SameLine,
WhileNewLinePlacement = NewLinePlacement.SameLine,
ArrayInitializerWrapping = Wrapping.WrapIfTooLong,
ArrayInitializerBraceStyle = BraceStyle.EndOfLine,
@ -291,6 +323,7 @@ namespace ICSharpCode.NRefactory.CSharp @@ -291,6 +323,7 @@ namespace ICSharpCode.NRefactory.CSharp
PropertyFormatting = PropertyFormatting.AllowOneLine,
SpaceBeforeMethodDeclarationParameterComma = false,
SpaceAfterMethodDeclarationParameterComma = true,
SpaceAfterDelegateDeclarationParameterComma = true,
SpaceBeforeFieldDeclarationComma = false,
SpaceAfterFieldDeclarationComma = true,
SpaceBeforeLocalVariableDeclarationComma = false,
@ -313,6 +346,21 @@ namespace ICSharpCode.NRefactory.CSharp @@ -313,6 +346,21 @@ namespace ICSharpCode.NRefactory.CSharp
BlankLinesBetweenMembers = 1,
KeepCommentsAtFirstColumn = true,
ChainedMethodCallWrapping = Wrapping.DoNotChange,
MethodCallArgumentWrapping = Wrapping.DoNotChange,
NewLineAferMethodCallOpenParentheses = true,
MethodCallClosingParenthesesOnNewLine = true,
IndexerArgumentWrapping = Wrapping.DoNotChange,
NewLineAferIndexerOpenBracket = false,
IndexerClosingBracketOnNewLine = false,
IfElseBraceForcement = BraceForcement.DoNotChange,
ForBraceForcement = BraceForcement.DoNotChange,
ForEachBraceForcement = BraceForcement.DoNotChange,
WhileBraceForcement = BraceForcement.DoNotChange,
UsingBraceForcement = BraceForcement.DoNotChange,
FixedBraceForcement = BraceForcement.DoNotChange
};
}
@ -321,19 +369,65 @@ namespace ICSharpCode.NRefactory.CSharp @@ -321,19 +369,65 @@ namespace ICSharpCode.NRefactory.CSharp
/// </summary>
public static CSharpFormattingOptions CreateAllman()
{
var baseOptions = CreateSharpDevelop();
baseOptions.AnonymousMethodBraceStyle = BraceStyle.EndOfLine;
baseOptions.PropertyBraceStyle = BraceStyle.EndOfLine;
baseOptions.PropertyGetBraceStyle = BraceStyle.EndOfLine;
baseOptions.PropertySetBraceStyle = BraceStyle.EndOfLine;
var baseOptions = CreateKRStyle();
baseOptions.AnonymousMethodBraceStyle = BraceStyle.NextLine;
baseOptions.PropertyBraceStyle = BraceStyle.NextLine;
baseOptions.PropertyGetBraceStyle = BraceStyle.NextLine;
baseOptions.PropertySetBraceStyle = BraceStyle.NextLine;
baseOptions.EventBraceStyle = BraceStyle.EndOfLine;
baseOptions.EventAddBraceStyle = BraceStyle.EndOfLine;
baseOptions.EventRemoveBraceStyle = BraceStyle.EndOfLine;
baseOptions.StatementBraceStyle = BraceStyle.EndOfLine;
baseOptions.ArrayInitializerBraceStyle = BraceStyle.EndOfLine;
baseOptions.EventBraceStyle = BraceStyle.NextLine;
baseOptions.EventAddBraceStyle = BraceStyle.NextLine;
baseOptions.EventRemoveBraceStyle = BraceStyle.NextLine;
baseOptions.StatementBraceStyle = BraceStyle.NextLine;
baseOptions.ArrayInitializerBraceStyle = BraceStyle.NextLine;
return baseOptions;
}
/// <summary>
/// The Whitesmiths style, also called Wishart style to a lesser extent, is less common today than the previous three. It was originally used in the documentation for the first commercial C compiler, the Whitesmiths Compiler.
/// </summary>
public static CSharpFormattingOptions CreateWhitesmiths()
{
var baseOptions = CreateKRStyle();
baseOptions.NamespaceBraceStyle = BraceStyle.NextLineShifted;
baseOptions.ClassBraceStyle = BraceStyle.NextLineShifted;
baseOptions.InterfaceBraceStyle = BraceStyle.NextLineShifted;
baseOptions.StructBraceStyle = BraceStyle.NextLineShifted;
baseOptions.EnumBraceStyle = BraceStyle.NextLineShifted;
baseOptions.MethodBraceStyle = BraceStyle.NextLineShifted;
baseOptions.ConstructorBraceStyle = BraceStyle.NextLineShifted;
baseOptions.DestructorBraceStyle = BraceStyle.NextLineShifted;
baseOptions.AnonymousMethodBraceStyle = BraceStyle.NextLineShifted;
baseOptions.PropertyBraceStyle = BraceStyle.NextLineShifted;
baseOptions.PropertyGetBraceStyle = BraceStyle.NextLineShifted;
baseOptions.PropertySetBraceStyle = BraceStyle.NextLineShifted;
baseOptions.EventBraceStyle = BraceStyle.NextLineShifted;
baseOptions.EventAddBraceStyle = BraceStyle.NextLineShifted;
baseOptions.EventRemoveBraceStyle = BraceStyle.NextLineShifted;
baseOptions.StatementBraceStyle = BraceStyle.NextLineShifted;
return baseOptions;
}
/// <summary>
/// Like the Allman and Whitesmiths styles, GNU style puts braces on a line by themselves, indented by 2 spaces,
/// except when opening a function definition, where they are not indented.
/// In either case, the contained code is indented by 2 spaces from the braces.
/// Popularised by Richard Stallman, the layout may be influenced by his background of writing Lisp code.
/// In Lisp the equivalent to a block (a progn)
/// is a first class data entity and giving it its own indent level helps to emphasize that,
/// whereas in C a block is just syntax.
/// Although not directly related to indentation, GNU coding style also includes a space before the bracketed
/// list of arguments to a function.
/// </summary>
public static CSharpFormattingOptions CreateGNU()
{
var baseOptions = CreateAllman();
baseOptions.StatementBraceStyle = BraceStyle.NextLineShifted2;
return baseOptions;
}
}
}

6
ICSharpCode.NRefactory.CSharp/Formatter/GeneratedCodeSettings.cs

@ -1,4 +1,4 @@ @@ -1,4 +1,4 @@
//
//
// GeneratedCodeSettings.cs
//
// Author:
@ -177,7 +177,9 @@ namespace ICSharpCode.NRefactory.CSharp @@ -177,7 +177,9 @@ namespace ICSharpCode.NRefactory.CSharp
var cmt = new Comment ("", CommentType.SingleLine);
var cmt2 = new Comment (" " + label, CommentType.SingleLine);
var cmt3 = new Comment ("", CommentType.SingleLine);
mem.Parent.InsertChildsBefore (mem, Roles.Comment, cmt, cmt2, cmt3);
mem.Parent.InsertChildBefore (mem, cmt, Roles.Comment);
mem.Parent.InsertChildBefore (mem, cmt2, Roles.Comment);
mem.Parent.InsertChildBefore (mem, cmt3, Roles.Comment);
if (cmt.PrevSibling is EntityDeclaration)
mem.Parent.InsertChildBefore (cmt, new UnixNewLine (), Roles.NewLine);

14
ICSharpCode.NRefactory.CSharp/Formatter/Indent.cs

@ -80,7 +80,19 @@ namespace ICSharpCode.NRefactory.CSharp @@ -80,7 +80,19 @@ namespace ICSharpCode.NRefactory.CSharp
indentString = new string(' ', curIndent);
return;
}
indentString = new string('\t', curIndent / options.TabSize) + new string(' ', curIndent % options.TabSize);
indentString = new string('\t', curIndent / options.TabSize) + new string(' ', curIndent % options.TabSize) + new string (' ', ExtraSpaces);
}
int extraSpaces;
public int ExtraSpaces {
get {
return extraSpaces;
}
set {
extraSpaces = value;
Update();
}
}
string indentString;

10
ICSharpCode.NRefactory.CSharp/Formatter/TextEditorOptions.cs

@ -94,12 +94,22 @@ namespace ICSharpCode.NRefactory.CSharp @@ -94,12 +94,22 @@ namespace ICSharpCode.NRefactory.CSharp
set;
}
/// <summary>
/// Gets or sets the length of the desired line length. The formatting engine will wrap at wrap points set to Wrapping.WrapIfTooLong if the line length is too long.
/// 0 means do not wrap.
/// </summary>
public int WrapLineLength {
get;
set;
}
public TextEditorOptions()
{
TabsToSpaces = false;
TabSize = 4;
IndentSize = 4;
ContinuationIndent = 4;
WrapLineLength = 0;
EolMarker = Environment.NewLine;
}
}

159
ICSharpCode.NRefactory.CSharp/ICSharpCode.NRefactory.CSharp.csproj

@ -14,12 +14,13 @@ @@ -14,12 +14,13 @@
<TreatWarningsAsErrors>false</TreatWarningsAsErrors>
<ProductVersion>10.0.0</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<SignAssembly>true</SignAssembly>
<SignAssembly>True</SignAssembly>
<AssemblyOriginatorKeyFile>..\ICSharpCode.NRefactory.snk</AssemblyOriginatorKeyFile>
<DelaySign>False</DelaySign>
<AssemblyOriginatorKeyMode>File</AssemblyOriginatorKeyMode>
<DocumentationFile>..\ICSharpCode.NRefactory\bin\$(Configuration)\ICSharpCode.NRefactory.CSharp.xml</DocumentationFile>
<DocumentationFile>..\bin\$(Configuration)\ICSharpCode.NRefactory.CSharp.xml</DocumentationFile>
<NoWarn>1591,1587,1570</NoWarn>
<OutputPath>..\bin\$(Configuration)\</OutputPath>
</PropertyGroup>
<PropertyGroup Condition=" '$(Platform)' == 'AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
@ -29,25 +30,43 @@ @@ -29,25 +30,43 @@
<FileAlignment>4096</FileAlignment>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">
<OutputPath>..\ICSharpCode.NRefactory\bin\Debug\</OutputPath>
<Optimize>False</Optimize>
<CheckForOverflowUnderflow>False</CheckForOverflowUnderflow>
<DefineConstants>DEBUG;TRACE;FULL_AST</DefineConstants>
<DefineConstants>DEBUG;TRACE;FULL_AST;NET_4_0</DefineConstants>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)' == 'Release' ">
<OutputPath>..\ICSharpCode.NRefactory\bin\Release\</OutputPath>
<Optimize>True</Optimize>
<CheckForOverflowUnderflow>False</CheckForOverflowUnderflow>
<DefineConstants>TRACE;FULL_AST</DefineConstants>
<DefineConstants>TRACE;FULL_AST;NET_4_0</DefineConstants>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>PdbOnly</DebugType>
<DebugSymbols>false</DebugSymbols>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugType>full</DebugType>
<DebugType>Full</DebugType>
<DebugSymbols>true</DebugSymbols>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)' == 'net_4_5_Debug' ">
<Optimize>False</Optimize>
<CheckForOverflowUnderflow>False</CheckForOverflowUnderflow>
<DefineConstants>DEBUG;TRACE;FULL_AST;NET_4_0;NET_4_5</DefineConstants>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'net_4_5_Debug|AnyCPU' ">
<DebugType>Full</DebugType>
<DebugSymbols>true</DebugSymbols>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)' == 'net_4_5_Release' ">
<Optimize>True</Optimize>
<CheckForOverflowUnderflow>False</CheckForOverflowUnderflow>
<DefineConstants>TRACE;FULL_AST;NET_4_0;NET_4_5</DefineConstants>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'net_4_5_Release|AnyCPU' ">
<DebugType>PdbOnly</DebugType>
<DebugSymbols>false</DebugSymbols>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Core">
@ -70,7 +89,7 @@ @@ -70,7 +89,7 @@
<Compile Include="Ast\AstType.cs" />
<Compile Include="Ast\DocumentationReference.cs" />
<Compile Include="Ast\IdentifierExpressionBackreference.cs" />
<Compile Include="Ast\CompilationUnit.cs" />
<Compile Include="Ast\SyntaxTree.cs" />
<Compile Include="Ast\ComposedType.cs" />
<Compile Include="Ast\CSharpModifierToken.cs" />
<Compile Include="Ast\CSharpTokenNode.cs" />
@ -131,6 +150,7 @@ @@ -131,6 +150,7 @@
<Compile Include="Ast\Modifiers.cs" />
<Compile Include="Ast\NodeType.cs" />
<Compile Include="Ast\ObservableAstVisitor.cs" />
<Compile Include="Ast\old_ObservableAstVisitor.cs" />
<Compile Include="Ast\PrimitiveType.cs" />
<Compile Include="Ast\SimpleType.cs" />
<Compile Include="Ast\Statements\BlockStatement.cs" />
@ -184,6 +204,7 @@ @@ -184,6 +204,7 @@
<Compile Include="OutputVisitor\IOutputFormatter.cs" />
<Compile Include="OutputVisitor\CSharpOutputVisitor.cs" />
<Compile Include="OutputVisitor\TextWriterOutputFormatter.cs" />
<Compile Include="Parser\CompilerSettings.cs" />
<Compile Include="Parser\CSharpParser.cs" />
<Compile Include="Parser\mcs\anonymous.cs" />
<Compile Include="Parser\mcs\argument.cs" />
@ -241,14 +262,80 @@ @@ -241,14 +262,80 @@
<Compile Include="Parser\mcs\typespec.cs" />
<Compile Include="Parser\mcs\visit.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="QueryExpressionExpander.cs" />
<Compile Include="Refactoring\CodeActions\ConvertAsToCastAction.cs" />
<Compile Include="Refactoring\CodeActions\ConvertCastToAsAction.cs" />
<Compile Include="Refactoring\CodeActions\ConvertConditionalToIfAction.cs" />
<Compile Include="Refactoring\CodeActions\ConvertExplicitToImplicitImplementationAction.cs" />
<Compile Include="Refactoring\CodeActions\ConvertIfToConditionalAction.cs" />
<Compile Include="Refactoring\CodeActions\ConvertIfToSwitchAction.cs" />
<Compile Include="Refactoring\CodeActions\ConvertImplicitToExplicitImplementationAction.cs" />
<Compile Include="Refactoring\CodeActions\ConvertLambdaBodyExpressionToStatementAction.cs" />
<Compile Include="Refactoring\CodeActions\ConvertLambdaBodyStatementToExpressionAction.cs" />
<Compile Include="Refactoring\CodeActions\ConvertSwitchToIfAction.cs" />
<Compile Include="Refactoring\CodeActions\CreateCustomEventImplementationAction.cs" />
<Compile Include="Refactoring\CodeActions\CreateOverloadWithoutParameterAction.cs" />
<Compile Include="Refactoring\CodeActions\JoinDeclarationAndAssignmentAction.cs" />
<Compile Include="Refactoring\CodeActions\JoinStringAction.cs" />
<Compile Include="Refactoring\CodeActions\MergeNestedIfAction.cs" />
<Compile Include="Refactoring\CodeActions\NegateRelationalExpressionAction.cs" />
<Compile Include="Refactoring\CodeActions\PutInsideUsingAction.cs" />
<Compile Include="Refactoring\CodeActions\SplitDeclarationListAction.cs" />
<Compile Include="Refactoring\CodeActions\UseStringFormatAction.cs" />
<Compile Include="Refactoring\CodeIssues\AccessToClosureIssues\AccessToClosureIssue.cs" />
<Compile Include="Refactoring\CodeIssues\AccessToClosureIssues\AccessToDisposedClosureIssue.cs" />
<Compile Include="Refactoring\CodeIssues\AccessToClosureIssues\AccessToModifiedClosureIssue.cs" />
<Compile Include="Refactoring\CodeIssues\AccessToClosureIssues\LocalVariableNamePicker.cs" />
<Compile Include="Refactoring\CodeIssues\AssignmentMadeToSameVariableIssue.cs" />
<Compile Include="Refactoring\CodeIssues\BitwiseOperationOnNonFlagsEnumIssue.cs" />
<Compile Include="Refactoring\CodeIssues\CastExpressionOfIncompatibleTypeIssue.cs" />
<Compile Include="Refactoring\CodeIssues\CompareBooleanWithTrueOrFalseIssue.cs" />
<Compile Include="Refactoring\CodeIssues\CompareFloatWithEqualityOperatorIssue.cs" />
<Compile Include="Refactoring\CodeIssues\ConstantConditionIssue.cs" />
<Compile Include="Refactoring\CodeIssues\DoubleNegationIssue.cs" />
<Compile Include="Refactoring\CodeIssues\ExpressionIsAlwaysOfProvidedTypeIssue.cs" />
<Compile Include="Refactoring\CodeIssues\ExpressionIsNeverOfProvidedTypeIssue.cs" />
<Compile Include="Refactoring\CodeIssues\MethodNeverReturnsIssue.cs" />
<Compile Include="Refactoring\CodeIssues\MethodOverloadHidesOptionalParameterIssue.cs" />
<Compile Include="Refactoring\CodeIssues\NegativeRelationalExpressionIssue.cs" />
<Compile Include="Refactoring\CodeIssues\ExplicitConversionInForEachIssue.cs" />
<Compile Include="Refactoring\CodeIssues\ForControlVariableNotModifiedIssue.cs" />
<Compile Include="Refactoring\CodeIssues\IdenticalConditionalBranchIssue.cs" />
<Compile Include="Refactoring\CodeIssues\MultipleEnumerationIssue.cs" />
<Compile Include="Refactoring\CodeIssues\RedundantArrayInitializerCommaIssue.cs" />
<Compile Include="Refactoring\CodeIssues\RedundantAssignmentIssue.cs" />
<Compile Include="Refactoring\CodeIssues\RedundantAttributeParenthesesIssue.cs" />
<Compile Include="Refactoring\CodeIssues\RedundantCaseLabelIssue.cs" />
<Compile Include="Refactoring\CodeIssues\RedundantElseIssue.cs" />
<Compile Include="Refactoring\CodeIssues\RedundantFieldInitializerIssue.cs" />
<Compile Include="Refactoring\CodeIssues\RedundantObjectCreationArgumentListIssue.cs" />
<Compile Include="Refactoring\CodeIssues\RedundantObjectOrCollectionInitializerIssue.cs" />
<Compile Include="Refactoring\CodeIssues\RedundantTypeCastIssue.cs" />
<Compile Include="Refactoring\CodeIssues\ReferenceEqualsCalledWithValueTypeIssue.cs" />
<Compile Include="Refactoring\CodeIssues\UnreachableCodeIssue.cs" />
<Compile Include="Refactoring\CodeIssues\VariableHidesMemberIssue\LocalVariableHidesMemberIssue.cs" />
<Compile Include="Refactoring\CodeIssues\VariableHidesMemberIssue\ParameterHidesMemberIssue.cs" />
<Compile Include="Refactoring\CodeIssues\VariableHidesMemberIssue\VariableHidesMemberIssue.cs" />
<Compile Include="Refactoring\CodeIssues\VariableOnlyAssignedIssues\LocalVariableOnlyAssignedIssue.cs" />
<Compile Include="Refactoring\CodeIssues\VariableNotUsedIssues\LocalVariableNotUsedIssue.cs" />
<Compile Include="Refactoring\CodeIssues\VariableNotUsedIssues\ParameterNotUsedIssue.cs" />
<Compile Include="Refactoring\CodeIssues\TypeParameterNotUsedIssue.cs" />
<Compile Include="Refactoring\CodeIssues\VariableNotUsedIssues\VariableNotUsedIssue.cs" />
<Compile Include="Refactoring\CodeIssues\VariableOnlyAssignedIssues\ParameterOnlyAssignedIssue.cs" />
<Compile Include="Refactoring\CodeIssues\VariableOnlyAssignedIssues\VariableOnlyAssignedIssue.cs" />
<Compile Include="Refactoring\DocumentScript.cs" />
<Compile Include="Refactoring\CodeActions\ExtractAnonymousMethodAction.cs" />
<Compile Include="Refactoring\LambdaHelper.cs" />
<Compile Include="Refactoring\PatternHelper.cs" />
<Compile Include="Refactoring\RefactoringAstHelper.cs" />
<Compile Include="Refactoring\RefactoringContext.cs" />
<Compile Include="Refactoring\Script.cs" />
<Compile Include="Refactoring\TypeCompatibilityHelper.cs" />
<Compile Include="Refactoring\TypeSystemAstBuilder.cs" />
<Compile Include="Refactoring\VariableReferenceGraph.cs" />
<Compile Include="Resolver\CompositeResolveVisitorNavigator.cs" />
<Compile Include="Resolver\DynamicInvocationResolveResult.cs" />
<Compile Include="Resolver\DynamicMemberResolveResult.cs" />
<Compile Include="Resolver\CSharpConversions.cs" />
<Compile Include="Resolver\CSharpAstResolver.cs" />
<Compile Include="Resolver\CSharpInvocationResolveResult.cs" />
@ -271,14 +358,14 @@ @@ -271,14 +358,14 @@
<Compile Include="Resolver\TypeInference.cs" />
<Compile Include="Completion\ICompletionDataFactory.cs" />
<Compile Include="Completion\IParameterCompletionDataFactory.cs" />
<Compile Include="SimpleNameLookupMode.cs" />
<Compile Include="NameLookupMode.cs" />
<Compile Include="TypeSystem\AliasNamespaceReference.cs" />
<Compile Include="TypeSystem\AttributeTypeReference.cs" />
<Compile Include="TypeSystem\ConstantValues.cs" />
<Compile Include="TypeSystem\CSharpAssembly.cs" />
<Compile Include="TypeSystem\CSharpAttribute.cs" />
<Compile Include="TypeSystem\CSharpDocumentationComment.cs" />
<Compile Include="TypeSystem\CSharpParsedFile.cs" />
<Compile Include="TypeSystem\CSharpUnresolvedFile.cs" />
<Compile Include="TypeSystem\CSharpUnresolvedTypeDefinition.cs" />
<Compile Include="TypeSystem\CSharpTypeResolveContext.cs" />
<Compile Include="TypeSystem\ResolvedUsingScope.cs" />
@ -294,7 +381,6 @@ @@ -294,7 +381,6 @@
<Compile Include="Completion\CSharpCompletionEngine.cs" />
<Compile Include="Completion\CSharpCompletionEngineBase.cs" />
<Compile Include="Completion\CSharpParameterCompletionEngine.cs" />
<Compile Include="Completion\IMemberProvider.cs" />
<Compile Include="Parser\mcs\module.cs" />
<Compile Include="Parser\mcs\settings.cs" />
<Compile Include="Parser\mcs\SourceMethodBuilder.cs" />
@ -370,6 +456,48 @@ @@ -370,6 +456,48 @@
<Compile Include="Ast\GeneralScope\WhitespaceNode.cs" />
<Compile Include="Ast\GeneralScope\TextNode.cs" />
<Compile Include="Formatter\FormattingOptionsFactory.cs" />
<Compile Include="Refactoring\CodeActions\ImplementInterfaceAction.cs" />
<Compile Include="Refactoring\CodeActions\ImplementInterfaceExplicitAction.cs" />
<Compile Include="Refactoring\CodeActions\ImplementAbstractMembersAction.cs" />
<Compile Include="Refactoring\CodeActions\RemoveRedundantCatchTypeAction.cs" />
<Compile Include="Refactoring\CodeActions\AddCatchTypeAction.cs" />
<Compile Include="Refactoring\CodeIssues\IncorrectExceptionParameterOrderingIssue.cs" />
<Compile Include="Refactoring\CodeIssues\CallToVirtualFunctionFromConstructorIssue.cs" />
<Compile Include="Refactoring\CodeActions\StaticMethodInvocationToExtensionMethodInvocationAction.cs" />
<Compile Include="Refactoring\CodeActions\ExtensionMethodInvocationToStaticMethodInvocationAction.cs" />
<Compile Include="Refactoring\CodeActions\IterateViaForeachAction.cs" />
<Compile Include="Refactoring\CodeActions\ExtractFieldAction.cs" />
<Compile Include="Completion\ICompletionContextProvider.cs" />
<Compile Include="Refactoring\CodeIssues\ValueParameterUnusedIssue.cs" />
<Compile Include="Refactoring\NamingHelper.cs" />
<Compile Include="Refactoring\CodeActions\ConvertToInitializer\ConvertToInitializerAction.cs" />
<Compile Include="Refactoring\CodeActions\ConvertToInitializer\StatementsToInitializerConverter.cs" />
<Compile Include="Refactoring\CodeActions\ConvertToInitializer\InitializerPath.cs" />
<Compile Include="Refactoring\CodeActions\MoveToOuterScopeAction.cs" />
<Compile Include="Refactoring\CodeIssues\VariableDeclaredInWideScopeIssue.cs" />
<Compile Include="Refactoring\CodeIssues\ParameterCanBeDemotedIssue\ParameterCanBeDemotedIssue.cs" />
<Compile Include="Refactoring\CodeIssues\ParameterCanBeDemotedIssue\ITypeCriterion.cs" />
<Compile Include="Refactoring\CodeIssues\ParameterCanBeDemotedIssue\HasMemberCriterion.cs" />
<Compile Include="Refactoring\CodeIssues\ParameterCanBeDemotedIssue\TypeCriteriaCollector.cs" />
<Compile Include="Refactoring\CodeIssues\ReferenceToStaticMemberViaDerivedTypeIssue.cs" />
<Compile Include="Refactoring\CodeIssues\ParameterCanBeDemotedIssue\IsTypeCriterion.cs" />
<Compile Include="Refactoring\CodeIssues\OptionalParameterCouldBeSkippedIssue.cs" />
<Compile Include="Refactoring\CodeIssues\RedundantCatchIssue.cs" />
<Compile Include="Refactoring\CodeIssues\RedundantToStringIssue.cs" />
<Compile Include="Refactoring\CodeIssues\CallToObjectEqualsViaBaseIssue.cs" />
<Compile Include="Refactoring\CodeIssues\IncorrectCallToObjectGetHashCodeIssue.cs" />
<Compile Include="Refactoring\CodeActions\ExtractMethod\VariableUsageAnalyzation.cs" />
<Compile Include="Refactoring\CodeIssues\FormatStringIssues\FormatStringIssue.cs" />
<Compile Include="Refactoring\CodeIssues\FormatStringIssues\FormatStringHelper.cs" />
<Compile Include="Refactoring\CodeActions\ConvertToInitializer\ConvertInitializerToExplicitInitializationsAction.cs" />
<Compile Include="Refactoring\CodeIssues\ExceptionRethrowIssue.cs" />
<Compile Include="Refactoring\CodeIssues\ThreadStaticOnInstanceFieldIssue.cs" />
<Compile Include="Refactoring\CodeIssues\StaticFieldInGenericTypeIssue.cs" />
<Compile Include="Parser\SeekableStreamReader.cs" />
<Compile Include="Refactoring\CodeActions\ConvertAnonymousDelegateToLambdaAction.cs" />
<Compile Include="Refactoring\CodeActions\ConvertLambdaToAnonymousDelegateAction.cs" />
<Compile Include="Refactoring\CodeIssues\ParameterCanBeDemotedIssue\IsArrayTypeCriterion.cs" />
<Compile Include="Refactoring\CodeIssues\ParameterCanBeDemotedIssue\SupportsIndexingCriterion.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\ICSharpCode.NRefactory\ICSharpCode.NRefactory.csproj">
@ -383,14 +511,17 @@ @@ -383,14 +511,17 @@
<Folder Include="Refactoring\CodeIssues\" />
<Folder Include="Refactoring\CodeIssues\InconsistentNamingIssue\" />
<Folder Include="Refactoring\CodeActions\ExtractMethod\" />
<Folder Include="Refactoring\CodeActions\ConvertToInitializer\" />
<Folder Include="Refactoring\CodeIssues\FormatStringIssues\" />
</ItemGroup>
<ProjectExtensions>
<MonoDevelop>
<Properties>
<Policies>
<TextStylePolicy TabWidth="4" EolMarker="Unix" inheritsSet="Mono" inheritsScope="text/plain" scope="text/plain" />
<TextStylePolicy FileWidth="120" TabWidth="4" EolMarker="Unix" inheritsSet="Mono" inheritsScope="text/plain" scope="text/x-csharp" />
<CSharpFormattingPolicy inheritsSet="1TBS" inheritsScope="text/x-csharp" scope="text/x-csharp" />
<TextStylePolicy TabsToSpaces="False" EolMarker="Unix" inheritsSet="VisualStudio" inheritsScope="text/plain" scope="text/plain" />
<TextStylePolicy FileWidth="120" TabsToSpaces="False" EolMarker="Unix" inheritsSet="VisualStudio" inheritsScope="text/plain" scope="text/x-csharp" />
<CSharpFormattingPolicy IndentSwitchBody="True" BeforeMethodDeclarationParentheses="False" BeforeMethodCallParentheses="False" BeforeConstructorDeclarationParentheses="False" BeforeDelegateDeclarationParentheses="False" NewParentheses="False" inheritsSet="Mono" inheritsScope="text/x-csharp" scope="text/x-csharp" />
<TextStylePolicy inheritsSet="null" scope="text/x-jay" />
</Policies>
</Properties>
</MonoDevelop>

2
ICSharpCode.NRefactory.CSharp/SimpleNameLookupMode.cs → ICSharpCode.NRefactory.CSharp/NameLookupMode.cs

@ -20,7 +20,7 @@ using System; @@ -20,7 +20,7 @@ using System;
namespace ICSharpCode.NRefactory.CSharp
{
public enum SimpleNameLookupMode
public enum NameLookupMode
{
/// <summary>
/// Normal name lookup in expressions

26
ICSharpCode.NRefactory.CSharp/OutputVisitor/CSharpOutputVisitor.cs

@ -917,7 +917,7 @@ namespace ICSharpCode.NRefactory.CSharp @@ -917,7 +917,7 @@ namespace ICSharpCode.NRefactory.CSharp
public void VisitNamedArgumentExpression(NamedArgumentExpression namedArgumentExpression)
{
StartNode(namedArgumentExpression);
namedArgumentExpression.IdentifierToken.AcceptVisitor(this);
namedArgumentExpression.NameToken.AcceptVisitor(this);
WriteToken(Roles.Colon);
Space();
namedArgumentExpression.Expression.AcceptVisitor(this);
@ -927,7 +927,7 @@ namespace ICSharpCode.NRefactory.CSharp @@ -927,7 +927,7 @@ namespace ICSharpCode.NRefactory.CSharp
public void VisitNamedExpression(NamedExpression namedExpression)
{
StartNode(namedExpression);
namedExpression.IdentifierToken.AcceptVisitor(this);
namedExpression.NameToken.AcceptVisitor(this);
Space();
WriteToken(Roles.Assign);
Space();
@ -1007,6 +1007,14 @@ namespace ICSharpCode.NRefactory.CSharp @@ -1007,6 +1007,14 @@ namespace ICSharpCode.NRefactory.CSharp
EndNode(primitiveExpression);
}
public static string PrintPrimitiveValue(object val)
{
StringWriter writer = new StringWriter();
CSharpOutputVisitor visitor = new CSharpOutputVisitor(writer, new CSharpFormattingOptions());
visitor.WritePrimitiveValue(val);
return writer.ToString();
}
void WritePrimitiveValue(object val)
{
if (val == null) {
@ -1837,16 +1845,19 @@ namespace ICSharpCode.NRefactory.CSharp @@ -1837,16 +1845,19 @@ namespace ICSharpCode.NRefactory.CSharp
label.AcceptVisitor(this);
first = false;
}
if (policy.IndentCaseBody) {
bool isBlock = switchSection.Statements.Count == 1 && switchSection.Statements.Single() is BlockStatement;
if (policy.IndentCaseBody && !isBlock) {
formatter.Indent();
}
foreach (var statement in switchSection.Statements) {
if (!isBlock)
NewLine();
foreach (var statement in switchSection.Statements) {
statement.AcceptVisitor(this);
}
if (policy.IndentCaseBody) {
if (policy.IndentCaseBody && !isBlock) {
formatter.Unindent();
}
@ -2161,6 +2172,7 @@ namespace ICSharpCode.NRefactory.CSharp @@ -2161,6 +2172,7 @@ namespace ICSharpCode.NRefactory.CSharp
WriteAttributes(indexerDeclaration.Attributes);
WriteModifiers(indexerDeclaration.ModifierTokens);
indexerDeclaration.ReturnType.AcceptVisitor(this);
Space();
WritePrivateImplementationType(indexerDeclaration.PrivateImplementationType);
WriteKeyword(IndexerDeclaration.ThisKeywordRole);
Space(policy.SpaceBeforeMethodDeclarationParentheses);
@ -2293,10 +2305,10 @@ namespace ICSharpCode.NRefactory.CSharp @@ -2293,10 +2305,10 @@ namespace ICSharpCode.NRefactory.CSharp
EndNode(variableInitializer);
}
public void VisitCompilationUnit(CompilationUnit compilationUnit)
public void VisitSyntaxTree(SyntaxTree syntaxTree)
{
// don't do node tracking as we visit all children directly
foreach (AstNode node in compilationUnit.Children) {
foreach (AstNode node in syntaxTree.Children) {
node.AcceptVisitor(this);
}
}

143
ICSharpCode.NRefactory.CSharp/OutputVisitor/CodeDomConvertVisitor.cs

@ -21,12 +21,12 @@ using System.CodeDom; @@ -21,12 +21,12 @@ using System.CodeDom;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using ICSharpCode.NRefactory.CSharp.Refactoring;
using ICSharpCode.NRefactory.CSharp.Resolver;
using ICSharpCode.NRefactory.CSharp.TypeSystem;
using ICSharpCode.NRefactory.PatternMatching;
using ICSharpCode.NRefactory.Semantics;
using ICSharpCode.NRefactory.TypeSystem;
using ICSharpCode.NRefactory.TypeSystem.Implementation;
namespace ICSharpCode.NRefactory.CSharp
{
@ -40,35 +40,44 @@ namespace ICSharpCode.NRefactory.CSharp @@ -40,35 +40,44 @@ namespace ICSharpCode.NRefactory.CSharp
{
//ICompilation compilation = MinimalResolveContext.Instance;
CSharpAstResolver resolver;
bool useFullyQualifiedTypeNames;
/// <summary>
/// Gets/Sets whether the visitor should use fully-qualified type references.
/// </summary>
public bool UseFullyQualifiedTypeNames {
get { return useFullyQualifiedTypeNames; }
set { useFullyQualifiedTypeNames = value; }
public bool UseFullyQualifiedTypeNames { get; set; }
/// <summary>
/// Gets whether the visitor is allowed to produce snippet nodes for
/// code that cannot be converted.
/// The default is true. If this property is set to false,
/// unconvertible code will throw a NotSupportedException.
/// </summary>
public bool AllowSnippetNodes { get; set; }
public CodeDomConvertVisitor()
{
this.AllowSnippetNodes = true;
}
/// <summary>
/// Converts a compilation unit to CodeDom.
/// Converts a syntax tree to CodeDom.
/// </summary>
/// <param name="compilationUnit">The input compilation unit.</param>
/// <param name="syntaxTree">The input syntax tree.</param>
/// <param name="compilation">The current compilation.</param>
/// <param name="parsedFile">CSharpParsedFile, used for resolving.</param>
/// <param name="unresolvedFile">CSharpUnresolvedFile, used for resolving.</param>
/// <returns>Converted CodeCompileUnit</returns>
/// <remarks>
/// This conversion process requires a resolver because it needs to distinguish field/property/event references etc.
/// </remarks>
public CodeCompileUnit Convert(ICompilation compilation, CompilationUnit compilationUnit, CSharpParsedFile parsedFile)
public CodeCompileUnit Convert(ICompilation compilation, SyntaxTree syntaxTree, CSharpUnresolvedFile unresolvedFile)
{
if (compilationUnit == null)
throw new ArgumentNullException("compilationUnit");
if (syntaxTree == null)
throw new ArgumentNullException("syntaxTree");
if (compilation == null)
throw new ArgumentNullException("compilation");
CSharpAstResolver resolver = new CSharpAstResolver(compilation, compilationUnit, parsedFile);
return (CodeCompileUnit)Convert(compilationUnit, resolver);
CSharpAstResolver resolver = new CSharpAstResolver(compilation, syntaxTree, unresolvedFile);
return (CodeCompileUnit)Convert(syntaxTree, resolver);
}
/// <summary>
@ -136,7 +145,15 @@ namespace ICSharpCode.NRefactory.CSharp @@ -136,7 +145,15 @@ namespace ICSharpCode.NRefactory.CSharp
CodeTypeReference Convert(IType type)
{
return new CodeTypeReference(type.ReflectionName);
if (type.Kind == TypeKind.Array) {
ArrayType a = (ArrayType)type;
return new CodeTypeReference(Convert(a.ElementType), a.Dimensions);
} else if (type is ParameterizedType) {
var pt = (ParameterizedType)type;
return new CodeTypeReference(pt.GetDefinition().ReflectionName, pt.TypeArguments.Select(Convert).ToArray());
} else {
return new CodeTypeReference(type.ReflectionName);
}
}
CodeStatement Convert(Statement stmt)
@ -148,6 +165,8 @@ namespace ICSharpCode.NRefactory.CSharp @@ -148,6 +165,8 @@ namespace ICSharpCode.NRefactory.CSharp
{
List<CodeStatement> result = new List<CodeStatement>();
foreach (Statement stmt in block.Statements) {
if (stmt is EmptyStatement)
continue;
CodeStatement s = Convert(stmt);
if (s != null)
result.Add(s);
@ -160,6 +179,8 @@ namespace ICSharpCode.NRefactory.CSharp @@ -160,6 +179,8 @@ namespace ICSharpCode.NRefactory.CSharp
BlockStatement block = embeddedStatement as BlockStatement;
if (block != null) {
return ConvertBlock(block);
} else if (embeddedStatement is EmptyStatement) {
return new CodeStatement[0];
}
CodeStatement s = Convert(embeddedStatement);
if (s != null)
@ -170,6 +191,8 @@ namespace ICSharpCode.NRefactory.CSharp @@ -170,6 +191,8 @@ namespace ICSharpCode.NRefactory.CSharp
string MakeSnippet(AstNode node)
{
if (!AllowSnippetNodes)
throw new NotSupportedException();
StringWriter w = new StringWriter();
CSharpOutputVisitor v = new CSharpOutputVisitor(w, FormattingOptionsFactory.CreateMono ());
node.AcceptVisitor(v);
@ -371,7 +394,7 @@ namespace ICSharpCode.NRefactory.CSharp @@ -371,7 +394,7 @@ namespace ICSharpCode.NRefactory.CSharp
TypeResolveResult trr = rr as TypeResolveResult;
if (trr != null) {
CodeTypeReference typeRef;
if (useFullyQualifiedTypeNames) {
if (UseFullyQualifiedTypeNames) {
typeRef = Convert(trr.Type);
} else {
typeRef = new CodeTypeReference(identifierExpression.Identifier);
@ -380,7 +403,7 @@ namespace ICSharpCode.NRefactory.CSharp @@ -380,7 +403,7 @@ namespace ICSharpCode.NRefactory.CSharp
return new CodeTypeReferenceExpression(typeRef);
}
MethodGroupResolveResult mgrr = rr as MethodGroupResolveResult;
if (mgrr != null) {
if (mgrr != null || identifierExpression.TypeArguments.Any()) {
return new CodeMethodReferenceExpression(new CodeThisReferenceExpression(), identifierExpression.Identifier, Convert(identifierExpression.TypeArguments));
}
return new CodeVariableReferenceExpression(identifierExpression.Identifier);
@ -635,7 +658,7 @@ namespace ICSharpCode.NRefactory.CSharp @@ -635,7 +658,7 @@ namespace ICSharpCode.NRefactory.CSharp
foreach (Expression expr in attribute.Arguments) {
NamedExpression ne = expr as NamedExpression;
if (ne != null)
attr.Arguments.Add(new CodeAttributeArgument(ne.Identifier, Convert(ne.Expression)));
attr.Arguments.Add(new CodeAttributeArgument(ne.Name, Convert(ne.Expression)));
else
attr.Arguments.Add(new CodeAttributeArgument(Convert(expr)));
}
@ -658,7 +681,7 @@ namespace ICSharpCode.NRefactory.CSharp @@ -658,7 +681,7 @@ namespace ICSharpCode.NRefactory.CSharp
CodeObject IAstVisitor<CodeObject>.VisitDelegateDeclaration(DelegateDeclaration delegateDeclaration)
{
CodeTypeDelegate d = new CodeTypeDelegate(delegateDeclaration.Name);
d.Attributes = ConvertMemberAttributes(delegateDeclaration.Modifiers);
d.Attributes = ConvertMemberAttributes(delegateDeclaration.Modifiers, EntityType.TypeDefinition);
d.CustomAttributes.AddRange(Convert(delegateDeclaration.Attributes));
d.ReturnType = Convert(delegateDeclaration.ReturnType);
d.Parameters.AddRange(Convert(delegateDeclaration.Parameters));
@ -666,13 +689,15 @@ namespace ICSharpCode.NRefactory.CSharp @@ -666,13 +689,15 @@ namespace ICSharpCode.NRefactory.CSharp
return d;
}
static MemberAttributes ConvertMemberAttributes(Modifiers modifiers)
MemberAttributes ConvertMemberAttributes(Modifiers modifiers, EntityType entityType)
{
MemberAttributes a = 0;
if ((modifiers & Modifiers.Abstract) != 0)
a |= MemberAttributes.Abstract;
if ((modifiers & Modifiers.Sealed) != 0)
a |= MemberAttributes.Final;
if (entityType != EntityType.TypeDefinition && (modifiers & (Modifiers.Abstract | Modifiers.Override | Modifiers.Virtual)) == 0)
a |= MemberAttributes.Final;
if ((modifiers & Modifiers.Static) != 0)
a |= MemberAttributes.Static;
if ((modifiers & Modifiers.Override) != 0)
@ -719,7 +744,7 @@ namespace ICSharpCode.NRefactory.CSharp @@ -719,7 +744,7 @@ namespace ICSharpCode.NRefactory.CSharp
{
//bool isNestedType = typeStack.Count > 0;
CodeTypeDeclaration typeDecl = new CodeTypeDeclaration(typeDeclaration.Name);
typeDecl.Attributes = ConvertMemberAttributes(typeDeclaration.Modifiers);
typeDecl.Attributes = ConvertMemberAttributes(typeDeclaration.Modifiers, EntityType.TypeDefinition);
typeDecl.CustomAttributes.AddRange(Convert(typeDeclaration.Attributes));
switch (typeDeclaration.ClassType) {
@ -809,7 +834,12 @@ namespace ICSharpCode.NRefactory.CSharp @@ -809,7 +834,12 @@ namespace ICSharpCode.NRefactory.CSharp
CodeObject IAstVisitor<CodeObject>.VisitEmptyStatement(EmptyStatement emptyStatement)
{
return null;
return EmptyStatement();
}
CodeStatement EmptyStatement()
{
return new CodeExpressionStatement(new CodeObjectCreateExpression(new CodeTypeReference(typeof(object))));
}
CodeObject IAstVisitor<CodeObject>.VisitExpressionStatement(ExpressionStatement expressionStatement)
@ -817,10 +847,55 @@ namespace ICSharpCode.NRefactory.CSharp @@ -817,10 +847,55 @@ namespace ICSharpCode.NRefactory.CSharp
AssignmentExpression assignment = expressionStatement.Expression as AssignmentExpression;
if (assignment != null && assignment.Operator == AssignmentOperatorType.Assign) {
return new CodeAssignStatement(Convert(assignment.Left), Convert(assignment.Right));
} else if (assignment != null && CanBeDuplicatedForCompoundAssignment(assignment.Left)) {
CodeBinaryOperatorType op;
switch (assignment.Operator) {
case AssignmentOperatorType.Add:
op = CodeBinaryOperatorType.Add;
break;
case AssignmentOperatorType.Subtract:
op = CodeBinaryOperatorType.Subtract;
break;
case AssignmentOperatorType.Multiply:
op = CodeBinaryOperatorType.Multiply;
break;
case AssignmentOperatorType.Divide:
op = CodeBinaryOperatorType.Divide;
break;
case AssignmentOperatorType.Modulus:
op = CodeBinaryOperatorType.Modulus;
break;
case AssignmentOperatorType.BitwiseAnd:
op = CodeBinaryOperatorType.BitwiseAnd;
break;
case AssignmentOperatorType.BitwiseOr:
op = CodeBinaryOperatorType.BitwiseOr;
break;
default:
return MakeSnippetStatement(expressionStatement);
}
var cboe = new CodeBinaryOperatorExpression(Convert(assignment.Left), op, Convert(assignment.Right));
return new CodeAssignStatement(Convert(assignment.Left), cboe);
}
UnaryOperatorExpression unary = expressionStatement.Expression as UnaryOperatorExpression;
if (unary != null && CanBeDuplicatedForCompoundAssignment(unary.Expression)) {
var op = unary.Operator;
if (op == UnaryOperatorType.Increment || op == UnaryOperatorType.PostIncrement) {
var cboe = new CodeBinaryOperatorExpression(Convert(unary.Expression), CodeBinaryOperatorType.Add, new CodePrimitiveExpression(1));
return new CodeAssignStatement(Convert(unary.Expression), cboe);
} else if (op == UnaryOperatorType.Decrement || op == UnaryOperatorType.PostDecrement) {
var cboe = new CodeBinaryOperatorExpression(Convert(unary.Expression), CodeBinaryOperatorType.Subtract, new CodePrimitiveExpression(1));
return new CodeAssignStatement(Convert(unary.Expression), cboe);
}
}
return new CodeExpressionStatement(Convert(expressionStatement.Expression));
}
bool CanBeDuplicatedForCompoundAssignment(Expression expr)
{
return expr is IdentifierExpression;
}
CodeObject IAstVisitor<CodeObject>.VisitFixedStatement(FixedStatement fixedStatement)
{
return MakeSnippetStatement(fixedStatement);
@ -956,7 +1031,7 @@ namespace ICSharpCode.NRefactory.CSharp @@ -956,7 +1031,7 @@ namespace ICSharpCode.NRefactory.CSharp
CodeObject IAstVisitor<CodeObject>.VisitWhileStatement(WhileStatement whileStatement)
{
return new CodeIterationStatement(null, Convert(whileStatement.Condition), null, ConvertEmbeddedStatement(whileStatement.EmbeddedStatement));
return new CodeIterationStatement(EmptyStatement(), Convert(whileStatement.Condition), EmptyStatement(), ConvertEmbeddedStatement(whileStatement.EmbeddedStatement));
}
CodeObject IAstVisitor<CodeObject>.VisitYieldBreakStatement(YieldBreakStatement yieldBreakStatement)
@ -977,7 +1052,7 @@ namespace ICSharpCode.NRefactory.CSharp @@ -977,7 +1052,7 @@ namespace ICSharpCode.NRefactory.CSharp
CodeObject IAstVisitor<CodeObject>.VisitConstructorDeclaration(ConstructorDeclaration constructorDeclaration)
{
CodeConstructor ctor = new CodeConstructor();
ctor.Attributes = ConvertMemberAttributes(constructorDeclaration.Modifiers);
ctor.Attributes = ConvertMemberAttributes(constructorDeclaration.Modifiers, EntityType.Constructor);
ctor.CustomAttributes.AddRange(Convert(constructorDeclaration.Attributes));
if (constructorDeclaration.Initializer.ConstructorInitializerType == ConstructorInitializerType.This) {
ctor.ChainedConstructorArgs.AddRange(Convert(constructorDeclaration.Initializer.Arguments));
@ -1019,7 +1094,7 @@ namespace ICSharpCode.NRefactory.CSharp @@ -1019,7 +1094,7 @@ namespace ICSharpCode.NRefactory.CSharp
}
CodeMemberEvent e = new CodeMemberEvent();
e.Attributes = ConvertMemberAttributes(eventDeclaration.Modifiers);
e.Attributes = ConvertMemberAttributes(eventDeclaration.Modifiers, EntityType.Event);
e.CustomAttributes.AddRange(Convert(eventDeclaration.Attributes));
e.Name = vi.Name;
e.Type = Convert(eventDeclaration.ReturnType);
@ -1037,7 +1112,7 @@ namespace ICSharpCode.NRefactory.CSharp @@ -1037,7 +1112,7 @@ namespace ICSharpCode.NRefactory.CSharp
{
foreach (VariableInitializer vi in fieldDeclaration.Variables) {
CodeMemberField f = new CodeMemberField(Convert(fieldDeclaration.ReturnType), vi.Name);
f.Attributes = ConvertMemberAttributes(fieldDeclaration.Modifiers);
f.Attributes = ConvertMemberAttributes(fieldDeclaration.Modifiers, EntityType.Field);
f.CustomAttributes.AddRange(Convert(fieldDeclaration.Attributes));
f.InitExpression = ConvertVariableInitializer(vi.Initializer, fieldDeclaration.ReturnType);
AddTypeMember(f);
@ -1048,7 +1123,7 @@ namespace ICSharpCode.NRefactory.CSharp @@ -1048,7 +1123,7 @@ namespace ICSharpCode.NRefactory.CSharp
CodeObject IAstVisitor<CodeObject>.VisitIndexerDeclaration(IndexerDeclaration indexerDeclaration)
{
CodeMemberProperty p = new CodeMemberProperty();
p.Attributes = ConvertMemberAttributes(indexerDeclaration.Modifiers);
p.Attributes = ConvertMemberAttributes(indexerDeclaration.Modifiers, EntityType.Indexer);
p.CustomAttributes.AddRange(Convert(indexerDeclaration.Attributes));
p.Name = "Items";
p.PrivateImplementationType = Convert(indexerDeclaration.PrivateImplementationType);
@ -1069,7 +1144,7 @@ namespace ICSharpCode.NRefactory.CSharp @@ -1069,7 +1144,7 @@ namespace ICSharpCode.NRefactory.CSharp
CodeObject IAstVisitor<CodeObject>.VisitMethodDeclaration(MethodDeclaration methodDeclaration)
{
CodeMemberMethod m = new CodeMemberMethod();
m.Attributes = ConvertMemberAttributes(methodDeclaration.Modifiers);
m.Attributes = ConvertMemberAttributes(methodDeclaration.Modifiers, EntityType.Method);
m.CustomAttributes.AddRange(Convert(methodDeclaration.Attributes.Where(a => a.AttributeTarget != "return")));
m.ReturnTypeCustomAttributes.AddRange(Convert(methodDeclaration.Attributes.Where(a => a.AttributeTarget == "return")));
@ -1087,7 +1162,7 @@ namespace ICSharpCode.NRefactory.CSharp @@ -1087,7 +1162,7 @@ namespace ICSharpCode.NRefactory.CSharp
CodeObject IAstVisitor<CodeObject>.VisitOperatorDeclaration(OperatorDeclaration operatorDeclaration)
{
CodeMemberMethod m = new CodeMemberMethod();
m.Attributes = ConvertMemberAttributes(operatorDeclaration.Modifiers);
m.Attributes = ConvertMemberAttributes(operatorDeclaration.Modifiers, EntityType.Method);
m.CustomAttributes.AddRange(Convert(operatorDeclaration.Attributes.Where(a => a.AttributeTarget != "return")));
m.ReturnTypeCustomAttributes.AddRange(Convert(operatorDeclaration.Attributes.Where(a => a.AttributeTarget == "return")));
@ -1129,7 +1204,7 @@ namespace ICSharpCode.NRefactory.CSharp @@ -1129,7 +1204,7 @@ namespace ICSharpCode.NRefactory.CSharp
CodeObject IAstVisitor<CodeObject>.VisitPropertyDeclaration(PropertyDeclaration propertyDeclaration)
{
CodeMemberProperty p = new CodeMemberProperty();
p.Attributes = ConvertMemberAttributes(propertyDeclaration.Modifiers);
p.Attributes = ConvertMemberAttributes(propertyDeclaration.Modifiers, EntityType.Property);
p.CustomAttributes.AddRange(Convert(propertyDeclaration.Attributes));
p.Name = propertyDeclaration.Name;
p.PrivateImplementationType = Convert(propertyDeclaration.PrivateImplementationType);
@ -1161,10 +1236,10 @@ namespace ICSharpCode.NRefactory.CSharp @@ -1161,10 +1236,10 @@ namespace ICSharpCode.NRefactory.CSharp
throw new NotSupportedException(); // should be handled by the parent node
}
CodeObject IAstVisitor<CodeObject>.VisitCompilationUnit(CompilationUnit compilationUnit)
CodeObject IAstVisitor<CodeObject>.VisitSyntaxTree(SyntaxTree syntaxTree)
{
CodeCompileUnit cu = new CodeCompileUnit();
foreach (AstNode node in compilationUnit.Children) {
foreach (AstNode node in syntaxTree.Children) {
CodeObject o = node.AcceptVisitor(this);
CodeNamespace ns = o as CodeNamespace;
@ -1181,7 +1256,7 @@ namespace ICSharpCode.NRefactory.CSharp @@ -1181,7 +1256,7 @@ namespace ICSharpCode.NRefactory.CSharp
CodeObject IAstVisitor<CodeObject>.VisitSimpleType(SimpleType simpleType)
{
if (useFullyQualifiedTypeNames) {
if (UseFullyQualifiedTypeNames) {
IType type = Resolve(simpleType).Type;
if (type.Kind != TypeKind.Unknown)
return Convert(type);
@ -1198,7 +1273,7 @@ namespace ICSharpCode.NRefactory.CSharp @@ -1198,7 +1273,7 @@ namespace ICSharpCode.NRefactory.CSharp
tr.TypeArguments.AddRange(Convert(memberType.TypeArguments));
return tr;
}
if (useFullyQualifiedTypeNames || memberType.IsDoubleColon) {
if (UseFullyQualifiedTypeNames || memberType.IsDoubleColon) {
IType type = Resolve(memberType).Type;
if (type.Kind != TypeKind.Unknown)
return Convert(type);
@ -1309,7 +1384,7 @@ namespace ICSharpCode.NRefactory.CSharp @@ -1309,7 +1384,7 @@ namespace ICSharpCode.NRefactory.CSharp
return null;
}
CodeObject IAstVisitor<CodeObject>.VisitPatternPlaceholder(AstNode placeholder, ICSharpCode.NRefactory.PatternMatching.Pattern pattern)
CodeObject IAstVisitor<CodeObject>.VisitPatternPlaceholder(AstNode placeholder, Pattern pattern)
{
return null;
}

963
ICSharpCode.NRefactory.CSharp/Parser/CSharpParser.cs

File diff suppressed because it is too large Load Diff

151
ICSharpCode.NRefactory.CSharp/Parser/CompilerSettings.cs

@ -0,0 +1,151 @@ @@ -0,0 +1,151 @@
// 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 ICSharpCode.NRefactory.TypeSystem.Implementation;
namespace ICSharpCode.NRefactory.CSharp
{
/// <summary>
/// C# compiler settings.
/// </summary>
[Serializable]
public class CompilerSettings : AbstractFreezable
{
protected override void FreezeInternal()
{
conditionalSymbols = FreezableHelper.FreezeList(conditionalSymbols);
specificWarningsAsErrors = FreezableHelper.FreezeList(specificWarningsAsErrors);
disabledWarnings = FreezableHelper.FreezeList(disabledWarnings);
base.FreezeInternal();
}
/// <summary>
/// Creates a new CompilerSettings instance.
/// </summary>
public CompilerSettings()
{
}
bool allowUnsafeBlocks = true;
/// <summary>
/// Gets/Sets whether <c>unsafe</c> code is allowed.
/// The default is <c>true</c>. If set to false, parsing unsafe code will result in parser errors.
/// </summary>
public bool AllowUnsafeBlocks {
get { return allowUnsafeBlocks; }
set {
FreezableHelper.ThrowIfFrozen(this);
allowUnsafeBlocks = value;
}
}
bool checkForOverflow;
/// <summary>
/// Gets/Sets whether overflow checking is enabled.
/// The default is <c>false</c>. This setting effects semantic analysis.
/// </summary>
public bool CheckForOverflow {
get { return checkForOverflow; }
set { checkForOverflow = value; }
}
Version languageVersion = new Version((int)Mono.CSharp.LanguageVersion.Default, 0);
/// <summary>
/// Gets/Sets the language version used by the parser.
/// Using language constructs newer than the supplied version will result in parser errors.
/// </summary>
public Version LanguageVersion {
get { return languageVersion; }
set {
FreezableHelper.ThrowIfFrozen(this);
if (value == null)
throw new ArgumentNullException();
languageVersion = value;
}
}
IList<string> conditionalSymbols = new List<string>();
/// <summary>
/// Gets/Sets the list of conditional symbols that are defined project-wide.
/// </summary>
public IList<string> ConditionalSymbols {
get { return conditionalSymbols; }
}
bool treatWarningsAsErrors;
public bool TreatWarningsAsErrors {
get { return treatWarningsAsErrors; }
set {
FreezableHelper.ThrowIfFrozen(this);
treatWarningsAsErrors = value;
}
}
IList<int> specificWarningsAsErrors = new List<int>();
/// <summary>
/// Allows treating specific warnings as errors without setting <see cref="TreatWarningsAsErrors"/> to true.
/// </summary>
public IList<int> SpecificWarningsAsErrors {
get { return specificWarningsAsErrors; }
}
int warningLevel = 4;
public int WarningLevel {
get { return warningLevel; }
set {
FreezableHelper.ThrowIfFrozen(this);
warningLevel = value;
}
}
IList<int> disabledWarnings = new List<int>();
/// <summary>
/// Allows treating specific warnings as errors without setting <see cref="TreatWarningsAsErrors"/> to true.
/// </summary>
public IList<int> DisabledWarnings {
get { return disabledWarnings; }
}
internal Mono.CSharp.CompilerSettings ToMono()
{
var s = new Mono.CSharp.CompilerSettings();
s.Unsafe = allowUnsafeBlocks;
s.Checked = checkForOverflow;
s.Version = (Mono.CSharp.LanguageVersion)languageVersion.Major;
s.WarningsAreErrors = treatWarningsAsErrors;
s.WarningLevel = warningLevel;
foreach (int code in disabledWarnings)
s.SetIgnoreWarning(code);
foreach (int code in specificWarningsAsErrors)
s.AddWarningAsError(code);
foreach (string sym in conditionalSymbols)
s.AddConditionalSymbol(sym);
return s;
}
}
}

103
ICSharpCode.NRefactory.CSharp/Parser/SeekableStreamReader.cs

@ -0,0 +1,103 @@ @@ -0,0 +1,103 @@
//
// SeekableStreamReader.cs
//
// Author:
// Mike Krüger <mkrueger@xamarin.com>
//
// Copyright (c) 2012 Xamarin Inc. (http://xamarin.com)
//
// 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 ICSharpCode.NRefactory.Editor;
using System.IO;
using System.Text;
namespace Mono.CSharp
{
public class SeekableStreamReader : IDisposable
{
public const int DefaultReadAheadSize = 2048;
readonly ITextSource textSource;
int pos;
static string GetAllText(Stream stream, Encoding encoding) {
using (var rdr = new StreamReader(stream, encoding)) {
return rdr.ReadToEnd();
}
}
public SeekableStreamReader (Stream stream, Encoding encoding, char[] sharedBuffer = null) : this(new StringTextSource(GetAllText(stream, encoding)))
{
}
public SeekableStreamReader (ITextSource source)
{
this.textSource = source;
}
public void Dispose ()
{
}
/// <remarks>
/// This value corresponds to the current position in a stream of characters.
/// The StreamReader hides its manipulation of the underlying byte stream and all
/// character set/decoding issues. Thus, we cannot use this position to guess at
/// the corresponding position in the underlying byte stream even though there is
/// a correlation between them.
/// </remarks>
public int Position {
get {
return pos;
}
set {
pos = value;
}
}
public char GetChar (int position)
{
return textSource.GetCharAt (position);
}
public char[] ReadChars (int fromPosition, int toPosition)
{
return textSource.GetText (fromPosition, toPosition - fromPosition).ToCharArray ();
}
public int Peek ()
{
if (pos >= textSource.TextLength)
return -1;
return textSource.GetCharAt (pos);
}
public int Read ()
{
if (pos >= textSource.TextLength)
return -1;
return textSource.GetCharAt (pos++);
}
}
}

2
ICSharpCode.NRefactory.CSharp/Parser/mcs/MonoSymbolFile.cs

@ -53,7 +53,7 @@ namespace Mono.CompilerServices.SymbolWriter @@ -53,7 +53,7 @@ namespace Mono.CompilerServices.SymbolWriter
}
}
internal class MyBinaryWriter : BinaryWriter
sealed class MyBinaryWriter : BinaryWriter
{
public MyBinaryWriter (Stream stream)
: base (stream)

81
ICSharpCode.NRefactory.CSharp/Parser/mcs/MonoSymbolTable.cs

@ -183,6 +183,7 @@ namespace Mono.CompilerServices.SymbolWriter @@ -183,6 +183,7 @@ namespace Mono.CompilerServices.SymbolWriter
{
#region This is actually written to the symbol file
public readonly int Row;
public int Column;
public readonly int File;
public readonly int Offset;
public readonly bool IsHidden; // Obsolete is never used
@ -195,28 +196,35 @@ namespace Mono.CompilerServices.SymbolWriter @@ -195,28 +196,35 @@ namespace Mono.CompilerServices.SymbolWriter
public int Compare (LineNumberEntry l1, LineNumberEntry l2)
{
return l1.Row == l2.Row ?
l1.Offset.CompareTo (l2.Offset) :
l1.Column.CompareTo (l2.Column) :
l1.Row.CompareTo (l2.Row);
}
}
public static readonly LineNumberEntry Null = new LineNumberEntry (0, 0, 0);
public static readonly LineNumberEntry Null = new LineNumberEntry (0, 0, 0, 0);
public LineNumberEntry (int file, int row, int column, int offset)
: this (file, row, offset, column, false)
{
}
public LineNumberEntry (int file, int row, int offset)
: this (file, row, offset, false)
{ }
: this (file, row, -1, offset, false)
{
}
public LineNumberEntry (int file, int row, int offset, bool is_hidden)
public LineNumberEntry (int file, int row, int column, int offset, bool is_hidden)
{
this.File = file;
this.Row = row;
this.Column = column;
this.Offset = offset;
this.IsHidden = is_hidden;
}
public override string ToString ()
{
return String.Format ("[Line {0}:{1}:{2}]", File, Row, Offset);
return String.Format ("[Line {0}:{1,2}:{3}]", File, Row, Column, Offset);
}
}
@ -675,8 +683,7 @@ namespace Mono.CompilerServices.SymbolWriter @@ -675,8 +683,7 @@ namespace Mono.CompilerServices.SymbolWriter
creating = true;
}
public SourceFileEntry (MonoSymbolFile file, string file_name,
byte[] guid, byte[] checksum)
public SourceFileEntry (MonoSymbolFile file, string file_name, byte[] guid, byte[] checksum)
: this (file, file_name)
{
this.guid = guid;
@ -694,13 +701,15 @@ namespace Mono.CompilerServices.SymbolWriter @@ -694,13 +701,15 @@ namespace Mono.CompilerServices.SymbolWriter
DataOffset = (int) bw.BaseStream.Position;
bw.Write (file_name);
if (guid == null) {
guid = Guid.NewGuid ().ToByteArray ();
if (guid == null)
guid = new byte[16];
if (hash == null) {
try {
using (FileStream fs = new FileStream (file_name, FileMode.Open, FileAccess.Read)) {
MD5 md5 = MD5.Create ();
hash = md5.ComputeHash (fs);
}
using (FileStream fs = new FileStream (file_name, FileMode.Open, FileAccess.Read)) {
MD5 md5 = MD5.Create ();
hash = md5.ComputeHash (fs);
}
} catch {
hash = new byte [16];
}
@ -791,7 +800,6 @@ namespace Mono.CompilerServices.SymbolWriter @@ -791,7 +800,6 @@ namespace Mono.CompilerServices.SymbolWriter
public const int Default_LineRange = 8;
public const byte Default_OpcodeBase = 9;
public const bool SuppressDuplicates = true;
#endregion
public const byte DW_LNS_copy = 1;
@ -822,7 +830,7 @@ namespace Mono.CompilerServices.SymbolWriter @@ -822,7 +830,7 @@ namespace Mono.CompilerServices.SymbolWriter
this._line_numbers = lines;
}
internal void Write (MonoSymbolFile file, MyBinaryWriter bw)
internal void Write (MonoSymbolFile file, MyBinaryWriter bw, bool readColumnsInfo)
{
int start = (int) bw.BaseStream.Position;
@ -832,11 +840,6 @@ namespace Mono.CompilerServices.SymbolWriter @@ -832,11 +840,6 @@ namespace Mono.CompilerServices.SymbolWriter
int line_inc = LineNumbers [i].Row - last_line;
int offset_inc = LineNumbers [i].Offset - last_offset;
if (SuppressDuplicates && (i+1 < LineNumbers.Length)) {
if (LineNumbers [i+1].Equals (LineNumbers [i]))
continue;
}
if (LineNumbers [i].File != last_file) {
bw.Write (DW_LNS_set_file);
bw.WriteLeb128 (LineNumbers [i].File);
@ -884,17 +887,23 @@ namespace Mono.CompilerServices.SymbolWriter @@ -884,17 +887,23 @@ namespace Mono.CompilerServices.SymbolWriter
bw.Write ((byte) 1);
bw.Write (DW_LNE_end_sequence);
for (int i = 0; i < LineNumbers.Length; i++) {
var ln = LineNumbers [i];
if (ln.Row >= 0)
bw.WriteLeb128 (ln.Column);
}
file.ExtendedLineNumberSize += (int) bw.BaseStream.Position - start;
}
internal static LineNumberTable Read (MonoSymbolFile file, MyBinaryReader br)
internal static LineNumberTable Read (MonoSymbolFile file, MyBinaryReader br, bool readColumnsInfo)
{
LineNumberTable lnt = new LineNumberTable (file);
lnt.DoRead (file, br);
lnt.DoRead (file, br, readColumnsInfo);
return lnt;
}
void DoRead (MonoSymbolFile file, MyBinaryReader br)
void DoRead (MonoSymbolFile file, MyBinaryReader br, bool includesColumns)
{
var lines = new List<LineNumberEntry> ();
@ -911,7 +920,7 @@ namespace Mono.CompilerServices.SymbolWriter @@ -911,7 +920,7 @@ namespace Mono.CompilerServices.SymbolWriter
if (opcode == DW_LNE_end_sequence) {
if (modified)
lines.Add (new LineNumberEntry (
stm_file, stm_line, stm_offset, is_hidden));
stm_file, stm_line, -1, stm_offset, is_hidden));
break;
} else if (opcode == DW_LNE_MONO_negate_is_hidden) {
is_hidden = !is_hidden;
@ -929,7 +938,7 @@ namespace Mono.CompilerServices.SymbolWriter @@ -929,7 +938,7 @@ namespace Mono.CompilerServices.SymbolWriter
switch (opcode) {
case DW_LNS_copy:
lines.Add (new LineNumberEntry (
stm_file, stm_line, stm_offset, is_hidden));
stm_file, stm_line, -1, stm_offset, is_hidden));
modified = false;
break;
case DW_LNS_advance_pc:
@ -959,13 +968,20 @@ namespace Mono.CompilerServices.SymbolWriter @@ -959,13 +968,20 @@ namespace Mono.CompilerServices.SymbolWriter
stm_offset += opcode / LineRange;
stm_line += LineBase + (opcode % LineRange);
lines.Add (new LineNumberEntry (
stm_file, stm_line, stm_offset, is_hidden));
stm_file, stm_line, -1, stm_offset, is_hidden));
modified = false;
}
}
_line_numbers = new LineNumberEntry [lines.Count];
lines.CopyTo (_line_numbers, 0);
_line_numbers = lines.ToArray ();
if (includesColumns) {
for (int i = 0; i < _line_numbers.Length; ++i) {
var ln = _line_numbers[i];
if (ln.Row >= 0)
ln.Column = br.ReadLeb128 ();
}
}
}
public bool GetMethodBounds (out LineNumberEntry start, out LineNumberEntry end)
@ -1022,7 +1038,8 @@ namespace Mono.CompilerServices.SymbolWriter @@ -1022,7 +1038,8 @@ namespace Mono.CompilerServices.SymbolWriter
[Flags]
public enum Flags
{
LocalNamesAmbiguous = 1
LocalNamesAmbiguous = 1,
ColumnsInfoIncluded = 1 << 1
}
public const int Size = 12;
@ -1176,7 +1193,7 @@ namespace Mono.CompilerServices.SymbolWriter @@ -1176,7 +1193,7 @@ namespace Mono.CompilerServices.SymbolWriter
}
LineNumberTableOffset = (int) bw.BaseStream.Position;
lnt.Write (file, bw);
lnt.Write (file, bw, (flags & Flags.ColumnsInfoIncluded) != 0);
DataOffset = (int) bw.BaseStream.Position;
@ -1204,7 +1221,7 @@ namespace Mono.CompilerServices.SymbolWriter @@ -1204,7 +1221,7 @@ namespace Mono.CompilerServices.SymbolWriter
long old_pos = reader.BaseStream.Position;
reader.BaseStream.Position = LineNumberTableOffset;
lnt = LineNumberTable.Read (SymbolFile, reader);
lnt = LineNumberTable.Read (SymbolFile, reader, (flags & Flags.ColumnsInfoIncluded) != 0);
reader.BaseStream.Position = old_pos;
return lnt;

4
ICSharpCode.NRefactory.CSharp/Parser/mcs/SourceMethodBuilder.cs

@ -64,7 +64,7 @@ namespace Mono.CompilerServices.SymbolWriter @@ -64,7 +64,7 @@ namespace Mono.CompilerServices.SymbolWriter
public void MarkSequencePoint (int offset, SourceFileEntry file, int line, int column, bool is_hidden)
{
int file_idx = file != null ? file.Index : 0;
var lne = new LineNumberEntry (file_idx, line, offset, is_hidden);
var lne = new LineNumberEntry (file_idx, line, column, offset, is_hidden);
if (method_lines.Count > 0) {
var prev = method_lines[method_lines.Count - 1];
@ -185,7 +185,7 @@ namespace Mono.CompilerServices.SymbolWriter @@ -185,7 +185,7 @@ namespace Mono.CompilerServices.SymbolWriter
{
MethodEntry entry = new MethodEntry (
file, _comp_unit.Entry, token, ScopeVariables,
Locals, method_lines.ToArray (), Blocks, null, 0, ns_id);
Locals, method_lines.ToArray (), Blocks, null, MethodEntry.Flags.ColumnsInfoIncluded, ns_id);
file.AddMethod (entry);
}

82
ICSharpCode.NRefactory.CSharp/Parser/mcs/anonymous.cs

@ -315,7 +315,7 @@ namespace Mono.CSharp { @@ -315,7 +315,7 @@ namespace Mono.CSharp {
}
var hoisted = localVariable.HoistedVariant;
if (hoisted != null && hoisted.Storey != this && hoisted.Storey.Kind == MemberKind.Struct) {
if (hoisted != null && hoisted.Storey != this && hoisted.Storey is StateMachine) {
// TODO: It's too late the field is defined in HoistedLocalVariable ctor
hoisted.Storey.hoisted_locals.Remove (hoisted);
hoisted = null;
@ -331,7 +331,7 @@ namespace Mono.CSharp { @@ -331,7 +331,7 @@ namespace Mono.CSharp {
hoisted_locals.Add (hoisted);
}
if (ec.CurrentBlock.Explicit != localVariable.Block.Explicit)
if (ec.CurrentBlock.Explicit != localVariable.Block.Explicit && !(hoisted.Storey is StateMachine))
hoisted.Storey.AddReferenceFromChildrenBlock (ec.CurrentBlock.Explicit);
}
@ -343,7 +343,7 @@ namespace Mono.CSharp { @@ -343,7 +343,7 @@ namespace Mono.CSharp {
var hoisted = parameterInfo.Parameter.HoistedVariant;
if (parameterInfo.Block.StateMachine is AsyncTaskStorey) {
if (parameterInfo.Block.StateMachine != null) {
//
// Another storey in same block exists but state machine does not
// have parameter captured. We need to add it there as well to
@ -365,7 +365,7 @@ namespace Mono.CSharp { @@ -365,7 +365,7 @@ namespace Mono.CSharp {
// Lift captured parameter from value type storey to reference type one. Otherwise
// any side effects would be done on a copy
//
if (hoisted != null && hoisted.Storey != this && hoisted.Storey.Kind == MemberKind.Struct) {
if (hoisted != null && hoisted.Storey != this && hoisted.Storey is StateMachine) {
if (hoisted_local_params == null)
hoisted_local_params = new List<HoistedParameter> ();
@ -488,7 +488,7 @@ namespace Mono.CSharp { @@ -488,7 +488,7 @@ namespace Mono.CSharp {
// When the current context is async (or iterator) lift local storey
// instantiation to the currect storey
//
if (ec.CurrentAnonymousMethod is StateMachineInitializer) {
if (ec.CurrentAnonymousMethod is StateMachineInitializer && (block.HasYield || block.HasAwait)) {
//
// Unfortunately, normal capture mechanism could not be used because we are
// too late in the pipeline and standart assign cannot be used either due to
@ -702,7 +702,7 @@ namespace Mono.CSharp { @@ -702,7 +702,7 @@ namespace Mono.CSharp {
public override void Emit (EmitContext ec)
{
ResolveContext rc = new ResolveContext (ec.MemberContext);
Expression e = hv.GetFieldExpression (ec).CreateExpressionTree (rc);
Expression e = hv.GetFieldExpression (ec).CreateExpressionTree (rc, false);
// This should never fail
e = e.Resolve (rc);
if (e != null)
@ -816,7 +816,7 @@ namespace Mono.CSharp { @@ -816,7 +816,7 @@ namespace Mono.CSharp {
sealed class HoistedFieldAssign : CompilerAssign
{
public HoistedFieldAssign (Expression target, Expression source)
: base (target, source, source.Location)
: base (target, source, target.Location)
{
}
@ -960,11 +960,16 @@ namespace Mono.CSharp { @@ -960,11 +960,16 @@ namespace Mono.CSharp {
return Block.Parameters;
}
}
public bool IsAsync {
get;
internal set;
}
public ReportPrinter TypeInferenceReportPrinter {
get; set;
}
#endregion
//
@ -975,7 +980,13 @@ namespace Mono.CSharp { @@ -975,7 +980,13 @@ namespace Mono.CSharp {
{
using (ec.With (ResolveContext.Options.InferReturnType, false)) {
using (ec.Set (ResolveContext.Options.ProbingMode)) {
return Compatible (ec, delegate_type) != null;
var prev = ec.Report.SetPrinter (TypeInferenceReportPrinter ?? new NullReportPrinter ());
var res = Compatible (ec, delegate_type) != null;
ec.Report.SetPrinter (prev);
return res;
}
}
}
@ -1109,12 +1120,23 @@ namespace Mono.CSharp { @@ -1109,12 +1120,23 @@ namespace Mono.CSharp {
}
using (ec.Set (ResolveContext.Options.ProbingMode | ResolveContext.Options.InferReturnType)) {
ReportPrinter prev;
if (TypeInferenceReportPrinter != null) {
prev = ec.Report.SetPrinter (TypeInferenceReportPrinter);
} else {
prev = null;
}
var body = CompatibleMethodBody (ec, tic, null, delegate_type);
if (body != null) {
am = body.Compatible (ec, body);
} else {
am = null;
}
if (TypeInferenceReportPrinter != null) {
ec.Report.SetPrinter (prev);
}
}
if (am == null)
@ -1476,8 +1498,15 @@ namespace Mono.CSharp { @@ -1476,8 +1498,15 @@ namespace Mono.CSharp {
if (ec.HasSet (ResolveContext.Options.ExpressionTreeConversion))
flags |= ResolveContext.Options.ExpressionTreeConversion;
if (ec.HasSet (ResolveContext.Options.BaseInitializer))
flags |= ResolveContext.Options.BaseInitializer;
aec.Set (flags);
var bc = ec as BlockContext;
if (bc != null)
aec.FlowOffset = bc.FlowOffset;
var errors = ec.Report.Errors;
bool res = Block.Resolve (ec.CurrentBranching, aec, null);
@ -1988,11 +2017,11 @@ namespace Mono.CSharp { @@ -1988,11 +2017,11 @@ namespace Mono.CSharp {
IntConstant FNV_prime = new IntConstant (Compiler.BuiltinTypes, 16777619, loc);
rs_hashcode = new Binary (Binary.Operator.Multiply,
new Binary (Binary.Operator.ExclusiveOr, rs_hashcode, field_hashcode, loc),
FNV_prime, loc);
new Binary (Binary.Operator.ExclusiveOr, rs_hashcode, field_hashcode),
FNV_prime);
Expression field_to_string = new Conditional (new BooleanExpression (new Binary (Binary.Operator.Inequality,
new MemberAccess (new This (f.Location), f.Name), new NullLiteral (loc), loc)),
new MemberAccess (new This (f.Location), f.Name), new NullLiteral (loc))),
new Invocation (new MemberAccess (
new MemberAccess (new This (f.Location), f.Name), "ToString"), null),
new StringConstant (Compiler.BuiltinTypes, string.Empty, loc), loc);
@ -2003,9 +2032,7 @@ namespace Mono.CSharp { @@ -2003,9 +2032,7 @@ namespace Mono.CSharp {
string_concat,
new Binary (Binary.Operator.Addition,
new StringConstant (Compiler.BuiltinTypes, " " + p.Name + " = ", loc),
field_to_string,
loc),
loc);
field_to_string));
continue;
}
@ -2015,18 +2042,15 @@ namespace Mono.CSharp { @@ -2015,18 +2042,15 @@ namespace Mono.CSharp {
string_concat = new Binary (Binary.Operator.Addition,
new Binary (Binary.Operator.Addition,
string_concat,
new StringConstant (Compiler.BuiltinTypes, ", " + p.Name + " = ", loc),
loc),
field_to_string,
loc);
new StringConstant (Compiler.BuiltinTypes, ", " + p.Name + " = ", loc)),
field_to_string);
rs_equals = new Binary (Binary.Operator.LogicalAnd, rs_equals, field_equal, loc);
rs_equals = new Binary (Binary.Operator.LogicalAnd, rs_equals, field_equal);
}
string_concat = new Binary (Binary.Operator.Addition,
string_concat,
new StringConstant (Compiler.BuiltinTypes, " }", loc),
loc);
new StringConstant (Compiler.BuiltinTypes, " }", loc));
//
// Equals (object obj) override
@ -2037,9 +2061,9 @@ namespace Mono.CSharp { @@ -2037,9 +2061,9 @@ namespace Mono.CSharp {
new As (equals_block.GetParameterReference (0, loc),
current_type, loc), loc)));
Expression equals_test = new Binary (Binary.Operator.Inequality, other_variable, new NullLiteral (loc), loc);
Expression equals_test = new Binary (Binary.Operator.Inequality, other_variable, new NullLiteral (loc));
if (rs_equals != null)
equals_test = new Binary (Binary.Operator.LogicalAnd, equals_test, rs_equals, loc);
equals_test = new Binary (Binary.Operator.LogicalAnd, equals_test, rs_equals);
equals_block.AddStatement (new Return (equals_test, loc));
equals.Block = equals_block;
@ -2081,19 +2105,19 @@ namespace Mono.CSharp { @@ -2081,19 +2105,19 @@ namespace Mono.CSharp {
var hash_variable = new LocalVariableReference (li_hash, loc);
hashcode_block.AddStatement (new StatementExpression (
new CompoundAssign (Binary.Operator.Addition, hash_variable,
new Binary (Binary.Operator.LeftShift, hash_variable, new IntConstant (Compiler.BuiltinTypes, 13, loc), loc), loc)));
new Binary (Binary.Operator.LeftShift, hash_variable, new IntConstant (Compiler.BuiltinTypes, 13, loc)))));
hashcode_block.AddStatement (new StatementExpression (
new CompoundAssign (Binary.Operator.ExclusiveOr, hash_variable,
new Binary (Binary.Operator.RightShift, hash_variable, new IntConstant (Compiler.BuiltinTypes, 7, loc), loc), loc)));
new Binary (Binary.Operator.RightShift, hash_variable, new IntConstant (Compiler.BuiltinTypes, 7, loc)))));
hashcode_block.AddStatement (new StatementExpression (
new CompoundAssign (Binary.Operator.Addition, hash_variable,
new Binary (Binary.Operator.LeftShift, hash_variable, new IntConstant (Compiler.BuiltinTypes, 3, loc), loc), loc)));
new Binary (Binary.Operator.LeftShift, hash_variable, new IntConstant (Compiler.BuiltinTypes, 3, loc)))));
hashcode_block.AddStatement (new StatementExpression (
new CompoundAssign (Binary.Operator.ExclusiveOr, hash_variable,
new Binary (Binary.Operator.RightShift, hash_variable, new IntConstant (Compiler.BuiltinTypes, 17, loc), loc), loc)));
new Binary (Binary.Operator.RightShift, hash_variable, new IntConstant (Compiler.BuiltinTypes, 17, loc)))));
hashcode_block.AddStatement (new StatementExpression (
new CompoundAssign (Binary.Operator.Addition, hash_variable,
new Binary (Binary.Operator.LeftShift, hash_variable, new IntConstant (Compiler.BuiltinTypes, 5, loc), loc), loc)));
new Binary (Binary.Operator.LeftShift, hash_variable, new IntConstant (Compiler.BuiltinTypes, 5, loc)))));
hashcode_block.AddStatement (new Return (hash_variable, loc));
hashcode.Block = hashcode_top;

16
ICSharpCode.NRefactory.CSharp/Parser/mcs/argument.cs

@ -320,20 +320,20 @@ namespace Mono.CSharp @@ -320,20 +320,20 @@ namespace Mono.CSharp
if (a.Expr is Constant) {
info_flags = new Binary (Binary.Operator.BitwiseOr, info_flags,
new MemberAccess (new MemberAccess (binder, info_flags_enum, loc), "Constant", loc), loc);
new MemberAccess (new MemberAccess (binder, info_flags_enum, loc), "Constant", loc));
} else if (a.ArgType == Argument.AType.Ref) {
info_flags = new Binary (Binary.Operator.BitwiseOr, info_flags,
new MemberAccess (new MemberAccess (binder, info_flags_enum, loc), "IsRef", loc), loc);
new MemberAccess (new MemberAccess (binder, info_flags_enum, loc), "IsRef", loc));
info_flags = new Binary (Binary.Operator.BitwiseOr, info_flags,
new MemberAccess (new MemberAccess (binder, info_flags_enum, loc), "UseCompileTimeType", loc), loc);
new MemberAccess (new MemberAccess (binder, info_flags_enum, loc), "UseCompileTimeType", loc));
} else if (a.ArgType == Argument.AType.Out) {
info_flags = new Binary (Binary.Operator.BitwiseOr, info_flags,
new MemberAccess (new MemberAccess (binder, info_flags_enum, loc), "IsOut", loc), loc);
new MemberAccess (new MemberAccess (binder, info_flags_enum, loc), "IsOut", loc));
info_flags = new Binary (Binary.Operator.BitwiseOr, info_flags,
new MemberAccess (new MemberAccess (binder, info_flags_enum, loc), "UseCompileTimeType", loc), loc);
new MemberAccess (new MemberAccess (binder, info_flags_enum, loc), "UseCompileTimeType", loc));
} else if (a.ArgType == Argument.AType.DynamicTypeName) {
info_flags = new Binary (Binary.Operator.BitwiseOr, info_flags,
new MemberAccess (new MemberAccess (binder, info_flags_enum, loc), "IsStaticType", loc), loc);
new MemberAccess (new MemberAccess (binder, info_flags_enum, loc), "IsStaticType", loc));
}
var arg_type = a.Expr.Type;
@ -354,14 +354,14 @@ namespace Mono.CSharp @@ -354,14 +354,14 @@ namespace Mono.CSharp
}
info_flags = new Binary (Binary.Operator.BitwiseOr, info_flags,
new MemberAccess (new MemberAccess (binder, info_flags_enum, loc), "UseCompileTimeType", loc), loc);
new MemberAccess (new MemberAccess (binder, info_flags_enum, loc), "UseCompileTimeType", loc));
}
string named_value;
NamedArgument na = a as NamedArgument;
if (na != null) {
info_flags = new Binary (Binary.Operator.BitwiseOr, info_flags,
new MemberAccess (new MemberAccess (binder, info_flags_enum, loc), "NamedArgument", loc), loc);
new MemberAccess (new MemberAccess (binder, info_flags_enum, loc), "NamedArgument", loc));
named_value = na.Name;
} else {

13
ICSharpCode.NRefactory.CSharp/Parser/mcs/assembly.cs

@ -624,9 +624,16 @@ namespace Mono.CSharp @@ -624,9 +624,16 @@ namespace Mono.CSharp
new MemberAccess (system_security_permissions, "SecurityPermissionAttribute"),
new Arguments[] { pos, named }, loc, false);
g.AttachTo (module, module);
var ctor = g.Resolve ();
if (ctor != null) {
g.ExtractSecurityPermissionSet (ctor, ref declarative_security);
// Disable no-location warnings (e.g. obsolete) for compiler generated attribute
Compiler.Report.DisableReporting ();
try {
var ctor = g.Resolve ();
if (ctor != null) {
g.ExtractSecurityPermissionSet (ctor, ref declarative_security);
}
} finally {
Compiler.Report.EnableReporting ();
}
}

16
ICSharpCode.NRefactory.CSharp/Parser/mcs/assign.cs

@ -543,11 +543,11 @@ namespace Mono.CSharp { @@ -543,11 +543,11 @@ namespace Mono.CSharp {
ExpressionStatement resolved;
IMemberContext mc;
public FieldInitializer (FieldSpec spec, Expression expression, IMemberContext mc)
: base (new FieldExpr (spec, expression.Location), expression, expression.Location)
public FieldInitializer (FieldBase mc, Expression expression, Location loc)
: base (new FieldExpr (mc.Spec, expression.Location), expression, loc)
{
this.mc = mc;
if (!spec.IsStatic)
if (!mc.IsStatic)
((FieldExpr)target).InstanceExpression = new CompilerGeneratedThis (mc.CurrentType, expression.Location);
}
@ -660,15 +660,15 @@ namespace Mono.CSharp { @@ -660,15 +660,15 @@ namespace Mono.CSharp {
}
}
public CompoundAssign (Binary.Operator op, Expression target, Expression source, Location loc)
: base (target, source, loc)
public CompoundAssign (Binary.Operator op, Expression target, Expression source)
: base (target, source, target.Location)
{
right = source;
this.op = op;
}
public CompoundAssign (Binary.Operator op, Expression target, Expression source, Expression left, Location loc)
: this (op, target, source, loc)
public CompoundAssign (Binary.Operator op, Expression target, Expression source, Expression left)
: this (op, target, source)
{
this.left = left;
}
@ -731,7 +731,7 @@ namespace Mono.CSharp { @@ -731,7 +731,7 @@ namespace Mono.CSharp {
if (left == null)
left = new TargetExpression (target);
source = new Binary (op, left, right, true, loc);
source = new Binary (op, left, right, true);
if (target is DynamicMemberAssignable) {
Arguments targs = ((DynamicMemberAssignable) target).Arguments;

14
ICSharpCode.NRefactory.CSharp/Parser/mcs/async.cs

@ -227,7 +227,9 @@ namespace Mono.CSharp @@ -227,7 +227,9 @@ namespace Mono.CSharp
//
// awaiter = expr.GetAwaiter ();
//
fe_awaiter.EmitAssign (ec, expr, false, false);
using (ec.With (BuilderContext.Options.OmitDebugInfo, true)) {
fe_awaiter.EmitAssign (ec, expr, false, false);
}
Label skip_continuation = ec.DefineLabel ();
@ -284,14 +286,8 @@ namespace Mono.CSharp @@ -284,14 +286,8 @@ namespace Mono.CSharp
awaiter.IsAvailableForReuse = true;
if (ResultType.Kind != MemberKind.Void) {
var storey = (AsyncTaskStorey) machine_initializer.Storey;
if (storey.HoistedReturn != null)
storey.HoistedReturn.EmitAssign (ec);
else
ec.Emit (OpCodes.Pop);
}
if (ResultType.Kind != MemberKind.Void)
ec.Emit (OpCodes.Pop);
}
void Error_WrongAwaiterPattern (ResolveContext rc, TypeSpec awaiter)

45
ICSharpCode.NRefactory.CSharp/Parser/mcs/attribute.cs

@ -1016,7 +1016,7 @@ namespace Mono.CSharp { @@ -1016,7 +1016,7 @@ namespace Mono.CSharp {
if (pos_args.Count == 1 && pos_args[0].Expr is Constant) {
var value = ((Constant) pos_args[0].Expr).GetValue () as string;
if (string.IsNullOrEmpty (value))
Error_AttributeEmitError ("DllName cannot be empty");
Error_AttributeEmitError ("DllName cannot be empty or null");
}
} else if (Type == predefined.MethodImpl && pt.BuiltinType == BuiltinTypeSpec.Type.Short &&
!System.Enum.IsDefined (typeof (MethodImplOptions), ((Constant) arg_expr).GetValue ().ToString ())) {
@ -1476,6 +1476,12 @@ namespace Mono.CSharp { @@ -1476,6 +1476,12 @@ namespace Mono.CSharp {
Encode (type.MemberDefinition.IsImported ? old_type.AssemblyQualifiedName : old_type.FullName);
}
public void EncodeTypeName (TypeContainer type)
{
Encode (type.GetSignatureForMetadata ());
}
//
// Encodes single property named argument per call
//
@ -1629,6 +1635,10 @@ namespace Mono.CSharp { @@ -1629,6 +1635,10 @@ namespace Mono.CSharp {
// New in .NET 4.0
public readonly PredefinedDynamicAttribute Dynamic;
// New in .NET 4.5
public readonly PredefinedStateMachineAttribute AsyncStateMachine;
public readonly PredefinedStateMachineAttribute IteratorStateMachine;
//
// Optional types which are used as types and for member lookup
//
@ -1690,6 +1700,11 @@ namespace Mono.CSharp { @@ -1690,6 +1700,11 @@ namespace Mono.CSharp {
StructLayout = new PredefinedAttribute (module, "System.Runtime.InteropServices", "StructLayoutAttribute");
FieldOffset = new PredefinedAttribute (module, "System.Runtime.InteropServices", "FieldOffsetAttribute");
AsyncStateMachine = new PredefinedStateMachineAttribute (module, "System.Runtime.CompilerServices", "AsyncStateMachineAttribute");
IteratorStateMachine = new PredefinedStateMachineAttribute (module, "System.Runtime.CompilerServices", "IteratorStateMachineAttribute") {
IsIterator = true
};
CallerMemberNameAttribute = new PredefinedAttribute (module, "System.Runtime.CompilerServices", "CallerMemberNameAttribute");
CallerLineNumberAttribute = new PredefinedAttribute (module, "System.Runtime.CompilerServices", "CallerLineNumberAttribute");
CallerFilePathAttribute = new PredefinedAttribute (module, "System.Runtime.CompilerServices", "CallerFilePathAttribute");
@ -1877,6 +1892,34 @@ namespace Mono.CSharp { @@ -1877,6 +1892,34 @@ namespace Mono.CSharp {
}
}
public class PredefinedStateMachineAttribute : PredefinedAttribute
{
public PredefinedStateMachineAttribute (ModuleContainer module, string ns, string name)
: base (module, ns, name)
{
}
public bool IsIterator { get; set; }
public void EmitAttribute (MethodBuilder builder, StateMachine type)
{
var predefined_ctor = IsIterator ?
module.PredefinedMembers.IteratorStateMachineAttributeCtor :
module.PredefinedMembers.AsyncStateMachineAttributeCtor;
var ctor = predefined_ctor.Get ();
if (ctor == null)
return;
AttributeEncoder encoder = new AttributeEncoder ();
encoder.EncodeTypeName (type);
encoder.EncodeEmptyNamedArguments ();
builder.SetCustomAttribute ((ConstructorInfo) ctor.GetMetaInfo (), encoder.ToArray ());
}
}
public class PredefinedDynamicAttribute : PredefinedAttribute
{
MethodSpec tctor;

40
ICSharpCode.NRefactory.CSharp/Parser/mcs/cfold.cs

@ -187,7 +187,7 @@ namespace Mono.CSharp { @@ -187,7 +187,7 @@ namespace Mono.CSharp {
//
if ((lt.BuiltinType == BuiltinTypeSpec.Type.Bool && right is NullLiteral) ||
(rt.BuiltinType == BuiltinTypeSpec.Type.Bool && left is NullLiteral)) {
var b = new Nullable.LiftedBinaryOperator (oper, left, right, loc).Resolve (ec);
var b = new Nullable.LiftedBinaryOperator (oper, left, right).Resolve (ec);
// false | null => null
// null | false => null
@ -231,7 +231,7 @@ namespace Mono.CSharp { @@ -231,7 +231,7 @@ namespace Mono.CSharp {
//
if ((lt.BuiltinType == BuiltinTypeSpec.Type.Bool && right is NullLiteral) ||
(rt.BuiltinType == BuiltinTypeSpec.Type.Bool && left is NullLiteral)) {
var b = new Nullable.LiftedBinaryOperator (oper, left, right, loc).Resolve (ec);
var b = new Nullable.LiftedBinaryOperator (oper, left, right).Resolve (ec);
// false & null => false
// null & false => false
@ -469,7 +469,7 @@ namespace Mono.CSharp { @@ -469,7 +469,7 @@ namespace Mono.CSharp {
if (left is NullLiteral && right is NullLiteral) {
var lifted_int = new Nullable.NullableType (ec.BuiltinTypes.Int, loc);
lifted_int.ResolveAsType (ec);
return (Constant) new Nullable.LiftedBinaryOperator (oper, lifted_int, right, loc).Resolve (ec);
return (Constant) new Nullable.LiftedBinaryOperator (oper, lifted_int, right).Resolve (ec);
}
if (!DoBinaryNumericPromotions (ec, ref left, ref right))
@ -566,7 +566,7 @@ namespace Mono.CSharp { @@ -566,7 +566,7 @@ namespace Mono.CSharp {
if (left is NullLiteral && right is NullLiteral) {
var lifted_int = new Nullable.NullableType (ec.BuiltinTypes.Int, loc);
lifted_int.ResolveAsType (ec);
return (Constant) new Nullable.LiftedBinaryOperator (oper, lifted_int, right, loc).Resolve (ec);
return (Constant) new Nullable.LiftedBinaryOperator (oper, lifted_int, right).Resolve (ec);
}
if (!DoBinaryNumericPromotions (ec, ref left, ref right))
@ -662,7 +662,7 @@ namespace Mono.CSharp { @@ -662,7 +662,7 @@ namespace Mono.CSharp {
if (left is NullLiteral && right is NullLiteral) {
var lifted_int = new Nullable.NullableType (ec.BuiltinTypes.Int, loc);
lifted_int.ResolveAsType (ec);
return (Constant) new Nullable.LiftedBinaryOperator (oper, lifted_int, right, loc).Resolve (ec);
return (Constant) new Nullable.LiftedBinaryOperator (oper, lifted_int, right).Resolve (ec);
}
if (!DoBinaryNumericPromotions (ec, ref left, ref right))
@ -762,7 +762,7 @@ namespace Mono.CSharp { @@ -762,7 +762,7 @@ namespace Mono.CSharp {
if (left is NullLiteral && right is NullLiteral) {
var lifted_int = new Nullable.NullableType (ec.BuiltinTypes.Int, loc);
lifted_int.ResolveAsType (ec);
return (Constant) new Nullable.LiftedBinaryOperator (oper, lifted_int, right, loc).Resolve (ec);
return (Constant) new Nullable.LiftedBinaryOperator (oper, lifted_int, right).Resolve (ec);
}
if (!DoBinaryNumericPromotions (ec, ref left, ref right))
@ -852,7 +852,7 @@ namespace Mono.CSharp { @@ -852,7 +852,7 @@ namespace Mono.CSharp {
if (left is NullLiteral && right is NullLiteral) {
var lifted_int = new Nullable.NullableType (ec.BuiltinTypes.Int, loc);
lifted_int.ResolveAsType (ec);
return (Constant) new Nullable.LiftedBinaryOperator (oper, lifted_int, right, loc).Resolve (ec);
return (Constant) new Nullable.LiftedBinaryOperator (oper, lifted_int, right).Resolve (ec);
}
IntConstant ic = right.ConvertImplicitly (ec.BuiltinTypes.Int) as IntConstant;
@ -873,7 +873,7 @@ namespace Mono.CSharp { @@ -873,7 +873,7 @@ namespace Mono.CSharp {
// null << value => null
if (left is NullLiteral)
return (Constant) new Nullable.LiftedBinaryOperator (oper, left, right, loc).Resolve (ec);
return (Constant) new Nullable.LiftedBinaryOperator (oper, left, right).Resolve (ec);
left = left.ConvertImplicitly (ec.BuiltinTypes.Int);
if (left.Type.BuiltinType == BuiltinTypeSpec.Type.Int)
@ -889,7 +889,7 @@ namespace Mono.CSharp { @@ -889,7 +889,7 @@ namespace Mono.CSharp {
if (left is NullLiteral && right is NullLiteral) {
var lifted_int = new Nullable.NullableType (ec.BuiltinTypes.Int, loc);
lifted_int.ResolveAsType (ec);
return (Constant) new Nullable.LiftedBinaryOperator (oper, lifted_int, right, loc).Resolve (ec);
return (Constant) new Nullable.LiftedBinaryOperator (oper, lifted_int, right).Resolve (ec);
}
IntConstant sic = right.ConvertImplicitly (ec.BuiltinTypes.Int) as IntConstant;
@ -909,7 +909,7 @@ namespace Mono.CSharp { @@ -909,7 +909,7 @@ namespace Mono.CSharp {
// null >> value => null
if (left is NullLiteral)
return (Constant) new Nullable.LiftedBinaryOperator (oper, left, right, loc).Resolve (ec);
return (Constant) new Nullable.LiftedBinaryOperator (oper, left, right).Resolve (ec);
left = left.ConvertImplicitly (ec.BuiltinTypes.Int);
if (left.Type.BuiltinType == BuiltinTypeSpec.Type.Int)
@ -925,7 +925,7 @@ namespace Mono.CSharp { @@ -925,7 +925,7 @@ namespace Mono.CSharp {
if (left.IsNull || right.IsNull) {
return ReducedExpression.Create (
new BoolConstant (ec.BuiltinTypes, left.IsNull == right.IsNull, left.Location),
new Binary (oper, left, right, loc));
new Binary (oper, left, right));
}
if (left is StringConstant && right is StringConstant)
@ -969,7 +969,7 @@ namespace Mono.CSharp { @@ -969,7 +969,7 @@ namespace Mono.CSharp {
if (left.IsNull || right.IsNull) {
return ReducedExpression.Create (
new BoolConstant (ec.BuiltinTypes, left.IsNull != right.IsNull, left.Location),
new Binary (oper, left, right, loc));
new Binary (oper, left, right));
}
if (left is StringConstant && right is StringConstant)
@ -1011,11 +1011,11 @@ namespace Mono.CSharp { @@ -1011,11 +1011,11 @@ namespace Mono.CSharp {
if (left is NullLiteral) {
var lifted_int = new Nullable.NullableType (ec.BuiltinTypes.Int, loc);
lifted_int.ResolveAsType (ec);
return (Constant) new Nullable.LiftedBinaryOperator (oper, lifted_int, right, loc).Resolve (ec);
return (Constant) new Nullable.LiftedBinaryOperator (oper, lifted_int, right).Resolve (ec);
}
if (left is Nullable.LiftedNull) {
return (Constant) new Nullable.LiftedBinaryOperator (oper, left, right, loc).Resolve (ec);
return (Constant) new Nullable.LiftedBinaryOperator (oper, left, right).Resolve (ec);
}
}
@ -1051,11 +1051,11 @@ namespace Mono.CSharp { @@ -1051,11 +1051,11 @@ namespace Mono.CSharp {
if (left is NullLiteral) {
var lifted_int = new Nullable.NullableType (ec.BuiltinTypes.Int, loc);
lifted_int.ResolveAsType (ec);
return (Constant) new Nullable.LiftedBinaryOperator (oper, lifted_int, right, loc).Resolve (ec);
return (Constant) new Nullable.LiftedBinaryOperator (oper, lifted_int, right).Resolve (ec);
}
if (left is Nullable.LiftedNull) {
return (Constant) new Nullable.LiftedBinaryOperator (oper, left, right, loc).Resolve (ec);
return (Constant) new Nullable.LiftedBinaryOperator (oper, left, right).Resolve (ec);
}
}
@ -1091,11 +1091,11 @@ namespace Mono.CSharp { @@ -1091,11 +1091,11 @@ namespace Mono.CSharp {
if (left is NullLiteral) {
var lifted_int = new Nullable.NullableType (ec.BuiltinTypes.Int, loc);
lifted_int.ResolveAsType (ec);
return (Constant) new Nullable.LiftedBinaryOperator (oper, lifted_int, right, loc).Resolve (ec);
return (Constant) new Nullable.LiftedBinaryOperator (oper, lifted_int, right).Resolve (ec);
}
if (left is Nullable.LiftedNull) {
return (Constant) new Nullable.LiftedBinaryOperator (oper, left, right, loc).Resolve (ec);
return (Constant) new Nullable.LiftedBinaryOperator (oper, left, right).Resolve (ec);
}
}
@ -1131,11 +1131,11 @@ namespace Mono.CSharp { @@ -1131,11 +1131,11 @@ namespace Mono.CSharp {
if (left is NullLiteral) {
var lifted_int = new Nullable.NullableType (ec.BuiltinTypes.Int, loc);
lifted_int.ResolveAsType (ec);
return (Constant) new Nullable.LiftedBinaryOperator (oper, lifted_int, right, loc).Resolve (ec);
return (Constant) new Nullable.LiftedBinaryOperator (oper, lifted_int, right).Resolve (ec);
}
if (left is Nullable.LiftedNull) {
return (Constant) new Nullable.LiftedBinaryOperator (oper, left, right, loc).Resolve (ec);
return (Constant) new Nullable.LiftedBinaryOperator (oper, left, right).Resolve (ec);
}
}

52
ICSharpCode.NRefactory.CSharp/Parser/mcs/class.cs

@ -70,6 +70,12 @@ namespace Mono.CSharp @@ -70,6 +70,12 @@ namespace Mono.CSharp
}
}
public Dictionary<string, MemberCore> DefinedNames {
get {
return defined_names;
}
}
public TypeDefinition PartialContainer {
get {
return main_container;
@ -340,12 +346,31 @@ namespace Mono.CSharp @@ -340,12 +346,31 @@ namespace Mono.CSharp
return MemberName.GetSignatureForError ();
}
public string GetSignatureForMetadata ()
{
#if STATIC
var name = TypeNameParser.Escape (MemberName.Basename);
if (Parent is TypeDefinition) {
return Parent.GetSignatureForMetadata () + "+" + name;
}
if (Parent != null && Parent.MemberName != null)
return Parent.GetSignatureForMetadata () + "." + name;
return name;
#else
throw new NotImplementedException ();
#endif
}
public virtual void RemoveContainer (TypeContainer cont)
{
if (containers != null)
containers.Remove (cont);
defined_names.Remove (cont.Basename);
var tc = Parent == Module ? Module : this;
tc.defined_names.Remove (cont.Basename);
}
public virtual void VerifyMembers ()
@ -1838,13 +1863,20 @@ namespace Mono.CSharp @@ -1838,13 +1863,20 @@ namespace Mono.CSharp
return;
string class_indexer_name = null;
has_normal_indexers = true;
//
// Check normal indexers for consistent name, explicit interface implementation
// indexers are ignored
//
foreach (var indexer in indexers) {
//
// FindMembers can return unfiltered full hierarchy names
//
if (indexer.DeclaringType != spec)
continue;
has_normal_indexers = true;
if (class_indexer_name == null) {
indexer_name = class_indexer_name = indexer.Name;
continue;
@ -1922,7 +1954,7 @@ namespace Mono.CSharp @@ -1922,7 +1954,7 @@ namespace Mono.CSharp
continue;
//
// Don't be pendatic over serializable attributes
// Don't be pedantic when type requires specific layout
//
if (f.OptAttributes != null || PartialContainer.HasStructLayout)
continue;
@ -1934,10 +1966,6 @@ namespace Mono.CSharp @@ -1934,10 +1966,6 @@ namespace Mono.CSharp
} else if (TypeSpec.IsReferenceType (f.MemberType)) {
value = "null";
} else {
// Ignore this warning for struct value fields (they are always initialized)
if (f.MemberType.IsStruct)
continue;
value = null;
}
@ -2403,16 +2431,6 @@ namespace Mono.CSharp @@ -2403,16 +2431,6 @@ namespace Mono.CSharp
base.AddNameToContainer (symbol, name);
}
public override void VerifyMembers ()
{
base.VerifyMembers ();
if (containers != null) {
foreach (var t in containers)
t.VerifyMembers ();
}
}
public override void ApplyAttributeBuilder (Attribute a, MethodSpec ctor, byte[] cdata, PredefinedAttributes pa)
{
if (a.IsValidSecurityAttribute ()) {

16
ICSharpCode.NRefactory.CSharp/Parser/mcs/codegen.cs

@ -944,10 +944,10 @@ namespace Mono.CSharp @@ -944,10 +944,10 @@ namespace Mono.CSharp
if (method.ReturnType.Kind == MemberKind.Void && method.IsConditionallyExcluded (ec.MemberContext, loc))
return;
EmitPredefined (ec, method, Arguments);
EmitPredefined (ec, method, Arguments, loc);
}
public void EmitPredefined (EmitContext ec, MethodSpec method, Arguments Arguments)
public void EmitPredefined (EmitContext ec, MethodSpec method, Arguments Arguments, Location? loc = null)
{
Expression instance_copy = null;
@ -1006,6 +1006,18 @@ namespace Mono.CSharp @@ -1006,6 +1006,18 @@ namespace Mono.CSharp
ec.Emit (OpCodes.Constrained, InstanceExpression.Type);
}
if (loc != null) {
//
// Emit explicit sequence point for expressions like Foo.Bar () to help debugger to
// break at right place when LHS expression can be stepped-into
//
// TODO: The list is probably not comprehensive, need to do more testing
//
if (InstanceExpression is PropertyExpr || InstanceExpression is Invocation || InstanceExpression is IndexerExpr ||
InstanceExpression is New || InstanceExpression is DelegateInvocation)
ec.Mark (loc.Value);
}
//
// Set instance expression to actual result expression. When it contains await it can be
// picked up by caller

2
ICSharpCode.NRefactory.CSharp/Parser/mcs/const.cs

@ -59,7 +59,7 @@ namespace Mono.CSharp { @@ -59,7 +59,7 @@ namespace Mono.CSharp {
if ((field_attr & FieldAttributes.InitOnly) != 0)
Parent.PartialContainer.RegisterFieldForInitialization (this,
new FieldInitializer (spec, initializer, this));
new FieldInitializer (this, initializer, Location));
if (declarators != null) {
var t = new TypeExpression (MemberType, TypeExpression.Location);

25
ICSharpCode.NRefactory.CSharp/Parser/mcs/context.cs

@ -13,6 +13,7 @@ @@ -13,6 +13,7 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Security.Cryptography;
namespace Mono.CSharp
{
@ -730,4 +731,28 @@ namespace Mono.CSharp @@ -730,4 +731,28 @@ namespace Mono.CSharp
return new FlagsHandle (this, options, enable ? options : 0);
}
}
//
// Parser session objects. We could recreate all these objects for each parser
// instance but the best parser performance the session object can be reused
//
public class ParserSession
{
MD5 md5;
public readonly char[] StreamReaderBuffer = new char[SeekableStreamReader.DefaultReadAheadSize * 2];
public readonly Dictionary<char[], string>[] Identifiers = new Dictionary<char[], string>[Tokenizer.MaxIdentifierLength + 1];
public readonly List<Parameter> ParametersStack = new List<Parameter> (4);
public readonly char[] IDBuilder = new char[Tokenizer.MaxIdentifierLength];
public readonly char[] NumberBuilder = new char[Tokenizer.MaxNumberLength];
public LocationsBag LocationsBag { get; set; }
public bool UseJayGlobalArrays { get; set; }
public Tokenizer.LocatedToken[] LocatedTokens { get; set; }
public MD5 GetChecksumAlgorithm ()
{
return md5 ?? (md5 = MD5.Create ());
}
}
}

3
ICSharpCode.NRefactory.CSharp/Parser/mcs/convert.cs

@ -1337,8 +1337,7 @@ namespace Mono.CSharp { @@ -1337,8 +1337,7 @@ namespace Mono.CSharp {
try {
c = c.ConvertImplicitly (target_type);
} catch {
Console.WriteLine ("Conversion error happened in line {0}", loc);
throw;
throw new InternalErrorException ("Conversion error", loc);
}
if (c != null)
return c;

9494
ICSharpCode.NRefactory.CSharp/Parser/mcs/cs-parser.cs

File diff suppressed because it is too large Load Diff

230
ICSharpCode.NRefactory.CSharp/Parser/mcs/cs-parser.jay

@ -10,12 +10,7 @@ @@ -10,12 +10,7 @@
//
// (C) 2001 Ximian, Inc (http://www.ximian.com)
// (C) 2004-2011 Novell, Inc
// Copyright 2011 Xamarin Inc.
//
// TODO:
// (1) Figure out why error productions dont work. `type-declaration' is a
// great spot to put an `error' because you can reproduce it with this input:
// "public X { }"
// Copyright 2011-2012 Xamarin Inc.
//
using System.Text;
@ -81,7 +76,7 @@ namespace Mono.CSharp @@ -81,7 +76,7 @@ namespace Mono.CSharp
///
/// An out-of-band stack.
///
static Stack<object> oob_stack;
Stack<object> oob_stack;
///
/// Controls the verbosity of the errors produced by the parser
@ -137,7 +132,7 @@ namespace Mono.CSharp @@ -137,7 +132,7 @@ namespace Mono.CSharp
// share the bucket for very common constructs which can never
// be recursive
//
static List<Parameter> parameters_bucket = new List<Parameter> (6);
List<Parameter> parameters_bucket;
//
// Full AST support members
@ -2669,6 +2664,22 @@ enum_member_declaration @@ -2669,6 +2664,22 @@ enum_member_declaration
$$ = em;
}
| opt_attributes IDENTIFIER error
{
Error_SyntaxError (yyToken);
var lt = (Tokenizer.LocatedToken) $2;
var em = new EnumMember ((Enum) current_type, new MemberName (lt.Value, lt.Location), (Attributes) $1);
((Enum) current_type).AddEnumMember (em);
if (doc_support) {
em.DocComment = Lexer.consume_doc_comment ();
Lexer.doc_state = XmlCommentState.Allowed;
}
$$ = em;
}
| attributes_without_members
;
delegate_declaration
@ -3196,6 +3207,14 @@ invocation_expression @@ -3196,6 +3207,14 @@ invocation_expression
$$ = new Invocation ((Expression) $1, (Arguments) $3);
lbag.AddLocation ($$, GetLocation ($2), GetLocation ($4));
}
| primary_expression open_parens_any argument_list error
{
Error_SyntaxError (yyToken);
$$ = new Invocation ((Expression) $1, (Arguments) $3);
lbag.AddLocation ($$, GetLocation ($2));
}
;
opt_object_or_collection_initializer
@ -3207,8 +3226,8 @@ object_or_collection_initializer @@ -3207,8 +3226,8 @@ object_or_collection_initializer
: OPEN_BRACE opt_member_initializer_list close_brace_or_complete_completion
{
if ($2 == null) {
$$ = CollectionOrObjectInitializers.Empty;
// TODO: lbag
$$ = new CollectionOrObjectInitializers (new List<Expression> (), GetLocation ($1));
lbag.AddLocation ($$, GetLocation ($1), GetLocation ($3));
} else {
$$ = new CollectionOrObjectInitializers ((List<Expression>) $2, GetLocation ($1));
lbag.AddLocation ($$, GetLocation ($1), GetLocation ($3));
@ -3279,7 +3298,8 @@ member_initializer @@ -3279,7 +3298,8 @@ member_initializer
| OPEN_BRACE CLOSE_BRACE
{
report.Error (1920, GetLocation ($1), "An element initializer cannot be empty");
$$ = null;
$$ = new CollectionElementInitializer (new List<Expression> (), GetLocation ($1));
lbag.AddLocation ($$, GetLocation ($2));
}
;
@ -3327,6 +3347,7 @@ argument_list @@ -3327,6 +3347,7 @@ argument_list
}
| argument_list COMMA error
{
lexer.putback (')'); // TODO: Wrong but what can I do
Error_SyntaxError (yyToken);
$$ = $1;
}
@ -3955,18 +3976,18 @@ multiplicative_expression @@ -3955,18 +3976,18 @@ multiplicative_expression
: prefixed_unary_expression
| multiplicative_expression STAR prefixed_unary_expression
{
$$ = new Binary (Binary.Operator.Multiply,
(Expression) $1, (Expression) $3, GetLocation ($2));
$$ = new Binary (Binary.Operator.Multiply, (Expression) $1, (Expression) $3);
lbag.AddLocation ($$, GetLocation ($2));
}
| multiplicative_expression DIV prefixed_unary_expression
{
$$ = new Binary (Binary.Operator.Division,
(Expression) $1, (Expression) $3, GetLocation ($2));
$$ = new Binary (Binary.Operator.Division, (Expression) $1, (Expression) $3);
lbag.AddLocation ($$, GetLocation ($2));
}
| multiplicative_expression PERCENT prefixed_unary_expression
{
$$ = new Binary (Binary.Operator.Modulus,
(Expression) $1, (Expression) $3, GetLocation ($2));
$$ = new Binary (Binary.Operator.Modulus, (Expression) $1, (Expression) $3);
lbag.AddLocation ($$, GetLocation ($2));
}
;
@ -3974,18 +3995,14 @@ additive_expression @@ -3974,18 +3995,14 @@ additive_expression
: multiplicative_expression
| additive_expression PLUS multiplicative_expression
{
$$ = new Binary (Binary.Operator.Addition,
(Expression) $1, (Expression) $3, GetLocation ($2));
$$ = new Binary (Binary.Operator.Addition, (Expression) $1, (Expression) $3);
lbag.AddLocation ($$, GetLocation ($2));
}
| additive_expression MINUS multiplicative_expression
{
$$ = new Binary (Binary.Operator.Subtraction, (Expression) $1, (Expression) $3, GetLocation ($2));
$$ = new Binary (Binary.Operator.Subtraction, (Expression) $1, (Expression) $3);
lbag.AddLocation ($$, GetLocation ($2));
}
| parenthesized_expression MINUS multiplicative_expression
{
// Shift/Reduce conflict
$$ = new Binary (Binary.Operator.Subtraction, (Expression) $1, (Expression) $3, GetLocation ($2));
}
| additive_expression AS type
{
$$ = new As ((Expression) $1, (Expression) $3, GetLocation ($2));
@ -4000,13 +4017,13 @@ shift_expression @@ -4000,13 +4017,13 @@ shift_expression
: additive_expression
| shift_expression OP_SHIFT_LEFT additive_expression
{
$$ = new Binary (Binary.Operator.LeftShift,
(Expression) $1, (Expression) $3, GetLocation ($2));
$$ = new Binary (Binary.Operator.LeftShift, (Expression) $1, (Expression) $3);
lbag.AddLocation ($$, GetLocation ($2));
}
| shift_expression OP_SHIFT_RIGHT additive_expression
{
$$ = new Binary (Binary.Operator.RightShift,
(Expression) $1, (Expression) $3, GetLocation ($2));
$$ = new Binary (Binary.Operator.RightShift, (Expression) $1, (Expression) $3);
lbag.AddLocation ($$, GetLocation ($2));
}
;
@ -4014,23 +4031,23 @@ relational_expression @@ -4014,23 +4031,23 @@ relational_expression
: shift_expression
| relational_expression OP_LT shift_expression
{
$$ = new Binary (Binary.Operator.LessThan,
(Expression) $1, (Expression) $3, GetLocation ($2));
$$ = new Binary (Binary.Operator.LessThan, (Expression) $1, (Expression) $3);
lbag.AddLocation ($$, GetLocation ($2));
}
| relational_expression OP_GT shift_expression
{
$$ = new Binary (Binary.Operator.GreaterThan,
(Expression) $1, (Expression) $3, GetLocation ($2));
$$ = new Binary (Binary.Operator.GreaterThan, (Expression) $1, (Expression) $3);
lbag.AddLocation ($$, GetLocation ($2));
}
| relational_expression OP_LE shift_expression
{
$$ = new Binary (Binary.Operator.LessThanOrEqual,
(Expression) $1, (Expression) $3, GetLocation ($2));
$$ = new Binary (Binary.Operator.LessThanOrEqual, (Expression) $1, (Expression) $3);
lbag.AddLocation ($$, GetLocation ($2));
}
| relational_expression OP_GE shift_expression
{
$$ = new Binary (Binary.Operator.GreaterThanOrEqual,
(Expression) $1, (Expression) $3, GetLocation ($2));
$$ = new Binary (Binary.Operator.GreaterThanOrEqual, (Expression) $1, (Expression) $3);
lbag.AddLocation ($$, GetLocation ($2));
}
;
@ -4038,13 +4055,13 @@ equality_expression @@ -4038,13 +4055,13 @@ equality_expression
: relational_expression
| equality_expression OP_EQ relational_expression
{
$$ = new Binary (Binary.Operator.Equality,
(Expression) $1, (Expression) $3, GetLocation ($2));
$$ = new Binary (Binary.Operator.Equality, (Expression) $1, (Expression) $3);
lbag.AddLocation ($$, GetLocation ($2));
}
| equality_expression OP_NE relational_expression
{
$$ = new Binary (Binary.Operator.Inequality,
(Expression) $1, (Expression) $3, GetLocation ($2));
$$ = new Binary (Binary.Operator.Inequality, (Expression) $1, (Expression) $3);
lbag.AddLocation ($$, GetLocation ($2));
}
;
@ -4052,8 +4069,8 @@ and_expression @@ -4052,8 +4069,8 @@ and_expression
: equality_expression
| and_expression BITWISE_AND equality_expression
{
$$ = new Binary (Binary.Operator.BitwiseAnd,
(Expression) $1, (Expression) $3, GetLocation ($2));
$$ = new Binary (Binary.Operator.BitwiseAnd, (Expression) $1, (Expression) $3);
lbag.AddLocation ($$, GetLocation ($2));
}
;
@ -4061,8 +4078,8 @@ exclusive_or_expression @@ -4061,8 +4078,8 @@ exclusive_or_expression
: and_expression
| exclusive_or_expression CARRET and_expression
{
$$ = new Binary (Binary.Operator.ExclusiveOr,
(Expression) $1, (Expression) $3, GetLocation ($2));
$$ = new Binary (Binary.Operator.ExclusiveOr, (Expression) $1, (Expression) $3);
lbag.AddLocation ($$, GetLocation ($2));
}
;
@ -4070,8 +4087,8 @@ inclusive_or_expression @@ -4070,8 +4087,8 @@ inclusive_or_expression
: exclusive_or_expression
| inclusive_or_expression BITWISE_OR exclusive_or_expression
{
$$ = new Binary (Binary.Operator.BitwiseOr,
(Expression) $1, (Expression) $3, GetLocation ($2));
$$ = new Binary (Binary.Operator.BitwiseOr, (Expression) $1, (Expression) $3);
lbag.AddLocation ($$, GetLocation ($2));
}
;
@ -4079,8 +4096,8 @@ conditional_and_expression @@ -4079,8 +4096,8 @@ conditional_and_expression
: inclusive_or_expression
| conditional_and_expression OP_AND inclusive_or_expression
{
$$ = new Binary (Binary.Operator.LogicalAnd,
(Expression) $1, (Expression) $3, GetLocation ($2));
$$ = new Binary (Binary.Operator.LogicalAnd, (Expression) $1, (Expression) $3);
lbag.AddLocation ($$, GetLocation ($2));
}
;
@ -4088,8 +4105,8 @@ conditional_or_expression @@ -4088,8 +4105,8 @@ conditional_or_expression
: conditional_and_expression
| conditional_or_expression OP_OR conditional_and_expression
{
$$ = new Binary (Binary.Operator.LogicalOr,
(Expression) $1, (Expression) $3, GetLocation ($2));
$$ = new Binary (Binary.Operator.LogicalOr, (Expression) $1, (Expression) $3);
lbag.AddLocation ($$, GetLocation ($2));
}
;
@ -4100,7 +4117,8 @@ null_coalescing_expression @@ -4100,7 +4117,8 @@ null_coalescing_expression
if (lang_version < LanguageVersion.ISO_2)
FeatureIsNotAvailable (GetLocation ($2), "null coalescing operator");
$$ = new Nullable.NullCoalescingOperator ((Expression) $1, (Expression) $3, GetLocation ($2));
$$ = new Nullable.NullCoalescingOperator ((Expression) $1, (Expression) $3);
lbag.AddLocation ($$, GetLocation ($2));
}
;
@ -4121,57 +4139,58 @@ conditional_expression @@ -4121,57 +4139,58 @@ conditional_expression
assignment_expression
: prefixed_unary_expression ASSIGN expression
{
$$ = new SimpleAssign ((Expression) $1, (Expression) $3, GetLocation ($2));
$$ = new SimpleAssign ((Expression) $1, (Expression) $3);
lbag.AddLocation ($$, GetLocation ($2));
}
| prefixed_unary_expression OP_MULT_ASSIGN expression
{
$$ = new CompoundAssign (
Binary.Operator.Multiply, (Expression) $1, (Expression) $3, GetLocation ($2));
$$ = new CompoundAssign (Binary.Operator.Multiply, (Expression) $1, (Expression) $3);
lbag.AddLocation ($$, GetLocation ($2));
}
| prefixed_unary_expression OP_DIV_ASSIGN expression
{
$$ = new CompoundAssign (
Binary.Operator.Division, (Expression) $1, (Expression) $3, GetLocation ($2));
$$ = new CompoundAssign (Binary.Operator.Division, (Expression) $1, (Expression) $3);
lbag.AddLocation ($$, GetLocation ($2));
}
| prefixed_unary_expression OP_MOD_ASSIGN expression
{
$$ = new CompoundAssign (
Binary.Operator.Modulus, (Expression) $1, (Expression) $3, GetLocation ($2));
$$ = new CompoundAssign (Binary.Operator.Modulus, (Expression) $1, (Expression) $3);
lbag.AddLocation ($$, GetLocation ($2));
}
| prefixed_unary_expression OP_ADD_ASSIGN expression
{
$$ = new CompoundAssign (
Binary.Operator.Addition, (Expression) $1, (Expression) $3, GetLocation ($2));
$$ = new CompoundAssign (Binary.Operator.Addition, (Expression) $1, (Expression) $3);
lbag.AddLocation ($$, GetLocation ($2));
}
| prefixed_unary_expression OP_SUB_ASSIGN expression
{
$$ = new CompoundAssign (
Binary.Operator.Subtraction, (Expression) $1, (Expression) $3, GetLocation ($2));
$$ = new CompoundAssign (Binary.Operator.Subtraction, (Expression) $1, (Expression) $3);
lbag.AddLocation ($$, GetLocation ($2));
}
| prefixed_unary_expression OP_SHIFT_LEFT_ASSIGN expression
{
$$ = new CompoundAssign (
Binary.Operator.LeftShift, (Expression) $1, (Expression) $3, GetLocation ($2));
$$ = new CompoundAssign (Binary.Operator.LeftShift, (Expression) $1, (Expression) $3);
lbag.AddLocation ($$, GetLocation ($2));
}
| prefixed_unary_expression OP_SHIFT_RIGHT_ASSIGN expression
{
$$ = new CompoundAssign (
Binary.Operator.RightShift, (Expression) $1, (Expression) $3, GetLocation ($2));
$$ = new CompoundAssign (Binary.Operator.RightShift, (Expression) $1, (Expression) $3);
lbag.AddLocation ($$, GetLocation ($2));
}
| prefixed_unary_expression OP_AND_ASSIGN expression
{
$$ = new CompoundAssign (
Binary.Operator.BitwiseAnd, (Expression) $1, (Expression) $3, GetLocation ($2));
$$ = new CompoundAssign (Binary.Operator.BitwiseAnd, (Expression) $1, (Expression) $3);
lbag.AddLocation ($$, GetLocation ($2));
}
| prefixed_unary_expression OP_OR_ASSIGN expression
{
$$ = new CompoundAssign (
Binary.Operator.BitwiseOr, (Expression) $1, (Expression) $3, GetLocation ($2));
$$ = new CompoundAssign (Binary.Operator.BitwiseOr, (Expression) $1, (Expression) $3);
lbag.AddLocation ($$, GetLocation ($2));
}
| prefixed_unary_expression OP_XOR_ASSIGN expression
{
$$ = new CompoundAssign (
Binary.Operator.ExclusiveOr, (Expression) $1, (Expression) $3, GetLocation ($2));
$$ = new CompoundAssign (Binary.Operator.ExclusiveOr, (Expression) $1, (Expression) $3);
lbag.AddLocation ($$, GetLocation ($2));
}
;
@ -4965,7 +4984,7 @@ identifier_inside_body @@ -4965,7 +4984,7 @@ identifier_inside_body
{
if (async_block) {
report.Error (4003, GetLocation ($1), "`await' cannot be used as an identifier within an async method or lambda expression");
$$ = Tokenizer.LocatedToken.Create ("await", GetLocation ($1));
$$ = new Tokenizer.LocatedToken ("await", GetLocation ($1));
}
}
;
@ -5347,19 +5366,19 @@ while_statement @@ -5347,19 +5366,19 @@ while_statement
do_statement
: DO embedded_statement WHILE open_parens_any boolean_expression CLOSE_PARENS SEMICOLON
{
$$ = new Do ((Statement) $2, (BooleanExpression) $5, GetLocation ($1));
$$ = new Do ((Statement) $2, (BooleanExpression) $5, GetLocation ($1), GetLocation ($3));
lbag.AddStatement ($$, GetLocation ($3), GetLocation ($4), GetLocation ($6), GetLocation ($7));
}
| DO embedded_statement error
{
Error_SyntaxError (yyToken);
$$ = new Do ((Statement) $2, null, GetLocation ($1));
$$ = new Do ((Statement) $2, null, GetLocation ($1), Location.Null);
}
| DO embedded_statement WHILE open_parens_any boolean_expression error
{
Error_SyntaxError (yyToken);
$$ = new Do ((Statement) $2, (BooleanExpression) $5, GetLocation ($1));
$$ = new Do ((Statement) $2, (BooleanExpression) $5, GetLocation ($1), GetLocation ($3));
lbag.AddStatement ($$, GetLocation ($3), GetLocation ($4));
}
;
@ -5414,6 +5433,7 @@ for_statement_condition @@ -5414,6 +5433,7 @@ for_statement_condition
{
$$ = $4;
}
| boolean_expression CLOSE_PARENS {
report.Error (1525, GetLocation ($2), "Unexpected symbol ')', expected ';'");
For f = (For) $0;
@ -5627,6 +5647,11 @@ return_statement @@ -5627,6 +5647,11 @@ return_statement
$$ = new Return ((Expression) $2, GetLocation ($1));
lbag.AddStatement ($$, GetLocation ($3));
}
| RETURN expression error
{
Error_SyntaxError (yyToken);
$$ = new Return ((Expression) $2, GetLocation ($1));
}
| RETURN error
{
Error_SyntaxError (yyToken);
@ -5664,6 +5689,24 @@ yield_statement @@ -5664,6 +5689,24 @@ yield_statement
$$ = new Yield ((Expression) $3, lt.Location);
lbag.AddStatement ($$, GetLocation ($2), GetLocation ($4));
}
| identifier_inside_body RETURN expression error
{
Error_SyntaxError (yyToken);
var lt = (Tokenizer.LocatedToken) $1;
string s = lt.Value;
if (s != "yield"){
report.Error (1003, lt.Location, "; expected");
} else if ($3 == null) {
report.Error (1627, GetLocation ($4), "Expression expected after yield return");
} else if (lang_version == LanguageVersion.ISO_1){
FeatureIsNotAvailable (lt.Location, "iterators");
}
current_block.Explicit.RegisterIteratorYield ();
$$ = new Yield ((Expression) $3, lt.Location);
lbag.AddStatement ($$, GetLocation ($2));
}
| identifier_inside_body BREAK SEMICOLON
{
var lt = (Tokenizer.LocatedToken) $1;
@ -6762,17 +6805,12 @@ public Tokenizer Lexer { @@ -6762,17 +6805,12 @@ public Tokenizer Lexer {
}
}
static CSharpParser ()
{
oob_stack = new Stack<object> ();
}
public CSharpParser (SeekableStreamReader reader, CompilationSourceFile file)
: this (reader, file, file.Compiler.Report)
public CSharpParser (SeekableStreamReader reader, CompilationSourceFile file, ParserSession session)
: this (reader, file, file.Compiler.Report, session)
{
}
public CSharpParser (SeekableStreamReader reader, CompilationSourceFile file, Report report)
public CSharpParser (SeekableStreamReader reader, CompilationSourceFile file, Report report, ParserSession session)
{
this.file = file;
current_container = current_namespace = file;
@ -6785,22 +6823,16 @@ public CSharpParser (SeekableStreamReader reader, CompilationSourceFile file, Re @@ -6785,22 +6823,16 @@ public CSharpParser (SeekableStreamReader reader, CompilationSourceFile file, Re
lang_version = settings.Version;
yacc_verbose_flag = settings.VerboseParserFlag;
doc_support = settings.DocumentationFile != null;
oob_stack.Clear ();
lexer = new Tokenizer (reader, file);
#if FULL_AST
lbag = new LocationsBag ();
#else
lbag = null;
#endif
use_global_stacks = true;
lexer = new Tokenizer (reader, file, session);
oob_stack = new Stack<object> ();
lbag = session.LocationsBag;
use_global_stacks = session.UseJayGlobalArrays;
parameters_bucket = session.ParametersStack;
}
public void parse ()
{
eof_token = Token.EOF;
Tokenizer.LocatedToken.Initialize ();
try {
if (yacc_verbose_flag > 1)
@ -6867,12 +6899,6 @@ Location GetLocation (object obj) @@ -6867,12 +6899,6 @@ Location GetLocation (object obj)
return lexer.Location;
}
public LocationsBag LocationsBag {
get {
return lbag;
}
}
void start_block (Location loc)
{
if (current_block == null) {

284
ICSharpCode.NRefactory.CSharp/Parser/mcs/cs-tokenizer.cs

@ -16,6 +16,7 @@ using System.Text; @@ -16,6 +16,7 @@ using System.Text;
using System.Collections.Generic;
using System.Globalization;
using System.Diagnostics;
using System.Collections;
namespace Mono.CSharp
{
@ -66,32 +67,62 @@ namespace Mono.CSharp @@ -66,32 +67,62 @@ namespace Mono.CSharp
}
//
// This class has to be used in the parser only, it reuses token
// details after each parse
// This class has to be used by parser only, it reuses token
// details after each file parse completion
//
public class LocatedToken
{
int row, column;
string value;
public int row, column;
public string value;
public SourceFile file;
static LocatedToken[] buffer = new LocatedToken[0];
static int pos;
private LocatedToken ()
public LocatedToken ()
{
}
public static LocatedToken Create (int row, int column)
public LocatedToken (string value, Location loc)
{
return Create (null, row, column);
this.value = value;
file = loc.SourceFile;
row = loc.Row;
column = loc.Column;
}
public static LocatedToken Create (string value, Location loc)
public override string ToString ()
{
return Create (value, loc.Row, loc.Column);
return string.Format ("Token '{0}' at {1},{2}", Value, row, column);
}
public static LocatedToken Create (string value, int row, int column)
public Location Location {
get { return new Location (file, row, column); }
}
public string Value {
get { return value; }
}
}
public class LocatedTokenBuffer
{
readonly LocatedToken[] buffer;
public int pos;
public LocatedTokenBuffer ()
{
buffer = new LocatedToken[0];
}
public LocatedTokenBuffer (LocatedToken[] buffer)
{
this.buffer = buffer ?? new LocatedToken[0];
}
public LocatedToken Create (SourceFile file, int row, int column)
{
return Create (null, file, row, column);
}
public LocatedToken Create (string value, SourceFile file, int row, int column)
{
//
// TODO: I am not very happy about the logic but it's the best
@ -105,15 +136,16 @@ namespace Mono.CSharp @@ -105,15 +136,16 @@ namespace Mono.CSharp
if (pos >= buffer.Length) {
entry = new LocatedToken ();
} else {
entry = buffer [pos];
entry = buffer[pos];
if (entry == null) {
entry = new LocatedToken ();
buffer [pos] = entry;
buffer[pos] = entry;
}
++pos;
}
entry.value = value;
entry.file = file;
entry.row = row;
entry.column = column;
return entry;
@ -123,31 +155,9 @@ namespace Mono.CSharp @@ -123,31 +155,9 @@ namespace Mono.CSharp
// Used for token not required by expression evaluator
//
[Conditional ("FULL_AST")]
public static void CreateOptional (int row, int col, ref object token)
{
token = Create (row, col);
}
public static void Initialize ()
{
#if !FULL_AST
if (buffer.Length == 0)
buffer = new LocatedToken [15000];
#endif
pos = 0;
}
public override string ToString ()
public void CreateOptional (SourceFile file, int row, int col, ref object token)
{
return string.Format ("Token '{0}' at {1},{2}", Value, row, column);
}
public Location Location {
get { return new Location (row, column); }
}
public string Value {
get { return value; }
token = Create (file, row, col);
}
}
@ -174,6 +184,7 @@ namespace Mono.CSharp @@ -174,6 +184,7 @@ namespace Mono.CSharp
readonly SeekableStreamReader reader;
readonly CompilationSourceFile source_file;
public CompilationSourceFile SourceFile { get { return source_file; } }
readonly CompilerContext context;
SourceFile current_source;
@ -192,6 +203,7 @@ namespace Mono.CSharp @@ -192,6 +203,7 @@ namespace Mono.CSharp
List<Location> escaped_identifiers;
int parsing_generic_less_than;
readonly bool doc_processing;
readonly LocatedTokenBuffer ltb;
//
// Used mainly for parser optimizations. Some expressions for instance
@ -355,27 +367,15 @@ namespace Mono.CSharp @@ -355,27 +367,15 @@ namespace Mono.CSharp
//
Stack<int> ifstack;
const int max_id_size = 512;
const int max_number_size = 512;
#if FULL_AST
readonly char [] id_builder = new char [max_id_size];
Dictionary<char[], string>[] identifiers = new Dictionary<char[], string>[max_id_size + 1];
public const int MaxIdentifierLength = 512;
public const int MaxNumberLength = 512;
char [] number_builder = new char [max_number_size];
readonly char[] id_builder;
readonly Dictionary<char[], string>[] identifiers;
readonly char[] number_builder;
int number_pos;
char[] value_builder = new char[256];
#else
static readonly char [] id_builder = new char [max_id_size];
static Dictionary<char[], string>[] identifiers = new Dictionary<char[], string>[max_id_size + 1];
static char [] number_builder = new char [max_number_size];
static int number_pos;
static char[] value_builder = new char[256];
#endif
char[] value_builder = new char[64];
public int Line {
get {
@ -386,6 +386,15 @@ namespace Mono.CSharp @@ -386,6 +386,15 @@ namespace Mono.CSharp
}
}
public int Column {
get {
return col;
}
set {
col = value;
}
}
//
// This is used when the tokenizer needs to save
// the current position as it needs to do some parsing
@ -430,11 +439,15 @@ namespace Mono.CSharp @@ -430,11 +439,15 @@ namespace Mono.CSharp
}
}
public Tokenizer (SeekableStreamReader input, CompilationSourceFile file)
public Tokenizer (SeekableStreamReader input, CompilationSourceFile file, ParserSession session)
{
this.source_file = file;
this.context = file.Compiler;
this.current_source = file.SourceFile;
this.identifiers = session.Identifiers;
this.id_builder = session.IDBuilder;
this.number_builder = session.NumberBuilder;
this.ltb = new LocatedTokenBuffer (session.LocatedTokens);
reader = input;
@ -444,8 +457,6 @@ namespace Mono.CSharp @@ -444,8 +457,6 @@ namespace Mono.CSharp
doc_processing = context.Settings.DocumentationFile != null;
tab_size = context.Settings.TabSize;
Mono.CSharp.Location.Push (current_source);
}
public void PushPosition ()
@ -829,11 +840,13 @@ namespace Mono.CSharp @@ -829,11 +840,13 @@ namespace Mono.CSharp
PushPosition ();
xtoken ();
if (xtoken () != Token.ARROW)
res = -1;
goto default;
PopPosition ();
break;
default:
// peek_token could overwrite id_buffer
id_builder [0] = 'a'; id_builder [1] = 's'; id_builder [2] = 'y'; id_builder [3] = 'n'; id_builder [4] = 'c';
res = -1;
break;
}
@ -891,7 +904,7 @@ namespace Mono.CSharp @@ -891,7 +904,7 @@ namespace Mono.CSharp
public Location Location {
get {
return new Location (ref_line, col);
return new Location (current_source, ref_line, col);
}
}
@ -1104,9 +1117,14 @@ namespace Mono.CSharp @@ -1104,9 +1117,14 @@ namespace Mono.CSharp
start:
int the_token = token ();
if (the_token == Token.OPEN_BRACKET) {
do {
while (true) {
the_token = token ();
} while (the_token != Token.CLOSE_BRACKET);
if (the_token == Token.EOF)
return true;
if (the_token == Token.CLOSE_BRACKET)
break;
}
the_token = token ();
} else if (the_token == Token.IN || the_token == Token.OUT) {
the_token = token ();
@ -1319,7 +1337,7 @@ namespace Mono.CSharp @@ -1319,7 +1337,7 @@ namespace Mono.CSharp
bool seen_digits = false;
if (c != -1){
if (number_pos == max_number_size)
if (number_pos == MaxNumberLength)
Error_NumericConstantTooLong ();
number_builder [number_pos++] = (char) c;
}
@ -1330,7 +1348,7 @@ namespace Mono.CSharp @@ -1330,7 +1348,7 @@ namespace Mono.CSharp
//
while ((d = peek_char2 ()) != -1){
if (d >= '0' && d <= '9'){
if (number_pos == max_number_size)
if (number_pos == MaxNumberLength)
Error_NumericConstantTooLong ();
number_builder [number_pos++] = (char) d;
get_char ();
@ -1595,23 +1613,23 @@ namespace Mono.CSharp @@ -1595,23 +1613,23 @@ namespace Mono.CSharp
if (c == 'e' || c == 'E'){
is_real = true;
if (number_pos == max_number_size)
if (number_pos == MaxNumberLength)
Error_NumericConstantTooLong ();
number_builder [number_pos++] = (char) c;
c = get_char ();
if (c == '+'){
if (number_pos == max_number_size)
if (number_pos == MaxNumberLength)
Error_NumericConstantTooLong ();
number_builder [number_pos++] = '+';
c = -1;
} else if (c == '-') {
if (number_pos == max_number_size)
if (number_pos == MaxNumberLength)
Error_NumericConstantTooLong ();
number_builder [number_pos++] = '-';
c = -1;
} else {
if (number_pos == max_number_size)
if (number_pos == MaxNumberLength)
Error_NumericConstantTooLong ();
number_builder [number_pos++] = '+';
}
@ -1780,7 +1798,7 @@ namespace Mono.CSharp @@ -1780,7 +1798,7 @@ namespace Mono.CSharp
if (peek_char () == '\n') {
putback_char = -1;
}
x = '\n';
advance_line ();
} else if (x == '\n') {
@ -1791,6 +1809,26 @@ namespace Mono.CSharp @@ -1791,6 +1809,26 @@ namespace Mono.CSharp
return x;
}
int get_char_withwithoutskippingwindowseol ()
{
int x;
if (putback_char != -1) {
x = putback_char;
putback_char = -1;
} else {
x = reader.Read ();
}
if (x == '\r') {
} else if (x == '\n') {
advance_line ();
} else {
col++;
}
return x;
}
void advance_line ()
{
line++;
@ -1816,13 +1854,10 @@ namespace Mono.CSharp @@ -1816,13 +1854,10 @@ namespace Mono.CSharp
public void putback (int c)
{
if (putback_char != -1){
Console.WriteLine ("Col: " + col);
Console.WriteLine ("Row: " + line);
Console.WriteLine ("Name: " + current_source.Name);
Console.WriteLine ("Current [{0}] putting back [{1}] ", putback_char, c);
throw new Exception ("This should not happen putback on putback");
if (putback_char != -1) {
throw new InternalErrorException (string.Format ("Secondary putback [{0}] putting back [{1}] is not allowed", (char)putback_char, (char) c), Location);
}
if (c == '\n' || col == 0) {
// It won't happen though.
line--;
@ -1963,7 +1998,7 @@ namespace Mono.CSharp @@ -1963,7 +1998,7 @@ namespace Mono.CSharp
}
if (pos != 0) {
if (pos > max_id_size)
if (pos > MaxIdentifierLength)
arg = new string (value_builder, 0, pos);
else
arg = InternIdentifier (value_builder, pos);
@ -1998,7 +2033,6 @@ namespace Mono.CSharp @@ -1998,7 +2033,6 @@ namespace Mono.CSharp
}
//ref_line = line;
Location.Push (current_source);
return true;
}
@ -2085,7 +2119,6 @@ namespace Mono.CSharp @@ -2085,7 +2119,6 @@ namespace Mono.CSharp
if (new_file_name != null) {
current_source = context.LookupFile (source_file, new_file_name);
source_file.AddIncludeFile (current_source);
Location.Push (current_source);
}
if (!hidden_block_start.IsNull) {
@ -2183,6 +2216,8 @@ namespace Mono.CSharp @@ -2183,6 +2216,8 @@ namespace Mono.CSharp
//
// The syntax is ` "foo.txt" "{guid}" "hash"'
//
// guid is predefined hash algorithm guid {406ea660-64cf-4c82-b6f0-42d48172a799} for md5
//
int c = get_char ();
if (c != '"')
@ -2245,6 +2280,7 @@ namespace Mono.CSharp @@ -2245,6 +2280,7 @@ namespace Mono.CSharp
// Any length of checksum
List<byte> checksum_bytes = new List<byte> (16);
var checksum_location = Location;
c = peek_char ();
while (c != '"' && c != -1) {
checksum_bytes.Add (read_hex (out error));
@ -2260,14 +2296,23 @@ namespace Mono.CSharp @@ -2260,14 +2296,23 @@ namespace Mono.CSharp
return false;
}
file.SetChecksum (guid_bytes, checksum_bytes.ToArray ());
current_source.AutoGenerated = true;
if (context.Settings.GenerateDebugInfo) {
var chsum = checksum_bytes.ToArray ();
if (file.HasChecksum) {
if (!ArrayComparer.IsEqual (file.Checksum, chsum)) {
// TODO: Report.SymbolRelatedToPreviousError
Report.Warning (1697, 1, checksum_location, "Different checksum values specified for file `{0}'", file.Name);
}
}
file.SetChecksum (guid_bytes, chsum);
current_source.AutoGenerated = true;
}
return true;
}
#if !FULL_AST
static
#endif
bool IsTokenIdentifierEqual (char[] identifier)
{
for (int i = 0; i < identifier.Length; ++i) {
@ -2871,7 +2916,7 @@ namespace Mono.CSharp @@ -2871,7 +2916,7 @@ namespace Mono.CSharp
#endif
while (true){
c = get_char ();
c = get_char_withwithoutskippingwindowseol ();
if (c == '"') {
if (quoted && peek_char () == '"') {
if (pos == value_builder.Length)
@ -3009,7 +3054,7 @@ namespace Mono.CSharp @@ -3009,7 +3054,7 @@ namespace Mono.CSharp
if (id_builder [0] >= '_' && !quoted) {
int keyword = GetKeyword (id_builder, pos);
if (keyword != -1) {
val = LocatedToken.Create (keyword == Token.AWAIT ? "await" : null, ref_line, column);
val = ltb.Create (keyword == Token.AWAIT ? "await" : null, current_source, ref_line, column);
return keyword;
}
}
@ -3017,12 +3062,12 @@ namespace Mono.CSharp @@ -3017,12 +3062,12 @@ namespace Mono.CSharp
string s = InternIdentifier (id_builder, pos);
#if FULL_AST
if (quoted) {
val = LocatedToken.Create ("@" + s, ref_line, column - 1);
val = ltb.Create ("@" + s, current_source, ref_line, column - 1);
} else {
val = LocatedToken.Create (s, ref_line, column);
val = ltb.Create (s, current_source, ref_line, column);
}
#else
val = LocatedToken.Create (s, ref_line, column);
val = ltb.Create (s, current_source, ref_line, column);
#endif
if (quoted && parsing_attribute_section)
AddEscapedIdentifier (((LocatedToken) val).Location);
@ -3030,9 +3075,6 @@ namespace Mono.CSharp @@ -3030,9 +3075,6 @@ namespace Mono.CSharp
return Token.IDENTIFIER;
}
#if !FULL_AST
static
#endif
string InternIdentifier (char[] charBuffer, int length)
{
//
@ -3098,17 +3140,17 @@ namespace Mono.CSharp @@ -3098,17 +3140,17 @@ namespace Mono.CSharp
return consume_identifier (c);
case '{':
val = LocatedToken.Create (ref_line, col);
val = ltb.Create (current_source, ref_line, col);
return Token.OPEN_BRACE;
case '}':
val = LocatedToken.Create (ref_line, col);
val = ltb.Create (current_source, ref_line, col);
return Token.CLOSE_BRACE;
case '[':
// To block doccomment inside attribute declaration.
if (doc_state == XmlCommentState.Allowed)
doc_state = XmlCommentState.NotAllowed;
val = LocatedToken.Create (ref_line, col);
val = ltb.Create (current_source, ref_line, col);
if (parsing_block == 0 || lambda_arguments_parsing)
return Token.OPEN_BRACKET;
@ -3134,10 +3176,10 @@ namespace Mono.CSharp @@ -3134,10 +3176,10 @@ namespace Mono.CSharp
return Token.OPEN_BRACKET_EXPR;
}
case ']':
LocatedToken.CreateOptional (ref_line, col, ref val);
ltb.CreateOptional (current_source, ref_line, col, ref val);
return Token.CLOSE_BRACKET;
case '(':
val = LocatedToken.Create (ref_line, col);
val = ltb.Create (current_source, ref_line, col);
//
// An expression versions of parens can appear in block context only
//
@ -3182,29 +3224,29 @@ namespace Mono.CSharp @@ -3182,29 +3224,29 @@ namespace Mono.CSharp
return Token.OPEN_PARENS;
case ')':
LocatedToken.CreateOptional (ref_line, col, ref val);
ltb.CreateOptional (current_source, ref_line, col, ref val);
return Token.CLOSE_PARENS;
case ',':
LocatedToken.CreateOptional (ref_line, col, ref val);
ltb.CreateOptional (current_source, ref_line, col, ref val);
return Token.COMMA;
case ';':
LocatedToken.CreateOptional (ref_line, col, ref val);
ltb.CreateOptional (current_source, ref_line, col, ref val);
return Token.SEMICOLON;
case '~':
val = LocatedToken.Create (ref_line, col);
val = ltb.Create (current_source, ref_line, col);
return Token.TILDE;
case '?':
val = LocatedToken.Create (ref_line, col);
val = ltb.Create (current_source, ref_line, col);
return TokenizePossibleNullableType ();
case '<':
val = LocatedToken.Create (ref_line, col);
val = ltb.Create (current_source, ref_line, col);
if (parsing_generic_less_than++ > 0)
return Token.OP_GENERICS_LT;
return TokenizeLessThan ();
case '>':
val = LocatedToken.Create (ref_line, col);
val = ltb.Create (current_source, ref_line, col);
d = peek_char ();
if (d == '=') {
@ -3231,7 +3273,7 @@ namespace Mono.CSharp @@ -3231,7 +3273,7 @@ namespace Mono.CSharp
return Token.OP_GT;
case '+':
val = LocatedToken.Create (ref_line, col);
val = ltb.Create (current_source, ref_line, col);
d = peek_char ();
if (d == '+') {
d = Token.OP_INC;
@ -3244,7 +3286,7 @@ namespace Mono.CSharp @@ -3244,7 +3286,7 @@ namespace Mono.CSharp
return d;
case '-':
val = LocatedToken.Create (ref_line, col);
val = ltb.Create (current_source, ref_line, col);
d = peek_char ();
if (d == '-') {
d = Token.OP_DEC;
@ -3259,15 +3301,15 @@ namespace Mono.CSharp @@ -3259,15 +3301,15 @@ namespace Mono.CSharp
return d;
case '!':
val = LocatedToken.Create (ref_line, col);
if (peek_char () == '=') {
val = ltb.Create (current_source, ref_line, col);
if (peek_char () == '='){
get_char ();
return Token.OP_NE;
}
return Token.BANG;
case '=':
val = LocatedToken.Create (ref_line, col);
val = ltb.Create (current_source, ref_line, col);
d = peek_char ();
if (d == '=') {
get_char ();
@ -3281,7 +3323,7 @@ namespace Mono.CSharp @@ -3281,7 +3323,7 @@ namespace Mono.CSharp
return Token.ASSIGN;
case '&':
val = LocatedToken.Create (ref_line, col);
val = ltb.Create (current_source, ref_line, col);
d = peek_char ();
if (d == '&') {
get_char ();
@ -3294,7 +3336,7 @@ namespace Mono.CSharp @@ -3294,7 +3336,7 @@ namespace Mono.CSharp
return Token.BITWISE_AND;
case '|':
val = LocatedToken.Create (ref_line, col);
val = ltb.Create (current_source, ref_line, col);
d = peek_char ();
if (d == '|') {
get_char ();
@ -3307,8 +3349,8 @@ namespace Mono.CSharp @@ -3307,8 +3349,8 @@ namespace Mono.CSharp
return Token.BITWISE_OR;
case '*':
val = LocatedToken.Create (ref_line, col);
if (peek_char () == '=') {
val = ltb.Create (current_source, ref_line, col);
if (peek_char () == '='){
get_char ();
return Token.OP_MULT_ASSIGN;
}
@ -3316,8 +3358,8 @@ namespace Mono.CSharp @@ -3316,8 +3358,8 @@ namespace Mono.CSharp
case '/':
d = peek_char ();
if (d == '=') {
val = LocatedToken.Create (ref_line, col);
if (d == '='){
val = ltb.Create (current_source, ref_line, col);
get_char ();
return Token.OP_DIV_ASSIGN;
}
@ -3426,11 +3468,11 @@ namespace Mono.CSharp @@ -3426,11 +3468,11 @@ namespace Mono.CSharp
update_formatted_doc_comment (current_comment_start);
continue;
}
val = LocatedToken.Create (ref_line, col);
val = ltb.Create (current_source, ref_line, col);
return Token.DIV;
case '%':
val = LocatedToken.Create (ref_line, col);
val = ltb.Create (current_source, ref_line, col);
if (peek_char () == '='){
get_char ();
return Token.OP_MOD_ASSIGN;
@ -3438,7 +3480,7 @@ namespace Mono.CSharp @@ -3438,7 +3480,7 @@ namespace Mono.CSharp
return Token.PERCENT;
case '^':
val = LocatedToken.Create (ref_line, col);
val = ltb.Create (current_source, ref_line, col);
if (peek_char () == '='){
get_char ();
return Token.OP_XOR_ASSIGN;
@ -3446,7 +3488,7 @@ namespace Mono.CSharp @@ -3446,7 +3488,7 @@ namespace Mono.CSharp
return Token.CARRET;
case ':':
val = LocatedToken.Create (ref_line, col);
val = ltb.Create (current_source, ref_line, col);
if (peek_char () == ':') {
get_char ();
return Token.DOUBLE_COLON;
@ -3470,7 +3512,7 @@ namespace Mono.CSharp @@ -3470,7 +3512,7 @@ namespace Mono.CSharp
if (d >= '0' && d <= '9')
return is_number (c);
LocatedToken.CreateOptional (ref_line, col, ref val);
ltb.CreateOptional (current_source, ref_line, col, ref val);
return Token.DOT;
case '#':

11
ICSharpCode.NRefactory.CSharp/Parser/mcs/decl.cs

@ -608,7 +608,7 @@ namespace Mono.CSharp { @@ -608,7 +608,7 @@ namespace Mono.CSharp {
if (al == Modifiers.PRIVATE) {
var decl = mc.Parent;
do {
same_access_restrictions = decl.CurrentType == p_parent;
same_access_restrictions = decl.CurrentType.MemberDefinition == p_parent.MemberDefinition;
} while (!same_access_restrictions && !decl.PartialContainer.IsTopLevel && (decl = decl.Parent) != null);
}
@ -945,6 +945,15 @@ namespace Mono.CSharp { @@ -945,6 +945,15 @@ namespace Mono.CSharp {
GenericTask = 1 << 22
}
//
// Some flags can be copied directly from other member
//
protected const StateFlags SharedStateFlags =
StateFlags.CLSCompliant | StateFlags.CLSCompliant_Undetected |
StateFlags.Obsolete | StateFlags.Obsolete_Undetected |
StateFlags.MissingDependency | StateFlags.MissingDependency_Undetected |
StateFlags.HasDynamicElement;
protected Modifiers modifiers;
public StateFlags state;
protected IMemberDefinition definition;

5
ICSharpCode.NRefactory.CSharp/Parser/mcs/delegate.cs

@ -520,8 +520,11 @@ namespace Mono.CSharp { @@ -520,8 +520,11 @@ namespace Mono.CSharp {
}
TypeSpec rt = delegate_method.ReturnType;
if (rt.BuiltinType == BuiltinTypeSpec.Type.Dynamic)
rt = ec.BuiltinTypes.Object;
if (!Delegate.IsTypeCovariant (ec, rt, invoke_method.ReturnType)) {
Expression ret_expr = new TypeExpression (rt, loc);
Expression ret_expr = new TypeExpression (delegate_method.ReturnType, loc);
Error_ConversionFailed (ec, delegate_method, ret_expr);
}

14
ICSharpCode.NRefactory.CSharp/Parser/mcs/doc.cs

@ -47,6 +47,8 @@ namespace Mono.CSharp @@ -47,6 +47,8 @@ namespace Mono.CSharp
//
Dictionary<string, XmlDocument> StoredDocuments = new Dictionary<string, XmlDocument> ();
ParserSession session;
public DocumentationBuilder (ModuleContainer module)
{
doc_module = new ModuleContainer (module.Compiler);
@ -324,12 +326,18 @@ namespace Mono.CSharp @@ -324,12 +326,18 @@ namespace Mono.CSharp
var encoding = module.Compiler.Settings.Encoding;
var s = new MemoryStream (encoding.GetBytes (cref));
SeekableStreamReader seekable = new SeekableStreamReader (s, encoding);
var source_file = new CompilationSourceFile (doc_module);
var source_file = new CompilationSourceFile (doc_module, mc.Location.SourceFile);
var report = new Report (doc_module.Compiler, new NullReportPrinter ());
var parser = new CSharpParser (seekable, source_file, report);
if (session == null)
session = new ParserSession () {
UseJayGlobalArrays = true
};
SeekableStreamReader seekable = new SeekableStreamReader (s, encoding, session.StreamReaderBuffer);
var parser = new CSharpParser (seekable, source_file, report, session);
ParsedParameters = null;
ParsedName = null;
ParsedBuiltinType = null;

75
ICSharpCode.NRefactory.CSharp/Parser/mcs/driver.cs

@ -20,6 +20,7 @@ using System.IO; @@ -20,6 +20,7 @@ using System.IO;
using System.Text;
using System.Globalization;
using System.Diagnostics;
using System.Threading;
namespace Mono.CSharp
{
@ -41,7 +42,7 @@ namespace Mono.CSharp @@ -41,7 +42,7 @@ namespace Mono.CSharp
}
}
void tokenize_file (SourceFile sourceFile, ModuleContainer module)
void tokenize_file (SourceFile sourceFile, ModuleContainer module, ParserSession session)
{
Stream input;
@ -56,7 +57,7 @@ namespace Mono.CSharp @@ -56,7 +57,7 @@ namespace Mono.CSharp
SeekableStreamReader reader = new SeekableStreamReader (input, ctx.Settings.Encoding);
var file = new CompilationSourceFile (module, sourceFile);
Tokenizer lexer = new Tokenizer (reader, file);
Tokenizer lexer = new Tokenizer (reader, file, session);
int token, tokens = 0, errors = 0;
while ((token = lexer.token ()) != Token.EOF){
@ -77,49 +78,97 @@ namespace Mono.CSharp @@ -77,49 +78,97 @@ namespace Mono.CSharp
Location.Initialize (sources);
var session = new ParserSession () {
UseJayGlobalArrays = true,
LocatedTokens = new Tokenizer.LocatedToken[15000]
};
for (int i = 0; i < sources.Count; ++i) {
if (tokenize_only) {
tokenize_file (sources[i], module);
tokenize_file (sources[i], module, session);
} else {
Parse (sources[i], module);
Parse (sources[i], module, session, Report);
}
}
}
public void Parse (SourceFile file, ModuleContainer module)
#if false
void ParseParallel (ModuleContainer module)
{
var sources = module.Compiler.SourceFiles;
Location.Initialize (sources);
var pcount = Environment.ProcessorCount;
var threads = new Thread[System.Math.Max (2, pcount - 1)];
for (int i = 0; i < threads.Length; ++i) {
var t = new Thread (l => {
var session = new ParserSession () {
//UseJayGlobalArrays = true,
};
var report = new Report (ctx, Report.Printer); // TODO: Implement flush at once printer
for (int ii = (int) l; ii < sources.Count; ii += threads.Length) {
Parse (sources[ii], module, session, report);
}
// TODO: Merge warning regions
});
t.Start (i);
threads[i] = t;
}
for (int t = 0; t < threads.Length; ++t) {
threads[t].Join ();
}
}
#endif
public void Parse (SourceFile file, ModuleContainer module, ParserSession session, Report report)
{
Stream input;
try {
input = File.OpenRead (file.Name);
} catch {
Report.Error (2001, "Source file `{0}' could not be found", file.Name);
report.Error (2001, "Source file `{0}' could not be found", file.Name);
return;
}
// Check 'MZ' header
if (input.ReadByte () == 77 && input.ReadByte () == 90) {
Report.Error (2015, "Source file `{0}' is a binary file and not a text file", file.Name);
report.Error (2015, "Source file `{0}' is a binary file and not a text file", file.Name);
input.Close ();
return;
}
input.Position = 0;
SeekableStreamReader reader = new SeekableStreamReader (input, ctx.Settings.Encoding);
SeekableStreamReader reader = new SeekableStreamReader (input, ctx.Settings.Encoding, session.StreamReaderBuffer);
Parse (reader, file, module, session, report);
if (ctx.Settings.GenerateDebugInfo && report.Errors == 0 && !file.HasChecksum) {
input.Position = 0;
var checksum = session.GetChecksumAlgorithm ();
file.SetChecksum (checksum.ComputeHash (input));
}
Parse (reader, file, module);
reader.Dispose ();
input.Close ();
}
public static CSharpParser Parse(SeekableStreamReader reader, SourceFile sourceFile, ModuleContainer module, int lineModifier = 0)
public static CSharpParser Parse (SeekableStreamReader reader, SourceFile sourceFile, ModuleContainer module, ParserSession session, Report report, int lineModifier = 0, int colModifier = 0)
{
var file = new CompilationSourceFile (module, sourceFile);
module.AddTypeContainer(file);
CSharpParser parser = new CSharpParser (reader, file);
CSharpParser parser = new CSharpParser (reader, file, report, session);
parser.Lexer.Line += lineModifier;
parser.Lexer.Column += colModifier;
parser.Lexer.sbag = new SpecialsBag ();
parser.parse ();
return parser;
@ -347,7 +396,8 @@ namespace Mono.CSharp @@ -347,7 +396,8 @@ namespace Mono.CSharp
tr.Stop (TimeReporter.TimerType.CloseTypes);
tr.Start (TimeReporter.TimerType.Resouces);
assembly.EmbedResources ();
if (!settings.WriteMetadataOnly)
assembly.EmbedResources ();
tr.Stop (TimeReporter.TimerType.Resouces);
if (Report.Errors > 0)
@ -369,6 +419,7 @@ namespace Mono.CSharp @@ -369,6 +419,7 @@ namespace Mono.CSharp
public ModuleContainer ModuleCompiled { get; set; }
public LocationsBag LocationsBag { get; set; }
public SpecialsBag SpecialsBag { get; set; }
public IEnumerable<string> Conditionals { get; set; }
public object LastYYValue { get; set; }
}

2
ICSharpCode.NRefactory.CSharp/Parser/mcs/dynamic.cs

@ -502,7 +502,7 @@ namespace Mono.CSharp @@ -502,7 +502,7 @@ namespace Mono.CSharp
using (ec.With (BuilderContext.Options.OmitDebugInfo, true)) {
if (s.Resolve (bc)) {
Statement init = new If (new Binary (Binary.Operator.Equality, site_field_expr, new NullLiteral (loc), loc), s, loc);
Statement init = new If (new Binary (Binary.Operator.Equality, site_field_expr, new NullLiteral (loc)), s, loc);
init.Emit (ec);
}

465
ICSharpCode.NRefactory.CSharp/Parser/mcs/ecore.cs

@ -2277,9 +2277,11 @@ namespace Mono.CSharp { @@ -2277,9 +2277,11 @@ namespace Mono.CSharp {
}
}
var report = ctx.Module.Compiler.Report;
var retval = ctx.LookupNamespaceOrType (Name, Arity, LookupMode.IgnoreAccessibility, loc);
if (retval != null) {
ctx.Module.Compiler.Report.SymbolRelatedToPreviousError (retval.Type);
report.SymbolRelatedToPreviousError (retval.Type);
ErrorIsInaccesible (ctx, retval.GetSignatureForError (), loc);
return;
}
@ -2290,7 +2292,17 @@ namespace Mono.CSharp { @@ -2290,7 +2292,17 @@ namespace Mono.CSharp {
return;
}
NamespaceContainer.Error_NamespaceNotFound (loc, Name, ctx.Module.Compiler.Report);
var ns_candidates = ctx.Module.GlobalRootNamespace.FindTypeNamespaces (ctx, Name, Arity);
if (ns_candidates != null) {
string usings = string.Join ("' or `", ns_candidates.ToArray ());
report.Error (246, loc,
"The type or namespace name `{0}' could not be found. Are you missing `{1}' using directive?",
Name, usings);
} else {
report.Error (246, loc,
"The type or namespace name `{0}' could not be found. Are you missing an assembly reference?",
Name);
}
}
public override FullNamedExpression ResolveAsTypeOrNamespace (IMemberContext ec)
@ -2401,7 +2413,7 @@ namespace Mono.CSharp { @@ -2401,7 +2413,7 @@ namespace Mono.CSharp {
} else {
break;
}
} else if (me is MethodGroupExpr) {
} else if (me is MethodGroupExpr || me is PropertyExpr || me is IndexerExpr) {
// Leave it to overload resolution to report correct error
} else {
// TODO: rc.Report.SymbolRelatedToPreviousError ()
@ -2777,8 +2789,14 @@ namespace Mono.CSharp { @@ -2777,8 +2789,14 @@ namespace Mono.CSharp {
}
}
// TODO: For now we do it for any hoisted call even if it's needed for
// hoisted stories only but that requires a new expression wrapper
//
// When base access is used inside anonymous method/iterator/etc we need to
// get back to the context of original type. We do it by emiting proxy
// method in original class and rewriting base call to this compiler
// generated method call which does the actual base invocation. This may
// introduce redundant storey but with `this' only but it's tricky to avoid
// at this stage as we don't know what expressions follow base
//
if (rc.CurrentAnonymousMethod != null) {
if (targs == null && method.IsGeneric) {
targs = method.TypeArguments;
@ -2792,8 +2810,9 @@ namespace Mono.CSharp { @@ -2792,8 +2810,9 @@ namespace Mono.CSharp {
// Ideally this should apply to any proxy rewrite but in the case of unary mutators on
// get/set member expressions second call would fail to proxy because left expression
// would be of 'this' and not 'base'
if (rc.CurrentType.IsStruct)
// would be of 'this' and not 'base' because we share InstanceExpression for get/set
// FIXME: The async check is another hack but will probably fail with mutators
if (rc.CurrentType.IsStruct || rc.CurrentAnonymousMethod.Storey is AsyncTaskStorey)
InstanceExpression = new This (loc).Resolve (rc);
}
@ -2967,7 +2986,7 @@ namespace Mono.CSharp { @@ -2967,7 +2986,7 @@ namespace Mono.CSharp {
"An object reference is required to access non-static member `{0}'",
GetSignatureForError ());
InstanceExpression = new CompilerGeneratedThis (type, loc).Resolve (rc);
InstanceExpression = new CompilerGeneratedThis (rc.CurrentType, loc).Resolve (rc);
return false;
}
@ -2993,12 +3012,15 @@ namespace Mono.CSharp { @@ -2993,12 +3012,15 @@ namespace Mono.CSharp {
if (me != null) {
me.ResolveInstanceExpression (rc, rhs);
var fe = me as FieldExpr;
if (fe != null && fe.IsMarshalByRefAccess (rc)) {
rc.Report.SymbolRelatedToPreviousError (me.DeclaringType);
rc.Report.Warning (1690, 1, loc,
"Cannot call methods, properties, or indexers on `{0}' because it is a value type member of a marshal-by-reference class",
me.GetSignatureForError ());
// Using this check to detect probing instance expression resolve
if (!rc.OmitStructFlowAnalysis) {
var fe = me as FieldExpr;
if (fe != null && fe.IsMarshalByRefAccess (rc)) {
rc.Report.SymbolRelatedToPreviousError (me.DeclaringType);
rc.Report.Warning (1690, 1, loc,
"Cannot call methods, properties, or indexers on `{0}' because it is a value type member of a marshal-by-reference class",
me.GetSignatureForError ());
}
}
return true;
@ -3166,8 +3188,12 @@ namespace Mono.CSharp { @@ -3166,8 +3188,12 @@ namespace Mono.CSharp {
}
var me = ExtensionExpression as MemberExpr;
if (me != null)
if (me != null) {
me.ResolveInstanceExpression (ec, null);
var fe = me as FieldExpr;
if (fe != null)
fe.Spec.MemberDefinition.SetIsUsed ();
}
InstanceExpression = null;
return this;
@ -3437,11 +3463,35 @@ namespace Mono.CSharp { @@ -3437,11 +3463,35 @@ namespace Mono.CSharp {
best_candidate_return = best_candidate.ReturnType;
}
if (best_candidate.IsGeneric && TypeParameterSpec.HasAnyTypeParameterConstrained (best_candidate.GenericDefinition)) {
ConstraintChecker cc = new ConstraintChecker (ec);
cc.CheckAll (best_candidate.GetGenericMethodDefinition (), best_candidate.TypeArguments, best_candidate.Constraints, loc);
}
//
// Additional check for possible imported base override method which
// could not be done during IsOverrideMethodBaseTypeAccessible
//
if (best_candidate.IsVirtual && (best_candidate.DeclaringType.Modifiers & Modifiers.PROTECTED) != 0 &&
best_candidate.MemberDefinition.IsImported && !best_candidate.DeclaringType.IsAccessible (ec)) {
ec.Report.SymbolRelatedToPreviousError (best_candidate);
ErrorIsInaccesible (ec, best_candidate.GetSignatureForError (), loc);
}
return this;
}
public override MemberExpr ResolveMemberAccess (ResolveContext ec, Expression left, SimpleName original)
{
var fe = left as FieldExpr;
if (fe != null) {
//
// Using method-group on struct fields makes the struct assigned. I am not sure
// why but that's what .net does
//
fe.Spec.MemberDefinition.SetIsAssigned ();
}
simple_name = original;
return base.ResolveMemberAccess (ec, left, original);
}
@ -3587,7 +3637,6 @@ namespace Mono.CSharp { @@ -3587,7 +3637,6 @@ namespace Mono.CSharp {
TypeSpec best_candidate_return_type;
SessionReportPrinter lambda_conv_msgs;
ReportPrinter prev_recorder;
public OverloadResolver (IList<MemberSpec> members, Restrictions restrictions, Location loc)
: this (members, null, restrictions, loc)
@ -3720,7 +3769,9 @@ namespace Mono.CSharp { @@ -3720,7 +3769,9 @@ namespace Mono.CSharp {
if (!TypeSpecComparer.Equals (p_m.Parameters.Types, q_m.Parameters.Types))
return 0;
var orig_p = p;
p = p_m.ReturnType;
var orig_q = q;
q = q_m.ReturnType;
//
@ -3737,14 +3788,14 @@ namespace Mono.CSharp { @@ -3737,14 +3788,14 @@ namespace Mono.CSharp {
return p.Kind != MemberKind.Void ? 1: 0;
}
var am = (AnonymousMethodExpression) a.Expr;
//
// When anonymous method is an asynchronous, and P has a return type Task<Y1>, and Q has a return type Task<Y2>
// better conversion is performed between underlying types Y1 and Y2
//
if (p.IsGenericTask || q.IsGenericTask) {
var async_am = a.Expr as AnonymousMethodExpression;
if (async_am != null && async_am.Block.IsAsync) {
if (am.Block.IsAsync) {
if (p.IsGenericTask != q.IsGenericTask) {
return 0;
}
@ -3752,6 +3803,19 @@ namespace Mono.CSharp { @@ -3752,6 +3803,19 @@ namespace Mono.CSharp {
q = q.TypeArguments[0];
p = p.TypeArguments[0];
}
} else if (q != p) {
//
// LAMESPEC: Lambda expression returning dynamic type has identity (better) conversion to delegate returning object type
//
if (q.BuiltinType == BuiltinTypeSpec.Type.Object) {
var am_rt = am.InferReturnType (ec, null, orig_q);
if (am_rt != null && am_rt.BuiltinType == BuiltinTypeSpec.Type.Dynamic)
return 2;
} else if (p.BuiltinType == BuiltinTypeSpec.Type.Object) {
var am_rt = am.InferReturnType (ec, null, orig_p);
if (am_rt != null && am_rt.BuiltinType == BuiltinTypeSpec.Type.Dynamic)
return 1;
}
}
//
@ -4030,6 +4094,32 @@ namespace Mono.CSharp { @@ -4030,6 +4094,32 @@ namespace Mono.CSharp {
return false;
}
static bool CheckInflatedArguments (MethodSpec ms)
{
if (!TypeParameterSpec.HasAnyTypeParameterTypeConstrained (ms.GenericDefinition))
return true;
// Setup constraint checker for probing only
ConstraintChecker cc = new ConstraintChecker (null);
var mp = ms.Parameters.Types;
for (int i = 0; i < mp.Length; ++i) {
var type = mp[i] as InflatedTypeSpec;
if (type == null)
continue;
var targs = type.TypeArguments;
if (targs.Length == 0)
continue;
// TODO: Checking inflated MVAR arguments should be enough
if (!cc.CheckAll (type.GetDefinition (), targs, type.Constraints, Location.Null))
return false;
}
return true;
}
public static void Error_ConstructorMismatch (ResolveContext rc, TypeSpec type, int argCount, Location loc)
{
rc.Report.Error (1729, loc,
@ -4045,6 +4135,7 @@ namespace Mono.CSharp { @@ -4045,6 +4135,7 @@ namespace Mono.CSharp {
//
// A return value rates candidate method compatibility,
// 0 = the best, int.MaxValue = the worst
// -1 = fatal error
//
int IsApplicable (ResolveContext ec, ref Arguments arguments, int arg_count, ref MemberSpec candidate, IParametersMember pm, ref bool params_expanded_form, ref bool dynamicArgument, ref TypeSpec returnType)
{
@ -4166,15 +4257,24 @@ namespace Mono.CSharp { @@ -4166,15 +4257,24 @@ namespace Mono.CSharp {
arg_count = arguments.Count;
}
//
// Don't do any expensive checks when the candidate cannot succeed
//
if (arg_count != param_count && !cpd.HasParams)
return (param_count - arg_count) * 2 + 1;
var dep = candidate.GetMissingDependencies ();
if (dep != null) {
ImportedTypeDefinition.Error_MissingDependency (ec, dep, loc);
return -1;
}
//
// 1. Handle generic method using type arguments when specified or type inference
//
TypeSpec[] ptypes;
var ms = candidate as MethodSpec;
if (ms != null && ms.IsGeneric) {
// Setup constraint checker for probing only
ConstraintChecker cc = new ConstraintChecker (null);
if (type_arguments != null) {
var g_args_count = ms.Arity;
if (g_args_count != type_arguments.Count)
@ -4182,31 +4282,50 @@ namespace Mono.CSharp { @@ -4182,31 +4282,50 @@ namespace Mono.CSharp {
ms = ms.MakeGenericMethod (ec, type_arguments.Arguments);
} else {
// TODO: It should not be here (we don't know yet whether any argument is lambda) but
// for now it simplifies things. I should probably add a callback to ResolveContext
//
// Deploy custom error reporting for infered anonymous expression or lambda methods. When
// probing lambda methods keep all errors reported in separate set and once we are done and no best
// candidate was found use the set to report more details about what was wrong with lambda body.
// The general idea is to distinguish between code errors and errors caused by
// trial-and-error type inference
//
if (lambda_conv_msgs == null) {
lambda_conv_msgs = new SessionReportPrinter ();
prev_recorder = ec.Report.SetPrinter (lambda_conv_msgs);
for (int i = 0; i < arg_count; i++) {
Argument a = arguments[i];
if (a == null)
continue;
var am = a.Expr as AnonymousMethodExpression;
if (am != null) {
if (lambda_conv_msgs == null)
lambda_conv_msgs = new SessionReportPrinter ();
am.TypeInferenceReportPrinter = lambda_conv_msgs;
}
}
}
var ti = new TypeInference (arguments);
TypeSpec[] i_args = ti.InferMethodArguments (ec, ms);
lambda_conv_msgs.EndSession ();
if (i_args == null)
return ti.InferenceScore - 20000;
//
// Clear any error messages when the result was success
//
if (lambda_conv_msgs != null)
lambda_conv_msgs.ClearSession ();
if (i_args.Length != 0) {
ms = ms.MakeGenericMethod (ec, i_args);
}
cc.IgnoreInferredDynamic = true;
}
//
// Type arguments constraints have to match for the method to be applicable
//
if (!cc.CheckAll (ms.GetGenericMethodDefinition (), ms.TypeArguments, ms.Constraints, loc)) {
if (!CheckInflatedArguments (ms)) {
candidate = ms;
return int.MaxValue - 25000;
}
@ -4403,28 +4522,11 @@ namespace Mono.CSharp { @@ -4403,28 +4522,11 @@ namespace Mono.CSharp {
if (argument.Type.BuiltinType == BuiltinTypeSpec.Type.Dynamic && (restrictions & Restrictions.CovariantDelegate) == 0)
return -1;
//
// Deploy custom error reporting for lambda methods. When probing lambda methods
// keep all errors reported in separate set and once we are done and no best
// candidate was found, this set is used to report more details about what was wrong
// with lambda body
//
if (argument.Expr.Type == InternalType.AnonymousMethod) {
if (lambda_conv_msgs == null) {
lambda_conv_msgs = new SessionReportPrinter ();
prev_recorder = ec.Report.SetPrinter (lambda_conv_msgs);
}
}
//
// Use implicit conversion in all modes to return same candidates when the expression
// is used as argument or delegate conversion
//
if (!Convert.ImplicitConversionExists (ec, argument.Expr, parameter)) {
if (lambda_conv_msgs != null) {
lambda_conv_msgs.EndSession ();
}
return 2;
}
}
@ -4450,7 +4552,7 @@ namespace Mono.CSharp { @@ -4450,7 +4552,7 @@ namespace Mono.CSharp {
return p;
if (specific == ac_q.Element)
return q;
} else if (TypeManager.IsGenericType (p)) {
} else if (p.IsGeneric && q.IsGeneric) {
var pargs = TypeManager.GetTypeArguments (p);
var qargs = TypeManager.GetTypeArguments (q);
@ -4494,147 +4596,148 @@ namespace Mono.CSharp { @@ -4494,147 +4596,148 @@ namespace Mono.CSharp {
bool error_mode = false;
MemberSpec invocable_member = null;
// Be careful, cannot return until error reporter is restored
while (true) {
best_candidate = null;
best_candidate_rate = int.MaxValue;
var type_members = members;
try {
do {
for (int i = 0; i < type_members.Count; ++i) {
var member = type_members[i];
do {
for (int i = 0; i < type_members.Count; ++i) {
var member = type_members[i];
//
// Methods in a base class are not candidates if any method in a derived
// class is applicable
//
if ((member.Modifiers & Modifiers.OVERRIDE) != 0)
continue;
if (!error_mode) {
if (!member.IsAccessible (rc))
continue;
if (rc.IsRuntimeBinder && !member.DeclaringType.IsAccessible (rc))
continue;
if ((member.Modifiers & (Modifiers.PROTECTED | Modifiers.STATIC)) == Modifiers.PROTECTED &&
instance_qualifier != null && !instance_qualifier.CheckProtectedMemberAccess (rc, member)) {
continue;
}
}
IParametersMember pm = member as IParametersMember;
if (pm == null) {
//
// Methods in a base class are not candidates if any method in a derived
// class is applicable
// Will use it later to report ambiguity between best method and invocable member
//
if ((member.Modifiers & Modifiers.OVERRIDE) != 0)
continue;
if (Invocation.IsMemberInvocable (member))
invocable_member = member;
if (!error_mode) {
if (!member.IsAccessible (rc))
continue;
continue;
}
if (rc.IsRuntimeBinder && !member.DeclaringType.IsAccessible (rc))
continue;
//
// Overload resolution is looking for base member but using parameter names
// and default values from the closest member. That means to do expensive lookup
// for the closest override for virtual or abstract members
//
if ((member.Modifiers & (Modifiers.VIRTUAL | Modifiers.ABSTRACT)) != 0) {
var override_params = base_provider.GetOverrideMemberParameters (member);
if (override_params != null)
pm = override_params;
}
if ((member.Modifiers & (Modifiers.PROTECTED | Modifiers.STATIC)) == Modifiers.PROTECTED &&
instance_qualifier != null && !instance_qualifier.CheckProtectedMemberAccess (rc, member)) {
//
// Check if the member candidate is applicable
//
bool params_expanded_form = false;
bool dynamic_argument = false;
TypeSpec rt = pm.MemberType;
int candidate_rate = IsApplicable (rc, ref candidate_args, args_count, ref member, pm, ref params_expanded_form, ref dynamic_argument, ref rt);
if (lambda_conv_msgs != null)
lambda_conv_msgs.EndSession ();
//
// How does it score compare to others
//
if (candidate_rate < best_candidate_rate) {
// Fatal error (missing dependency), cannot continue
if (candidate_rate < 0)
return null;
best_candidate_rate = candidate_rate;
best_candidate = member;
best_candidate_args = candidate_args;
best_candidate_params = params_expanded_form;
best_candidate_dynamic = dynamic_argument;
best_parameter_member = pm;
best_candidate_return_type = rt;
} else if (candidate_rate == 0) {
//
// The member look is done per type for most operations but sometimes
// it's not possible like for binary operators overload because they
// are unioned between 2 sides
//
if ((restrictions & Restrictions.BaseMembersIncluded) != 0) {
if (TypeSpec.IsBaseClass (best_candidate.DeclaringType, member.DeclaringType, true))
continue;
}
}
IParametersMember pm = member as IParametersMember;
if (pm == null) {
bool is_better;
if (best_candidate.DeclaringType.IsInterface && member.DeclaringType.ImplementsInterface (best_candidate.DeclaringType, false)) {
//
// Will use it later to report ambiguity between best method and invocable member
// We pack all interface members into top level type which makes the overload resolution
// more complicated for interfaces. We compensate it by removing methods with same
// signature when building the cache hence this path should not really be hit often
//
if (Invocation.IsMemberInvocable (member))
invocable_member = member;
// Example:
// interface IA { void Foo (int arg); }
// interface IB : IA { void Foo (params int[] args); }
//
// IB::Foo is the best overload when calling IB.Foo (1)
//
is_better = true;
if (ambiguous_candidates != null) {
foreach (var amb_cand in ambiguous_candidates) {
if (member.DeclaringType.ImplementsInterface (best_candidate.DeclaringType, false)) {
continue;
}
continue;
}
is_better = false;
break;
}
//
// Overload resolution is looking for base member but using parameter names
// and default values from the closest member. That means to do expensive lookup
// for the closest override for virtual or abstract members
//
if ((member.Modifiers & (Modifiers.VIRTUAL | Modifiers.ABSTRACT)) != 0) {
var override_params = base_provider.GetOverrideMemberParameters (member);
if (override_params != null)
pm = override_params;
if (is_better)
ambiguous_candidates = null;
}
} else {
// Is the new candidate better
is_better = BetterFunction (rc, candidate_args, member, pm.Parameters, params_expanded_form, best_candidate, best_parameter_member.Parameters, best_candidate_params);
}
//
// Check if the member candidate is applicable
//
bool params_expanded_form = false;
bool dynamic_argument = false;
TypeSpec rt = pm.MemberType;
int candidate_rate = IsApplicable (rc, ref candidate_args, args_count, ref member, pm, ref params_expanded_form, ref dynamic_argument, ref rt);
//
// How does it score compare to others
//
if (candidate_rate < best_candidate_rate) {
best_candidate_rate = candidate_rate;
if (is_better) {
best_candidate = member;
best_candidate_args = candidate_args;
best_candidate_params = params_expanded_form;
best_candidate_dynamic = dynamic_argument;
best_parameter_member = pm;
best_candidate_return_type = rt;
} else if (candidate_rate == 0) {
//
// The member look is done per type for most operations but sometimes
// it's not possible like for binary operators overload because they
// are unioned between 2 sides
//
if ((restrictions & Restrictions.BaseMembersIncluded) != 0) {
if (TypeSpec.IsBaseClass (best_candidate.DeclaringType, member.DeclaringType, true))
continue;
}
bool is_better;
if (best_candidate.DeclaringType.IsInterface && member.DeclaringType.ImplementsInterface (best_candidate.DeclaringType, false)) {
//
// We pack all interface members into top level type which makes the overload resolution
// more complicated for interfaces. We compensate it by removing methods with same
// signature when building the cache hence this path should not really be hit often
//
// Example:
// interface IA { void Foo (int arg); }
// interface IB : IA { void Foo (params int[] args); }
//
// IB::Foo is the best overload when calling IB.Foo (1)
//
is_better = true;
if (ambiguous_candidates != null) {
foreach (var amb_cand in ambiguous_candidates) {
if (member.DeclaringType.ImplementsInterface (best_candidate.DeclaringType, false)) {
continue;
}
is_better = false;
break;
}
if (is_better)
ambiguous_candidates = null;
}
} else {
// Is the new candidate better
is_better = BetterFunction (rc, candidate_args, member, pm.Parameters, params_expanded_form, best_candidate, best_parameter_member.Parameters, best_candidate_params);
}
} else {
// It's not better but any other found later could be but we are not sure yet
if (ambiguous_candidates == null)
ambiguous_candidates = new List<AmbiguousCandidate> ();
if (is_better) {
best_candidate = member;
best_candidate_args = candidate_args;
best_candidate_params = params_expanded_form;
best_candidate_dynamic = dynamic_argument;
best_parameter_member = pm;
best_candidate_return_type = rt;
} else {
// It's not better but any other found later could be but we are not sure yet
if (ambiguous_candidates == null)
ambiguous_candidates = new List<AmbiguousCandidate> ();
ambiguous_candidates.Add (new AmbiguousCandidate (member, pm.Parameters, params_expanded_form));
}
ambiguous_candidates.Add (new AmbiguousCandidate (member, pm.Parameters, params_expanded_form));
}
// Restore expanded arguments
if (candidate_args != args)
candidate_args = args;
}
} while (best_candidate_rate != 0 && (type_members = base_provider.GetBaseMembers (type_members[0].DeclaringType.BaseType)) != null);
} finally {
if (prev_recorder != null)
rc.Report.SetPrinter (prev_recorder);
}
// Restore expanded arguments
if (candidate_args != args)
candidate_args = args;
}
} while (best_candidate_rate != 0 && (type_members = base_provider.GetBaseMembers (type_members[0].DeclaringType.BaseType)) != null);
//
// We've found exact match
@ -4685,6 +4788,17 @@ namespace Mono.CSharp { @@ -4685,6 +4788,17 @@ namespace Mono.CSharp {
args [0].Type.GetSignatureForError (), best_candidate.Name, best_candidate.GetSignatureForError ());
}
//
// Check type constraints only when explicit type arguments are used
//
if (best_candidate.IsGeneric && type_arguments != null) {
MethodSpec bc = best_candidate as MethodSpec;
if (bc != null && TypeParameterSpec.HasAnyTypeParameterConstrained (bc.GenericDefinition)) {
ConstraintChecker cc = new ConstraintChecker (rc);
cc.CheckAll (bc.GetGenericMethodDefinition (), bc.TypeArguments, bc.Constraints, loc);
}
}
BestCandidateIsDynamic = true;
return null;
}
@ -4744,11 +4858,6 @@ namespace Mono.CSharp { @@ -4744,11 +4858,6 @@ namespace Mono.CSharp {
if (oa != null && !rc.IsObsolete)
AttributeTester.Report_ObsoleteMessage (oa, best_candidate.GetSignatureForError (), loc, rc.Report);
var dep = best_candidate.GetMissingDependencies ();
if (dep != null) {
ImportedTypeDefinition.Error_MissingDependency (rc, dep, loc);
}
best_candidate.MemberDefinition.SetIsUsed ();
args = best_candidate_args;
@ -4825,9 +4934,8 @@ namespace Mono.CSharp { @@ -4825,9 +4934,8 @@ namespace Mono.CSharp {
return;
}
if (lambda_conv_msgs != null) {
if (lambda_conv_msgs.Merge (rc.Report.Printer))
return;
if (lambda_conv_msgs != null && lambda_conv_msgs.Merge (rc.Report.Printer)) {
return;
}
@ -5217,14 +5325,25 @@ namespace Mono.CSharp { @@ -5217,14 +5325,25 @@ namespace Mono.CSharp {
public override Expression CreateExpressionTree (ResolveContext ec)
{
return CreateExpressionTree (ec, true);
}
public Expression CreateExpressionTree (ResolveContext ec, bool convertInstance)
{
Arguments args;
Expression instance;
if (InstanceExpression == null) {
instance = new NullLiteral (loc);
} else {
} else if (convertInstance) {
instance = InstanceExpression.CreateExpressionTree (ec);
} else {
args = new Arguments (1);
args.Add (new Argument (InstanceExpression));
instance = CreateExpressionFactoryCall (ec, "Constant", args);
}
Arguments args = Arguments.CreateForExpressionTree (ec, null,
args = Arguments.CreateForExpressionTree (ec, null,
instance,
CreateTypeOfExpression ());
@ -5238,6 +5357,8 @@ namespace Mono.CSharp { @@ -5238,6 +5357,8 @@ namespace Mono.CSharp {
protected override Expression DoResolve (ResolveContext ec)
{
spec.MemberDefinition.SetIsUsed ();
return DoResolve (ec, null);
}
@ -5279,7 +5400,7 @@ namespace Mono.CSharp { @@ -5279,7 +5400,7 @@ namespace Mono.CSharp {
if (lvalue_instance && var != null && var.VariableInfo != null) {
var.VariableInfo.SetStructFieldAssigned (ec, Name);
}
if (fb != null) {
IFixedExpression fe = InstanceExpression as IFixedExpression;
if (!ec.HasSet (ResolveContext.Options.FixedInitializerScope) && (fe == null || !fe.IsFixed)) {
@ -5457,8 +5578,6 @@ namespace Mono.CSharp { @@ -5457,8 +5578,6 @@ namespace Mono.CSharp {
{
bool is_volatile = (spec.Modifiers & Modifiers.VOLATILE) != 0;
spec.MemberDefinition.SetIsUsed ();
if (IsStatic){
if (is_volatile)
ec.Emit (OpCodes.Volatile);
@ -6046,7 +6165,7 @@ namespace Mono.CSharp { @@ -6046,7 +6165,7 @@ namespace Mono.CSharp {
GetSignatureForError ());
} else {
rc.Report.SymbolRelatedToPreviousError (best_candidate.Set);
ErrorIsInaccesible (rc, best_candidate.Set.GetSignatureForError (), loc);
ErrorIsInaccesible (rc, best_candidate.GetSignatureForError (), loc);
}
}

11
ICSharpCode.NRefactory.CSharp/Parser/mcs/eval.cs

@ -79,7 +79,7 @@ namespace Mono.CSharp @@ -79,7 +79,7 @@ namespace Mono.CSharp
module = new ModuleContainer (ctx);
module.Evaluator = this;
source_file = new CompilationSourceFile (module);
source_file = new CompilationSourceFile (module, null);
module.AddTypeContainer (source_file);
startup_files = ctx.SourceFiles.Count;
@ -115,9 +115,10 @@ namespace Mono.CSharp @@ -115,9 +115,10 @@ namespace Mono.CSharp
Location.Initialize (ctx.SourceFiles);
var parser_session = new ParserSession ();
for (int i = 0; i < startup_files; ++i) {
var sf = ctx.SourceFiles [i];
d.Parse (sf, module);
d.Parse (sf, module, parser_session, ctx.Report);
}
}
@ -442,7 +443,7 @@ namespace Mono.CSharp @@ -442,7 +443,7 @@ namespace Mono.CSharp
//
InputKind ToplevelOrStatement (SeekableStreamReader seekable)
{
Tokenizer tokenizer = new Tokenizer (seekable, source_file);
Tokenizer tokenizer = new Tokenizer (seekable, source_file, new ParserSession ());
int t = tokenizer.token ();
switch (t){
@ -571,7 +572,7 @@ namespace Mono.CSharp @@ -571,7 +572,7 @@ namespace Mono.CSharp
seekable.Position = 0;
source_file.DeclarationFound = false;
CSharpParser parser = new CSharpParser (seekable, source_file);
CSharpParser parser = new CSharpParser (seekable, source_file, new ParserSession ());
if (kind == InputKind.StatementOrExpression){
parser.Lexer.putback_char = Tokenizer.EvalStatementParserCharacter;
@ -976,7 +977,9 @@ namespace Mono.CSharp @@ -976,7 +977,9 @@ namespace Mono.CSharp
static public string help {
get {
return "Static methods:\n" +
#if !NET_2_1
" Describe (object); - Describes the object's type\n" +
#endif
" LoadPackage (package); - Loads the given Package (like -pkg:FILE)\n" +
" LoadAssembly (assembly); - Loads the given assembly (like -r:ASSEMBLY)\n" +
" ShowVars (); - Shows defined local variables.\n" +

74
ICSharpCode.NRefactory.CSharp/Parser/mcs/expression.cs

@ -1211,7 +1211,7 @@ namespace Mono.CSharp @@ -1211,7 +1211,7 @@ namespace Mono.CSharp
var one = new IntConstant (ec.BuiltinTypes, 1, loc);
var op = IsDecrement ? Binary.Operator.Subtraction : Binary.Operator.Addition;
operation = new Binary (op, source, one, loc);
operation = new Binary (op, source, one);
operation = operation.Resolve (ec);
if (operation == null)
throw new NotImplementedException ("should not be reached");
@ -1527,7 +1527,7 @@ namespace Mono.CSharp @@ -1527,7 +1527,7 @@ namespace Mono.CSharp
// Turn is check into simple null check for implicitly convertible reference types
//
return ReducedExpression.Create (
new Binary (Binary.Operator.Inequality, expr, new NullLiteral (loc), loc).Resolve (ec),
new Binary (Binary.Operator.Inequality, expr, new NullLiteral (loc)).Resolve (ec),
this).Resolve (ec);
}
@ -2014,7 +2014,7 @@ namespace Mono.CSharp @@ -2014,7 +2014,7 @@ namespace Mono.CSharp
// b = b.left >> b.right & (0x1f|0x3f)
//
b.right = new Binary (Operator.BitwiseAnd,
b.right, new IntConstant (ec.BuiltinTypes, right_mask, b.right.Location), b.loc).Resolve (ec);
b.right, new IntConstant (ec.BuiltinTypes, right_mask, b.right.Location)).Resolve (ec);
//
// Expression tree representation does not use & mask
@ -2202,19 +2202,19 @@ namespace Mono.CSharp @@ -2202,19 +2202,19 @@ namespace Mono.CSharp
protected State state;
Expression enum_conversion;
public Binary (Operator oper, Expression left, Expression right, bool isCompound, Location loc)
: this (oper, left, right, loc)
public Binary (Operator oper, Expression left, Expression right, bool isCompound)
: this (oper, left, right)
{
if (isCompound)
state |= State.Compound;
}
public Binary (Operator oper, Expression left, Expression right, Location loc)
public Binary (Operator oper, Expression left, Expression right)
{
this.oper = oper;
this.left = left;
this.right = right;
this.loc = loc;
this.loc = left.Location;
}
#region Properties
@ -2319,7 +2319,7 @@ namespace Mono.CSharp @@ -2319,7 +2319,7 @@ namespace Mono.CSharp
public static void Error_OperatorCannotBeApplied (ResolveContext ec, Expression left, Expression right, Operator oper, Location loc)
{
new Binary (oper, left, right, loc).Error_OperatorCannotBeApplied (ec, left, right);
new Binary (oper, left, right).Error_OperatorCannotBeApplied (ec, left, right);
}
public static void Error_OperatorCannotBeApplied (ResolveContext ec, Expression left, Expression right, string oper, Location loc)
@ -3031,7 +3031,7 @@ namespace Mono.CSharp @@ -3031,7 +3031,7 @@ namespace Mono.CSharp
(TypeSpec.IsValueType (left.Type) && right is NullLiteral) ||
(right.Type.IsNullableType && (left is NullLiteral || left.Type.IsNullableType || TypeSpec.IsValueType (left.Type))) ||
(TypeSpec.IsValueType (right.Type) && left is NullLiteral))) {
var lifted = new Nullable.LiftedBinaryOperator (oper, left, right, loc);
var lifted = new Nullable.LiftedBinaryOperator (oper, left, right);
lifted.state = state;
return lifted.Resolve (ec);
}
@ -4409,7 +4409,7 @@ namespace Mono.CSharp @@ -4409,7 +4409,7 @@ namespace Mono.CSharp
// TODO: Should be the checks resolve context sensitive?
ResolveContext rc = new ResolveContext (ec.MemberContext, ResolveContext.Options.UnsafeScope);
right = new Binary (Binary.Operator.Multiply, right, right_const, loc).Resolve (rc);
right = new Binary (Binary.Operator.Multiply, right, right_const).Resolve (rc);
if (right == null)
return;
}
@ -5264,8 +5264,10 @@ namespace Mono.CSharp @@ -5264,8 +5264,10 @@ namespace Mono.CSharp
{
this.expr = expr;
this.arguments = arguments;
if (expr != null)
loc = expr.Location;
if (expr != null) {
var ma = expr as MemberAccess;
loc = ma != null ? ma.GetLeftExpressionLocation () : expr.Location;
}
}
#region Properties
@ -6154,7 +6156,7 @@ namespace Mono.CSharp @@ -6154,7 +6156,7 @@ namespace Mono.CSharp
{
if (initializers != null && bounds == null) {
//
// We use this to store all the date values in the order in which we
// We use this to store all the data values in the order in which we
// will need to store them in the byte blob later
//
array_data = new List<Expression> ();
@ -6212,7 +6214,16 @@ namespace Mono.CSharp @@ -6212,7 +6214,16 @@ namespace Mono.CSharp
ec.Report.Error (623, loc, "Array initializers can only be used in a variable or field initializer. Try using a new expression instead");
return false;
}
// When we don't have explicitly specified dimensions, record whatever dimension we first encounter at each level
if (!bounds.ContainsKey(idx + 1))
bounds[idx + 1] = sub_probe.Count;
if (bounds[idx + 1] != sub_probe.Count) {
ec.Report.Error(847, sub_probe.Location, "An array initializer of length `{0}' was expected", bounds[idx + 1].ToString());
return false;
}
bool ret = CheckIndices (ec, sub_probe, idx + 1, specified_dims, child_bounds - 1);
if (!ret)
return false;
@ -6987,7 +6998,7 @@ namespace Mono.CSharp @@ -6987,7 +6998,7 @@ namespace Mono.CSharp
if (variable_info == null)
return;
if (rc.HasSet (ResolveContext.Options.OmitStructFlowAnalysis))
if (rc.OmitStructFlowAnalysis)
return;
if (!variable_info.IsAssigned (rc)) {
@ -7932,6 +7943,18 @@ namespace Mono.CSharp @@ -7932,6 +7943,18 @@ namespace Mono.CSharp
expr.Error_OperatorCannotBeApplied (rc, loc, ".", type);
}
public Location GetLeftExpressionLocation ()
{
Expression expr = LeftExpression;
MemberAccess ma = expr as MemberAccess;
while (ma != null && ma.LeftExpression != null) {
expr = ma.LeftExpression;
ma = expr as MemberAccess;
}
return expr == null ? Location : expr.Location;
}
public static bool IsValidDotExpression (TypeSpec type)
{
const MemberKind dot_kinds = MemberKind.Class | MemberKind.Struct | MemberKind.Delegate | MemberKind.Enum |
@ -8252,9 +8275,19 @@ namespace Mono.CSharp @@ -8252,9 +8275,19 @@ namespace Mono.CSharp
{
if (ec.Module.Compiler.Settings.Version > LanguageVersion.ISO_2 && !ec.IsRuntimeBinder && MethodGroupExpr.IsExtensionMethodArgument (expr)) {
ec.Report.SymbolRelatedToPreviousError (type);
var cand = ec.Module.GlobalRootNamespace.FindExtensionMethodNamespaces (ec, type, name, Arity);
string missing;
// a using directive or an assembly reference
if (cand != null) {
missing = "`" + string.Join ("' or `", cand.ToArray ()) + "' using directive";
} else {
missing = "an assembly reference";
}
ec.Report.Error (1061, loc,
"Type `{0}' does not contain a definition for `{1}' and no extension method `{1}' of type `{0}' could be found (are you missing a using directive or an assembly reference?)",
type.GetSignatureForError (), name);
"Type `{0}' does not contain a definition for `{1}' and no extension method `{1}' of type `{0}' could be found. Are you missing {2}?",
type.GetSignatureForError (), name, missing);
return;
}
@ -9461,7 +9494,7 @@ namespace Mono.CSharp @@ -9461,7 +9494,7 @@ namespace Mono.CSharp
this.left = left;
this.spec = spec;
this.loc = spec.Location;
this.loc = left.Location;
}
public override TypeSpec ResolveAsType (IMemberContext ec)
@ -9843,6 +9876,9 @@ namespace Mono.CSharp @@ -9843,6 +9876,9 @@ namespace Mono.CSharp
//
class CollectionElementInitializer : Invocation
{
public readonly bool IsSingle;
public class ElementInitializerArgument : Argument
{
public ElementInitializerArgument (Expression e)
@ -9870,6 +9906,7 @@ namespace Mono.CSharp @@ -9870,6 +9906,7 @@ namespace Mono.CSharp
public CollectionElementInitializer (Expression argument)
: base (null, new Arguments (1))
{
IsSingle = true;
base.arguments.Add (new ElementInitializerArgument (argument));
this.loc = argument.Location;
}
@ -9877,6 +9914,7 @@ namespace Mono.CSharp @@ -9877,6 +9914,7 @@ namespace Mono.CSharp
public CollectionElementInitializer (List<Expression> arguments, Location loc)
: base (null, new Arguments (arguments.Count))
{
IsSingle = false;
foreach (Expression e in arguments)
base.arguments.Add (new ElementInitializerArgument (e));

5
ICSharpCode.NRefactory.CSharp/Parser/mcs/field.cs

@ -640,13 +640,12 @@ namespace Mono.CSharp @@ -640,13 +640,12 @@ namespace Mono.CSharp
}
if (initializer != null) {
Parent.RegisterFieldForInitialization (this,
new FieldInitializer (spec, initializer, this));
Parent.RegisterFieldForInitialization (this, new FieldInitializer (this, initializer, TypeExpression.Location));
}
if (declarators != null) {
var t = new TypeExpression (MemberType, TypeExpression.Location);
foreach (var d in declarators) {
var t = new TypeExpression (MemberType, d.Name.Location);
var f = new Field (Parent, t, ModFlags, new MemberName (d.Name.Value, d.Name.Location), OptAttributes);
if (d.Initializer != null)
f.initializer = d.Initializer;

84
ICSharpCode.NRefactory.CSharp/Parser/mcs/generic.cs

@ -737,6 +737,12 @@ namespace Mono.CSharp { @@ -737,6 +737,12 @@ namespace Mono.CSharp {
}
}
public bool HasAnyTypeConstraint {
get {
return (spec & (SpecialConstraint.Class | SpecialConstraint.Struct)) != 0 || ifaces != null || targs != null || HasTypeConstraint;
}
}
public bool HasTypeConstraint {
get {
var bt = BaseType.BuiltinType;
@ -1226,6 +1232,30 @@ namespace Mono.CSharp { @@ -1226,6 +1232,30 @@ namespace Mono.CSharp {
return false;
}
public static bool HasAnyTypeParameterTypeConstrained (IGenericMethodDefinition md)
{
var tps = md.TypeParameters;
for (int i = 0; i < md.TypeParametersCount; ++i) {
if (tps[i].HasAnyTypeConstraint) {
return true;
}
}
return false;
}
public static bool HasAnyTypeParameterConstrained (IGenericMethodDefinition md)
{
var tps = md.TypeParameters;
for (int i = 0; i < md.TypeParametersCount; ++i) {
if (tps[i].IsConstrained) {
return true;
}
}
return false;
}
public override TypeSpec Mutate (TypeParameterMutator mutator)
{
return mutator.Mutate (this);
@ -1488,7 +1518,9 @@ namespace Mono.CSharp { @@ -1488,7 +1518,9 @@ namespace Mono.CSharp {
if (targs == null)
throw new ArgumentNullException ("targs");
// this.state = openType.state;
this.state &= ~SharedStateFlags;
this.state |= (openType.state & SharedStateFlags);
this.context = context;
this.open_type = openType;
this.targs = targs;
@ -2222,29 +2254,14 @@ namespace Mono.CSharp { @@ -2222,29 +2254,14 @@ namespace Mono.CSharp {
struct ConstraintChecker
{
IMemberContext mc;
bool ignore_inferred_dynamic;
bool recursive_checks;
public ConstraintChecker (IMemberContext ctx)
{
this.mc = ctx;
ignore_inferred_dynamic = false;
recursive_checks = false;
}
#region Properties
public bool IgnoreInferredDynamic {
get {
return ignore_inferred_dynamic;
}
set {
ignore_inferred_dynamic = value;
}
}
#endregion
//
// Checks the constraints of open generic type against type
// arguments. This version is used for types which could not be
@ -2289,14 +2306,11 @@ namespace Mono.CSharp { @@ -2289,14 +2306,11 @@ namespace Mono.CSharp {
//
// Checks all type arguments againts type parameters constraints
// NOTE: It can run in probing mode when `mc' is null
// NOTE: It can run in probing mode when `this.mc' is null
//
public bool CheckAll (MemberSpec context, TypeSpec[] targs, TypeParameterSpec[] tparams, Location loc)
{
for (int i = 0; i < tparams.Length; i++) {
if (ignore_inferred_dynamic && targs[i].BuiltinType == BuiltinTypeSpec.Type.Dynamic)
continue;
var targ = targs[i];
if (!CheckConstraint (context, targ, tparams [i], loc))
return false;
@ -2342,15 +2356,6 @@ namespace Mono.CSharp { @@ -2342,15 +2356,6 @@ namespace Mono.CSharp {
// Check the class constraint
//
if (tparam.HasTypeConstraint) {
var dep = tparam.BaseType.GetMissingDependencies ();
if (dep != null) {
if (mc == null)
return false;
ImportedTypeDefinition.Error_MissingDependency (mc, dep, loc);
ok = false;
}
if (!CheckConversion (mc, context, atype, tparam, tparam.BaseType, loc)) {
if (mc == null)
return false;
@ -2364,19 +2369,6 @@ namespace Mono.CSharp { @@ -2364,19 +2369,6 @@ namespace Mono.CSharp {
//
if (tparam.Interfaces != null) {
foreach (TypeSpec iface in tparam.Interfaces) {
var dep = iface.GetMissingDependencies ();
if (dep != null) {
if (mc == null)
return false;
ImportedTypeDefinition.Error_MissingDependency (mc, dep, loc);
ok = false;
// return immediately to avoid duplicate errors because we are scanning
// expanded interface list
return false;
}
if (!CheckConversion (mc, context, atype, tparam, iface, loc)) {
if (mc == null)
return false;
@ -2466,14 +2458,6 @@ namespace Mono.CSharp { @@ -2466,14 +2458,6 @@ namespace Mono.CSharp {
return true;
}
//
// When partial/full type inference finds a dynamic type argument delay
// the constraint check to runtime, it can succeed for real underlying
// dynamic type
//
if (ignore_inferred_dynamic && HasDynamicTypeArgument (ttype.TypeArguments))
return true;
if (mc != null) {
mc.Module.Compiler.Report.SymbolRelatedToPreviousError (tparam);
if (atype.IsGenericParameter) {

71
ICSharpCode.NRefactory.CSharp/Parser/mcs/import.cs

@ -90,7 +90,7 @@ namespace Mono.CSharp @@ -90,7 +90,7 @@ namespace Mono.CSharp
if (cad.Count > 0) {
foreach (var ca in cad) {
var dt = ca.Constructor.DeclaringType;
if (dt.Name != "DynamicAttribute" && dt.Namespace != CompilerServicesNamespace)
if (dt.Name != "DynamicAttribute" || dt.Namespace != CompilerServicesNamespace)
continue;
if (ca.ConstructorArguments.Count == 0) {
@ -390,18 +390,21 @@ namespace Mono.CSharp @@ -390,18 +390,21 @@ namespace Mono.CSharp
if ((mod & Modifiers.OVERRIDE) != 0) {
bool is_real_override = false;
if (kind == MemberKind.Method && declaringType.BaseType != null) {
var filter = MemberFilter.Method (name, tparams != null ? tparams.Length : 0, parameters, null);
var candidate = MemberCache.FindMember (declaringType.BaseType, filter, BindingRestriction.None);
//
// For imported class method do additional validation to be sure that metadata
// override flag was correct
//
// Difference between protected internal and protected is ok
//
const Modifiers conflict_mask = Modifiers.AccessibilityMask & ~Modifiers.INTERNAL;
if (candidate != null && (candidate.Modifiers & conflict_mask) == (mod & conflict_mask) && !candidate.IsStatic) {
is_real_override = true;
var btype = declaringType.BaseType;
if (IsOverrideMethodBaseTypeAccessible (btype)) {
var filter = MemberFilter.Method (name, tparams != null ? tparams.Length : 0, parameters, null);
var candidate = MemberCache.FindMember (btype, filter, BindingRestriction.None);
//
// For imported class method do additional validation to be sure that metadata
// override flag was correct
//
// Difference between protected internal and protected is ok
//
const Modifiers conflict_mask = Modifiers.AccessibilityMask & ~Modifiers.INTERNAL;
if (candidate != null && (candidate.Modifiers & conflict_mask) == (mod & conflict_mask) && !candidate.IsStatic) {
is_real_override = true;
}
}
}
@ -434,6 +437,30 @@ namespace Mono.CSharp @@ -434,6 +437,30 @@ namespace Mono.CSharp
return ms;
}
bool IsOverrideMethodBaseTypeAccessible (TypeSpec baseType)
{
switch (baseType.Modifiers & Modifiers.AccessibilityMask) {
case Modifiers.PUBLIC:
return true;
case Modifiers.INTERNAL:
//
// Check whether imported method in base type is accessible from compiled
// context
//
return baseType.MemberDefinition.IsInternalAsPublic (module.DeclaringAssembly);
case Modifiers.PRIVATE:
return false;
default:
// protected
// protected internal
//
// Method accessibility checks will be done later based on context
// where the method is called (CS0122 error will be reported for inaccessible)
//
return true;
}
}
//
// Imports System.Reflection parameters
//
@ -835,6 +862,13 @@ namespace Mono.CSharp @@ -835,6 +862,13 @@ namespace Mono.CSharp
import_cache.Add (type, spec);
if (kind == MemberKind.TypeParameter) {
if (canImportBaseType)
ImportTypeParameterTypeConstraints ((TypeParameterSpec) spec, type);
return spec;
}
//
// Two stage setup as the base type can be inflated declaring type or
// another nested type inside same declaring type which has not been
@ -992,7 +1026,6 @@ namespace Mono.CSharp @@ -992,7 +1026,6 @@ namespace Mono.CSharp
ImportTypeParameterTypeConstraints (tp, tp.GetMetaInfo ());
}
}
}
protected void ImportTypes (MetaType[] types, Namespace targetNamespace, bool hasExtensionTypes)
@ -1796,7 +1829,15 @@ namespace Mono.CSharp @@ -1796,7 +1829,15 @@ namespace Mono.CSharp
// or referenced from the user core in which case compilation error has to
// be reported because compiler cannot continue anyway
//
foreach (var t in types) {
for (int i = 0; i < types.Count; ++i) {
var t = types [i];
//
// Report missing types only once per type
//
if (i > 0 && types.IndexOf (t) < i)
continue;
string name = t.GetSignatureForError ();
if (t.MemberDefinition.DeclaringAssembly == ctx.Module.DeclaringAssembly) {

4
ICSharpCode.NRefactory.CSharp/Parser/mcs/iterators.cs

@ -972,7 +972,9 @@ namespace Mono.CSharp @@ -972,7 +972,9 @@ namespace Mono.CSharp
method.Block.IsCompilerGenerated = true;
method.Block.AddStatement (new TryFinallyBlockProxyStatement (this, block));
storey.AddMember (method);
// Cannot it add to storey because it'd be emitted before nested
// anonoymous methods which could capture shared variable
return method;
}

54
ICSharpCode.NRefactory.CSharp/Parser/mcs/location.cs

@ -52,13 +52,15 @@ namespace Mono.CSharp @@ -52,13 +52,15 @@ namespace Mono.CSharp
}
}
static readonly byte[] MD5Algorith = { 96, 166, 110, 64, 207, 100, 130, 76, 182, 240, 66, 212, 129, 114, 167, 153 };
public readonly string Name;
public readonly string FullPathName;
public readonly int Index;
public bool AutoGenerated;
SourceFileEntry file;
byte[] guid, checksum;
byte[] algGuid, checksum;
List<LocationRegion> hidden_lines;
public SourceFile (string name, string path, int index)
@ -68,15 +70,32 @@ namespace Mono.CSharp @@ -68,15 +70,32 @@ namespace Mono.CSharp
this.FullPathName = path;
}
public byte[] Checksum {
get {
return checksum;
}
}
public bool HasChecksum {
get {
return checksum != null;
}
}
public SourceFileEntry SourceFileEntry {
get {
return file;
}
}
public void SetChecksum (byte[] guid, byte[] checksum)
public void SetChecksum (byte[] checksum)
{
this.guid = guid;
SetChecksum (MD5Algorith, checksum);
}
public void SetChecksum (byte[] algorithmGuid, byte[] checksum)
{
this.algGuid = algorithmGuid;
this.checksum = checksum;
}
@ -85,13 +104,9 @@ namespace Mono.CSharp @@ -85,13 +104,9 @@ namespace Mono.CSharp
if (hidden_lines != null)
hidden_lines.Sort ();
if (guid != null) {
file = new SourceFileEntry (symwriter, FullPathName, guid, checksum);
} else {
file = new SourceFileEntry (symwriter, FullPathName);
if (AutoGenerated)
file.SetAutoGenerated ();
}
file = new SourceFileEntry (symwriter, FullPathName, algGuid, checksum);
if (AutoGenerated)
file.SetAutoGenerated ();
return file;
}
@ -177,7 +192,6 @@ namespace Mono.CSharp @@ -177,7 +192,6 @@ namespace Mono.CSharp
const int max_column = column_mask;
static List<SourceFile> source_list;
static int current_source;
static Checkpoint [] checkpoints;
static int checkpoint_index;
@ -192,7 +206,6 @@ namespace Mono.CSharp @@ -192,7 +206,6 @@ namespace Mono.CSharp
public static void Reset ()
{
source_list = new List<SourceFile> ();
current_source = 0;
checkpoint_index = 0;
}
@ -220,13 +233,7 @@ namespace Mono.CSharp @@ -220,13 +233,7 @@ namespace Mono.CSharp
checkpoints [0] = new Checkpoint (0, 0);
}
static public void Push (SourceFile file)
{
current_source = file != null ? file.Index : -1;
// File is always pushed before being changed.
}
public Location (int row, int column)
public Location (SourceFile file, int row, int column)
{
if (row <= 0)
token = 0;
@ -237,6 +244,9 @@ namespace Mono.CSharp @@ -237,6 +244,9 @@ namespace Mono.CSharp
long target = -1;
long delta = 0;
// TODO: For eval only, need better handling of empty
int file_index = file == null ? 0 : file.Index;
// FIXME: This value is certainly wrong but what was the intension
int max = checkpoint_index < 10 ?
checkpoint_index : 10;
@ -245,13 +255,13 @@ namespace Mono.CSharp @@ -245,13 +255,13 @@ namespace Mono.CSharp
delta = row - offset;
if (delta >= 0 &&
delta < (1 << line_delta_bits) &&
checkpoints [checkpoint_index - i].File == current_source) {
checkpoints[checkpoint_index - i].File == file_index) {
target = checkpoint_index - i;
break;
}
}
if (target == -1) {
AddCheckpoint (current_source, row);
AddCheckpoint (file_index, row);
target = checkpoint_index;
delta = row % (1 << line_delta_bits);
}
@ -269,7 +279,7 @@ namespace Mono.CSharp @@ -269,7 +279,7 @@ namespace Mono.CSharp
public static Location operator - (Location loc, int columns)
{
return new Location (loc.Row, loc.Column - columns);
return new Location (loc.SourceFile, loc.Row, loc.Column - columns);
}
static void AddCheckpoint (int file, int row)

7
ICSharpCode.NRefactory.CSharp/Parser/mcs/membercache.cs

@ -435,12 +435,15 @@ namespace Mono.CSharp { @@ -435,12 +435,15 @@ namespace Mono.CSharp {
// A special method to work with member lookup only. It returns a list of all members named @name
// starting from @container. It's very performance sensitive
//
public static IList<MemberSpec> FindMembers (TypeSpec container, string name, bool declaredOnly)
// declaredOnlyClass cannot be used interfaces. Manual filtering is required because names are
// compacted
//
public static IList<MemberSpec> FindMembers (TypeSpec container, string name, bool declaredOnlyClass)
{
IList<MemberSpec> applicable;
do {
if (container.MemberCache.member_hash.TryGetValue (name, out applicable) || declaredOnly)
if (container.MemberCache.member_hash.TryGetValue (name, out applicable) || declaredOnlyClass)
return applicable;
container = container.BaseType;

90
ICSharpCode.NRefactory.CSharp/Parser/mcs/method.cs

@ -496,6 +496,20 @@ namespace Mono.CSharp { @@ -496,6 +496,20 @@ namespace Mono.CSharp {
missing.AddRange (m);
}
if (Arity > 0) {
foreach (var tp in GenericDefinition.TypeParameters) {
var m = tp.GetMissingDependencies ();
if (m == null)
continue;
if (missing == null)
missing = new List<TypeSpec> ();
missing.AddRange (m);
}
}
return missing;
}
@ -1199,6 +1213,9 @@ namespace Mono.CSharp { @@ -1199,6 +1213,9 @@ namespace Mono.CSharp {
block = (ToplevelBlock) block.ConvertToAsyncTask (this, Parent.PartialContainer, parameters, ReturnType, Location);
ModFlags |= Modifiers.DEBUGGER_HIDDEN;
}
if (Compiler.Settings.WriteMetadataOnly)
block = null;
}
if ((ModFlags & Modifiers.STATIC) == 0)
@ -1287,10 +1304,18 @@ namespace Mono.CSharp { @@ -1287,10 +1304,18 @@ namespace Mono.CSharp {
}
}
base.Emit ();
if (block != null && block.StateMachine != null) {
var psm = block.StateMachine is IteratorStorey ?
Module.PredefinedAttributes.IteratorStateMachine :
Module.PredefinedAttributes.AsyncStateMachine;
psm.EmitAttribute (MethodBuilder, block.StateMachine);
}
if ((ModFlags & Modifiers.METHOD_EXTENSION) != 0)
Module.PredefinedAttributes.Extension.EmitAttribute (MethodBuilder);
base.Emit ();
} catch {
Console.WriteLine ("Internal compiler error at {0}: exception caught while emitting {1}",
Location, MethodBuilder);
@ -1418,8 +1443,7 @@ namespace Mono.CSharp { @@ -1418,8 +1443,7 @@ namespace Mono.CSharp {
base_ctor = ConstructorLookup (ec, type, ref argument_list, loc);
}
// TODO MemberCache: Does it work for inflated types ?
if (base_ctor == caller_builder.Spec){
if (base_ctor != null && base_ctor.MemberDefinition == caller_builder.Spec.MemberDefinition) {
ec.Report.Error (516, loc, "Constructor `{0}' cannot call itself",
caller_builder.GetSignatureForError ());
}
@ -1604,10 +1628,15 @@ namespace Mono.CSharp { @@ -1604,10 +1628,15 @@ namespace Mono.CSharp {
Parent.MemberCache.AddMember (spec);
// It's here only to report an error
if (block != null && block.IsIterator) {
member_type = Compiler.BuiltinTypes.Void;
Iterator.CreateIterator (this, Parent.PartialContainer, ModFlags);
if (block != null) {
// It's here only to report an error
if (block.IsIterator) {
member_type = Compiler.BuiltinTypes.Void;
Iterator.CreateIterator (this, Parent.PartialContainer, ModFlags);
}
if (Compiler.Settings.WriteMetadataOnly)
block = null;
}
return true;
@ -1643,14 +1672,14 @@ namespace Mono.CSharp { @@ -1643,14 +1672,14 @@ namespace Mono.CSharp {
BlockContext bc = new BlockContext (this, block, Compiler.BuiltinTypes.Void);
bc.Set (ResolveContext.Options.ConstructorScope);
//
// If we use a "this (...)" constructor initializer, then
// do not emit field initializers, they are initialized in the other constructor
//
if (!(Initializer is ConstructorThisInitializer))
Parent.PartialContainer.ResolveFieldInitializers (bc);
if (block != null) {
//
// If we use a "this (...)" constructor initializer, then
// do not emit field initializers, they are initialized in the other constructor
//
if (!(Initializer is ConstructorThisInitializer))
Parent.PartialContainer.ResolveFieldInitializers (bc);
if (!IsStatic) {
if (Initializer == null) {
if (Parent.PartialContainer.Kind == MemberKind.Struct) {
@ -1951,7 +1980,7 @@ namespace Mono.CSharp { @@ -1951,7 +1980,7 @@ namespace Mono.CSharp {
//
if ((flags & MethodAttributes.MemberAccessMask) != MethodAttributes.Public) {
implementing = null;
} else if (optional && (container.Interfaces == null || Array.IndexOf (container.Interfaces, implementing.DeclaringType) < 0)) {
} else if (optional && (container.Interfaces == null || !container.Definition.Interfaces.Contains (implementing.DeclaringType))) {
//
// We are not implementing interface when base class already implemented it
//
@ -2142,6 +2171,16 @@ namespace Mono.CSharp { @@ -2142,6 +2171,16 @@ namespace Mono.CSharp {
return true;
}
public override bool Define ()
{
base.Define ();
if (Compiler.Settings.WriteMetadataOnly)
block = null;
return true;
}
public override void Emit()
{
var base_type = Parent.PartialContainer.BaseType;
@ -2505,13 +2544,18 @@ namespace Mono.CSharp { @@ -2505,13 +2544,18 @@ namespace Mono.CSharp {
if (!base.Define ())
return false;
if (block != null && block.IsIterator) {
//
// Current method is turned into automatically generated
// wrapper which creates an instance of iterator
//
Iterator.CreateIterator (this, Parent.PartialContainer, ModFlags);
ModFlags |= Modifiers.DEBUGGER_HIDDEN;
if (block != null) {
if (block.IsIterator) {
//
// Current method is turned into automatically generated
// wrapper which creates an instance of iterator
//
Iterator.CreateIterator (this, Parent.PartialContainer, ModFlags);
ModFlags |= Modifiers.DEBUGGER_HIDDEN;
}
if (Compiler.Settings.WriteMetadataOnly)
block = null;
}
// imlicit and explicit operator of same types are not allowed

2
ICSharpCode.NRefactory.CSharp/Parser/mcs/module.cs

@ -429,7 +429,7 @@ namespace Mono.CSharp @@ -429,7 +429,7 @@ namespace Mono.CSharp
base.EmitContainer ();
if (Compiler.Report.Errors == 0)
if (Compiler.Report.Errors == 0 && !Compiler.Settings.WriteMetadataOnly)
VerifyMembers ();
if (anonymous_types != null) {

161
ICSharpCode.NRefactory.CSharp/Parser/mcs/namespace.cs

@ -41,6 +41,46 @@ namespace Mono.CSharp { @@ -41,6 +41,46 @@ namespace Mono.CSharp {
report.Error (1681, loc, "The global extern alias cannot be redefined");
}
//
// For better error reporting where we try to guess missing using directive
//
public List<string> FindTypeNamespaces (IMemberContext ctx, string name, int arity)
{
List<string> res = null;
foreach (var ns in all_namespaces) {
var type = ns.Value.LookupType (ctx, name, arity, LookupMode.Normal, Location.Null);
if (type != null) {
if (res == null)
res = new List<string> ();
res.Add (ns.Key);
}
}
return res;
}
//
// For better error reporting where compiler tries to guess missing using directive
//
public List<string> FindExtensionMethodNamespaces (IMemberContext ctx, TypeSpec extensionType, string name, int arity)
{
List<string> res = null;
foreach (var ns in all_namespaces) {
var methods = ns.Value.LookupExtensionMethod (ctx, extensionType, name, arity);
if (methods != null) {
if (res == null)
res = new List<string> ();
res.Add (ns.Key);
}
}
return res;
}
public void RegisterNamespace (Namespace child)
{
if (child != this)
@ -181,14 +221,51 @@ namespace Mono.CSharp { @@ -181,14 +221,51 @@ namespace Mono.CSharp {
return;
}
string assembly = null;
string possible_name = fullname + "." + name;
// Only assembly unique name should be added
switch (possible_name) {
case "System.Drawing":
case "System.Web.Services":
case "System.Web":
case "System.Data":
case "System.Configuration":
case "System.Data.Services":
case "System.DirectoryServices":
case "System.Json":
case "System.Net.Http":
case "System.Numerics":
case "System.Runtime.Caching":
case "System.ServiceModel":
case "System.Transactions":
case "System.Web.Routing":
case "System.Xml.Linq":
case "System.Xml":
assembly = possible_name;
break;
case "System.Linq":
case "System.Linq.Expressions":
assembly = "System.Core";
break;
case "System.Windows.Forms":
case "System.Windows.Forms.Layout":
assembly = "System.Windows.Name";
break;
}
assembly = assembly == null ? "an" : "`" + assembly + "'";
if (this is GlobalRootNamespace) {
ctx.Module.Compiler.Report.Error (400, loc,
"The type or namespace name `{0}' could not be found in the global namespace (are you missing an assembly reference?)",
name);
"The type or namespace name `{0}' could not be found in the global namespace. Are you missing {1} assembly reference?",
name, assembly);
} else {
ctx.Module.Compiler.Report.Error (234, loc,
"The type or namespace name `{0}' does not exist in the namespace `{1}'. Are you missing an assembly reference?",
name, GetSignatureForError ());
"The type or namespace name `{0}' does not exist in the namespace `{1}'. Are you missing {2} assembly reference?",
name, GetSignatureForError (), assembly);
}
}
@ -209,10 +286,16 @@ namespace Mono.CSharp { @@ -209,10 +286,16 @@ namespace Mono.CSharp {
ns_parent = this;
}
return ns_parent.TryAddNamespace (name.Basename);
}
Namespace TryAddNamespace (string name)
{
Namespace ns;
if (!ns_parent.namespaces.TryGetValue (name.Basename, out ns)) {
ns = new Namespace (ns_parent, name.Basename);
ns_parent.namespaces.Add (name.Basename, ns);
if (!namespaces.TryGetValue (name, out ns)) {
ns = new Namespace (this, name);
namespaces.Add (name, ns);
}
return ns;
@ -591,6 +674,14 @@ namespace Mono.CSharp { @@ -591,6 +674,14 @@ namespace Mono.CSharp {
}
}
public IEnumerable<string> Conditionals {
get {
if (conditionals == null)
return Enumerable.Empty<string> ();
return conditionals.Where (kv => kv.Value).Select (kv => kv.Key);
}
}
public string FileName {
get {
return file.Name;
@ -801,8 +892,10 @@ namespace Mono.CSharp { @@ -801,8 +892,10 @@ namespace Mono.CSharp {
name = mn.Name;
}
var names_container = Parent == null ? Module : (TypeContainer) this;
MemberCore mc;
if (defined_names.TryGetValue (name, out mc)) {
if (names_container.DefinedNames.TryGetValue (name, out mc)) {
if (tc is NamespaceContainer && mc is NamespaceContainer) {
containers.Add (tc);
return;
@ -816,7 +909,7 @@ namespace Mono.CSharp { @@ -816,7 +909,7 @@ namespace Mono.CSharp {
GetSignatureForError (), mn.GetSignatureForError ());
}
} else {
defined_names.Add (name, tc);
names_container.DefinedNames.Add (name, tc);
}
base.AddTypeContainer (tc);
@ -1100,44 +1193,6 @@ namespace Mono.CSharp { @@ -1100,44 +1193,6 @@ namespace Mono.CSharp {
return match;
}
static void MsgtryRef (string s)
{
Console.WriteLine (" Try using -r:" + s);
}
static void MsgtryPkg (string s)
{
Console.WriteLine (" Try using -pkg:" + s);
}
public static void Error_NamespaceNotFound (Location loc, string name, Report Report)
{
Report.Error (246, loc, "The type or namespace name `{0}' could not be found. Are you missing a using directive or an assembly reference?",
name);
switch (name) {
case "Gtk": case "GtkSharp":
MsgtryPkg ("gtk-sharp-2.0");
break;
case "Gdk": case "GdkSharp":
MsgtryPkg ("gdk-sharp-2.0");
break;
case "Glade": case "GladeSharp":
MsgtryPkg ("glade-sharp-2.0");
break;
case "System.Drawing":
case "System.Web.Services":
case "System.Web":
case "System.Data":
case "System.Windows.Forms":
MsgtryRef (name);
break;
}
}
protected override void DefineNamespace ()
{
if (namespace_using_table == null)
@ -1180,11 +1235,23 @@ namespace Mono.CSharp { @@ -1180,11 +1235,23 @@ namespace Mono.CSharp {
entry.Define (this);
//
// It's needed for repl only, when using clause cannot be resolved don't hold it in
// global list which is resolved for each evaluation
//
if (entry.ResolvedExpression == null) {
clauses.RemoveAt (i--);
continue;
}
Namespace using_ns = entry.ResolvedExpression as Namespace;
if (using_ns == null)
continue;
if (list.Contains (using_ns)) {
// Ensure we don't report the warning multiple times in repl
clauses.RemoveAt (i--);
Compiler.Report.Warning (105, 3, entry.Location,
"The using directive for `{0}' appeared previously in this namespace", using_ns.GetSignatureForError ());
} else {

12
ICSharpCode.NRefactory.CSharp/Parser/mcs/nullable.cs

@ -539,8 +539,8 @@ namespace Mono.CSharp.Nullable @@ -539,8 +539,8 @@ namespace Mono.CSharp.Nullable
Expression user_operator;
MethodSpec wrap_ctor;
public LiftedBinaryOperator (Binary.Operator op, Expression left, Expression right, Location loc)
: base (op, left, right, loc)
public LiftedBinaryOperator (Binary.Operator op, Expression left, Expression right)
: base (op, left, right)
{
}
@ -583,7 +583,7 @@ namespace Mono.CSharp.Nullable @@ -583,7 +583,7 @@ namespace Mono.CSharp.Nullable
Constant c = new BoolConstant (ec.BuiltinTypes, Oper == Operator.Inequality, loc);
if ((Oper & Operator.EqualityMask) != 0) {
ec.Report.Warning (472, 2, loc, "The result of comparing value type `{0}' with null is `{1}'",
ec.Report.Warning (472, 2, loc, "The result of comparing value type `{0}' with null is always `{1}'",
TypeManager.CSharpName (expr.Type), c.GetValueAsLiteral ());
} else {
ec.Report.Warning (464, 2, loc, "The result of comparing type `{0}' with null is always `{1}'",
@ -1000,12 +1000,12 @@ namespace Mono.CSharp.Nullable @@ -1000,12 +1000,12 @@ namespace Mono.CSharp.Nullable
{
Expression left, right;
Unwrap unwrap;
public NullCoalescingOperator (Expression left, Expression right, Location loc)
public NullCoalescingOperator (Expression left, Expression right)
{
this.left = left;
this.right = right;
this.loc = loc;
this.loc = left.Location;
}
public Expression LeftExpression {

40
ICSharpCode.NRefactory.CSharp/Parser/mcs/outline.cs

@ -29,6 +29,8 @@ @@ -29,6 +29,8 @@
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
#if !NET_2_1
using System;
using System.Reflection;
using System.Collections;
@ -88,9 +90,7 @@ public class Outline { @@ -88,9 +90,7 @@ public class Outline {
OutlineParams (method.GetParameters ());
o.Write (")");
#if NET_2_0
WriteGenericConstraints (t.GetGenericArguments ());
#endif
o.WriteLine (";");
return;
@ -119,9 +119,9 @@ public class Outline { @@ -119,9 +119,9 @@ public class Outline {
if (underlyingType != typeof (int))
o.Write (" : {0}", FormatType (underlyingType));
}
#if NET_2_0
WriteGenericConstraints (t.GetGenericArguments ());
#endif
o.WriteLine (" {");
o.Indent++;
@ -142,7 +142,6 @@ public class Outline { @@ -142,7 +142,6 @@ public class Outline {
first = true;
foreach (ConstructorInfo ci in t.GetConstructors (DefaultFlags)) {
if (! ShowMember (ci))
continue;
@ -150,6 +149,7 @@ public class Outline { @@ -150,6 +149,7 @@ public class Outline {
o.WriteLine ();
first = false;
OutlineMemberAttribute (ci);
OutlineConstructor (ci);
o.WriteLine ();
@ -169,7 +169,8 @@ public class Outline { @@ -169,7 +169,8 @@ public class Outline {
if (first)
o.WriteLine ();
first = false;
OutlineMemberAttribute (m);
OutlineMethod (m);
o.WriteLine ();
@ -191,6 +192,7 @@ public class Outline { @@ -191,6 +192,7 @@ public class Outline {
o.WriteLine ();
first = false;
OutlineMemberAttribute (m);
OutlineOperator (m);
o.WriteLine ();
@ -208,6 +210,7 @@ public class Outline { @@ -208,6 +210,7 @@ public class Outline {
o.WriteLine ();
first = false;
OutlineMemberAttribute (pi);
OutlineProperty (pi);
o.WriteLine ();
@ -224,6 +227,7 @@ public class Outline { @@ -224,6 +227,7 @@ public class Outline {
o.WriteLine ();
first = false;
OutlineMemberAttribute (fi);
OutlineField (fi);
o.WriteLine ();
@ -240,6 +244,7 @@ public class Outline { @@ -240,6 +244,7 @@ public class Outline {
o.WriteLine ();
first = false;
OutlineMemberAttribute (ei);
OutlineEvent (ei);
o.WriteLine ();
@ -286,6 +291,15 @@ public class Outline { @@ -286,6 +291,15 @@ public class Outline {
o.WriteLine ("[Obsolete]");
}
void OutlineMemberAttribute (MemberInfo mi)
{
if (!mi.IsDefined (typeof (System.ObsoleteAttribute), false))
return;
var oa = mi.GetCustomAttributes (typeof (System.ObsoleteAttribute), false) [0] as ObsoleteAttribute;
var msg = oa.Message;
o.WriteLine ("[Obsolete{0}]", msg == null || msg == "" ? "" : string.Format ("(\"{0}\")", msg));
}
void OutlineEvent (EventInfo ei)
{
MethodBase accessor = ei.GetAddMethod (true);
@ -382,15 +396,11 @@ public class Outline { @@ -382,15 +396,11 @@ public class Outline {
}
o.Write (mi.Name);
#if NET_2_0
o.Write (FormatGenericParams (mi.GetGenericArguments ()));
#endif
o.Write (" (");
OutlineParams (mi.GetParameters ());
o.Write (")");
#if NET_2_0
WriteGenericConstraints (mi.GetGenericArguments ());
#endif
o.Write (";");
}
@ -549,7 +559,6 @@ public class Outline { @@ -549,7 +559,6 @@ public class Outline {
}
}
#if NET_2_0
string FormatGenericParams (Type [] args)
{
StringBuilder sb = new StringBuilder ();
@ -565,7 +574,6 @@ public class Outline { @@ -565,7 +574,6 @@ public class Outline {
sb.Append (">");
return sb.ToString ();
}
#endif
// TODO: fine tune this so that our output is less verbose. We need to figure
// out a way to do this while not making things confusing.
@ -665,9 +673,7 @@ public class Outline { @@ -665,9 +673,7 @@ public class Outline {
void GetTypeName (StringBuilder sb, Type t)
{
sb.Append (RemoveGenericArity (t.Name));
#if NET_2_0
sb.Append (FormatGenericParams (t.GetGenericArguments ()));
#endif
}
string GetFullName (Type t)
@ -679,12 +685,10 @@ public class Outline { @@ -679,12 +685,10 @@ public class Outline {
void GetFullName_recursed (StringBuilder sb, Type t, bool recursed)
{
#if NET_2_0
if (t.IsGenericParameter) {
sb.Append (t.Name);
return;
}
#endif
if (t.DeclaringType != null) {
GetFullName_recursed (sb, t.DeclaringType, true);
@ -702,7 +706,6 @@ public class Outline { @@ -702,7 +706,6 @@ public class Outline {
GetTypeName (sb, t);
}
#if NET_2_0
void WriteGenericConstraints (Type [] args)
{
@ -758,7 +761,6 @@ public class Outline { @@ -758,7 +761,6 @@ public class Outline {
}
}
}
#endif
string OperatorFromName (string name)
{
@ -1022,3 +1024,5 @@ public class Comparer : IComparer { @@ -1022,3 +1024,5 @@ public class Comparer : IComparer {
}
}
}
#endif

28
ICSharpCode.NRefactory.CSharp/Parser/mcs/property.cs

@ -362,8 +362,13 @@ namespace Mono.CSharp @@ -362,8 +362,13 @@ namespace Mono.CSharp
CheckAbstractAndExtern (block != null);
CheckProtectedModifier ();
if (block != null && block.IsIterator)
Iterator.CreateIterator (this, Parent.PartialContainer, ModFlags);
if (block != null) {
if (block.IsIterator)
Iterator.CreateIterator (this, Parent.PartialContainer, ModFlags);
if (Compiler.Settings.WriteMetadataOnly)
block = null;
}
return null;
}
@ -906,7 +911,7 @@ namespace Mono.CSharp @@ -906,7 +911,7 @@ namespace Mono.CSharp
public override void Emit (TypeDefinition parent)
{
if ((method.ModFlags & (Modifiers.ABSTRACT | Modifiers.EXTERN)) == 0) {
if ((method.ModFlags & (Modifiers.ABSTRACT | Modifiers.EXTERN)) == 0 && !Compiler.Settings.WriteMetadataOnly) {
block = new ToplevelBlock (Compiler, ParameterInfo, Location) {
IsCompilerGenerated = true
};
@ -938,11 +943,10 @@ namespace Mono.CSharp @@ -938,11 +943,10 @@ namespace Mono.CSharp
var cond = new BooleanExpression (new Binary (Binary.Operator.Inequality,
new Cast (new TypeExpression (Module.Compiler.BuiltinTypes.Object, Location), new LocalVariableReference (obj1, Location), Location),
new Cast (new TypeExpression (Module.Compiler.BuiltinTypes.Object, Location), new LocalVariableReference (obj2, Location), Location),
Location));
new Cast (new TypeExpression (Module.Compiler.BuiltinTypes.Object, Location), new LocalVariableReference (obj2, Location), Location)));
var body = new ExplicitBlock (block, Location, Location);
block.AddStatement (new Do (body, cond, Location));
block.AddStatement (new Do (body, cond, Location, Location));
body.AddStatement (new StatementExpression (
new SimpleAssign (new LocalVariableReference (obj2, Location), new LocalVariableReference (obj1, Location))));
@ -1194,6 +1198,9 @@ namespace Mono.CSharp @@ -1194,6 +1198,9 @@ namespace Mono.CSharp
if (!method_data.Define (parent.PartialContainer, method.GetFullName (MemberName)))
return null;
if (Compiler.Settings.WriteMetadataOnly)
block = null;
MethodBuilder mb = method_data.MethodBuilder;
Spec = new MethodSpec (MemberKind.Method, parent.PartialContainer.Definition, this, ReturnType, mb, ParameterInfo, method.ModFlags);
@ -1440,7 +1447,14 @@ namespace Mono.CSharp @@ -1440,7 +1447,14 @@ namespace Mono.CSharp
public override MethodBuilder Define (TypeContainer parent)
{
parameters.Resolve (this);
// Disable reporting, parameters are resolved twice
Report.DisableReporting ();
try {
parameters.Resolve (this);
} finally {
Report.EnableReporting ();
}
return base.Define (parent);
}

16
ICSharpCode.NRefactory.CSharp/Parser/mcs/report.cs

@ -49,7 +49,7 @@ namespace Mono.CSharp { @@ -49,7 +49,7 @@ namespace Mono.CSharp {
809, 824,
1030, 1058, 1060, 1066,
1522, 1570, 1571, 1572, 1573, 1574, 1580, 1581, 1584, 1587, 1589, 1590, 1591, 1592,
1607, 1616, 1633, 1634, 1635, 1685, 1690, 1691, 1692, 1695, 1696, 1699,
1607, 1616, 1633, 1634, 1635, 1685, 1690, 1691, 1692, 1695, 1696, 1697, 1699,
1700, 1701, 1702, 1709, 1711, 1717, 1718, 1720, 1735,
1901, 1956, 1981, 1998,
2002, 2023, 2029,
@ -170,12 +170,6 @@ namespace Mono.CSharp { @@ -170,12 +170,6 @@ namespace Mono.CSharp {
extra_information.Add (msg);
}
public bool CheckWarningCode (string code, Location loc)
{
Warning (1691, 1, loc, "`{0}' is not a valid warning number", code);
return false;
}
public bool CheckWarningCode (int code, Location loc)
{
if (AllWarningsHashSet == null)
@ -184,7 +178,8 @@ namespace Mono.CSharp { @@ -184,7 +178,8 @@ namespace Mono.CSharp {
if (AllWarningsHashSet.Contains (code))
return true;
return CheckWarningCode (code.ToString (), loc);
Warning (1691, 1, loc, "`{0}' is not a valid warning number", code);
return false;
}
public void ExtraInformation (Location loc, string msg)
@ -644,6 +639,11 @@ namespace Mono.CSharp { @@ -644,6 +639,11 @@ namespace Mono.CSharp {
bool showFullPaths;
public void ClearSession ()
{
session_messages = null;
}
public override void Print (AbstractMessage msg, bool showFullPath)
{
//

93
ICSharpCode.NRefactory.CSharp/Parser/mcs/settings.cs

@ -159,6 +159,8 @@ namespace Mono.CSharp { @@ -159,6 +159,8 @@ namespace Mono.CSharp {
public RuntimeVersion StdLibRuntimeVersion;
public bool WriteMetadataOnly;
readonly List<string> conditional_symbols;
readonly List<SourceFile> source_files;
@ -180,10 +182,8 @@ namespace Mono.CSharp { @@ -180,10 +182,8 @@ namespace Mono.CSharp {
StdLibRuntimeVersion = RuntimeVersion.v4;
WarningLevel = 4;
if (Environment.OSVersion.Platform == PlatformID.Win32NT)
TabSize = 4;
else
TabSize = 8;
// Default to 1 or mdb files would be platform speficic
TabSize = 1;
AssemblyReferences = new List<string> ();
AssemblyReferencesAliases = new List<Tuple<string, string>> ();
@ -565,36 +565,22 @@ namespace Mono.CSharp { @@ -565,36 +565,22 @@ namespace Mono.CSharp {
source_file_index.Add (path, unit.Index);
}
void AddWarningAsError (string warningId, CompilerSettings settings)
public bool ProcessWarningsList (string text, Action<int> action)
{
int id;
try {
id = int.Parse (warningId);
} catch {
report.CheckWarningCode (warningId, Location.Null);
return;
}
if (!report.CheckWarningCode (id, Location.Null))
return;
settings.AddWarningAsError (id);
}
bool valid = true;
foreach (string wid in text.Split (numeric_value_separator)) {
int id;
if (!int.TryParse (wid, NumberStyles.AllowLeadingWhite, CultureInfo.InvariantCulture, out id)) {
report.Error (1904, "`{0}' is not a valid warning number", wid);
valid = false;
continue;
}
void RemoveWarningAsError (string warningId, CompilerSettings settings)
{
int id;
try {
id = int.Parse (warningId);
} catch {
report.CheckWarningCode (warningId, Location.Null);
return;
if (report.CheckWarningCode (id, Location.Null))
action (id);
}
if (!report.CheckWarningCode (id, Location.Null))
return;
settings.AddWarningOnly (id);
return valid;
}
void Error_RequiresArgument (string option)
@ -684,8 +670,9 @@ namespace Mono.CSharp { @@ -684,8 +670,9 @@ namespace Mono.CSharp {
{
output.WriteLine (
"Other flags in the compiler\n" +
" --fatal[=COUNT] Makes errors after COUNT fatal\n" +
" --fatal[=COUNT] Makes error after COUNT fatal\n" +
" --lint Enhanced warnings\n" +
" --metadata-only Produced assembly will contain metadata only\n" +
" --parse Only parses the source file\n" +
" --runtime:VERSION Sets mscorlib.dll metadata version: v1, v2, v4\n" +
" --stacktrace Shows stack trace at error location\n" +
@ -947,7 +934,7 @@ namespace Mono.CSharp { @@ -947,7 +934,7 @@ namespace Mono.CSharp {
return ParseResult.Success;
case "/debug":
if (value == "full" || value == "pdbonly" || idx < 0) {
if (value.Equals ("full", StringComparison.OrdinalIgnoreCase) || value.Equals ("pdbonly", StringComparison.OrdinalIgnoreCase) || idx < 0) {
settings.GenerateDebugInfo = true;
return ParseResult.Success;
}
@ -997,8 +984,8 @@ namespace Mono.CSharp { @@ -997,8 +984,8 @@ namespace Mono.CSharp {
settings.WarningsAreErrors = true;
parser_settings.WarningsAreErrors = true;
} else {
foreach (string wid in value.Split (numeric_value_separator))
AddWarningAsError (wid, settings);
if (!ProcessWarningsList (value, v => settings.AddWarningAsError (v)))
return ParseResult.Error;
}
return ParseResult.Success;
@ -1006,12 +993,13 @@ namespace Mono.CSharp { @@ -1006,12 +993,13 @@ namespace Mono.CSharp {
if (value.Length == 0) {
settings.WarningsAreErrors = false;
} else {
foreach (string wid in value.Split (numeric_value_separator))
RemoveWarningAsError (wid, settings);
if (!ProcessWarningsList (value, v => settings.AddWarningOnly (v)))
return ParseResult.Error;
}
return ParseResult.Success;
case "/warn":
case "/w":
if (value.Length == 0) {
Error_RequiresArgument (option);
return ParseResult.Error;
@ -1021,28 +1009,15 @@ namespace Mono.CSharp { @@ -1021,28 +1009,15 @@ namespace Mono.CSharp {
return ParseResult.Success;
case "/nowarn":
if (value.Length == 0) {
Error_RequiresArgument (option);
return ParseResult.Error;
}
if (value.Length == 0) {
Error_RequiresArgument (option);
return ParseResult.Error;
}
var warns = value.Split (numeric_value_separator);
foreach (string wc in warns) {
try {
if (wc.Trim ().Length == 0)
continue;
if (!ProcessWarningsList (value, v => settings.SetIgnoreWarning (v)))
return ParseResult.Error;
int warn = Int32.Parse (wc);
if (warn < 1) {
throw new ArgumentOutOfRangeException ("warn");
}
settings.SetIgnoreWarning (warn);
} catch {
report.Error (1904, "`{0}' is not a valid warning number", wc);
return ParseResult.Error;
}
}
return ParseResult.Success;
return ParseResult.Success;
case "/noconfig":
settings.LoadDefaultReferences = false;
@ -1451,6 +1426,10 @@ namespace Mono.CSharp { @@ -1451,6 +1426,10 @@ namespace Mono.CSharp {
settings.LoadDefaultReferences = false;
return ParseResult.Success;
case "--metadata-only":
settings.WriteMetadataOnly = true;
return ParseResult.Success;
default:
if (arg.StartsWith ("--fatal", StringComparison.Ordinal)){
int fatal = 1;
@ -1565,7 +1544,7 @@ namespace Mono.CSharp { @@ -1565,7 +1544,7 @@ namespace Mono.CSharp {
" -reference:A1[,An] Imports metadata from the specified assembly (short: -r)\n" +
" -reference:ALIAS=A Imports metadata using specified extern alias (short: -r)\n" +
" -sdk:VERSION Specifies SDK version of referenced assemblies\n" +
" VERSION can be one of: 2, 4 (default) or custom value\n" +
" VERSION can be one of: 2, 4, 4.5 (default) or a custom value\n" +
" -target:KIND Specifies the format of the output assembly (short: -t)\n" +
" KIND can be one of: exe, winexe, library, module\n" +
" -unsafe[+|-] Allows to compile code which uses unsafe keyword\n" +

99
ICSharpCode.NRefactory.CSharp/Parser/mcs/statement.cs

@ -281,11 +281,16 @@ namespace Mono.CSharp { @@ -281,11 +281,16 @@ namespace Mono.CSharp {
public Expression expr;
public Statement EmbeddedStatement;
public Do (Statement statement, BooleanExpression bool_expr, Location l)
public Do (Statement statement, BooleanExpression bool_expr, Location doLocation, Location whileLocation)
{
expr = bool_expr;
EmbeddedStatement = statement;
loc = l;
loc = doLocation;
WhileLocation = whileLocation;
}
public Location WhileLocation {
get; private set;
}
public override bool Resolve (BlockContext ec)
@ -332,7 +337,7 @@ namespace Mono.CSharp { @@ -332,7 +337,7 @@ namespace Mono.CSharp {
ec.MarkLabel (ec.LoopBegin);
// Mark start of while condition
ec.Mark (expr.Location);
ec.Mark (WhileLocation);
//
// Dead code elimination
@ -461,7 +466,7 @@ namespace Mono.CSharp { @@ -461,7 +466,7 @@ namespace Mono.CSharp {
ec.MarkLabel (ec.LoopBegin);
ec.Mark (expr.Location);
ec.Mark (loc);
expr.EmitBranchable (ec, while_loop, true);
ec.MarkLabel (ec.LoopEnd);
@ -784,12 +789,10 @@ namespace Mono.CSharp { @@ -784,12 +789,10 @@ namespace Mono.CSharp {
public sealed override bool Resolve (BlockContext ec)
{
if (!DoResolve (ec))
return false;
var res = DoResolve (ec);
unwind_protect = ec.CurrentBranching.AddReturnOrigin (ec.CurrentBranching.CurrentUsageVector, this);
ec.CurrentBranching.CurrentUsageVector.Goto ();
return true;
return res;
}
}
@ -880,7 +883,6 @@ namespace Mono.CSharp { @@ -880,7 +883,6 @@ namespace Mono.CSharp {
return true;
}
// TODO: Better error message
if (async_type.Kind == MemberKind.Void) {
ec.Report.Error (127, loc,
"`{0}': A return keyword must not be followed by any expression when method returns void",
@ -911,6 +913,15 @@ namespace Mono.CSharp { @@ -911,6 +913,15 @@ namespace Mono.CSharp {
}
}
} else {
// Same error code as .NET but better error message
if (block_return_type.Kind == MemberKind.Void) {
ec.Report.Error (127, loc,
"`{0}': A return keyword must not be followed by any expression when delegate returns void",
am.GetSignatureForError ());
return false;
}
var l = am as AnonymousMethodBody;
if (l != null && l.ReturnTypeInference != null && expr != null) {
l.ReturnTypeInference.AddCommonTypeBound (expr.Type);
@ -952,10 +963,9 @@ namespace Mono.CSharp { @@ -952,10 +963,9 @@ namespace Mono.CSharp {
async_return.EmitAssign (ec);
ec.EmitEpilogue ();
ec.Emit (unwind_protect ? OpCodes.Leave : OpCodes.Br, async_body.BodyEnd);
}
ec.Emit (unwind_protect ? OpCodes.Leave : OpCodes.Br, async_body.BodyEnd);
return;
}
@ -1438,6 +1448,7 @@ namespace Mono.CSharp { @@ -1438,6 +1448,7 @@ namespace Mono.CSharp {
protected FullNamedExpression type_expr;
protected LocalVariable li;
protected List<Declarator> declarators;
TypeSpec type;
public BlockVariableDeclaration (FullNamedExpression type, LocalVariable li)
{
@ -1514,8 +1525,7 @@ namespace Mono.CSharp { @@ -1514,8 +1525,7 @@ namespace Mono.CSharp {
public bool Resolve (BlockContext bc, bool resolveDeclaratorInitializers)
{
if (li.Type == null) {
TypeSpec type = null;
if (type == null && !li.IsCompilerGenerated) {
var vexpr = type_expr as VarExpr;
//
@ -1623,8 +1633,10 @@ namespace Mono.CSharp { @@ -1623,8 +1633,10 @@ namespace Mono.CSharp {
if (declarators != null) {
foreach (var d in declarators) {
d.Variable.CreateBuilder (ec);
if (d.Initializer != null)
if (d.Initializer != null) {
ec.Mark (d.Variable.Location);
((ExpressionStatement) d.Initializer).EmitStatement (ec);
}
}
}
}
@ -2464,15 +2476,6 @@ namespace Mono.CSharp { @@ -2464,15 +2476,6 @@ namespace Mono.CSharp {
if (ec.CurrentAnonymousMethod is StateMachineInitializer && ParametersBlock.Original == ec.CurrentAnonymousMethod.Block.Original)
return ec.CurrentAnonymousMethod.Storey;
//
// When referencing a variable inside iterator where all
// variables will be captured anyway we don't need to create
// another storey context
//
if (ParametersBlock.StateMachine is IteratorStorey) {
return ParametersBlock.StateMachine;
}
if (am_storey == null) {
MemberBase mc = ec.MemberContext as MemberBase;
@ -4248,10 +4251,10 @@ namespace Mono.CSharp { @@ -4248,10 +4251,10 @@ namespace Mono.CSharp {
Expression cond = null;
for (int ci = 0; ci < s.Labels.Count; ++ci) {
var e = new Binary (Binary.Operator.Equality, value, s.Labels[ci].Converted, loc);
var e = new Binary (Binary.Operator.Equality, value, s.Labels[ci].Converted);
if (ci > 0) {
cond = new Binary (Binary.Operator.LogicalOr, cond, e, loc);
cond = new Binary (Binary.Operator.LogicalOr, cond, e);
} else {
cond = e;
}
@ -4541,6 +4544,12 @@ namespace Mono.CSharp { @@ -4541,6 +4544,12 @@ namespace Mono.CSharp {
ec.MarkLabel (start_finally);
if (finally_host != null) {
finally_host.Define ();
finally_host.Emit ();
// Now it's safe to add, to close it properly and emit sequence points
finally_host.Parent.AddMember (finally_host);
var ce = new CallEmitter ();
ce.InstanceExpression = new CompilerGeneratedThis (ec.CurrentType, loc);
ce.EmitPredefined (ec, finally_host.Spec, new Arguments (0));
@ -4755,21 +4764,9 @@ namespace Mono.CSharp { @@ -4755,21 +4764,9 @@ namespace Mono.CSharp {
locked = false;
}
using (ec.Set (ResolveContext.Options.LockScope)) {
ec.StartFlowBranching (this);
Statement.Resolve (ec);
ec.EndFlowBranching ();
}
if (lv != null) {
lv.IsLockedByStatement = locked;
}
base.Resolve (ec);
//
// Have to keep original lock value around to unlock same location
// in the case the original has changed or is null
// in the case of original value has changed or is null
//
expr_copy = TemporaryVariableReference.Create (ec.BuiltinTypes.Object, ec.CurrentBlock, loc);
expr_copy.Resolve (ec);
@ -4782,6 +4779,18 @@ namespace Mono.CSharp { @@ -4782,6 +4779,18 @@ namespace Mono.CSharp {
lock_taken.Resolve (ec);
}
using (ec.Set (ResolveContext.Options.LockScope)) {
ec.StartFlowBranching (this);
Statement.Resolve (ec);
ec.EndFlowBranching ();
}
if (lv != null) {
lv.IsLockedByStatement = locked;
}
base.Resolve (ec);
return true;
}
@ -5136,8 +5145,8 @@ namespace Mono.CSharp { @@ -5136,8 +5145,8 @@ namespace Mono.CSharp {
// fixed (T* e_ptr = (e == null || e.Length == 0) ? null : converted [0])
//
converted = new Conditional (new BooleanExpression (new Binary (Binary.Operator.LogicalOr,
new Binary (Binary.Operator.Equality, initializer, new NullLiteral (loc), loc),
new Binary (Binary.Operator.Equality, new MemberAccess (initializer, "Length"), new IntConstant (bc.BuiltinTypes, 0, loc), loc), loc)),
new Binary (Binary.Operator.Equality, initializer, new NullLiteral (loc)),
new Binary (Binary.Operator.Equality, new MemberAccess (initializer, "Length"), new IntConstant (bc.BuiltinTypes, 0, loc)))),
new NullLiteral (loc),
converted, loc);
@ -5703,7 +5712,7 @@ namespace Mono.CSharp { @@ -5703,7 +5712,7 @@ namespace Mono.CSharp {
// Add conditional call when disposing possible null variable
if (!type.IsStruct || type.IsNullableType)
dispose = new If (new Binary (Binary.Operator.Inequality, lvr, new NullLiteral (loc), loc), dispose, dispose.loc);
dispose = new If (new Binary (Binary.Operator.Inequality, lvr, new NullLiteral (loc)), dispose, dispose.loc);
return dispose;
}
@ -5717,7 +5726,7 @@ namespace Mono.CSharp { @@ -5717,7 +5726,7 @@ namespace Mono.CSharp {
{
for (int i = declarators.Count - 1; i >= 0; --i) {
var d = declarators [i];
var vd = new VariableDeclaration (d.Variable, type_expr.Location);
var vd = new VariableDeclaration (d.Variable, d.Variable.Location);
vd.Initializer = d.Initializer;
vd.IsNested = true;
vd.dispose_call = CreateDisposeCall (bc, d.Variable);
@ -5953,7 +5962,7 @@ namespace Mono.CSharp { @@ -5953,7 +5962,7 @@ namespace Mono.CSharp {
if (variable_ref == null)
return false;
for_each.body.AddScopeStatement (new StatementExpression (new CompilerAssign (variable_ref, access, Location.Null), for_each.variable.Location));
for_each.body.AddScopeStatement (new StatementExpression (new CompilerAssign (variable_ref, access, Location.Null), for_each.type.Location));
bool ok = true;
@ -6049,7 +6058,7 @@ namespace Mono.CSharp { @@ -6049,7 +6058,7 @@ namespace Mono.CSharp {
var idisaposable_test = new Binary (Binary.Operator.Inequality, new CompilerAssign (
dispose_variable.CreateReferenceExpression (bc, loc),
new As (lv.CreateReferenceExpression (bc, loc), new TypeExpression (dispose_variable.Type, loc), loc),
loc), new NullLiteral (loc), loc);
loc), new NullLiteral (loc));
var m = bc.Module.PredefinedMembers.IDisposableDispose.Resolve (loc);
@ -6264,7 +6273,7 @@ namespace Mono.CSharp { @@ -6264,7 +6273,7 @@ namespace Mono.CSharp {
if (variable_ref == null)
return false;
for_each.body.AddScopeStatement (new StatementExpression (new CompilerAssign (variable_ref, current_pe, Location.Null), variable.Location));
for_each.body.AddScopeStatement (new StatementExpression (new CompilerAssign (variable_ref, current_pe, Location.Null), for_each.type.Location));
var init = new Invocation (get_enumerator_mg, null);

14
ICSharpCode.NRefactory.CSharp/Parser/mcs/support.cs

@ -127,7 +127,7 @@ namespace Mono.CSharp { @@ -127,7 +127,7 @@ namespace Mono.CSharp {
return true;
}
}
#if !FULL_AST
/// <summary>
/// This is an arbitrarily seekable StreamReader wrapper.
///
@ -137,21 +137,23 @@ namespace Mono.CSharp { @@ -137,21 +137,23 @@ namespace Mono.CSharp {
/// </summary>
public class SeekableStreamReader : IDisposable
{
public const int DefaultReadAheadSize = 2048;
StreamReader reader;
Stream stream;
static char[] buffer;
char[] buffer;
int read_ahead_length; // the length of read buffer
int buffer_start; // in chars
int char_count; // count of filled characters in buffer[]
int pos; // index into buffer[]
public SeekableStreamReader (Stream stream, Encoding encoding)
public SeekableStreamReader (Stream stream, Encoding encoding, char[] sharedBuffer = null)
{
this.stream = stream;
this.buffer = sharedBuffer;
const int default_read_ahead = 2048;
InitializeStream (default_read_ahead);
InitializeStream (DefaultReadAheadSize);
reader = new StreamReader (stream, encoding, true);
}
@ -274,7 +276,7 @@ namespace Mono.CSharp { @@ -274,7 +276,7 @@ namespace Mono.CSharp {
return buffer [pos++];
}
}
#endif
public class UnixUtils {
[System.Runtime.InteropServices.DllImport ("libc", EntryPoint="isatty")]
extern static int _isatty (int fd);

38
ICSharpCode.NRefactory.CSharp/Parser/mcs/typemanager.cs

@ -144,7 +144,7 @@ namespace Mono.CSharp @@ -144,7 +144,7 @@ namespace Mono.CSharp
{
var ctx = module.Compiler;
foreach (var p in types) {
var found = PredefinedType.Resolve (module, p.Kind, p.Namespace, p.Name, p.Arity);
var found = PredefinedType.Resolve (module, p.Kind, p.Namespace, p.Name, p.Arity, true, true);
if (found == null || found == p)
continue;
@ -340,6 +340,7 @@ namespace Mono.CSharp @@ -340,6 +340,7 @@ namespace Mono.CSharp
public readonly PredefinedMember<MethodSpec> AsyncVoidMethodBuilderSetStateMachine;
public readonly PredefinedMember<MethodSpec> AsyncVoidMethodBuilderOnCompleted;
public readonly PredefinedMember<MethodSpec> AsyncVoidMethodBuilderOnCompletedUnsafe;
public readonly PredefinedMember<MethodSpec> AsyncStateMachineAttributeCtor;
public readonly PredefinedMember<MethodSpec> DebuggerBrowsableAttributeCtor;
public readonly PredefinedMember<MethodSpec> DecimalCtor;
public readonly PredefinedMember<MethodSpec> DecimalCtorInt;
@ -357,6 +358,7 @@ namespace Mono.CSharp @@ -357,6 +358,7 @@ namespace Mono.CSharp
public readonly PredefinedMember<MethodSpec> IEnumerableGetEnumerator;
public readonly PredefinedMember<MethodSpec> InterlockedCompareExchange;
public readonly PredefinedMember<MethodSpec> InterlockedCompareExchange_T;
public readonly PredefinedMember<MethodSpec> IteratorStateMachineAttributeCtor;
public readonly PredefinedMember<MethodSpec> FixedBufferAttributeCtor;
public readonly PredefinedMember<MethodSpec> MethodInfoGetMethodFromHandle;
public readonly PredefinedMember<MethodSpec> MethodInfoGetMethodFromHandle2;
@ -549,6 +551,10 @@ namespace Mono.CSharp @@ -549,6 +551,10 @@ namespace Mono.CSharp
}, false),
btypes.Void));
AsyncStateMachineAttributeCtor = new PredefinedMember<MethodSpec> (module, atypes.AsyncStateMachine,
MemberFilter.Constructor (ParametersCompiled.CreateFullyResolved (
btypes.Type)));
DebuggerBrowsableAttributeCtor = new PredefinedMember<MethodSpec> (module, atypes.DebuggerBrowsable,
MemberFilter.Constructor (null));
@ -625,6 +631,10 @@ namespace Mono.CSharp @@ -625,6 +631,10 @@ namespace Mono.CSharp
}, false),
null));
IteratorStateMachineAttributeCtor = new PredefinedMember<MethodSpec> (module, atypes.IteratorStateMachine,
MemberFilter.Constructor (ParametersCompiled.CreateFullyResolved (
btypes.Type)));
MethodInfoGetMethodFromHandle = new PredefinedMember<MethodSpec> (module, types.MethodBase,
"GetMethodFromHandle", MemberKind.Method, types.RuntimeMethodHandle);
@ -748,7 +758,7 @@ namespace Mono.CSharp @@ -748,7 +758,7 @@ namespace Mono.CSharp
if (type != null)
return true;
type = Resolve (module, kind, ns, name, arity, false);
type = Resolve (module, kind, ns, name, arity, false, false);
return type != null;
}
@ -757,17 +767,21 @@ namespace Mono.CSharp @@ -757,17 +767,21 @@ namespace Mono.CSharp
return ns + "." + name;
}
public static TypeSpec Resolve (ModuleContainer module, MemberKind kind, string ns, string name, int arity)
public static TypeSpec Resolve (ModuleContainer module, MemberKind kind, string ns, string name, int arity, bool required, bool reportErrors)
{
return Resolve (module, kind, ns, name, arity, true);
}
//
// Cannot call it with true because it could create non-existent namespaces for
// predefined types. It's set to true only for build-in types which all must
// exist therefore it does not matter, for predefined types we don't want to create
// fake namespaces when type is optional and does not exist (e.g. System.Linq).
//
Namespace type_ns = module.GlobalRootNamespace.GetNamespace (ns, required);
IList<TypeSpec> found = null;
if (type_ns != null)
found = type_ns.GetAllTypes (name);
public static TypeSpec Resolve (ModuleContainer module, MemberKind kind, string ns, string name, int arity, bool reportErrors)
{
Namespace type_ns = module.GlobalRootNamespace.GetNamespace (ns, true);
var found = type_ns.GetAllTypes (name);
if (found == null) {
if (reportErrors)
if (reportErrors )
module.Compiler.Report.Error (518, "The predefined type `{0}.{1}' is not defined or imported", ns, name);
return null;
@ -837,13 +851,13 @@ namespace Mono.CSharp @@ -837,13 +851,13 @@ namespace Mono.CSharp
public TypeSpec Resolve ()
{
if (type == null)
type = Resolve (module, kind, ns, name, arity);
type = Resolve (module, kind, ns, name, arity, false, true);
return type;
}
}
class PredefinedMember<T> where T : MemberSpec
public class PredefinedMember<T> where T : MemberSpec
{
readonly ModuleContainer module;
T member;

46
ICSharpCode.NRefactory.CSharp/Parser/mcs/typespec.cs

@ -23,6 +23,9 @@ using System.Reflection; @@ -23,6 +23,9 @@ using System.Reflection;
namespace Mono.CSharp
{
//
// Inflated or non-inflated representation of any type.
//
public class TypeSpec : MemberSpec
{
protected MetaType info;
@ -306,6 +309,9 @@ namespace Mono.CSharp @@ -306,6 +309,9 @@ namespace Mono.CSharp
}
}
//
// A cache of all type members (including nested types)
//
public MemberCache MemberCache {
get {
if (cache == null || (state & StateFlags.PendingMemberCacheMembers) != 0)
@ -435,6 +441,9 @@ namespace Mono.CSharp @@ -435,6 +441,9 @@ namespace Mono.CSharp
return aua;
}
//
// Return metadata information used during emit to describe the type
//
public virtual MetaType GetMetaInfo ()
{
return info;
@ -445,6 +454,9 @@ namespace Mono.CSharp @@ -445,6 +454,9 @@ namespace Mono.CSharp
return this;
}
//
// Text representation of type used by documentation writer
//
public override string GetSignatureForDocumentation ()
{
StringBuilder sb = new StringBuilder ();
@ -651,6 +663,9 @@ namespace Mono.CSharp @@ -651,6 +663,9 @@ namespace Mono.CSharp
return new InflatedTypeSpec (inflator.Context, this, inflator.TypeInstance, targs);
}
//
// Inflates current type using specific type arguments
//
public InflatedTypeSpec MakeGenericType (IModuleContext context, TypeSpec[] targs)
{
if (targs.Length == 0 && !IsNested)
@ -721,6 +736,18 @@ namespace Mono.CSharp @@ -721,6 +736,18 @@ namespace Mono.CSharp
}
}
if (MemberDefinition.TypeParametersCount > 0) {
foreach (var tp in MemberDefinition.TypeParameters) {
var tp_missing = tp.GetMissingDependencies ();
if (tp_missing != null) {
if (missing == null)
missing = new List<TypeSpec> ();
missing.AddRange (tp_missing);
}
}
}
if (missing != null || BaseType == null)
return missing;
@ -741,6 +768,10 @@ namespace Mono.CSharp @@ -741,6 +768,10 @@ namespace Mono.CSharp
}
}
//
// Special version used for types which must exist in corlib or
// the compiler cannot work
//
public sealed class BuiltinTypeSpec : TypeSpec
{
public enum Type
@ -922,6 +953,9 @@ namespace Mono.CSharp @@ -922,6 +953,9 @@ namespace Mono.CSharp
}
}
//
// Various type comparers used by compiler
//
static class TypeSpecComparer
{
//
@ -1333,7 +1367,7 @@ namespace Mono.CSharp @@ -1333,7 +1367,7 @@ namespace Mono.CSharp
cache = MemberCache.Empty;
// Make all internal types CLS-compliant, non-obsolete
state = (state & ~(StateFlags.CLSCompliant_Undetected | StateFlags.Obsolete_Undetected)) | StateFlags.CLSCompliant;
state = (state & ~(StateFlags.CLSCompliant_Undetected | StateFlags.Obsolete_Undetected | StateFlags.MissingDependency_Undetected)) | StateFlags.CLSCompliant;
}
#region Properties
@ -1447,6 +1481,9 @@ namespace Mono.CSharp @@ -1447,6 +1481,9 @@ namespace Mono.CSharp
#endregion
}
//
// Common base class for composite types
//
public abstract class ElementTypeSpec : TypeSpec, ITypeDefinition
{
protected ElementTypeSpec (MemberKind kind, TypeSpec element, MetaType info)
@ -1454,11 +1491,8 @@ namespace Mono.CSharp @@ -1454,11 +1491,8 @@ namespace Mono.CSharp
{
this.Element = element;
// Some flags can be copied directly from the element
const StateFlags shared_flags = StateFlags.CLSCompliant | StateFlags.CLSCompliant_Undetected
| StateFlags.Obsolete | StateFlags.Obsolete_Undetected | StateFlags.HasDynamicElement;
state &= ~shared_flags;
state |= (element.state & shared_flags);
state &= ~SharedStateFlags;
state |= (element.state & SharedStateFlags);
if (element.BuiltinType == BuiltinTypeSpec.Type.Dynamic)
state |= StateFlags.HasDynamicElement;

7
ICSharpCode.NRefactory.CSharp/Parser/mcs/visit.cs

@ -11,6 +11,7 @@ @@ -11,6 +11,7 @@
//
using System;
using System.Diagnostics;
namespace Mono.CSharp
{
@ -18,7 +19,7 @@ namespace Mono.CSharp @@ -18,7 +19,7 @@ namespace Mono.CSharp
{
public virtual void Visit (MemberCore member)
{
Console.WriteLine ("unknown member type: " + member.GetType ());
Debug.Fail ("unknown member type: " + member.GetType ());
}
public virtual void Visit (ModuleContainer mc)
@ -125,7 +126,7 @@ namespace Mono.CSharp @@ -125,7 +126,7 @@ namespace Mono.CSharp
public virtual object Visit (Statement stmt)
{
Console.WriteLine ("unknown statement:" + stmt);
Debug.Fail ("unknown statement:" + stmt);
return null;
}
@ -309,7 +310,7 @@ namespace Mono.CSharp @@ -309,7 +310,7 @@ namespace Mono.CSharp
public virtual object Visit (Expression expression)
{
Console.WriteLine ("Visit unknown expression:" + expression);
Debug.Fail ("Visit unknown expression:" + expression);
return null;
}

357
ICSharpCode.NRefactory.CSharp/QueryExpressionExpander.cs

@ -0,0 +1,357 @@ @@ -0,0 +1,357 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.Linq;
using System.Text;
using ICSharpCode.NRefactory.PatternMatching;
namespace ICSharpCode.NRefactory.CSharp {
public class QueryExpressionExpansionResult {
public AstNode AstNode { get; private set; }
/// <summary>
/// Maps original range variables to some node in the new tree that represents them.
/// </summary>
public IDictionary<Identifier, AstNode> RangeVariables { get; private set; }
/// <summary>
/// Maps clauses to method calls. The keys will always be either a <see cref="QueryClause"/> or a <see cref="QueryOrdering"/>
/// </summary>
public IDictionary<AstNode, Expression> Expressions { get; private set; }
public QueryExpressionExpansionResult(AstNode astNode, IDictionary<Identifier, AstNode> rangeVariables, IDictionary<AstNode, Expression> expressions) {
AstNode = astNode;
RangeVariables = rangeVariables;
Expressions = expressions;
}
}
public class QueryExpressionExpander {
class Visitor : DepthFirstAstVisitor<AstNode> {
int currentTransparentParameter;
const string TransparentParameterNameTemplate = "<>x{0}";
protected override AstNode VisitChildren(AstNode node) {
List<AstNode> newChildren = null;
int i = 0;
foreach (var child in node.Children) {
var newChild = child.AcceptVisitor(this);
if (newChild != null) {
newChildren = newChildren ?? Enumerable.Repeat((AstNode)null, i).ToList();
newChildren.Add(newChild);
}
else if (newChildren != null) {
newChildren.Add(null);
}
i++;
}
if (newChildren == null)
return null;
var result = node.Clone();
i = 0;
foreach (var children in result.Children) {
if (newChildren[i] != null)
children.ReplaceWith(newChildren[i]);
i++;
}
return result;
}
Expression MakeNestedMemberAccess(Expression target, IEnumerable<string> members) {
return members.Aggregate(target, (current, m) => current.Member(m));
}
Expression VisitNested(Expression node, ParameterDeclaration transparentParameter) {
var oldRangeVariableSubstitutions = activeRangeVariableSubstitutions;
try {
if (transparentParameter != null && currentTransparentType.Count > 1) {
activeRangeVariableSubstitutions = new Dictionary<string, Expression>(activeRangeVariableSubstitutions);
foreach (var t in currentTransparentType)
activeRangeVariableSubstitutions[t.Item1.Name] = MakeNestedMemberAccess(new IdentifierExpression(transparentParameter.Name), t.Item2);
}
var result = node.AcceptVisitor(this);
return (Expression)(result ?? node.Clone());
}
finally {
activeRangeVariableSubstitutions = oldRangeVariableSubstitutions;
}
}
QueryClause GetNextQueryClause(QueryClause clause) {
for (AstNode node = clause.NextSibling; node != null; node = node.NextSibling) {
if (node.Role == QueryExpression.ClauseRole)
return (QueryClause)node;
}
return null;
}
public IDictionary<Identifier, AstNode> rangeVariables = new Dictionary<Identifier, AstNode>();
public IDictionary<AstNode, Expression> expressions = new Dictionary<AstNode, Expression>();
Dictionary<string, Expression> activeRangeVariableSubstitutions = new Dictionary<string, Expression>();
List<Tuple<Identifier, List<string>>> currentTransparentType = new List<Tuple<Identifier, List<string>>>();
Expression currentResult;
bool eatSelect;
void MapExpression(AstNode orig, Expression newExpr) {
Debug.Assert(orig is QueryClause || orig is QueryOrdering);
expressions[orig] = newExpr;
}
ParameterDeclaration CreateParameterForCurrentRangeVariable() {
var param = new ParameterDeclaration();
if (currentTransparentType.Count == 1) {
var clonedRangeVariable = (Identifier)currentTransparentType[0].Item1.Clone();
if (!rangeVariables.ContainsKey(currentTransparentType[0].Item1))
rangeVariables[currentTransparentType[0].Item1] = param;
param.AddChild(clonedRangeVariable, Roles.Identifier);
}
else {
param.AddChild(Identifier.Create(string.Format(CultureInfo.InvariantCulture, TransparentParameterNameTemplate, currentTransparentParameter++)), Roles.Identifier);
}
return param;
}
LambdaExpression CreateLambda(IList<ParameterDeclaration> parameters, Expression body) {
var result = new LambdaExpression();
if (parameters.Count > 1)
result.AddChild(new CSharpTokenNode(TextLocation.Empty), Roles.LPar);
result.AddChild(parameters[0], Roles.Parameter);
for (int i = 1; i < parameters.Count; i++) {
result.AddChild(new CSharpTokenNode(TextLocation.Empty), Roles.Comma);
result.AddChild(parameters[i], Roles.Parameter);
}
if (parameters.Count > 1)
result.AddChild(new CSharpTokenNode(TextLocation.Empty), Roles.RPar);
result.AddChild(body, LambdaExpression.BodyRole);
return result;
}
ParameterDeclaration CreateParameter(Identifier identifier) {
var result = new ParameterDeclaration();
result.AddChild(identifier, Roles.Identifier);
return result;
}
Expression AddMemberToCurrentTransparentType(ParameterDeclaration param, Identifier name, Expression value, bool namedExpression) {
Expression newAssignment = VisitNested(value, param);
if (namedExpression) {
newAssignment = new NamedExpression(name.Name, VisitNested(value, param));
if (!rangeVariables.ContainsKey(name) )
rangeVariables[name] = ((NamedExpression)newAssignment).NameToken;
}
foreach (var t in currentTransparentType)
t.Item2.Insert(0, param.Name);
currentTransparentType.Add(Tuple.Create(name, new List<string> { name.Name }));
return new AnonymousTypeCreateExpression(new[] { new IdentifierExpression(param.Name), newAssignment });
}
void AddFirstMemberToCurrentTransparentType(Identifier identifier) {
Debug.Assert(currentTransparentType.Count == 0);
currentTransparentType.Add(Tuple.Create(identifier, new List<string>()));
}
public override AstNode VisitQueryExpression(QueryExpression queryExpression) {
var oldTransparentType = currentTransparentType;
var oldResult = currentResult;
var oldEatSelect = eatSelect;
try {
currentTransparentType = new List<Tuple<Identifier, List<string>>>();
currentResult = null;
eatSelect = false;
foreach (var clause in queryExpression.Clauses) {
var result = (Expression)clause.AcceptVisitor(this);
MapExpression(clause, result ?? currentResult);
currentResult = result;
}
return currentResult;
}
finally {
currentTransparentType = oldTransparentType;
currentResult = oldResult;
eatSelect = oldEatSelect;
}
}
public override AstNode VisitQueryContinuationClause(QueryContinuationClause queryContinuationClause) {
var prev = VisitNested(queryContinuationClause.PrecedingQuery, null);
AddFirstMemberToCurrentTransparentType(queryContinuationClause.IdentifierToken);
return prev;
}
public override AstNode VisitQueryFromClause(QueryFromClause queryFromClause) {
if (currentResult == null) {
AddFirstMemberToCurrentTransparentType(queryFromClause.IdentifierToken);
if (queryFromClause.Type.IsNull) {
return VisitNested(queryFromClause.Expression, null);
}
else {
return VisitNested(queryFromClause.Expression, null).Invoke("Cast", new[] { queryFromClause.Type.Clone() }, new Expression[0]);
}
}
else {
var innerSelectorParam = CreateParameterForCurrentRangeVariable();
var innerSelector = CreateLambda(new[] { innerSelectorParam }, VisitNested(queryFromClause.Expression, innerSelectorParam));
var clonedIdentifier = (Identifier)queryFromClause.IdentifierToken.Clone();
var resultParam = CreateParameterForCurrentRangeVariable();
Expression body;
// Second from clause - SelectMany
var select = GetNextQueryClause(queryFromClause) as QuerySelectClause;
if (select != null) {
body = VisitNested(select.Expression, resultParam);
eatSelect = true;
}
else {
body = AddMemberToCurrentTransparentType(resultParam, queryFromClause.IdentifierToken, new IdentifierExpression(queryFromClause.Identifier), false);
}
var resultSelectorParam2 = CreateParameter(clonedIdentifier);
var resultSelector = CreateLambda(new[] { resultParam, resultSelectorParam2 }, body);
rangeVariables[queryFromClause.IdentifierToken] = resultSelectorParam2;
return currentResult.Invoke("SelectMany", innerSelector, resultSelector);
}
}
public override AstNode VisitQueryLetClause(QueryLetClause queryLetClause) {
var param = CreateParameterForCurrentRangeVariable();
var body = AddMemberToCurrentTransparentType(param, queryLetClause.IdentifierToken, queryLetClause.Expression, true);
var lambda = CreateLambda(new[] { param }, body);
return currentResult.Invoke("Select", lambda);
}
public override AstNode VisitQueryWhereClause(QueryWhereClause queryWhereClause) {
var param = CreateParameterForCurrentRangeVariable();
return currentResult.Invoke("Where", CreateLambda(new[] { param }, VisitNested(queryWhereClause.Condition, param)));
}
public override AstNode VisitQueryJoinClause(QueryJoinClause queryJoinClause) {
Expression resultSelectorBody = null;
var inExpression = VisitNested(queryJoinClause.InExpression, null);
var key1SelectorFirstParam = CreateParameterForCurrentRangeVariable();
var key1Selector = CreateLambda(new[] { key1SelectorFirstParam }, VisitNested(queryJoinClause.OnExpression, key1SelectorFirstParam));
var key2Param = CreateParameter(Identifier.Create(queryJoinClause.JoinIdentifier));
var key2Selector = CreateLambda(new[] { key2Param }, VisitNested(queryJoinClause.EqualsExpression, null));
var resultSelectorFirstParam = CreateParameterForCurrentRangeVariable();
var select = GetNextQueryClause(queryJoinClause) as QuerySelectClause;
if (select != null) {
resultSelectorBody = VisitNested(select.Expression, resultSelectorFirstParam);
eatSelect = true;
}
if (queryJoinClause.IntoKeyword.IsNull) {
// Normal join
if (resultSelectorBody == null)
resultSelectorBody = AddMemberToCurrentTransparentType(resultSelectorFirstParam, queryJoinClause.JoinIdentifierToken, new IdentifierExpression(queryJoinClause.JoinIdentifier), false);
var resultSelector = CreateLambda(new[] { resultSelectorFirstParam, CreateParameter(Identifier.Create(queryJoinClause.JoinIdentifier)) }, resultSelectorBody);
rangeVariables[queryJoinClause.JoinIdentifierToken] = key2Param;
return currentResult.Invoke("Join", inExpression, key1Selector, key2Selector, resultSelector);
}
else {
// Group join
if (resultSelectorBody == null)
resultSelectorBody = AddMemberToCurrentTransparentType(resultSelectorFirstParam, queryJoinClause.IntoIdentifierToken, new IdentifierExpression(queryJoinClause.IntoIdentifier), false);
var intoParam = CreateParameter(Identifier.Create(queryJoinClause.IntoIdentifier));
var resultSelector = CreateLambda(new[] { resultSelectorFirstParam, intoParam }, resultSelectorBody);
rangeVariables[queryJoinClause.IntoIdentifierToken] = intoParam;
return currentResult.Invoke("GroupJoin", inExpression, key1Selector, key2Selector, resultSelector);
}
}
public override AstNode VisitQueryOrderClause(QueryOrderClause queryOrderClause) {
var current = currentResult;
bool first = true;
foreach (var o in queryOrderClause.Orderings) {
string methodName = first ? (o.Direction == QueryOrderingDirection.Descending ? "OrderByDescending" : "OrderBy")
: (o.Direction == QueryOrderingDirection.Descending ? "ThenByDescending" : "ThenBy");
var param = CreateParameterForCurrentRangeVariable();
current = current.Invoke(methodName, CreateLambda(new[] { param }, VisitNested(o.Expression, param)));
MapExpression(o, current);
first = false;
}
return current;
}
bool IsSingleRangeVariable(Expression expr) {
if (currentTransparentType.Count > 1)
return false;
var unpacked = ParenthesizedExpression.UnpackParenthesizedExpression(expr);
return unpacked is IdentifierExpression && ((IdentifierExpression)unpacked).Identifier == currentTransparentType[0].Item1.Name;
}
public override AstNode VisitQuerySelectClause(QuerySelectClause querySelectClause) {
if (eatSelect) {
eatSelect = false;
return currentResult;
}
else if (((QueryExpression)querySelectClause.Parent).Clauses.Count > 2 && IsSingleRangeVariable(querySelectClause.Expression)) {
// A simple query that ends with a trivial select should be removed.
return currentResult;
}
var param = CreateParameterForCurrentRangeVariable();
var lambda = CreateLambda(new[] { param }, VisitNested(querySelectClause.Expression, param));
return currentResult.Invoke("Select", lambda);
}
public override AstNode VisitQueryGroupClause(QueryGroupClause queryGroupClause) {
var param = CreateParameterForCurrentRangeVariable();
var keyLambda = CreateLambda(new[] { param }, VisitNested(queryGroupClause.Key, param));
if (IsSingleRangeVariable(queryGroupClause.Projection)) {
// We are grouping by the single active range variable, so we can use the single argument form of GroupBy
return currentResult.Invoke("GroupBy", keyLambda);
}
else {
var projectionParam = CreateParameterForCurrentRangeVariable();
var projectionLambda = CreateLambda(new[] { projectionParam }, VisitNested(queryGroupClause.Projection, projectionParam));
return currentResult.Invoke("GroupBy", keyLambda, projectionLambda);
}
}
public override AstNode VisitIdentifierExpression(IdentifierExpression identifierExpression) {
Expression subst;
activeRangeVariableSubstitutions.TryGetValue(identifierExpression.Identifier, out subst);
return subst != null ? subst.Clone() : null;
}
}
/// <summary>
/// Expands all occurances of query patterns in the specified node. Returns a clone of the node with all query patterns expanded, or null if there was no query pattern to expand.
/// </summary>
/// <param name="node"></param>
/// <returns></returns>
public QueryExpressionExpansionResult ExpandQueryExpressions(AstNode node) {
var visitor = new Visitor();
var astNode = node.AcceptVisitor(visitor);
if (astNode != null) {
astNode.Freeze();
return new QueryExpressionExpansionResult(astNode, visitor.rangeVariables, visitor.expressions);
}
else {
return null;
}
}
}
}

30
ICSharpCode.NRefactory.CSharp/Refactoring/BaseRefactoringContext.cs

@ -35,6 +35,7 @@ using ICSharpCode.NRefactory.TypeSystem.Implementation; @@ -35,6 +35,7 @@ using ICSharpCode.NRefactory.TypeSystem.Implementation;
using ICSharpCode.NRefactory.Editor;
using System.ComponentModel.Design;
using ICSharpCode.NRefactory.CSharp.Analysis;
using ICSharpCode.NRefactory.Utils;
namespace ICSharpCode.NRefactory.CSharp.Refactoring
{
@ -72,9 +73,9 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring @@ -72,9 +73,9 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring
}
}
public virtual CSharpParsedFile ParsedFile {
public virtual CSharpUnresolvedFile UnresolvedFile {
get {
return resolver.ParsedFile;
return resolver.UnresolvedFile;
}
}
@ -135,6 +136,31 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring @@ -135,6 +136,31 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring
{
return new DefiniteAssignmentAnalysis (root, resolver, CancellationToken);
}
/// <summary>
/// Creates a new reachability analysis object with a given statement.
/// </summary>
/// <param name="statement">
/// The statement to start the analysis.
/// </param>
/// <returns>
/// The reachability analysis object.
/// </returns>
public ReachabilityAnalysis CreateReachabilityAnalysis (Statement statement)
{
return ReachabilityAnalysis.Create (statement, resolver, CancellationToken);
}
/// <summary>
/// Parses a composite format string.
/// </summary>
/// <returns>
/// The format string parsing result.
/// </returns>
public virtual FormatStringParseResult ParseFormatString(string source)
{
return new CompositeFormatStringParser().Parse(source);
}
#endregion
/// <summary>

4
ICSharpCode.NRefactory.CSharp/Refactoring/CodeActions/AddAnotherAccessorAction.cs

@ -37,7 +37,7 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring @@ -37,7 +37,7 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring
public IEnumerable<CodeAction> GetActions(RefactoringContext context)
{
var pdecl = GetPropertyDeclaration(context);
if (pdecl == null) {
if (pdecl == null || !pdecl.Getter.IsNull && !pdecl.Setter.IsNull) {
yield break;
}
@ -45,7 +45,7 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring @@ -45,7 +45,7 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring
if (type != null && type.ClassType == ClassType.Interface) {
yield break;
}
yield return new CodeAction (pdecl.Setter.IsNull ? context.TranslateString("Add getter") : context.TranslateString("Add setter"), script => {
yield return new CodeAction (pdecl.Setter.IsNull ? context.TranslateString("Add setter") : context.TranslateString("Add getter"), script => {
var accessorStatement = BuildAccessorStatement(context, pdecl);
Accessor accessor = new Accessor () {

59
ICSharpCode.NRefactory.CSharp/Refactoring/CodeActions/AddCatchTypeAction.cs

@ -0,0 +1,59 @@ @@ -0,0 +1,59 @@
//
// AddCatchTypeAction.cs
//
// Author:
// Simon Lindgren <simon.n.lindgren@gmail.com>
//
// Copyright (c) 2012 Simon Lindgren
//
// 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 ICSharpCode.NRefactory.CSharp;
using System.Collections.Generic;
namespace ICSharpCode.NRefactory.CSharp.Refactoring
{
[ContextAction("Add type",
Description = "Adds an exception type specifier to catch clauses.")]
public class AddCatchTypeAction : ICodeActionProvider
{
#region ICodeActionProvider implementation
public IEnumerable<CodeAction> GetActions(RefactoringContext context)
{
var catchClause = context.GetNode<CatchClause>();
if (catchClause == null)
yield break;
if (!catchClause.Type.IsNull)
yield break;
yield return new CodeAction(context.TranslateString("Add type specifier"), script => {
var newIdentifier = Identifier.Create("e");
var newType = context.CreateShortType("System", "Exception");
script.Replace(catchClause, new CatchClause() {
Type = newType,
VariableNameToken = newIdentifier,
Body = catchClause.Body.Clone() as BlockStatement
});
script.Link(newType);
script.Link(newIdentifier);
});
}
#endregion
}
}

14
ICSharpCode.NRefactory.CSharp/Refactoring/CodeActions/CheckIfParameterIsNullAction.cs

@ -37,18 +37,24 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring @@ -37,18 +37,24 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring
{
protected override CodeAction GetAction(RefactoringContext context, ParameterDeclaration parameter)
{
var bodyStatement = parameter.Parent.GetChildByRole(Roles.Body);
if (bodyStatement == null)
BlockStatement bodyStatement;
if (parameter.Parent is LambdaExpression) {
bodyStatement = parameter.Parent.GetChildByRole (LambdaExpression.BodyRole) as BlockStatement;
} else {
bodyStatement = parameter.Parent.GetChildByRole (Roles.Body);
}
if (bodyStatement == null || bodyStatement.IsNull)
return null;
var type = context.ResolveType(parameter.Type);
if (type.IsReferenceType == false || HasNullCheck(parameter))
return null;
return new CodeAction (context.TranslateString("Add null check for parameter"), script => {
var statement = new IfElseStatement () {
return new CodeAction(context.TranslateString("Add null check for parameter"), script => {
var statement = new IfElseStatement() {
Condition = new BinaryOperatorExpression (new IdentifierExpression (parameter.Name), BinaryOperatorType.Equality, new NullReferenceExpression ()),
TrueStatement = new ThrowStatement (new ObjectCreateExpression (context.CreateShortType("System", "ArgumentNullException"), new PrimitiveExpression (parameter.Name)))
};
System.Console.WriteLine(bodyStatement.StartLocation +"/" + bodyStatement.EndLocation);
script.AddTo(bodyStatement, statement);
});
}

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save