From 2c75fada90c95aa0119adea8dcfcca10921dafb9 Mon Sep 17 00:00:00 2001 From: Daniel Grunwald Date: Sun, 29 Jun 2014 11:49:15 +0200 Subject: [PATCH] Update to NRefactory 5.4 --- NRefactory/.gitattributes | 5 +- NRefactory/.gitignore | 1 + .../AssemblyInfo.cs | 27 - ...pCode.NRefactory.CSharp.AstVerifier.csproj | 69 - .../Main.cs | 83 - .../AnnotationNames.cs} | 65 +- .../Analysis/ControlFlow.cs | 88 +- .../DeclarationSpace/LocalDeclarationSpace.cs | 157 + .../LocalDeclarationSpaceVisitor.cs | 138 + .../Analysis/DefiniteAssignmentAnalysis.cs | 2 +- .../Analysis/NullValueAnalysis.cs | 2215 +++ .../Analysis/NullValueStatus.cs | 84 + .../Analysis/ReachabilityAnalysis.cs | 140 +- .../Analysis/SemanticHighlightingVisitor.cs | 691 + .../Ast/AstNode.cs | 282 +- .../Ast/AstNodeCollection.cs | 19 +- .../Ast/AstType.cs | 73 +- .../Ast/CSharpModifierToken.cs | 102 +- .../Ast/CSharpTokenNode.cs | 36 +- .../Ast/CSharpUtil.cs | 115 +- .../Ast/ComposedType.cs | 44 +- .../Ast/DepthFirstAstVisitor.cs | 43 +- .../Ast/DocumentationReference.cs | 30 +- .../Ast/ErrorNode.cs | 4 +- .../Expressions/AnonymousMethodExpression.cs | 3 +- .../Ast/Expressions/ArrayCreateExpression.cs | 2 +- .../Expressions/ArrayInitializerExpression.cs | 5 +- .../Ast/Expressions/AsExpression.cs | 70 +- .../Ast/Expressions/AssignmentExpression.cs | 67 + .../Expressions/BinaryOperatorExpression.cs | 66 + .../Ast/Expressions/CastExpression.cs | 72 +- .../Ast/Expressions/ConditionalExpression.cs | 67 + .../Ast/Expressions/ErrorExpression.cs | 54 +- .../Ast/Expressions/Expression.cs | 37 +- .../Ast/Expressions/IsExpression.cs | 78 + .../Ast/Expressions/LambdaExpression.cs | 8 + .../Expressions/MemberReferenceExpression.cs | 2 +- .../Expressions/NamedArgumentExpression.cs | 2 +- .../Expressions/NullReferenceExpression.cs | 10 +- .../Ast/Expressions/PrimitiveExpression.cs | 78 +- .../Ast/Expressions/QueryExpression.cs | 89 +- .../Expressions/TypeReferenceExpression.cs | 2 +- .../Expressions/UnaryOperatorExpression.cs | 5 +- .../Ast/GeneralScope/Attribute.cs | 19 +- .../Ast/GeneralScope/AttributeSection.cs | 15 +- .../Ast/GeneralScope/Comment.cs | 9 + .../Ast/GeneralScope/Constraint.cs | 6 +- .../Ast/GeneralScope/DelegateDeclaration.cs | 4 +- .../Ast/GeneralScope/NamespaceDeclaration.cs | 111 +- .../Ast/GeneralScope/NewLineNode.cs | 109 +- .../Ast/GeneralScope/PreProcessorDirective.cs | 81 + .../Ast/GeneralScope/TypeDeclaration.cs | 22 +- .../GeneralScope/TypeParameterDeclaration.cs | 2 +- .../Ast/GeneralScope/UsingDeclaration.cs | 27 +- .../Ast/IAstVisitor.cs | 14 +- .../Ast/Identifier.cs | 13 +- .../Ast/IdentifierExpressionBackreference.cs | 2 +- .../Ast/MemberType.cs | 37 +- .../Ast/ObservableAstVisitor.cs | 11 +- .../Ast/PrimitiveType.cs | 13 +- .../Ast/SimpleType.cs | 34 +- .../Ast/Statements/BlockStatement.cs | 14 +- .../Ast/Statements/BreakStatement.cs | 2 +- .../Ast/Statements/DoWhileStatement.cs | 10 + .../Ast/Statements/LabelStatement.cs | 2 +- .../Ast/Statements/Statement.cs | 35 +- .../Ast/Statements/TryCatchStatement.cs | 5 +- .../Ast/Statements/WhileStatement.cs | 10 + .../Ast/SyntaxExtensions.cs | 45 + .../Ast/SyntaxTree.cs | 21 +- .../Ast/TokenRole.cs | 32 +- .../Ast/TypeMembers/Accessor.cs | 25 +- .../Ast/TypeMembers/ConstructorDeclaration.cs | 25 +- .../Ast/TypeMembers/DestructorDeclaration.cs | 4 +- .../Ast/TypeMembers/EntityDeclaration.cs | 10 +- .../Ast/TypeMembers/EnumMemberDeclaration.cs | 10 +- .../Ast/TypeMembers/EventDeclaration.cs | 31 +- .../Ast/TypeMembers/FieldDeclaration.cs | 20 +- .../Ast/TypeMembers/FixedFieldDeclaration.cs | 4 +- .../Ast/TypeMembers/IndexerDeclaration.cs | 12 +- .../Ast/TypeMembers/MethodDeclaration.cs | 4 +- .../Ast/TypeMembers/OperatorDeclaration.cs | 6 +- .../Ast/TypeMembers/ParameterDeclaration.cs | 17 +- .../Ast/TypeMembers/PropertyDeclaration.cs | 4 +- .../Ast/TypeMembers/VariableInitializer.cs | 17 +- .../Ast/old_ObservableAstVisitor.cs | 1201 -- .../CSharpProjectContent.cs | 16 +- .../CombineQueryExpressions.cs | 216 + .../Completion/CSharpCompletionEngine.cs | 2544 ++- .../Completion/CSharpCompletionEngineBase.cs | 418 +- .../CSharpParameterCompletionEngine.cs | 268 +- .../Completion/CompletionDataWrapper.cs | 179 +- .../Completion/ICompletionContextProvider.cs | 9 +- .../Completion/ICompletionDataFactory.cs | 28 +- .../IParameterCompletionDataFactory.cs | 9 +- .../Formatter/AstFormattingVisitor.cs | 2181 --- .../Formatter/CSharpFormatter.cs | 159 + .../Formatter/CSharpFormattingOptions.cs | 218 +- .../Formatter/ConstructFixer.cs | 514 + .../Formatter/FormattingChanges.cs | 169 + .../Formatter/FormattingOptionsFactory.cs | 143 +- .../Formatter/FormattingVisitor.cs | 661 + .../FormattingVisitor_Expressions.cs | 735 + .../Formatter/FormattingVisitor_Global.cs | 351 + .../Formatter/FormattingVisitor_Query.cs | 124 + .../Formatter/FormattingVisitor_Statements.cs | 517 + .../FormattingVisitor_TypeMembers.cs | 477 + .../Formatter/GeneratedCodeSettings.cs | 6 +- .../Formatter/Indent.cs | 154 +- .../ICSharpCode.NRefactory.CSharp.csproj | 110 +- .../IndentEngine/CSharpIndentEngine.cs | 557 + .../IndentEngine/CacheIndentEngine.cs | 627 + .../IndentEngine/IDocumentIndentEngine.cs | 108 + .../IStateMachineIndentEngine.cs} | 61 +- .../IndentEngine/IndentState.cs | 2014 +++ .../NullIStateMachineIndentEngine.cs | 215 + .../IndentEngine/TextPasteIndentEngine.cs | 632 + .../IntroduceQueryExpressions.cs | 386 + .../NameLookupMode.cs | 2 +- .../OutputVisitor/CSharpAmbience.cs | 238 +- .../OutputVisitor/CSharpOutputVisitor.cs | 683 +- .../OutputVisitor/CodeDomConvertVisitor.cs | 75 +- .../OutputVisitor/IOutputFormatter.cs | 60 - .../OutputVisitor/ITokenWriter.cs | 161 + .../InsertMissingTokensDecorator.cs | 123 + .../OutputVisitor/InsertParenthesesVisitor.cs | 4 +- .../InsertRequiredSpacesDecorator.cs | 184 + .../OutputVisitor/InsertSpecialsDecorator.cs | 157 + .../TextWriterOutputFormatter.cs | 365 +- .../Parser/CSharpParser.cs | 3626 ++-- .../Parser/CompilerSettings.cs | 4 +- .../Parser/mcs/MonoSymbolFile.cs | 8 +- .../Parser/mcs/MonoSymbolTable.cs | 81 +- .../Parser/mcs/MonoSymbolWriter.cs | 4 - .../Parser/mcs/SourceMethodBuilder.cs | 15 +- .../Parser/mcs/anonymous.cs | 333 +- .../Parser/mcs/argument.cs | 71 +- .../Parser/mcs/assembly.cs | 141 +- .../Parser/mcs/assign.cs | 137 +- .../Parser/mcs/async.cs | 265 +- .../Parser/mcs/attribute.cs | 256 +- .../Parser/mcs/cfold.cs | 196 +- .../Parser/mcs/class.cs | 580 +- .../Parser/mcs/codegen.cs | 82 +- .../Parser/mcs/complete.cs | 56 +- .../Parser/mcs/const.cs | 4 +- .../Parser/mcs/constant.cs | 218 +- .../Parser/mcs/context.cs | 233 +- .../Parser/mcs/convert.cs | 288 +- .../Parser/mcs/cs-parser.cs | 14932 +++++++++------- .../Parser/mcs/cs-parser.jay | 1308 +- .../Parser/mcs/cs-tokenizer.cs | 463 +- .../Parser/mcs/decl.cs | 51 +- .../Parser/mcs/delegate.cs | 171 +- .../Parser/mcs/doc.cs | 60 +- .../Parser/mcs/driver.cs | 11 +- .../Parser/mcs/dynamic.cs | 37 +- .../Parser/mcs/ecore.cs | 1328 +- .../Parser/mcs/enum.cs | 4 +- .../Parser/mcs/eval.cs | 235 +- .../Parser/mcs/expression.cs | 2777 ++- .../Parser/mcs/field.cs | 72 +- .../Parser/mcs/flowanalysis.cs | 1495 +- .../Parser/mcs/generic.cs | 641 +- .../Parser/mcs/import.cs | 444 +- .../Parser/mcs/iterators.cs | 218 +- .../Parser/mcs/lambda.cs | 6 +- .../Parser/mcs/linq.cs | 5 +- .../Parser/mcs/literal.cs | 2 +- .../Parser/mcs/location.cs | 241 +- .../Parser/mcs/membercache.cs | 75 +- .../Parser/mcs/method.cs | 528 +- .../Parser/mcs/modifiers.cs | 7 +- .../Parser/mcs/module.cs | 82 +- .../Parser/mcs/namespace.cs | 332 +- .../Parser/mcs/nullable.cs | 829 +- .../Parser/mcs/outline.cs | 22 +- .../Parser/mcs/parameter.cs | 150 +- .../Parser/mcs/pending.cs | 50 +- .../Parser/mcs/property.cs | 195 +- .../Parser/mcs/reflection.cs | 8 +- .../Parser/mcs/report.cs | 35 +- .../Parser/mcs/settings.cs | 88 +- .../Parser/mcs/statement.cs | 3913 ++-- .../Parser/mcs/support.cs | 42 +- .../Parser/mcs/typemanager.cs | 77 +- .../Parser/mcs/typespec.cs | 212 +- .../Parser/mcs/visit.cs | 15 +- .../PatternMatching/AnyType.cs} | 30 +- .../Properties/AssemblyInfo.cs | 22 +- .../QueryExpressionExpander.cs | 95 +- .../Refactoring/BaseRefactoringContext.cs | 129 +- .../Refactoring/CodeAction.cs | 134 +- ...ctionProvider.cs => CodeActionProvider.cs} | 4 +- .../CodeActions/AddAnotherAccessorAction.cs | 93 - .../CodeActions/AddCatchTypeAction.cs | 59 - .../CheckIfParameterIsNullAction.cs | 93 - .../ConvertAnonymousDelegateToLambdaAction.cs | 61 - .../CodeActions/ConvertAsToCastAction.cs | 44 - .../CodeActions/ConvertCastToAsAction.cs | 52 - .../ConvertConditionalToIfAction.cs | 146 - .../CodeActions/ConvertDecToHexAction.cs | 52 - ...tExplicitToImplicitImplementationAction.cs | 69 - .../CodeActions/ConvertForeachToForAction.cs | 109 - .../CodeActions/ConvertHexToDecAction.cs | 53 - .../ConvertIfToConditionalAction.cs | 138 - .../CodeActions/ConvertIfToSwitchAction.cs | 193 - ...tImplicitToExplicitImplementationAction.cs | 60 - ...rtLambdaBodyExpressionToStatementAction.cs | 61 - ...rtLambdaBodyStatementToExpressionAction.cs | 57 - .../ConvertLambdaToAnonymousDelegateAction.cs | 80 - .../CodeActions/ConvertSwitchToIfAction.cs | 147 - ...tializerToExplicitInitializationsAction.cs | 208 - .../ConvertToInitializerAction.cs | 109 - .../ConvertToInitializer/InitializerPath.cs | 180 - .../StatementsToInitializerConverter.cs | 428 - .../CodeActions/CreateBackingStoreAction.cs | 78 - .../CreateClassDeclarationAction.cs | 238 - .../CreateConstructorDeclarationAction.cs | 63 - .../CreateCustomEventImplementationAction.cs | 66 - .../CodeActions/CreateDelegateAction.cs | 71 - .../CodeActions/CreateEventInvocatorAction.cs | 116 - .../CodeActions/CreateIndexerAction.cs | 102 - .../CodeActions/CreateLocalVariableAction.cs | 73 - .../CreateMethodDeclarationAction.cs | 357 - .../CreateOverloadWithoutParameterAction.cs | 140 - .../CodeActions/CreatePropertyAction.cs | 126 - .../CodeActions/DeclareLocalVariableAction.cs | 166 - ...nvocationToStaticMethodInvocationAction.cs | 69 - .../ExtractAnonymousMethodAction.cs | 117 - .../CodeActions/ExtractFieldAction.cs | 93 - .../ExtractMethod/ExtractMethodAction.cs | 207 - .../ExtractMethod/StaticVisitor.cs | 85 - .../ExtractMethod/VariableLookupVisitor.cs | 102 - .../ExtractMethod/VariableUsageAnalyzation.cs | 146 - .../FlipOperatorArgumentsAction.cs | 61 - .../CodeActions/GenerateGetterAction.cs | 101 - .../CodeActions/GeneratePropertyAction.cs | 108 - .../CodeActions/GenerateSwitchLabelsAction.cs | 86 - .../ImplementAbstractMembersAction.cs | 116 - .../CodeActions/ImplementInterfaceAction.cs | 179 - .../ImplementInterfaceExplicitAction.cs | 68 - .../CodeActions/InlineLocalVariableAction.cs | 66 - .../InsertAnonymousMethodSignatureAction.cs | 94 - .../CodeActions/IntroduceConstantAction.cs | 89 - .../CodeActions/IntroduceFormatItemAction.cs | 105 - .../Refactoring/CodeActions/InvertIfAction.cs | 62 - .../CodeActions/IterateViaForeachAction.cs | 168 - .../JoinDeclarationAndAssignmentAction.cs | 63 - .../CodeActions/JoinStringAction.cs | 62 - .../CodeActions/MergeNestedIfAction.cs | 106 - .../CodeActions/MoveToOuterScopeAction.cs | 154 - .../NegateRelationalExpressionAction.cs | 48 - .../CodeActions/PutInsideUsingAction.cs | 147 - .../CodeActions/RemoveBackingStoreAction.cs | 125 - .../CodeActions/RemoveBracesAction.cs | 69 - ...veFieldRefactoryActionRefactoringAction.cs | 110 + .../RemoveRedundantCatchTypeAction.cs | 80 - .../CodeActions/RemoveRegionAction.cs | 112 - .../CodeActions/ReplaceEmptyStringAction.cs | 54 - .../CodeActions/SpecializedCodeAction.cs | 38 - .../SplitDeclarationAndAssignmentAction.cs | 79 - .../CodeActions/SplitDeclarationListAction.cs | 93 - .../CodeActions/SplitStringAction.cs | 61 - ...cationToExtensionMethodInvocationAction.cs | 68 - .../CodeActions/UseExplicitTypeAction.cs | 87 - .../CodeActions/UseStringFormatAction.cs | 144 - .../CodeActions/UseVarKeywordAction.cs | 72 - .../Refactoring/CodeGenerationService.cs | 64 + .../Refactoring/CodeIssue.cs | 128 +- ...AffectedEntity.cs => CodeIssueProvider.cs} | 86 +- .../AccessToClosureIssue.cs | 327 - .../AccessToDisposedClosureIssue.cs | 93 - .../AccessToModifiedClosureIssue.cs | 115 - .../LocalVariableNamePicker.cs | 70 - .../AssignmentMadeToSameVariableIssue.cs | 94 - .../BitwiseOperationOnNonFlagsEnumIssue.cs | 119 - .../CallToObjectEqualsViaBaseIssue.cs | 90 - ...llToVirtualFunctionFromConstructorIssue.cs | 113 - .../CastExpressionOfIncompatibleTypeIssue.cs | 75 - .../CompareBooleanWithTrueOrFalseIssue.cs | 89 - .../CompareFloatWithEqualityOperatorIssue.cs | 130 - .../ConditionalToNullCoalescingIssue.cs | 87 - .../CodeIssues/ConstantConditionIssue.cs | 146 - .../CodeIssues/DoubleNegationIssue.cs | 78 - .../CodeIssues/ExceptionRethrowIssue.cs | 130 - .../ExplicitConversionInForEachIssue.cs | 71 - .../ExpressionIsAlwaysOfProvidedTypeIssue.cs | 69 - .../ExpressionIsNeverOfProvidedTypeIssue.cs | 63 - .../ForControlVariableNotModifiedIssue.cs | 141 - .../FormatStringIssues/FormatStringIssue.cs | 110 - .../CodeIssues/GatherVisitorBase.cs | 96 - .../IdenticalConditionalBranchIssue.cs | 65 - .../InconsistentNamingIssue/DefaultRules.cs | 135 - .../InconsistentNamingIssue.cs | 347 - .../NamingConventionService.cs | 99 - .../InconsistentNamingIssue/NamingRule.cs | 392 - .../IncorrectCallToObjectGetHashCodeIssue.cs | 77 - ...ncorrectExceptionParameterOrderingIssue.cs | 97 - .../CodeIssues/MethodNeverReturnsIssue.cs | 88 - ...thodOverloadHidesOptionalParameterIssue.cs | 84 - .../CodeIssues/MultipleEnumerationIssue.cs | 371 - .../NegativeRelationalExpressionIssue.cs | 87 - .../NotImplementedExceptionIssue.cs | 66 - .../OptionalParameterCouldBeSkippedIssue.cs | 163 - .../HasMemberCriterion.cs | 88 - .../IsTypeCriterion.cs | 50 - .../ParameterCanBeDemotedIssue.cs | 201 - .../SupportsIndexingCriterion.cs | 107 - .../TypeCriteriaCollector.cs | 222 - .../RedundantArrayInitializerCommaIssue.cs | 65 - .../CodeIssues/RedundantAssignmentIssue.cs | 272 - .../RedundantAttributeParenthesesIssue.cs | 64 - .../CodeIssues/RedundantCaseLabelIssue.cs | 70 - .../CodeIssues/RedundantCatchIssue.cs | 139 - .../CodeIssues/RedundantElseIssue.cs | 95 - .../RedundantFieldInitializerIssue.cs | 121 - .../CodeIssues/RedundantInternalIssue.cs | 74 - .../RedundantNamespaceUsageIssue.cs | 101 - ...edundantObjectCreationArgumentListIssue.cs | 69 - ...ndantObjectOrCollectionInitializerIssue.cs | 65 - .../CodeIssues/RedundantPrivateIssue.cs | 135 - .../CodeIssues/RedundantThisIssue.cs | 131 - .../CodeIssues/RedundantToStringIssue.cs | 231 - .../CodeIssues/RedundantTypeCastIssue.cs | 105 - .../CodeIssues/RedundantUsingIssue.cs | 152 - ...ReferenceEqualsCalledWithValueTypeIssue.cs | 74 - ...erenceToStaticMemberViaDerivedTypeIssue.cs | 111 - .../StaticFieldInGenericTypeIssue.cs | 69 - .../CodeIssues/StringIsNullOrEmptyIssue.cs | 110 - .../ThreadStaticOnInstanceFieldIssue.cs | 103 - .../CodeIssues/TypeParameterNotUsedIssue.cs | 95 - .../CodeIssues/Uncategorized/.DS_Store | Bin 0 -> 6148 bytes .../CodeIssues/UnreachableCodeIssue.cs | 185 - .../CodeIssues/UseVarKeywordIssue.cs | 105 - .../CodeIssues/ValueParameterUnusedIssue.cs | 97 - .../VariableDeclaredInWideScopeIssue.cs | 299 - .../LocalVariableHidesMemberIssue.cs | 71 - .../ParameterHidesMemberIssue.cs | 60 - .../VariableHidesMemberIssue.cs | 58 - .../LocalVariableNotUsedIssue.cs | 101 - .../ParameterNotUsedIssue.cs | 71 - .../VariableNotUsedIssue.cs | 60 - .../LocalVariableOnlyAssignedIssue.cs | 72 - .../ParameterOnlyAssignedIssue.cs | 67 - .../VariableOnlyAssignedIssue.cs | 92 - ...rayTypeCriterion.cs => CommonSubIssues.cs} | 20 +- .../Refactoring/DocumentScript.cs | 36 +- .../FormatStringHelper.cs | 32 +- .../Refactoring/IssueAttribute.cs | 51 +- .../Refactoring/LambdaHelper.cs | 29 +- .../Refactoring/LocalReferenceFinder.cs | 159 + .../Refactoring/NamingHelper.cs | 30 +- .../Refactoring/PatternHelper.cs | 134 +- .../Refactoring/RefactoringAstHelper.cs | 2 +- .../Refactoring/RefactoringContext.cs | 79 +- .../Refactoring/Script.cs | 376 +- .../Refactoring/TypeCompatibilityHelper.cs | 128 - .../CreateFieldAction.cs => TypeGuessing.cs} | 258 +- .../Refactoring/TypeSystemAstBuilder.cs | 279 +- .../Refactoring/UsingHelper.cs | 204 + .../Refactoring/VariableReferenceGraph.cs | 67 +- .../WordParser.cs | 0 .../AliasNamespaceResolveResult.cs} | 61 +- .../AliasTypeResolveResult.cs} | 41 +- .../Resolver/AwaitResolveResult.cs | 81 + .../Resolver/CSharpAstResolver.cs | 8 +- .../Resolver/CSharpConversions.cs | 324 +- .../Resolver/CSharpInvocationResolveResult.cs | 29 +- .../Resolver/CSharpOperators.cs | 32 +- .../Resolver/CSharpResolver.cs | 413 +- .../Resolver/CastResolveResult.cs | 63 + .../CompositeResolveVisitorNavigator.cs | 2 +- .../Resolver/DetectSkippableNodesNavigator.cs | 2 +- .../DynamicInvocationResolveResult.cs | 2 +- .../Resolver/DynamicMemberResolveResult.cs | 2 +- .../Resolver/FindReferenceSearchScope.cs | 8 +- .../Resolver/FindReferencedEntities.cs | 2 +- .../Resolver/FindReferences.cs | 447 +- .../Resolver/IResolveVisitorNavigator.cs | 4 +- .../Resolver/LambdaResolveResult.cs | 13 +- .../Resolver/Log.cs | 12 +- .../Resolver/MemberLookup.cs | 127 +- .../Resolver/MethodGroupResolveResult.cs | 12 +- .../NodeListResolveVisitorNavigator.cs | 2 +- .../Resolver/OverloadResolution.cs | 86 +- .../Resolver/OverloadResolutionErrors.cs | 2 +- .../Resolver/ReducedExtensionMethod.cs | 455 + .../Resolver/RenameCallbackArguments.cs} | 30 +- .../Resolver/ResolveAtLocation.cs | 35 +- .../Resolver/ResolveVisitor.cs | 384 +- .../Resolver/TypeInference.cs | 64 +- .../TypeSystem/AliasNamespaceReference.cs | 21 +- .../TypeSystem/AttributeTypeReference.cs | 10 +- .../TypeSystem/CSharpAssembly.cs | 46 +- .../TypeSystem/CSharpAttribute.cs | 96 +- .../TypeSystem/CSharpDocumentationComment.cs | 2 +- .../TypeSystem/CSharpTypeResolveContext.cs | 2 +- .../TypeSystem/CSharpUnresolvedFile.cs | 41 +- .../CSharpUnresolvedTypeDefinition.cs | 5 +- .../TypeSystem/ConstantValues.cs | 284 +- .../MemberTypeOrNamespaceReference.cs | 39 +- ...odTypeParameterWithInheritedConstraints.cs | 4 +- .../TypeSystem/ResolvedUsingScope.cs | 24 +- .../SimpleTypeOrNamespaceReference.cs | 25 +- .../TypeSystem/TypeOrNamespaceReference.cs | 16 +- .../TypeSystem/TypeSystemConvertVisitor.cs | 392 +- .../TypeSystem/UsingScope.cs | 2 +- .../Util/CloneableStack.cs | 201 + .../CecilLoader.cs | 1215 +- .../ICSharpCode.NRefactory.Cecil.csproj | 99 + .../Properties/AssemblyInfo.cs} | 39 +- .../CSharpFile.cs | 3 +- .../CSharpProject.cs | 9 +- .../FindReferencesConsistencyCheck.cs | 18 +- ...arpCode.NRefactory.ConsistencyCheck.csproj | 39 +- .../PatternMatchingTest.cs | 68 + .../Program.cs | 3 +- .../Properties/AssemblyInfo.cs | 20 +- .../RandomizedOrderResolverTest.cs | 2 +- .../ResolverTest.cs | 6 +- .../RoundtripTest.cs | 2 +- .../Solution.cs | 4 +- .../TypeSystemTests.cs | 5 +- .../VisitorBenchmark.cs | 2 +- .../Xml/IncrementalXmlParserTests.cs | 4 +- .../Xml/XmlReaderTest.cs | 33 +- .../CSDemo.Designer.cs | 182 - .../ICSharpCode.NRefactory.Demo/CSDemo.cs | 284 - .../ICSharpCode.NRefactory.Demo/CSDemo.resx | 120 - .../ICSharpCode.NRefactory.Demo.csproj | 129 - .../MainForm.Designer.cs | 130 - .../ICSharpCode.NRefactory.Demo/MainForm.resx | 123 - .../Properties/AssemblyInfo.cs | 13 - .../SemanticTreeDialog.Designer.cs | 80 - .../SemanticTreeDialog.cs | 92 - .../SemanticTreeDialog.resx | 120 - .../VBAstView.Designer.cs | 74 - .../ICSharpCode.NRefactory.Demo/VBAstView.cs | 240 - .../VBAstView.resx | 120 - .../VBDemo.Designer.cs | 149 - .../ICSharpCode.NRefactory.Demo/VBDemo.cs | 155 - .../ICSharpCode.NRefactory.Demo/VBDemo.resx | 120 - .../VBEditDialog.Designer.cs | 103 - .../VBEditDialog.cs | 33 - .../VBEditDialog.resx | 120 - .../AssemblyInfo.cs | 52 - .../CSharpDemo.cs | 23 - .../ICSharpCode.NRefactory.GtkDemo.csproj | 123 - .../MainWindow.cs | 261 - ...SharpCode.NRefactory.GtkDemo.MainWindow.cs | 99 - .../gtk-gui/generated.cs | 29 - .../gtk-gui/gui.stetic | 102 - .../pixbuf/comment.png | Bin 532 -> 0 bytes .../pixbuf/element-class-16.png | Bin 830 -> 0 bytes .../pixbuf/element-field-16.png | Bin 640 -> 0 bytes .../pixbuf/element-literal-16.png | Bin 424 -> 0 bytes .../pixbuf/element-method-16.png | Bin 604 -> 0 bytes .../pixbuf/element-namespace-16.png | Bin 679 -> 0 bytes .../Analysis/DefiniteAssignmentTests.cs | 329 - .../CSharp/AstStructureTests.cs | 62 - .../CSharp/CSharpAmbienceTests.cs | 303 - .../CSharp/CSharpOutputVisitorTests.cs | 142 - .../CodeActions/AddAnotherAccessorTests.cs | 99 - .../CSharp/CodeActions/AddCatchTypeTests.cs | 134 - .../CheckIfParameterIsNullTests.cs | 108 - .../CodeActions/ContextActionTestBase.cs | 101 - .../ConvertAnonymousDelegateToLambdaTests.cs | 93 - .../CodeActions/ConvertAsToCastTests.cs | 58 - .../CodeActions/ConvertCastToAsTests.cs | 84 - .../ConvertConditionalToIfTests.cs | 273 - .../CodeActions/ConvertDecToHexTests.cs | 62 - ...rtExplicitToImplicitImplementationTests.cs | 92 - .../CodeActions/ConvertForeachToForTests.cs | 117 - .../CodeActions/ConvertHexToDecTests.cs | 62 - .../ConvertIfToConditionalTests.cs | 237 - .../CodeActions/ConvertIfToSwtichTests.cs | 471 - ...tImplicitToExplicittImplementationTests.cs | 108 - ...ertLambdaBodyExpressionToStatementTests.cs | 161 - ...ertLambdaBodyStatementToExpressionTests.cs | 79 - .../ConvertLamdaToAnonymousDelegateTests.cs | 79 - .../CodeActions/ConvertSwitchToIfTests.cs | 244 - ...nitializerToExplicitIntializationsTests.cs | 141 - .../ConvertToInitializerTests.cs | 669 - .../CodeActions/CreateBackingStoreTests.cs | 77 - .../CreateClassDeclarationTests.cs | 305 - .../CreateConstructorDeclarationTests.cs | 158 - .../CreateCustomEventImplementationTests.cs | 82 - .../CSharp/CodeActions/CreateDelegateTests.cs | 73 - .../CSharp/CodeActions/CreateFieldTests.cs | 213 - .../CSharp/CodeActions/CreateIndexerTests.cs | 188 - .../CodeActions/CreateLocalVariableTests.cs | 240 - .../CreateMethodDeclarationTests.cs | 720 - .../CreateOverloadWithoutParameterTests.cs | 209 - .../CSharp/CodeActions/CreatePropertyTests.cs | 282 - .../CodeActions/DeclareLocalVariableTests.cs | 222 - ...InvocationToStaticMethodInvocationTests.cs | 145 - .../ExtractAnonymousMethodTests.cs | 159 - .../CSharp/CodeActions/ExtractFieldTests.cs | 146 - .../CSharp/CodeActions/ExtractMethodTests.cs | 419 - .../CodeActions/FlipOperatorArgumentsTests.cs | 64 - .../CSharp/CodeActions/GenerateGetterTests.cs | 60 - .../CodeActions/GeneratePropertyTests.cs | 137 - .../CodeActions/GenerateSwitchLabelsTests.cs | 72 - .../ImplementAbstractMembersTest.cs | 63 - .../ImplementInterfaceExplicitTests.cs | 83 - .../CodeActions/ImplementInterfaceTests.cs | 303 - .../CodeActions/InlineLocalVariableTests.cs | 56 - .../InsertAnonymousMethodSignatureTests.cs | 65 - .../CodeActions/IntroduceConstantTests.cs | 93 - .../CodeActions/IntroduceFormatItemTests.cs | 85 - .../CSharp/CodeActions/InvertIfTests.cs | 68 - .../CodeActions/IterateViaForeachTests.cs | 335 - .../JoinDeclarationAndAssignmentTests.cs | 78 - .../CSharp/CodeActions/JoinStringTests.cs | 86 - .../CSharp/CodeActions/MergeNestedIfTests.cs | 226 - .../CodeActions/MoveToOuterScopeTests.cs | 141 - .../NegateRelationalExpressionTests.cs | 90 - .../CSharp/CodeActions/PutInsideUsingTests.cs | 192 - .../CodeActions/RemoveBackingStoreTests.cs | 100 - .../CSharp/CodeActions/RemoveBracesTests.cs | 125 - .../RemoveRedundantCatchTypeTests.cs | 137 - .../CSharp/CodeActions/RemoveRegionTests.cs | 91 - .../CodeActions/ReplaceEmptyStringTests.cs | 60 - .../SplitDeclarationAndAssignmentTests.cs | 109 - .../CodeActions/SplitDeclarationListTests.cs | 132 - .../CSharp/CodeActions/SplitStringTests.cs | 84 - ...ocationToExtensionMethodInvocationTests.cs | 175 - .../CodeActions/TestRefactoringContext.cs | 290 - .../CodeActions/UseExplicitTypeTests.cs | 78 - .../CodeActions/UseStringFormatTests.cs | 99 - .../CSharp/CodeActions/UseVarKeywordTests.cs | 79 - .../CodeCompletion/BrowsableAttributeTests.cs | 148 - .../CodeCompletionAccessibleTests.cs | 1349 -- .../CodeCompletion/CodeCompletionBugTests.cs | 5420 ------ .../CodeCompletionCSharp3Tests.cs | 474 - .../CodeCompletionCSharpTests.cs | 347 - .../CodeComplteionOperatorTests.cs | 673 - .../CodeCompletion/CompletionDataList.cs | 65 - .../CodeCompletion/DelegateContextTests.cs | 126 - .../DocumentationContextTests.cs | 74 - .../CSharp/CodeCompletion/EnumContextTests.cs | 145 - .../CSharp/CodeCompletion/KeywordTests.cs | 496 - .../CSharp/CodeCompletion/NameContextTests.cs | 192 - .../CodeCompletion/ObjectInitializerTests.cs | 593 - .../ParameterCompletionTests.cs | 981 - .../CodeCompletion/PreProcessorTests.cs | 68 - .../CSharp/CodeCompletion/TestBase.cs | 73 - .../VariableDeclarationStatementTests.cs | 139 - .../CSharp/CodeDomConvertVisitorTests.cs | 432 - .../AccessToDisposedClosureTests.cs | 106 - .../AccessToModifiedClosureTests.cs | 808 - .../AssignmentMadeToSameVariableIssueTests.cs | 153 - ...itwiseOperationOnNonFlagsEnumIssueTests.cs | 105 - .../CallToObjectEqualsViaBaseTests.cs | 115 - ...llToVirtualFunctionFromConstructorTests.cs | 118 - ...tExpressionOfIncompatibleTypeIssueTests.cs | 50 - ...CompareBooleanWithTrueOrFalseIssueTests.cs | 101 - ...pareFloatWithEqualityOperatorIssueTests.cs | 98 - ...nditionalToNullCoalescingInspectorTests.cs | 133 - .../CodeIssues/ConstantConditionIssueTests.cs | 185 - .../CodeIssues/DoubleNegationIssueTests.cs | 63 - .../CodeIssues/ExceptionRethrowTests.cs | 88 - .../ExplicitConversionInForEachIssueTests.cs | 75 - ...ressionIsAlwaysOfProvidedTypeIssueTests.cs | 90 - ...pressionIsNeverOfProvidedTypeIssueTests.cs | 263 - ...ForControlVariableNotModifiedIssueTests.cs | 133 - .../FormatStringIssues/FormatStringTests.cs | 176 - .../IdenticalConditionalBranchIssueTests.cs | 59 - .../CodeIssues/InconsistentNamingTests.cs | 316 - .../IncorrectCallToGetHashCodeTests.cs | 109 - ...ncorrectExceptionParameterOrderingTests.cs | 89 - .../CodeIssues/InspectionActionTestBase.cs | 91 - .../LocalVariableHidesMemberIssueTests.cs | 115 - .../LocalVariableNotUsedIssueTests.cs | 128 - .../LocalVariableOnlyAssignedIssueTests.cs | 97 - .../MethodNeverReturnsIssueTests.cs | 91 - ...verloadHidesOptionalParameterIssueTests.cs | 75 - .../MultipleEnumerationIssueTests.cs | 679 - .../NegativeRelationalExpressionIssueTests.cs | 107 - .../NotImplementedExceptionInspectorTests.cs | 53 - .../OptionalParameterCouldBeSkippedTests.cs | 305 - .../IsTypeCriterionTests.cs | 115 - .../ParameterCanBeDemotedTests.cs | 893 - .../SupportsIndexingCriterionTests.cs | 94 - .../ParameterHidesMemberIssueTests.cs | 110 - .../CodeIssues/ParameterNotUsedIssueTests.cs | 88 - .../ParameterOnlyAssignedIssueTests.cs | 64 - ...edundantArrayInitializerCommaIssueTests.cs | 57 - .../RedundantAssignmentIssueTests.cs | 294 - ...RedundantAttributeParenthesesIssueTests.cs | 47 - .../RedundantCaseLabelIssueTests.cs | 65 - .../CSharp/CodeIssues/RedundantCatchTests.cs | 223 - .../CodeIssues/RedundantElseIssueTests.cs | 204 - .../RedundantFieldInitializerIssueTests.cs | 173 - .../RedundantInternalInspectorTests.cs | 62 - .../RedundantNamespaceUsageInspectorTests.cs | 85 - ...antObjectCreationArgumentListIssueTests.cs | 82 - ...ObjectOrCollectionInitializerIssueTests.cs | 95 - .../RedundantPrivateInspectorTests.cs | 62 - .../CodeIssues/RedundantThisInspectorTests.cs | 60 - .../CodeIssues/RedundantToStringTests.cs | 254 - .../CodeIssues/RedundantTypeCastIssueTests.cs | 150 - .../RedundantUsingInspectorTests.cs | 139 - ...renceEqualsCalledWithValueTypeIssueTest.cs | 74 - ...erenceToStaticMemberViaDerivedTypeTests.cs | 304 - .../StaticFieldInGenericTypeTests.cs | 78 - .../StringIsNullOrEmptyInspectorTests.cs | 439 - .../ThreadStaticOnInstanceFieldTests.cs | 101 - .../TypeParameterNotUsedIssueTests.cs | 68 - .../CodeIssues/UnreachableCodeIssueTests.cs | 277 - .../CodeIssues/UseVarKeywordInspectorTests.cs | 54 - .../CodeIssues/ValueParameterUnusedTests.cs | 146 - .../VariableDeclaredInWideScopeTests.cs | 472 - .../CSharp/InsertParenthesesVisitorTests.cs | 397 - .../CSharp/Parser/Bugs/ParserBugTests.cs | 415 - .../AnonymousMethodExpressionTests.cs | 82 - .../AnonymousTypeCreateExpressionTests.cs | 40 - .../Expression/ArrayCreateExpressionTests.cs | 173 - .../Expression/AssignmentExpressionTests.cs | 113 - .../BaseReferenceExpressionTests.cs | 34 - .../BinaryOperatorExpressionTests.cs | 242 - .../Parser/Expression/CastExpressionTests.cs | 180 - .../Expression/ConditionalExpressionTests.cs | 119 - .../Expression/DefaultValueExpressionTests.cs | 94 - .../Expression/IdentifierExpressionTests.cs | 102 - .../Expression/IndexerExpressionTests.cs | 44 - .../Expression/InvocationExpressionTests.cs | 187 - .../Parser/Expression/IsExpressionTests.cs | 61 - .../Expression/LambdaExpressionTests.cs | 147 - .../MemberReferenceExpressionTests.cs | 126 - .../Expression/ObjectCreateExpressionTests.cs | 252 - .../ParenthesizedExpressionTests.cs | 36 - .../PointerReferenceExpressionTests.cs | 48 - .../Expression/PrimitiveExpressionTests.cs | 260 - .../Parser/Expression/QueryExpressionTests.cs | 485 - .../Expression/SizeOfExpressionTests.cs | 34 - .../Expression/StackAllocExpressionTests.cs | 37 - .../ThisReferenceExpressionTests.cs | 33 - .../Expression/TypeOfExpressionTests.cs | 154 - .../TypeReferenceExpressionTests.cs | 71 - .../UnaryOperatorExpressionTests.cs | 155 - .../Expression/UndocumentedExpressionTests.cs | 132 - .../GeneralScope/AttributeSectionTests.cs | 261 - .../Parser/GeneralScope/CommentTests.cs | 112 - .../GeneralScope/DelegateDeclarationTests.cs | 78 - .../GeneralScope/NamespaceDeclarationTests.cs | 72 - .../PreprocessorDirectiveTests.cs | 268 - .../GeneralScope/TypeDeclarationTests.cs | 369 - .../GeneralScope/UsingDeclarationTests.cs | 116 - .../CSharp/Parser/ParseSelfTests.cs | 156 - .../CSharp/Parser/ParseUtil.cs | 149 - .../Parser/Statements/BlockStatementTests.cs | 57 - .../Statements/CheckedStatementTests.cs | 60 - .../Parser/Statements/EmptyStatementTests.cs | 33 - .../Statements/ExpressionStatementTests.cs | 41 - .../Parser/Statements/FixedStatementTests.cs | 67 - .../Parser/Statements/ForStatementTests.cs | 82 - .../Parser/Statements/GotoStatementTests.cs | 59 - .../Parser/Statements/IfElseStatementTests.cs | 54 - .../Statements/InvalidStatementsTests.cs | 45 - .../Parser/Statements/LabelStatementTests.cs | 44 - .../Parser/Statements/LockStatementTests.cs | 34 - .../Parser/Statements/ReturnStatementTests.cs | 48 - .../Parser/Statements/SwitchStatementTests.cs | 35 - .../Parser/Statements/ThrowStatementTests.cs | 41 - .../Statements/TryCatchStatementTests.cs | 89 - .../Parser/Statements/UnsafeStatementTests.cs | 34 - .../Parser/Statements/UsingStatementTests.cs | 69 - .../VariableDeclarationStatementTests.cs | 260 - .../Parser/Statements/WhileStatementTests.cs | 43 - .../Parser/Statements/YieldStatementTests.cs | 54 - .../ConstructorDeclarationTests.cs | 67 - .../TypeMembers/DestructorDeclarationTests.cs | 47 - .../TypeMembers/EventDeclarationTests.cs | 104 - .../TypeMembers/FieldDeclarationTests.cs | 91 - .../TypeMembers/IndexerDeclarationTests.cs | 74 - .../TypeMembers/MethodDeclarationTests.cs | 428 - .../TypeMembers/OperatorDeclarationTests.cs | 74 - .../TypeMembers/PropertyDeclarationTests.cs | 107 - .../Parser/TypeSystemConvertVisitorTests.cs | 100 - .../CSharp/QueryExpressionExpanderTests.cs | 541 - .../CSharp/Refactoring/NamingHelperTests.cs | 300 - .../Refactoring/TypeSystemAstBuilderTests.cs | 214 - .../CSharp/Resolver/AnonymousTypeTests.cs | 100 - .../CSharp/Resolver/ArrayCreateTests.cs | 115 - .../CSharp/Resolver/AttributeTests.cs | 121 - .../CSharp/Resolver/BinaryOperatorTests.cs | 705 - .../CSharp/Resolver/CastTests.cs | 101 - .../CSharp/Resolver/ComTests.cs | 51 - .../Resolver/ConditionalOperatorTests.cs | 201 - .../CSharp/Resolver/ConversionsTest.cs | 605 - .../CSharp/Resolver/DynamicTests.cs | 705 - .../Resolver/ExplicitConversionsTest.cs | 514 - .../CSharp/Resolver/ExtensionMethodTests.cs | 239 - .../CSharp/Resolver/FindReferencesTest.cs | 215 - .../CSharp/Resolver/InvocationTests.cs | 739 - .../CSharp/Resolver/LambdaTests.cs | 639 - .../CSharp/Resolver/LinqTests.cs | 396 - .../Resolver/LocalTypeInferenceTests.cs | 214 - .../CSharp/Resolver/MemberLookupTests.cs | 460 - .../CSharp/Resolver/MethodTests.cs | 229 - .../CSharp/Resolver/NameLookupTests.cs | 1019 -- .../CSharp/Resolver/ObjectCreationTests.cs | 320 - .../Resolver/OverloadResolutionTests.cs | 319 - .../CSharp/Resolver/ResolveAtLocationTests.cs | 183 - .../CSharp/Resolver/ResolverTestBase.cs | 272 - .../CSharp/Resolver/TypeInferenceTests.cs | 464 - .../CSharp/Resolver/UnaryOperatorTests.cs | 278 - .../CSharp/Resolver/UnsafeCodeTests.cs | 69 - .../Documentation/CSharpCrefLookupTests.cs | 192 - .../Documentation/CSharpCrefParserTests.cs | 293 - .../Documentation/CSharpDocumentationTests.cs | 173 - .../Documentation/IDStringTests.cs | 359 - .../Editor/ReadOnlyDocumentTests.cs | 75 - .../TestBlankLineFormatting.cs | 286 - .../FormattingTests/TestBraceStlye.cs | 466 - .../FormattingTests/TestFormattingBugs.cs | 310 - .../TestKeepReformattingRules.cs | 105 - .../FormattingTests/TestSpacingVisitor.cs | 1639 -- .../TestStatementIndentation.cs | 2015 --- .../TestTypeLevelIndentation.cs | 641 - .../FormattingTests/TestWrapping.cs | 618 - .../FormattingTests/TextEditorTestAdapter.cs | 82 - .../ICSharpCode.NRefactory.Tests.csproj | 407 - .../Properties/AssemblyInfo.cs | 13 - .../TypeSystem/BlobLoaderTests.cs | 55 - .../TypeSystem/CecilLoaderTests.cs | 325 - .../TypeSystem/CyclicProjectDependency.cs | 64 - .../TypeSystem/GetAllBaseTypesTest.cs | 256 - .../TypeSystem/GetMembersTests.cs | 104 - .../TypeSystem/LazyLoadedCecilLoaderTests.cs | 36 - .../TypeSystem/ReflectionHelperTests.cs | 306 - .../TypeSystem/SerializedCecilLoaderTests.cs | 44 - .../TypeSystem/StructureTests.cs | 74 - .../TypeSystem/TestInterningProvider.cs | 207 - .../TypeSystem/TypeParameterTests.cs | 83 - .../TypeSystem/TypeSystemHelper.cs | 48 - .../TypeSystem/TypeSystemTests.TestCase.cs | 330 - .../TypeSystem/TypeSystemTests.cs | 1204 -- .../Utils/CSharpPrimitiveCastTests.cs | 83 - .../CompositeFormatStringParserTests.cs | 366 - .../Utils/TreeTraversalTests.cs | 62 - .../AXmlAttribute.cs | 118 - .../AXmlDocument.cs | 64 - .../ICSharpCode.NRefactory.Xml/AXmlElement.cs | 178 - .../ICSharpCode.NRefactory.Xml/AXmlObject.cs | 205 - .../ICSharpCode.NRefactory.Xml/AXmlParser.cs | 137 - .../ICSharpCode.NRefactory.Xml/AXmlReader.cs | 345 - .../ICSharpCode.NRefactory.Xml/AXmlTag.cs | 98 - .../ICSharpCode.NRefactory.Xml/AXmlText.cs | 63 - .../ICSharpCode.NRefactory.Xml/AXmlVisitor.cs | 62 - .../DocumentationElement.cs | 272 - .../ICSharpCode.NRefactory.Xml.csproj | 113 - .../IncrementalParserState.cs | 115 - .../InternalDocument.cs | 175 - NRefactory/ICSharpCode.NRefactory.Xml/Log.cs | 88 - .../ObjectIterator.cs | 109 - .../Properties/AssemblyInfo.cs | 15 - .../ICSharpCode.NRefactory.Xml/SyntaxError.cs | 63 - .../TagMatchingHeuristics.cs | 352 - .../ICSharpCode.NRefactory.Xml/TagReader.cs | 836 - .../ICSharpCode.NRefactory.Xml/TextType.cs | 47 - .../ICSharpCode.NRefactory.Xml/TokenReader.cs | 350 - .../ICSharpCode.NRefactory.Xml/XmlSegment.cs | 48 - .../Analysis/AbiComparer.cs | 248 + .../Analysis/SymbolCollector.cs | 160 + .../Analysis/TypeGraph.cs | 82 + .../Analysis/TypeGraphNode.cs} | 46 +- .../Completion/CompletionExtensionMethods.cs | 5 +- .../Completion/DisplayFlags.cs | 5 +- .../Completion/FrameworkLookup.cs | 490 + .../Completion/IParameterDataProvider.cs | 5 + .../Documentation/DocumentationComment.cs | 2 +- .../GetPotentiallyNestedClassTypeReference.cs | 11 +- .../Documentation/IDocumentationProvider.cs | 2 +- .../Documentation/IdStringMemberReference.cs | 27 +- .../Documentation/IdStringProvider.cs | 23 +- .../Documentation/XmlDocumentationProvider.cs | 102 +- .../Editor/IDocument.cs | 13 +- .../Editor/IDocumentLine.cs | 2 +- .../ICSharpCode.NRefactory/Editor/ISegment.cs | 2 +- .../Editor/ITextAnchor.cs | 2 +- .../Editor/ITextPasteHandler.cs} | 35 +- .../Editor/ITextSource.cs | 5 +- .../Editor/ReadOnlyDocument.cs | 28 +- .../Editor/StringBuilderDocument.cs | 16 +- .../Editor/StringTextSource.cs | 2 +- .../Editor/TextChangeEventArgs.cs | 2 +- .../Editor/TextSourceVersionProvider.cs | 6 +- .../Editor/UnicodeNewline.cs | 365 + .../ICSharpCode.NRefactory/IAnnotatable.cs | 6 +- .../ICSharpCode.NRefactory.csproj | 56 +- .../PatternMatching/AnyNode.cs | 3 +- .../PatternMatching/AnyNodeOrNull.cs | 58 + .../PatternMatching/Backreference.cs | 7 +- .../PatternMatching/BacktrackingInfo.cs | 3 +- .../PatternMatching/Choice.cs | 2 +- .../PatternMatching/INode.cs | 2 +- .../PatternMatching/Match.cs | 9 +- .../PatternMatching/NamedNode.cs | 2 +- .../PatternMatching/OptionalNode.cs | 2 +- .../PatternMatching/Pattern.cs | 2 +- .../PatternMatching/Repeat.cs | 2 +- .../Properties/AssemblyInfo.cs | 24 +- .../Properties/GlobalAssemblyInfo.cs | 27 +- .../Refactoring/IssueMarker.cs | 9 +- .../Refactoring/Severity.cs | 2 +- NRefactory/ICSharpCode.NRefactory/Role.cs | 4 +- .../Semantics/AmbiguousResolveResult.cs | 2 +- .../Semantics/ArrayAccessResolveResult.cs | 2 +- .../Semantics/ArrayCreateResolveResult.cs | 8 +- .../Semantics/ByReferenceResolveResult.cs | 2 +- .../Semantics/ConstantResolveResult.cs | 2 +- .../Semantics/Conversion.cs | 97 +- .../Semantics/ConversionResolveResult.cs | 5 +- .../Semantics/ErrorResolveResult.cs | 2 +- .../Semantics/ForEachResolveResult.cs | 2 +- .../InitializedObjectResolveResult.cs | 2 +- .../Semantics/InvocationResolveResult.cs | 8 +- .../Semantics/LocalResolveResult.cs | 4 +- .../Semantics/MemberResolveResult.cs | 23 +- .../Semantics/NamedArgumentResolveResult.cs | 2 +- .../Semantics/NamespaceResolveResult.cs | 2 +- .../Semantics/OperatorResolveResult.cs | 2 +- .../Semantics/ResolveResult.cs | 3 +- .../Semantics/SizeOfResolveResult.cs} | 56 +- .../Semantics/ThisResolveResult.cs | 2 +- .../Semantics/TypeIsResolveResult.cs | 2 +- .../Semantics/TypeOfResolveResult.cs | 2 +- .../Semantics/TypeResolveResult.cs | 2 +- .../Semantics/UnknownMemberResolveResult.cs | 2 +- .../ICSharpCode.NRefactory/TextLocation.cs | 37 +- .../TypeSystem/Accessibility.cs | 2 +- .../TypeSystem/AnonymousType.cs | 47 +- .../TypeSystem/ArrayType.cs | 21 +- .../TypeSystem/AssemblyLoader.cs | 94 + .../TypeSystem/AssemblyQualifiedTypeName.cs | 79 + .../TypeSystem/ByReferenceType.cs | 9 +- .../TypeSystem/ComHelper.cs | 2 +- .../TypeSystem/DefaultSolutionSnapshot.cs | 17 +- .../TypeSystem/DomRegion.cs | 16 +- .../TypeSystem/EntityType.cs | 50 +- .../TypeSystem/FullTypeName.cs | 315 + .../TypeSystem/IAmbience.cs | 16 +- .../TypeSystem/IAssembly.cs | 21 +- .../TypeSystem/IAttribute.cs | 2 +- .../TypeSystem/ICodeContext.cs} | 28 +- .../TypeSystem/ICompilation.cs | 21 +- .../TypeSystem/IConstantValue.cs | 2 +- .../TypeSystem/IEntity.cs | 13 +- .../TypeSystem/IEvent.cs | 2 +- .../TypeSystem/IField.cs | 19 +- .../TypeSystem/IFreezable.cs | 2 +- .../TypeSystem/IInterningProvider.cs | 62 +- .../TypeSystem/IMember.cs | 32 +- .../TypeSystem/IMethod.cs | 50 +- .../TypeSystem/INamedElement.cs | 2 +- .../TypeSystem/INamespace.cs | 6 +- .../TypeSystem/IParameter.cs | 8 +- .../TypeSystem/IParameterizedMember.cs | 2 +- .../TypeSystem/IProjectContent.cs | 2 +- .../TypeSystem/IProperty.cs | 2 +- .../TypeSystem/ISolutionSnapshot.cs | 2 +- .../TypeSystem/ISupportsInterning.cs | 9 +- .../TypeSystem/ISymbol.cs | 100 + .../TypeSystem/IType.cs | 34 +- .../TypeSystem/ITypeDefinition.cs | 18 +- .../TypeSystem/ITypeParameter.cs | 19 +- .../TypeSystem/ITypeReference.cs | 12 +- .../TypeSystem/IUnresolvedFile.cs | 7 +- .../TypeSystem/IVariable.cs | 6 +- .../Implementation/AbstractFreezable.cs | 21 +- .../Implementation/AbstractResolvedEntity.cs | 17 +- .../Implementation/AbstractResolvedMember.cs | 36 +- .../AbstractResolvedTypeParameter.cs | 161 +- .../TypeSystem/Implementation/AbstractType.cs | 27 +- .../AbstractUnresolvedEntity.cs | 23 +- .../AbstractUnresolvedMember.cs | 24 +- .../AccessorOwnerMemberReference.cs | 7 +- .../Implementation/BaseTypeCollector.cs | 2 +- .../TypeSystem/Implementation/BlobReader.cs | 387 + .../DefaultAssemblyReference.cs | 11 +- .../Implementation/DefaultAttribute.cs | 2 +- .../Implementation/DefaultMemberReference.cs | 36 +- .../Implementation/DefaultParameter.cs | 74 +- .../Implementation/DefaultResolvedEvent.cs | 9 +- .../Implementation/DefaultResolvedField.cs | 38 +- .../Implementation/DefaultResolvedMethod.cs | 66 +- .../Implementation/DefaultResolvedProperty.cs | 15 +- .../DefaultResolvedTypeDefinition.cs | 82 +- .../DefaultResolvedTypeParameter.cs | 6 +- .../DefaultUnresolvedAssembly.cs | 136 +- .../DefaultUnresolvedAttribute.cs | 76 +- .../Implementation/DefaultUnresolvedEvent.cs | 14 +- .../Implementation/DefaultUnresolvedField.cs | 22 +- .../Implementation/DefaultUnresolvedMethod.cs | 32 +- .../DefaultUnresolvedParameter.cs | 68 +- .../DefaultUnresolvedProperty.cs | 14 +- .../DefaultUnresolvedTypeDefinition.cs | 42 +- .../DefaultUnresolvedTypeParameter.cs | 33 +- .../Implementation/DefaultVariable.cs | 109 + .../Implementation/DummyTypeParameter.cs | 41 +- ...tInterfaceImplementationMemberReference.cs | 11 +- .../FullNameAndTypeParameterCount.cs | 71 +- .../Implementation/GetClassTypeReference.cs | 116 +- .../Implementation/GetMembersHelper.cs | 2 +- .../Implementation/KnownTypeCache.cs | 7 +- .../Implementation/MergedNamespace.cs | 11 +- .../Implementation/MinimalCorlib.cs | 4 +- .../Implementation/NestedTypeReference.cs | 24 +- .../Implementation/ResolvedAttributeBlob.cs | 176 + .../Implementation/SimpleCompilation.cs | 14 +- .../Implementation/SimpleConstantValue.cs | 12 +- .../Implementation/SimpleInterningProvider.cs | 80 +- .../Implementation/SpecializedEvent.cs | 4 +- .../Implementation/SpecializedField.cs | 10 +- .../Implementation/SpecializedMember.cs | 128 +- .../Implementation/SpecializedMethod.cs | 71 +- .../Implementation/SpecializedProperty.cs | 4 +- .../SpecializingMemberReference.cs | 12 +- .../Implementation/TypeParameterReference.cs | 58 +- .../Implementation/TypeWithElementType.cs | 2 +- .../TypeSystem/Implementation/UnknownType.cs | 52 +- .../Implementation/UnresolvedAttributeBlob.cs | 78 + .../UnresolvedSecurityDeclarationBlob.cs | 152 + .../Implementation/VoidTypeDefinition.cs | 2 +- .../TypeSystem/InheritanceHelper.cs | 20 +- .../TypeSystem/IntersectionType.cs | 2 +- .../TypeSystem/KnownTypeReference.cs | 36 +- .../TypeSystem/NullableType.cs | 5 +- .../TypeSystem/ParameterListComparer.cs | 37 +- .../TypeSystem/ParameterizedType.cs | 36 +- .../TypeSystem/PointerType.cs | 9 +- .../TypeSystem/ProjectReference.cs | 2 +- .../TypeSystem/ReflectionHelper.cs | 22 +- .../ReflectionNameParseException.cs | 2 +- .../TypeSystem/SimpleTypeResolveContext.cs | 2 +- .../TypeSystem/SpecialType.cs | 2 +- .../TypeSystem/TaskType.cs | 78 + .../TypeSystem/TopLevelTypeName.cs | 144 + .../TypeSystem/TypeKind.cs | 2 +- .../TypeParameterSubstitution.cs | 10 +- ...sionMethods.cs => TypeSystemExtensions.cs} | 383 +- .../TypeSystem/TypeVisitor.cs | 2 +- .../Utils/BitVector16.cs | 2 +- .../Utils/BusyManager.cs | 2 +- .../Utils/CSharpPrimitiveCast.cs | 4 +- .../Utils/CacheManager.cs | 2 +- .../Utils/CallbackOnDispose.cs | 2 +- .../Utils/ComparableList.cs | 166 + .../CompositeFormatStringParser.cs | 46 +- .../ICSharpCode.NRefactory/Utils/EmptyList.cs | 2 +- .../Utils/ExtensionMethods.cs | 4 +- .../Utils/FastSerializer.cs | 42 +- .../Utils/GraphVizGraph.cs | 10 +- .../Utils/ImmutableStack.cs | 19 +- .../Utils/KeyComparer.cs | 23 +- .../ICSharpCode.NRefactory/Utils/LazyInit.cs | 4 +- .../Utils/MultiDictionary.cs | 22 +- .../ICSharpCode.NRefactory/Utils/Platform.cs | 2 +- .../Utils/ProjectedList.cs | 2 +- .../Utils/ReferenceComparer.cs | 2 +- .../Utils/TreeTraversal.cs | 2 +- NRefactory/NRefactory.sln | 203 - .../Packages/ICSharpCode.NRefactory.nuspec | 36 - NRefactory/README | 12 +- NRefactory/doc/TODO | 10 +- NRefactory/doc/license.txt | 2 +- 969 files changed, 51916 insertions(+), 113370 deletions(-) delete mode 100644 NRefactory/ICSharpCode.NRefactory.CSharp.AstVerifier/AssemblyInfo.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.CSharp.AstVerifier/ICSharpCode.NRefactory.CSharp.AstVerifier.csproj delete mode 100644 NRefactory/ICSharpCode.NRefactory.CSharp.AstVerifier/Main.cs rename NRefactory/ICSharpCode.NRefactory.CSharp/{Ast/Expressions/EmptyExpression.cs => Analysis/AnnotationNames.cs} (50%) create mode 100644 NRefactory/ICSharpCode.NRefactory.CSharp/Analysis/DeclarationSpace/LocalDeclarationSpace.cs create mode 100644 NRefactory/ICSharpCode.NRefactory.CSharp/Analysis/DeclarationSpace/LocalDeclarationSpaceVisitor.cs create mode 100644 NRefactory/ICSharpCode.NRefactory.CSharp/Analysis/NullValueAnalysis.cs create mode 100644 NRefactory/ICSharpCode.NRefactory.CSharp/Analysis/NullValueStatus.cs create mode 100644 NRefactory/ICSharpCode.NRefactory.CSharp/Analysis/SemanticHighlightingVisitor.cs create mode 100644 NRefactory/ICSharpCode.NRefactory.CSharp/Ast/SyntaxExtensions.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.CSharp/Ast/old_ObservableAstVisitor.cs create mode 100644 NRefactory/ICSharpCode.NRefactory.CSharp/CombineQueryExpressions.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.CSharp/Formatter/AstFormattingVisitor.cs create mode 100644 NRefactory/ICSharpCode.NRefactory.CSharp/Formatter/CSharpFormatter.cs create mode 100644 NRefactory/ICSharpCode.NRefactory.CSharp/Formatter/ConstructFixer.cs create mode 100644 NRefactory/ICSharpCode.NRefactory.CSharp/Formatter/FormattingChanges.cs create mode 100644 NRefactory/ICSharpCode.NRefactory.CSharp/Formatter/FormattingVisitor.cs create mode 100644 NRefactory/ICSharpCode.NRefactory.CSharp/Formatter/FormattingVisitor_Expressions.cs create mode 100644 NRefactory/ICSharpCode.NRefactory.CSharp/Formatter/FormattingVisitor_Global.cs create mode 100644 NRefactory/ICSharpCode.NRefactory.CSharp/Formatter/FormattingVisitor_Query.cs create mode 100644 NRefactory/ICSharpCode.NRefactory.CSharp/Formatter/FormattingVisitor_Statements.cs create mode 100644 NRefactory/ICSharpCode.NRefactory.CSharp/Formatter/FormattingVisitor_TypeMembers.cs create mode 100644 NRefactory/ICSharpCode.NRefactory.CSharp/IndentEngine/CSharpIndentEngine.cs create mode 100644 NRefactory/ICSharpCode.NRefactory.CSharp/IndentEngine/CacheIndentEngine.cs create mode 100644 NRefactory/ICSharpCode.NRefactory.CSharp/IndentEngine/IDocumentIndentEngine.cs rename NRefactory/ICSharpCode.NRefactory.CSharp/{Refactoring/CodeIssues/IssueCategories.cs => IndentEngine/IStateMachineIndentEngine.cs} (57%) create mode 100644 NRefactory/ICSharpCode.NRefactory.CSharp/IndentEngine/IndentState.cs create mode 100644 NRefactory/ICSharpCode.NRefactory.CSharp/IndentEngine/NullIStateMachineIndentEngine.cs create mode 100644 NRefactory/ICSharpCode.NRefactory.CSharp/IndentEngine/TextPasteIndentEngine.cs create mode 100644 NRefactory/ICSharpCode.NRefactory.CSharp/IntroduceQueryExpressions.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.CSharp/OutputVisitor/IOutputFormatter.cs create mode 100644 NRefactory/ICSharpCode.NRefactory.CSharp/OutputVisitor/ITokenWriter.cs create mode 100644 NRefactory/ICSharpCode.NRefactory.CSharp/OutputVisitor/InsertMissingTokensDecorator.cs create mode 100644 NRefactory/ICSharpCode.NRefactory.CSharp/OutputVisitor/InsertRequiredSpacesDecorator.cs create mode 100644 NRefactory/ICSharpCode.NRefactory.CSharp/OutputVisitor/InsertSpecialsDecorator.cs rename NRefactory/{ICSharpCode.NRefactory.Tests/CSharp/Inspector/InconsistentNamingIssueTests.cs => ICSharpCode.NRefactory.CSharp/PatternMatching/AnyType.cs} (79%) rename NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/{ICodeActionProvider.cs => CodeActionProvider.cs} (91%) delete mode 100644 NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/CodeActions/AddAnotherAccessorAction.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/CodeActions/AddCatchTypeAction.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/CodeActions/CheckIfParameterIsNullAction.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/CodeActions/ConvertAnonymousDelegateToLambdaAction.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/CodeActions/ConvertAsToCastAction.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/CodeActions/ConvertCastToAsAction.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/CodeActions/ConvertConditionalToIfAction.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/CodeActions/ConvertDecToHexAction.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/CodeActions/ConvertExplicitToImplicitImplementationAction.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/CodeActions/ConvertForeachToForAction.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/CodeActions/ConvertHexToDecAction.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/CodeActions/ConvertIfToConditionalAction.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/CodeActions/ConvertIfToSwitchAction.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/CodeActions/ConvertImplicitToExplicitImplementationAction.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/CodeActions/ConvertLambdaBodyExpressionToStatementAction.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/CodeActions/ConvertLambdaBodyStatementToExpressionAction.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/CodeActions/ConvertLambdaToAnonymousDelegateAction.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/CodeActions/ConvertSwitchToIfAction.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/CodeActions/ConvertToInitializer/ConvertInitializerToExplicitInitializationsAction.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/CodeActions/ConvertToInitializer/ConvertToInitializerAction.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/CodeActions/ConvertToInitializer/InitializerPath.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/CodeActions/ConvertToInitializer/StatementsToInitializerConverter.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/CodeActions/CreateBackingStoreAction.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/CodeActions/CreateClassDeclarationAction.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/CodeActions/CreateConstructorDeclarationAction.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/CodeActions/CreateCustomEventImplementationAction.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/CodeActions/CreateDelegateAction.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/CodeActions/CreateEventInvocatorAction.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/CodeActions/CreateIndexerAction.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/CodeActions/CreateLocalVariableAction.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/CodeActions/CreateMethodDeclarationAction.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/CodeActions/CreateOverloadWithoutParameterAction.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/CodeActions/CreatePropertyAction.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/CodeActions/DeclareLocalVariableAction.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/CodeActions/ExtensionMethodInvocationToStaticMethodInvocationAction.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/CodeActions/ExtractAnonymousMethodAction.cs delete mode 100755 NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/CodeActions/ExtractFieldAction.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/CodeActions/ExtractMethod/ExtractMethodAction.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/CodeActions/ExtractMethod/StaticVisitor.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/CodeActions/ExtractMethod/VariableLookupVisitor.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/CodeActions/ExtractMethod/VariableUsageAnalyzation.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/CodeActions/FlipOperatorArgumentsAction.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/CodeActions/GenerateGetterAction.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/CodeActions/GeneratePropertyAction.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/CodeActions/GenerateSwitchLabelsAction.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/CodeActions/ImplementAbstractMembersAction.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/CodeActions/ImplementInterfaceAction.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/CodeActions/ImplementInterfaceExplicitAction.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/CodeActions/InlineLocalVariableAction.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/CodeActions/InsertAnonymousMethodSignatureAction.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/CodeActions/IntroduceConstantAction.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/CodeActions/IntroduceFormatItemAction.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/CodeActions/InvertIfAction.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/CodeActions/IterateViaForeachAction.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/CodeActions/JoinDeclarationAndAssignmentAction.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/CodeActions/JoinStringAction.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/CodeActions/MergeNestedIfAction.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/CodeActions/MoveToOuterScopeAction.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/CodeActions/NegateRelationalExpressionAction.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/CodeActions/PutInsideUsingAction.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/CodeActions/RemoveBackingStoreAction.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/CodeActions/RemoveBracesAction.cs create mode 100644 NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/CodeActions/RemoveFieldRefactoryActionRefactoringAction.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/CodeActions/RemoveRedundantCatchTypeAction.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/CodeActions/RemoveRegionAction.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/CodeActions/ReplaceEmptyStringAction.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/CodeActions/SpecializedCodeAction.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/CodeActions/SplitDeclarationAndAssignmentAction.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/CodeActions/SplitDeclarationListAction.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/CodeActions/SplitStringAction.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/CodeActions/StaticMethodInvocationToExtensionMethodInvocationAction.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/CodeActions/UseExplicitTypeAction.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/CodeActions/UseStringFormatAction.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/CodeActions/UseVarKeywordAction.cs create mode 100644 NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/CodeGenerationService.cs rename NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/{CodeIssues/InconsistentNamingIssue/AffectedEntity.cs => CodeIssueProvider.cs} (51%) delete mode 100644 NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/CodeIssues/AccessToClosureIssues/AccessToClosureIssue.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/CodeIssues/AccessToClosureIssues/AccessToDisposedClosureIssue.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/CodeIssues/AccessToClosureIssues/AccessToModifiedClosureIssue.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/CodeIssues/AccessToClosureIssues/LocalVariableNamePicker.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/CodeIssues/AssignmentMadeToSameVariableIssue.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/CodeIssues/BitwiseOperationOnNonFlagsEnumIssue.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/CodeIssues/CallToObjectEqualsViaBaseIssue.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/CodeIssues/CallToVirtualFunctionFromConstructorIssue.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/CodeIssues/CastExpressionOfIncompatibleTypeIssue.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/CodeIssues/CompareBooleanWithTrueOrFalseIssue.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/CodeIssues/CompareFloatWithEqualityOperatorIssue.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/CodeIssues/ConditionalToNullCoalescingIssue.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/CodeIssues/ConstantConditionIssue.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/CodeIssues/DoubleNegationIssue.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/CodeIssues/ExceptionRethrowIssue.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/CodeIssues/ExplicitConversionInForEachIssue.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/CodeIssues/ExpressionIsAlwaysOfProvidedTypeIssue.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/CodeIssues/ExpressionIsNeverOfProvidedTypeIssue.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/CodeIssues/ForControlVariableNotModifiedIssue.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/CodeIssues/FormatStringIssues/FormatStringIssue.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/CodeIssues/GatherVisitorBase.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/CodeIssues/IdenticalConditionalBranchIssue.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/CodeIssues/InconsistentNamingIssue/DefaultRules.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/CodeIssues/InconsistentNamingIssue/InconsistentNamingIssue.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/CodeIssues/InconsistentNamingIssue/NamingConventionService.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/CodeIssues/InconsistentNamingIssue/NamingRule.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/CodeIssues/IncorrectCallToObjectGetHashCodeIssue.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/CodeIssues/IncorrectExceptionParameterOrderingIssue.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/CodeIssues/MethodNeverReturnsIssue.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/CodeIssues/MethodOverloadHidesOptionalParameterIssue.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/CodeIssues/MultipleEnumerationIssue.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/CodeIssues/NegativeRelationalExpressionIssue.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/CodeIssues/NotImplementedExceptionIssue.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/CodeIssues/OptionalParameterCouldBeSkippedIssue.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/CodeIssues/ParameterCanBeDemotedIssue/HasMemberCriterion.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/CodeIssues/ParameterCanBeDemotedIssue/IsTypeCriterion.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/CodeIssues/ParameterCanBeDemotedIssue/ParameterCanBeDemotedIssue.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/CodeIssues/ParameterCanBeDemotedIssue/SupportsIndexingCriterion.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/CodeIssues/ParameterCanBeDemotedIssue/TypeCriteriaCollector.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/CodeIssues/RedundantArrayInitializerCommaIssue.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/CodeIssues/RedundantAssignmentIssue.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/CodeIssues/RedundantAttributeParenthesesIssue.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/CodeIssues/RedundantCaseLabelIssue.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/CodeIssues/RedundantCatchIssue.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/CodeIssues/RedundantElseIssue.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/CodeIssues/RedundantFieldInitializerIssue.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/CodeIssues/RedundantInternalIssue.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/CodeIssues/RedundantNamespaceUsageIssue.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/CodeIssues/RedundantObjectCreationArgumentListIssue.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/CodeIssues/RedundantObjectOrCollectionInitializerIssue.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/CodeIssues/RedundantPrivateIssue.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/CodeIssues/RedundantThisIssue.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/CodeIssues/RedundantToStringIssue.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/CodeIssues/RedundantTypeCastIssue.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/CodeIssues/RedundantUsingIssue.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/CodeIssues/ReferenceEqualsCalledWithValueTypeIssue.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/CodeIssues/ReferenceToStaticMemberViaDerivedTypeIssue.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/CodeIssues/StaticFieldInGenericTypeIssue.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/CodeIssues/StringIsNullOrEmptyIssue.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/CodeIssues/ThreadStaticOnInstanceFieldIssue.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/CodeIssues/TypeParameterNotUsedIssue.cs create mode 100644 NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/CodeIssues/Uncategorized/.DS_Store delete mode 100644 NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/CodeIssues/UnreachableCodeIssue.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/CodeIssues/UseVarKeywordIssue.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/CodeIssues/ValueParameterUnusedIssue.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/CodeIssues/VariableDeclaredInWideScopeIssue.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/CodeIssues/VariableHidesMemberIssue/LocalVariableHidesMemberIssue.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/CodeIssues/VariableHidesMemberIssue/ParameterHidesMemberIssue.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/CodeIssues/VariableHidesMemberIssue/VariableHidesMemberIssue.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/CodeIssues/VariableNotUsedIssues/LocalVariableNotUsedIssue.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/CodeIssues/VariableNotUsedIssues/ParameterNotUsedIssue.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/CodeIssues/VariableNotUsedIssues/VariableNotUsedIssue.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/CodeIssues/VariableOnlyAssignedIssues/LocalVariableOnlyAssignedIssue.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/CodeIssues/VariableOnlyAssignedIssues/ParameterOnlyAssignedIssue.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/CodeIssues/VariableOnlyAssignedIssues/VariableOnlyAssignedIssue.cs rename NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/{CodeIssues/ParameterCanBeDemotedIssue/IsArrayTypeCriterion.cs => CommonSubIssues.cs} (76%) rename NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/{CodeIssues/FormatStringIssues => }/FormatStringHelper.cs (66%) create mode 100644 NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/LocalReferenceFinder.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/TypeCompatibilityHelper.cs rename NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/{CodeActions/CreateFieldAction.cs => TypeGuessing.cs} (52%) create mode 100644 NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/UsingHelper.cs rename NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/{CodeIssues/InconsistentNamingIssue => }/WordParser.cs (100%) rename NRefactory/ICSharpCode.NRefactory.CSharp/{Refactoring/CodeIssues/InconsistentNamingIssue/NamingStyle.cs => Resolver/AliasNamespaceResolveResult.cs} (62%) rename NRefactory/ICSharpCode.NRefactory.CSharp/{Refactoring/ICodeIssueProvider.cs => Resolver/AliasTypeResolveResult.cs} (67%) create mode 100644 NRefactory/ICSharpCode.NRefactory.CSharp/Resolver/AwaitResolveResult.cs create mode 100644 NRefactory/ICSharpCode.NRefactory.CSharp/Resolver/CastResolveResult.cs create mode 100644 NRefactory/ICSharpCode.NRefactory.CSharp/Resolver/ReducedExtensionMethod.cs rename NRefactory/{ICSharpCode.NRefactory.Tests/CSharp/Parser/Expression/CheckedExpressionTests.cs => ICSharpCode.NRefactory.CSharp/Resolver/RenameCallbackArguments.cs} (62%) create mode 100644 NRefactory/ICSharpCode.NRefactory.CSharp/Util/CloneableStack.cs rename NRefactory/{ICSharpCode.NRefactory/TypeSystem => ICSharpCode.NRefactory.Cecil}/CecilLoader.cs (62%) create mode 100644 NRefactory/ICSharpCode.NRefactory.Cecil/ICSharpCode.NRefactory.Cecil.csproj rename NRefactory/{ICSharpCode.NRefactory.GtkDemo/Main.cs => ICSharpCode.NRefactory.Cecil/Properties/AssemblyInfo.cs} (73%) create mode 100644 NRefactory/ICSharpCode.NRefactory.ConsistencyCheck/PatternMatchingTest.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Demo/CSDemo.Designer.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Demo/CSDemo.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Demo/CSDemo.resx delete mode 100644 NRefactory/ICSharpCode.NRefactory.Demo/ICSharpCode.NRefactory.Demo.csproj delete mode 100644 NRefactory/ICSharpCode.NRefactory.Demo/MainForm.Designer.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Demo/MainForm.resx delete mode 100644 NRefactory/ICSharpCode.NRefactory.Demo/Properties/AssemblyInfo.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Demo/SemanticTreeDialog.Designer.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Demo/SemanticTreeDialog.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Demo/SemanticTreeDialog.resx delete mode 100644 NRefactory/ICSharpCode.NRefactory.Demo/VBAstView.Designer.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Demo/VBAstView.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Demo/VBAstView.resx delete mode 100644 NRefactory/ICSharpCode.NRefactory.Demo/VBDemo.Designer.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Demo/VBDemo.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Demo/VBDemo.resx delete mode 100644 NRefactory/ICSharpCode.NRefactory.Demo/VBEditDialog.Designer.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Demo/VBEditDialog.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Demo/VBEditDialog.resx delete mode 100644 NRefactory/ICSharpCode.NRefactory.GtkDemo/AssemblyInfo.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.GtkDemo/CSharpDemo.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.GtkDemo/ICSharpCode.NRefactory.GtkDemo.csproj delete mode 100644 NRefactory/ICSharpCode.NRefactory.GtkDemo/MainWindow.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.GtkDemo/gtk-gui/ICSharpCode.NRefactory.GtkDemo.MainWindow.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.GtkDemo/gtk-gui/generated.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.GtkDemo/gtk-gui/gui.stetic delete mode 100644 NRefactory/ICSharpCode.NRefactory.GtkDemo/pixbuf/comment.png delete mode 100644 NRefactory/ICSharpCode.NRefactory.GtkDemo/pixbuf/element-class-16.png delete mode 100644 NRefactory/ICSharpCode.NRefactory.GtkDemo/pixbuf/element-field-16.png delete mode 100644 NRefactory/ICSharpCode.NRefactory.GtkDemo/pixbuf/element-literal-16.png delete mode 100644 NRefactory/ICSharpCode.NRefactory.GtkDemo/pixbuf/element-method-16.png delete mode 100644 NRefactory/ICSharpCode.NRefactory.GtkDemo/pixbuf/element-namespace-16.png delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Analysis/DefiniteAssignmentTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/AstStructureTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/CSharpAmbienceTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/CSharpOutputVisitorTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/CodeActions/AddAnotherAccessorTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/CodeActions/AddCatchTypeTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/CodeActions/CheckIfParameterIsNullTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/CodeActions/ContextActionTestBase.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/CodeActions/ConvertAnonymousDelegateToLambdaTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/CodeActions/ConvertAsToCastTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/CodeActions/ConvertCastToAsTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/CodeActions/ConvertConditionalToIfTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/CodeActions/ConvertDecToHexTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/CodeActions/ConvertExplicitToImplicitImplementationTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/CodeActions/ConvertForeachToForTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/CodeActions/ConvertHexToDecTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/CodeActions/ConvertIfToConditionalTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/CodeActions/ConvertIfToSwtichTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/CodeActions/ConvertImplicitToExplicittImplementationTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/CodeActions/ConvertLambdaBodyExpressionToStatementTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/CodeActions/ConvertLambdaBodyStatementToExpressionTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/CodeActions/ConvertLamdaToAnonymousDelegateTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/CodeActions/ConvertSwitchToIfTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/CodeActions/ConvertToInitializer/ConvertInitializerToExplicitIntializationsTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/CodeActions/ConvertToInitializer/ConvertToInitializerTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/CodeActions/CreateBackingStoreTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/CodeActions/CreateClassDeclarationTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/CodeActions/CreateConstructorDeclarationTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/CodeActions/CreateCustomEventImplementationTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/CodeActions/CreateDelegateTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/CodeActions/CreateFieldTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/CodeActions/CreateIndexerTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/CodeActions/CreateLocalVariableTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/CodeActions/CreateMethodDeclarationTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/CodeActions/CreateOverloadWithoutParameterTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/CodeActions/CreatePropertyTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/CodeActions/DeclareLocalVariableTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/CodeActions/ExtensionMethodInvocationToStaticMethodInvocationTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/CodeActions/ExtractAnonymousMethodTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/CodeActions/ExtractFieldTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/CodeActions/ExtractMethodTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/CodeActions/FlipOperatorArgumentsTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/CodeActions/GenerateGetterTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/CodeActions/GeneratePropertyTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/CodeActions/GenerateSwitchLabelsTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/CodeActions/ImplementAbstractMembersTest.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/CodeActions/ImplementInterfaceExplicitTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/CodeActions/ImplementInterfaceTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/CodeActions/InlineLocalVariableTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/CodeActions/InsertAnonymousMethodSignatureTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/CodeActions/IntroduceConstantTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/CodeActions/IntroduceFormatItemTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/CodeActions/InvertIfTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/CodeActions/IterateViaForeachTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/CodeActions/JoinDeclarationAndAssignmentTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/CodeActions/JoinStringTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/CodeActions/MergeNestedIfTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/CodeActions/MoveToOuterScopeTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/CodeActions/NegateRelationalExpressionTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/CodeActions/PutInsideUsingTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/CodeActions/RemoveBackingStoreTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/CodeActions/RemoveBracesTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/CodeActions/RemoveRedundantCatchTypeTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/CodeActions/RemoveRegionTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/CodeActions/ReplaceEmptyStringTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/CodeActions/SplitDeclarationAndAssignmentTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/CodeActions/SplitDeclarationListTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/CodeActions/SplitStringTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/CodeActions/StaticMethodInvocationToExtensionMethodInvocationTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/CodeActions/TestRefactoringContext.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/CodeActions/UseExplicitTypeTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/CodeActions/UseStringFormatTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/CodeActions/UseVarKeywordTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/CodeCompletion/BrowsableAttributeTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/CodeCompletion/CodeCompletionAccessibleTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/CodeCompletion/CodeCompletionBugTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/CodeCompletion/CodeCompletionCSharp3Tests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/CodeCompletion/CodeCompletionCSharpTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/CodeCompletion/CodeComplteionOperatorTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/CodeCompletion/CompletionDataList.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/CodeCompletion/DelegateContextTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/CodeCompletion/DocumentationContextTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/CodeCompletion/EnumContextTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/CodeCompletion/KeywordTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/CodeCompletion/NameContextTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/CodeCompletion/ObjectInitializerTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/CodeCompletion/ParameterCompletionTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/CodeCompletion/PreProcessorTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/CodeCompletion/TestBase.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/CodeCompletion/VariableDeclarationStatementTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/CodeDomConvertVisitorTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/CodeIssues/AccessToDisposedClosureTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/CodeIssues/AccessToModifiedClosureTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/CodeIssues/AssignmentMadeToSameVariableIssueTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/CodeIssues/BitwiseOperationOnNonFlagsEnumIssueTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/CodeIssues/CallToObjectEqualsViaBaseTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/CodeIssues/CallToVirtualFunctionFromConstructorTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/CodeIssues/CastExpressionOfIncompatibleTypeIssueTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/CodeIssues/CompareBooleanWithTrueOrFalseIssueTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/CodeIssues/CompareFloatWithEqualityOperatorIssueTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/CodeIssues/ConditionalToNullCoalescingInspectorTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/CodeIssues/ConstantConditionIssueTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/CodeIssues/DoubleNegationIssueTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/CodeIssues/ExceptionRethrowTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/CodeIssues/ExplicitConversionInForEachIssueTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/CodeIssues/ExpressionIsAlwaysOfProvidedTypeIssueTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/CodeIssues/ExpressionIsNeverOfProvidedTypeIssueTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/CodeIssues/ForControlVariableNotModifiedIssueTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/CodeIssues/FormatStringIssues/FormatStringTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/CodeIssues/IdenticalConditionalBranchIssueTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/CodeIssues/InconsistentNamingTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/CodeIssues/IncorrectCallToGetHashCodeTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/CodeIssues/IncorrectExceptionParameterOrderingTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/CodeIssues/InspectionActionTestBase.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/CodeIssues/LocalVariableHidesMemberIssueTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/CodeIssues/LocalVariableNotUsedIssueTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/CodeIssues/LocalVariableOnlyAssignedIssueTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/CodeIssues/MethodNeverReturnsIssueTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/CodeIssues/MethodOverloadHidesOptionalParameterIssueTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/CodeIssues/MultipleEnumerationIssueTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/CodeIssues/NegativeRelationalExpressionIssueTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/CodeIssues/NotImplementedExceptionInspectorTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/CodeIssues/OptionalParameterCouldBeSkippedTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/CodeIssues/ParameterCanBeDemotedIssue/IsTypeCriterionTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/CodeIssues/ParameterCanBeDemotedIssue/ParameterCanBeDemotedTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/CodeIssues/ParameterCanBeDemotedIssue/SupportsIndexingCriterionTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/CodeIssues/ParameterHidesMemberIssueTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/CodeIssues/ParameterNotUsedIssueTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/CodeIssues/ParameterOnlyAssignedIssueTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/CodeIssues/RedundantArrayInitializerCommaIssueTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/CodeIssues/RedundantAssignmentIssueTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/CodeIssues/RedundantAttributeParenthesesIssueTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/CodeIssues/RedundantCaseLabelIssueTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/CodeIssues/RedundantCatchTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/CodeIssues/RedundantElseIssueTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/CodeIssues/RedundantFieldInitializerIssueTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/CodeIssues/RedundantInternalInspectorTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/CodeIssues/RedundantNamespaceUsageInspectorTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/CodeIssues/RedundantObjectCreationArgumentListIssueTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/CodeIssues/RedundantObjectOrCollectionInitializerIssueTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/CodeIssues/RedundantPrivateInspectorTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/CodeIssues/RedundantThisInspectorTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/CodeIssues/RedundantToStringTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/CodeIssues/RedundantTypeCastIssueTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/CodeIssues/RedundantUsingInspectorTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/CodeIssues/ReferenceEqualsCalledWithValueTypeIssueTest.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/CodeIssues/ReferenceToStaticMemberViaDerivedTypeTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/CodeIssues/StaticFieldInGenericTypeTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/CodeIssues/StringIsNullOrEmptyInspectorTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/CodeIssues/ThreadStaticOnInstanceFieldTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/CodeIssues/TypeParameterNotUsedIssueTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/CodeIssues/UnreachableCodeIssueTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/CodeIssues/UseVarKeywordInspectorTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/CodeIssues/ValueParameterUnusedTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/CodeIssues/VariableDeclaredInWideScopeTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/InsertParenthesesVisitorTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/Bugs/ParserBugTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/Expression/AnonymousMethodExpressionTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/Expression/AnonymousTypeCreateExpressionTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/Expression/ArrayCreateExpressionTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/Expression/AssignmentExpressionTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/Expression/BaseReferenceExpressionTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/Expression/BinaryOperatorExpressionTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/Expression/CastExpressionTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/Expression/ConditionalExpressionTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/Expression/DefaultValueExpressionTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/Expression/IdentifierExpressionTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/Expression/IndexerExpressionTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/Expression/InvocationExpressionTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/Expression/IsExpressionTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/Expression/LambdaExpressionTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/Expression/MemberReferenceExpressionTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/Expression/ObjectCreateExpressionTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/Expression/ParenthesizedExpressionTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/Expression/PointerReferenceExpressionTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/Expression/PrimitiveExpressionTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/Expression/QueryExpressionTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/Expression/SizeOfExpressionTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/Expression/StackAllocExpressionTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/Expression/ThisReferenceExpressionTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/Expression/TypeOfExpressionTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/Expression/TypeReferenceExpressionTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/Expression/UnaryOperatorExpressionTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/Expression/UndocumentedExpressionTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/GeneralScope/AttributeSectionTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/GeneralScope/CommentTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/GeneralScope/DelegateDeclarationTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/GeneralScope/NamespaceDeclarationTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/GeneralScope/PreprocessorDirectiveTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/GeneralScope/TypeDeclarationTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/GeneralScope/UsingDeclarationTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/ParseSelfTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/ParseUtil.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/Statements/BlockStatementTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/Statements/CheckedStatementTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/Statements/EmptyStatementTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/Statements/ExpressionStatementTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/Statements/FixedStatementTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/Statements/ForStatementTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/Statements/GotoStatementTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/Statements/IfElseStatementTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/Statements/InvalidStatementsTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/Statements/LabelStatementTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/Statements/LockStatementTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/Statements/ReturnStatementTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/Statements/SwitchStatementTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/Statements/ThrowStatementTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/Statements/TryCatchStatementTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/Statements/UnsafeStatementTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/Statements/UsingStatementTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/Statements/VariableDeclarationStatementTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/Statements/WhileStatementTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/Statements/YieldStatementTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/TypeMembers/ConstructorDeclarationTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/TypeMembers/DestructorDeclarationTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/TypeMembers/EventDeclarationTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/TypeMembers/FieldDeclarationTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/TypeMembers/IndexerDeclarationTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/TypeMembers/MethodDeclarationTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/TypeMembers/OperatorDeclarationTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/TypeMembers/PropertyDeclarationTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/TypeSystemConvertVisitorTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/QueryExpressionExpanderTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Refactoring/NamingHelperTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Refactoring/TypeSystemAstBuilderTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Resolver/AnonymousTypeTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Resolver/ArrayCreateTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Resolver/AttributeTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Resolver/BinaryOperatorTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Resolver/CastTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Resolver/ComTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Resolver/ConditionalOperatorTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Resolver/ConversionsTest.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Resolver/DynamicTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Resolver/ExplicitConversionsTest.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Resolver/ExtensionMethodTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Resolver/FindReferencesTest.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Resolver/InvocationTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Resolver/LambdaTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Resolver/LinqTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Resolver/LocalTypeInferenceTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Resolver/MemberLookupTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Resolver/MethodTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Resolver/NameLookupTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Resolver/ObjectCreationTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Resolver/OverloadResolutionTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Resolver/ResolveAtLocationTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Resolver/ResolverTestBase.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Resolver/TypeInferenceTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Resolver/UnaryOperatorTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Resolver/UnsafeCodeTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/Documentation/CSharpCrefLookupTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/Documentation/CSharpCrefParserTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/Documentation/CSharpDocumentationTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/Documentation/IDStringTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/Editor/ReadOnlyDocumentTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/FormattingTests/TestBlankLineFormatting.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/FormattingTests/TestBraceStlye.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/FormattingTests/TestFormattingBugs.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/FormattingTests/TestKeepReformattingRules.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/FormattingTests/TestSpacingVisitor.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/FormattingTests/TestStatementIndentation.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/FormattingTests/TestTypeLevelIndentation.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/FormattingTests/TestWrapping.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/FormattingTests/TextEditorTestAdapter.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/ICSharpCode.NRefactory.Tests.csproj delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/Properties/AssemblyInfo.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/TypeSystem/BlobLoaderTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/TypeSystem/CecilLoaderTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/TypeSystem/CyclicProjectDependency.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/TypeSystem/GetAllBaseTypesTest.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/TypeSystem/GetMembersTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/TypeSystem/LazyLoadedCecilLoaderTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/TypeSystem/ReflectionHelperTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/TypeSystem/SerializedCecilLoaderTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/TypeSystem/StructureTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/TypeSystem/TestInterningProvider.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/TypeSystem/TypeParameterTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/TypeSystem/TypeSystemHelper.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/TypeSystem/TypeSystemTests.TestCase.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/TypeSystem/TypeSystemTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/Utils/CSharpPrimitiveCastTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/Utils/CompositeFormatStringParser/CompositeFormatStringParserTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Tests/Utils/TreeTraversalTests.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Xml/AXmlAttribute.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Xml/AXmlDocument.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Xml/AXmlElement.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Xml/AXmlObject.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Xml/AXmlParser.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Xml/AXmlReader.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Xml/AXmlTag.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Xml/AXmlText.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Xml/AXmlVisitor.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Xml/DocumentationElement.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Xml/ICSharpCode.NRefactory.Xml.csproj delete mode 100644 NRefactory/ICSharpCode.NRefactory.Xml/IncrementalParserState.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Xml/InternalDocument.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Xml/Log.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Xml/ObjectIterator.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Xml/Properties/AssemblyInfo.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Xml/SyntaxError.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Xml/TagMatchingHeuristics.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Xml/TagReader.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Xml/TextType.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Xml/TokenReader.cs delete mode 100644 NRefactory/ICSharpCode.NRefactory.Xml/XmlSegment.cs create mode 100644 NRefactory/ICSharpCode.NRefactory/Analysis/AbiComparer.cs create mode 100644 NRefactory/ICSharpCode.NRefactory/Analysis/SymbolCollector.cs create mode 100644 NRefactory/ICSharpCode.NRefactory/Analysis/TypeGraph.cs rename NRefactory/{ICSharpCode.NRefactory.Demo/MainForm.cs => ICSharpCode.NRefactory/Analysis/TypeGraphNode.cs} (62%) create mode 100644 NRefactory/ICSharpCode.NRefactory/Completion/FrameworkLookup.cs rename NRefactory/{ICSharpCode.NRefactory.CSharp/Refactoring/CodeIssues/ParameterCanBeDemotedIssue/ITypeCriterion.cs => ICSharpCode.NRefactory/Editor/ITextPasteHandler.cs} (52%) create mode 100644 NRefactory/ICSharpCode.NRefactory/Editor/UnicodeNewline.cs create mode 100644 NRefactory/ICSharpCode.NRefactory/PatternMatching/AnyNodeOrNull.cs rename NRefactory/{ICSharpCode.NRefactory.CSharp => ICSharpCode.NRefactory}/Refactoring/IssueMarker.cs (90%) rename NRefactory/{ICSharpCode.NRefactory.CSharp => ICSharpCode.NRefactory}/Refactoring/Severity.cs (97%) rename NRefactory/{ICSharpCode.NRefactory.Xml/ReuseEqualityComparer.cs => ICSharpCode.NRefactory/Semantics/SizeOfResolveResult.cs} (54%) create mode 100644 NRefactory/ICSharpCode.NRefactory/TypeSystem/AssemblyLoader.cs create mode 100644 NRefactory/ICSharpCode.NRefactory/TypeSystem/AssemblyQualifiedTypeName.cs create mode 100644 NRefactory/ICSharpCode.NRefactory/TypeSystem/FullTypeName.cs rename NRefactory/{ICSharpCode.NRefactory.Demo/Program.cs => ICSharpCode.NRefactory/TypeSystem/ICodeContext.cs} (68%) create mode 100644 NRefactory/ICSharpCode.NRefactory/TypeSystem/ISymbol.cs create mode 100644 NRefactory/ICSharpCode.NRefactory/TypeSystem/Implementation/BlobReader.cs create mode 100644 NRefactory/ICSharpCode.NRefactory/TypeSystem/Implementation/DefaultVariable.cs create mode 100644 NRefactory/ICSharpCode.NRefactory/TypeSystem/Implementation/ResolvedAttributeBlob.cs create mode 100644 NRefactory/ICSharpCode.NRefactory/TypeSystem/Implementation/UnresolvedAttributeBlob.cs create mode 100644 NRefactory/ICSharpCode.NRefactory/TypeSystem/Implementation/UnresolvedSecurityDeclarationBlob.cs create mode 100644 NRefactory/ICSharpCode.NRefactory/TypeSystem/TaskType.cs create mode 100644 NRefactory/ICSharpCode.NRefactory/TypeSystem/TopLevelTypeName.cs rename NRefactory/ICSharpCode.NRefactory/TypeSystem/{Implementation => }/TypeParameterSubstitution.cs (94%) rename NRefactory/ICSharpCode.NRefactory/TypeSystem/{ExtensionMethods.cs => TypeSystemExtensions.cs} (50%) create mode 100644 NRefactory/ICSharpCode.NRefactory/Utils/ComparableList.cs delete mode 100644 NRefactory/NRefactory.sln delete mode 100644 NRefactory/Packages/ICSharpCode.NRefactory.nuspec diff --git a/NRefactory/.gitattributes b/NRefactory/.gitattributes index 1a1533024..fbfb41be8 100644 --- a/NRefactory/.gitattributes +++ b/NRefactory/.gitattributes @@ -1,2 +1,3 @@ -*.sln -crlf -*.csproj -crlf \ No newline at end of file +*.cs text diff=csharp +*.sln text eol=crlf +*.csproj text eol=crlf diff --git a/NRefactory/.gitignore b/NRefactory/.gitignore index 0031dcbe2..813e7d15c 100644 --- a/NRefactory/.gitignore +++ b/NRefactory/.gitignore @@ -1,5 +1,6 @@ bin obj +*.suo /lib/*.dll /ICSharpCode.NRefactory.Tests/PartCover/* _ReSharper*/* diff --git a/NRefactory/ICSharpCode.NRefactory.CSharp.AstVerifier/AssemblyInfo.cs b/NRefactory/ICSharpCode.NRefactory.CSharp.AstVerifier/AssemblyInfo.cs deleted file mode 100644 index 7bd701bed..000000000 --- a/NRefactory/ICSharpCode.NRefactory.CSharp.AstVerifier/AssemblyInfo.cs +++ /dev/null @@ -1,27 +0,0 @@ -using System.Reflection; -using System.Runtime.CompilerServices; - -// Information about this assembly is defined by the following attributes. -// Change them to the values specific to your project. - -[assembly: AssemblyTitle("ICSharpCode.NRefactory.CSharp.AstVerifier")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("")] -[assembly: AssemblyCopyright("mike")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// The assembly version has the format "{Major}.{Minor}.{Build}.{Revision}". -// The form "{Major}.{Minor}.*" will automatically update the build and revision, -// and "{Major}.{Minor}.{Build}.*" will update just the revision. - -[assembly: AssemblyVersion("1.0.*")] - -// The following attributes are used to specify the signing key for the assembly, -// if desired. See the Mono documentation for more information about signing. - -//[assembly: AssemblyDelaySign(false)] -//[assembly: AssemblyKeyFile("")] - diff --git a/NRefactory/ICSharpCode.NRefactory.CSharp.AstVerifier/ICSharpCode.NRefactory.CSharp.AstVerifier.csproj b/NRefactory/ICSharpCode.NRefactory.CSharp.AstVerifier/ICSharpCode.NRefactory.CSharp.AstVerifier.csproj deleted file mode 100644 index 0647960a0..000000000 --- a/NRefactory/ICSharpCode.NRefactory.CSharp.AstVerifier/ICSharpCode.NRefactory.CSharp.AstVerifier.csproj +++ /dev/null @@ -1,69 +0,0 @@ - - - - Debug - AnyCPU - 10.0.0 - 2.0 - {961DADFA-7CE6-429F-BC22-47630D6DB826} - Exe - ICSharpCode.NRefactory.CSharp.AstVerifier - AstVerifier - - - true - full - false - bin\Debug - DEBUG; - prompt - 4 - true - - - none - false - bin\Release - prompt - 4 - true - - - true - full - false - bin\Debug - DEBUG; - prompt - 4 - true - v4.5 - - - none - false - bin\Release - prompt - 4 - true - v4.5 - - - - - - - - - - - - {53DCA265-3C3C-42F9-B647-F72BA678122B} - ICSharpCode.NRefactory.CSharp - - - {3B2A5653-EC97-4001-BB9B-D90F1AF2C371} - ICSharpCode.NRefactory - - - \ No newline at end of file diff --git a/NRefactory/ICSharpCode.NRefactory.CSharp.AstVerifier/Main.cs b/NRefactory/ICSharpCode.NRefactory.CSharp.AstVerifier/Main.cs deleted file mode 100644 index 54ac57b80..000000000 --- a/NRefactory/ICSharpCode.NRefactory.CSharp.AstVerifier/Main.cs +++ /dev/null @@ -1,83 +0,0 @@ -using System; -using System.IO; - -namespace ICSharpCode.NRefactory.CSharp.AstVerifier -{ - class MainClass - { - static bool IsMatch (string src1, string src2, out int i, out int j) - { - i = 0; - j = 0; - while (i < src1.Length && j < src2.Length) { - char c1 = src1 [i]; - char c2 = src2 [j]; - if (char.IsWhiteSpace (c1)) { - i++; - continue; - } - if (char.IsWhiteSpace (c2)) { - j++; - continue; - } - if (c1 != c2) - return false; - i++; - j++; - } - while (i < src1.Length && char.IsWhiteSpace (src1[i])) { - i++; - } - while (j < src2.Length && char.IsWhiteSpace (src2[j])) { - j++; - } - - return i == src1.Length && j == src2.Length; - } - - public static void Main (string[] args) - { - if (args.Length == 0) { - Console.WriteLine ("Usage: AstVerifier [-v|-verbose] [Directory]"); - return; - } - string directory = args[args.Length - 1]; - bool verboseOutput = args.Length > 1 && (args[0] == "-v" || args[0] == "-verbose"); - - try { - if (!Directory.Exists (directory)) { - Console.WriteLine ("Directory not found."); - return; - } - } catch (IOException) { - Console.WriteLine ("Exception while trying to access the directory."); - return; - } - int failed = 0, passed = 0; - Console.WriteLine ("search in " + directory); - foreach (var file in Directory.GetFileSystemEntries (directory, "*", SearchOption.AllDirectories)) { - if (!file.EndsWith (".cs")) - continue; - string text = File.ReadAllText (file); - var unit = SyntaxTree.Parse (text, file); - if (unit == null) - continue; - string generated = unit.GetText (); - int i, j; - if (!IsMatch (text, generated, out i, out j)) { - if (i > 0 && j > 0 && verboseOutput) { - Console.WriteLine ("fail :" + file + "----original:"); - Console.WriteLine (text.Substring (0, Math.Min (text.Length, i + 1))); - Console.WriteLine ("----generated:"); - Console.WriteLine (generated.Substring (0, Math.Min (generated.Length, j + 1))); - } - failed++; - } else { - passed++; - } - } - - Console.WriteLine ("{0} passed, {1} failed", passed, failed); - } - } -} diff --git a/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/Expressions/EmptyExpression.cs b/NRefactory/ICSharpCode.NRefactory.CSharp/Analysis/AnnotationNames.cs similarity index 50% rename from NRefactory/ICSharpCode.NRefactory.CSharp/Ast/Expressions/EmptyExpression.cs rename to NRefactory/ICSharpCode.NRefactory.CSharp/Analysis/AnnotationNames.cs index 7dc5da777..94d19e4b6 100644 --- a/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/Expressions/EmptyExpression.cs +++ b/NRefactory/ICSharpCode.NRefactory.CSharp/Analysis/AnnotationNames.cs @@ -1,10 +1,10 @@ -// -// EmptyExpression.cs +// +// Annotations.cs // // Author: -// Mike Krüger +// Luís Reis // -// Copyright (c) 2011 Novell, Inc (http://www.novell.com) +// Copyright (c) 2013 Luís Reis // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal @@ -23,57 +23,26 @@ // 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; namespace ICSharpCode.NRefactory.CSharp { - /// - /// Type<[EMPTY]> - /// - public class EmptyExpression : Expression + public static class AnnotationNames { - TextLocation location; + //Used const instead of readonly to allow values to be used in switch cases. - public override TextLocation StartLocation { - get { - return location; - } - } - - public override TextLocation EndLocation { - get { - return location; - } - } + public const string AssertionMethodAttribute = "JetBrains.Annotations.AssertionMethodAttribute"; + public const string AssertionConditionAttribute = "JetBrains.Annotations.AssertionConditionAttribute"; + public const string AssertionConditionTypeAttribute = "JetBrains.Annotations.AssertionConditionType"; - public EmptyExpression () - { - } + public const string AssertionConditionTypeIsTrue = "JetBrains.Annotations.AssertionConditionType.IS_TRUE"; + public const string AssertionConditionTypeIsFalse = "JetBrains.Annotations.AssertionConditionType.IS_FALSE"; + public const string AssertionConditionTypeIsNull = "JetBrains.Annotations.AssertionConditionType.IS_NULL"; + public const string AssertionConditionTypeIsNotNull = "JetBrains.Annotations.AssertionConditionType.IS_NOT_NULL"; - public EmptyExpression (TextLocation location) - { - this.location = location; - } - - public override void AcceptVisitor (IAstVisitor visitor) - { - visitor.VisitEmptyExpression (this); - } - - public override T AcceptVisitor (IAstVisitor visitor) - { - return visitor.VisitEmptyExpression (this); - } - - public override S AcceptVisitor (IAstVisitor visitor, T data) - { - return visitor.VisitEmptyExpression (this, data); - } - - protected internal override bool DoMatch (AstNode other, PatternMatching.Match match) - { - var o = other as EmptyExpression; - return o != null; - } + public const string NotNullAttribute = "JetBrains.Annotations.NotNullAttribute"; + public const string CanBeNullAttribute = "JetBrains.Annotations.CanBeNullAttribute"; } } + diff --git a/NRefactory/ICSharpCode.NRefactory.CSharp/Analysis/ControlFlow.cs b/NRefactory/ICSharpCode.NRefactory.CSharp/Analysis/ControlFlow.cs index 21b452696..2d3895b1e 100644 --- a/NRefactory/ICSharpCode.NRefactory.CSharp/Analysis/ControlFlow.cs +++ b/NRefactory/ICSharpCode.NRefactory.CSharp/Analysis/ControlFlow.cs @@ -1,4 +1,4 @@ -// Copyright (c) AlphaSierraPapa for the SharpDevelop Team +// Copyright (c) 2010-2013 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 @@ -26,6 +26,7 @@ using ICSharpCode.NRefactory.CSharp.TypeSystem; using ICSharpCode.NRefactory.Semantics; using ICSharpCode.NRefactory.TypeSystem; using ICSharpCode.NRefactory.TypeSystem.Implementation; +using ICSharpCode.NRefactory.Utils; namespace ICSharpCode.NRefactory.CSharp.Analysis { @@ -248,6 +249,8 @@ namespace ICSharpCode.NRefactory.CSharp.Analysis #region Create*Node ControlFlowNode CreateStartNode(Statement statement) { + if (statement.IsNull) + return null; ControlFlowNode node = CreateNode(null, statement, ControlFlowNodeType.StartNode); nodes.Add(node); return node; @@ -294,6 +297,8 @@ namespace ICSharpCode.NRefactory.CSharp.Analysis /// The constant value of the expression; or null if the expression is not a constant. ResolveResult EvaluateConstant(Expression expr) { + if (expr.IsNull) + return null; if (EvaluateOnlyPrimitiveConstants) { if (!(expr is PrimitiveExpression || expr is NullReferenceExpression)) return null; @@ -336,6 +341,8 @@ namespace ICSharpCode.NRefactory.CSharp.Analysis internal ControlFlowEdge Connect(ControlFlowNode from, ControlFlowNode to, ControlFlowEdgeType type = ControlFlowEdgeType.Normal) { + if (from == null || to == null) + return null; ControlFlowEdge edge = builder.CreateEdge(from, to, type); from.Outgoing.Add(edge); to.Incoming.Add(edge); @@ -354,8 +361,8 @@ namespace ICSharpCode.NRefactory.CSharp.Analysis protected override ControlFlowNode VisitChildren(AstNode node, ControlFlowNode data) { - // We have overrides for all possible expressions and should visit expressions only. - throw new NotImplementedException(); + // We have overrides for all possible statements and should visit statements only. + throw new NotSupportedException(); } public override ControlFlowNode VisitBlockStatement(BlockStatement blockStatement, ControlFlowNode data) @@ -406,22 +413,20 @@ namespace ICSharpCode.NRefactory.CSharp.Analysis public override ControlFlowNode VisitIfElseStatement(IfElseStatement ifElseStatement, ControlFlowNode data) { bool? cond = builder.EvaluateCondition(ifElseStatement.Condition); + ControlFlowNode trueBegin = builder.CreateStartNode(ifElseStatement.TrueStatement); if (cond != false) Connect(data, trueBegin, ControlFlowEdgeType.ConditionTrue); ControlFlowNode trueEnd = ifElseStatement.TrueStatement.AcceptVisitor(this, trueBegin); - ControlFlowNode falseEnd; - if (ifElseStatement.FalseStatement.IsNull) { - falseEnd = null; - } else { - ControlFlowNode falseBegin = builder.CreateStartNode(ifElseStatement.FalseStatement); - if (cond != true) - Connect(data, falseBegin, ControlFlowEdgeType.ConditionFalse); - falseEnd = ifElseStatement.FalseStatement.AcceptVisitor(this, falseBegin); - } + + ControlFlowNode falseBegin = builder.CreateStartNode(ifElseStatement.FalseStatement); + if (cond != true) + Connect(data, falseBegin, ControlFlowEdgeType.ConditionFalse); + ControlFlowNode falseEnd = ifElseStatement.FalseStatement.AcceptVisitor(this, falseBegin); + // (if no else statement exists, both falseBegin and falseEnd will be null) + ControlFlowNode end = builder.CreateEndNode(ifElseStatement); - if (trueEnd != null) - Connect(trueEnd, end); + Connect(trueEnd, end); if (falseEnd != null) { Connect(falseEnd, end); } else if (cond != true) { @@ -599,8 +604,7 @@ namespace ICSharpCode.NRefactory.CSharp.Analysis ControlFlowNode bodyStart = builder.CreateStartNode(forStatement.EmbeddedStatement); ControlFlowNode bodyEnd = forStatement.EmbeddedStatement.AcceptVisitor(this, bodyStart); - if (bodyEnd != null) - Connect(bodyEnd, iteratorStart); + Connect(bodyEnd, iteratorStart); breakTargets.Pop(); continueTargets.Pop(); @@ -743,5 +747,57 @@ namespace ICSharpCode.NRefactory.CSharp.Analysis return CreateConnectedEndNode(fixedStatement, bodyEnd); } } + + /// + /// Debugging helper that exports a control flow graph. + /// + public static GraphVizGraph ExportGraph(IList nodes) + { + GraphVizGraph g = new GraphVizGraph(); + GraphVizNode[] n = new GraphVizNode[nodes.Count]; + Dictionary dict = new Dictionary(); + for (int i = 0; i < n.Length; i++) { + dict.Add(nodes[i], i); + n[i] = new GraphVizNode(i); + string name = "#" + i + " = "; + switch (nodes[i].Type) { + case ControlFlowNodeType.StartNode: + case ControlFlowNodeType.BetweenStatements: + name += nodes[i].NextStatement.DebugToString(); + break; + case ControlFlowNodeType.EndNode: + name += "End of " + nodes[i].PreviousStatement.DebugToString(); + break; + case ControlFlowNodeType.LoopCondition: + name += "Condition in " + nodes[i].NextStatement.DebugToString(); + break; + default: + name += "?"; + break; + } + n[i].label = name; + g.AddNode(n[i]); + } + for (int i = 0; i < n.Length; i++) { + foreach (ControlFlowEdge edge in nodes[i].Outgoing) { + GraphVizEdge ge = new GraphVizEdge(i, dict[edge.To]); + if (edge.IsLeavingTryFinally) + ge.style = "dashed"; + switch (edge.Type) { + case ControlFlowEdgeType.ConditionTrue: + ge.color = "green"; + break; + case ControlFlowEdgeType.ConditionFalse: + ge.color = "red"; + break; + case ControlFlowEdgeType.Jump: + ge.color = "blue"; + break; + } + g.AddEdge(ge); + } + } + return g; + } } } diff --git a/NRefactory/ICSharpCode.NRefactory.CSharp/Analysis/DeclarationSpace/LocalDeclarationSpace.cs b/NRefactory/ICSharpCode.NRefactory.CSharp/Analysis/DeclarationSpace/LocalDeclarationSpace.cs new file mode 100644 index 000000000..a412cba3a --- /dev/null +++ b/NRefactory/ICSharpCode.NRefactory.CSharp/Analysis/DeclarationSpace/LocalDeclarationSpace.cs @@ -0,0 +1,157 @@ +// +// LovalVariableDeclarationSpace.cs +// +// Author: +// Simon Lindgren +// +// Copyright (c) 2013 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.Utils; +using System.Collections.Generic; +using System.Linq; +using System; + +namespace ICSharpCode.NRefactory.CSharp.Analysis +{ + /// + /// Represents a declaration space. (§3.3) + /// + public class LocalDeclarationSpace + { + /// + /// Maps from variable name to the declarations in this declaration space. + /// + /// + /// This maps from variable name + /// + MultiDictionary declarations = new MultiDictionary (); + + public LocalDeclarationSpace() + { + Children = new List (); + } + + /// + /// The child declaration spaces. + /// + public IList Children { + get; + private set; + } + + /// + /// The parent declaration space. + /// + /// The parent. + public LocalDeclarationSpace Parent { + get; + private set; + } + + /// + /// The names declared in this declaration space, excluding child spaces. + /// + /// The declared names. + public ICollection DeclaredNames { + get { + return declarations.Keys; + } + } + + /// + /// Get all nodes declaring the name specified in . + /// + /// The declaring nodes. + /// The declaration name. + public IEnumerable GetNameDeclarations(string name) + { + return declarations [name].Concat(Children.SelectMany(child => child.GetNameDeclarations(name))); + } + + /// + /// Adds a child declaration space. + /// + /// The to add. + public void AddChildSpace(LocalDeclarationSpace child) + { + if (child == null) + throw new ArgumentNullException("child"); + if (Children.Contains(child)) + throw new InvalidOperationException("the child was already added"); + + Children.Add(child); + child.Parent = this; + } + + /// + /// Adds a new declaration to the declaration space. + /// + /// The name of the declared variable. + /// A node associated with the declaration. + public void AddDeclaration(string name, AstNode node) + { + if (name == null) + throw new ArgumentNullException("name"); + if (node == null) + throw new ArgumentNullException("node"); + declarations.Add(name, node); + } + + /// + /// Determines if the name exists in the this declaration space. + /// + /// true, if the name specified in is used in this variable declaration space, false otherwise. + /// The name to look for. + /// When true, child declaration spaces are included in the search. + public bool ContainsName(string name, bool includeChildren) + { + if (name == null) + throw new ArgumentNullException("name"); + + if (declarations.Keys.Contains(name)) + return true; + return includeChildren && Children.Any(child => child.ContainsName(name, true)); + } + + /// + /// Determines whether the name specified in is used in surrouding code. + /// + /// true if the name is used, false otherwise. + /// The name to check. + /// + /// Contrary to , this method also checks parent declaration spaces + /// for name conflicts. Typically, this will be the right method to use when determining if a name can be used. + /// + public bool IsNameUsed(string name) + { + if (name == null) + throw new ArgumentNullException("name"); + + return IsNameUsedBySelfOrParent(name) || Children.Any(child => child.ContainsName(name, true)); + } + + bool IsNameUsedBySelfOrParent(string name) + { + if (declarations.Keys.Contains(name)) + return true; + return Parent != null && Parent.IsNameUsedBySelfOrParent(name); + } + } +} \ No newline at end of file diff --git a/NRefactory/ICSharpCode.NRefactory.CSharp/Analysis/DeclarationSpace/LocalDeclarationSpaceVisitor.cs b/NRefactory/ICSharpCode.NRefactory.CSharp/Analysis/DeclarationSpace/LocalDeclarationSpaceVisitor.cs new file mode 100644 index 000000000..08389a413 --- /dev/null +++ b/NRefactory/ICSharpCode.NRefactory.CSharp/Analysis/DeclarationSpace/LocalDeclarationSpaceVisitor.cs @@ -0,0 +1,138 @@ +// +// LocalDeclarationSpaceVisitor.cs +// +// Author: +// Simon Lindgren +// +// Copyright (c) 2013 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 System; +using System.Collections.Generic; + +namespace ICSharpCode.NRefactory.CSharp.Analysis +{ + public class LocalDeclarationSpaceVisitor : DepthFirstAstVisitor + { + LocalDeclarationSpace currentDeclarationSpace; + Dictionary nodeDeclarationSpaces = new Dictionary(); + + public LocalDeclarationSpace GetDeclarationSpace(AstNode node) + { + if (node == null) + throw new ArgumentNullException("node"); + while (node != null) { + LocalDeclarationSpace declarationSpace; + if (nodeDeclarationSpaces.TryGetValue(node, out declarationSpace)) + return declarationSpace; + node = node.Parent; + } + return null; + } + + #region Visitor + + void AddDeclaration(string name, AstNode node) + { + if (currentDeclarationSpace != null) + currentDeclarationSpace.AddDeclaration(name, node); + } + + public override void VisitVariableInitializer(VariableInitializer variableInitializer) + { + AddDeclaration(variableInitializer.Name, variableInitializer); + base.VisitVariableInitializer(variableInitializer); + } + + public override void VisitParameterDeclaration(ParameterDeclaration parameterDeclaration) + { + AddDeclaration(parameterDeclaration.Name, parameterDeclaration); + base.VisitParameterDeclaration(parameterDeclaration); + } + + void VisitNewDeclarationSpace(AstNode node) + { + var oldDeclarationSpace = currentDeclarationSpace; + currentDeclarationSpace = new LocalDeclarationSpace(); + if (oldDeclarationSpace != null) + oldDeclarationSpace.AddChildSpace(currentDeclarationSpace); + + VisitChildren(node); + + nodeDeclarationSpaces.Add(node, currentDeclarationSpace); + currentDeclarationSpace = oldDeclarationSpace; + } + + #region Declaration space creating nodes + + public override void VisitMethodDeclaration(MethodDeclaration methodDeclaration) + { + VisitNewDeclarationSpace(methodDeclaration); + } + + public override void VisitBlockStatement(BlockStatement blockStatement) + { + VisitNewDeclarationSpace(blockStatement); + } + + public override void VisitSwitchStatement(SwitchStatement switchStatement) + { + VisitNewDeclarationSpace(switchStatement); + } + + public override void VisitForeachStatement(ForeachStatement foreachStatement) + { + AddDeclaration(foreachStatement.VariableName, foreachStatement); + VisitNewDeclarationSpace(foreachStatement); + } + + public override void VisitForStatement(ForStatement forStatement) + { + VisitNewDeclarationSpace(forStatement); + } + + public override void VisitUsingStatement(UsingStatement usingStatement) + { + VisitNewDeclarationSpace(usingStatement); + } + + public override void VisitLambdaExpression(LambdaExpression lambdaExpression) + { + VisitNewDeclarationSpace(lambdaExpression); + } + + public override void VisitAnonymousMethodExpression(AnonymousMethodExpression anonymousMethodExpression) + { + VisitNewDeclarationSpace(anonymousMethodExpression); + } + + public override void VisitEventDeclaration(EventDeclaration eventDeclaration) + { + AddDeclaration(eventDeclaration.Name, eventDeclaration); + } + + public override void VisitCustomEventDeclaration(CustomEventDeclaration eventDeclaration) + { + VisitNewDeclarationSpace(eventDeclaration); + } + + #endregion + #endregion + } +} diff --git a/NRefactory/ICSharpCode.NRefactory.CSharp/Analysis/DefiniteAssignmentAnalysis.cs b/NRefactory/ICSharpCode.NRefactory.CSharp/Analysis/DefiniteAssignmentAnalysis.cs index 0e2ad2b89..9b33e74a7 100644 --- a/NRefactory/ICSharpCode.NRefactory.CSharp/Analysis/DefiniteAssignmentAnalysis.cs +++ b/NRefactory/ICSharpCode.NRefactory.CSharp/Analysis/DefiniteAssignmentAnalysis.cs @@ -1,4 +1,4 @@ -// Copyright (c) AlphaSierraPapa for the SharpDevelop Team +// Copyright (c) 2010-2013 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 diff --git a/NRefactory/ICSharpCode.NRefactory.CSharp/Analysis/NullValueAnalysis.cs b/NRefactory/ICSharpCode.NRefactory.CSharp/Analysis/NullValueAnalysis.cs new file mode 100644 index 000000000..a20b4a0f0 --- /dev/null +++ b/NRefactory/ICSharpCode.NRefactory.CSharp/Analysis/NullValueAnalysis.cs @@ -0,0 +1,2215 @@ +// +// NullValueAnalysis.cs +// +// Author: +// Luís Reis +// +// Copyright (c) 2013 Luís Reis +// +// 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; +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; +using System.Threading; +using System.Text; +using ICSharpCode.NRefactory.CSharp.Resolver; +using ICSharpCode.NRefactory.Semantics; +using ICSharpCode.NRefactory.TypeSystem; +using ICSharpCode.NRefactory.CSharp.Refactoring; +using ICSharpCode.NRefactory.PatternMatching; +using ICSharpCode.NRefactory.CSharp; +using ICSharpCode.NRefactory.Utils; + +namespace ICSharpCode.NRefactory.CSharp.Analysis +{ + public class NullValueAnalysis + { + sealed class VariableStatusInfo : IEquatable, IEnumerable> + { + readonly Dictionary VariableStatus = new Dictionary(); + + public NullValueStatus this[string name] + { + get { + NullValueStatus status; + if (VariableStatus.TryGetValue(name, out status)) { + return status; + } + return NullValueStatus.UnreachableOrInexistent; + } + set { + if (value == NullValueStatus.UnreachableOrInexistent) { + VariableStatus.Remove(name); + } else { + VariableStatus [name] = value; + } + } + } + + /// + /// Modifies the variable state to consider a new incoming path + /// + /// true, if the state has changed, false otherwise. + /// The variable state of the incoming path + public bool ReceiveIncoming(VariableStatusInfo incomingState) + { + bool changed = false; + var listOfVariables = VariableStatus.Keys.Concat(incomingState.VariableStatus.Keys).ToList(); + foreach (string variable in listOfVariables) + { + var newValue = CombineStatus(this [variable], incomingState [variable]); + if (this [variable] != newValue) { + this [variable] = newValue; + changed = true; + } + } + + return changed; + } + + public static NullValueStatus CombineStatus(NullValueStatus oldValue, NullValueStatus incomingValue) + { + if (oldValue == NullValueStatus.Error || incomingValue == NullValueStatus.Error) + return NullValueStatus.Error; + + if (oldValue == NullValueStatus.UnreachableOrInexistent || + oldValue == NullValueStatus.Unassigned) + return incomingValue; + + if (incomingValue == NullValueStatus.Unassigned) { + return NullValueStatus.Unassigned; + } + + if (oldValue == NullValueStatus.CapturedUnknown || incomingValue == NullValueStatus.CapturedUnknown) { + //TODO: Check if this is right + return NullValueStatus.CapturedUnknown; + } + + if (oldValue == NullValueStatus.Unknown) { + return NullValueStatus.Unknown; + } + + if (oldValue == NullValueStatus.DefinitelyNull) { + return incomingValue == NullValueStatus.DefinitelyNull ? + NullValueStatus.DefinitelyNull : NullValueStatus.PotentiallyNull; + } + + if (oldValue == NullValueStatus.DefinitelyNotNull) { + if (incomingValue == NullValueStatus.Unknown) + return NullValueStatus.Unknown; + if (incomingValue == NullValueStatus.DefinitelyNotNull) + return NullValueStatus.DefinitelyNotNull; + return NullValueStatus.PotentiallyNull; + } + + Debug.Assert(oldValue == NullValueStatus.PotentiallyNull); + return NullValueStatus.PotentiallyNull; + } + + public bool HasVariable(string variable) { + return VariableStatus.ContainsKey(variable); + } + + public VariableStatusInfo Clone() { + var clone = new VariableStatusInfo(); + foreach (var item in VariableStatus) { + clone.VariableStatus.Add(item.Key, item.Value); + } + return clone; + } + + public override bool Equals(object obj) + { + return Equals(obj as VariableStatusInfo); + } + + public bool Equals(VariableStatusInfo obj) + { + if (obj == null) { + return false; + } + + if (VariableStatus.Count != obj.VariableStatus.Count) + return false; + + return VariableStatus.All(item => item.Value == obj[item.Key]); + } + + public override int GetHashCode() + { + //STUB + return VariableStatus.Count.GetHashCode(); + } + + public static bool operator ==(VariableStatusInfo obj1, VariableStatusInfo obj2) { + return object.ReferenceEquals(obj1, null) ? + object.ReferenceEquals(obj2, null) : obj1.Equals(obj2); + } + + public static bool operator !=(VariableStatusInfo obj1, VariableStatusInfo obj2) { + return !(obj1 == obj2); + } + + public IEnumerator> GetEnumerator() + { + return VariableStatus.GetEnumerator(); + } + + IEnumerator IEnumerable.GetEnumerator() + { + return GetEnumerator(); + } + + public override string ToString() + { + var builder = new StringBuilder("["); + foreach (var item in this) { + builder.Append(item.Key); + builder.Append("="); + builder.Append(item.Value); + } + builder.Append("]"); + return builder.ToString(); + } + } + + sealed class NullAnalysisNode : ControlFlowNode + { + public readonly VariableStatusInfo VariableState = new VariableStatusInfo(); + public bool Visited { get; private set; } + + public NullAnalysisNode(Statement previousStatement, Statement nextStatement, ControlFlowNodeType type) + : base(previousStatement, nextStatement, type) + { + } + + public bool ReceiveIncoming(VariableStatusInfo incomingState) + { + bool changed = VariableState.ReceiveIncoming(incomingState); + if (!Visited) { + Visited = true; + return true; + } + return changed; + } + } + + sealed class NullAnalysisGraphBuilder : ControlFlowGraphBuilder + { + protected override ControlFlowNode CreateNode(Statement previousStatement, Statement nextStatement, ControlFlowNodeType type) + { + return new NullAnalysisNode(previousStatement, nextStatement, type); + } + } + + class PendingNode : IEquatable { + internal readonly NullAnalysisNode nodeToVisit; + internal readonly VariableStatusInfo statusInfo; + internal readonly ComparableList pendingTryFinallyNodes; + internal readonly NullAnalysisNode nodeAfterFinally; + + internal PendingNode(NullAnalysisNode nodeToVisit, VariableStatusInfo statusInfo) + : this(nodeToVisit, statusInfo, new ComparableList(), null) + { + } + + public PendingNode(NullAnalysisNode nodeToVisit, VariableStatusInfo statusInfo, ComparableList pendingFinallyNodes, NullAnalysisNode nodeAfterFinally) + { + this.nodeToVisit = nodeToVisit; + this.statusInfo = statusInfo; + this.pendingTryFinallyNodes = pendingFinallyNodes; + this.nodeAfterFinally = nodeAfterFinally; + } + + public override bool Equals(object obj) + { + return Equals(obj as PendingNode); + } + + public bool Equals(PendingNode obj) { + if (obj == null) return false; + + if (nodeToVisit != obj.nodeToVisit) return false; + if (statusInfo != obj.statusInfo) return false; + if (pendingTryFinallyNodes != obj.pendingTryFinallyNodes) return false; + if (nodeAfterFinally != obj.nodeAfterFinally) return false; + + return true; + } + + public override int GetHashCode() + { + return nodeToVisit.GetHashCode() ^ + statusInfo.GetHashCode() ^ + pendingTryFinallyNodes.GetHashCode() ^ + (nodeAfterFinally == null ? 0 : nodeAfterFinally.GetHashCode()); + } + } + + readonly BaseRefactoringContext context; + readonly NullAnalysisVisitor visitor; + List allNodes; + readonly HashSet nodesToVisit = new HashSet(); + Dictionary nodeBeforeStatementDict; + Dictionary nodeAfterStatementDict; + readonly Dictionary expressionResult = new Dictionary(); + + public NullValueAnalysis(BaseRefactoringContext context, MethodDeclaration methodDeclaration, CancellationToken cancellationToken) + : this(context, methodDeclaration.Body, methodDeclaration.Parameters, cancellationToken) + { + } + + readonly IEnumerable parameters; + readonly Statement rootStatement; + + readonly CancellationToken cancellationToken; + + public NullValueAnalysis(BaseRefactoringContext context, Statement rootStatement, IEnumerable parameters, CancellationToken cancellationToken) + { + if (rootStatement == null) + throw new ArgumentNullException("rootStatement"); + if (context == null) + throw new ArgumentNullException("context"); + + this.context = context; + this.rootStatement = rootStatement; + this.parameters = parameters; + this.visitor = new NullAnalysisVisitor(this); + this.cancellationToken = cancellationToken; + } + + /// + /// Sets the local variable value. + /// This method does not change anything if identifier does not refer to a local variable. + /// Do not use this in variable declarations since resolving the variable won't work yet. + /// + /// true, if local variable value was set, false otherwise. + /// The variable status data to change. + /// The identifier to set. + /// The name of the identifier to set. + /// The value to set the identifier. + bool SetLocalVariableValue (VariableStatusInfo data, AstNode identifierNode, string identifierName, NullValueStatus value) { + var resolveResult = context.Resolve(identifierNode); + if (resolveResult is LocalResolveResult) { + if (data [identifierName] != NullValueStatus.CapturedUnknown) { + data [identifierName] = value; + + return true; + } + } + return false; + } + + bool SetLocalVariableValue (VariableStatusInfo data, IdentifierExpression identifierExpression, NullValueStatus value) { + return SetLocalVariableValue(data, identifierExpression, identifierExpression.Identifier, value); + } + + bool SetLocalVariableValue (VariableStatusInfo data, Identifier identifier, NullValueStatus value) { + return SetLocalVariableValue(data, identifier, identifier.Name, value); + } + + void SetupNode(NullAnalysisNode node) + { + foreach (var parameter in parameters) { + var resolveResult = context.Resolve(parameter.Type); + node.VariableState[parameter.Name] = GetInitialVariableStatus(resolveResult); + } + + nodesToVisit.Add(new PendingNode(node, node.VariableState)); + } + + static bool IsTypeNullable(IType type) + { + return type.IsReferenceType == true || type.FullName == "System.Nullable"; + } + + public bool IsParametersAreUninitialized { + get; + set; + } + + NullValueStatus GetInitialVariableStatus(ResolveResult resolveResult) + { + var typeResolveResult = resolveResult as TypeResolveResult; + if (typeResolveResult == null) { + return NullValueStatus.Error; + } + var type = typeResolveResult.Type; + if (type.IsReferenceType == null) { + return NullValueStatus.Error; + } + if (!IsParametersAreUninitialized) + return NullValueStatus.DefinitelyNotNull; + return IsTypeNullable(type) ? NullValueStatus.PotentiallyNull : NullValueStatus.DefinitelyNotNull; + } + + public void Analyze() + { + var cfgBuilder = new NullAnalysisGraphBuilder(); + allNodes = cfgBuilder.BuildControlFlowGraph(rootStatement, cancellationToken).Cast().ToList(); + nodeBeforeStatementDict = allNodes.Where(node => node.Type == ControlFlowNodeType.StartNode || node.Type == ControlFlowNodeType.BetweenStatements) + .ToDictionary(node => node.NextStatement); + nodeAfterStatementDict = allNodes.Where(node => node.Type == ControlFlowNodeType.BetweenStatements || node.Type == ControlFlowNodeType.EndNode) + .ToDictionary(node => node.PreviousStatement); + + foreach (var node in allNodes) { + if (node.Type == ControlFlowNodeType.StartNode && node.NextStatement == rootStatement) { + Debug.Assert(!nodesToVisit.Any()); + + SetupNode(node); + } + } + + while (nodesToVisit.Any()) { + var nodeToVisit = nodesToVisit.First(); + nodesToVisit.Remove(nodeToVisit); + + Visit(nodeToVisit); + } + } + + int visits = 0; + + public int NodeVisits + { + get { + return visits; + } + } + + void Visit(PendingNode nodeInfo) + { + cancellationToken.ThrowIfCancellationRequested(); + + var node = nodeInfo.nodeToVisit; + var statusInfo = nodeInfo.statusInfo; + + visits++; + if (visits > 100) { + //Visiting way too often, let's enter fast mode + //Fast mode is slighly less accurate but visits each node less times + nodesToVisit.RemoveWhere(candidate => candidate.nodeToVisit == nodeInfo.nodeToVisit && + candidate.pendingTryFinallyNodes.Equals(nodeInfo.pendingTryFinallyNodes) && + candidate.nodeAfterFinally == nodeInfo.nodeAfterFinally); + statusInfo = node.VariableState; + } + + var nextStatement = node.NextStatement; + VariableStatusInfo outgoingStatusInfo = statusInfo; + VisitorResult result = null; + + if (nextStatement != null && (!(nextStatement is DoWhileStatement) || node.Type == ControlFlowNodeType.LoopCondition)) { + result = nextStatement.AcceptVisitor(visitor, statusInfo); + if (result == null) { + Console.WriteLine("Failure in {0}", nextStatement); + throw new InvalidOperationException(); + } + + outgoingStatusInfo = result.Variables; + } + + if ((result == null || !result.ThrowsException) && node.Outgoing.Any()) { + var tryFinallyStatement = nextStatement as TryCatchStatement; + + foreach (var outgoingEdge in node.Outgoing) { + VariableStatusInfo edgeInfo; + edgeInfo = outgoingStatusInfo.Clone(); + + if (node.Type == ControlFlowNodeType.EndNode) { + var previousBlock = node.PreviousStatement as BlockStatement; + if (previousBlock != null) { + //We're leaving a block statement. + //As such, we'll remove the variables that were declared *in* the loop + //This helps GetVariableStatusAfter/BeforeStatement be more accurate + //and prevents some redundant revisiting. + + foreach (var variableInitializer in previousBlock.Statements + .OfType() + .SelectMany(declaration => declaration.Variables)) { + + edgeInfo [variableInitializer.Name] = NullValueStatus.UnreachableOrInexistent; + } + } + } + + if (tryFinallyStatement != null) { + //With the exception of try statements, this needs special handling: + //we'll set all changed variables to Unknown or CapturedUnknown + if (outgoingEdge.To.NextStatement == tryFinallyStatement.FinallyBlock) { + foreach (var identifierExpression in tryFinallyStatement.TryBlock.Descendants.OfType()) { + //TODO: Investigate CaptureUnknown + SetLocalVariableValue(edgeInfo, identifierExpression, NullValueStatus.Unknown); + } + } else { + var clause = tryFinallyStatement.CatchClauses + .FirstOrDefault(candidateClause => candidateClause.Body == outgoingEdge.To.NextStatement); + + if (clause != null) { + SetLocalVariableValue(edgeInfo, clause.VariableNameToken, NullValueStatus.DefinitelyNotNull); + + foreach (var identifierExpression in tryFinallyStatement.TryBlock.Descendants.OfType()) { + //TODO: Investigate CaptureUnknown + SetLocalVariableValue(edgeInfo, identifierExpression, NullValueStatus.Unknown); + } + } + } + } + + if (result != null) { + switch (outgoingEdge.Type) { + case ControlFlowEdgeType.ConditionTrue: + if (result.KnownBoolResult == false) { + //No need to explore this path -- expression is known to be false + continue; + } + edgeInfo = result.TruePathVariables; + break; + case ControlFlowEdgeType.ConditionFalse: + if (result.KnownBoolResult == true) { + //No need to explore this path -- expression is known to be true + continue; + } + edgeInfo = result.FalsePathVariables; + break; + } + } + + if (outgoingEdge.IsLeavingTryFinally) { + var nodeAfterFinally = (NullAnalysisNode)outgoingEdge.To; + var finallyNodes = outgoingEdge.TryFinallyStatements.Select(tryFinally => nodeBeforeStatementDict [tryFinally.FinallyBlock]).ToList(); + var nextNode = finallyNodes.First(); + var remainingFinallyNodes = new ComparableList(finallyNodes.Skip(1)); + //We have to visit the node even if ReceiveIncoming returns false + //since the finallyNodes/nodeAfterFinally might be different even if the values of variables are the same -- and they need to be visited either way! + //TODO 1: Is there any point in visiting the finally statement here? + //TODO 2: Do we need the ReceiveIncoming at all? + nextNode.ReceiveIncoming(edgeInfo); + nodesToVisit.Add(new PendingNode(nextNode, edgeInfo, remainingFinallyNodes, nodeAfterFinally)); + } else { + var outgoingNode = (NullAnalysisNode)outgoingEdge.To; + if (outgoingNode.ReceiveIncoming(edgeInfo)) { + nodesToVisit.Add(new PendingNode(outgoingNode, edgeInfo)); + } + } + } + } else { + //We found a return/throw/yield break or some other termination node + var finallyBlockStarts = nodeInfo.pendingTryFinallyNodes; + var nodeAfterFinally = nodeInfo.nodeAfterFinally; + + if (finallyBlockStarts.Any()) { + var nextNode = finallyBlockStarts.First(); + if (nextNode.ReceiveIncoming(outgoingStatusInfo)) + nodesToVisit.Add(new PendingNode(nextNode, outgoingStatusInfo, new ComparableList(finallyBlockStarts.Skip(1)), nodeInfo.nodeAfterFinally)); + } else if (nodeAfterFinally != null && nodeAfterFinally.ReceiveIncoming(outgoingStatusInfo)) { + nodesToVisit.Add(new PendingNode(nodeAfterFinally, outgoingStatusInfo)); + } else { + //Maybe we finished a try/catch/finally statement the "normal" way (no direct jumps) + //so let's check that case + var statement = node.PreviousStatement ?? node.NextStatement; + Debug.Assert(statement != null); + var parent = statement.GetParent(); + var parentTryCatch = parent as TryCatchStatement; + if (parentTryCatch != null) { + var nextNode = nodeAfterStatementDict [parentTryCatch]; + if (nextNode.ReceiveIncoming(outgoingStatusInfo)) { + nodesToVisit.Add(new PendingNode(nextNode, outgoingStatusInfo)); + } + } + } + } + } + + public NullValueStatus GetExpressionResult(Expression expr) + { + if (expr == null) + throw new ArgumentNullException("expr"); + + NullValueStatus info; + if (expressionResult.TryGetValue(expr, out info)) { + return info; + } + + return NullValueStatus.UnreachableOrInexistent; + } + + public NullValueStatus GetVariableStatusBeforeStatement(Statement stmt, string variableName) + { + if (stmt == null) + throw new ArgumentNullException("stmt"); + if (variableName == null) + throw new ArgumentNullException("variableName"); + + NullAnalysisNode node; + if (nodeBeforeStatementDict.TryGetValue(stmt, out node)) { + return node.VariableState [variableName]; + } + + return NullValueStatus.UnreachableOrInexistent; + } + + public NullValueStatus GetVariableStatusAfterStatement(Statement stmt, string variableName) + { + if (stmt == null) + throw new ArgumentNullException("stmt"); + if (variableName == null) + throw new ArgumentNullException("variableName"); + + NullAnalysisNode node; + if (nodeAfterStatementDict.TryGetValue(stmt, out node)) { + return node.VariableState [variableName]; + } + + return NullValueStatus.UnreachableOrInexistent; + } + + class ConditionalBranchInfo + { + /// + /// True if the variable is null for the true path, false if it is false for the true path. + /// + public Dictionary TrueResultVariableNullStates = new Dictionary(); + /// + /// True if the variable is null for the false path, false if it is false for the false path. + /// + public Dictionary FalseResultVariableNullStates = new Dictionary(); + } + + class VisitorResult + { + /// + /// Indicates the return value of the expression. + /// + /// + /// Only applicable for expressions. + /// + public NullValueStatus NullableReturnResult; + + /// + /// Indicates the value of each item in an array or linq query. + /// + public NullValueStatus EnumeratedValueResult; + + /// + /// Information that indicates the restrictions to add + /// when branching. + /// + /// + /// Used in if/else statements, conditional expressions and + /// while statements. + /// + public ConditionalBranchInfo ConditionalBranchInfo; + + /// + /// The state of the variables after the expression is executed. + /// + public VariableStatusInfo Variables; + + /// + /// The expression is known to be invalid and trigger an error + /// (e.g. a NullReferenceException) + /// + public bool ThrowsException; + + /// + /// The known bool result of an expression. + /// + public bool? KnownBoolResult; + + public static VisitorResult ForEnumeratedValue(VariableStatusInfo variables, NullValueStatus itemValues) + { + var result = new VisitorResult(); + result.NullableReturnResult = NullValueStatus.DefinitelyNotNull; + result.EnumeratedValueResult = itemValues; + result.Variables = variables.Clone(); + return result; + } + + public static VisitorResult ForValue(VariableStatusInfo variables, NullValueStatus returnValue) + { + var result = new VisitorResult(); + result.NullableReturnResult = returnValue; + result.Variables = variables.Clone(); + return result; + } + + public static VisitorResult ForBoolValue(VariableStatusInfo variables, bool newValue) + { + var result = new VisitorResult(); + result.NullableReturnResult = NullValueStatus.DefinitelyNotNull; //Bool expressions are never null + result.KnownBoolResult = newValue; + result.Variables = variables.Clone(); + return result; + } + + public static VisitorResult ForException(VariableStatusInfo variables) { + var result = new VisitorResult(); + result.NullableReturnResult = NullValueStatus.UnreachableOrInexistent; + result.ThrowsException = true; + result.Variables = variables.Clone(); + return result; + } + + public VisitorResult Negated { + get { + var result = new VisitorResult(); + if (NullableReturnResult.IsDefiniteValue()) { + result.NullableReturnResult = NullableReturnResult == NullValueStatus.DefinitelyNull + ? NullValueStatus.DefinitelyNotNull : NullValueStatus.DefinitelyNull; + } else { + result.NullableReturnResult = NullableReturnResult; + } + result.Variables = Variables.Clone(); + result.KnownBoolResult = !KnownBoolResult; + if (ConditionalBranchInfo != null) { + result.ConditionalBranchInfo = new ConditionalBranchInfo(); + foreach (var item in ConditionalBranchInfo.TrueResultVariableNullStates) { + result.ConditionalBranchInfo.FalseResultVariableNullStates [item.Key] = item.Value; + } + foreach (var item in ConditionalBranchInfo.FalseResultVariableNullStates) { + result.ConditionalBranchInfo.TrueResultVariableNullStates [item.Key] = item.Value; + } + } + return result; + } + } + + public VariableStatusInfo TruePathVariables { + get { + var variables = Variables.Clone(); + if (ConditionalBranchInfo != null) { + foreach (var item in ConditionalBranchInfo.TrueResultVariableNullStates) { + variables [item.Key] = item.Value ? NullValueStatus.DefinitelyNull : NullValueStatus.DefinitelyNotNull; + } + } + return variables; + } + } + + public VariableStatusInfo FalsePathVariables { + get { + var variables = Variables.Clone(); + if (ConditionalBranchInfo != null) { + foreach (var item in ConditionalBranchInfo.FalseResultVariableNullStates) { + variables [item.Key] = item.Value ? NullValueStatus.DefinitelyNull : NullValueStatus.DefinitelyNotNull; + } + } + return variables; + } + } + + public static VisitorResult AndOperation(VisitorResult tentativeLeftResult, VisitorResult tentativeRightResult) + { + var result = new VisitorResult(); + result.KnownBoolResult = tentativeLeftResult.KnownBoolResult & tentativeRightResult.KnownBoolResult; + + var trueTruePath = tentativeRightResult.TruePathVariables; + var trueFalsePath = tentativeRightResult.FalsePathVariables; + var falsePath = tentativeLeftResult.FalsePathVariables; + + var trueVariables = trueTruePath; + + var falseVariables = trueFalsePath.Clone(); + falseVariables.ReceiveIncoming(falsePath); + result.Variables = trueVariables.Clone(); + result.Variables.ReceiveIncoming(falseVariables); + + result.ConditionalBranchInfo = new ConditionalBranchInfo(); + + foreach (var variable in trueVariables) { + if (!variable.Value.IsDefiniteValue()) + continue; + + string variableName = variable.Key; + + if (variable.Value != result.Variables[variableName]) { + bool isNull = variable.Value == NullValueStatus.DefinitelyNull; + result.ConditionalBranchInfo.TrueResultVariableNullStates.Add(variableName, isNull); + } + } + + foreach (var variable in falseVariables) { + if (!variable.Value.IsDefiniteValue()) + continue; + + string variableName = variable.Key; + + if (variable.Value != result.Variables [variableName]) { + bool isNull = variable.Value == NullValueStatus.DefinitelyNull; + result.ConditionalBranchInfo.FalseResultVariableNullStates.Add(variableName, isNull); + } + } + + return result; + } + + public static VisitorResult OrOperation(VisitorResult tentativeLeftResult, VisitorResult tentativeRightResult) + { + return VisitorResult.AndOperation(tentativeLeftResult.Negated, tentativeRightResult.Negated).Negated; + } + } + + class NullAnalysisVisitor : DepthFirstAstVisitor + { + NullValueAnalysis analysis; + + public NullAnalysisVisitor(NullValueAnalysis analysis) { + this.analysis = analysis; + } + + protected override VisitorResult VisitChildren(AstNode node, VariableStatusInfo data) + { + Debug.Fail("Missing override for " + node.GetType().Name); + return VisitorResult.ForValue(data, NullValueStatus.Unknown); + } + + public override VisitorResult VisitNullNode(AstNode nullNode, VariableStatusInfo data) + { + // can occur due to syntax errors + return VisitorResult.ForValue(data, NullValueStatus.Unknown); + } + + public override VisitorResult VisitEmptyStatement(EmptyStatement emptyStatement, VariableStatusInfo data) + { + return VisitorResult.ForValue(data, NullValueStatus.Unknown); + } + + public override VisitorResult VisitBlockStatement(BlockStatement blockStatement, VariableStatusInfo data) + { + //We'll visit the child statements later (we'll visit each one directly from the CFG) + //As such this is mostly a dummy node. + return new VisitorResult { Variables = data }; + } + + public override VisitorResult VisitVariableDeclarationStatement(VariableDeclarationStatement variableDeclarationStatement, VariableStatusInfo data) + { + foreach (var variable in variableDeclarationStatement.Variables) { + var result = variable.AcceptVisitor(this, data); + if (result.ThrowsException) + return result; + data = result.Variables; + } + + return VisitorResult.ForValue(data, NullValueStatus.Unknown); + } + + public override VisitorResult VisitVariableInitializer(VariableInitializer variableInitializer, VariableStatusInfo data) + { + if (variableInitializer.Initializer.IsNull) { + data = data.Clone(); + data[variableInitializer.Name] = NullValueStatus.Unassigned; + } else { + var result = variableInitializer.Initializer.AcceptVisitor(this, data); + if (result.ThrowsException) + return result; + data = result.Variables.Clone(); + data[variableInitializer.Name] = result.NullableReturnResult; + } + + return VisitorResult.ForValue(data, data [variableInitializer.Name]); + } + + public override VisitorResult VisitIfElseStatement(IfElseStatement ifElseStatement, VariableStatusInfo data) + { + //We'll visit the true/false statements later (directly from the CFG) + return ifElseStatement.Condition.AcceptVisitor(this, data); + } + + public override VisitorResult VisitWhileStatement(WhileStatement whileStatement, VariableStatusInfo data) + { + return whileStatement.Condition.AcceptVisitor(this, data); + } + + public override VisitorResult VisitDoWhileStatement(DoWhileStatement doWhileStatement, VariableStatusInfo data) + { + return doWhileStatement.Condition.AcceptVisitor(this, data); + } + + public override VisitorResult VisitForStatement(ForStatement forStatement, VariableStatusInfo data) + { + //The initializers, the embedded statement and the iterators aren't visited here + //because they have their own CFG nodes. + if (forStatement.Condition.IsNull) + return VisitorResult.ForValue(data, NullValueStatus.Unknown); + return forStatement.Condition.AcceptVisitor(this, data); + } + + public override VisitorResult VisitForeachStatement(ForeachStatement foreachStatement, VariableStatusInfo data) + { + var newVariable = foreachStatement.VariableNameToken; + var inExpressionResult = foreachStatement.InExpression.AcceptVisitor(this, data); + if (inExpressionResult.ThrowsException) + return inExpressionResult; + + var newData = inExpressionResult.Variables.Clone(); + + var resolveResult = analysis.context.Resolve(foreachStatement.VariableNameToken) as LocalResolveResult; + if (resolveResult != null) { + //C# 5.0 changed the meaning of foreach so that each iteration declares a new variable + //as such, the variable is "uncaptured" only for C# >= 5.0 + if (analysis.context.Supports(new Version(5, 0)) || data[newVariable.Name] != NullValueStatus.CapturedUnknown) { + newData[newVariable.Name] = NullValueAnalysis.IsTypeNullable(resolveResult.Type) ? inExpressionResult.EnumeratedValueResult : NullValueStatus.DefinitelyNotNull; + } + } + + return VisitorResult.ForValue(newData, NullValueStatus.Unknown); + } + + public override VisitorResult VisitUsingStatement(UsingStatement usingStatement, VariableStatusInfo data) + { + return usingStatement.ResourceAcquisition.AcceptVisitor(this, data); + } + + public override VisitorResult VisitFixedStatement(FixedStatement fixedStatement, VariableStatusInfo data) + { + foreach (var variable in fixedStatement.Variables) { + var result = variable.AcceptVisitor(this, data); + if (result.ThrowsException) + return result; + data = result.Variables; + } + + return VisitorResult.ForValue(data, NullValueStatus.Unknown); + } + + public override VisitorResult VisitSwitchStatement(SwitchStatement switchStatement, VariableStatusInfo data) + { + //We could do better than this, but it would require special handling outside the visitor + //so for now, for simplicity, we'll just take the easy way + + var tentativeResult = switchStatement.Expression.AcceptVisitor(this, data); + if (tentativeResult.ThrowsException) { + return tentativeResult; + } + + foreach (var section in switchStatement.SwitchSections) { + //No need to check for ThrowsException, since it will always be false (see VisitSwitchSection) + section.AcceptVisitor(this, tentativeResult.Variables); + } + + return VisitorResult.ForValue(tentativeResult.Variables, NullValueStatus.Unknown); + } + + public override VisitorResult VisitSwitchSection(SwitchSection switchSection, VariableStatusInfo data) + { + return VisitorResult.ForValue(data, NullValueStatus.Unknown); + } + + public override VisitorResult VisitExpressionStatement(ExpressionStatement expressionStatement, VariableStatusInfo data) + { + return expressionStatement.Expression.AcceptVisitor(this, data); + } + + public override VisitorResult VisitReturnStatement(ReturnStatement returnStatement, VariableStatusInfo data) + { + if (returnStatement.Expression.IsNull) + return VisitorResult.ForValue(data, NullValueStatus.Unknown); + return returnStatement.Expression.AcceptVisitor(this, data); + } + + public override VisitorResult VisitTryCatchStatement(TryCatchStatement tryCatchStatement, VariableStatusInfo data) + { + //The needs special treatment in the analyser itself + return VisitorResult.ForValue(data, NullValueStatus.Unknown); + } + + public override VisitorResult VisitBreakStatement(BreakStatement breakStatement, VariableStatusInfo data) + { + return VisitorResult.ForValue(data, NullValueStatus.Unknown); + } + + public override VisitorResult VisitContinueStatement(ContinueStatement continueStatement, VariableStatusInfo data) + { + return VisitorResult.ForValue(data, NullValueStatus.Unknown); + } + + public override VisitorResult VisitGotoStatement(GotoStatement gotoStatement, VariableStatusInfo data) + { + return VisitorResult.ForValue(data, NullValueStatus.Unknown); + } + + public override VisitorResult VisitGotoCaseStatement(GotoCaseStatement gotoCaseStatement, VariableStatusInfo data) + { + return VisitorResult.ForValue(data, NullValueStatus.Unknown); + } + + public override VisitorResult VisitGotoDefaultStatement(GotoDefaultStatement gotoDefaultStatement, VariableStatusInfo data) + { + return VisitorResult.ForValue(data, NullValueStatus.Unknown); + } + + public override VisitorResult VisitLabelStatement(LabelStatement labelStatement, VariableStatusInfo data) + { + return VisitorResult.ForValue(data, NullValueStatus.Unknown); + } + + public override VisitorResult VisitUnsafeStatement(UnsafeStatement unsafeStatement, VariableStatusInfo data) + { + return VisitorResult.ForValue(data, NullValueStatus.Unknown); + } + + public override VisitorResult VisitLockStatement(LockStatement lockStatement, VariableStatusInfo data) + { + var expressionResult = lockStatement.Expression.AcceptVisitor(this, data); + if (expressionResult.ThrowsException) + return expressionResult; + + if (expressionResult.NullableReturnResult == NullValueStatus.DefinitelyNull) { + return VisitorResult.ForException(expressionResult.Variables); + } + + var identifier = CSharpUtil.GetInnerMostExpression(lockStatement.Expression) as IdentifierExpression; + if (identifier != null) { + var identifierValue = expressionResult.Variables [identifier.Identifier]; + if (identifierValue != NullValueStatus.CapturedUnknown) { + var newVariables = expressionResult.Variables.Clone(); + analysis.SetLocalVariableValue(newVariables, identifier, NullValueStatus.DefinitelyNotNull); + + return VisitorResult.ForValue(newVariables, NullValueStatus.Unknown); + } + } + + return VisitorResult.ForValue(expressionResult.Variables, NullValueStatus.Unknown); + } + + public override VisitorResult VisitThrowStatement(ThrowStatement throwStatement, VariableStatusInfo data) + { + if (throwStatement.Expression.IsNull) + return VisitorResult.ForValue(data, NullValueStatus.DefinitelyNotNull); + return throwStatement.Expression.AcceptVisitor(this, data); + } + + public override VisitorResult VisitYieldBreakStatement(YieldBreakStatement yieldBreakStatement, VariableStatusInfo data) + { + return VisitorResult.ForValue(data, NullValueStatus.Unknown); + } + + public override VisitorResult VisitYieldReturnStatement(YieldReturnStatement yieldReturnStatement, VariableStatusInfo data) + { + return yieldReturnStatement.Expression.AcceptVisitor(this, data); + } + + public override VisitorResult VisitCheckedStatement(CheckedStatement checkedStatement, VariableStatusInfo data) + { + return VisitorResult.ForValue(data, NullValueStatus.Unknown); + } + + public override VisitorResult VisitUncheckedStatement(UncheckedStatement uncheckedStatement, VariableStatusInfo data) + { + return VisitorResult.ForValue(data, NullValueStatus.Unknown); + } + + void RegisterExpressionResult(Expression expression, NullValueStatus expressionResult) + { + NullValueStatus oldStatus; + if (analysis.expressionResult.TryGetValue(expression, out oldStatus)) { + analysis.expressionResult[expression] = VariableStatusInfo.CombineStatus(analysis.expressionResult[expression], expressionResult); + } + else { + analysis.expressionResult[expression] = expressionResult; + } + } + + VisitorResult HandleExpressionResult(Expression expression, VariableStatusInfo dataAfterExpression, NullValueStatus expressionResult) { + RegisterExpressionResult(expression, expressionResult); + + return VisitorResult.ForValue(dataAfterExpression, expressionResult); + } + + VisitorResult HandleExpressionResult(Expression expression, VariableStatusInfo dataAfterExpression, bool expressionResult) { + RegisterExpressionResult(expression, NullValueStatus.DefinitelyNotNull); + + return VisitorResult.ForBoolValue(dataAfterExpression, expressionResult); + } + + VisitorResult HandleExpressionResult(Expression expression, VisitorResult result) { + RegisterExpressionResult(expression, result.NullableReturnResult); + + return result; + } + + public override VisitorResult VisitAssignmentExpression(AssignmentExpression assignmentExpression, VariableStatusInfo data) + { + var tentativeResult = assignmentExpression.Left.AcceptVisitor(this, data); + if (tentativeResult.ThrowsException) + return HandleExpressionResult(assignmentExpression, tentativeResult); + tentativeResult = assignmentExpression.Right.AcceptVisitor(this, tentativeResult.Variables); + if (tentativeResult.ThrowsException) + return HandleExpressionResult(assignmentExpression, tentativeResult); + + var leftIdentifier = assignmentExpression.Left as IdentifierExpression; + if (leftIdentifier != null) { + var resolveResult = analysis.context.Resolve(leftIdentifier); + if (resolveResult.IsError) { + return HandleExpressionResult(assignmentExpression, data, NullValueStatus.Error); + } + + if (resolveResult is LocalResolveResult) { + var result = new VisitorResult(); + result.NullableReturnResult = tentativeResult.NullableReturnResult; + result.Variables = tentativeResult.Variables.Clone(); + var oldValue = result.Variables [leftIdentifier.Identifier]; + + if (assignmentExpression.Operator == AssignmentOperatorType.Assign || + oldValue == NullValueStatus.Unassigned || + oldValue == NullValueStatus.DefinitelyNotNull || + tentativeResult.NullableReturnResult == NullValueStatus.Error || + tentativeResult.NullableReturnResult == NullValueStatus.Unknown) { + analysis.SetLocalVariableValue(result.Variables, leftIdentifier, tentativeResult.NullableReturnResult); + } else { + if (oldValue == NullValueStatus.DefinitelyNull) { + //Do nothing --it'll remain null + } else { + analysis.SetLocalVariableValue(result.Variables, leftIdentifier, NullValueStatus.PotentiallyNull); + } + } + + return HandleExpressionResult(assignmentExpression, result); + } + } + + return HandleExpressionResult(assignmentExpression, tentativeResult); + } + + public override VisitorResult VisitIdentifierExpression(IdentifierExpression identifierExpression, VariableStatusInfo data) + { + var resolveResult = analysis.context.Resolve(identifierExpression); + if (resolveResult.IsError) { + return HandleExpressionResult(identifierExpression, data, NullValueStatus.Error); + } + var local = resolveResult as LocalResolveResult; + if (local != null) { + var value = data [local.Variable.Name]; + if (value == NullValueStatus.CapturedUnknown) + value = NullValueStatus.Unknown; + return HandleExpressionResult(identifierExpression, data, value); + } + if (resolveResult.IsCompileTimeConstant) { + object value = resolveResult.ConstantValue; + if (value == null) { + return HandleExpressionResult(identifierExpression, data, NullValueStatus.DefinitelyNull); + } + var boolValue = value as bool?; + if (boolValue != null) { + return VisitorResult.ForBoolValue(data, (bool)boolValue); + } + return HandleExpressionResult(identifierExpression, data, NullValueStatus.DefinitelyNotNull); + } + + var memberResolveResult = resolveResult as MemberResolveResult; + + var returnValue = GetFieldReturnValue(memberResolveResult, data); + + return HandleExpressionResult(identifierExpression, data, returnValue); + } + + public override VisitorResult VisitDefaultValueExpression(DefaultValueExpression defaultValueExpression, VariableStatusInfo data) + { + var resolveResult = analysis.context.Resolve(defaultValueExpression); + if (resolveResult.IsError) { + return HandleExpressionResult(defaultValueExpression, data, NullValueStatus.Unknown); + } + + Debug.Assert(resolveResult.IsCompileTimeConstant); + + var status = resolveResult.ConstantValue == null && resolveResult.Type.IsReferenceType != false ? NullValueStatus.DefinitelyNull : NullValueStatus.DefinitelyNotNull; + return HandleExpressionResult(defaultValueExpression, data, status); + } + + public override VisitorResult VisitNullReferenceExpression(NullReferenceExpression nullReferenceExpression, VariableStatusInfo data) + { + return HandleExpressionResult(nullReferenceExpression, data, NullValueStatus.DefinitelyNull); + } + + public override VisitorResult VisitPrimitiveExpression(PrimitiveExpression primitiveExpression, VariableStatusInfo data) + { + return HandleExpressionResult(primitiveExpression, data, NullValueStatus.DefinitelyNotNull); + } + + public override VisitorResult VisitParenthesizedExpression(ParenthesizedExpression parenthesizedExpression, VariableStatusInfo data) + { + return HandleExpressionResult(parenthesizedExpression, parenthesizedExpression.Expression.AcceptVisitor(this, data)); + } + + public override VisitorResult VisitConditionalExpression(ConditionalExpression conditionalExpression, VariableStatusInfo data) + { + var tentativeBaseResult = conditionalExpression.Condition.AcceptVisitor(this, data); + if (tentativeBaseResult.ThrowsException) + return HandleExpressionResult(conditionalExpression, tentativeBaseResult); + + var conditionResolveResult = analysis.context.Resolve(conditionalExpression.Condition); + + if (tentativeBaseResult.KnownBoolResult == true || true.Equals(conditionResolveResult.ConstantValue)) { + return HandleExpressionResult(conditionalExpression, conditionalExpression.TrueExpression.AcceptVisitor(this, tentativeBaseResult.TruePathVariables)); + } + if (tentativeBaseResult.KnownBoolResult == false || false.Equals(conditionResolveResult.ConstantValue)) { + return HandleExpressionResult(conditionalExpression, conditionalExpression.FalseExpression.AcceptVisitor(this, tentativeBaseResult.FalsePathVariables)); + } + + //No known bool result + var trueCaseResult = conditionalExpression.TrueExpression.AcceptVisitor(this, tentativeBaseResult.TruePathVariables); + if (trueCaseResult.ThrowsException) { + //We know that the true case will never be completed, then the right case is the only possible route. + return HandleExpressionResult(conditionalExpression, conditionalExpression.FalseExpression.AcceptVisitor(this, tentativeBaseResult.FalsePathVariables)); + } + var falseCaseResult = conditionalExpression.FalseExpression.AcceptVisitor(this, tentativeBaseResult.FalsePathVariables); + if (falseCaseResult.ThrowsException) { + return HandleExpressionResult(conditionalExpression, trueCaseResult.Variables, true); + } + + return HandleExpressionResult(conditionalExpression, VisitorResult.OrOperation(trueCaseResult, falseCaseResult)); + } + + public override VisitorResult VisitBinaryOperatorExpression(BinaryOperatorExpression binaryOperatorExpression, VariableStatusInfo data) + { + //Let's not evaluate the sides just yet because of ??, && and || + + //We'll register the results here (with HandleExpressionResult) + //so each Visit*Expression won't have to do it itself + switch (binaryOperatorExpression.Operator) { + case BinaryOperatorType.ConditionalAnd: + return HandleExpressionResult(binaryOperatorExpression, VisitConditionalAndExpression(binaryOperatorExpression, data)); + case BinaryOperatorType.ConditionalOr: + return HandleExpressionResult(binaryOperatorExpression, VisitConditionalOrExpression(binaryOperatorExpression, data)); + case BinaryOperatorType.NullCoalescing: + return HandleExpressionResult(binaryOperatorExpression, VisitNullCoalescing(binaryOperatorExpression, data)); + case BinaryOperatorType.Equality: + return HandleExpressionResult(binaryOperatorExpression, VisitEquality(binaryOperatorExpression, data)); + case BinaryOperatorType.InEquality: + return HandleExpressionResult(binaryOperatorExpression, VisitEquality(binaryOperatorExpression, data).Negated); + default: + return HandleExpressionResult(binaryOperatorExpression, VisitOtherBinaryExpression(binaryOperatorExpression, data)); + } + } + + VisitorResult VisitOtherBinaryExpression(BinaryOperatorExpression binaryOperatorExpression, VariableStatusInfo data) + { + var leftTentativeResult = binaryOperatorExpression.Left.AcceptVisitor(this, data); + if (leftTentativeResult.ThrowsException) + return leftTentativeResult; + var rightTentativeResult = binaryOperatorExpression.Right.AcceptVisitor(this, leftTentativeResult.Variables); + if (rightTentativeResult.ThrowsException) + return rightTentativeResult; + + //TODO: Assuming operators are not overloaded by users + // (or, if they are, that they retain similar behavior to the default ones) + + switch (binaryOperatorExpression.Operator) { + case BinaryOperatorType.LessThan: + case BinaryOperatorType.GreaterThan: + //Operations < and > with nulls always return false + //Those same operations will other values may or may not return false + if (leftTentativeResult.NullableReturnResult == NullValueStatus.DefinitelyNull && + rightTentativeResult.NullableReturnResult == NullValueStatus.DefinitelyNull) { + return VisitorResult.ForBoolValue(rightTentativeResult.Variables, false); + } + //We don't know what the value is, but we know that both true and false are != null. + return VisitorResult.ForValue(rightTentativeResult.Variables, NullValueStatus.DefinitelyNotNull); + case BinaryOperatorType.LessThanOrEqual: + case BinaryOperatorType.GreaterThanOrEqual: + if (leftTentativeResult.NullableReturnResult == NullValueStatus.DefinitelyNull) { + if (rightTentativeResult.NullableReturnResult == NullValueStatus.DefinitelyNull) + return VisitorResult.ForBoolValue(rightTentativeResult.Variables, true); + if (rightTentativeResult.NullableReturnResult == NullValueStatus.DefinitelyNotNull) + return VisitorResult.ForBoolValue(rightTentativeResult.Variables, false); + } else if (leftTentativeResult.NullableReturnResult == NullValueStatus.DefinitelyNotNull) { + if (rightTentativeResult.NullableReturnResult == NullValueStatus.DefinitelyNull) + return VisitorResult.ForBoolValue(rightTentativeResult.Variables, false); + } + + return VisitorResult.ForValue(rightTentativeResult.Variables, NullValueStatus.Unknown); + default: + //Anything else: null + anything == anything + null == null. + //not null + not null = not null + if (leftTentativeResult.NullableReturnResult == NullValueStatus.DefinitelyNull) { + return VisitorResult.ForValue(rightTentativeResult.Variables, NullValueStatus.DefinitelyNull); + } + if (leftTentativeResult.NullableReturnResult == NullValueStatus.DefinitelyNotNull) { + if (rightTentativeResult.NullableReturnResult == NullValueStatus.DefinitelyNull) + return VisitorResult.ForValue(rightTentativeResult.Variables, NullValueStatus.DefinitelyNull); + if (rightTentativeResult.NullableReturnResult == NullValueStatus.DefinitelyNotNull) + return VisitorResult.ForValue(rightTentativeResult.Variables, NullValueStatus.DefinitelyNotNull); + } + + return VisitorResult.ForValue(rightTentativeResult.Variables, NullValueStatus.Unknown); + } + } + + VisitorResult WithVariableValue(VisitorResult result, IdentifierExpression identifier, bool isNull) + { + var localVariableResult = analysis.context.Resolve(identifier) as LocalResolveResult; + if (localVariableResult != null) { + result.ConditionalBranchInfo.TrueResultVariableNullStates[identifier.Identifier] = isNull; + if (isNull) { + result.ConditionalBranchInfo.FalseResultVariableNullStates[identifier.Identifier] = false; + } + } + return result; + } + + VisitorResult VisitEquality(BinaryOperatorExpression binaryOperatorExpression, VariableStatusInfo data) + { + //TODO: Should this check for user operators? + + var tentativeLeftResult = binaryOperatorExpression.Left.AcceptVisitor(this, data); + if (tentativeLeftResult.ThrowsException) + return tentativeLeftResult; + var tentativeRightResult = binaryOperatorExpression.Right.AcceptVisitor(this, tentativeLeftResult.Variables); + if (tentativeRightResult.ThrowsException) + return tentativeRightResult; + + if (tentativeLeftResult.KnownBoolResult != null && tentativeLeftResult.KnownBoolResult == tentativeRightResult.KnownBoolResult) { + return VisitorResult.ForBoolValue(tentativeRightResult.Variables, true); + } + + if (tentativeLeftResult.KnownBoolResult != null && tentativeLeftResult.KnownBoolResult == !tentativeRightResult.KnownBoolResult) { + return VisitorResult.ForBoolValue(tentativeRightResult.Variables, false); + } + + if (tentativeLeftResult.NullableReturnResult.IsDefiniteValue()) { + if (tentativeRightResult.NullableReturnResult.IsDefiniteValue()) { + if (tentativeLeftResult.NullableReturnResult == NullValueStatus.DefinitelyNull || tentativeRightResult.NullableReturnResult == NullValueStatus.DefinitelyNull) { + return VisitorResult.ForBoolValue(tentativeRightResult.Variables, tentativeLeftResult.NullableReturnResult == tentativeRightResult.NullableReturnResult); + } + } + } + + var result = new VisitorResult(); + result.Variables = tentativeRightResult.Variables; + result.NullableReturnResult = NullValueStatus.Unknown; + result.ConditionalBranchInfo = new ConditionalBranchInfo(); + + if (tentativeRightResult.NullableReturnResult.IsDefiniteValue()) { + var identifier = CSharpUtil.GetInnerMostExpression(binaryOperatorExpression.Left) as IdentifierExpression; + + if (identifier != null) { + bool isNull = (tentativeRightResult.NullableReturnResult == NullValueStatus.DefinitelyNull); + + WithVariableValue(result, identifier, isNull); + } + } + + if (tentativeLeftResult.NullableReturnResult.IsDefiniteValue()) { + var identifier = CSharpUtil.GetInnerMostExpression(binaryOperatorExpression.Right) as IdentifierExpression; + + if (identifier != null) { + bool isNull = (tentativeLeftResult.NullableReturnResult == NullValueStatus.DefinitelyNull); + + WithVariableValue(result, identifier, isNull); + } + } + + return result; + } + + VisitorResult VisitConditionalAndExpression(BinaryOperatorExpression binaryOperatorExpression, VariableStatusInfo data) + { + var tentativeLeftResult = binaryOperatorExpression.Left.AcceptVisitor(this, data); + if (tentativeLeftResult.KnownBoolResult == false || tentativeLeftResult.ThrowsException) { + return tentativeLeftResult; + } + + var truePath = tentativeLeftResult.TruePathVariables; + var tentativeRightResult = binaryOperatorExpression.Right.AcceptVisitor(this, truePath); + if (tentativeRightResult.ThrowsException) { + //If the true path throws an exception, then the only way for the expression to complete + //successfully is if the left expression is false + return VisitorResult.ForBoolValue(tentativeLeftResult.FalsePathVariables, false); + } + + return VisitorResult.AndOperation(tentativeLeftResult, tentativeRightResult); + } + + VisitorResult VisitConditionalOrExpression(BinaryOperatorExpression binaryOperatorExpression, VariableStatusInfo data) + { + var tentativeLeftResult = binaryOperatorExpression.Left.AcceptVisitor(this, data); + if (tentativeLeftResult.KnownBoolResult == true || tentativeLeftResult.ThrowsException) { + return tentativeLeftResult; + } + + var falsePath = tentativeLeftResult.FalsePathVariables; + var tentativeRightResult = binaryOperatorExpression.Right.AcceptVisitor(this, falsePath); + if (tentativeRightResult.ThrowsException) { + //If the false path throws an exception, then the only way for the expression to complete + //successfully is if the left expression is true + return VisitorResult.ForBoolValue(tentativeLeftResult.TruePathVariables, true); + } + + return VisitorResult.OrOperation(tentativeLeftResult, tentativeRightResult); + } + + VisitorResult VisitNullCoalescing(BinaryOperatorExpression binaryOperatorExpression, VariableStatusInfo data) + { + var leftTentativeResult = binaryOperatorExpression.Left.AcceptVisitor(this, data); + if (leftTentativeResult.NullableReturnResult == NullValueStatus.DefinitelyNotNull || leftTentativeResult.ThrowsException) { + return leftTentativeResult; + } + + //If the right side is found, then the left side is known to be null + var newData = leftTentativeResult.Variables; + var leftIdentifier = CSharpUtil.GetInnerMostExpression(binaryOperatorExpression.Left) as IdentifierExpression; + if (leftIdentifier != null) { + newData = newData.Clone(); + analysis.SetLocalVariableValue(newData, leftIdentifier, NullValueStatus.DefinitelyNull); + } + + var rightTentativeResult = binaryOperatorExpression.Right.AcceptVisitor(this, newData); + if (rightTentativeResult.ThrowsException) { + //This means the left expression was not null all along (or else the expression will throw an exception) + + if (leftIdentifier != null) { + newData = newData.Clone(); + analysis.SetLocalVariableValue(newData, leftIdentifier, NullValueStatus.DefinitelyNotNull); + return VisitorResult.ForValue(newData, NullValueStatus.DefinitelyNotNull); + } + + return VisitorResult.ForValue(leftTentativeResult.Variables, NullValueStatus.DefinitelyNotNull); + } + + var mergedVariables = rightTentativeResult.Variables; + var nullValue = rightTentativeResult.NullableReturnResult; + + if (leftTentativeResult.NullableReturnResult != NullValueStatus.DefinitelyNull) { + mergedVariables = mergedVariables.Clone(); + mergedVariables.ReceiveIncoming(leftTentativeResult.Variables); + if (nullValue == NullValueStatus.DefinitelyNull) { + nullValue = NullValueStatus.PotentiallyNull; + } + } + + return VisitorResult.ForValue(mergedVariables, nullValue); + } + + public override VisitorResult VisitUnaryOperatorExpression(UnaryOperatorExpression unaryOperatorExpression, VariableStatusInfo data) + { + //TODO: Again, what to do when overloaded operators are found? + + var tentativeResult = unaryOperatorExpression.Expression.AcceptVisitor(this, data); + if (tentativeResult.ThrowsException) + return HandleExpressionResult(unaryOperatorExpression, tentativeResult); + + if (unaryOperatorExpression.Operator == UnaryOperatorType.Not) { + return HandleExpressionResult(unaryOperatorExpression, tentativeResult.Negated); + } + return HandleExpressionResult(unaryOperatorExpression, tentativeResult); + } + + public override VisitorResult VisitInvocationExpression(InvocationExpression invocationExpression, VariableStatusInfo data) + { + //TODO: Handle some common methods such as string.IsNullOrEmpty + + var targetResult = invocationExpression.Target.AcceptVisitor(this, data); + if (targetResult.ThrowsException) + return HandleExpressionResult(invocationExpression, targetResult); + + data = targetResult.Variables; + + var methodResolveResult = analysis.context.Resolve(invocationExpression) as CSharpInvocationResolveResult; + + List parameterResults = new List(); + + foreach (var argumentToHandle in invocationExpression.Arguments.Select((argument, parameterIndex) => new { argument, parameterIndex })) { + var argument = argumentToHandle.argument; + var parameterIndex = argumentToHandle.parameterIndex; + + var result = argument.AcceptVisitor(this, data); + if (result.ThrowsException) + return HandleExpressionResult(invocationExpression, result); + parameterResults.Add(result); + + var namedArgument = argument as NamedArgumentExpression; + + var directionExpression = (namedArgument == null ? argument : namedArgument.Expression) as DirectionExpression; + if (directionExpression != null && methodResolveResult != null) { + var identifier = directionExpression.Expression as IdentifierExpression; + if (identifier != null) { + //out and ref parameters do *NOT* capture the variable (since they must stop changing it by the time they return) + var identifierResolveResult = analysis.context.Resolve(identifier) as LocalResolveResult; + if (identifierResolveResult != null && IsTypeNullable(identifierResolveResult.Type)) { + data = data.Clone(); + + FixParameter(argument, methodResolveResult.Member.Parameters, parameterIndex, identifier, data); + } + } + + + continue; + } + + data = result.Variables; + } + + var identifierExpression = CSharpUtil.GetInnerMostExpression(invocationExpression.Target) as IdentifierExpression; + if (identifierExpression != null) { + if (targetResult.NullableReturnResult == NullValueStatus.DefinitelyNull) { + return HandleExpressionResult(invocationExpression, VisitorResult.ForException(data)); + } + + var descendentIdentifiers = invocationExpression.Arguments.SelectMany(argument => argument.DescendantsAndSelf).OfType(); + if (!descendentIdentifiers.Any(identifier => identifier.Identifier == identifierExpression.Identifier)) { + //TODO: We can make this check better (see VisitIndexerExpression for more details) + data = data.Clone(); + analysis.SetLocalVariableValue(data, identifierExpression, NullValueStatus.DefinitelyNotNull); + } + } + + return HandleExpressionResult(invocationExpression, GetMethodVisitorResult(methodResolveResult, data, parameterResults)); + } + + static VisitorResult GetMethodVisitorResult(CSharpInvocationResolveResult methodResolveResult, VariableStatusInfo data, List parameterResults) + { + if (methodResolveResult == null) + return VisitorResult.ForValue(data, NullValueStatus.Unknown); + + var method = methodResolveResult.Member as IMethod; + if (method != null) { + if (method.GetAttribute(new FullTypeName(AnnotationNames.AssertionMethodAttribute)) != null) { + var assertionParameters = method.Parameters.Select((parameter, index) => new { index, parameter }) + .Select(parameter => new { parameter.index, parameter.parameter, attributes = parameter.parameter.Attributes.Where(attribute => attribute.AttributeType.FullName == AnnotationNames.AssertionConditionAttribute).ToList() }) + .Where(parameter => parameter.attributes.Count() == 1) + .Select(parameter => new { parameter.index, parameter.parameter, attribute = parameter.attributes[0] }) + .ToList(); + + //Unclear what should be done if there are multiple assertion conditions + if (assertionParameters.Count() == 1) { + Debug.Assert(methodResolveResult.Arguments.Count == parameterResults.Count); + + var assertionParameter = assertionParameters [0]; + VisitorResult assertionParameterResult = null; + + object intendedResult = true; + var positionalArgument = assertionParameter.attribute.PositionalArguments.FirstOrDefault() as MemberResolveResult; + if (positionalArgument != null && positionalArgument.Type.FullName == AnnotationNames.AssertionConditionTypeAttribute) { + switch (positionalArgument.Member.FullName) { + case AnnotationNames.AssertionConditionTypeIsTrue: + intendedResult = true; + break; + case AnnotationNames.AssertionConditionTypeIsFalse: + intendedResult = false; + break; + case AnnotationNames.AssertionConditionTypeIsNull: + intendedResult = null; + break; + case AnnotationNames.AssertionConditionTypeIsNotNull: + intendedResult = ""; + break; + } + } + + int parameterIndex = assertionParameter.index; + if (assertionParameter.index < methodResolveResult.Arguments.Count && !(methodResolveResult.Arguments [assertionParameter.index] is NamedArgumentResolveResult)) { + //Use index + assertionParameterResult = parameterResults [assertionParameter.index]; + } else { + //Use named argument + int? nameIndex = methodResolveResult.Arguments.Select((argument, index) => new { argument, index}) + .Where(argument => { + var namedArgument = argument.argument as NamedArgumentResolveResult; + return namedArgument != null && namedArgument.ParameterName == assertionParameter.parameter.Name; + }).Select(argument => (int?)argument.index).FirstOrDefault(); + + if (nameIndex != null) { + parameterIndex = nameIndex.Value; + assertionParameterResult = parameterResults [nameIndex.Value]; + } else if (assertionParameter.parameter.IsOptional) { + //Try to use default value + + if (intendedResult is string) { + if (assertionParameter.parameter.ConstantValue == null) { + return VisitorResult.ForException(data); + } + } else { + if (!object.Equals(assertionParameter.parameter.ConstantValue, intendedResult)) { + return VisitorResult.ForException(data); + } + } + } else { + //The parameter was not specified, yet it is not optional? + return VisitorResult.ForException(data); + } + } + + //Now check assertion + if (assertionParameterResult != null) { + if (intendedResult is bool) { + if (assertionParameterResult.KnownBoolResult == !(bool)intendedResult) { + return VisitorResult.ForException(data); + } + + data = (bool)intendedResult ? assertionParameterResult.TruePathVariables : assertionParameterResult.FalsePathVariables; + } else { + bool shouldBeNull = intendedResult == null; + + if (assertionParameterResult.NullableReturnResult == (shouldBeNull ? NullValueStatus.DefinitelyNotNull : NullValueStatus.DefinitelyNull)) { + return VisitorResult.ForException(data); + } + + var parameterResolveResult = methodResolveResult.Arguments [parameterIndex]; + + LocalResolveResult localVariableResult = null; + + var conversionResolveResult = parameterResolveResult as ConversionResolveResult; + if (conversionResolveResult != null) { + if (!IsTypeNullable(conversionResolveResult.Type)) { + if (intendedResult == null) { + return VisitorResult.ForException(data); + } + } else { + localVariableResult = conversionResolveResult.Input as LocalResolveResult; + } + } else { + localVariableResult = parameterResolveResult as LocalResolveResult; + } + + if (localVariableResult != null && data[localVariableResult.Variable.Name] != NullValueStatus.CapturedUnknown) { + data = data.Clone(); + data [localVariableResult.Variable.Name] = shouldBeNull ? NullValueStatus.DefinitelyNull : NullValueStatus.DefinitelyNotNull; + } + } + } + } + } + } + + bool isNullable = IsTypeNullable(methodResolveResult.Type); + if (!isNullable) { + return VisitorResult.ForValue(data, NullValueStatus.DefinitelyNotNull); + } + + if (method != null) + return VisitorResult.ForValue(data, GetNullableStatus(method)); + + return VisitorResult.ForValue(data, GetNullableStatus(methodResolveResult.TargetResult.Type.GetDefinition())); + } + + static NullValueStatus GetNullableStatus(IEntity entity) + { + if (entity.DeclaringType != null && entity.DeclaringType.Kind == TypeKind.Delegate) { + //Handle Delegate.Invoke method + return GetNullableStatus(entity.DeclaringTypeDefinition); + } + + return GetNullableStatus(fullTypeName => entity.GetAttribute(new FullTypeName(fullTypeName))); + } + + static NullValueStatus GetNullableStatus(IParameter parameter) + { + return GetNullableStatus(fullTypeName => parameter.Attributes.FirstOrDefault(attribute => attribute.AttributeType.FullName == fullTypeName)); + } + + static NullValueStatus GetNullableStatus(Func attributeGetter) + { + if (attributeGetter(AnnotationNames.NotNullAttribute) != null) { + return NullValueStatus.DefinitelyNotNull; + } + if (attributeGetter(AnnotationNames.CanBeNullAttribute) != null) { + return NullValueStatus.PotentiallyNull; + } + return NullValueStatus.Unknown; + } + + public override VisitorResult VisitMemberReferenceExpression(MemberReferenceExpression memberReferenceExpression, VariableStatusInfo data) + { + var targetResult = memberReferenceExpression.Target.AcceptVisitor(this, data); + if (targetResult.ThrowsException) + return HandleExpressionResult(memberReferenceExpression, targetResult); + + var variables = targetResult.Variables; + + var memberResolveResult = analysis.context.Resolve(memberReferenceExpression) as MemberResolveResult; + + var targetIdentifier = CSharpUtil.GetInnerMostExpression(memberReferenceExpression.Target) as IdentifierExpression; + if (targetIdentifier != null) { + if (memberResolveResult == null) { + var invocation = memberReferenceExpression.Parent as InvocationExpression; + if (invocation != null) { + memberResolveResult = analysis.context.Resolve(invocation) as MemberResolveResult; + } + } + + if (memberResolveResult != null && memberResolveResult.Member.FullName != "System.Nullable.HasValue") { + var method = memberResolveResult.Member as IMethod; + if (method == null || !method.IsExtensionMethod) { + if (targetResult.NullableReturnResult == NullValueStatus.DefinitelyNull) { + return HandleExpressionResult(memberReferenceExpression, VisitorResult.ForException(variables)); + } + if (variables [targetIdentifier.Identifier] != NullValueStatus.CapturedUnknown) { + variables = variables.Clone(); + analysis.SetLocalVariableValue(variables, targetIdentifier, NullValueStatus.DefinitelyNotNull); + } + } + } + } + + var returnValue = GetFieldReturnValue(memberResolveResult, data); + return HandleExpressionResult(memberReferenceExpression, variables, returnValue); + } + + static NullValueStatus GetFieldReturnValue(MemberResolveResult memberResolveResult, VariableStatusInfo data) + { + bool isNullable = memberResolveResult == null || IsTypeNullable(memberResolveResult.Type); + if (!isNullable) { + return NullValueStatus.DefinitelyNotNull; + } + + if (memberResolveResult != null) { + return GetNullableStatus(memberResolveResult.Member); + } + + return NullValueStatus.Unknown; + } + + public override VisitorResult VisitTypeReferenceExpression(TypeReferenceExpression typeReferenceExpression, VariableStatusInfo data) + { + return HandleExpressionResult(typeReferenceExpression, data, NullValueStatus.Unknown); + + } + + void FixParameter(Expression argument, IList parameters, int parameterIndex, IdentifierExpression identifier, VariableStatusInfo data) + { + NullValueStatus newValue = NullValueStatus.Unknown; + if (argument is NamedArgumentExpression) { + var namedResolveResult = analysis.context.Resolve(argument) as NamedArgumentResolveResult; + if (namedResolveResult != null) { + newValue = GetNullableStatus(namedResolveResult.Parameter); + } + } + else { + var parameter = parameters[parameterIndex]; + newValue = GetNullableStatus(parameter); + } + analysis.SetLocalVariableValue(data, identifier, newValue); + } + + public override VisitorResult VisitObjectCreateExpression(ObjectCreateExpression objectCreateExpression, VariableStatusInfo data) + { + foreach (var argumentToHandle in objectCreateExpression.Arguments.Select((argument, parameterIndex) => new { argument, parameterIndex })) { + var argument = argumentToHandle.argument; + var parameterIndex = argumentToHandle.parameterIndex; + + var namedArgument = argument as NamedArgumentExpression; + + var directionExpression = (namedArgument == null ? argument : namedArgument.Expression) as DirectionExpression; + if (directionExpression != null) { + var identifier = directionExpression.Expression as IdentifierExpression; + if (identifier != null && data [identifier.Identifier] != NullValueStatus.CapturedUnknown) { + //out and ref parameters do *NOT* capture the variable (since they must stop changing it by the time they return) + data = data.Clone(); + + var constructorResolveResult = analysis.context.Resolve(objectCreateExpression) as CSharpInvocationResolveResult; + if (constructorResolveResult != null) + FixParameter(argument, constructorResolveResult.Member.Parameters, parameterIndex, identifier, data); + } + continue; + } + + var argumentResult = argument.AcceptVisitor(this, data); + if (argumentResult.ThrowsException) + return argumentResult; + + data = argumentResult.Variables; + } + + //Constructors never return null + return HandleExpressionResult(objectCreateExpression, data, NullValueStatus.DefinitelyNotNull); + } + + public override VisitorResult VisitArrayCreateExpression(ArrayCreateExpression arrayCreateExpression, VariableStatusInfo data) + { + foreach (var argument in arrayCreateExpression.Arguments) { + var result = argument.AcceptVisitor(this, data); + if (result.ThrowsException) + return result; + data = result.Variables.Clone(); + } + + if (arrayCreateExpression.Initializer.IsNull) { + return HandleExpressionResult(arrayCreateExpression, data, NullValueStatus.DefinitelyNotNull); + } + + return HandleExpressionResult(arrayCreateExpression, arrayCreateExpression.Initializer.AcceptVisitor(this, data)); + } + + public override VisitorResult VisitArrayInitializerExpression(ArrayInitializerExpression arrayInitializerExpression, VariableStatusInfo data) + { + if (arrayInitializerExpression.IsSingleElement) { + return HandleExpressionResult(arrayInitializerExpression, arrayInitializerExpression.Elements.Single().AcceptVisitor(this, data)); + } + if (!arrayInitializerExpression.Elements.Any()) { + //Empty array + return HandleExpressionResult(arrayInitializerExpression, VisitorResult.ForValue(data, NullValueStatus.Unknown)); + } + + NullValueStatus enumeratedValue = NullValueStatus.UnreachableOrInexistent; + foreach (var element in arrayInitializerExpression.Elements) { + var result = element.AcceptVisitor(this, data); + if (result.ThrowsException) + return result; + data = result.Variables.Clone(); + enumeratedValue = VariableStatusInfo.CombineStatus(enumeratedValue, result.NullableReturnResult); + + } + return HandleExpressionResult(arrayInitializerExpression, VisitorResult.ForEnumeratedValue(data, enumeratedValue)); + } + + public override VisitorResult VisitAnonymousTypeCreateExpression(AnonymousTypeCreateExpression anonymousTypeCreateExpression, VariableStatusInfo data) + { + foreach (var initializer in anonymousTypeCreateExpression.Initializers) { + var result = initializer.AcceptVisitor(this, data); + if (result.ThrowsException) + return result; + data = result.Variables; + } + + return HandleExpressionResult(anonymousTypeCreateExpression, data, NullValueStatus.DefinitelyNotNull); + } + + public override VisitorResult VisitLambdaExpression(LambdaExpression lambdaExpression, VariableStatusInfo data) + { + var newData = data.Clone(); + + var identifiers = lambdaExpression.Descendants.OfType(); + foreach (var identifier in identifiers) { + //Check if it is in a "change-null-state" context + //For instance, x++ does not change the null state + //but `x = y` does. + if (identifier.Parent is AssignmentExpression && identifier.Role == AssignmentExpression.LeftRole) { + var parent = (AssignmentExpression)identifier.Parent; + if (parent.Operator != AssignmentOperatorType.Assign) { + continue; + } + } else { + //No other context matters + //Captured variables are never passed by reference (out/ref) + continue; + } + + //At this point, we know there's a good chance the variable has been changed + var identifierResolveResult = analysis.context.Resolve(identifier) as LocalResolveResult; + if (identifierResolveResult != null && IsTypeNullable(identifierResolveResult.Type)) { + analysis.SetLocalVariableValue(newData, identifier, NullValueStatus.CapturedUnknown); + } + } + + //The lambda itself is known not to be null + return HandleExpressionResult(lambdaExpression, newData, NullValueStatus.DefinitelyNotNull); + } + + public override VisitorResult VisitAnonymousMethodExpression(AnonymousMethodExpression anonymousMethodExpression, VariableStatusInfo data) + { + var newData = data.Clone(); + + var identifiers = anonymousMethodExpression.Descendants.OfType(); + foreach (var identifier in identifiers) { + //Check if it is in a "change-null-state" context + //For instance, x++ does not change the null state + //but `x = y` does. + if (identifier.Parent is AssignmentExpression && identifier.Role == AssignmentExpression.LeftRole) { + var parent = (AssignmentExpression)identifier.Parent; + if (parent.Operator != AssignmentOperatorType.Assign) { + continue; + } + } else { + //No other context matters + //Captured variables are never passed by reference (out/ref) + continue; + } + + //At this point, we know there's a good chance the variable has been changed + var identifierResolveResult = analysis.context.Resolve(identifier) as LocalResolveResult; + if (identifierResolveResult != null && IsTypeNullable(identifierResolveResult.Type)) { + analysis.SetLocalVariableValue(newData, identifier, NullValueStatus.CapturedUnknown); + } + } + + //The anonymous method itself is known not to be null + return HandleExpressionResult(anonymousMethodExpression, newData, NullValueStatus.DefinitelyNotNull); + } + + + public override VisitorResult VisitNamedExpression(NamedExpression namedExpression, VariableStatusInfo data) + { + return HandleExpressionResult(namedExpression, namedExpression.Expression.AcceptVisitor(this, data)); + } + + public override VisitorResult VisitAsExpression(AsExpression asExpression, VariableStatusInfo data) + { + var tentativeResult = asExpression.Expression.AcceptVisitor(this, data); + if (tentativeResult.ThrowsException) + return tentativeResult; + + NullValueStatus result; + if (tentativeResult.NullableReturnResult == NullValueStatus.DefinitelyNull) { + result = NullValueStatus.DefinitelyNull; + } else { + var asResolveResult = analysis.context.Resolve(asExpression) as CastResolveResult; + if (asResolveResult == null || + asResolveResult.IsError || + asResolveResult.Input.Type.Kind == TypeKind.Unknown || + asResolveResult.Type.Kind == TypeKind.Unknown) { + + result = NullValueStatus.Unknown; + } else { + var conversion = new CSharpConversions(analysis.context.Compilation); + var foundConversion = conversion.ExplicitConversion(asResolveResult.Input.Type, asResolveResult.Type); + + if (foundConversion == Conversion.None) { + result = NullValueStatus.DefinitelyNull; + } else if (foundConversion == Conversion.IdentityConversion) { + result = tentativeResult.NullableReturnResult; + } else { + result = NullValueStatus.PotentiallyNull; + } + } + } + return HandleExpressionResult(asExpression, tentativeResult.Variables, result); + } + + public override VisitorResult VisitCastExpression(CastExpression castExpression, VariableStatusInfo data) + { + var tentativeResult = castExpression.Expression.AcceptVisitor(this, data); + if (tentativeResult.ThrowsException) + return tentativeResult; + + NullValueStatus result; + if (tentativeResult.NullableReturnResult == NullValueStatus.DefinitelyNull) { + result = NullValueStatus.DefinitelyNull; + } else { + result = NullValueStatus.Unknown; + } + + VariableStatusInfo variables = tentativeResult.Variables; + + var resolveResult = analysis.context.Resolve(castExpression) as CastResolveResult; + if (resolveResult != null && !IsTypeNullable(resolveResult.Type)) { + if (result == NullValueStatus.DefinitelyNull) { + return HandleExpressionResult(castExpression, VisitorResult.ForException(tentativeResult.Variables)); + } + + var identifierExpression = CSharpUtil.GetInnerMostExpression(castExpression.Expression) as IdentifierExpression; + if (identifierExpression != null) { + var currentValue = variables [identifierExpression.Identifier]; + if (currentValue != NullValueStatus.CapturedUnknown && + currentValue != NullValueStatus.UnreachableOrInexistent && + currentValue != NullValueStatus.DefinitelyNotNull) { + //DefinitelyNotNull is included in this list because if that's the status + // then we don't need to change anything + + variables = variables.Clone(); + variables [identifierExpression.Identifier] = NullValueStatus.DefinitelyNotNull; + } + } + + result = NullValueStatus.DefinitelyNotNull; + } + + return HandleExpressionResult(castExpression, variables, result); + } + + public override VisitorResult VisitIsExpression(IsExpression isExpression, VariableStatusInfo data) + { + var tentativeResult = isExpression.Expression.AcceptVisitor(this, data); + if (tentativeResult.ThrowsException) + return tentativeResult; + + //TODO: Consider, for instance: new X() is X. The result is known to be true, so we can use KnownBoolValue + return HandleExpressionResult(isExpression, tentativeResult.Variables, NullValueStatus.DefinitelyNotNull); + } + + public override VisitorResult VisitDirectionExpression(DirectionExpression directionExpression, VariableStatusInfo data) + { + return HandleExpressionResult(directionExpression, directionExpression.Expression.AcceptVisitor(this, data)); + } + + public override VisitorResult VisitCheckedExpression(CheckedExpression checkedExpression, VariableStatusInfo data) + { + return HandleExpressionResult(checkedExpression, checkedExpression.Expression.AcceptVisitor(this, data)); + } + + public override VisitorResult VisitUncheckedExpression(UncheckedExpression uncheckedExpression, VariableStatusInfo data) + { + return HandleExpressionResult(uncheckedExpression, uncheckedExpression.Expression.AcceptVisitor(this, data)); + } + + public override VisitorResult VisitThisReferenceExpression(ThisReferenceExpression thisReferenceExpression, VariableStatusInfo data) + { + return HandleExpressionResult(thisReferenceExpression, data, NullValueStatus.DefinitelyNotNull); + } + + public override VisitorResult VisitIndexerExpression(IndexerExpression indexerExpression, VariableStatusInfo data) + { + var tentativeResult = indexerExpression.Target.AcceptVisitor(this, data); + if (tentativeResult.ThrowsException) + return tentativeResult; + + data = tentativeResult.Variables; + + foreach (var argument in indexerExpression.Arguments) { + var result = argument.AcceptVisitor(this, data); + if (result.ThrowsException) + return result; + data = result.Variables.Clone(); + } + + IdentifierExpression targetAsIdentifier = CSharpUtil.GetInnerMostExpression(indexerExpression.Target) as IdentifierExpression; + if (targetAsIdentifier != null) { + if (tentativeResult.NullableReturnResult == NullValueStatus.DefinitelyNull) + return HandleExpressionResult(indexerExpression, VisitorResult.ForException(data)); + + //If this doesn't cause an exception, then the target is not null + //But we won't set it if it has been changed + var descendentIdentifiers = indexerExpression.Arguments + .SelectMany(argument => argument.DescendantsAndSelf).OfType(); + if (!descendentIdentifiers.Any(identifier => identifier.Identifier == targetAsIdentifier.Identifier)) { + //TODO: this check might be improved to include more legitimate cases + //A good check will necessarily have to consider captured variables + data = data.Clone(); + analysis.SetLocalVariableValue(data, targetAsIdentifier, NullValueStatus.DefinitelyNotNull); + } + } + + var indexerResolveResult = analysis.context.Resolve(indexerExpression) as CSharpInvocationResolveResult; + bool isNullable = indexerResolveResult == null || IsTypeNullable(indexerResolveResult.Type); + + var returnValue = isNullable ? NullValueStatus.Unknown : NullValueStatus.DefinitelyNotNull; + return HandleExpressionResult(indexerExpression, data, returnValue); + } + + public override VisitorResult VisitBaseReferenceExpression(BaseReferenceExpression baseReferenceExpression, VariableStatusInfo data) + { + return HandleExpressionResult(baseReferenceExpression, data, NullValueStatus.DefinitelyNotNull); + } + + public override VisitorResult VisitTypeOfExpression(TypeOfExpression typeOfExpression, VariableStatusInfo data) + { + return HandleExpressionResult(typeOfExpression, data, NullValueStatus.DefinitelyNotNull); + } + + public override VisitorResult VisitSizeOfExpression(SizeOfExpression sizeOfExpression, VariableStatusInfo data) + { + return HandleExpressionResult(sizeOfExpression, data, NullValueStatus.DefinitelyNotNull); + } + + public override VisitorResult VisitPointerReferenceExpression(PointerReferenceExpression pointerReferenceExpression, VariableStatusInfo data) + { + var targetResult = pointerReferenceExpression.Target.AcceptVisitor(this, data); + if (targetResult.ThrowsException) + return targetResult; + return HandleExpressionResult(pointerReferenceExpression, targetResult.Variables, NullValueStatus.DefinitelyNotNull); + } + + public override VisitorResult VisitStackAllocExpression(StackAllocExpression stackAllocExpression, VariableStatusInfo data) + { + var countResult = stackAllocExpression.CountExpression.AcceptVisitor(this, data); + if (countResult.ThrowsException) + return countResult; + return HandleExpressionResult(stackAllocExpression, countResult.Variables, NullValueStatus.DefinitelyNotNull); + } + + public override VisitorResult VisitNamedArgumentExpression(NamedArgumentExpression namedArgumentExpression, VariableStatusInfo data) + { + return HandleExpressionResult(namedArgumentExpression, namedArgumentExpression.Expression.AcceptVisitor(this, data)); + } + + public override VisitorResult VisitUndocumentedExpression(UndocumentedExpression undocumentedExpression, VariableStatusInfo data) + { + throw new NotImplementedException(); + } + + public override VisitorResult VisitQueryExpression(QueryExpression queryExpression, VariableStatusInfo data) + { + VariableStatusInfo outgoingData = data.Clone(); + NullValueStatus? outgoingEnumeratedValue = null; + var clauses = queryExpression.Clauses.ToList(); + + var backtracingClauses = (from item in clauses.Select((clause, i) => new { clause, i }) + where item.clause is QueryFromClause || item.clause is QueryJoinClause || item.clause is QueryContinuationClause + select item.i).ToList(); + + var beforeClauseVariableStates = Enumerable.Range(0, clauses.Count).ToDictionary(clauseIndex => clauseIndex, + clauseIndex => new VariableStatusInfo()); + var afterClauseVariableStates = Enumerable.Range(0, clauses.Count).ToDictionary(clauseIndex => clauseIndex, + clauseIndex => new VariableStatusInfo()); + + VisitorResult lastValidResult = null; + int currentClauseIndex = 0; + for (;;) { + VisitorResult result = null; + QueryClause clause = null; + bool backtrack = false; + + if (currentClauseIndex >= clauses.Count) { + backtrack = true; + } else { + clause = clauses [currentClauseIndex]; + beforeClauseVariableStates [currentClauseIndex].ReceiveIncoming(data); + result = clause.AcceptVisitor(this, data); + data = result.Variables; + lastValidResult = result; + if (result.KnownBoolResult == false) { + backtrack = true; + } + if (result.ThrowsException) { + //Don't backtrack. Exceptions completely stop the query. + break; + } + else { + afterClauseVariableStates [currentClauseIndex].ReceiveIncoming(data); + } + } + + if (backtrack) { + int? newIndex; + for (;;) { + newIndex = backtracingClauses.LastOrDefault(index => index < currentClauseIndex); + if (newIndex == null) { + //We've reached the end + break; + } + + currentClauseIndex = (int)newIndex + 1; + + if (!beforeClauseVariableStates[currentClauseIndex].ReceiveIncoming(lastValidResult.Variables)) { + newIndex = null; + break; + } + } + + if (newIndex == null) { + break; + } + + } else { + if (clause is QuerySelectClause) { + outgoingData.ReceiveIncoming(data); + if (outgoingEnumeratedValue == null) + outgoingEnumeratedValue = result.EnumeratedValueResult; + else + outgoingEnumeratedValue = VariableStatusInfo.CombineStatus(outgoingEnumeratedValue.Value, result.EnumeratedValueResult); + } + + ++currentClauseIndex; + } + } + + var finalData = new VariableStatusInfo(); + var endingClauseIndices = from item in clauses.Select((clause, i) => new { clause, i }) + let clause = item.clause + where clause is QueryFromClause || + clause is QueryContinuationClause || + clause is QueryJoinClause || + clause is QuerySelectClause || + clause is QueryWhereClause + select item.i; + foreach (var clauseIndex in endingClauseIndices) { + finalData.ReceiveIncoming(afterClauseVariableStates [clauseIndex]); + } + + return VisitorResult.ForEnumeratedValue(finalData, outgoingEnumeratedValue ?? NullValueStatus.Unknown); + } + + public override VisitorResult VisitQueryContinuationClause(QueryContinuationClause queryContinuationClause, VariableStatusInfo data) + { + return IntroduceVariableFromEnumeratedValue(queryContinuationClause.Identifier, queryContinuationClause.PrecedingQuery, data); + } + + VisitorResult IntroduceVariableFromEnumeratedValue(string newVariable, Expression expression, VariableStatusInfo data) + { + var result = expression.AcceptVisitor(this, data); + var newVariables = result.Variables.Clone(); + newVariables[newVariable] = result.EnumeratedValueResult; + return VisitorResult.ForValue(newVariables, NullValueStatus.Unknown); + } + + public override VisitorResult VisitQueryFromClause(QueryFromClause queryFromClause, VariableStatusInfo data) + { + return IntroduceVariableFromEnumeratedValue(queryFromClause.Identifier, queryFromClause.Expression, data); + } + + public override VisitorResult VisitQueryJoinClause(QueryJoinClause queryJoinClause, VariableStatusInfo data) + { + //TODO: Check if this really works in weird edge-cases. + var tentativeResult = IntroduceVariableFromEnumeratedValue(queryJoinClause.JoinIdentifier, queryJoinClause.InExpression, data); + tentativeResult = queryJoinClause.OnExpression.AcceptVisitor(this, tentativeResult.Variables); + tentativeResult = queryJoinClause.EqualsExpression.AcceptVisitor(this, tentativeResult.Variables); + + if (queryJoinClause.IsGroupJoin) { + var newVariables = tentativeResult.Variables.Clone(); + analysis.SetLocalVariableValue(newVariables, queryJoinClause.IntoIdentifierToken, NullValueStatus.DefinitelyNotNull); + return VisitorResult.ForValue(newVariables, NullValueStatus.Unknown); + } + + return tentativeResult; + } + + public override VisitorResult VisitQueryLetClause(QueryLetClause queryLetClause, VariableStatusInfo data) + { + var result = queryLetClause.Expression.AcceptVisitor(this, data); + + string newVariable = queryLetClause.Identifier; + var newVariables = result.Variables.Clone(); + newVariables [newVariable] = result.NullableReturnResult; + + return VisitorResult.ForValue(newVariables, NullValueStatus.Unknown); + } + + public override VisitorResult VisitQuerySelectClause(QuerySelectClause querySelectClause, VariableStatusInfo data) + { + var result = querySelectClause.Expression.AcceptVisitor(this, data); + + //The value of the expression in select becomes the "enumerated" value + return VisitorResult.ForEnumeratedValue(result.Variables, result.NullableReturnResult); + } + + public override VisitorResult VisitQueryWhereClause(QueryWhereClause queryWhereClause, VariableStatusInfo data) + { + var result = queryWhereClause.Condition.AcceptVisitor(this, data); + + return VisitorResult.ForEnumeratedValue(result.TruePathVariables, NullValueStatus.Unknown); + } + + public override VisitorResult VisitQueryOrderClause(QueryOrderClause queryOrderClause, VariableStatusInfo data) + { + foreach (var ordering in queryOrderClause.Orderings) { + data = ordering.AcceptVisitor(this, data).Variables; + } + + return VisitorResult.ForValue(data, NullValueStatus.Unknown); + } + + public override VisitorResult VisitQueryOrdering(QueryOrdering queryOrdering, VariableStatusInfo data) + { + return VisitorResult.ForValue(queryOrdering.Expression.AcceptVisitor(this, data).Variables, NullValueStatus.Unknown); + } + + public override VisitorResult VisitQueryGroupClause(QueryGroupClause queryGroupClause, VariableStatusInfo data) + { + var projectionResult = queryGroupClause.Projection.AcceptVisitor(this, data); + data = projectionResult.Variables; + data = queryGroupClause.Key.AcceptVisitor(this, data).Variables; + + return VisitorResult.ForEnumeratedValue(data, projectionResult.NullableReturnResult); + } + } + } +} + diff --git a/NRefactory/ICSharpCode.NRefactory.CSharp/Analysis/NullValueStatus.cs b/NRefactory/ICSharpCode.NRefactory.CSharp/Analysis/NullValueStatus.cs new file mode 100644 index 000000000..f6816dfd5 --- /dev/null +++ b/NRefactory/ICSharpCode.NRefactory.CSharp/Analysis/NullValueStatus.cs @@ -0,0 +1,84 @@ +// +// NullValueAnalysis.cs +// +// Author: +// Luís Reis +// +// Copyright (c) 2013 Luís Reis +// +// 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; + +namespace ICSharpCode.NRefactory.CSharp.Analysis +{ + /// + /// Represents the null value status of a variable at a specific location. + /// + public enum NullValueStatus + { + /// + /// The value of the variable is unknown, possibly due to limitations + /// of the null value analysis. + /// + Unknown = 0, + /// + /// The value of the variable is unknown and even assigning it to a + /// value won't change its state, since it has been captured by a lambda + /// that may change it at any time (potentially even from a different thread). + /// Only going out of scope and creating a new variable may change the value + /// of this variable. + /// + CapturedUnknown, + /// + /// This variable is potentially unassigned. + /// + Unassigned, + /// + /// The value of the variable is provably null. + /// + DefinitelyNull, + /// + /// The value of the variable might or might not be null + /// + PotentiallyNull, + /// + /// The value of the variable is provably not null + /// + DefinitelyNotNull, + /// + /// The position of this node is unreachable, therefore the value + /// of the variable is not meaningful. + /// Alternatively, it might mean no local variable exists with the requested name. + /// + UnreachableOrInexistent, + /// + /// The analyser has encountered an error when attempting to find the value + /// of this variable. + /// + Error + } + + public static class NullValueStatusExtensions + { + public static bool IsDefiniteValue (this NullValueStatus self) { + return self == NullValueStatus.DefinitelyNull || self == NullValueStatus.DefinitelyNotNull; + } + } +} + diff --git a/NRefactory/ICSharpCode.NRefactory.CSharp/Analysis/ReachabilityAnalysis.cs b/NRefactory/ICSharpCode.NRefactory.CSharp/Analysis/ReachabilityAnalysis.cs index ebb8d419d..ce64f5f3b 100644 --- a/NRefactory/ICSharpCode.NRefactory.CSharp/Analysis/ReachabilityAnalysis.cs +++ b/NRefactory/ICSharpCode.NRefactory.CSharp/Analysis/ReachabilityAnalysis.cs @@ -1,4 +1,4 @@ -// Copyright (c) AlphaSierraPapa for the SharpDevelop Team +// Copyright (c) 2010-2013 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 @@ -18,10 +18,12 @@ using System; using System.Collections.Generic; +using System.Linq; using System.Threading; using ICSharpCode.NRefactory.CSharp.Resolver; using ICSharpCode.NRefactory.CSharp.TypeSystem; using ICSharpCode.NRefactory.Semantics; +using ICSharpCode.NRefactory.CSharp; namespace ICSharpCode.NRefactory.CSharp.Analysis { @@ -34,32 +36,37 @@ namespace ICSharpCode.NRefactory.CSharp.Analysis HashSet reachableEndPoints = new HashSet(); HashSet visitedNodes = new HashSet(); Stack stack = new Stack(); + RecursiveDetectorVisitor recursiveDetectorVisitor = null; private ReachabilityAnalysis() {} - public static ReachabilityAnalysis Create(Statement statement, CSharpAstResolver resolver = null, CancellationToken cancellationToken = default(CancellationToken)) + public static ReachabilityAnalysis Create(Statement statement, CSharpAstResolver resolver = null, RecursiveDetectorVisitor recursiveDetectorVisitor = null, CancellationToken cancellationToken = default(CancellationToken)) { var cfgBuilder = new ControlFlowGraphBuilder(); var cfg = cfgBuilder.BuildControlFlowGraph(statement, resolver, cancellationToken); - return Create(cfg, cancellationToken); + return Create(cfg, recursiveDetectorVisitor, cancellationToken); } internal static ReachabilityAnalysis Create(Statement statement, Func resolver, CSharpTypeResolveContext typeResolveContext, CancellationToken cancellationToken) { var cfgBuilder = new ControlFlowGraphBuilder(); var cfg = cfgBuilder.BuildControlFlowGraph(statement, resolver, typeResolveContext, cancellationToken); - return Create(cfg, cancellationToken); + return Create(cfg, null, cancellationToken); } - public static ReachabilityAnalysis Create(IList controlFlowGraph, CancellationToken cancellationToken = default(CancellationToken)) + public static ReachabilityAnalysis Create(IList controlFlowGraph, RecursiveDetectorVisitor recursiveDetectorVisitor = null, CancellationToken cancellationToken = default(CancellationToken)) { if (controlFlowGraph == null) throw new ArgumentNullException("controlFlowGraph"); ReachabilityAnalysis ra = new ReachabilityAnalysis(); - ra.stack.Push(controlFlowGraph[0]); - while (ra.stack.Count > 0) { - cancellationToken.ThrowIfCancellationRequested(); - ra.MarkReachable(ra.stack.Pop()); + ra.recursiveDetectorVisitor = recursiveDetectorVisitor; + // Analysing a null node can result in an empty control flow graph + if (controlFlowGraph.Count > 0) { + ra.stack.Push(controlFlowGraph[0]); + while (ra.stack.Count > 0) { + cancellationToken.ThrowIfCancellationRequested(); + ra.MarkReachable(ra.stack.Pop()); + } } ra.stack = null; ra.visitedNodes = null; @@ -68,15 +75,32 @@ namespace ICSharpCode.NRefactory.CSharp.Analysis void MarkReachable(ControlFlowNode node) { - if (node.PreviousStatement != null) + if (node.PreviousStatement != null) { + if (node.PreviousStatement is LabelStatement) { + reachableStatements.Add(node.PreviousStatement); + } reachableEndPoints.Add(node.PreviousStatement); - if (node.NextStatement != null) + } + if (node.NextStatement != null) { reachableStatements.Add(node.NextStatement); + if (IsRecursive(node.NextStatement)) { + return; + } + } foreach (var edge in node.Outgoing) { if (visitedNodes.Add(edge.To)) stack.Push(edge.To); } } + + bool IsRecursive(Statement statement) + { + return recursiveDetectorVisitor != null && statement.AcceptVisitor(recursiveDetectorVisitor); + } + + public IEnumerable ReachableStatements { + get { return reachableStatements; } + } public bool IsReachable(Statement statement) { @@ -87,5 +111,99 @@ namespace ICSharpCode.NRefactory.CSharp.Analysis { return reachableEndPoints.Contains(statement); } + + public class RecursiveDetectorVisitor : DepthFirstAstVisitor + { + public override bool VisitConditionalExpression(ConditionalExpression conditionalExpression) + { + if (conditionalExpression.Condition.AcceptVisitor(this)) + return true; + + if (!conditionalExpression.TrueExpression.AcceptVisitor(this)) + return false; + + return conditionalExpression.FalseExpression.AcceptVisitor(this); + } + + public override bool VisitBinaryOperatorExpression(BinaryOperatorExpression binaryOperatorExpression) + { + if (binaryOperatorExpression.Operator == BinaryOperatorType.NullCoalescing) { + return binaryOperatorExpression.Left.AcceptVisitor(this); + } + return base.VisitBinaryOperatorExpression(binaryOperatorExpression); + } + + public override bool VisitIfElseStatement(IfElseStatement ifElseStatement) + { + if (ifElseStatement.Condition.AcceptVisitor(this)) + return true; + + if (!ifElseStatement.TrueStatement.AcceptVisitor(this)) + return false; + + //No need to worry about null ast nodes, since AcceptVisitor will just + //return false in those cases + return ifElseStatement.FalseStatement.AcceptVisitor(this); + } + + public override bool VisitForeachStatement(ForeachStatement foreachStatement) + { + //Even if the body is always recursive, the function may stop if the collection + // is empty. + return foreachStatement.InExpression.AcceptVisitor(this); + } + + public override bool VisitForStatement(ForStatement forStatement) + { + if (forStatement.Initializers.Any(initializer => initializer.AcceptVisitor(this))) + return true; + + return forStatement.Condition.AcceptVisitor(this); + } + + public override bool VisitSwitchStatement(SwitchStatement switchStatement) + { + if (switchStatement.Expression.AcceptVisitor(this)) { + return true; + } + + bool foundDefault = false; + foreach (var section in switchStatement.SwitchSections) { + foundDefault = foundDefault || section.CaseLabels.Any(label => label.Expression.IsNull); + if (!section.AcceptVisitor(this)) + return false; + } + + return foundDefault; + } + + public override bool VisitBlockStatement(BlockStatement blockStatement) + { + //If the block has a recursive statement, then that statement will be visited + //individually by the CFG construction algorithm later. + return false; + } + + protected override bool VisitChildren(AstNode node) + { + return VisitNodeList(node.Children); + } + + bool VisitNodeList(IEnumerable nodes) { + return nodes.Any(node => node.AcceptVisitor(this)); + } + + public override bool VisitQueryExpression(QueryExpression queryExpression) + { + //We only care about the first from clause because: + //in "from x in Method() select x", Method() might be recursive + //but in "from x in Bar() from y in Method() select x + y", even if Method() is recursive + //Bar might still be empty. + var queryFromClause = queryExpression.Clauses.OfType().FirstOrDefault(); + if (queryFromClause == null) + return true; + return queryFromClause.AcceptVisitor(this); + } + } } } diff --git a/NRefactory/ICSharpCode.NRefactory.CSharp/Analysis/SemanticHighlightingVisitor.cs b/NRefactory/ICSharpCode.NRefactory.CSharp/Analysis/SemanticHighlightingVisitor.cs new file mode 100644 index 000000000..b0ef67743 --- /dev/null +++ b/NRefactory/ICSharpCode.NRefactory.CSharp/Analysis/SemanticHighlightingVisitor.cs @@ -0,0 +1,691 @@ +// Copyright (c) 2010-2013 AlphaSierraPapa for the SharpDevelop Team +// +// Permission is hereby granted, free of charge, to any person obtaining a copy of this +// software and associated documentation files (the "Software"), to deal in the Software +// without restriction, including without limitation the rights to use, copy, modify, merge, +// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons +// to whom the Software is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all copies or +// substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, +// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE +// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS IN THE SOFTWARE. + +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; +using ICSharpCode.NRefactory.CSharp.Resolver; +using ICSharpCode.NRefactory.Semantics; +using ICSharpCode.NRefactory.TypeSystem; +using System.Threading; +using ICSharpCode.NRefactory.CSharp.Completion; +using System.Collections.ObjectModel; + +namespace ICSharpCode.NRefactory.CSharp.Analysis +{ + /// + /// C# Semantic highlighter. + /// + public abstract class SemanticHighlightingVisitor : DepthFirstAstVisitor + { + protected CancellationToken cancellationToken = default (CancellationToken); + + protected TColor defaultTextColor; + protected TColor referenceTypeColor; + protected TColor valueTypeColor; + protected TColor interfaceTypeColor; + protected TColor enumerationTypeColor; + protected TColor typeParameterTypeColor; + protected TColor delegateTypeColor; + + protected TColor methodCallColor; + protected TColor methodDeclarationColor; + + protected TColor eventDeclarationColor; + protected TColor eventAccessColor; + + protected TColor propertyDeclarationColor; + protected TColor propertyAccessColor; + + protected TColor fieldDeclarationColor; + protected TColor fieldAccessColor; + + protected TColor variableDeclarationColor; + protected TColor variableAccessColor; + + protected TColor parameterDeclarationColor; + protected TColor parameterAccessColor; + + protected TColor valueKeywordColor; + protected TColor externAliasKeywordColor; + protected TColor varKeywordTypeColor; + + /// + /// Used for 'in' modifiers on type parameters. + /// + /// + /// 'in' may have a different color when used with 'foreach'. + /// 'out' is not colored by semantic highlighting, as syntax highlighting can already detect it as a parameter modifier. + /// + protected TColor parameterModifierColor; + + /// + /// Used for inactive code (excluded by preprocessor or ConditionalAttribute) + /// + protected TColor inactiveCodeColor; + + protected TColor stringFormatItemColor; + + + protected TColor syntaxErrorColor; + + protected TextLocation regionStart; + protected TextLocation regionEnd; + + protected CSharpAstResolver resolver; + bool isInAccessorContainingValueParameter; + + protected abstract void Colorize(TextLocation start, TextLocation end, TColor color); + + #region Colorize helper methods + protected void Colorize(Identifier identifier, ResolveResult rr) + { + if (identifier.IsNull) + return; + if (rr.IsError) { + Colorize(identifier, syntaxErrorColor); + return; + } + if (rr is TypeResolveResult) { + if (blockDepth > 0 && identifier.Name == "var" && rr.Type.Kind != TypeKind.Null && rr.Type.Name != "var" ) { + Colorize(identifier, varKeywordTypeColor); + return; + } + + TColor color; + if (TryGetTypeHighlighting (rr.Type.Kind, out color)) { + Colorize(identifier, color); + } + return; + } + var mrr = rr as MemberResolveResult; + if (mrr != null) { + TColor color; + if (TryGetMemberColor (mrr.Member, out color)) { + Colorize(identifier, color); + return; + } + } + + if (rr is MethodGroupResolveResult) { + Colorize (identifier, methodCallColor); + return; + } + + var localResult = rr as LocalResolveResult; + if (localResult != null) { + if (localResult.Variable is IParameter) { + Colorize (identifier, parameterAccessColor); + } else { + Colorize (identifier, variableAccessColor); + } + } + + + VisitIdentifier(identifier); // un-colorize contextual keywords + } + + protected void Colorize(AstNode node, TColor color) + { + if (node.IsNull) + return; + Colorize(node.StartLocation, node.EndLocation, color); + } + #endregion + + protected override void VisitChildren(AstNode node) + { + for (var child = node.FirstChild; child != null; child = child.NextSibling) { + if (child.StartLocation < regionEnd && child.EndLocation > regionStart) + child.AcceptVisitor(this); + } + } + + /// + /// Visit all children of node until (but excluding) end. + /// If end is a null node, nothing will be visited. + /// + protected void VisitChildrenUntil(AstNode node, AstNode end) + { + if (end.IsNull) + return; + Debug.Assert(node == end.Parent); + for (var child = node.FirstChild; child != end; child = child.NextSibling) { + cancellationToken.ThrowIfCancellationRequested(); + if (child.StartLocation < regionEnd && child.EndLocation > regionStart) + child.AcceptVisitor(this); + } + } + + /// + /// Visit all children of node after (excluding) start. + /// If start is a null node, all children will be visited. + /// + protected void VisitChildrenAfter(AstNode node, AstNode start) + { + Debug.Assert(start.IsNull || start.Parent == node); + for (var child = (start.IsNull ? node.FirstChild : start.NextSibling); child != null; child = child.NextSibling) { + cancellationToken.ThrowIfCancellationRequested(); + if (child.StartLocation < regionEnd && child.EndLocation > regionStart) + child.AcceptVisitor(this); + } + } + + public override void VisitIdentifier(Identifier identifier) + { + switch (identifier.Name) { + case "add": + case "async": + case "await": + case "get": + case "partial": + case "remove": + case "set": + case "where": + case "yield": + case "from": + case "select": + case "group": + case "into": + case "orderby": + case "join": + case "let": + case "on": + case "equals": + case "by": + case "ascending": + case "descending": + case "dynamic": + case "var": + // Reset color of contextual keyword to default if it's used as an identifier. + // Note that this method does not get called when 'var' or 'dynamic' is used as a type, + // because types get highlighted with valueTypeColor/referenceTypeColor instead. + Colorize(identifier, defaultTextColor); + break; + case "global": + // Reset color of 'global' keyword to default unless its used as part of 'global::'. + MemberType parentMemberType = identifier.Parent as MemberType; + if (parentMemberType == null || !parentMemberType.IsDoubleColon) + Colorize(identifier, defaultTextColor); + break; + } + // "value" is handled in VisitIdentifierExpression() + // "alias" is handled in VisitExternAliasDeclaration() + } + + public override void VisitSimpleType(SimpleType simpleType) + { + var identifierToken = simpleType.IdentifierToken; + VisitChildrenUntil(simpleType, identifierToken); + Colorize(identifierToken, resolver.Resolve(simpleType, cancellationToken)); + VisitChildrenAfter(simpleType, identifierToken); + } + + public override void VisitMemberType(MemberType memberType) + { + var memberNameToken = memberType.MemberNameToken; + VisitChildrenUntil(memberType, memberNameToken); + Colorize(memberNameToken, resolver.Resolve(memberType, cancellationToken)); + VisitChildrenAfter(memberType, memberNameToken); + } + + public override void VisitIdentifierExpression(IdentifierExpression identifierExpression) + { + var identifier = identifierExpression.IdentifierToken; + VisitChildrenUntil(identifierExpression, identifier); + if (isInAccessorContainingValueParameter && identifierExpression.Identifier == "value") { + Colorize(identifier, valueKeywordColor); + } else { + Colorize(identifier, resolver.Resolve(identifierExpression, cancellationToken)); + } + VisitChildrenAfter(identifierExpression, identifier); + } + + public override void VisitMemberReferenceExpression(MemberReferenceExpression memberReferenceExpression) + { + var memberNameToken = memberReferenceExpression.MemberNameToken; + VisitChildrenUntil(memberReferenceExpression, memberNameToken); + ResolveResult rr = resolver.Resolve(memberReferenceExpression, cancellationToken); + Colorize(memberNameToken, rr); + VisitChildrenAfter(memberReferenceExpression, memberNameToken); + } + + void HighlightStringFormatItems(PrimitiveExpression expr) + { + if (!(expr.Value is string)) + return; + int line = expr.StartLocation.Line; + int col = expr.StartLocation.Column; + TextLocation start = TextLocation.Empty; + for (int i = 0; i < expr.LiteralValue.Length; i++) { + char ch = expr.LiteralValue [i]; + + if (NewLine.GetDelimiterType(ch, i + 1 < expr.LiteralValue.Length ? expr.LiteralValue [i + 1] : '\0') != UnicodeNewline.Unknown) { + line++; + col = 1; + continue; + } + + + if (ch == '{' && start.IsEmpty) { + char next = i + 1 < expr.LiteralValue.Length ? expr.LiteralValue [i + 1] : '\0'; + if (next == '{') { + i++; + col += 2; + continue; + } + start = new TextLocation(line, col); + } + col++; + if (ch == '}' &&!start.IsEmpty) { + char next = i + 1 < expr.LiteralValue.Length ? expr.LiteralValue [i + 1] : '\0'; + if (next == '}') { + i++; + col += 2; + continue; + } + Colorize(start, new TextLocation(line, col), stringFormatItemColor); + start = TextLocation.Empty; + } + } + + } + + public override void VisitInvocationExpression(InvocationExpression invocationExpression) + { + Expression target = invocationExpression.Target; + if (target is IdentifierExpression || target is MemberReferenceExpression || target is PointerReferenceExpression) { + var invocationRR = resolver.Resolve(invocationExpression, cancellationToken) as CSharpInvocationResolveResult; + if (invocationRR != null) { + if (invocationExpression.Parent is ExpressionStatement && (IsInactiveConditionalMethod(invocationRR.Member) || IsEmptyPartialMethod(invocationRR.Member))) { + // mark the whole invocation statement as inactive code + Colorize(invocationExpression.Parent, inactiveCodeColor); + return; + } + + Expression fmtArgumets; + IList args; + if (invocationRR.Arguments.Count > 1 && FormatStringHelper.TryGetFormattingParameters(invocationRR, invocationExpression, out fmtArgumets, out args, null)) { + var expr = invocationExpression.Arguments.First() as PrimitiveExpression; + if (expr != null) + HighlightStringFormatItems(expr); + } + } + + VisitChildrenUntil(invocationExpression, target); + + // highlight the method call + var identifier = target.GetChildByRole(Roles.Identifier); + VisitChildrenUntil(target, identifier); + if (invocationRR != null && !invocationRR.IsDelegateInvocation) { + Colorize(identifier, methodCallColor); + } else { + ResolveResult targetRR = resolver.Resolve(target, cancellationToken); + Colorize(identifier, targetRR); + } + VisitChildrenAfter(target, identifier); + VisitChildrenAfter(invocationExpression, target); + } else { + VisitChildren(invocationExpression); + } + } + + #region IsInactiveConditional helper methods + bool IsInactiveConditionalMethod(IParameterizedMember member) + { + if (member.SymbolKind != SymbolKind.Method || member.ReturnType.Kind != TypeKind.Void) + return false; + foreach (var baseMember in InheritanceHelper.GetBaseMembers(member, false)) { + if (IsInactiveConditional (baseMember.Attributes)) + return true; + } + return IsInactiveConditional(member.Attributes); + } + + static bool IsEmptyPartialMethod(IParameterizedMember member) + { + if (member.SymbolKind != SymbolKind.Method || member.ReturnType.Kind != TypeKind.Void) + return false; + var method = (IMethod)member; + return method.IsPartial && !method.HasBody; + } + + bool IsInactiveConditional(IList attributes) + { + bool hasConditionalAttribute = false; + foreach (var attr in attributes) { + if (attr.AttributeType.Name == "ConditionalAttribute" && attr.AttributeType.Namespace == "System.Diagnostics" && attr.PositionalArguments.Count == 1) { + string symbol = attr.PositionalArguments[0].ConstantValue as string; + if (symbol != null) { + hasConditionalAttribute = true; + var cu = this.resolver.RootNode as SyntaxTree; + if (cu != null) { + if (cu.ConditionalSymbols.Contains(symbol)) + return false; // conditional is active + } + } + } + } + + return hasConditionalAttribute; + } + #endregion + + public override void VisitExternAliasDeclaration (ExternAliasDeclaration externAliasDeclaration) + { + var aliasToken = externAliasDeclaration.AliasToken; + VisitChildrenUntil(externAliasDeclaration, aliasToken); + Colorize (aliasToken, externAliasKeywordColor); + VisitChildrenAfter(externAliasDeclaration, aliasToken); + } + + public override void VisitAccessor(Accessor accessor) + { + isInAccessorContainingValueParameter = accessor.Role != PropertyDeclaration.GetterRole; + try { + VisitChildren(accessor); + } finally { + isInAccessorContainingValueParameter = false; + } + } + + bool CheckInterfaceImplementation (EntityDeclaration entityDeclaration) + { + var result = resolver.Resolve (entityDeclaration, cancellationToken) as MemberResolveResult; + if (result == null) + return false; + if (result.Member.ImplementedInterfaceMembers.Count == 0) { + Colorize (entityDeclaration.NameToken, syntaxErrorColor); + return false; + } + return true; + } + + public override void VisitMethodDeclaration(MethodDeclaration methodDeclaration) + { + var nameToken = methodDeclaration.NameToken; + VisitChildrenUntil(methodDeclaration, nameToken); + if (!methodDeclaration.PrivateImplementationType.IsNull) { + if (!CheckInterfaceImplementation (methodDeclaration)) { + VisitChildrenAfter(methodDeclaration, nameToken); + return; + } + } + Colorize(nameToken, methodDeclarationColor); + VisitChildrenAfter(methodDeclaration, nameToken); + } + + public override void VisitParameterDeclaration(ParameterDeclaration parameterDeclaration) + { + var nameToken = parameterDeclaration.NameToken; + VisitChildrenUntil(parameterDeclaration, nameToken); + Colorize(nameToken, parameterDeclarationColor); + VisitChildrenAfter(parameterDeclaration, nameToken); + } + + public override void VisitEventDeclaration(EventDeclaration eventDeclaration) + { + var nameToken = eventDeclaration.NameToken; + VisitChildrenUntil(eventDeclaration, nameToken); + Colorize(nameToken, eventDeclarationColor); + VisitChildrenAfter(eventDeclaration, nameToken); + } + + public override void VisitCustomEventDeclaration(CustomEventDeclaration eventDeclaration) + { + var nameToken = eventDeclaration.NameToken; + VisitChildrenUntil(eventDeclaration, nameToken); + if (!eventDeclaration.PrivateImplementationType.IsNull) { + if (!CheckInterfaceImplementation (eventDeclaration)) { + VisitChildrenAfter(eventDeclaration, nameToken); + return; + } + } + Colorize(nameToken, eventDeclarationColor); + VisitChildrenAfter(eventDeclaration, nameToken); + } + + public override void VisitPropertyDeclaration(PropertyDeclaration propertyDeclaration) + { + var nameToken = propertyDeclaration.NameToken; + VisitChildrenUntil(propertyDeclaration, nameToken); + if (!propertyDeclaration.PrivateImplementationType.IsNull) { + if (!CheckInterfaceImplementation (propertyDeclaration)) { + VisitChildrenAfter(propertyDeclaration, nameToken); + return; + } + } + Colorize(nameToken, propertyDeclarationColor); + VisitChildrenAfter(propertyDeclaration, nameToken); + } + + public override void VisitIndexerDeclaration(IndexerDeclaration indexerDeclaration) + { + base.VisitIndexerDeclaration(indexerDeclaration); + if (!indexerDeclaration.PrivateImplementationType.IsNull) { + CheckInterfaceImplementation (indexerDeclaration); + } + } + + public override void VisitFieldDeclaration(FieldDeclaration fieldDeclaration) + { + fieldDeclaration.ReturnType.AcceptVisitor (this); + foreach (var init in fieldDeclaration.Variables) { + Colorize (init.NameToken, fieldDeclarationColor); + init.Initializer.AcceptVisitor (this); + } + } + + public override void VisitFixedFieldDeclaration(FixedFieldDeclaration fixedFieldDeclaration) + { + fixedFieldDeclaration.ReturnType.AcceptVisitor (this); + foreach (var init in fixedFieldDeclaration.Variables) { + Colorize (init.NameToken, fieldDeclarationColor); + init.CountExpression.AcceptVisitor (this); + } + } + + public override void VisitConstructorDeclaration(ConstructorDeclaration constructorDeclaration) + { + HandleConstructorOrDestructor(constructorDeclaration); + } + + public override void VisitDestructorDeclaration(DestructorDeclaration destructorDeclaration) + { + HandleConstructorOrDestructor(destructorDeclaration); + } + + void HandleConstructorOrDestructor(AstNode constructorDeclaration) + { + Identifier nameToken = constructorDeclaration.GetChildByRole(Roles.Identifier); + VisitChildrenUntil(constructorDeclaration, nameToken); + var currentTypeDef = resolver.GetResolverStateBefore(constructorDeclaration).CurrentTypeDefinition; + if (currentTypeDef != null && nameToken.Name == currentTypeDef.Name) { + TColor color; + if (TryGetTypeHighlighting (currentTypeDef.Kind, out color)) + Colorize(nameToken, color); + } + VisitChildrenAfter(constructorDeclaration, nameToken); + } + + bool TryGetMemberColor(IMember member, out TColor color) + { + switch (member.SymbolKind) { + case SymbolKind.Field: + color = fieldAccessColor; + return true; + case SymbolKind.Property: + color = propertyAccessColor; + return true; + case SymbolKind.Event: + color = eventAccessColor; + return true; + case SymbolKind.Method: + color = methodCallColor; + return true; + case SymbolKind.Constructor: + case SymbolKind.Destructor: + return TryGetTypeHighlighting (member.DeclaringType.Kind, out color); + default: + color = default (TColor); + return false; + } + } + + TColor GetTypeHighlighting (ClassType classType) + { + switch (classType) { + case ClassType.Class: + return referenceTypeColor; + case ClassType.Struct: + return valueTypeColor; + case ClassType.Interface: + return interfaceTypeColor; + case ClassType.Enum: + return enumerationTypeColor; + default: + throw new InvalidOperationException ("Unknown class type :" + classType); + } + } + + bool TryGetTypeHighlighting (TypeKind kind, out TColor color) + { + switch (kind) { + case TypeKind.Class: + color = referenceTypeColor; + return true; + case TypeKind.Struct: + color = valueTypeColor; + return true; + case TypeKind.Interface: + color = interfaceTypeColor; + return true; + case TypeKind.Enum: + color = enumerationTypeColor; + return true; + case TypeKind.TypeParameter: + color = typeParameterTypeColor; + return true; + case TypeKind.Delegate: + color = delegateTypeColor; + return true; + case TypeKind.Unknown: + case TypeKind.Null: + color = syntaxErrorColor; + return true; + default: + color = default (TColor); + return false; + } + } + + public override void VisitTypeDeclaration(TypeDeclaration typeDeclaration) + { + var nameToken = typeDeclaration.NameToken; + VisitChildrenUntil(typeDeclaration, nameToken); + Colorize(nameToken, GetTypeHighlighting (typeDeclaration.ClassType)); + VisitChildrenAfter(typeDeclaration, nameToken); + } + + public override void VisitTypeParameterDeclaration(TypeParameterDeclaration typeParameterDeclaration) + { + if (typeParameterDeclaration.Variance == VarianceModifier.Contravariant) + Colorize(typeParameterDeclaration.VarianceToken, parameterModifierColor); + + // bool isValueType = false; + // if (typeParameterDeclaration.Parent != null) { + // foreach (var constraint in typeParameterDeclaration.Parent.GetChildrenByRole(Roles.Constraint)) { + // if (constraint.TypeParameter.Identifier == typeParameterDeclaration.Name) { + // isValueType = constraint.BaseTypes.OfType().Any(p => p.Keyword == "struct"); + // } + // } + // } + var nameToken = typeParameterDeclaration.NameToken; + VisitChildrenUntil(typeParameterDeclaration, nameToken); + Colorize(nameToken, typeParameterTypeColor); /*isValueType ? valueTypeColor : referenceTypeColor*/ + VisitChildrenAfter(typeParameterDeclaration, nameToken); + } + + public override void VisitDelegateDeclaration(DelegateDeclaration delegateDeclaration) + { + var nameToken = delegateDeclaration.NameToken; + VisitChildrenUntil(delegateDeclaration, nameToken); + Colorize(nameToken, delegateTypeColor); + VisitChildrenAfter(delegateDeclaration, nameToken); + } + + public override void VisitVariableInitializer(VariableInitializer variableInitializer) + { + var nameToken = variableInitializer.NameToken; + VisitChildrenUntil(variableInitializer, nameToken); + if (variableInitializer.Parent is FieldDeclaration) { + Colorize(nameToken, fieldDeclarationColor); + } else if (variableInitializer.Parent is EventDeclaration) { + Colorize(nameToken, eventDeclarationColor); + } else { + Colorize(nameToken, variableDeclarationColor); + } + VisitChildrenAfter(variableInitializer, nameToken); + } + + public override void VisitComment(Comment comment) + { + if (comment.CommentType == CommentType.InactiveCode) { + Colorize(comment, inactiveCodeColor); + } + } + + public override void VisitPreProcessorDirective(PreProcessorDirective preProcessorDirective) + { + } + + public override void VisitAttribute(ICSharpCode.NRefactory.CSharp.Attribute attribute) + { + ITypeDefinition attrDef = resolver.Resolve(attribute.Type, cancellationToken).Type.GetDefinition(); + if (attrDef != null && IsInactiveConditional(attrDef.Attributes)) { + Colorize(attribute, inactiveCodeColor); + } else { + VisitChildren(attribute); + } + } + + public override void VisitArrayInitializerExpression (ArrayInitializerExpression arrayInitializerExpression) + { + foreach (var a in arrayInitializerExpression.Elements) { + var namedElement = a as NamedExpression; + if (namedElement != null) { + var result = resolver.Resolve (namedElement, cancellationToken); + if (result.IsError) + Colorize (namedElement.NameToken, syntaxErrorColor); + namedElement.Expression.AcceptVisitor (this); + } else { + a.AcceptVisitor (this); + } + } + } + + int blockDepth; + public override void VisitBlockStatement(BlockStatement blockStatement) + { + blockDepth++; + base.VisitBlockStatement(blockStatement); + blockDepth--; + } + } +} diff --git a/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/AstNode.cs b/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/AstNode.cs index 5d73c90db..8676beb67 100644 --- a/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/AstNode.cs +++ b/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/AstNode.cs @@ -31,10 +31,11 @@ using System.Diagnostics; using System.IO; using System.Linq; using System.Threading; +using ICSharpCode.NRefactory.TypeSystem; namespace ICSharpCode.NRefactory.CSharp { - public abstract class AstNode : AbstractAnnotatable, ICSharpCode.NRefactory.TypeSystem.IFreezable, PatternMatching.INode + public abstract class AstNode : AbstractAnnotatable, ICSharpCode.NRefactory.TypeSystem.IFreezable, PatternMatching.INode, ICloneable { // the Root role must be available when creating the null nodes, so we can't put it in the Roles class internal static readonly Role RootRole = new Role ("Root"); @@ -58,16 +59,17 @@ namespace ICSharpCode.NRefactory.CSharp public override void AcceptVisitor (IAstVisitor visitor) { + visitor.VisitNullNode(this); } public override T AcceptVisitor (IAstVisitor visitor) { - return default (T); + return visitor.VisitNullNode(this); } public override S AcceptVisitor (IAstVisitor visitor, T data) { - return default (S); + return visitor.VisitNullNode(this, data); } protected internal override bool DoMatch (AstNode other, PatternMatching.Match match) @@ -192,6 +194,12 @@ namespace ICSharpCode.NRefactory.CSharp return child.EndLocation; } } + + public DomRegion Region { + get { + return new DomRegion (StartLocation, EndLocation); + } + } /// /// Gets the region from StartLocation to EndLocation for this node. @@ -223,6 +231,10 @@ namespace ICSharpCode.NRefactory.CSharp } } + internal uint RoleIndex { + get { return flags & roleIndexMask; } + } + void SetRole(Role role) { flags = (flags & ~roleIndexMask) | role.Index; @@ -286,31 +298,67 @@ namespace ICSharpCode.NRefactory.CSharp } /// - /// Gets all descendants of this node (excluding this node itself). + /// Gets all descendants of this node (excluding this node itself) in pre-order. /// public IEnumerable Descendants { - get { return GetDescendants(false); } + get { return GetDescendantsImpl(false); } } /// - /// Gets all descendants of this node (including this node itself). + /// Gets all descendants of this node (including this node itself) in pre-order. /// public IEnumerable DescendantsAndSelf { - get { return GetDescendants(true); } + get { return GetDescendantsImpl(true); } } - - IEnumerable GetDescendants(bool includeSelf) + + static bool IsInsideRegion(DomRegion region, AstNode pos) + { + if (region.IsEmpty) + return true; + var nodeRegion = pos.Region; + return region.IntersectsWith(nodeRegion) || region.OverlapsWith(nodeRegion); + } + + public IEnumerable DescendantNodes (Func descendIntoChildren = null) { - if (includeSelf) - yield return this; + return GetDescendantsImpl(false, new DomRegion (), descendIntoChildren); + } + + public IEnumerable DescendantNodes (DomRegion region, Func descendIntoChildren = null) + { + return GetDescendantsImpl(false, region, descendIntoChildren); + } + + public IEnumerable DescendantNodesAndSelf (Func descendIntoChildren = null) + { + return GetDescendantsImpl(true, new DomRegion (), descendIntoChildren); + } + + public IEnumerable DescendantNodesAndSelf (DomRegion region, Func descendIntoChildren = null) + { + return GetDescendantsImpl(true, region, descendIntoChildren); + } + + IEnumerable GetDescendantsImpl(bool includeSelf, DomRegion region = new DomRegion (), Func descendIntoChildren = null) + { + if (includeSelf) { + if (IsInsideRegion (region, this)) + yield return this; + if (descendIntoChildren != null && !descendIntoChildren(this)) + yield break; + } + Stack nextStack = new Stack(); nextStack.Push(null); AstNode pos = firstChild; while (pos != null) { + // Remember next before yielding pos. + // This allows removing/replacing nodes while iterating through the list. if (pos.nextSibling != null) nextStack.Push(pos.nextSibling); - yield return pos; - if (pos.firstChild != null) + if (IsInsideRegion(region, pos)) + yield return pos; + if (pos.firstChild != null && (descendIntoChildren == null || descendIntoChildren(pos))) pos = pos.firstChild; else pos = nextStack.Pop(); @@ -337,7 +385,12 @@ namespace ICSharpCode.NRefactory.CSharp { return Ancestors.OfType().FirstOrDefault(); } - + + public AstNode GetParent(Func pred) + { + return Ancestors.FirstOrDefault(pred); + } + public AstNodeCollection GetChildrenByRole (Role role) where T : AstNode { return new AstNodeCollection (this, role); @@ -359,6 +412,8 @@ namespace ICSharpCode.NRefactory.CSharp if (child == null || child.IsNull) return; ThrowIfFrozen(); + if (child == this) + throw new ArgumentException ("Cannot add a node to itself as a child.", "child"); if (child.parent != null) throw new ArgumentException ("Node is already used in another tree.", "child"); if (child.IsFrozen) @@ -366,10 +421,24 @@ namespace ICSharpCode.NRefactory.CSharp AddChildUnsafe (child, role); } + public void AddChildWithExistingRole (AstNode child) + { + if (child == null || child.IsNull) + return; + ThrowIfFrozen(); + if (child == this) + throw new ArgumentException ("Cannot add a node to itself as a child.", "child"); + if (child.parent != null) + throw new ArgumentException ("Node is already used in another tree.", "child"); + if (child.IsFrozen) + throw new ArgumentException ("Cannot add a frozen node.", "child"); + AddChildUnsafe (child, child.Role); + } + /// /// Adds a child without performing any safety checks. /// - void AddChildUnsafe (AstNode child, Role role) + internal void AddChildUnsafe (AstNode child, Role role) { child.parent = this; child.SetRole(role); @@ -405,7 +474,7 @@ namespace ICSharpCode.NRefactory.CSharp InsertChildBeforeUnsafe (nextSibling, child, role); } - void InsertChildBeforeUnsafe (AstNode nextSibling, AstNode child, Role role) + internal void InsertChildBeforeUnsafe (AstNode nextSibling, AstNode child, Role role) { child.parent = this; child.SetRole(role); @@ -566,6 +635,11 @@ namespace ICSharpCode.NRefactory.CSharp return copy; } + object ICloneable.Clone() + { + return Clone(); + } + public abstract void AcceptVisitor (IAstVisitor visitor); public abstract T AcceptVisitor (IAstVisitor visitor); @@ -612,6 +686,19 @@ namespace ICSharpCode.NRefactory.CSharp return null; } + /// + /// Gets the next node which fullfills a given predicate + /// + /// The next node. + /// The predicate. + public AstNode GetNextNode (Func pred) + { + var next = GetNextNode(); + while (next != null && !pred (next)) + next = next.GetNextNode(); + return next; + } + public AstNode GetPrevNode () { if (PrevSibling != null) @@ -620,6 +707,19 @@ namespace ICSharpCode.NRefactory.CSharp return Parent.GetPrevNode (); return null; } + + /// + /// Gets the previous node which fullfills a given predicate + /// + /// The next node. + /// The predicate. + public AstNode GetPrevNode (Func pred) + { + var prev = GetPrevNode(); + while (prev != null && !pred (prev)) + prev = prev.GetPrevNode(); + return prev; + } // filters all non c# nodes (comments, white spaces or pre processor directives) public AstNode GetCSharpNodeBefore (AstNode node) { @@ -631,6 +731,32 @@ namespace ICSharpCode.NRefactory.CSharp } return null; } + + /// + /// Gets the next sibling which fullfills a given predicate + /// + /// The next node. + /// The predicate. + public AstNode GetNextSibling (Func pred) + { + var next = NextSibling; + while (next != null && !pred (next)) + next = next.NextSibling; + return next; + } + + /// + /// Gets the next sibling which fullfills a given predicate + /// + /// The next node. + /// The predicate. + public AstNode GetPrevSibling (Func pred) + { + var prev = PrevSibling; + while (prev != null && !pred (prev)) + prev = prev.PrevSibling; + return prev; + } #region GetNodeAt /// @@ -652,20 +778,18 @@ namespace ICSharpCode.NRefactory.CSharp { AstNode result = null; AstNode node = this; - while (node.FirstChild != null) { - var child = node.FirstChild; - while (child != null) { - if (child.StartLocation <= location && location < child.EndLocation) { - if (pred == null || pred (child)) - result = child; - node = child; - break; - } - child = child.NextSibling; - } - // found no better child node - therefore the parent is the right one. - if (child == null) + while (node.LastChild != null) { + var child = node.LastChild; + while (child != null && child.StartLocation > location) + child = child.prevSibling; + if (child != null && location < child.EndLocation) { + if (pred == null || pred (child)) + result = child; + node = child; + } else { + // found no better child node - therefore the parent is the right one. break; + } } return result; } @@ -689,20 +813,18 @@ namespace ICSharpCode.NRefactory.CSharp { T result = null; AstNode node = this; - while (node.FirstChild != null) { - var child = node.FirstChild; - while (child != null) { - if (child.StartLocation <= location && location < child.EndLocation) { - if (child is T) - result = (T)child; - node = child; - break; - } - child = child.NextSibling; - } - // found no better child node - therefore the parent is the right one. - if (child == null) + while (node.LastChild != null) { + var child = node.LastChild; + while (child != null && child.StartLocation > location) + child = child.prevSibling; + if (child != null && location < child.EndLocation) { + if (child is T) + result = (T)child; + node = child; + } else { + // found no better child node - therefore the parent is the right one. break; + } } return result; } @@ -729,20 +851,18 @@ namespace ICSharpCode.NRefactory.CSharp { AstNode result = null; AstNode node = this; - while (node.FirstChild != null) { - var child = node.FirstChild; - while (child != null) { - if (child.StartLocation <= location && location <= child.EndLocation) { - if (pred == null || pred (child)) - result = child; - node = child; - break; - } - child = child.NextSibling; - } - // found no better child node - therefore the parent is the right one. - if (child == null) + while (node.LastChild != null) { + var child = node.LastChild; + while (child != null && child.StartLocation > location) + child = child.prevSibling; + if (child != null && location <= child.EndLocation) { + if (pred == null || pred (child)) + result = child; + node = child; + } else { + // found no better child node - therefore the parent is the right one. break; + } } return result; } @@ -766,20 +886,18 @@ namespace ICSharpCode.NRefactory.CSharp { T result = null; AstNode node = this; - while (node.FirstChild != null) { - var child = node.FirstChild; - while (child != null) { - if (child.StartLocation <= location && location < child.EndLocation) { - if (child is T) - result = (T)child; - node = child; - break; - } - child = child.NextSibling; - } - // found no better child node - therefore the parent is the right one. - if (child == null) + while (node.LastChild != null) { + var child = node.LastChild; + while (child != null && child.StartLocation > location) + child = child.prevSibling; + if (child != null && location <= child.EndLocation) { + if (child is T) + result = (T)child; + node = child; + } else { + // found no better child node - therefore the parent is the right one. break; + } } return result; } @@ -798,11 +916,17 @@ namespace ICSharpCode.NRefactory.CSharp return this; } + /// + /// Returns the root nodes of all subtrees that are fully contained in the specified region. + /// public IEnumerable GetNodesBetween (int startLine, int startColumn, int endLine, int endColumn) { return GetNodesBetween (new TextLocation (startLine, startColumn), new TextLocation (endLine, endColumn)); } + /// + /// Returns the root nodes of all subtrees that are fully contained between and (inclusive). + /// public IEnumerable GetNodesBetween (TextLocation start, TextLocation end) { AstNode node = this; @@ -811,11 +935,11 @@ namespace ICSharpCode.NRefactory.CSharp if (start <= node.StartLocation && node.EndLocation <= end) { // Remember next before yielding node. // This allows iteration to continue when the caller removes/replaces the node. - next = node.NextSibling; + next = node.GetNextNode(); yield return node; } else { if (node.EndLocation <= start) { - next = node.NextSibling; + next = node.GetNextNode(); } else { next = node.FirstChild; } @@ -826,14 +950,19 @@ namespace ICSharpCode.NRefactory.CSharp node = next; } } - + [Obsolete("Use ToString(options).")] + public string GetText (CSharpFormattingOptions formattingOptions = null) + { + return ToString(formattingOptions); + } + /// /// Gets the node as formatted C# output. /// /// /// Formatting options. /// - public virtual string GetText (CSharpFormattingOptions formattingOptions = null) + public virtual string ToString (CSharpFormattingOptions formattingOptions) { if (IsNull) return ""; @@ -841,7 +970,12 @@ namespace ICSharpCode.NRefactory.CSharp AcceptVisitor (new CSharpOutputVisitor (w, formattingOptions ?? FormattingOptionsFactory.CreateMono ())); return w.ToString (); } - + + public sealed override string ToString() + { + return ToString(null); + } + /// /// Returns true, if the given coordinates (line, column) are in the node. /// @@ -897,7 +1031,7 @@ namespace ICSharpCode.NRefactory.CSharp { if (IsNull) return "Null"; - string text = GetText(); + string text = ToString(); text = text.TrimEnd().Replace("\t", "").Replace(Environment.NewLine, " "); if (text.Length > 100) return text.Substring(0, 97) + "..."; diff --git a/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/AstNodeCollection.cs b/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/AstNodeCollection.cs index b727dc211..32d08b2e4 100644 --- a/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/AstNodeCollection.cs +++ b/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/AstNodeCollection.cs @@ -1,4 +1,4 @@ -// Copyright (c) AlphaSierraPapa for the SharpDevelop Team +// Copyright (c) 2010-2013 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 @@ -28,7 +28,11 @@ namespace ICSharpCode.NRefactory.CSharp /// /// Represents the children of an AstNode that have a specific role. /// - public class AstNodeCollection : ICollection where T : AstNode + public class AstNodeCollection : ICollection + #if NET_4_5 + , IReadOnlyCollection + #endif + where T : AstNode { readonly AstNode node; readonly Role role; @@ -46,8 +50,9 @@ namespace ICSharpCode.NRefactory.CSharp public int Count { get { int count = 0; + uint roleIndex = role.Index; for (AstNode cur = node.FirstChild; cur != null; cur = cur.NextSibling) { - if (cur.Role == role) + if (cur.RoleIndex == roleIndex) count++; } return count; @@ -103,7 +108,7 @@ namespace ICSharpCode.NRefactory.CSharp public bool Contains(T element) { - return element != null && element.Parent == node && element.Role == role; + return element != null && element.Parent == node && element.RoleIndex == role.Index; } public bool Remove(T element) @@ -159,13 +164,14 @@ namespace ICSharpCode.NRefactory.CSharp public IEnumerator GetEnumerator() { + uint roleIndex = role.Index; 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) + if (cur.RoleIndex == roleIndex) yield return (T)cur; } } @@ -210,13 +216,14 @@ namespace ICSharpCode.NRefactory.CSharp /// public void AcceptVisitor(IAstVisitor visitor) { + uint roleIndex = role.Index; 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) + if (cur.RoleIndex == roleIndex) cur.AcceptVisitor(visitor); } } diff --git a/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/AstType.cs b/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/AstType.cs index 022f3cc07..2f13f0fdd 100644 --- a/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/AstType.cs +++ b/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/AstType.cs @@ -1,4 +1,4 @@ -// Copyright (c) AlphaSierraPapa for the SharpDevelop Team +// Copyright (c) 2010-2013 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 @@ -41,16 +41,17 @@ namespace ICSharpCode.NRefactory.CSharp public override void AcceptVisitor (IAstVisitor visitor) { + visitor.VisitNullNode(this); } public override T AcceptVisitor (IAstVisitor visitor) { - return default (T); + return visitor.VisitNullNode(this); } public override S AcceptVisitor (IAstVisitor visitor, T data) { - return default (S); + return visitor.VisitNullNode(this, data); } protected internal override bool DoMatch(AstNode other, PatternMatching.Match match) @@ -58,7 +59,7 @@ namespace ICSharpCode.NRefactory.CSharp return other == null || other.IsNull; } - public override ITypeReference ToTypeReference(NameLookupMode lookupMode) + public override ITypeReference ToTypeReference(NameLookupMode lookupMode, InterningProvider interningProvider) { return SpecialType.UnknownType; } @@ -99,7 +100,7 @@ namespace ICSharpCode.NRefactory.CSharp return visitor.VisitPatternPlaceholder (this, child, data); } - public override ITypeReference ToTypeReference(NameLookupMode lookupMode) + public override ITypeReference ToTypeReference(NameLookupMode lookupMode, InterningProvider interningProvider) { throw new NotSupportedException(); } @@ -125,8 +126,18 @@ namespace ICSharpCode.NRefactory.CSharp return (AstType)base.Clone(); } + /// + /// Gets whether this type is a SimpleType "var". + /// + public bool IsVar() + { + SimpleType st = this as SimpleType; + return st != null && st.Identifier == "var" && st.TypeArguments.Count == 0; + } + /// /// Create an ITypeReference for this AstType. + /// Uses the context (ancestors of this node) to determine the correct . /// /// /// The resulting type reference will read the context information from the @@ -135,7 +146,42 @@ namespace ICSharpCode.NRefactory.CSharp /// For resolving simple names, the current namespace and usings from the CurrentUsingScope /// (on CSharpTypeResolveContext only) is used. /// - public abstract ITypeReference ToTypeReference(NameLookupMode lookupMode = NameLookupMode.Type); + public ITypeReference ToTypeReference(InterningProvider interningProvider = null) + { + return ToTypeReference(GetNameLookupMode(), interningProvider); + } + + /// + /// Create an ITypeReference for this AstType. + /// + /// + /// The resulting type reference will read the context information from the + /// : + /// For resolving type parameters, the CurrentTypeDefinition/CurrentMember is used. + /// For resolving simple names, the current namespace and usings from the CurrentUsingScope + /// (on CSharpTypeResolveContext only) is used. + /// + public abstract ITypeReference ToTypeReference(NameLookupMode lookupMode, InterningProvider interningProvider = null); + + /// + /// Gets the name lookup mode from the context (looking at the ancestors of this ). + /// + public NameLookupMode GetNameLookupMode() + { + AstType outermostType = this; + while (outermostType.Parent is AstType) + outermostType = (AstType)outermostType.Parent; + + if (outermostType.Parent is UsingDeclaration || outermostType.Parent is UsingAliasDeclaration) { + return NameLookupMode.TypeInUsingDeclaration; + } else if (outermostType.Role == Roles.BaseType) { + // Use BaseTypeReference for a type's base type, and for a constraint on a type. + // Do not use it for a constraint on a method. + if (outermostType.Parent is TypeDeclaration || (outermostType.Parent is Constraint && outermostType.Parent.Parent is TypeDeclaration)) + return NameLookupMode.BaseTypeReference; + } + return NameLookupMode.Type; + } /// /// Creates a pointer type from this type by nesting it in a . @@ -215,5 +261,20 @@ namespace ICSharpCode.NRefactory.CSharp { return new TypeReferenceExpression { Type = this }.Invoke(methodName, typeArguments, arguments); } + + /// + /// Creates a simple AstType from a dotted name. + /// Does not support generics, arrays, etc. - just simple dotted names, + /// e.g. namespace names. + /// + public static AstType Create(string dottedName) + { + string[] parts = dottedName.Split('.'); + AstType type = new SimpleType(parts[0]); + for (int i = 1; i < parts.Length; i++) { + type = new MemberType(type, parts[i]); + } + return type; + } } } diff --git a/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/CSharpModifierToken.cs b/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/CSharpModifierToken.cs index ac59c7246..1a46006f2 100644 --- a/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/CSharpModifierToken.cs +++ b/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/CSharpModifierToken.cs @@ -40,14 +40,14 @@ namespace ICSharpCode.NRefactory.CSharp this.modifier = value; } } - - protected override int TokenLength { + + public override TextLocation EndLocation { get { - return GetModifierName (modifier).Length; + return new TextLocation (StartLocation.Line, StartLocation.Column + GetModifierLength (Modifier)); } } - - public override string GetText (CSharpFormattingOptions formattingOptions = null) + + public override string ToString(CSharpFormattingOptions formattingOptions) { return GetModifierName (Modifier); } @@ -75,7 +75,7 @@ namespace ICSharpCode.NRefactory.CSharp get { return allModifiers; } } - public CSharpModifierToken (TextLocation location, Modifiers modifier) : base (location) + public CSharpModifierToken (TextLocation location, Modifiers modifier) : base (location, null) { this.Modifier = modifier; } @@ -124,5 +124,95 @@ namespace ICSharpCode.NRefactory.CSharp throw new NotSupportedException("Invalid value for Modifiers"); } } + + public static int GetModifierLength(Modifiers modifier) + { + switch (modifier) { + case Modifiers.Private: + return "private".Length; + case Modifiers.Internal: + return "internal".Length; + case Modifiers.Protected: + return "protected".Length; + case Modifiers.Public: + return "public".Length; + case Modifiers.Abstract: + return "abstract".Length; + case Modifiers.Virtual: + return "virtual".Length; + case Modifiers.Sealed: + return "sealed".Length; + case Modifiers.Static: + return "static".Length; + case Modifiers.Override: + return "override".Length; + case Modifiers.Readonly: + return "readonly".Length; + case Modifiers.Const: + return "const".Length; + case Modifiers.New: + return "new".Length; + case Modifiers.Partial: + return "partial".Length; + case Modifiers.Extern: + return "extern".Length; + case Modifiers.Volatile: + return "volatile".Length; + case Modifiers.Unsafe: + return "unsafe".Length; + case Modifiers.Async: + return "async".Length; + case Modifiers.Any: + // even though it's used for pattern matching only, 'any' needs to be in this list to be usable in the AST + return "any".Length; + default: + throw new NotSupportedException("Invalid value for Modifiers"); + } + } + + public static Modifiers GetModifierValue(string modifier) + { + switch (modifier) { + case "private": + return Modifiers.Private; + case "internal": + return Modifiers.Internal; + case "protected": + return Modifiers.Protected; + case "public": + return Modifiers.Public; + case "abstract": + return Modifiers.Abstract; + case "virtual": + return Modifiers.Virtual; + case "sealed": + return Modifiers.Sealed; + case "static": + return Modifiers.Static; + case "override": + return Modifiers.Override; + case "readonly": + return Modifiers.Readonly; + case "const": + return Modifiers.Const; + case "new": + return Modifiers.New; + case "partial": + return Modifiers.Partial; + case "extern": + return Modifiers.Extern; + case "volatile": + return Modifiers.Volatile; + case "unsafe": + return Modifiers.Unsafe; + case "async": + return Modifiers.Async; + case "any": + // even though it's used for pattern matching only, 'any' needs to be in this list to be usable in the AST + return Modifiers.Any; + default: + throw new NotSupportedException("Invalid value for Modifiers"); + } + } } } \ No newline at end of file diff --git a/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/CSharpTokenNode.cs b/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/CSharpTokenNode.cs index 04910ae18..713f664b3 100644 --- a/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/CSharpTokenNode.cs +++ b/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/CSharpTokenNode.cs @@ -44,22 +44,23 @@ namespace ICSharpCode.NRefactory.CSharp } } - public NullCSharpTokenNode () : base (TextLocation.Empty) + public NullCSharpTokenNode () : base (TextLocation.Empty, null) { } public override void AcceptVisitor (IAstVisitor visitor) { + visitor.VisitNullNode(this); } - + public override T AcceptVisitor (IAstVisitor visitor) { - return default (T); + return visitor.VisitNullNode(this); } public override S AcceptVisitor (IAstVisitor visitor, T data) { - return default (S); + return visitor.VisitNullNode(this, data); } protected internal override bool DoMatch(AstNode other, PatternMatching.Match match) @@ -80,12 +81,10 @@ namespace ICSharpCode.NRefactory.CSharp return startLocation; } } - - protected virtual int TokenLength { + + int TokenLength { get { - if (!(Role is TokenRole)) - return 0; - return ((TokenRole)Role).Length; + return TokenRole.TokenLengths [(int)(this.flags >> AstNodeFlagsUsedBits)]; } } @@ -94,17 +93,17 @@ namespace ICSharpCode.NRefactory.CSharp return new TextLocation (StartLocation.Line, StartLocation.Column + TokenLength); } } - - public CSharpTokenNode (TextLocation location) + + public CSharpTokenNode (TextLocation location, TokenRole role) { this.startLocation = location; + if (role != null) + this.flags |= role.TokenIndex << AstNodeFlagsUsedBits; } - - public override string GetText (CSharpFormattingOptions formattingOptions = null) + + public override string ToString(CSharpFormattingOptions formattingOptions) { - if (!(Role is TokenRole)) - return null; - return ((TokenRole)Role).Token; + return TokenRole.Tokens [(int)(this.flags >> AstNodeFlagsUsedBits)]; } public override void AcceptVisitor (IAstVisitor visitor) @@ -127,11 +126,6 @@ namespace ICSharpCode.NRefactory.CSharp CSharpTokenNode o = other as CSharpTokenNode; return o != null && !o.IsNull && !(o is CSharpModifierToken); } - - public override string ToString () - { - return string.Format ("[CSharpTokenNode: StartLocation={0}, EndLocation={1}, Role={2}]", StartLocation, EndLocation, Role); - } } } diff --git a/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/CSharpUtil.cs b/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/CSharpUtil.cs index e266c1a71..a2a07ad6e 100644 --- a/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/CSharpUtil.cs +++ b/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/CSharpUtil.cs @@ -25,51 +25,87 @@ // THE SOFTWARE. using System; using ICSharpCode.NRefactory.CSharp; +using ICSharpCode.NRefactory.PatternMatching; namespace ICSharpCode.NRefactory.CSharp { public static class CSharpUtil { - public static Expression InvertCondition (Expression condition) + /// + /// Inverts a boolean condition. Note: The condition object can be frozen (from AST) it's cloned internally. + /// + /// The condition to invert. + public static Expression InvertCondition(Expression condition) { - return InvertConditionInternal (condition.Clone ()); + return InvertConditionInternal(condition); } - static Expression InvertConditionInternal (Expression condition) + static Expression InvertConditionInternal(Expression condition) { if (condition is ParenthesizedExpression) { - ((ParenthesizedExpression)condition).Expression = InvertCondition (((ParenthesizedExpression)condition).Expression); - return condition; + return new ParenthesizedExpression(InvertCondition(((ParenthesizedExpression)condition).Expression)); } if (condition is UnaryOperatorExpression) { var uOp = (UnaryOperatorExpression)condition; - if (uOp.Operator == UnaryOperatorType.Not) - return uOp.Expression; - return new UnaryOperatorExpression (UnaryOperatorType.Not, uOp); + if (uOp.Operator == UnaryOperatorType.Not) { + if (!(uOp.Parent is Expression)) + return GetInnerMostExpression(uOp.Expression).Clone(); + return uOp.Expression.Clone(); + } + return new UnaryOperatorExpression(UnaryOperatorType.Not, uOp.Clone()); } if (condition is BinaryOperatorExpression) { var bOp = (BinaryOperatorExpression)condition; - var negatedOp = NegateRelationalOperator (bOp.Operator); - if (negatedOp == BinaryOperatorType.Any) - return new UnaryOperatorExpression (UnaryOperatorType.Not, new ParenthesizedExpression (condition)); - bOp.Operator = negatedOp; - return bOp; + + if ((bOp.Operator == BinaryOperatorType.ConditionalAnd) || (bOp.Operator == BinaryOperatorType.ConditionalOr)) { + return new BinaryOperatorExpression(InvertCondition(bOp.Left), NegateConditionOperator(bOp.Operator), InvertCondition(bOp.Right)); + } else if ((bOp.Operator == BinaryOperatorType.Equality) || (bOp.Operator == BinaryOperatorType.InEquality) || (bOp.Operator == BinaryOperatorType.GreaterThan) + || (bOp.Operator == BinaryOperatorType.GreaterThanOrEqual) || (bOp.Operator == BinaryOperatorType.LessThan) || + (bOp.Operator == BinaryOperatorType.LessThanOrEqual)) { + return new BinaryOperatorExpression(bOp.Left.Clone(), NegateRelationalOperator(bOp.Operator), bOp.Right.Clone()); + } else { + var negatedOp = NegateRelationalOperator(bOp.Operator); + if (negatedOp == BinaryOperatorType.Any) + return new UnaryOperatorExpression(UnaryOperatorType.Not, new ParenthesizedExpression(condition.Clone())); + bOp = (BinaryOperatorExpression)bOp.Clone(); + bOp.Operator = negatedOp; + return bOp; + } } if (condition is ConditionalExpression) { - var cEx = condition as ConditionalExpression; - cEx.Condition = InvertCondition (cEx.Condition); + var cEx = condition.Clone() as ConditionalExpression; + cEx.Condition = InvertCondition(cEx.Condition); return cEx; } if (condition is PrimitiveExpression) { var pex = condition as PrimitiveExpression; if (pex.Value is bool) { - return new PrimitiveExpression (!((bool)pex.Value)); + return new PrimitiveExpression(!((bool)pex.Value)); } } - return new UnaryOperatorExpression (UnaryOperatorType.Not, condition); + return new UnaryOperatorExpression(UnaryOperatorType.Not, AddParensForUnaryExpressionIfRequired(condition.Clone())); + } + + /// + /// When negating an expression this is required, otherwise you would end up with + /// a or b -> !a or b + /// + internal static Expression AddParensForUnaryExpressionIfRequired(Expression expression) + { + if ((expression is BinaryOperatorExpression) || + (expression is AssignmentExpression) || + (expression is CastExpression) || + (expression is AsExpression) || + (expression is IsExpression) || + (expression is LambdaExpression) || + (expression is ConditionalExpression)) { + return new ParenthesizedExpression(expression); + } + + return expression; } /// @@ -78,7 +114,7 @@ namespace ICSharpCode.NRefactory.CSharp /// /// negation of the specified relational operator, or BinaryOperatorType.Any if it's not a relational operator /// - public static BinaryOperatorType NegateRelationalOperator (BinaryOperatorType op) + public static BinaryOperatorType NegateRelationalOperator(BinaryOperatorType op) { switch (op) { case BinaryOperatorType.GreaterThan: @@ -93,9 +129,52 @@ namespace ICSharpCode.NRefactory.CSharp return BinaryOperatorType.GreaterThanOrEqual; case BinaryOperatorType.LessThanOrEqual: return BinaryOperatorType.GreaterThan; + case BinaryOperatorType.ConditionalOr: + return BinaryOperatorType.ConditionalAnd; + case BinaryOperatorType.ConditionalAnd: + return BinaryOperatorType.ConditionalOr; } return BinaryOperatorType.Any; } + + /// + /// Returns true, if the specified operator is a relational operator + /// + public static bool IsRelationalOperator(BinaryOperatorType op) + { + return NegateRelationalOperator(op) != BinaryOperatorType.Any; + } + + /// + /// Get negation of the condition operator + /// + /// + /// negation of the specified condition operator, or BinaryOperatorType.Any if it's not a condition operator + /// + public static BinaryOperatorType NegateConditionOperator(BinaryOperatorType op) + { + switch (op) { + case BinaryOperatorType.ConditionalOr: + return BinaryOperatorType.ConditionalAnd; + case BinaryOperatorType.ConditionalAnd: + return BinaryOperatorType.ConditionalOr; + } + return BinaryOperatorType.Any; + } + + public static bool AreConditionsEqual(Expression cond1, Expression cond2) + { + if (cond1 == null || cond2 == null) + return false; + return GetInnerMostExpression(cond1).IsMatch(GetInnerMostExpression(cond2)); + } + + public static Expression GetInnerMostExpression(Expression target) + { + while (target is ParenthesizedExpression) + target = ((ParenthesizedExpression)target).Expression; + return target; + } } } diff --git a/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/ComposedType.cs b/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/ComposedType.cs index 0103937a6..0c0f96c62 100644 --- a/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/ComposedType.cs +++ b/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/ComposedType.cs @@ -47,7 +47,13 @@ namespace ICSharpCode.NRefactory.CSharp return !GetChildByRole(NullableRole).IsNull; } set { - SetChildByRole(NullableRole, value ? new CSharpTokenNode(TextLocation.Empty) : null); + SetChildByRole(NullableRole, value ? new CSharpTokenNode(TextLocation.Empty, null) : null); + } + } + + public CSharpTokenNode NullableSpecifierToken { + get { + return GetChildByRole(NullableRole); } } @@ -64,7 +70,7 @@ namespace ICSharpCode.NRefactory.CSharp d--; } while (d < value) { - InsertChildBefore(GetChildByRole(PointerRole), new CSharpTokenNode(TextLocation.Empty), PointerRole); + InsertChildBefore(GetChildByRole(PointerRole), new CSharpTokenNode(TextLocation.Empty, PointerRole), PointerRole); d++; } } @@ -73,12 +79,16 @@ namespace ICSharpCode.NRefactory.CSharp public AstNodeCollection ArraySpecifiers { get { return GetChildrenByRole (ArraySpecifierRole); } } + + public AstNodeCollection PointerTokens { + get { return GetChildrenByRole (PointerRole); } + } public override void AcceptVisitor (IAstVisitor visitor) { visitor.VisitComposedType (this); } - + public override T AcceptVisitor (IAstVisitor visitor) { return visitor.VisitComposedType (this); @@ -92,10 +102,12 @@ namespace ICSharpCode.NRefactory.CSharp protected internal override bool DoMatch(AstNode other, PatternMatching.Match match) { ComposedType o = other as ComposedType; - return o != null && this.HasNullableSpecifier == o.HasNullableSpecifier && this.PointerRank == o.PointerRank && this.ArraySpecifiers.DoMatch(o.ArraySpecifiers, match); + return o != null && this.HasNullableSpecifier == o.HasNullableSpecifier && this.PointerRank == o.PointerRank + && this.BaseType.DoMatch(o.BaseType, match) + && this.ArraySpecifiers.DoMatch(o.ArraySpecifiers, match); } - - public override string ToString() + + public override string ToString(CSharpFormattingOptions formattingOptions) { StringBuilder b = new StringBuilder(); b.Append(this.BaseType.ToString()); @@ -126,18 +138,20 @@ namespace ICSharpCode.NRefactory.CSharp return this; } - public override ITypeReference ToTypeReference(NameLookupMode lookupMode = NameLookupMode.Type) + public override ITypeReference ToTypeReference(NameLookupMode lookupMode, InterningProvider interningProvider = null) { - ITypeReference t = this.BaseType.ToTypeReference(lookupMode); + if (interningProvider == null) + interningProvider = InterningProvider.Dummy; + ITypeReference t = this.BaseType.ToTypeReference(lookupMode, interningProvider); if (this.HasNullableSpecifier) { - t = NullableType.Create(t); + t = interningProvider.Intern(NullableType.Create(t)); } int pointerRank = this.PointerRank; for (int i = 0; i < pointerRank; i++) { - t = new PointerTypeReference(t); + t = interningProvider.Intern(new PointerTypeReference(t)); } foreach (var a in this.ArraySpecifiers.Reverse()) { - t = new ArrayTypeReference(t, a.Dimensions); + t = interningProvider.Intern(new ArrayTypeReference(t, a.Dimensions)); } return t; } @@ -176,7 +190,7 @@ namespace ICSharpCode.NRefactory.CSharp d--; } while (d < value) { - InsertChildBefore(GetChildByRole(Roles.Comma), new CSharpTokenNode(TextLocation.Empty), Roles.Comma); + InsertChildBefore(GetChildByRole(Roles.Comma), new CSharpTokenNode(TextLocation.Empty, Roles.Comma), Roles.Comma); d++; } } @@ -190,7 +204,7 @@ namespace ICSharpCode.NRefactory.CSharp { visitor.VisitArraySpecifier (this); } - + public override T AcceptVisitor (IAstVisitor visitor) { return visitor.VisitArraySpecifier (this); @@ -206,8 +220,8 @@ namespace ICSharpCode.NRefactory.CSharp ArraySpecifier o = other as ArraySpecifier; return o != null && this.Dimensions == o.Dimensions; } - - public override string ToString() + + public override string ToString(CSharpFormattingOptions formattingOptions) { return "[" + new string(',', this.Dimensions - 1) + "]"; } diff --git a/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/DepthFirstAstVisitor.cs b/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/DepthFirstAstVisitor.cs index 81982caf5..59f006cda 100644 --- a/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/DepthFirstAstVisitor.cs +++ b/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/DepthFirstAstVisitor.cs @@ -44,6 +44,14 @@ namespace ICSharpCode.NRefactory.CSharp } } + public virtual void VisitNullNode(AstNode nullNode) + { + // Should we call VisitChildren here? + // We usually want to ignore null nodes. + // Older NR versions (before VisitNullNode was introduced) didn't call VisitChildren() with null nodes; + // so changing this might break VisitChildren() overrides that expect the node to be part of the AST. + } + public virtual void VisitSyntaxTree (SyntaxTree syntaxTree) { VisitChildren (syntaxTree); @@ -613,12 +621,7 @@ namespace ICSharpCode.NRefactory.CSharp { VisitChildren (namedExpression); } - - public virtual void VisitEmptyExpression (EmptyExpression emptyExpression) - { - VisitChildren (emptyExpression); - } - + public virtual void VisitPatternPlaceholder(AstNode placeholder, PatternMatching.Pattern pattern) { VisitChildren (placeholder); @@ -642,6 +645,15 @@ namespace ICSharpCode.NRefactory.CSharp return default (T); } + public virtual T VisitNullNode(AstNode nullNode) + { + // Should we call VisitChildren here? + // We usually want to ignore null nodes. + // Older NR versions (before VisitNullNode was introduced) didn't call VisitChildren() with null nodes; + // so changing this might break VisitChildren() overrides that expect the node to be part of the AST. + return default (T); + } + public virtual T VisitSyntaxTree (SyntaxTree unit) { return VisitChildren (unit); @@ -1212,11 +1224,6 @@ namespace ICSharpCode.NRefactory.CSharp return VisitChildren (namedExpression); } - public virtual T VisitEmptyExpression (EmptyExpression emptyExpression) - { - return VisitChildren (emptyExpression); - } - public virtual T VisitPatternPlaceholder(AstNode placeholder, PatternMatching.Pattern pattern) { return VisitChildren (placeholder); @@ -1240,6 +1247,15 @@ namespace ICSharpCode.NRefactory.CSharp return default (S); } + public virtual S VisitNullNode(AstNode nullNode, T data) + { + // Should we call VisitChildren here? + // We usually want to ignore null nodes. + // Older NR versions (before VisitNullNode was introduced) didn't call VisitChildren() with null nodes; + // so changing this might break VisitChildren() overrides that expect the node to be part of the AST. + return default (S); + } + public virtual S VisitSyntaxTree (SyntaxTree unit, T data) { return VisitChildren (unit, data); @@ -1810,11 +1826,6 @@ namespace ICSharpCode.NRefactory.CSharp return VisitChildren (namedExpression, data); } - public virtual S VisitEmptyExpression (EmptyExpression emptyExpression, T data) - { - return VisitChildren (emptyExpression, data); - } - public virtual S VisitPatternPlaceholder(AstNode placeholder, PatternMatching.Pattern pattern, T data) { return VisitChildren (placeholder, data); diff --git a/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/DocumentationReference.cs b/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/DocumentationReference.cs index 9c599ce6b..633f921b2 100644 --- a/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/DocumentationReference.cs +++ b/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/DocumentationReference.cs @@ -1,4 +1,4 @@ -// Copyright (c) AlphaSierraPapa for the SharpDevelop Team +// Copyright (c) 2010-2013 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 @@ -29,29 +29,29 @@ namespace ICSharpCode.NRefactory.CSharp public static readonly Role DeclaringTypeRole = new Role("DeclaringType", AstType.Null); public static readonly Role ConversionOperatorReturnTypeRole = new Role("ConversionOperatorReturnType", AstType.Null); - EntityType entityType; + SymbolKind symbolKind; OperatorType operatorType; bool hasParameterList; /// /// Gets/Sets the entity type. /// Possible values are: - /// EntityType.Operator for operators, - /// EntityType.Indexer for indexers, - /// EntityType.TypeDefinition for references to primitive types, - /// and EntityType.None for everything else. + /// SymbolKind.Operator for operators, + /// SymbolKind.Indexer for indexers, + /// SymbolKind.TypeDefinition for references to primitive types, + /// and SymbolKind.None for everything else. /// - public EntityType EntityType { - get { return entityType; } + public SymbolKind SymbolKind { + get { return symbolKind; } set { ThrowIfFrozen(); - entityType = value; + symbolKind = value; } } /// /// Gets/Sets the operator type. - /// This property is only used when EntityType==Operator. + /// This property is only used when SymbolKind==Operator. /// public OperatorType OperatorType { get { return operatorType; } @@ -86,7 +86,7 @@ namespace ICSharpCode.NRefactory.CSharp /// /// Gets/sets the member name. - /// This property is only used when EntityType==None. + /// This property is only used when SymbolKind==None. /// public string MemberName { get { return GetChildByRole(Roles.Identifier).Name; } @@ -95,7 +95,7 @@ namespace ICSharpCode.NRefactory.CSharp /// /// Gets/Sets the return type of conversion operators. - /// This property is only used when EntityType==Operator and OperatorType is explicit or implicit. + /// This property is only used when SymbolKind==Operator and OperatorType is explicit or implicit. /// public AstType ConversionOperatorReturnType { get { return GetChildByRole(ConversionOperatorReturnTypeRole); } @@ -113,16 +113,16 @@ namespace ICSharpCode.NRefactory.CSharp protected internal override bool DoMatch(AstNode other, ICSharpCode.NRefactory.PatternMatching.Match match) { DocumentationReference o = other as DocumentationReference; - if (!(o != null && this.EntityType == o.EntityType && this.HasParameterList == o.HasParameterList)) + if (!(o != null && this.SymbolKind == o.SymbolKind && this.HasParameterList == o.HasParameterList)) return false; - if (this.EntityType == EntityType.Operator) { + if (this.SymbolKind == SymbolKind.Operator) { if (this.OperatorType != o.OperatorType) return false; if (this.OperatorType == OperatorType.Implicit || this.OperatorType == OperatorType.Explicit) { if (!this.ConversionOperatorReturnType.DoMatch(o.ConversionOperatorReturnType, match)) return false; } - } else if (this.EntityType == EntityType.None) { + } else if (this.SymbolKind == SymbolKind.None) { if (!MatchString(this.MemberName, o.MemberName)) return false; if (!this.TypeArguments.DoMatch(o.TypeArguments, match)) diff --git a/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/ErrorNode.cs b/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/ErrorNode.cs index ee5f88521..e402a8047 100644 --- a/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/ErrorNode.cs +++ b/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/ErrorNode.cs @@ -78,8 +78,8 @@ namespace ICSharpCode.NRefactory.CSharp var o = other as ErrorNode; return o != null; } - - public override string ToString () + + public override string ToString(CSharpFormattingOptions formattingOptions) { return "[ErrorNode]"; } diff --git a/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/Expressions/AnonymousMethodExpression.cs b/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/Expressions/AnonymousMethodExpression.cs index 07de16197..e8de95431 100644 --- a/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/Expressions/AnonymousMethodExpression.cs +++ b/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/Expressions/AnonymousMethodExpression.cs @@ -48,7 +48,7 @@ namespace ICSharpCode.NRefactory.CSharp bool hasParameterList; public bool HasParameterList { - get { return hasParameterList; } + get { return hasParameterList || Parameters.Any(); } set { ThrowIfFrozen(); hasParameterList = value; } } @@ -80,6 +80,7 @@ namespace ICSharpCode.NRefactory.CSharp public AnonymousMethodExpression (BlockStatement body, IEnumerable parameters = null) { if (parameters != null) { + hasParameterList = true; foreach (var parameter in parameters) { AddChild (parameter, Roles.Parameter); } diff --git a/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/Expressions/ArrayCreateExpression.cs b/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/Expressions/ArrayCreateExpression.cs index c9f1b2a62..3720a3fc8 100644 --- a/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/Expressions/ArrayCreateExpression.cs +++ b/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/Expressions/ArrayCreateExpression.cs @@ -1,4 +1,4 @@ -// Copyright (c) AlphaSierraPapa for the SharpDevelop Team +// Copyright (c) 2010-2013 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 diff --git a/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/Expressions/ArrayInitializerExpression.cs b/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/Expressions/ArrayInitializerExpression.cs index 0bfc1c1d7..fa3246f92 100644 --- a/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/Expressions/ArrayInitializerExpression.cs +++ b/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/Expressions/ArrayInitializerExpression.cs @@ -72,16 +72,17 @@ namespace ICSharpCode.NRefactory.CSharp public override void AcceptVisitor (IAstVisitor visitor) { + visitor.VisitNullNode(this); } public override T AcceptVisitor (IAstVisitor visitor) { - return default (T); + return visitor.VisitNullNode(this); } public override S AcceptVisitor (IAstVisitor visitor, T data) { - return default (S); + return visitor.VisitNullNode(this, data); } protected internal override bool DoMatch(AstNode other, PatternMatching.Match match) diff --git a/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/Expressions/AsExpression.cs b/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/Expressions/AsExpression.cs index cf9cfb4f9..5a7b5ac5d 100644 --- a/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/Expressions/AsExpression.cs +++ b/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/Expressions/AsExpression.cs @@ -23,6 +23,8 @@ // 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.Collections.Generic; +using System; namespace ICSharpCode.NRefactory.CSharp { @@ -56,7 +58,7 @@ namespace ICSharpCode.NRefactory.CSharp AddChild (expression, Roles.Expression); AddChild (type, Roles.Type); } - + public override void AcceptVisitor (IAstVisitor visitor) { visitor.VisitAsExpression (this); @@ -77,6 +79,72 @@ namespace ICSharpCode.NRefactory.CSharp AsExpression o = other as AsExpression; return o != null && this.Expression.DoMatch(o.Expression, match) && this.Type.DoMatch(o.Type, match); } + + #region Builder methods + public override MemberReferenceExpression Member(string memberName) + { + return new MemberReferenceExpression { Target = this, MemberName = memberName }; + } + + public override IndexerExpression Indexer(IEnumerable arguments) + { + IndexerExpression expr = new IndexerExpression(); + expr.Target = new ParenthesizedExpression(this); + expr.Arguments.AddRange(arguments); + return expr; + } + + public override IndexerExpression Indexer(params Expression[] arguments) + { + IndexerExpression expr = new IndexerExpression(); + expr.Target = new ParenthesizedExpression(this); + expr.Arguments.AddRange(arguments); + return expr; + } + + public override InvocationExpression Invoke(string methodName, IEnumerable typeArguments, IEnumerable arguments) + { + InvocationExpression ie = new InvocationExpression(); + MemberReferenceExpression mre = new MemberReferenceExpression(); + mre.Target = new ParenthesizedExpression(this); + mre.MemberName = methodName; + mre.TypeArguments.AddRange(typeArguments); + ie.Target = mre; + ie.Arguments.AddRange(arguments); + return ie; + } + + public override InvocationExpression Invoke(IEnumerable arguments) + { + InvocationExpression ie = new InvocationExpression(); + ie.Target = new ParenthesizedExpression(this); + ie.Arguments.AddRange(arguments); + return ie; + } + + public override InvocationExpression Invoke(params Expression[] arguments) + { + InvocationExpression ie = new InvocationExpression(); + ie.Target = new ParenthesizedExpression(this); + ie.Arguments.AddRange(arguments); + return ie; + } + + public override CastExpression CastTo(AstType type) + { + return new CastExpression { Type = type, Expression = new ParenthesizedExpression(this) }; + } + + public override AsExpression CastAs(AstType type) + { + return new AsExpression { Type = type, Expression = new ParenthesizedExpression(this) }; + } + + public override IsExpression IsType(AstType type) + { + return new IsExpression { Type = type, Expression = new ParenthesizedExpression(this) }; + } + #endregion } } diff --git a/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/Expressions/AssignmentExpression.cs b/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/Expressions/AssignmentExpression.cs index 14021d323..95d0cdf28 100644 --- a/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/Expressions/AssignmentExpression.cs +++ b/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/Expressions/AssignmentExpression.cs @@ -26,6 +26,7 @@ using System; using System.Linq.Expressions; +using System.Collections.Generic; namespace ICSharpCode.NRefactory.CSharp { @@ -201,6 +202,72 @@ namespace ICSharpCode.NRefactory.CSharp throw new NotSupportedException("Invalid value for AssignmentOperatorType"); } } + + #region Builder methods + public override MemberReferenceExpression Member(string memberName) + { + return new MemberReferenceExpression { Target = this, MemberName = memberName }; + } + + public override IndexerExpression Indexer(IEnumerable arguments) + { + IndexerExpression expr = new IndexerExpression(); + expr.Target = new ParenthesizedExpression(this); + expr.Arguments.AddRange(arguments); + return expr; + } + + public override IndexerExpression Indexer(params Expression[] arguments) + { + IndexerExpression expr = new IndexerExpression(); + expr.Target = new ParenthesizedExpression(this); + expr.Arguments.AddRange(arguments); + return expr; + } + + public override InvocationExpression Invoke(string methodName, IEnumerable typeArguments, IEnumerable arguments) + { + InvocationExpression ie = new InvocationExpression(); + MemberReferenceExpression mre = new MemberReferenceExpression(); + mre.Target = new ParenthesizedExpression(this); + mre.MemberName = methodName; + mre.TypeArguments.AddRange(typeArguments); + ie.Target = mre; + ie.Arguments.AddRange(arguments); + return ie; + } + + public override InvocationExpression Invoke(IEnumerable arguments) + { + InvocationExpression ie = new InvocationExpression(); + ie.Target = new ParenthesizedExpression(this); + ie.Arguments.AddRange(arguments); + return ie; + } + + public override InvocationExpression Invoke(params Expression[] arguments) + { + InvocationExpression ie = new InvocationExpression(); + ie.Target = new ParenthesizedExpression(this); + ie.Arguments.AddRange(arguments); + return ie; + } + + public override CastExpression CastTo(AstType type) + { + return new CastExpression { Type = type, Expression = new ParenthesizedExpression(this) }; + } + + public override AsExpression CastAs(AstType type) + { + return new AsExpression { Type = type, Expression = new ParenthesizedExpression(this) }; + } + + public override IsExpression IsType(AstType type) + { + return new IsExpression { Type = type, Expression = new ParenthesizedExpression(this) }; + } + #endregion } public enum AssignmentOperatorType diff --git a/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/Expressions/BinaryOperatorExpression.cs b/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/Expressions/BinaryOperatorExpression.cs index 819d90f53..e4408e184 100644 --- a/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/Expressions/BinaryOperatorExpression.cs +++ b/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/Expressions/BinaryOperatorExpression.cs @@ -26,6 +26,7 @@ using System; using System.Linq.Expressions; +using System.Collections.Generic; namespace ICSharpCode.NRefactory.CSharp { @@ -200,6 +201,71 @@ namespace ICSharpCode.NRefactory.CSharp throw new NotSupportedException("Invalid value for BinaryOperatorType"); } } + #region Builder methods + public override MemberReferenceExpression Member(string memberName) + { + return new MemberReferenceExpression { Target = this, MemberName = memberName }; + } + + public override IndexerExpression Indexer(IEnumerable arguments) + { + IndexerExpression expr = new IndexerExpression(); + expr.Target = new ParenthesizedExpression(this); + expr.Arguments.AddRange(arguments); + return expr; + } + + public override IndexerExpression Indexer(params Expression[] arguments) + { + IndexerExpression expr = new IndexerExpression(); + expr.Target = new ParenthesizedExpression(this); + expr.Arguments.AddRange(arguments); + return expr; + } + + public override InvocationExpression Invoke(string methodName, IEnumerable typeArguments, IEnumerable arguments) + { + InvocationExpression ie = new InvocationExpression(); + MemberReferenceExpression mre = new MemberReferenceExpression(); + mre.Target = new ParenthesizedExpression(this); + mre.MemberName = methodName; + mre.TypeArguments.AddRange(typeArguments); + ie.Target = mre; + ie.Arguments.AddRange(arguments); + return ie; + } + + public override InvocationExpression Invoke(IEnumerable arguments) + { + InvocationExpression ie = new InvocationExpression(); + ie.Target = new ParenthesizedExpression(this); + ie.Arguments.AddRange(arguments); + return ie; + } + + public override InvocationExpression Invoke(params Expression[] arguments) + { + InvocationExpression ie = new InvocationExpression(); + ie.Target = new ParenthesizedExpression(this); + ie.Arguments.AddRange(arguments); + return ie; + } + + public override CastExpression CastTo(AstType type) + { + return new CastExpression { Type = type, Expression = new ParenthesizedExpression(this) }; + } + + public override AsExpression CastAs(AstType type) + { + return new AsExpression { Type = type, Expression = new ParenthesizedExpression(this) }; + } + + public override IsExpression IsType(AstType type) + { + return new IsExpression { Type = type, Expression = new ParenthesizedExpression(this) }; + } + #endregion } public enum BinaryOperatorType diff --git a/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/Expressions/CastExpression.cs b/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/Expressions/CastExpression.cs index 96f41bcf3..e771d18fe 100644 --- a/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/Expressions/CastExpression.cs +++ b/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/Expressions/CastExpression.cs @@ -23,6 +23,8 @@ // 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.Collections.Generic; +using System; namespace ICSharpCode.NRefactory.CSharp { @@ -52,13 +54,13 @@ namespace ICSharpCode.NRefactory.CSharp public CastExpression () { } - + public CastExpression (AstType castToType, Expression expression) { AddChild (castToType, Roles.Type); AddChild (expression, Roles.Expression); } - + public override void AcceptVisitor (IAstVisitor visitor) { visitor.VisitCastExpression (this); @@ -79,6 +81,72 @@ namespace ICSharpCode.NRefactory.CSharp CastExpression o = other as CastExpression; return o != null && this.Type.DoMatch(o.Type, match) && this.Expression.DoMatch(o.Expression, match); } + + #region Builder methods + public override MemberReferenceExpression Member(string memberName) + { + return new MemberReferenceExpression { Target = this, MemberName = memberName }; + } + + public override IndexerExpression Indexer(IEnumerable arguments) + { + IndexerExpression expr = new IndexerExpression(); + expr.Target = new ParenthesizedExpression(this); + expr.Arguments.AddRange(arguments); + return expr; + } + + public override IndexerExpression Indexer(params Expression[] arguments) + { + IndexerExpression expr = new IndexerExpression(); + expr.Target = new ParenthesizedExpression(this); + expr.Arguments.AddRange(arguments); + return expr; + } + + public override InvocationExpression Invoke(string methodName, IEnumerable typeArguments, IEnumerable arguments) + { + InvocationExpression ie = new InvocationExpression(); + MemberReferenceExpression mre = new MemberReferenceExpression(); + mre.Target = new ParenthesizedExpression(this); + mre.MemberName = methodName; + mre.TypeArguments.AddRange(typeArguments); + ie.Target = mre; + ie.Arguments.AddRange(arguments); + return ie; + } + + public override InvocationExpression Invoke(IEnumerable arguments) + { + InvocationExpression ie = new InvocationExpression(); + ie.Target = new ParenthesizedExpression(this); + ie.Arguments.AddRange(arguments); + return ie; + } + + public override InvocationExpression Invoke(params Expression[] arguments) + { + InvocationExpression ie = new InvocationExpression(); + ie.Target = new ParenthesizedExpression(this); + ie.Arguments.AddRange(arguments); + return ie; + } + + public override CastExpression CastTo(AstType type) + { + return new CastExpression { Type = type, Expression = new ParenthesizedExpression(this) }; + } + + public override AsExpression CastAs(AstType type) + { + return new AsExpression { Type = type, Expression = new ParenthesizedExpression(this) }; + } + + public override IsExpression IsType(AstType type) + { + return new IsExpression { Type = type, Expression = new ParenthesizedExpression(this) }; + } + #endregion } } diff --git a/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/Expressions/ConditionalExpression.cs b/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/Expressions/ConditionalExpression.cs index fb2d5cb59..4367a0cce 100644 --- a/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/Expressions/ConditionalExpression.cs +++ b/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/Expressions/ConditionalExpression.cs @@ -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.Collections.Generic; namespace ICSharpCode.NRefactory.CSharp { @@ -91,5 +92,71 @@ namespace ICSharpCode.NRefactory.CSharp ConditionalExpression o = other as ConditionalExpression; return o != null && this.Condition.DoMatch(o.Condition, match) && this.TrueExpression.DoMatch(o.TrueExpression, match) && this.FalseExpression.DoMatch(o.FalseExpression, match); } + + #region Builder methods + public override MemberReferenceExpression Member(string memberName) + { + return new MemberReferenceExpression { Target = this, MemberName = memberName }; + } + + public override IndexerExpression Indexer(IEnumerable arguments) + { + IndexerExpression expr = new IndexerExpression(); + expr.Target = new ParenthesizedExpression(this); + expr.Arguments.AddRange(arguments); + return expr; + } + + public override IndexerExpression Indexer(params Expression[] arguments) + { + IndexerExpression expr = new IndexerExpression(); + expr.Target = new ParenthesizedExpression(this); + expr.Arguments.AddRange(arguments); + return expr; + } + + public override InvocationExpression Invoke(string methodName, IEnumerable typeArguments, IEnumerable arguments) + { + InvocationExpression ie = new InvocationExpression(); + MemberReferenceExpression mre = new MemberReferenceExpression(); + mre.Target = new ParenthesizedExpression(this); + mre.MemberName = methodName; + mre.TypeArguments.AddRange(typeArguments); + ie.Target = mre; + ie.Arguments.AddRange(arguments); + return ie; + } + + public override InvocationExpression Invoke(IEnumerable arguments) + { + InvocationExpression ie = new InvocationExpression(); + ie.Target = new ParenthesizedExpression(this); + ie.Arguments.AddRange(arguments); + return ie; + } + + public override InvocationExpression Invoke(params Expression[] arguments) + { + InvocationExpression ie = new InvocationExpression(); + ie.Target = new ParenthesizedExpression(this); + ie.Arguments.AddRange(arguments); + return ie; + } + + public override CastExpression CastTo(AstType type) + { + return new CastExpression { Type = type, Expression = new ParenthesizedExpression(this) }; + } + + public override AsExpression CastAs(AstType type) + { + return new AsExpression { Type = type, Expression = new ParenthesizedExpression(this) }; + } + + public override IsExpression IsType(AstType type) + { + return new IsExpression { Type = type, Expression = new ParenthesizedExpression(this) }; + } + #endregion } } diff --git a/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/Expressions/ErrorExpression.cs b/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/Expressions/ErrorExpression.cs index bd6506c81..163204448 100644 --- a/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/Expressions/ErrorExpression.cs +++ b/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/Expressions/ErrorExpression.cs @@ -27,6 +27,42 @@ using System; namespace ICSharpCode.NRefactory.CSharp { + [Obsolete("This class is obsolete. Remove all referencing code.")] + public class EmptyExpression : AstNode + { + #region implemented abstract members of AstNode + + public override void AcceptVisitor(IAstVisitor visitor) + { + throw new NotImplementedException(); + } + + public override T AcceptVisitor(IAstVisitor visitor) + { + throw new NotImplementedException(); + } + + public override S AcceptVisitor(IAstVisitor visitor, T data) + { + throw new NotImplementedException(); + } + + protected internal override bool DoMatch(AstNode other, ICSharpCode.NRefactory.PatternMatching.Match match) + { + throw new NotImplementedException(); + } + + public override NodeType NodeType { + get { + throw new NotImplementedException(); + } + } + + #endregion + + + } + public class ErrorExpression : Expression { TextLocation location; @@ -43,6 +79,11 @@ namespace ICSharpCode.NRefactory.CSharp } } + public string Error { + get; + private set; + } + public ErrorExpression () { } @@ -51,7 +92,18 @@ namespace ICSharpCode.NRefactory.CSharp { this.location = location; } - + + public ErrorExpression (string error) + { + this.Error = error; + } + + public ErrorExpression (string error, TextLocation location) + { + this.location = location; + this.Error = error; + } + public override void AcceptVisitor (IAstVisitor visitor) { // nothing diff --git a/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/Expressions/Expression.cs b/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/Expressions/Expression.cs index d9bbed466..22962a606 100644 --- a/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/Expressions/Expression.cs +++ b/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/Expressions/Expression.cs @@ -1,4 +1,4 @@ -// Copyright (c) AlphaSierraPapa for the SharpDevelop Team +// Copyright (c) 2010-2013 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 @@ -43,16 +43,17 @@ namespace ICSharpCode.NRefactory.CSharp public override void AcceptVisitor (IAstVisitor visitor) { + visitor.VisitNullNode(this); } public override T AcceptVisitor (IAstVisitor visitor) { - return default (T); + return visitor.VisitNullNode(this); } public override S AcceptVisitor (IAstVisitor visitor, T data) { - return default (S); + return visitor.VisitNullNode(this, data); } protected internal override bool DoMatch(AstNode other, PatternMatching.Match match) @@ -118,13 +119,7 @@ namespace ICSharpCode.NRefactory.CSharp { return (Expression)base.Clone(); } - - // Make debugging easier by giving Expressions a ToString() implementation - public override string ToString() - { - return DebugToString(); - } - + public Expression ReplaceWith(Func replaceFunction) { if (replaceFunction == null) @@ -136,7 +131,7 @@ namespace ICSharpCode.NRefactory.CSharp /// /// Builds an member reference expression using this expression as target. /// - public MemberReferenceExpression Member(string memberName) + public virtual MemberReferenceExpression Member(string memberName) { return new MemberReferenceExpression { Target = this, MemberName = memberName }; } @@ -144,7 +139,7 @@ namespace ICSharpCode.NRefactory.CSharp /// /// Builds an indexer expression using this expression as target. /// - public IndexerExpression Indexer(IEnumerable arguments) + public virtual IndexerExpression Indexer(IEnumerable arguments) { IndexerExpression expr = new IndexerExpression(); expr.Target = this; @@ -155,7 +150,7 @@ namespace ICSharpCode.NRefactory.CSharp /// /// Builds an indexer expression using this expression as target. /// - public IndexerExpression Indexer(params Expression[] arguments) + public virtual IndexerExpression Indexer(params Expression[] arguments) { IndexerExpression expr = new IndexerExpression(); expr.Target = this; @@ -166,7 +161,7 @@ namespace ICSharpCode.NRefactory.CSharp /// /// Builds an invocation expression using this expression as target. /// - public InvocationExpression Invoke(string methodName, IEnumerable arguments) + public virtual InvocationExpression Invoke(string methodName, IEnumerable arguments) { return Invoke(methodName, null, arguments); } @@ -174,7 +169,7 @@ namespace ICSharpCode.NRefactory.CSharp /// /// Builds an invocation expression using this expression as target. /// - public InvocationExpression Invoke(string methodName, params Expression[] arguments) + public virtual InvocationExpression Invoke(string methodName, params Expression[] arguments) { return Invoke(methodName, null, arguments); } @@ -182,7 +177,7 @@ namespace ICSharpCode.NRefactory.CSharp /// /// Builds an invocation expression using this expression as target. /// - public InvocationExpression Invoke(string methodName, IEnumerable typeArguments, IEnumerable arguments) + public virtual InvocationExpression Invoke(string methodName, IEnumerable typeArguments, IEnumerable arguments) { InvocationExpression ie = new InvocationExpression(); MemberReferenceExpression mre = new MemberReferenceExpression(); @@ -197,7 +192,7 @@ namespace ICSharpCode.NRefactory.CSharp /// /// Builds an invocation expression using this expression as target. /// - public InvocationExpression Invoke(IEnumerable arguments) + public virtual InvocationExpression Invoke(IEnumerable arguments) { InvocationExpression ie = new InvocationExpression(); ie.Target = this; @@ -208,7 +203,7 @@ namespace ICSharpCode.NRefactory.CSharp /// /// Builds an invocation expression using this expression as target. /// - public InvocationExpression Invoke(params Expression[] arguments) + public virtual InvocationExpression Invoke(params Expression[] arguments) { InvocationExpression ie = new InvocationExpression(); ie.Target = this; @@ -216,17 +211,17 @@ namespace ICSharpCode.NRefactory.CSharp return ie; } - public CastExpression CastTo(AstType type) + public virtual CastExpression CastTo(AstType type) { return new CastExpression { Type = type, Expression = this }; } - public AsExpression CastAs(AstType type) + public virtual AsExpression CastAs(AstType type) { return new AsExpression { Type = type, Expression = this }; } - public IsExpression IsType(AstType type) + public virtual IsExpression IsType(AstType type) { return new IsExpression { Type = type, Expression = this }; } diff --git a/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/Expressions/IsExpression.cs b/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/Expressions/IsExpression.cs index 163cef041..791ab25d7 100644 --- a/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/Expressions/IsExpression.cs +++ b/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/Expressions/IsExpression.cs @@ -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.Collections.Generic; namespace ICSharpCode.NRefactory.CSharp { @@ -46,6 +47,17 @@ namespace ICSharpCode.NRefactory.CSharp get { return GetChildByRole(Roles.Type); } set { SetChildByRole(Roles.Type, value); } } + + public IsExpression() + { + } + + public IsExpression (Expression expression, AstType type) + { + AddChild (expression, Roles.Expression); + AddChild (type, Roles.Type); + } + public override void AcceptVisitor (IAstVisitor visitor) { @@ -67,6 +79,72 @@ namespace ICSharpCode.NRefactory.CSharp IsExpression o = other as IsExpression; return o != null && this.Expression.DoMatch(o.Expression, match) && this.Type.DoMatch(o.Type, match); } + + #region Builder methods + public override MemberReferenceExpression Member(string memberName) + { + return new MemberReferenceExpression { Target = this, MemberName = memberName }; + } + + public override IndexerExpression Indexer(IEnumerable arguments) + { + IndexerExpression expr = new IndexerExpression(); + expr.Target = new ParenthesizedExpression(this); + expr.Arguments.AddRange(arguments); + return expr; + } + + public override IndexerExpression Indexer(params Expression[] arguments) + { + IndexerExpression expr = new IndexerExpression(); + expr.Target = new ParenthesizedExpression(this); + expr.Arguments.AddRange(arguments); + return expr; + } + + public override InvocationExpression Invoke(string methodName, IEnumerable typeArguments, IEnumerable arguments) + { + InvocationExpression ie = new InvocationExpression(); + MemberReferenceExpression mre = new MemberReferenceExpression(); + mre.Target = new ParenthesizedExpression(this); + mre.MemberName = methodName; + mre.TypeArguments.AddRange(typeArguments); + ie.Target = mre; + ie.Arguments.AddRange(arguments); + return ie; + } + + public override InvocationExpression Invoke(IEnumerable arguments) + { + InvocationExpression ie = new InvocationExpression(); + ie.Target = new ParenthesizedExpression(this); + ie.Arguments.AddRange(arguments); + return ie; + } + + public override InvocationExpression Invoke(params Expression[] arguments) + { + InvocationExpression ie = new InvocationExpression(); + ie.Target = new ParenthesizedExpression(this); + ie.Arguments.AddRange(arguments); + return ie; + } + + public override CastExpression CastTo(AstType type) + { + return new CastExpression { Type = type, Expression = new ParenthesizedExpression(this) }; + } + + public override AsExpression CastAs(AstType type) + { + return new AsExpression { Type = type, Expression = new ParenthesizedExpression(this) }; + } + + public override IsExpression IsType(AstType type) + { + return new IsExpression { Type = type, Expression = new ParenthesizedExpression(this) }; + } + #endregion } } diff --git a/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/Expressions/LambdaExpression.cs b/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/Expressions/LambdaExpression.cs index 001ffcb32..e85902d84 100644 --- a/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/Expressions/LambdaExpression.cs +++ b/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/Expressions/LambdaExpression.cs @@ -44,10 +44,18 @@ namespace ICSharpCode.NRefactory.CSharp set { ThrowIfFrozen(); isAsync = value; } } + public CSharpTokenNode LParToken { + get { return GetChildByRole (Roles.LPar); } + } + public AstNodeCollection Parameters { get { return GetChildrenByRole (Roles.Parameter); } } + public CSharpTokenNode RParToken { + get { return GetChildByRole (Roles.RPar); } + } + public CSharpTokenNode ArrowToken { get { return GetChildByRole (ArrowRole); } } diff --git a/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/Expressions/MemberReferenceExpression.cs b/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/Expressions/MemberReferenceExpression.cs index 4a433b46d..334c6a260 100644 --- a/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/Expressions/MemberReferenceExpression.cs +++ b/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/Expressions/MemberReferenceExpression.cs @@ -93,7 +93,7 @@ namespace ICSharpCode.NRefactory.CSharp public MemberReferenceExpression (Expression target, string memberName, params AstType[] arguments) : this (target, memberName, (IEnumerable)arguments) { - } + } public override void AcceptVisitor (IAstVisitor visitor) { diff --git a/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/Expressions/NamedArgumentExpression.cs b/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/Expressions/NamedArgumentExpression.cs index 0751afe1e..6b485f015 100644 --- a/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/Expressions/NamedArgumentExpression.cs +++ b/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/Expressions/NamedArgumentExpression.cs @@ -1,4 +1,4 @@ -// Copyright (c) AlphaSierraPapa for the SharpDevelop Team +// Copyright (c) 2010-2013 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 diff --git a/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/Expressions/NullReferenceExpression.cs b/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/Expressions/NullReferenceExpression.cs index a7a3ab7b5..fbfeb6f91 100644 --- a/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/Expressions/NullReferenceExpression.cs +++ b/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/Expressions/NullReferenceExpression.cs @@ -1,6 +1,6 @@ // // NullReferenceExpression.cs -// +// // Author: // Mike Krüger // @@ -38,6 +38,12 @@ namespace ICSharpCode.NRefactory.CSharp } } + internal void SetStartLocation(TextLocation value) + { + ThrowIfFrozen(); + this.location = value; + } + public override TextLocation EndLocation { get { return new TextLocation (location.Line, location.Column + "null".Length); @@ -57,7 +63,7 @@ namespace ICSharpCode.NRefactory.CSharp { visitor.VisitNullReferenceExpression (this); } - + public override T AcceptVisitor (IAstVisitor visitor) { return visitor.VisitNullReferenceExpression (this); diff --git a/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/Expressions/PrimitiveExpression.cs b/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/Expressions/PrimitiveExpression.cs index 9f867fe1e..adfe7c3ba 100644 --- a/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/Expressions/PrimitiveExpression.cs +++ b/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/Expressions/PrimitiveExpression.cs @@ -1,6 +1,6 @@ // // PrimitiveExpression.cs -// +// // Author: // Mike Krüger // @@ -42,10 +42,22 @@ namespace ICSharpCode.NRefactory.CSharp } } + internal void SetStartLocation(TextLocation value) + { + ThrowIfFrozen(); + this.startLocation = value; + this.endLocation = null; + } + string literalValue; + TextLocation? endLocation; public override TextLocation EndLocation { get { - return new TextLocation (StartLocation.Line, StartLocation.Column + literalValue.Length); + if (!endLocation.HasValue) { + endLocation = value is string ? AdvanceLocation (StartLocation, literalValue ?? "") : + new TextLocation (StartLocation.Line, StartLocation.Column + (literalValue ?? "").Length); + } + return endLocation.Value; } } @@ -53,46 +65,56 @@ namespace ICSharpCode.NRefactory.CSharp public object Value { get { return this.value; } - set { - ThrowIfFrozen(); + set { + ThrowIfFrozen(); this.value = value; + literalValue = null; } } + /// Never returns null. public string LiteralValue { + get { return literalValue ?? ""; } + } + + /// Can be null. + public string UnsafeLiteralValue { get { return literalValue; } - set { - if (value == null) - throw new ArgumentNullException(); - ThrowIfFrozen(); - literalValue = value; - } + } + + public void SetValue(object value, string literalValue) + { + if (value == null) + throw new ArgumentNullException(); + ThrowIfFrozen(); + this.value = value; + this.literalValue = literalValue; } public PrimitiveExpression (object value) { this.Value = value; - this.literalValue = ""; + this.literalValue = null; } public PrimitiveExpression (object value, string literalValue) { this.Value = value; - this.literalValue = literalValue ?? ""; + this.literalValue = literalValue; } public PrimitiveExpression (object value, TextLocation startLocation, string literalValue) { this.Value = value; this.startLocation = startLocation; - this.literalValue = literalValue ?? ""; + this.literalValue = literalValue; } public override void AcceptVisitor (IAstVisitor visitor) { visitor.VisitPrimitiveExpression (this); } - + public override T AcceptVisitor (IAstVisitor visitor) { return visitor.VisitPrimitiveExpression (this); @@ -102,6 +124,34 @@ namespace ICSharpCode.NRefactory.CSharp { return visitor.VisitPrimitiveExpression (this, data); } + + unsafe static TextLocation AdvanceLocation(TextLocation startLocation, string str) + { + int line = startLocation.Line; + int col = startLocation.Column; + fixed (char* start = str) { + char* p = start; + char* endPtr = start + str.Length; + while (p < endPtr) { + var nl = NewLine.GetDelimiterLength(*p, () => { + char* nextp = p + 1; + if (nextp < endPtr) + return *nextp; + return '\0'; + }); + if (nl > 0) { + line++; + col = 1; + if (nl == 2) + p++; + } else { + col++; + } + p++; + } + } + return new TextLocation (line, col); + } protected internal override bool DoMatch(AstNode other, PatternMatching.Match match) { diff --git a/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/Expressions/QueryExpression.cs b/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/Expressions/QueryExpression.cs index e5f36ae10..b52f50a47 100644 --- a/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/Expressions/QueryExpression.cs +++ b/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/Expressions/QueryExpression.cs @@ -1,4 +1,4 @@ -// Copyright (c) AlphaSierraPapa for the SharpDevelop Team +// Copyright (c) 2010-2013 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 @@ -38,16 +38,17 @@ namespace ICSharpCode.NRefactory.CSharp public override void AcceptVisitor (IAstVisitor visitor) { + visitor.VisitNullNode(this); } - + public override T AcceptVisitor (IAstVisitor visitor) { - return default (T); + return visitor.VisitNullNode(this); } - + public override S AcceptVisitor (IAstVisitor visitor, T data) { - return default (S); + return visitor.VisitNullNode(this, data); } protected internal override bool DoMatch(AstNode other, PatternMatching.Match match) @@ -81,6 +82,72 @@ namespace ICSharpCode.NRefactory.CSharp QueryExpression o = other as QueryExpression; return o != null && !o.IsNull && this.Clauses.DoMatch(o.Clauses, match); } + + #region Builder methods + public override MemberReferenceExpression Member(string memberName) + { + return new MemberReferenceExpression { Target = this, MemberName = memberName }; + } + + public override IndexerExpression Indexer(IEnumerable arguments) + { + IndexerExpression expr = new IndexerExpression(); + expr.Target = new ParenthesizedExpression(this); + expr.Arguments.AddRange(arguments); + return expr; + } + + public override IndexerExpression Indexer(params Expression[] arguments) + { + IndexerExpression expr = new IndexerExpression(); + expr.Target = new ParenthesizedExpression(this); + expr.Arguments.AddRange(arguments); + return expr; + } + + public override InvocationExpression Invoke(string methodName, IEnumerable typeArguments, IEnumerable arguments) + { + InvocationExpression ie = new InvocationExpression(); + MemberReferenceExpression mre = new MemberReferenceExpression(); + mre.Target = new ParenthesizedExpression(this); + mre.MemberName = methodName; + mre.TypeArguments.AddRange(typeArguments); + ie.Target = mre; + ie.Arguments.AddRange(arguments); + return ie; + } + + public override InvocationExpression Invoke(IEnumerable arguments) + { + InvocationExpression ie = new InvocationExpression(); + ie.Target = new ParenthesizedExpression(this); + ie.Arguments.AddRange(arguments); + return ie; + } + + public override InvocationExpression Invoke(params Expression[] arguments) + { + InvocationExpression ie = new InvocationExpression(); + ie.Target = new ParenthesizedExpression(this); + ie.Arguments.AddRange(arguments); + return ie; + } + + public override CastExpression CastTo(AstType type) + { + return new CastExpression { Type = type, Expression = new ParenthesizedExpression(this) }; + } + + public override AsExpression CastAs(AstType type) + { + return new AsExpression { Type = type, Expression = new ParenthesizedExpression(this) }; + } + + public override IsExpression IsType(AstType type) + { + return new IsExpression { Type = type, Expression = new ParenthesizedExpression(this) }; + } + #endregion } public abstract class QueryClause : AstNode @@ -118,6 +185,10 @@ namespace ICSharpCode.NRefactory.CSharp set { SetChildByRole(PrecedingQueryRole, value); } } + public CSharpTokenNode IntoKeyword { + get { return GetChildByRole (IntoKeywordRole); } + } + public string Identifier { get { return GetChildByRole (Roles.Identifier).Name; @@ -158,6 +229,10 @@ namespace ICSharpCode.NRefactory.CSharp public static readonly TokenRole FromKeywordRole = new TokenRole ("from"); public static readonly TokenRole InKeywordRole = new TokenRole ("in"); + public CSharpTokenNode FromKeyword { + get { return GetChildByRole (FromKeywordRole); } + } + public AstType Type { get { return GetChildByRole (Roles.Type); } set { SetChildByRole (Roles.Type, value); } @@ -176,6 +251,10 @@ namespace ICSharpCode.NRefactory.CSharp get { return GetChildByRole(Roles.Identifier); } } + public CSharpTokenNode InKeyword { + get { return GetChildByRole (InKeywordRole); } + } + public Expression Expression { get { return GetChildByRole (Roles.Expression); } set { SetChildByRole (Roles.Expression, value); } diff --git a/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/Expressions/TypeReferenceExpression.cs b/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/Expressions/TypeReferenceExpression.cs index 129e1364a..84b2d60dc 100644 --- a/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/Expressions/TypeReferenceExpression.cs +++ b/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/Expressions/TypeReferenceExpression.cs @@ -1,4 +1,4 @@ -// Copyright (c) AlphaSierraPapa for the SharpDevelop Team +// Copyright (c) 2010-2013 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 diff --git a/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/Expressions/UnaryOperatorExpression.cs b/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/Expressions/UnaryOperatorExpression.cs index 70d178728..878d6132f 100644 --- a/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/Expressions/UnaryOperatorExpression.cs +++ b/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/Expressions/UnaryOperatorExpression.cs @@ -62,9 +62,10 @@ namespace ICSharpCode.NRefactory.CSharp public CSharpTokenNode OperatorToken { get { return GetChildByRole (GetOperatorRole (Operator)); } } - + + static Expression NoUnaryExpressionError = new ErrorExpression ("No unary expression"); public Expression Expression { - get { return GetChildByRole (Roles.Expression); } + get { return GetChildByRole (Roles.Expression) ?? NoUnaryExpressionError; } set { SetChildByRole (Roles.Expression, value); } } diff --git a/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/GeneralScope/Attribute.cs b/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/GeneralScope/Attribute.cs index 74fd9d7e3..cc99936e5 100644 --- a/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/GeneralScope/Attribute.cs +++ b/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/GeneralScope/Attribute.cs @@ -43,11 +43,19 @@ namespace ICSharpCode.NRefactory.CSharp get { return GetChildByRole (Roles.Type); } set { SetChildByRole (Roles.Type, value); } } - + + public CSharpTokenNode LParToken { + get { return GetChildByRole (Roles.LPar); } + } + public AstNodeCollection Arguments { get { return base.GetChildrenByRole (Roles.Argument); } } - + + public CSharpTokenNode RParToken { + get { return GetChildByRole (Roles.RPar); } + } + // HasArgumentList == false: [Empty] public bool HasArgumentList { get; @@ -74,13 +82,12 @@ namespace ICSharpCode.NRefactory.CSharp Attribute o = other as Attribute; return o != null && this.Type.DoMatch (o.Type, match) && this.Arguments.DoMatch (o.Arguments, match); } - - public override string ToString () + + public override string ToString(CSharpFormattingOptions formattingOptions) { if (IsNull) return "Null"; - else - return GetText(); + return base.ToString(formattingOptions); } } } diff --git a/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/GeneralScope/AttributeSection.cs b/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/GeneralScope/AttributeSection.cs index cd065b9c1..67b04412b 100644 --- a/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/GeneralScope/AttributeSection.cs +++ b/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/GeneralScope/AttributeSection.cs @@ -135,7 +135,7 @@ namespace ICSharpCode.NRefactory.CSharp protected internal override bool DoMatch(AstNode other, PatternMatching.Match match) { AttributeSection o = other as AttributeSection; - return o != null && this.AttributeTarget == o.AttributeTarget && this.Attributes.DoMatch(o.Attributes, match); + return o != null && MatchString(this.AttributeTarget, o.AttributeTarget) && this.Attributes.DoMatch(o.Attributes, match); } public AttributeSection() @@ -171,17 +171,4 @@ namespace ICSharpCode.NRefactory.CSharp // } // } } - - public enum AttributeTarget { - None, - Assembly, - Module, - - Type, - Param, - Field, - Return, - Method, - Unknown - } } diff --git a/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/GeneralScope/Comment.cs b/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/GeneralScope/Comment.cs index 83c00c9bf..9d53f6e66 100644 --- a/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/GeneralScope/Comment.cs +++ b/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/GeneralScope/Comment.cs @@ -65,6 +65,15 @@ namespace ICSharpCode.NRefactory.CSharp set { ThrowIfFrozen(); commentType = value; } } + /// + /// Returns true if the is Documentation or MultiLineDocumentation. + /// + public bool IsDocumentation { + get { + return commentType == CommentType.Documentation || commentType == CommentType.MultiLineDocumentation; + } + } + bool startsLine; public bool StartsLine { diff --git a/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/GeneralScope/Constraint.cs b/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/GeneralScope/Constraint.cs index cfd15f7af..c49930427 100644 --- a/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/GeneralScope/Constraint.cs +++ b/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/GeneralScope/Constraint.cs @@ -41,7 +41,11 @@ namespace ICSharpCode.NRefactory.CSharp return NodeType.Unknown; } } - + + public CSharpTokenNode WhereKeyword { + get { return GetChildByRole (Roles.WhereKeyword); } + } + public SimpleType TypeParameter { get { return GetChildByRole (Roles.ConstraintTypeParameter); diff --git a/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/GeneralScope/DelegateDeclaration.cs b/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/GeneralScope/DelegateDeclaration.cs index 088afa90b..68489bc7f 100644 --- a/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/GeneralScope/DelegateDeclaration.cs +++ b/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/GeneralScope/DelegateDeclaration.cs @@ -37,8 +37,8 @@ namespace ICSharpCode.NRefactory.CSharp get { return NodeType.TypeDeclaration; } } - public override EntityType EntityType { - get { return EntityType.TypeDefinition; } + public override SymbolKind SymbolKind { + get { return SymbolKind.TypeDefinition; } } public CSharpTokenNode DelegateToken { diff --git a/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/GeneralScope/NamespaceDeclaration.cs b/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/GeneralScope/NamespaceDeclaration.cs index a374f490d..dbcf0192d 100644 --- a/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/GeneralScope/NamespaceDeclaration.cs +++ b/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/GeneralScope/NamespaceDeclaration.cs @@ -23,10 +23,10 @@ // 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.Collections.Generic; using System.Linq; using System.Text; +using System; namespace ICSharpCode.NRefactory.CSharp { @@ -36,36 +36,42 @@ namespace ICSharpCode.NRefactory.CSharp public class NamespaceDeclaration : AstNode { public static readonly Role MemberRole = SyntaxTree.MemberRole; - + public static readonly Role NamespaceNameRole = new Role("NamespaceName", AstType.Null); + public override NodeType NodeType { get { return NodeType.Unknown; } } - + public CSharpTokenNode NamespaceToken { - get { return GetChildByRole (Roles.NamespaceKeyword); } + get { return GetChildByRole(Roles.NamespaceKeyword); } } - + + public AstType NamespaceName { + get { return GetChildByRole(NamespaceNameRole) ?? AstType.Null; } + set { SetChildByRole(NamespaceNameRole, value); } + } + public string Name { get { - StringBuilder builder = new StringBuilder (); - foreach (Identifier identifier in GetChildrenByRole (Roles.Identifier)) { - if (builder.Length > 0) - builder.Append ('.'); - builder.Append (identifier.Name); - } - return builder.ToString (); + return UsingDeclaration.ConstructNamespace(NamespaceName); } set { - GetChildrenByRole(Roles.Identifier).ReplaceWith(value.Split('.').Select(ident => Identifier.Create (ident))); + var arr = value.Split('.'); + NamespaceName = ConstructType(arr, arr.Length - 1); } } - - public AstNodeCollection Identifiers { - get { return GetChildrenByRole (Roles.Identifier); } + + static AstType ConstructType(string[] arr, int i) + { + if (i < 0 || i >= arr.Length) + throw new ArgumentOutOfRangeException("i"); + if (i == 0) + return new SimpleType(arr[i]); + return new MemberType(ConstructType(arr, i - 1), arr[i]); } - + /// /// Gets the full namespace name (including any parent namespaces) /// @@ -73,65 +79,80 @@ namespace ICSharpCode.NRefactory.CSharp get { NamespaceDeclaration parentNamespace = Parent as NamespaceDeclaration; if (parentNamespace != null) - return BuildQualifiedName (parentNamespace.FullName, Name); + return BuildQualifiedName(parentNamespace.FullName, Name); return Name; } } - + + public IEnumerable Identifiers { + get { + var result = new Stack(); + AstType type = NamespaceName; + while (type is MemberType) { + var mt = (MemberType)type; + result.Push(mt.MemberName); + type = mt.Target; + } + if (type is SimpleType) + result.Push(((SimpleType)type).Identifier); + return result; + } + } + public CSharpTokenNode LBraceToken { - get { return GetChildByRole (Roles.LBrace); } + get { return GetChildByRole(Roles.LBrace); } } - + public AstNodeCollection Members { get { return GetChildrenByRole(MemberRole); } } - + public CSharpTokenNode RBraceToken { - get { return GetChildByRole (Roles.RBrace); } + get { return GetChildByRole(Roles.RBrace); } } - - public NamespaceDeclaration () + + public NamespaceDeclaration() { } - - public NamespaceDeclaration (string name) + + public NamespaceDeclaration(string name) { this.Name = name; } - - public static string BuildQualifiedName (string name1, string name2) + + public static string BuildQualifiedName(string name1, string name2) { - if (string.IsNullOrEmpty (name1)) + if (string.IsNullOrEmpty(name1)) return name2; - if (string.IsNullOrEmpty (name2)) + if (string.IsNullOrEmpty(name2)) return name1; return name1 + "." + name2; } - - public void AddMember (AstNode child) + + public void AddMember(AstNode child) { - AddChild (child, MemberRole); + AddChild(child, MemberRole); } - - public override void AcceptVisitor (IAstVisitor visitor) + + public override void AcceptVisitor(IAstVisitor visitor) { - visitor.VisitNamespaceDeclaration (this); + visitor.VisitNamespaceDeclaration(this); } - - public override T AcceptVisitor (IAstVisitor visitor) + + public override T AcceptVisitor(IAstVisitor visitor) { - return visitor.VisitNamespaceDeclaration (this); + return visitor.VisitNamespaceDeclaration(this); } - - public override S AcceptVisitor (IAstVisitor visitor, T data) + + public override S AcceptVisitor(IAstVisitor visitor, T data) { - return visitor.VisitNamespaceDeclaration (this, data); + return visitor.VisitNamespaceDeclaration(this, data); } - + protected internal override bool DoMatch(AstNode other, PatternMatching.Match match) { NamespaceDeclaration o = other as NamespaceDeclaration; return o != null && MatchString(this.Name, o.Name) && this.Members.DoMatch(o.Members, match); } } -}; +} ; diff --git a/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/GeneralScope/NewLineNode.cs b/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/GeneralScope/NewLineNode.cs index a2cba46c8..12b004420 100644 --- a/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/GeneralScope/NewLineNode.cs +++ b/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/GeneralScope/NewLineNode.cs @@ -1,16 +1,11 @@ using System; namespace ICSharpCode.NRefactory.CSharp { - public enum NewLineType { - Unix, - Windows, - Mac - } /// /// A New line node represents a line break in the text. /// - public abstract class NewLineNode : AstNode + public sealed class NewLineNode : AstNode { public override NodeType NodeType { get { @@ -18,8 +13,31 @@ namespace ICSharpCode.NRefactory.CSharp } } - public abstract NewLineType NewLineType { - get; + const uint newLineMask = 0xfu << AstNodeFlagsUsedBits; + static readonly UnicodeNewline[] newLineTypes = { + UnicodeNewline.Unknown, + UnicodeNewline.LF, + UnicodeNewline.CRLF, + UnicodeNewline.CR, + UnicodeNewline.NEL, + UnicodeNewline.VT, + UnicodeNewline.FF, + UnicodeNewline.LS, + UnicodeNewline.PS + }; + + public UnicodeNewline NewLineType { + get { + return newLineTypes[(flags & newLineMask) >> AstNodeFlagsUsedBits]; + } + set { + ThrowIfFrozen(); + int pos = Array.IndexOf(newLineTypes, value); + if (pos < 0) + pos = 0; + flags &= ~newLineMask; // clear old newline type + flags |= (uint)pos << AstNodeFlagsUsedBits; + } } TextLocation startLocation; @@ -44,6 +62,11 @@ namespace ICSharpCode.NRefactory.CSharp this.startLocation = startLocation; } + public sealed override string ToString(CSharpFormattingOptions formattingOptions) + { + return NewLine.GetString (NewLineType); + } + public override void AcceptVisitor(IAstVisitor visitor) { visitor.VisitNewLine (this); @@ -58,74 +81,10 @@ namespace ICSharpCode.NRefactory.CSharp { return visitor.VisitNewLine (this, data); } - } - - public class UnixNewLine : NewLineNode - { - public override NewLineType NewLineType { - get { - return NewLineType.Unix; - } - } - - public UnixNewLine() - { - } - - public UnixNewLine(TextLocation startLocation) : base (startLocation) - { - } - - protected internal override bool DoMatch(AstNode other, PatternMatching.Match match) - { - var o = other as UnixNewLine; - return o != null; - } - } - - public class WindowsNewLine : NewLineNode - { - public override NewLineType NewLineType { - get { - return NewLineType.Windows; - } - } - - public WindowsNewLine() - { - } - - public WindowsNewLine(TextLocation startLocation) : base (startLocation) - { - } - - protected internal override bool DoMatch(AstNode other, PatternMatching.Match match) - { - var o = other as WindowsNewLine; - return o != null; - } - } - - public class MacNewLine : NewLineNode - { - public override NewLineType NewLineType { - get { - return NewLineType.Mac; - } - } - - public MacNewLine() - { - } - - public MacNewLine(TextLocation startLocation) : base (startLocation) - { - } - - protected internal override bool DoMatch(AstNode other, PatternMatching.Match match) + + protected internal override bool DoMatch(AstNode other, ICSharpCode.NRefactory.PatternMatching.Match match) { - var o = other as MacNewLine; - return o != null; + return other is NewLineNode; } } } diff --git a/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/GeneralScope/PreProcessorDirective.cs b/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/GeneralScope/PreProcessorDirective.cs index b630087ab..631f35e98 100644 --- a/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/GeneralScope/PreProcessorDirective.cs +++ b/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/GeneralScope/PreProcessorDirective.cs @@ -24,6 +24,8 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. using System; +using System.Collections.Generic; +using System.Linq; namespace ICSharpCode.NRefactory.CSharp { @@ -45,6 +47,85 @@ namespace ICSharpCode.NRefactory.CSharp Pragma = 11, Line = 12 } + + public class LinePreprocessorDirective : PreProcessorDirective + { + public int LineNumber { + get; + set; + } + + public string FileName { + get; + set; + } + + public LinePreprocessorDirective(TextLocation startLocation, TextLocation endLocation) : base (PreProcessorDirectiveType.Line, startLocation, endLocation) + { + } + + public LinePreprocessorDirective(string argument = null) : base (PreProcessorDirectiveType.Line, argument) + { + } + } + + public class PragmaWarningPreprocessorDirective : PreProcessorDirective + { + public static readonly Role WarningRole = new Role ("Warning"); + + public static readonly TokenRole PragmaKeywordRole = new TokenRole ("#pragma"); + public static readonly TokenRole WarningKeywordRole = new TokenRole ("warning"); + public static readonly TokenRole DisableKeywordRole = new TokenRole ("disable"); + public static readonly TokenRole RestoreKeywordRole = new TokenRole ("restore"); + + public bool Disable { + get { + return !DisableToken.IsNull; + } + } + + public CSharpTokenNode PragmaToken { + get { return GetChildByRole (PragmaKeywordRole); } + } + + public CSharpTokenNode WarningToken { + get { return GetChildByRole (WarningKeywordRole); } + } + + public CSharpTokenNode DisableToken { + get { return GetChildByRole (DisableKeywordRole); } + } + + public CSharpTokenNode RestoreToken { + get { return GetChildByRole (RestoreKeywordRole); } + } + + public AstNodeCollection Warnings { + get { return GetChildrenByRole(WarningRole); } + } + + public override TextLocation EndLocation { + get { + var child = LastChild; + if (child == null) + return base.EndLocation; + return child.EndLocation; + } + } + + public PragmaWarningPreprocessorDirective(TextLocation startLocation, TextLocation endLocation) : base (PreProcessorDirectiveType.Pragma, startLocation, endLocation) + { + } + + public PragmaWarningPreprocessorDirective(string argument = null) : base (PreProcessorDirectiveType.Pragma, argument) + { + } + + public bool IsDefined(int pragmaWarning) + { + return Warnings.Select(w => (int)w.Value).Any(n => n == pragmaWarning); + } + } public class PreProcessorDirective : AstNode { diff --git a/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/GeneralScope/TypeDeclaration.cs b/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/GeneralScope/TypeDeclaration.cs index d4ac6eaf6..f2dedfa16 100644 --- a/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/GeneralScope/TypeDeclaration.cs +++ b/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/GeneralScope/TypeDeclaration.cs @@ -47,8 +47,8 @@ namespace ICSharpCode.NRefactory.CSharp get { return NodeType.TypeDeclaration; } } - public override EntityType EntityType { - get { return EntityType.TypeDefinition; } + public override SymbolKind SymbolKind { + get { return SymbolKind.TypeDefinition; } } ClassType classType; @@ -78,9 +78,25 @@ namespace ICSharpCode.NRefactory.CSharp } } + public CSharpTokenNode LChevronToken { + get { return GetChildByRole (Roles.LChevron); } + } + public AstNodeCollection TypeParameters { get { return GetChildrenByRole (Roles.TypeParameter); } } + + public CSharpTokenNode RChevronToken { + get { return GetChildByRole (Roles.RChevron); } + } + + + + public CSharpTokenNode ColonToken { + get { + return GetChildByRole(Roles.Colon); + } + } public AstNodeCollection BaseTypes { get { return GetChildrenByRole(Roles.BaseType); } @@ -93,7 +109,7 @@ namespace ICSharpCode.NRefactory.CSharp public CSharpTokenNode LBraceToken { get { return GetChildByRole (Roles.LBrace); } } - + public AstNodeCollection Members { get { return GetChildrenByRole (Roles.TypeMemberRole); } } diff --git a/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/GeneralScope/TypeParameterDeclaration.cs b/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/GeneralScope/TypeParameterDeclaration.cs index ede85f16a..c992b629a 100644 --- a/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/GeneralScope/TypeParameterDeclaration.cs +++ b/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/GeneralScope/TypeParameterDeclaration.cs @@ -1,4 +1,4 @@ -// Copyright (c) AlphaSierraPapa for the SharpDevelop Team +// Copyright (c) 2010-2013 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 diff --git a/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/GeneralScope/UsingDeclaration.cs b/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/GeneralScope/UsingDeclaration.cs index c5ae72351..9e0c35a89 100644 --- a/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/GeneralScope/UsingDeclaration.cs +++ b/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/GeneralScope/UsingDeclaration.cs @@ -27,6 +27,7 @@ using System; using System.Linq; using System.Text; +using System.Collections.Generic; namespace ICSharpCode.NRefactory.CSharp { @@ -54,7 +55,29 @@ namespace ICSharpCode.NRefactory.CSharp } public string Namespace { - get { return this.Import.ToString(); } + get { return ConstructNamespace (Import); } + } + + internal static string ConstructNamespace (AstType type) + { + var stack = new Stack(); + while (type is MemberType) { + var mt = (MemberType)type; + stack.Push(mt.MemberName); + type = mt.Target; + if (mt.IsDoubleColon) { + stack.Push("::"); + } else { + stack.Push("."); + } + } + if (type is SimpleType) + stack.Push(((SimpleType)type).Identifier); + + var result = new StringBuilder(); + while (stack.Count > 0) + result.Append(stack.Pop()); + return result.ToString(); } public CSharpTokenNode SemicolonToken { @@ -67,7 +90,7 @@ namespace ICSharpCode.NRefactory.CSharp public UsingDeclaration (string nameSpace) { - AddChild (new SimpleType (nameSpace), ImportRole); + AddChild (AstType.Create (nameSpace), ImportRole); } public UsingDeclaration (AstType import) diff --git a/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/IAstVisitor.cs b/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/IAstVisitor.cs index c375afacf..a14c4fa54 100644 --- a/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/IAstVisitor.cs +++ b/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/IAstVisitor.cs @@ -1,4 +1,4 @@ -// Copyright (c) AlphaSierraPapa for the SharpDevelop Team +// Copyright (c) 2010-2013 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 @@ -59,8 +59,7 @@ namespace ICSharpCode.NRefactory.CSharp void VisitTypeReferenceExpression(TypeReferenceExpression typeReferenceExpression); void VisitUnaryOperatorExpression(UnaryOperatorExpression unaryOperatorExpression); void VisitUncheckedExpression(UncheckedExpression uncheckedExpression); - void VisitEmptyExpression (EmptyExpression emptyExpression); - + void VisitQueryExpression(QueryExpression queryExpression); void VisitQueryContinuationClause(QueryContinuationClause queryContinuationClause); void VisitQueryFromClause(QueryFromClause queryFromClause); @@ -148,6 +147,7 @@ namespace ICSharpCode.NRefactory.CSharp void VisitCSharpTokenNode(CSharpTokenNode cSharpTokenNode); void VisitIdentifier(Identifier identifier); + void VisitNullNode(AstNode nullNode); void VisitPatternPlaceholder(AstNode placeholder, PatternMatching.Pattern pattern); } @@ -190,8 +190,7 @@ namespace ICSharpCode.NRefactory.CSharp S VisitTypeReferenceExpression(TypeReferenceExpression typeReferenceExpression); S VisitUnaryOperatorExpression(UnaryOperatorExpression unaryOperatorExpression); S VisitUncheckedExpression(UncheckedExpression uncheckedExpression); - S VisitEmptyExpression (EmptyExpression emptyExpression); - + S VisitQueryExpression(QueryExpression queryExpression); S VisitQueryContinuationClause(QueryContinuationClause queryContinuationClause); S VisitQueryFromClause(QueryFromClause queryFromClause); @@ -279,6 +278,7 @@ namespace ICSharpCode.NRefactory.CSharp S VisitCSharpTokenNode(CSharpTokenNode cSharpTokenNode); S VisitIdentifier(Identifier identifier); + S VisitNullNode(AstNode nullNode); S VisitPatternPlaceholder(AstNode placeholder, PatternMatching.Pattern pattern); } @@ -321,8 +321,7 @@ namespace ICSharpCode.NRefactory.CSharp S VisitTypeReferenceExpression(TypeReferenceExpression typeReferenceExpression, T data); S VisitUnaryOperatorExpression(UnaryOperatorExpression unaryOperatorExpression, T data); S VisitUncheckedExpression(UncheckedExpression uncheckedExpression, T data); - S VisitEmptyExpression (EmptyExpression emptyExpression, T data); - + S VisitQueryExpression(QueryExpression queryExpression, T data); S VisitQueryContinuationClause(QueryContinuationClause queryContinuationClause, T data); S VisitQueryFromClause(QueryFromClause queryFromClause, T data); @@ -410,6 +409,7 @@ namespace ICSharpCode.NRefactory.CSharp S VisitCSharpTokenNode(CSharpTokenNode cSharpTokenNode, T data); S VisitIdentifier(Identifier identifier, T data); + S VisitNullNode(AstNode nullNode, T data); S VisitPatternPlaceholder(AstNode placeholder, PatternMatching.Pattern pattern, T data); } } diff --git a/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/Identifier.cs b/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/Identifier.cs index 3321de2a0..cf403afbd 100644 --- a/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/Identifier.cs +++ b/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/Identifier.cs @@ -41,16 +41,17 @@ namespace ICSharpCode.NRefactory.CSharp public override void AcceptVisitor (IAstVisitor visitor) { + visitor.VisitNullNode(this); } public override T AcceptVisitor (IAstVisitor visitor) { - return default (T); + return visitor.VisitNullNode(this); } public override S AcceptVisitor (IAstVisitor visitor, T data) { - return default (S); + return visitor.VisitNullNode(this, data); } protected internal override bool DoMatch(AstNode other, PatternMatching.Match match) @@ -83,6 +84,12 @@ namespace ICSharpCode.NRefactory.CSharp } } + internal void SetStartLocation(TextLocation value) + { + ThrowIfFrozen(); + this.startLocation = value; + } + const uint verbatimBit = 1u << AstNodeFlagsUsedBits; public bool IsVerbatim { @@ -127,7 +134,7 @@ namespace ICSharpCode.NRefactory.CSharp if (string.IsNullOrEmpty(name)) return Identifier.Null; if (name[0] == '@') - return new Identifier (name.Substring (1), location) { IsVerbatim = true }; + return new Identifier (name.Substring (1), new TextLocation (location.Line, location.Column + 1)) { IsVerbatim = true }; else return new Identifier (name, location); } diff --git a/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/IdentifierExpressionBackreference.cs b/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/IdentifierExpressionBackreference.cs index 0ce09e244..7bfacd990 100644 --- a/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/IdentifierExpressionBackreference.cs +++ b/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/IdentifierExpressionBackreference.cs @@ -1,4 +1,4 @@ -// Copyright (c) AlphaSierraPapa for the SharpDevelop Team +// Copyright (c) 2010-2013 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 diff --git a/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/MemberType.cs b/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/MemberType.cs index 76efbc7a8..2045d00ed 100644 --- a/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/MemberType.cs +++ b/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/MemberType.cs @@ -115,46 +115,35 @@ namespace ICSharpCode.NRefactory.CSharp protected internal override bool DoMatch(AstNode other, PatternMatching.Match match) { MemberType o = other as MemberType; - return o != null && this.IsDoubleColon == o.IsDoubleColon && MatchString(this.MemberName, o.MemberName) && this.Target.DoMatch(o.Target, match); + return o != null && this.IsDoubleColon == o.IsDoubleColon + && MatchString(this.MemberName, o.MemberName) && this.Target.DoMatch(o.Target, match) + && this.TypeArguments.DoMatch(o.TypeArguments, match); } - - public override string ToString() - { - StringBuilder b = new StringBuilder(); - b.Append(this.Target); - if (IsDoubleColon) - b.Append("::"); - else - b.Append('.'); - b.Append(this.MemberName); - if (this.TypeArguments.Any()) { - b.Append('<'); - b.Append(string.Join(", ", this.TypeArguments)); - b.Append('>'); - } - return b.ToString(); - } - - public override ITypeReference ToTypeReference(NameLookupMode lookupMode = NameLookupMode.Type) + + public override ITypeReference ToTypeReference(NameLookupMode lookupMode, InterningProvider interningProvider = null) { + if (interningProvider == null) + interningProvider = InterningProvider.Dummy; + TypeOrNamespaceReference t; if (this.IsDoubleColon) { SimpleType st = this.Target as SimpleType; if (st != null) { - t = new AliasNamespaceReference(st.Identifier); + t = interningProvider.Intern(new AliasNamespaceReference(interningProvider.Intern(st.Identifier))); } else { t = null; } } else { - t = this.Target.ToTypeReference(lookupMode) as TypeOrNamespaceReference; + t = this.Target.ToTypeReference(lookupMode, interningProvider) as TypeOrNamespaceReference; } if (t == null) return SpecialType.UnknownType; var typeArguments = new List(); foreach (var ta in this.TypeArguments) { - typeArguments.Add(ta.ToTypeReference(lookupMode)); + typeArguments.Add(ta.ToTypeReference(lookupMode, interningProvider)); } - return new MemberTypeOrNamespaceReference(t, this.MemberName, typeArguments, lookupMode); + string memberName = interningProvider.Intern(this.MemberName); + return interningProvider.Intern(new MemberTypeOrNamespaceReference(t, memberName, interningProvider.InternList(typeArguments), lookupMode)); } } } diff --git a/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/ObservableAstVisitor.cs b/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/ObservableAstVisitor.cs index 3291bccf7..6ac87439a 100644 --- a/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/ObservableAstVisitor.cs +++ b/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/ObservableAstVisitor.cs @@ -44,6 +44,10 @@ namespace ICSharpCode.NRefactory.CSharp if (leave != null) leave(node); } + + void IAstVisitor.VisitNullNode(AstNode nullNode) + { + } public event Action EnterSyntaxTree, LeaveSyntaxTree; @@ -842,13 +846,6 @@ namespace ICSharpCode.NRefactory.CSharp Visit(EnterNamedExpression, LeaveNamedExpression, namedExpression); } - public event Action EnterEmptyExpression, LeaveEmptyExpression; - - void IAstVisitor.VisitEmptyExpression(EmptyExpression emptyExpression) - { - Visit(EnterEmptyExpression, LeaveEmptyExpression, emptyExpression); - } - void IAstVisitor.VisitPatternPlaceholder(AstNode placeholder, PatternMatching.Pattern pattern) { } diff --git a/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/PrimitiveType.cs b/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/PrimitiveType.cs index 9d8a575be..5b52a37ac 100644 --- a/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/PrimitiveType.cs +++ b/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/PrimitiveType.cs @@ -71,6 +71,13 @@ namespace ICSharpCode.NRefactory.CSharp return location; } } + + internal void SetStartLocation(TextLocation value) + { + ThrowIfFrozen(); + this.location = value; + } + public override TextLocation EndLocation { get { return new TextLocation (location.Line, location.Column + keyword.Length); @@ -97,13 +104,13 @@ namespace ICSharpCode.NRefactory.CSharp PrimitiveType o = other as PrimitiveType; return o != null && MatchString(this.Keyword, o.Keyword); } - - public override string ToString() + + public override string ToString(CSharpFormattingOptions formattingOptions) { return Keyword; } - public override ITypeReference ToTypeReference(NameLookupMode lookupMode = NameLookupMode.Type) + public override ITypeReference ToTypeReference(NameLookupMode lookupMode, InterningProvider interningProvider = null) { KnownTypeCode typeCode = GetTypeCodeForPrimitiveType(this.Keyword); if (typeCode == KnownTypeCode.None) diff --git a/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/SimpleType.cs b/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/SimpleType.cs index 79b4e0f9c..529a62fbe 100644 --- a/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/SimpleType.cs +++ b/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/SimpleType.cs @@ -49,16 +49,17 @@ namespace ICSharpCode.NRefactory.CSharp public override void AcceptVisitor (IAstVisitor visitor) { + visitor.VisitNullNode(this); } - + public override T AcceptVisitor (IAstVisitor visitor) { - return default (T); + return visitor.VisitNullNode(this); } public override S AcceptVisitor (IAstVisitor visitor, T data) { - return default (S); + return visitor.VisitNullNode(this, data); } protected internal override bool DoMatch(AstNode other, PatternMatching.Match match) @@ -66,7 +67,7 @@ namespace ICSharpCode.NRefactory.CSharp return other == null || other.IsNull; } - public override ITypeReference ToTypeReference(NameLookupMode lookupMode) + public override ITypeReference ToTypeReference(NameLookupMode lookupMode, InterningProvider interningProvider) { return SpecialType.UnknownType; } @@ -130,7 +131,7 @@ namespace ICSharpCode.NRefactory.CSharp { visitor.VisitSimpleType (this); } - + public override T AcceptVisitor (IAstVisitor visitor) { return visitor.VisitSimpleType (this); @@ -147,28 +148,21 @@ namespace ICSharpCode.NRefactory.CSharp return o != null && MatchString(this.Identifier, o.Identifier) && this.TypeArguments.DoMatch(o.TypeArguments, match); } - public override string ToString() - { - StringBuilder b = new StringBuilder(this.Identifier); - if (this.TypeArguments.Any()) { - b.Append('<'); - b.Append(string.Join(", ", this.TypeArguments)); - b.Append('>'); - } - return b.ToString(); - } - - public override ITypeReference ToTypeReference(NameLookupMode lookupMode = NameLookupMode.Type) + public override ITypeReference ToTypeReference(NameLookupMode lookupMode, InterningProvider interningProvider = null) { + if (interningProvider == null) + interningProvider = InterningProvider.Dummy; var typeArguments = new List(); foreach (var ta in this.TypeArguments) { - typeArguments.Add(ta.ToTypeReference(lookupMode)); + typeArguments.Add(ta.ToTypeReference(lookupMode, interningProvider)); } - if (typeArguments.Count == 0 && string.IsNullOrEmpty(this.Identifier)) { + string identifier = interningProvider.Intern(this.Identifier); + if (typeArguments.Count == 0 && string.IsNullOrEmpty(identifier)) { // empty SimpleType is used for typeof(List<>). return SpecialType.UnboundTypeArgument; } - return new SimpleTypeOrNamespaceReference(this.Identifier, typeArguments, lookupMode); + var t = new SimpleTypeOrNamespaceReference(identifier, interningProvider.InternList(typeArguments), lookupMode); + return interningProvider.Intern(t); } } } diff --git a/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/Statements/BlockStatement.cs b/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/Statements/BlockStatement.cs index d30484d8d..24b9cd106 100644 --- a/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/Statements/BlockStatement.cs +++ b/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/Statements/BlockStatement.cs @@ -47,16 +47,17 @@ namespace ICSharpCode.NRefactory.CSharp public override void AcceptVisitor (IAstVisitor visitor) { + visitor.VisitNullNode(this); } - + public override T AcceptVisitor (IAstVisitor visitor) { - return default (T); + return visitor.VisitNullNode(this); } - + public override S AcceptVisitor (IAstVisitor visitor, T data) { - return default (S); + return visitor.VisitNullNode(this, data); } protected internal override bool DoMatch(AstNode other, PatternMatching.Match match) @@ -150,11 +151,6 @@ namespace ICSharpCode.NRefactory.CSharp AddChild(statement, StatementRole); } - public void Add(Expression expression) - { - AddChild(new ExpressionStatement(expression), StatementRole); - } - IEnumerator IEnumerable.GetEnumerator() { return this.Statements.GetEnumerator(); diff --git a/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/Statements/BreakStatement.cs b/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/Statements/BreakStatement.cs index 056cf55e4..4bb4e39ef 100644 --- a/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/Statements/BreakStatement.cs +++ b/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/Statements/BreakStatement.cs @@ -40,7 +40,7 @@ namespace ICSharpCode.NRefactory.CSharp public CSharpTokenNode SemicolonToken { get { return GetChildByRole (Roles.Semicolon); } } - + public override void AcceptVisitor (IAstVisitor visitor) { visitor.VisitBreakStatement (this); diff --git a/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/Statements/DoWhileStatement.cs b/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/Statements/DoWhileStatement.cs index ec6e2ce26..280ca7cea 100644 --- a/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/Statements/DoWhileStatement.cs +++ b/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/Statements/DoWhileStatement.cs @@ -84,6 +84,16 @@ namespace ICSharpCode.NRefactory.CSharp DoWhileStatement o = other as DoWhileStatement; return o != null && this.EmbeddedStatement.DoMatch(o.EmbeddedStatement, match) && this.Condition.DoMatch(o.Condition, match); } + + public DoWhileStatement() + { + } + + public DoWhileStatement(Expression condition, Statement embeddedStatement) + { + this.Condition = condition; + this.EmbeddedStatement = embeddedStatement; + } } } diff --git a/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/Statements/LabelStatement.cs b/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/Statements/LabelStatement.cs index ef2190bfe..43d22cea7 100644 --- a/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/Statements/LabelStatement.cs +++ b/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/Statements/LabelStatement.cs @@ -45,7 +45,7 @@ namespace ICSharpCode.NRefactory.CSharp set { SetChildByRole (Roles.Identifier, value); } } - public CSharpTokenNode Colon { + public CSharpTokenNode ColonToken { get { return GetChildByRole (Roles.Colon); } } diff --git a/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/Statements/Statement.cs b/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/Statements/Statement.cs index 6d3ec7d1f..24d3ede92 100644 --- a/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/Statements/Statement.cs +++ b/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/Statements/Statement.cs @@ -1,5 +1,20 @@ -// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) -// This code is distributed under MIT X11 license (for details please see \doc\license.txt) +// Copyright (c) 2010-2013 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; @@ -27,16 +42,17 @@ namespace ICSharpCode.NRefactory.CSharp public override void AcceptVisitor (IAstVisitor visitor) { + visitor.VisitNullNode(this); } - + public override T AcceptVisitor (IAstVisitor visitor) { - return default (T); + return visitor.VisitNullNode(this); } - + public override S AcceptVisitor (IAstVisitor visitor, T data) { - return default (S); + return visitor.VisitNullNode(this, data); } protected internal override bool DoMatch(AstNode other, PatternMatching.Match match) @@ -107,11 +123,10 @@ namespace ICSharpCode.NRefactory.CSharp public override NodeType NodeType { get { return NodeType.Statement; } } - - // Make debugging easier by giving Statements a ToString() implementation - public override string ToString() + + public static implicit operator Statement (Expression type) { - return DebugToString(); + return new ExpressionStatement(type); } } } diff --git a/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/Statements/TryCatchStatement.cs b/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/Statements/TryCatchStatement.cs index 13e375b49..3611574b7 100644 --- a/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/Statements/TryCatchStatement.cs +++ b/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/Statements/TryCatchStatement.cs @@ -104,16 +104,17 @@ namespace ICSharpCode.NRefactory.CSharp public override void AcceptVisitor (IAstVisitor visitor) { + visitor.VisitNullNode(this); } public override T AcceptVisitor (IAstVisitor visitor) { - return default (T); + return visitor.VisitNullNode(this); } public override S AcceptVisitor (IAstVisitor visitor, T data) { - return default (S); + return visitor.VisitNullNode(this, data); } protected internal override bool DoMatch(AstNode other, PatternMatching.Match match) diff --git a/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/Statements/WhileStatement.cs b/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/Statements/WhileStatement.cs index 256ddb864..e38daa144 100644 --- a/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/Statements/WhileStatement.cs +++ b/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/Statements/WhileStatement.cs @@ -75,5 +75,15 @@ namespace ICSharpCode.NRefactory.CSharp WhileStatement o = other as WhileStatement; return o != null && this.Condition.DoMatch(o.Condition, match) && this.EmbeddedStatement.DoMatch(o.EmbeddedStatement, match); } + + public WhileStatement() + { + } + + public WhileStatement(Expression condition, Statement embeddedStatement) + { + this.Condition = condition; + this.EmbeddedStatement = embeddedStatement; + } } } diff --git a/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/SyntaxExtensions.cs b/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/SyntaxExtensions.cs new file mode 100644 index 000000000..bac28bb76 --- /dev/null +++ b/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/SyntaxExtensions.cs @@ -0,0 +1,45 @@ +// Copyright (c) 2013 Daniel Grunwald +// +// 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; + +namespace ICSharpCode.NRefactory.CSharp +{ + /// + /// Extension methods for the syntax tree. + /// + public static class SyntaxExtensions + { + public static bool IsComparisonOperator(this OperatorType operatorType) + { + switch (operatorType) { + case OperatorType.Equality: + case OperatorType.Inequality: + case OperatorType.GreaterThan: + case OperatorType.LessThan: + case OperatorType.GreaterThanOrEqual: + case OperatorType.LessThanOrEqual: + return true; + default: + return false; + } + } + } +} diff --git a/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/SyntaxTree.cs b/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/SyntaxTree.cs index 2906696b3..6ac536159 100644 --- a/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/SyntaxTree.cs +++ b/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/SyntaxTree.cs @@ -105,27 +105,34 @@ namespace ICSharpCode.NRefactory.CSharp { } - public IEnumerable GetTypes(bool includeInnerTypes = false) + /// + /// Gets all defined types in this syntax tree. + /// + /// + /// A list containing or nodes. + /// + public IEnumerable GetTypes(bool includeInnerTypes = false) { Stack nodeStack = new Stack (); nodeStack.Push(this); while (nodeStack.Count > 0) { var curNode = nodeStack.Pop(); - if (curNode is TypeDeclaration) { - yield return (TypeDeclaration)curNode; + if (curNode is TypeDeclaration || curNode is DelegateDeclaration) { + yield return (EntityDeclaration)curNode; } foreach (var child in curNode.Children) { if (!(child is Statement || child is Expression) && - (child.Role != Roles.TypeMemberRole || (child is TypeDeclaration && includeInnerTypes))) + (child.Role != Roles.TypeMemberRole || ((child is TypeDeclaration || child is DelegateDeclaration) && includeInnerTypes))) nodeStack.Push (child); } } } + protected internal override bool DoMatch(AstNode other, PatternMatching.Match match) { SyntaxTree o = other as SyntaxTree; - return o != null && GetChildrenByRole(MemberRole).DoMatch(o.GetChildrenByRole(MemberRole), match); + return o != null && this.Members.DoMatch(o.Members, match); } public override void AcceptVisitor (IAstVisitor visitor) @@ -157,24 +164,28 @@ namespace ICSharpCode.NRefactory.CSharp public static SyntaxTree Parse (string program, string fileName = "", CompilerSettings settings = null, CancellationToken cancellationToken = default (CancellationToken)) { + cancellationToken.ThrowIfCancellationRequested(); var parser = new CSharpParser (settings); return parser.Parse (program, fileName); } public static SyntaxTree Parse (TextReader reader, string fileName = "", CompilerSettings settings = null, CancellationToken cancellationToken = default (CancellationToken)) { + cancellationToken.ThrowIfCancellationRequested(); var parser = new CSharpParser (settings); return parser.Parse (reader, fileName); } public static SyntaxTree Parse (Stream stream, string fileName = "", CompilerSettings settings = null, CancellationToken cancellationToken = default (CancellationToken)) { + cancellationToken.ThrowIfCancellationRequested(); var parser = new CSharpParser (settings); return parser.Parse (stream, fileName); } public static SyntaxTree Parse (ITextSource textSource, string fileName = "", CompilerSettings settings = null, CancellationToken cancellationToken = default (CancellationToken)) { + cancellationToken.ThrowIfCancellationRequested(); var parser = new CSharpParser (settings); return parser.Parse (textSource, fileName); } diff --git a/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/TokenRole.cs b/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/TokenRole.cs index 29a67ab27..8c9c7392a 100644 --- a/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/TokenRole.cs +++ b/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/TokenRole.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Generic; namespace ICSharpCode.NRefactory.CSharp { @@ -7,6 +8,17 @@ namespace ICSharpCode.NRefactory.CSharp /// public sealed class TokenRole : Role { + internal readonly static List Tokens = new List (); + internal readonly static List TokenLengths = new List (); + internal readonly uint TokenIndex; + + static TokenRole () + { + // null token + Tokens.Add (""); + TokenLengths.Add (0); + } + /// /// Gets the token as string. Note that the token Name and Token value may differ. /// @@ -22,11 +34,27 @@ namespace ICSharpCode.NRefactory.CSharp get; private set; } - - public TokenRole (string token) : base (token, CSharpTokenNode.Null) + + + public TokenRole(string token) : base (token, CSharpTokenNode.Null) { this.Token = token; this.Length = token.Length; + + bool found = false; + for (int i = 0; i < Tokens.Count; i++) { + var existingToken = Tokens [i]; + if (existingToken == token) { + TokenIndex = (uint)i; + found = true; + break; + } + } + if (!found) { + TokenIndex = (uint)Tokens.Count; + Tokens.Add (token); + TokenLengths.Add (this.Length); + } } } } diff --git a/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/TypeMembers/Accessor.cs b/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/TypeMembers/Accessor.cs index a920a849c..8bd18c477 100644 --- a/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/TypeMembers/Accessor.cs +++ b/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/TypeMembers/Accessor.cs @@ -45,16 +45,17 @@ namespace ICSharpCode.NRefactory.CSharp public override void AcceptVisitor (IAstVisitor visitor) { + visitor.VisitNullNode(this); } public override T AcceptVisitor (IAstVisitor visitor) { - return default (T); + return visitor.VisitNullNode(this); } public override S AcceptVisitor (IAstVisitor visitor, T data) { - return default (S); + return visitor.VisitNullNode(this, data); } protected internal override bool DoMatch(AstNode other, PatternMatching.Match match) @@ -67,8 +68,24 @@ namespace ICSharpCode.NRefactory.CSharp get { return NodeType.Unknown; } } - public override EntityType EntityType { - get { return EntityType.Method; } + public override SymbolKind SymbolKind { + get { return SymbolKind.Method; } + } + + /// + /// Gets the 'get'/'set'/'add'/'remove' keyword + /// + public CSharpTokenNode Keyword { + get { + for (AstNode child = this.FirstChild; child != null; child = child.NextSibling) { + if (child.Role == PropertyDeclaration.GetKeywordRole || child.Role == PropertyDeclaration.SetKeywordRole + || child.Role == CustomEventDeclaration.AddKeywordRole || child.Role == CustomEventDeclaration.RemoveKeywordRole) + { + return (CSharpTokenNode)child; + } + } + return CSharpTokenNode.Null; + } } public BlockStatement Body { diff --git a/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/TypeMembers/ConstructorDeclaration.cs b/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/TypeMembers/ConstructorDeclaration.cs index 204776793..23a973a5c 100644 --- a/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/TypeMembers/ConstructorDeclaration.cs +++ b/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/TypeMembers/ConstructorDeclaration.cs @@ -32,8 +32,8 @@ namespace ICSharpCode.NRefactory.CSharp { public static readonly Role InitializerRole = new Role("Initializer", ConstructorInitializer.Null); - public override EntityType EntityType { - get { return EntityType.Constructor; } + public override SymbolKind SymbolKind { + get { return SymbolKind.Constructor; } } public CSharpTokenNode LParToken { @@ -86,6 +86,7 @@ namespace ICSharpCode.NRefactory.CSharp } public enum ConstructorInitializerType { + Any, Base, This } @@ -112,16 +113,17 @@ namespace ICSharpCode.NRefactory.CSharp public override void AcceptVisitor (IAstVisitor visitor) { + visitor.VisitNullNode(this); } - + public override T AcceptVisitor (IAstVisitor visitor) { - return default (T); + return visitor.VisitNullNode(this); } public override S AcceptVisitor (IAstVisitor visitor, T data) { - return default (S); + return visitor.VisitNullNode(this, data); } protected internal override bool DoMatch(AstNode other, PatternMatching.Match match) @@ -141,6 +143,15 @@ namespace ICSharpCode.NRefactory.CSharp set; } + public CSharpTokenNode Keyword { + get { + if (ConstructorInitializerType == ConstructorInitializerType.Base) + return GetChildByRole(BaseKeywordRole); + else + return GetChildByRole(ThisKeywordRole); + } + } + public CSharpTokenNode LParToken { get { return GetChildByRole (Roles.LPar); } } @@ -171,7 +182,9 @@ namespace ICSharpCode.NRefactory.CSharp protected internal override bool DoMatch(AstNode other, PatternMatching.Match match) { ConstructorInitializer o = other as ConstructorInitializer; - return o != null && !o.IsNull && this.ConstructorInitializerType == o.ConstructorInitializerType && this.Arguments.DoMatch(o.Arguments, match); + return o != null && !o.IsNull + && (this.ConstructorInitializerType == ConstructorInitializerType.Any || this.ConstructorInitializerType == o.ConstructorInitializerType) + && this.Arguments.DoMatch(o.Arguments, match); } } } diff --git a/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/TypeMembers/DestructorDeclaration.cs b/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/TypeMembers/DestructorDeclaration.cs index 5f2411ec8..0609e5dc6 100644 --- a/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/TypeMembers/DestructorDeclaration.cs +++ b/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/TypeMembers/DestructorDeclaration.cs @@ -36,8 +36,8 @@ namespace ICSharpCode.NRefactory.CSharp get { return GetChildByRole (TildeRole); } } - public override EntityType EntityType { - get { return EntityType.Destructor; } + public override SymbolKind SymbolKind { + get { return SymbolKind.Destructor; } } public CSharpTokenNode LParToken { diff --git a/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/TypeMembers/EntityDeclaration.cs b/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/TypeMembers/EntityDeclaration.cs index ca8f69338..c02ff21b6 100644 --- a/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/TypeMembers/EntityDeclaration.cs +++ b/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/TypeMembers/EntityDeclaration.cs @@ -1,4 +1,4 @@ -// Copyright (c) AlphaSierraPapa for the SharpDevelop Team +// Copyright (c) 2010-2013 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 @@ -33,7 +33,7 @@ namespace ICSharpCode.NRefactory.CSharp get { return NodeType.Member; } } - public abstract NRefactory.TypeSystem.EntityType EntityType { get; } + public abstract NRefactory.TypeSystem.SymbolKind SymbolKind { get; } public AstNodeCollection Attributes { get { return base.GetChildrenByRole (AttributeRole); } @@ -71,7 +71,11 @@ namespace ICSharpCode.NRefactory.CSharp get { return GetChildByRole (Roles.Type); } set { SetChildByRole(Roles.Type, value); } } - + + public CSharpTokenNode SemicolonToken { + get { return GetChildByRole (Roles.Semicolon); } + } + internal static Modifiers GetModifiers(AstNode node) { Modifiers m = 0; diff --git a/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/TypeMembers/EnumMemberDeclaration.cs b/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/TypeMembers/EnumMemberDeclaration.cs index 8f05e4e2a..b7c924ab9 100644 --- a/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/TypeMembers/EnumMemberDeclaration.cs +++ b/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/TypeMembers/EnumMemberDeclaration.cs @@ -33,10 +33,14 @@ namespace ICSharpCode.NRefactory.CSharp { public static readonly Role InitializerRole = new Role("Initializer", Expression.Null); - public override EntityType EntityType { - get { return EntityType.Field; } + public override SymbolKind SymbolKind { + get { return SymbolKind.Field; } } - + + public CSharpTokenNode AssignToken { + get { return GetChildByRole (Roles.Assign); } + } + public Expression Initializer { get { return GetChildByRole (InitializerRole); } set { SetChildByRole (InitializerRole, value); } diff --git a/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/TypeMembers/EventDeclaration.cs b/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/TypeMembers/EventDeclaration.cs index 8c1958cf8..d543f9ea7 100644 --- a/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/TypeMembers/EventDeclaration.cs +++ b/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/TypeMembers/EventDeclaration.cs @@ -24,7 +24,10 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. +using System; using System.Collections.Generic; +using System.ComponentModel; + using ICSharpCode.NRefactory.TypeSystem; namespace ICSharpCode.NRefactory.CSharp @@ -33,14 +36,32 @@ namespace ICSharpCode.NRefactory.CSharp { public static readonly TokenRole EventKeywordRole = new TokenRole ("event"); - public override EntityType EntityType { - get { return EntityType.Event; } + public override SymbolKind SymbolKind { + get { return SymbolKind.Event; } } - + + public CSharpTokenNode EventToken { + get { return GetChildByRole (EventKeywordRole); } + } + public AstNodeCollection Variables { get { return GetChildrenByRole (Roles.Variable); } } + // Hide .Name and .NameToken from users; the actual field names + // are stored in the VariableInitializer. + [EditorBrowsable(EditorBrowsableState.Never)] + public override string Name { + get { return string.Empty; } + set { throw new NotSupportedException(); } + } + + [EditorBrowsable(EditorBrowsableState.Never)] + public override Identifier NameToken { + get { return Identifier.Null; } + set { throw new NotSupportedException(); } + } + public override void AcceptVisitor (IAstVisitor visitor) { visitor.VisitEventDeclaration (this); @@ -73,8 +94,8 @@ namespace ICSharpCode.NRefactory.CSharp public static readonly Role AddAccessorRole = new Role("AddAccessor", Accessor.Null); public static readonly Role RemoveAccessorRole = new Role("RemoveAccessor", Accessor.Null); - public override EntityType EntityType { - get { return EntityType.Event; } + public override SymbolKind SymbolKind { + get { return SymbolKind.Event; } } /// diff --git a/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/TypeMembers/FieldDeclaration.cs b/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/TypeMembers/FieldDeclaration.cs index 16406d59d..de220ecd7 100644 --- a/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/TypeMembers/FieldDeclaration.cs +++ b/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/TypeMembers/FieldDeclaration.cs @@ -24,20 +24,36 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. +using System; +using System.ComponentModel; using ICSharpCode.NRefactory.TypeSystem; namespace ICSharpCode.NRefactory.CSharp { public class FieldDeclaration : EntityDeclaration { - public override EntityType EntityType { - get { return EntityType.Field; } + public override SymbolKind SymbolKind { + get { return SymbolKind.Field; } } public AstNodeCollection Variables { get { return GetChildrenByRole (Roles.Variable); } } + // Hide .Name and .NameToken from users; the actual field names + // are stored in the VariableInitializer. + [EditorBrowsable(EditorBrowsableState.Never)] + public override string Name { + get { return string.Empty; } + set { throw new NotSupportedException(); } + } + + [EditorBrowsable(EditorBrowsableState.Never)] + public override Identifier NameToken { + get { return Identifier.Null; } + set { throw new NotSupportedException(); } + } + public override void AcceptVisitor (IAstVisitor visitor) { visitor.VisitFieldDeclaration (this); diff --git a/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/TypeMembers/FixedFieldDeclaration.cs b/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/TypeMembers/FixedFieldDeclaration.cs index ebc20c5ef..fea2a2af2 100644 --- a/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/TypeMembers/FixedFieldDeclaration.cs +++ b/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/TypeMembers/FixedFieldDeclaration.cs @@ -33,8 +33,8 @@ namespace ICSharpCode.NRefactory.CSharp public static readonly TokenRole FixedKeywordRole = new TokenRole ("fixed"); public static readonly Role VariableRole = new Role ("FixedVariable"); - public override EntityType EntityType { - get { return EntityType.Field; } + public override SymbolKind SymbolKind { + get { return SymbolKind.Field; } } public CSharpTokenNode FixedToken { diff --git a/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/TypeMembers/IndexerDeclaration.cs b/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/TypeMembers/IndexerDeclaration.cs index 02bc126ae..56156dd19 100644 --- a/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/TypeMembers/IndexerDeclaration.cs +++ b/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/TypeMembers/IndexerDeclaration.cs @@ -25,6 +25,7 @@ // THE SOFTWARE. using System; +using System.ComponentModel; using ICSharpCode.NRefactory.TypeSystem; namespace ICSharpCode.NRefactory.CSharp @@ -35,8 +36,8 @@ namespace ICSharpCode.NRefactory.CSharp public static readonly Role GetterRole = PropertyDeclaration.GetterRole; public static readonly Role SetterRole = PropertyDeclaration.SetterRole; - public override EntityType EntityType { - get { return EntityType.Indexer; } + public override SymbolKind SymbolKind { + get { return SymbolKind.Indexer; } } /// @@ -53,14 +54,19 @@ namespace ICSharpCode.NRefactory.CSharp set { throw new NotSupportedException(); } } + [EditorBrowsable(EditorBrowsableState.Never)] public override Identifier NameToken { get { return Identifier.Null; } set { throw new NotSupportedException(); } } - + public CSharpTokenNode LBracketToken { get { return GetChildByRole (Roles.LBracket); } } + + public CSharpTokenNode ThisToken { + get { return GetChildByRole (ThisKeywordRole); } + } public AstNodeCollection Parameters { get { return GetChildrenByRole (Roles.Parameter); } diff --git a/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/TypeMembers/MethodDeclaration.cs b/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/TypeMembers/MethodDeclaration.cs index 0d4a2340b..90aaa3047 100644 --- a/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/TypeMembers/MethodDeclaration.cs +++ b/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/TypeMembers/MethodDeclaration.cs @@ -30,8 +30,8 @@ namespace ICSharpCode.NRefactory.CSharp { public class MethodDeclaration : EntityDeclaration { - public override EntityType EntityType { - get { return EntityType.Method; } + public override SymbolKind SymbolKind { + get { return SymbolKind.Method; } } /// diff --git a/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/TypeMembers/OperatorDeclaration.cs b/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/TypeMembers/OperatorDeclaration.cs index 8e0967357..b4ae52a2a 100644 --- a/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/TypeMembers/OperatorDeclaration.cs +++ b/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/TypeMembers/OperatorDeclaration.cs @@ -25,6 +25,7 @@ // THE SOFTWARE. using System; +using System.ComponentModel; using ICSharpCode.NRefactory.TypeSystem; namespace ICSharpCode.NRefactory.CSharp @@ -105,8 +106,8 @@ namespace ICSharpCode.NRefactory.CSharp public static readonly TokenRole ExplicitRole = new TokenRole ("explicit"); public static readonly TokenRole ImplicitRole = new TokenRole ("implicit"); - public override EntityType EntityType { - get { return EntityType.Operator; } + public override SymbolKind SymbolKind { + get { return SymbolKind.Operator; } } OperatorType operatorType; @@ -250,6 +251,7 @@ namespace ICSharpCode.NRefactory.CSharp set { throw new NotSupportedException(); } } + [EditorBrowsable(EditorBrowsableState.Never)] public override Identifier NameToken { get { return Identifier.Null; } set { throw new NotSupportedException(); } diff --git a/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/TypeMembers/ParameterDeclaration.cs b/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/TypeMembers/ParameterDeclaration.cs index 15b4993d2..cc69ff1fd 100644 --- a/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/TypeMembers/ParameterDeclaration.cs +++ b/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/TypeMembers/ParameterDeclaration.cs @@ -88,7 +88,11 @@ namespace ICSharpCode.NRefactory.CSharp SetChildByRole (Roles.Identifier, value); } } - + + public CSharpTokenNode AssignToken { + get { return GetChildByRole (Roles.Assign); } + } + public Expression DefaultExpression { get { return GetChildByRole (Roles.Expression); } set { SetChildByRole (Roles.Expression, value); } @@ -127,6 +131,17 @@ namespace ICSharpCode.NRefactory.CSharp Name = name; ParameterModifier = modifier; } + + public ParameterDeclaration(string name, ParameterModifier modifier = ParameterModifier.None) + { + Name = name; + ParameterModifier = modifier; + } + + public new ParameterDeclaration Clone() + { + return (ParameterDeclaration)base.Clone(); + } } } diff --git a/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/TypeMembers/PropertyDeclaration.cs b/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/TypeMembers/PropertyDeclaration.cs index df0fa9876..1f137e0c9 100644 --- a/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/TypeMembers/PropertyDeclaration.cs +++ b/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/TypeMembers/PropertyDeclaration.cs @@ -34,8 +34,8 @@ namespace ICSharpCode.NRefactory.CSharp public static readonly Role GetterRole = new Role("Getter", Accessor.Null); public static readonly Role SetterRole = new Role("Setter", Accessor.Null); - public override EntityType EntityType { - get { return EntityType.Property; } + public override SymbolKind SymbolKind { + get { return SymbolKind.Property; } } /// diff --git a/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/TypeMembers/VariableInitializer.cs b/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/TypeMembers/VariableInitializer.cs index 8b0c3fff2..dbf4bbe3d 100644 --- a/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/TypeMembers/VariableInitializer.cs +++ b/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/TypeMembers/VariableInitializer.cs @@ -41,16 +41,17 @@ namespace ICSharpCode.NRefactory.CSharp public override void AcceptVisitor (IAstVisitor visitor) { + visitor.VisitNullNode(this); } - + public override T AcceptVisitor (IAstVisitor visitor) { - return default (T); + return visitor.VisitNullNode(this); } public override S AcceptVisitor (IAstVisitor visitor, T data) { - return default (S); + return visitor.VisitNullNode(this, data); } protected internal override bool DoMatch(AstNode other, PatternMatching.Match match) @@ -163,15 +164,7 @@ namespace ICSharpCode.NRefactory.CSharp { return visitor.VisitVariableInitializer (this, data); } - - public override string ToString() - { - if (this.Initializer.IsNull) - return "[VariableInitializer " + this.Name + "]"; - else - return "[VariableInitializer " + this.Name + " = " + this.Initializer.ToString() + "]"; - } - + protected internal override bool DoMatch(AstNode other, PatternMatching.Match match) { VariableInitializer o = other as VariableInitializer; diff --git a/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/old_ObservableAstVisitor.cs b/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/old_ObservableAstVisitor.cs deleted file mode 100644 index 6baf690df..000000000 --- a/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/old_ObservableAstVisitor.cs +++ /dev/null @@ -1,1201 +0,0 @@ -// -// ObservableAstVisitor.cs -// -// Author: -// Mike Krüger -// -// Copyright (c) 2011 Novell, Inc (http://www.novell.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; - -namespace ICSharpCode.NRefactory.CSharp -{ - [Obsolete("Use the non-generic version of the ObservableAstVisitor instead (the 'data' parameter and return value cannot be used meaningfully when using events)")] - public class ObservableAstVisitor: IAstVisitor - { - S VisitChildren (AstNode node, T data) - { - 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, data); - } - return default (S); - } - - public event Action CompilationUnitVisited; - - S IAstVisitor.VisitSyntaxTree (SyntaxTree unit, T data) - { - var handler = CompilationUnitVisited; - if (handler != null) - handler (unit, data); - return VisitChildren (unit, data); - } - - public event Action CommentVisited; - - S IAstVisitor.VisitComment (Comment comment, T data) - { - var handler = CommentVisited; - if (handler != null) - handler (comment, data); - return VisitChildren (comment, data); - } - - public event Action NewLineVisited; - - S IAstVisitor.VisitNewLine(NewLineNode newLineNode, T data) - { - var handler = NewLineVisited; - if (handler != null) - handler(newLineNode, data); - return VisitChildren(newLineNode, data); - } - - public event Action WhitespaceVisited; - - S IAstVisitor.VisitWhitespace(WhitespaceNode whitespace, T data) - { - var handler = WhitespaceVisited; - if (handler != null) - handler(whitespace, data); - return VisitChildren(whitespace, data); - } - - public event Action TextVisited; - - S IAstVisitor.VisitText(TextNode textNode, T data) - { - var handler = TextVisited; - if (handler != null) - handler(textNode, data); - return VisitChildren(textNode, data); - } - - public event Action PreProcessorDirectiveVisited; - S IAstVisitor.VisitPreProcessorDirective (PreProcessorDirective preProcessorDirective, T data) - { - var handler = PreProcessorDirectiveVisited; - if (handler != null) - handler (preProcessorDirective, data); - return VisitChildren (preProcessorDirective, data); - } - - public event Action DocumentationReferenceVisited; - - S IAstVisitor.VisitDocumentationReference (DocumentationReference documentationReference, T data) - { - var handler = DocumentationReferenceVisited; - if (handler != null) - handler (documentationReference, data); - return VisitChildren (documentationReference, data); - } - - public event Action IdentifierVisited; - - S IAstVisitor.VisitIdentifier (Identifier identifier, T data) - { - var handler = IdentifierVisited; - if (handler != null) - handler (identifier, data); - return VisitChildren (identifier, data); - } - - public event Action CSharpTokenNodeVisited; - - S IAstVisitor.VisitCSharpTokenNode (CSharpTokenNode token, T data) - { - var handler = CSharpTokenNodeVisited; - if (handler != null) - handler (token, data); - return VisitChildren (token, data); - } - - public event Action PrimitiveTypeVisited; - - S IAstVisitor.VisitPrimitiveType (PrimitiveType primitiveType, T data) - { - var handler = PrimitiveTypeVisited; - if (handler != null) - handler (primitiveType, data); - return VisitChildren (primitiveType, data); - } - - public event Action ComposedTypeVisited; - - S IAstVisitor.VisitComposedType (ComposedType composedType, T data) - { - var handler = ComposedTypeVisited; - if (handler != null) - handler (composedType, data); - return VisitChildren (composedType, data); - } - - public event Action SimpleTypeVisited; - - S IAstVisitor.VisitSimpleType (SimpleType simpleType, T data) - { - var handler = SimpleTypeVisited; - if (handler != null) - handler (simpleType, data); - return VisitChildren (simpleType, data); - } - - public event Action MemberTypeVisited; - - S IAstVisitor.VisitMemberType (MemberType memberType, T data) - { - var handler = MemberTypeVisited; - if (handler != null) - handler (memberType, data); - return VisitChildren (memberType, data); - } - - public event Action AttributeVisited; - - S IAstVisitor.VisitAttribute (Attribute attribute, T data) - { - var handler = AttributeVisited; - if (handler != null) - handler (attribute, data); - return VisitChildren (attribute, data); - } - - public event Action AttributeSectionVisited; - - S IAstVisitor.VisitAttributeSection (AttributeSection attributeSection, T data) - { - var handler = AttributeSectionVisited; - if (handler != null) - handler (attributeSection, data); - return VisitChildren (attributeSection, data); - } - - public event Action DelegateDeclarationVisited; - - S IAstVisitor.VisitDelegateDeclaration (DelegateDeclaration delegateDeclaration, T data) - { - var handler = DelegateDeclarationVisited; - if (handler != null) - handler (delegateDeclaration, data); - return VisitChildren (delegateDeclaration, data); - } - - public event Action NamespaceDeclarationVisited; - - S IAstVisitor.VisitNamespaceDeclaration (NamespaceDeclaration namespaceDeclaration, T data) - { - var handler = NamespaceDeclarationVisited; - if (handler != null) - handler (namespaceDeclaration, data); - return VisitChildren (namespaceDeclaration, data); - } - - public event Action TypeDeclarationVisited; - - S IAstVisitor.VisitTypeDeclaration (TypeDeclaration typeDeclaration, T data) - { - var handler = TypeDeclarationVisited; - if (handler != null) - handler (typeDeclaration, data); - return VisitChildren (typeDeclaration, data); - } - - public event Action TypeParameterDeclarationVisited; - - S IAstVisitor.VisitTypeParameterDeclaration (TypeParameterDeclaration typeParameterDeclaration, T data) - { - var handler = TypeParameterDeclarationVisited; - if (handler != null) - handler (typeParameterDeclaration, data); - return VisitChildren (typeParameterDeclaration, data); - } - - public event Action EnumMemberDeclarationVisited; - - S IAstVisitor.VisitEnumMemberDeclaration (EnumMemberDeclaration enumMemberDeclaration, T data) - { - var handler = EnumMemberDeclarationVisited; - if (handler != null) - handler (enumMemberDeclaration, data); - return VisitChildren (enumMemberDeclaration, data); - } - - public event Action UsingDeclarationVisited; - - S IAstVisitor.VisitUsingDeclaration (UsingDeclaration usingDeclaration, T data) - { - var handler = UsingDeclarationVisited; - if (handler != null) - handler (usingDeclaration, data); - return VisitChildren (usingDeclaration, data); - } - - public event Action UsingAliasDeclarationVisited; - - S IAstVisitor.VisitUsingAliasDeclaration (UsingAliasDeclaration usingDeclaration, T data) - { - var handler = UsingAliasDeclarationVisited; - if (handler != null) - handler (usingDeclaration, data); - return VisitChildren (usingDeclaration, data); - } - - public event Action ExternAliasDeclarationVisited; - - S IAstVisitor.VisitExternAliasDeclaration (ExternAliasDeclaration externAliasDeclaration, T data) - { - var handler = ExternAliasDeclarationVisited; - if (handler != null) - handler (externAliasDeclaration, data); - return VisitChildren (externAliasDeclaration, data); - } - - public event Action ConstructorDeclarationVisited; - - S IAstVisitor.VisitConstructorDeclaration (ConstructorDeclaration constructorDeclaration, T data) - { - var handler = ConstructorDeclarationVisited; - if (handler != null) - handler (constructorDeclaration, data); - return VisitChildren (constructorDeclaration, data); - } - - public event Action ConstructorInitializerVisited; - - S IAstVisitor.VisitConstructorInitializer (ConstructorInitializer constructorInitializer, T data) - { - var handler = ConstructorInitializerVisited; - if (handler != null) - handler (constructorInitializer, data); - return VisitChildren (constructorInitializer, data); - } - - public event Action DestructorDeclarationVisited; - - S IAstVisitor.VisitDestructorDeclaration (DestructorDeclaration destructorDeclaration, T data) - { - var handler = DestructorDeclarationVisited; - if (handler != null) - handler (destructorDeclaration, data); - return VisitChildren (destructorDeclaration, data); - } - - public event Action EventDeclarationVisited; - - S IAstVisitor.VisitEventDeclaration (EventDeclaration eventDeclaration, T data) - { - var handler = EventDeclarationVisited; - if (handler != null) - handler (eventDeclaration, data); - return VisitChildren (eventDeclaration, data); - } - - public event Action CustomEventDeclarationVisited; - - S IAstVisitor.VisitCustomEventDeclaration (CustomEventDeclaration eventDeclaration, T data) - { - var handler = CustomEventDeclarationVisited; - if (handler != null) - handler (eventDeclaration, data); - return VisitChildren (eventDeclaration, data); - } - - public event Action FieldDeclarationVisited; - - S IAstVisitor.VisitFieldDeclaration (FieldDeclaration fieldDeclaration, T data) - { - var handler = FieldDeclarationVisited; - if (handler != null) - handler (fieldDeclaration, data); - return VisitChildren (fieldDeclaration, data); - } - - public event Action FixedFieldDeclarationVisited; - - S IAstVisitor.VisitFixedFieldDeclaration (FixedFieldDeclaration fixedFieldDeclaration, T data) - { - var handler = FixedFieldDeclarationVisited; - if (handler != null) - handler (fixedFieldDeclaration, data); - return VisitChildren (fixedFieldDeclaration, data); - } - - public event Action FixedVariableInitializerVisited; - - S IAstVisitor.VisitFixedVariableInitializer (FixedVariableInitializer fixedVariableInitializer, T data) - { - var handler = FixedVariableInitializerVisited; - if (handler != null) - handler (fixedVariableInitializer, data); - return VisitChildren (fixedVariableInitializer, data); - } - - public event Action IndexerDeclarationVisited; - - S IAstVisitor.VisitIndexerDeclaration (IndexerDeclaration indexerDeclaration, T data) - { - var handler = IndexerDeclarationVisited; - if (handler != null) - handler (indexerDeclaration, data); - return VisitChildren (indexerDeclaration, data); - } - - public event Action MethodDeclarationVisited; - - S IAstVisitor.VisitMethodDeclaration (MethodDeclaration methodDeclaration, T data) - { - var handler = MethodDeclarationVisited; - if (handler != null) - handler (methodDeclaration, data); - return VisitChildren (methodDeclaration, data); - } - - public event Action OperatorDeclarationVisited; - - S IAstVisitor.VisitOperatorDeclaration (OperatorDeclaration operatorDeclaration, T data) - { - var handler = OperatorDeclarationVisited; - if (handler != null) - handler (operatorDeclaration, data); - return VisitChildren (operatorDeclaration, data); - } - - public event Action PropertyDeclarationVisited; - - S IAstVisitor.VisitPropertyDeclaration (PropertyDeclaration propertyDeclaration, T data) - { - var handler = PropertyDeclarationVisited; - if (handler != null) - handler (propertyDeclaration, data); - return VisitChildren (propertyDeclaration, data); - } - - public event Action AccessorVisited; - - S IAstVisitor.VisitAccessor (Accessor accessor, T data) - { - var handler = AccessorVisited; - if (handler != null) - handler (accessor, data); - return VisitChildren (accessor, data); - } - - public event Action VariableInitializerVisited; - - S IAstVisitor.VisitVariableInitializer (VariableInitializer variableInitializer, T data) - { - var handler = VariableInitializerVisited; - if (handler != null) - handler (variableInitializer, data); - return VisitChildren (variableInitializer, data); - } - - public event Action ParameterDeclarationVisited; - - S IAstVisitor.VisitParameterDeclaration (ParameterDeclaration parameterDeclaration, T data) - { - var handler = ParameterDeclarationVisited; - if (handler != null) - handler (parameterDeclaration, data); - return VisitChildren (parameterDeclaration, data); - } - - public event Action ConstraintVisited; - - S IAstVisitor.VisitConstraint (Constraint constraint, T data) - { - var handler = ConstraintVisited; - if (handler != null) - handler (constraint, data); - return VisitChildren (constraint, data); - } - - public event Action BlockStatementVisited; - - S IAstVisitor.VisitBlockStatement (BlockStatement blockStatement, T data) - { - var handler = BlockStatementVisited; - if (handler != null) - handler (blockStatement, data); - return VisitChildren (blockStatement, data); - } - - public event Action ExpressionStatementVisited; - - S IAstVisitor.VisitExpressionStatement (ExpressionStatement expressionStatement, T data) - { - var handler = ExpressionStatementVisited; - if (handler != null) - handler (expressionStatement, data); - return VisitChildren (expressionStatement, data); - } - - public event Action BreakStatementVisited; - - S IAstVisitor.VisitBreakStatement (BreakStatement breakStatement, T data) - { - var handler = BreakStatementVisited; - if (handler != null) - handler (breakStatement, data); - return VisitChildren (breakStatement, data); - } - - public event Action CheckedStatementVisited; - - S IAstVisitor.VisitCheckedStatement (CheckedStatement checkedStatement, T data) - { - var handler = CheckedStatementVisited; - if (handler != null) - handler (checkedStatement, data); - return VisitChildren (checkedStatement, data); - } - - public event Action ContinueStatementVisited; - - S IAstVisitor.VisitContinueStatement (ContinueStatement continueStatement, T data) - { - var handler = ContinueStatementVisited; - if (handler != null) - handler (continueStatement, data); - return VisitChildren (continueStatement, data); - } - - public event Action DoWhileStatementVisited; - - S IAstVisitor.VisitDoWhileStatement (DoWhileStatement doWhileStatement, T data) - { - var handler = DoWhileStatementVisited; - if (handler != null) - handler (doWhileStatement, data); - return VisitChildren (doWhileStatement, data); - } - - public event Action EmptyStatementVisited; - - S IAstVisitor.VisitEmptyStatement (EmptyStatement emptyStatement, T data) - { - var handler = EmptyStatementVisited; - if (handler != null) - handler (emptyStatement, data); - return VisitChildren (emptyStatement, data); - } - - public event Action FixedStatementVisited; - - S IAstVisitor.VisitFixedStatement (FixedStatement fixedStatement, T data) - { - var handler = FixedStatementVisited; - if (handler != null) - handler (fixedStatement, data); - return VisitChildren (fixedStatement, data); - } - - public event Action ForeachStatementVisited; - - S IAstVisitor.VisitForeachStatement (ForeachStatement foreachStatement, T data) - { - var handler = ForeachStatementVisited; - if (handler != null) - handler (foreachStatement, data); - return VisitChildren (foreachStatement, data); - } - - public event Action ForStatementVisited; - - S IAstVisitor.VisitForStatement (ForStatement forStatement, T data) - { - var handler = ForStatementVisited; - if (handler != null) - handler (forStatement, data); - return VisitChildren (forStatement, data); - } - - public event Action GotoCaseStatementVisited; - - S IAstVisitor.VisitGotoCaseStatement (GotoCaseStatement gotoCaseStatement, T data) - { - var handler = GotoCaseStatementVisited; - if (handler != null) - handler (gotoCaseStatement, data); - return VisitChildren (gotoCaseStatement, data); - } - - public event Action GotoDefaultStatementVisited; - - S IAstVisitor.VisitGotoDefaultStatement (GotoDefaultStatement gotoDefaultStatement, T data) - { - var handler = GotoDefaultStatementVisited; - if (handler != null) - handler (gotoDefaultStatement, data); - return VisitChildren (gotoDefaultStatement, data); - } - - public event Action GotoStatementVisited; - - S IAstVisitor.VisitGotoStatement (GotoStatement gotoStatement, T data) - { - var handler = GotoStatementVisited; - if (handler != null) - handler (gotoStatement, data); - return VisitChildren (gotoStatement, data); - } - - public event Action IfElseStatementVisited; - - S IAstVisitor.VisitIfElseStatement (IfElseStatement ifElseStatement, T data) - { - var handler = IfElseStatementVisited; - if (handler != null) - handler (ifElseStatement, data); - return VisitChildren (ifElseStatement, data); - } - - public event Action LabelStatementVisited; - - S IAstVisitor.VisitLabelStatement (LabelStatement labelStatement, T data) - { - var handler = LabelStatementVisited; - if (handler != null) - handler (labelStatement, data); - return VisitChildren (labelStatement, data); - } - - public event Action LockStatementVisited; - - S IAstVisitor.VisitLockStatement (LockStatement lockStatement, T data) - { - var handler = LockStatementVisited; - if (handler != null) - handler (lockStatement, data); - return VisitChildren (lockStatement, data); - } - - public event Action ReturnStatementVisited; - - S IAstVisitor.VisitReturnStatement (ReturnStatement returnStatement, T data) - { - var handler = ReturnStatementVisited; - if (handler != null) - handler (returnStatement, data); - return VisitChildren (returnStatement, data); - } - - public event Action SwitchStatementVisited; - - S IAstVisitor.VisitSwitchStatement (SwitchStatement switchStatement, T data) - { - var handler = SwitchStatementVisited; - if (handler != null) - handler (switchStatement, data); - return VisitChildren (switchStatement, data); - } - - public event Action SwitchSectionVisited; - - S IAstVisitor.VisitSwitchSection (SwitchSection switchSection, T data) - { - var handler = SwitchSectionVisited; - if (handler != null) - handler (switchSection, data); - return VisitChildren (switchSection, data); - } - - public event Action CaseLabelVisited; - - S IAstVisitor.VisitCaseLabel (CaseLabel caseLabel, T data) - { - var handler = CaseLabelVisited; - if (handler != null) - handler (caseLabel, data); - return VisitChildren (caseLabel, data); - } - - public event Action ThrowStatementVisited; - - S IAstVisitor.VisitThrowStatement (ThrowStatement throwStatement, T data) - { - var handler = ThrowStatementVisited; - if (handler != null) - handler (throwStatement, data); - return VisitChildren (throwStatement, data); - } - - public event Action TryCatchStatementVisited; - - S IAstVisitor.VisitTryCatchStatement (TryCatchStatement tryCatchStatement, T data) - { - var handler = TryCatchStatementVisited; - if (handler != null) - handler (tryCatchStatement, data); - return VisitChildren (tryCatchStatement, data); - } - - public event Action CatchClauseVisited; - - S IAstVisitor.VisitCatchClause (CatchClause catchClause, T data) - { - var handler = CatchClauseVisited; - if (handler != null) - handler (catchClause, data); - return VisitChildren (catchClause, data); - } - - public event Action UncheckedStatementVisited; - - S IAstVisitor.VisitUncheckedStatement (UncheckedStatement uncheckedStatement, T data) - { - var handler = UncheckedStatementVisited; - if (handler != null) - handler (uncheckedStatement, data); - return VisitChildren (uncheckedStatement, data); - } - - public event Action UnsafeStatementVisited; - - S IAstVisitor.VisitUnsafeStatement (UnsafeStatement unsafeStatement, T data) - { - var handler = UnsafeStatementVisited; - if (handler != null) - handler (unsafeStatement, data); - return VisitChildren (unsafeStatement, data); - } - - public event Action UsingStatementVisited; - - S IAstVisitor.VisitUsingStatement (UsingStatement usingStatement, T data) - { - var handler = UsingStatementVisited; - if (handler != null) - handler (usingStatement, data); - return VisitChildren (usingStatement, data); - } - - public event Action VariableDeclarationStatementVisited; - - S IAstVisitor.VisitVariableDeclarationStatement (VariableDeclarationStatement variableDeclarationStatement, T data) - { - var handler = VariableDeclarationStatementVisited; - if (handler != null) - handler (variableDeclarationStatement, data); - return VisitChildren (variableDeclarationStatement, data); - } - - public event Action WhileStatementVisited; - - S IAstVisitor.VisitWhileStatement (WhileStatement whileStatement, T data) - { - var handler = WhileStatementVisited; - if (handler != null) - handler (whileStatement, data); - return VisitChildren (whileStatement, data); - } - - public event Action YieldBreakStatementVisited; - - S IAstVisitor.VisitYieldBreakStatement (YieldBreakStatement yieldBreakStatement, T data) - { - var handler = YieldBreakStatementVisited; - if (handler != null) - handler (yieldBreakStatement, data); - return VisitChildren (yieldBreakStatement, data); - } - - public event Action YieldReturnStatementVisited; - - S IAstVisitor.VisitYieldReturnStatement (YieldReturnStatement yieldStatement, T data) - { - var handler = YieldReturnStatementVisited; - if (handler != null) - handler (yieldStatement, data); - return VisitChildren (yieldStatement, data); - } - - public event Action AnonymousMethodExpressionVisited; - - S IAstVisitor.VisitAnonymousMethodExpression (AnonymousMethodExpression anonymousMethodExpression, T data) - { - var handler = AnonymousMethodExpressionVisited; - if (handler != null) - handler (anonymousMethodExpression, data); - return VisitChildren (anonymousMethodExpression, data); - } - - public event Action LambdaExpressionVisited; - - S IAstVisitor.VisitLambdaExpression (LambdaExpression lambdaExpression, T data) - { - var handler = LambdaExpressionVisited; - if (handler != null) - handler (lambdaExpression, data); - return VisitChildren (lambdaExpression, data); - } - - public event Action AssignmentExpressionVisited; - - S IAstVisitor.VisitAssignmentExpression (AssignmentExpression assignmentExpression, T data) - { - var handler = AssignmentExpressionVisited; - if (handler != null) - handler (assignmentExpression, data); - return VisitChildren (assignmentExpression, data); - } - - public event Action BaseReferenceExpressionVisited; - - S IAstVisitor.VisitBaseReferenceExpression (BaseReferenceExpression baseReferenceExpression, T data) - { - var handler = BaseReferenceExpressionVisited; - if (handler != null) - handler (baseReferenceExpression, data); - return VisitChildren (baseReferenceExpression, data); - } - - public event Action BinaryOperatorExpressionVisited; - - S IAstVisitor.VisitBinaryOperatorExpression (BinaryOperatorExpression binaryOperatorExpression, T data) - { - var handler = BinaryOperatorExpressionVisited; - if (handler != null) - handler (binaryOperatorExpression, data); - return VisitChildren (binaryOperatorExpression, data); - } - - public event Action CastExpressionVisited; - - S IAstVisitor.VisitCastExpression (CastExpression castExpression, T data) - { - var handler = CastExpressionVisited; - if (handler != null) - handler (castExpression, data); - return VisitChildren (castExpression, data); - } - - public event Action CheckedExpressionVisited; - - S IAstVisitor.VisitCheckedExpression (CheckedExpression checkedExpression, T data) - { - var handler = CheckedExpressionVisited; - if (handler != null) - handler (checkedExpression, data); - return VisitChildren (checkedExpression, data); - } - - public event Action ConditionalExpressionVisited; - - S IAstVisitor.VisitConditionalExpression (ConditionalExpression conditionalExpression, T data) - { - var handler = ConditionalExpressionVisited; - if (handler != null) - handler (conditionalExpression, data); - return VisitChildren (conditionalExpression, data); - } - - public event Action IdentifierExpressionVisited; - - S IAstVisitor.VisitIdentifierExpression (IdentifierExpression identifierExpression, T data) - { - var handler = IdentifierExpressionVisited; - if (handler != null) - handler (identifierExpression, data); - return VisitChildren (identifierExpression, data); - } - - public event Action IndexerExpressionVisited; - - S IAstVisitor.VisitIndexerExpression (IndexerExpression indexerExpression, T data) - { - var handler = IndexerExpressionVisited; - if (handler != null) - handler (indexerExpression, data); - return VisitChildren (indexerExpression, data); - } - - public event Action InvocationExpressionVisited; - - S IAstVisitor.VisitInvocationExpression (InvocationExpression invocationExpression, T data) - { - var handler = InvocationExpressionVisited; - if (handler != null) - handler (invocationExpression, data); - return VisitChildren (invocationExpression, data); - } - - public event Action DirectionExpressionVisited; - - S IAstVisitor.VisitDirectionExpression (DirectionExpression directionExpression, T data) - { - var handler = DirectionExpressionVisited; - if (handler != null) - handler (directionExpression, data); - return VisitChildren (directionExpression, data); - } - - public event Action MemberReferenceExpressionVisited; - - S IAstVisitor.VisitMemberReferenceExpression (MemberReferenceExpression memberReferenceExpression, T data) - { - var handler = MemberReferenceExpressionVisited; - if (handler != null) - handler (memberReferenceExpression, data); - return VisitChildren (memberReferenceExpression, data); - } - - public event Action NullReferenceExpressionVisited; - - S IAstVisitor.VisitNullReferenceExpression (NullReferenceExpression nullReferenceExpression, T data) - { - var handler = NullReferenceExpressionVisited; - if (handler != null) - handler (nullReferenceExpression, data); - return VisitChildren (nullReferenceExpression, data); - } - - public event Action ObjectCreateExpressionVisited; - - S IAstVisitor.VisitObjectCreateExpression (ObjectCreateExpression objectCreateExpression, T data) - { - var handler = ObjectCreateExpressionVisited; - if (handler != null) - handler (objectCreateExpression, data); - return VisitChildren (objectCreateExpression, data); - } - - public event Action AnonymousTypeCreateExpressionVisited; - - S IAstVisitor.VisitAnonymousTypeCreateExpression (AnonymousTypeCreateExpression anonymousTypeCreateExpression, T data) - { - var handler = AnonymousTypeCreateExpressionVisited; - if (handler != null) - handler (anonymousTypeCreateExpression, data); - return VisitChildren (anonymousTypeCreateExpression, data); - } - - public event Action ArrayCreateExpressionVisited; - - S IAstVisitor.VisitArrayCreateExpression (ArrayCreateExpression arraySCreateExpression, T data) - { - var handler = ArrayCreateExpressionVisited; - if (handler != null) - handler (arraySCreateExpression, data); - return VisitChildren (arraySCreateExpression, data); - } - - public event Action ParenthesizedExpressionVisited; - - S IAstVisitor.VisitParenthesizedExpression (ParenthesizedExpression parenthesizedExpression, T data) - { - var handler = ParenthesizedExpressionVisited; - if (handler != null) - handler (parenthesizedExpression, data); - return VisitChildren (parenthesizedExpression, data); - } - - public event Action PointerReferenceExpressionVisited; - - S IAstVisitor.VisitPointerReferenceExpression (PointerReferenceExpression pointerReferenceExpression, T data) - { - var handler = PointerReferenceExpressionVisited; - if (handler != null) - handler (pointerReferenceExpression, data); - return VisitChildren (pointerReferenceExpression, data); - } - - public event Action PrimitiveExpressionVisited; - - S IAstVisitor.VisitPrimitiveExpression (PrimitiveExpression primitiveExpression, T data) - { - var handler = PrimitiveExpressionVisited; - if (handler != null) - handler (primitiveExpression, data); - return VisitChildren (primitiveExpression, data); - } - - public event Action SizeOfExpressionVisited; - - S IAstVisitor.VisitSizeOfExpression (SizeOfExpression sizeOfExpression, T data) - { - var handler = SizeOfExpressionVisited; - if (handler != null) - handler (sizeOfExpression, data); - return VisitChildren (sizeOfExpression, data); - } - - public event Action StackAllocExpressionVisited; - - S IAstVisitor.VisitStackAllocExpression (StackAllocExpression stackAllocExpression, T data) - { - var handler = StackAllocExpressionVisited; - if (handler != null) - handler (stackAllocExpression, data); - return VisitChildren (stackAllocExpression, data); - } - - public event Action ThisReferenceExpressionVisited; - - S IAstVisitor.VisitThisReferenceExpression (ThisReferenceExpression thisReferenceExpression, T data) - { - var handler = ThisReferenceExpressionVisited; - if (handler != null) - handler (thisReferenceExpression, data); - return VisitChildren (thisReferenceExpression, data); - } - - public event Action TypeOfExpressionVisited; - - S IAstVisitor.VisitTypeOfExpression (TypeOfExpression typeOfExpression, T data) - { - var handler = TypeOfExpressionVisited; - if (handler != null) - handler (typeOfExpression, data); - return VisitChildren (typeOfExpression, data); - } - - public event Action TypeReferenceExpressionVisited; - - S IAstVisitor.VisitTypeReferenceExpression (TypeReferenceExpression typeReferenceExpression, T data) - { - var handler = TypeReferenceExpressionVisited; - if (handler != null) - handler (typeReferenceExpression, data); - return VisitChildren (typeReferenceExpression, data); - } - - public event Action UnaryOperatorExpressionVisited; - - S IAstVisitor.VisitUnaryOperatorExpression (UnaryOperatorExpression unaryOperatorExpression, T data) - { - var handler = UnaryOperatorExpressionVisited; - if (handler != null) - handler (unaryOperatorExpression, data); - return VisitChildren (unaryOperatorExpression, data); - } - - public event Action UncheckedExpressionVisited; - - S IAstVisitor.VisitUncheckedExpression (UncheckedExpression uncheckedExpression, T data) - { - var handler = UncheckedExpressionVisited; - if (handler != null) - handler (uncheckedExpression, data); - return VisitChildren (uncheckedExpression, data); - } - - public event Action QueryExpressionVisited; - - S IAstVisitor.VisitQueryExpression (QueryExpression queryExpression, T data) - { - var handler = QueryExpressionVisited; - if (handler != null) - handler (queryExpression, data); - return VisitChildren (queryExpression, data); - } - - public event Action QueryContinuationClauseVisited; - - S IAstVisitor.VisitQueryContinuationClause (QueryContinuationClause queryContinuationClause, T data) - { - var handler = QueryContinuationClauseVisited; - if (handler != null) - handler (queryContinuationClause, data); - return VisitChildren (queryContinuationClause, data); - } - - public event Action QueryFromClauseVisited; - - S IAstVisitor.VisitQueryFromClause (QueryFromClause queryFromClause, T data) - { - var handler = QueryFromClauseVisited; - if (handler != null) - handler (queryFromClause, data); - return VisitChildren (queryFromClause, data); - } - - public event Action QueryLetClauseVisited; - - S IAstVisitor.VisitQueryLetClause (QueryLetClause queryLetClause, T data) - { - var handler = QueryLetClauseVisited; - if (handler != null) - handler (queryLetClause, data); - return VisitChildren (queryLetClause, data); - } - - public event Action QueryWhereClauseVisited; - - S IAstVisitor.VisitQueryWhereClause (QueryWhereClause queryWhereClause, T data) - { - var handler = QueryWhereClauseVisited; - if (handler != null) - handler (queryWhereClause, data); - return VisitChildren (queryWhereClause, data); - } - - public event Action QueryJoinClauseVisited; - - S IAstVisitor.VisitQueryJoinClause (QueryJoinClause queryJoinClause, T data) - { - var handler = QueryJoinClauseVisited; - if (handler != null) - handler (queryJoinClause, data); - return VisitChildren (queryJoinClause, data); - } - - public event Action QueryOrderClauseVisited; - - S IAstVisitor.VisitQueryOrderClause (QueryOrderClause queryOrderClause, T data) - { - var handler = QueryOrderClauseVisited; - if (handler != null) - handler (queryOrderClause, data); - return VisitChildren (queryOrderClause, data); - } - - public event Action QueryOrderingVisited; - - S IAstVisitor.VisitQueryOrdering (QueryOrdering queryOrdering, T data) - { - var handler = QueryOrderingVisited; - if (handler != null) - handler (queryOrdering, data); - return VisitChildren (queryOrdering, data); - } - - public event Action QuerySelectClauseVisited; - - S IAstVisitor.VisitQuerySelectClause (QuerySelectClause querySelectClause, T data) - { - var handler = QuerySelectClauseVisited; - if (handler != null) - handler (querySelectClause, data); - return VisitChildren (querySelectClause, data); - } - - public event Action QueryGroupClauseVisited; - - S IAstVisitor.VisitQueryGroupClause (QueryGroupClause queryGroupClause, T data) - { - var handler = QueryGroupClauseVisited; - if (handler != null) - handler (queryGroupClause, data); - return VisitChildren (queryGroupClause, data); - } - - public event Action AsExpressionVisited; - - S IAstVisitor.VisitAsExpression (AsExpression asExpression, T data) - { - var handler = AsExpressionVisited; - if (handler != null) - handler (asExpression, data); - return VisitChildren (asExpression, data); - } - - public event Action IsExpressionVisited; - - S IAstVisitor.VisitIsExpression (IsExpression isExpression, T data) - { - var handler = IsExpressionVisited; - if (handler != null) - handler (isExpression, data); - return VisitChildren (isExpression, data); - } - - public event Action DefaultValueExpressionVisited; - - S IAstVisitor.VisitDefaultValueExpression (DefaultValueExpression defaultValueExpression, T data) - { - var handler = DefaultValueExpressionVisited; - if (handler != null) - handler (defaultValueExpression, data); - return VisitChildren (defaultValueExpression, data); - } - - public event Action UndocumentedExpressionVisited; - - S IAstVisitor.VisitUndocumentedExpression (UndocumentedExpression undocumentedExpression, T data) - { - var handler = UndocumentedExpressionVisited; - if (handler != null) - handler (undocumentedExpression, data); - return VisitChildren (undocumentedExpression, data); - } - - public event Action ArrayInitializerExpressionVisited; - - S IAstVisitor.VisitArrayInitializerExpression (ArrayInitializerExpression arrayInitializerExpression, T data) - { - var handler = ArrayInitializerExpressionVisited; - if (handler != null) - handler (arrayInitializerExpression, data); - return VisitChildren (arrayInitializerExpression, data); - } - - public event Action ArraySpecifierVisited; - - S IAstVisitor.VisitArraySpecifier (ArraySpecifier arraySpecifier, T data) - { - var handler = ArraySpecifierVisited; - if (handler != null) - handler (arraySpecifier, data); - return VisitChildren (arraySpecifier, data); - } - - public event Action NamedArgumentExpressionVisited; - - S IAstVisitor.VisitNamedArgumentExpression (NamedArgumentExpression namedArgumentExpression, T data) - { - var handler = NamedArgumentExpressionVisited; - if (handler != null) - handler (namedArgumentExpression, data); - return VisitChildren (namedArgumentExpression, data); - } - - public event Action NamedExpressionVisited; - - S IAstVisitor.VisitNamedExpression (NamedExpression namedExpression, T data) - { - var handler = NamedExpressionVisited; - if (handler != null) - handler (namedExpression, data); - return VisitChildren (namedExpression, data); - } - - public event Action EmptyExpressionVisited; - - S IAstVisitor.VisitEmptyExpression (EmptyExpression emptyExpression, T data) - { - var handler = EmptyExpressionVisited; - if (handler != null) - handler (emptyExpression, data); - return VisitChildren (emptyExpression, data); - } - - S IAstVisitor.VisitPatternPlaceholder (AstNode placeholder, PatternMatching.Pattern pattern, T data) - { - return VisitChildren (placeholder, data); - } - } -} - - diff --git a/NRefactory/ICSharpCode.NRefactory.CSharp/CSharpProjectContent.cs b/NRefactory/ICSharpCode.NRefactory.CSharp/CSharpProjectContent.cs index fccba4622..ae0ba716e 100644 --- a/NRefactory/ICSharpCode.NRefactory.CSharp/CSharpProjectContent.cs +++ b/NRefactory/ICSharpCode.NRefactory.CSharp/CSharpProjectContent.cs @@ -1,4 +1,4 @@ -// Copyright (c) AlphaSierraPapa for the SharpDevelop Team +// Copyright (c) 2010-2013 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 @@ -31,6 +31,7 @@ namespace ICSharpCode.NRefactory.CSharp public class CSharpProjectContent : IProjectContent { string assemblyName; + string fullAssemblyName; string projectFileName; string location; Dictionary unresolvedFiles; @@ -48,6 +49,7 @@ namespace ICSharpCode.NRefactory.CSharp protected CSharpProjectContent(CSharpProjectContent pc) { this.assemblyName = pc.assemblyName; + this.fullAssemblyName = pc.fullAssemblyName; this.projectFileName = pc.projectFileName; this.location = pc.location; this.unresolvedFiles = new Dictionary(pc.unresolvedFiles, Platform.FileNameComparer); @@ -71,6 +73,10 @@ namespace ICSharpCode.NRefactory.CSharp get { return assemblyName; } } + public string FullAssemblyName { + get { return fullAssemblyName; } + } + public string Location { get { return location; } } @@ -128,10 +134,16 @@ namespace ICSharpCode.NRefactory.CSharp return new CSharpProjectContent(this); } + /// + /// Sets both the short and the full assembly names. + /// + /// New full assembly name. public IProjectContent SetAssemblyName(string newAssemblyName) { CSharpProjectContent pc = Clone(); - pc.assemblyName = newAssemblyName; + pc.fullAssemblyName = newAssemblyName; + int pos = newAssemblyName != null ? newAssemblyName.IndexOf(',') : -1; + pc.assemblyName = pos < 0 ? newAssemblyName : newAssemblyName.Substring(0, pos); return pc; } diff --git a/NRefactory/ICSharpCode.NRefactory.CSharp/CombineQueryExpressions.cs b/NRefactory/ICSharpCode.NRefactory.CSharp/CombineQueryExpressions.cs new file mode 100644 index 000000000..5311d9a24 --- /dev/null +++ b/NRefactory/ICSharpCode.NRefactory.CSharp/CombineQueryExpressions.cs @@ -0,0 +1,216 @@ +// +// CombineQueryExpressions.cs +// +// Modified by Luís Reis (Copyright (C) 2013) +// +// Copyright header of the original version follows: +// +// Copyright (c) 2011 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.Linq; +using ICSharpCode.NRefactory.CSharp; +using ICSharpCode.NRefactory.PatternMatching; + +namespace ICSharpCode.NRefactory.CSharp +{ + /// + /// Combines query expressions and removes transparent identifiers. + /// + public class CombineQueryExpressions + { + static readonly InvocationExpression castPattern = new InvocationExpression { + Target = new MemberReferenceExpression { + Target = new AnyNode("inExpr"), + MemberName = "Cast", + TypeArguments = { new AnyNode("targetType") } + }}; + + public string CombineQuery(AstNode node, AstNode rootQuery = null) + { + if (rootQuery == null) { + rootQuery = node; + } + + QueryExpression query = node as QueryExpression; + if (query != null) { + string continuationIdentifier = null; + + foreach (var clause in query.Clauses) { + var continuation = clause as QueryContinuationClause; + if (continuation != null) { + CombineQuery(continuation.PrecedingQuery); + } + + var from = clause as QueryFromClause; + if (from != null) { + continuationIdentifier = CombineQuery(from.Expression, rootQuery); + } + } + + QueryFromClause fromClause = (QueryFromClause)query.Clauses.First(); + QueryExpression innerQuery = fromClause.Expression as QueryExpression; + if (innerQuery != null) { + continuationIdentifier = continuationIdentifier ?? ((QueryFromClause)innerQuery.Clauses.First()).Identifier; + + string transparentIdentifier; + if (TryRemoveTransparentIdentifier(query, fromClause, innerQuery, continuationIdentifier, out transparentIdentifier)) { + RemoveTransparentIdentifierReferences(rootQuery, transparentIdentifier); + } else if (fromClause.Type.IsNull) { + QueryContinuationClause continuation = new QueryContinuationClause(); + continuation.PrecedingQuery = innerQuery.Detach(); + continuation.Identifier = fromClause.Identifier; + fromClause.ReplaceWith(continuation); + } + + return transparentIdentifier; + } else { + Match m = castPattern.Match(fromClause.Expression); + if (m.Success) { + fromClause.Type = m.Get("targetType").Single().Detach(); + fromClause.Expression = m.Get("inExpr").Single().Detach(); + } + } + } + + return null; + } + + static readonly QuerySelectClause selectTransparentIdentifierPattern = new QuerySelectClause { + Expression = new AnonymousTypeCreateExpression { + Initializers = { + new AnyNode("nae1"), + new AnyNode("nae2") + } + } + }; + + bool TryRemoveTransparentIdentifier(QueryExpression query, QueryFromClause fromClause, QueryExpression innerQuery, string continuationIdentifier, out string transparentIdentifier) + { + transparentIdentifier = fromClause.Identifier; + + Match match = selectTransparentIdentifierPattern.Match(innerQuery.Clauses.Last()); + if (!match.Success) + return false; + QuerySelectClause selectClause = (QuerySelectClause)innerQuery.Clauses.Last(); + Expression nae1 = match.Get("nae1").SingleOrDefault(); + string nae1Name = ExtractExpressionName(ref nae1); + if (nae1Name == null) + return false; + + Expression nae2 = match.Get("nae2").SingleOrDefault(); + string nae2Name = ExtractExpressionName(ref nae2); + if (nae1Name == null) + return false; + + bool introduceLetClause = true; + var nae1Identifier = nae1 as IdentifierExpression; + var nae2Identifier = nae2 as IdentifierExpression; + if (nae1Identifier != null && nae2Identifier != null && nae1Identifier.Identifier == nae1Name && nae2Identifier.Identifier == nae2Name) { + introduceLetClause = false; + } + + if (nae1Name != continuationIdentifier) { + if (nae2Name == continuationIdentifier) { + //Members are in reversed order + string tempName = nae1Name; + Expression tempNae = nae1; + + nae1Name = nae2Name; + nae1 = nae2; + nae2Name = tempName; + nae2 = tempNae; + } else { + return false; + } + } + + if (introduceLetClause && innerQuery.Clauses.OfType().Any(from => from.Identifier == nae2Name)) { + return false; + } + if (introduceLetClause && innerQuery.Clauses.OfType().Any(join => join.JoinIdentifier == nae2Name)) { + return false; + } + + // from * in (from x in ... select new { x = x, y = expr }) ... + // => + // from x in ... let y = expr ... + fromClause.Remove(); + selectClause.Remove(); + // Move clauses from innerQuery to query + QueryClause insertionPos = null; + foreach (var clause in innerQuery.Clauses) { + query.Clauses.InsertAfter(insertionPos, insertionPos = clause.Detach()); + } + if (introduceLetClause) { + query.Clauses.InsertAfter(insertionPos, new QueryLetClause { Identifier = nae2Name, Expression = nae2.Detach() }); + } + return true; + } + + /// + /// Removes all occurrences of transparent identifiers + /// + void RemoveTransparentIdentifierReferences(AstNode node, string transparentIdentifier) + { + foreach (AstNode child in node.Children) { + RemoveTransparentIdentifierReferences(child, transparentIdentifier); + } + MemberReferenceExpression mre = node as MemberReferenceExpression; + if (mre != null) { + IdentifierExpression ident = mre.Target as IdentifierExpression; + if (ident != null && ident.Identifier == transparentIdentifier) { + IdentifierExpression newIdent = new IdentifierExpression(mre.MemberName); + mre.TypeArguments.MoveTo(newIdent.TypeArguments); + newIdent.CopyAnnotationsFrom(mre); + newIdent.RemoveAnnotations(); // remove the reference to the property of the anonymous type + mre.ReplaceWith(newIdent); + return; + } else if (mre.MemberName == transparentIdentifier) { + var newVar = mre.Target.Detach(); + newVar.CopyAnnotationsFrom(mre); + newVar.RemoveAnnotations(); // remove the reference to the property of the anonymous type + mre.ReplaceWith(newVar); + return; + } + } + } + + string ExtractExpressionName(ref Expression expr) + { + NamedExpression namedExpr = expr as NamedExpression; + if (namedExpr != null) { + expr = namedExpr.Expression; + return namedExpr.Name; + } + + IdentifierExpression identifier = expr as IdentifierExpression; + if (identifier != null) { + return identifier.Identifier; + } + + MemberReferenceExpression memberRef = expr as MemberReferenceExpression; + if (memberRef != null) { + return memberRef.MemberName; + } + + return null; + } + } +} \ No newline at end of file diff --git a/NRefactory/ICSharpCode.NRefactory.CSharp/Completion/CSharpCompletionEngine.cs b/NRefactory/ICSharpCode.NRefactory.CSharp/Completion/CSharpCompletionEngine.cs index 704218dd3..613d13262 100644 --- a/NRefactory/ICSharpCode.NRefactory.CSharp/Completion/CSharpCompletionEngine.cs +++ b/NRefactory/ICSharpCode.NRefactory.CSharp/Completion/CSharpCompletionEngine.cs @@ -1,4 +1,4 @@ -// +// // CSharpCompletionEngine.cs // // Author: @@ -27,7 +27,6 @@ using System; using System.Collections.Generic; using System.Linq; using System.Text; - using ICSharpCode.NRefactory.Completion; using ICSharpCode.NRefactory.CSharp.Refactoring; using ICSharpCode.NRefactory.CSharp.Resolver; @@ -38,26 +37,56 @@ using ICSharpCode.NRefactory.CSharp.TypeSystem; namespace ICSharpCode.NRefactory.CSharp.Completion { + public enum EditorBrowsableBehavior + { + Ignore, + Normal, + IncludeAdvanced + } + + public class CompletionEngineCache + { + public List namespaces; + public ICompletionData[] importCompletion; + } + public class CSharpCompletionEngine : CSharpCompletionEngineBase { internal ICompletionDataFactory factory; - + #region Additional input properties + public CSharpFormattingOptions FormattingPolicy { get; set; } - + public string EolMarker { get; set; } - + public string IndentString { get; set; } + + public bool AutomaticallyAddImports { get; set; } + + public bool IncludeKeywordsInCompletionList { get; set; } + + public EditorBrowsableBehavior EditorBrowsableBehavior { get; set; } + + public CompletionEngineCache CompletionEngineCache { get; set; } + #endregion - + #region Result properties + public bool AutoCompleteEmptyMatch; + /// + /// The auto complete empty match on curly bracket. (only taken into account when AutoCompleteEmptyMatch is true ) + /// + public bool AutoCompleteEmptyMatchOnCurlyBracket = true; public bool AutoSelect; public string DefaultCompletionString; public bool CloseOnSquareBrackets; -#endregion - - public CSharpCompletionEngine(IDocument document, ICompletionContextProvider completionContextProvider, ICompletionDataFactory factory, IProjectContent content, CSharpTypeResolveContext ctx) : base (content, completionContextProvider, ctx) + public readonly List PossibleDelegates = new List(); + + #endregion + + public CSharpCompletionEngine(IDocument document, ICompletionContextProvider completionContextProvider, ICompletionDataFactory factory, IProjectContent content, CSharpTypeResolveContext ctx) : base(content, completionContextProvider, ctx) { if (document == null) { throw new ArgumentNullException("document"); @@ -70,9 +99,11 @@ namespace ICSharpCode.NRefactory.CSharp.Completion // Set defaults for additional input properties this.FormattingPolicy = FormattingOptionsFactory.CreateMono(); this.EolMarker = Environment.NewLine; + this.IncludeKeywordsInCompletionList = true; + EditorBrowsableBehavior = EditorBrowsableBehavior.IncludeAdvanced; this.IndentString = "\t"; } - + public bool TryGetCompletionWord(int offset, out int startPos, out int wordLength) { startPos = wordLength = 0; @@ -85,10 +116,10 @@ namespace ICSharpCode.NRefactory.CSharp.Completion } if (pos == -1) return false; - + pos++; startPos = pos; - + while (pos < document.TextLength) { char c = document.GetCharAt(pos); if (!char.IsLetterOrDigit(c) && c != '_') @@ -98,7 +129,7 @@ namespace ICSharpCode.NRefactory.CSharp.Completion wordLength = pos - startPos; return true; } - + public IEnumerable GetCompletionData(int offset, bool controlSpace) { this.AutoCompleteEmptyMatch = true; @@ -107,16 +138,18 @@ namespace ICSharpCode.NRefactory.CSharp.Completion SetOffset(offset); if (offset > 0) { char lastChar = document.GetCharAt(offset - 1); - var result = MagicKeyCompletion(lastChar, controlSpace) ?? Enumerable.Empty(); - if (controlSpace && char.IsWhiteSpace(lastChar)) { + bool isComplete = false; + var result = MagicKeyCompletion(lastChar, controlSpace, out isComplete) ?? Enumerable.Empty(); + if (!isComplete && controlSpace && char.IsWhiteSpace(lastChar)) { offset -= 2; - while (offset >= 0 && char.IsWhiteSpace (document.GetCharAt (offset))) { + while (offset >= 0 && char.IsWhiteSpace(document.GetCharAt(offset))) { offset--; } if (offset > 0) { var nonWsResult = MagicKeyCompletion( document.GetCharAt(offset), - controlSpace + controlSpace, + out isComplete ); if (nonWsResult != null) { var text = new HashSet(result.Select(r => r.CompletionText)); @@ -124,12 +157,44 @@ namespace ICSharpCode.NRefactory.CSharp.Completion } } } - + return result; } return Enumerable.Empty(); } - + + /// + /// Gets the types that needs to be imported via using or full type name. + /// + public IEnumerable GetImportCompletionData(int offset) + { + var generalLookup = new MemberLookup(null, Compilation.MainAssembly); + SetOffset(offset); + + // flatten usings + var namespaces = new List(); + for (var n = ctx.CurrentUsingScope; n != null; n = n.Parent) { + namespaces.Add(n.Namespace); + foreach (var u in n.Usings) + namespaces.Add(u); + } + + foreach (var type in Compilation.GetAllTypeDefinitions ()) { + if (!generalLookup.IsAccessible(type, false)) + continue; + if (namespaces.Any(n => n.FullName == type.Namespace)) + continue; + bool useFullName = false; + foreach (var ns in namespaces) { + if (ns.GetTypeDefinition(type.Name, type.TypeParameterCount) != null) { + useFullName = true; + break; + } + } + yield return factory.CreateImportCompletionData(type, useFullName, false); + } + } + IEnumerable GenerateNameProposals(AstType type) { if (type is PrimitiveType) { @@ -166,9 +231,9 @@ namespace ICSharpCode.NRefactory.CSharp.Completion } else { yield break; } - + var names = WordParser.BreakWords(name); - + var possibleName = new StringBuilder(); for (int i = 0; i < names.Count; i++) { possibleName.Length = 0; @@ -184,44 +249,52 @@ namespace ICSharpCode.NRefactory.CSharp.Completion yield return possibleName.ToString(); } } - + IEnumerable HandleMemberReferenceCompletion(ExpressionResult expr) { - if (expr == null) + if (expr == null) return null; - - // do not complete . (but ..) + + // do not auto select . (but ..) (0.ToString() is valid) if (expr.Node is PrimitiveExpression) { var pexpr = (PrimitiveExpression)expr.Node; if (!(pexpr.Value is string || pexpr.Value is char) && !pexpr.LiteralValue.Contains('.')) { - return null; + AutoSelect = false; } } var resolveResult = ResolveExpression(expr); + if (resolveResult == null) { return null; } if (expr.Node is AstType) { + + // check for namespace names + if (expr.Node.AncestorsAndSelf + .TakeWhile(n => n is AstType) + .Any(m => m.Role == NamespaceDeclaration.NamespaceNameRole)) + return null; + // need to look at paren.parent because of "catch (.A" expression if (expr.Node.Parent != null && expr.Node.Parent.Parent is CatchClause) return HandleCatchClauseType(expr); return CreateTypeAndNamespaceCompletionData( location, - resolveResult.Item1, + resolveResult.Result, expr.Node, - resolveResult.Item2 + resolveResult.Resolver ); } - - + + return CreateCompletionData( location, - resolveResult.Item1, + resolveResult.Result, expr.Node, - resolveResult.Item2 + resolveResult.Resolver ); } - + bool IsInPreprocessorDirective() { var text = GetMemberTextToCaret().Item1; @@ -229,71 +302,355 @@ namespace ICSharpCode.NRefactory.CSharp.Completion miniLexer.Parse(); return miniLexer.IsInPreprocessorDirective; } - + IEnumerable HandleObjectInitializer(SyntaxTree unit, AstNode n) { var p = n.Parent; while (p != null && !(p is ObjectCreateExpression)) { p = p.Parent; } - var parent = (ArrayInitializerExpression)n.Parent; + var parent = n.Parent as ArrayInitializerExpression; + if (parent == null) + return null; if (parent.IsSingleElement) parent = (ArrayInitializerExpression)parent.Parent; if (p != null) { var contextList = new CompletionDataWrapper(this); var initializerResult = ResolveExpression(p); - if (initializerResult != null && initializerResult.Item1.Type.Kind != TypeKind.Unknown) { + IType initializerType = null; + + if (initializerResult.Result is DynamicInvocationResolveResult) { + var dr = (DynamicInvocationResolveResult)initializerResult.Result; + var constructor = (dr.Target as MethodGroupResolveResult).Methods.FirstOrDefault(); + if (constructor != null) + initializerType = constructor.DeclaringType; + } else { + initializerType = initializerResult != null ? initializerResult.Result.Type : null; + } + + + if (initializerType != null && initializerType.Kind != TypeKind.Unknown) { // check 3 cases: // 1) New initalizer { xpr // 2) Object initializer { prop = val1, field = val2, xpr // 3) Array initializer { new Foo (), a, xpr // in case 1 all object/array initializer options should be given - in the others not. - + AstNode prev = null; if (parent.Elements.Count > 1) { prev = parent.Elements.First(); - if (prev is ArrayInitializerExpression && ((ArrayInitializerExpression)prev).IsSingleElement) + if (prev is ArrayInitializerExpression && ((ArrayInitializerExpression)prev).IsSingleElement) prev = ((ArrayInitializerExpression)prev).Elements.FirstOrDefault(); } - + if (prev != null && !(prev is NamedExpression)) { AddContextCompletion(contextList, GetState(), n); // case 3) return contextList.Result; } - - foreach (var m in initializerResult.Item1.Type.GetMembers (m => m.IsPublic && (m.EntityType == EntityType.Property || m.EntityType == EntityType.Field))) { - contextList.AddMember(m); + var lookup = new MemberLookup(ctx.CurrentTypeDefinition, Compilation.MainAssembly); + var list = typeof(System.Collections.IList).ToTypeReference().Resolve(Compilation); + var list1 = typeof(System.Collections.Generic.IList<>).ToTypeReference().Resolve(Compilation); + bool isProtectedAllowed = ctx.CurrentTypeDefinition != null && initializerType.GetDefinition() != null ? + ctx.CurrentTypeDefinition.IsDerivedFrom(initializerType.GetDefinition()) : + false; + foreach (var m in initializerType.GetMembers (m => m.SymbolKind == SymbolKind.Field)) { + var f = m as IField; + if (f != null && (f.IsReadOnly || f.IsConst)) + continue; + if (lookup.IsAccessible(m, isProtectedAllowed)) { + var data = contextList.AddMember(m); + if (data != null) + data.DisplayFlags |= DisplayFlags.NamedArgument; + } + } + + foreach (IProperty m in initializerType.GetMembers (m => m.SymbolKind == SymbolKind.Property)) { + if (m.CanSet && lookup.IsAccessible(m.Setter, isProtectedAllowed) || + m.CanGet && lookup.IsAccessible(m.Getter, isProtectedAllowed) && m.ReturnType.GetDefinition() != null && + (m.ReturnType.GetDefinition().IsDerivedFrom(list.GetDefinition()) || m.ReturnType.GetDefinition().IsDerivedFrom(list1.GetDefinition()))) { + var data = contextList.AddMember(m); + if (data != null) + data.DisplayFlags |= DisplayFlags.NamedArgument; + } } - + if (prev != null && (prev is NamedExpression)) { // case 2) return contextList.Result; } - + // case 1) - + // check if the object is a list, if not only provide object initalizers - var list = typeof(System.Collections.IList).ToTypeReference().Resolve(Compilation); - if (initializerResult.Item1.Type.Kind != TypeKind.Array && list != null) { - var def = initializerResult.Item1.Type.GetDefinition(); - if (def != null && !def.IsDerivedFrom(list.GetDefinition())) + if (initializerType.Kind != TypeKind.Array && list != null) { + var def = initializerType.GetDefinition(); + if (def != null && !def.IsDerivedFrom(list.GetDefinition()) && !def.IsDerivedFrom(list1.GetDefinition())) return contextList.Result; } - + AddContextCompletion(contextList, GetState(), n); return contextList.Result; } } return null; } - - IEnumerable MagicKeyCompletion(char completionChar, bool controlSpace) + + static readonly DateTime curDate = DateTime.Now; + + IEnumerable GenerateNumberFormatitems(bool isFloatingPoint) + { + yield return factory.CreateFormatItemCompletionData("D", "decimal", 123); + yield return factory.CreateFormatItemCompletionData("D5", "decimal", 123); + yield return factory.CreateFormatItemCompletionData("C", "currency", 123); + yield return factory.CreateFormatItemCompletionData("C0", "currency", 123); + yield return factory.CreateFormatItemCompletionData("E", "exponential", 1.23E4); + yield return factory.CreateFormatItemCompletionData("E2", "exponential", 1.234); + yield return factory.CreateFormatItemCompletionData("e2", "exponential", 1.234); + yield return factory.CreateFormatItemCompletionData("F", "fixed-point", 123.45); + yield return factory.CreateFormatItemCompletionData("F1", "fixed-point", 123.45); + yield return factory.CreateFormatItemCompletionData("G", "general", 1.23E+56); + yield return factory.CreateFormatItemCompletionData("g2", "general", 1.23E+56); + yield return factory.CreateFormatItemCompletionData("N", "number", 12345.68); + yield return factory.CreateFormatItemCompletionData("N1", "number", 12345.68); + yield return factory.CreateFormatItemCompletionData("P", "percent", 12.34); + yield return factory.CreateFormatItemCompletionData("P1", "percent", 12.34); + yield return factory.CreateFormatItemCompletionData("R", "round-trip", 0.1230000001); + yield return factory.CreateFormatItemCompletionData("X", "hexadecimal", 1234); + yield return factory.CreateFormatItemCompletionData("x8", "hexadecimal", 1234); + yield return factory.CreateFormatItemCompletionData("0000", "custom", 123); + yield return factory.CreateFormatItemCompletionData("####", "custom", 123); + yield return factory.CreateFormatItemCompletionData("##.###", "custom", 1.23); + yield return factory.CreateFormatItemCompletionData("##.000", "custom", 1.23); + yield return factory.CreateFormatItemCompletionData("## 'items'", "custom", 12); + } + + IEnumerable GenerateDateTimeFormatitems() + { + yield return factory.CreateFormatItemCompletionData("D", "long date", curDate); + yield return factory.CreateFormatItemCompletionData("d", "short date", curDate); + yield return factory.CreateFormatItemCompletionData("F", "full date long", curDate); + yield return factory.CreateFormatItemCompletionData("f", "full date short", curDate); + yield return factory.CreateFormatItemCompletionData("G", "general long", curDate); + yield return factory.CreateFormatItemCompletionData("g", "general short", curDate); + yield return factory.CreateFormatItemCompletionData("M", "month", curDate); + yield return factory.CreateFormatItemCompletionData("O", "ISO 8601", curDate); + yield return factory.CreateFormatItemCompletionData("R", "RFC 1123", curDate); + yield return factory.CreateFormatItemCompletionData("s", "sortable", curDate); + yield return factory.CreateFormatItemCompletionData("T", "long time", curDate); + yield return factory.CreateFormatItemCompletionData("t", "short time", curDate); + yield return factory.CreateFormatItemCompletionData("U", "universal full", curDate); + yield return factory.CreateFormatItemCompletionData("u", "universal sortable", curDate); + yield return factory.CreateFormatItemCompletionData("Y", "year month", curDate); + yield return factory.CreateFormatItemCompletionData("yy-MM-dd", "custom", curDate); + yield return factory.CreateFormatItemCompletionData("yyyy MMMMM dd", "custom", curDate); + yield return factory.CreateFormatItemCompletionData("yy-MMM-dd ddd", "custom", curDate); + yield return factory.CreateFormatItemCompletionData("yyyy-M-d dddd", "custom", curDate); + yield return factory.CreateFormatItemCompletionData("hh:mm:ss t z", "custom", curDate); + yield return factory.CreateFormatItemCompletionData("hh:mm:ss tt zz", "custom", curDate); + yield return factory.CreateFormatItemCompletionData("HH:mm:ss tt zz", "custom", curDate); + yield return factory.CreateFormatItemCompletionData("HH:m:s tt zz", "custom", curDate); + + } + + [Flags] + enum TestEnum + { + EnumCaseName = 0, + Flag1 = 1, + Flag2 = 2, + Flags + + } + + IEnumerable GenerateEnumFormatitems() + { + yield return factory.CreateFormatItemCompletionData("G", "string value", TestEnum.EnumCaseName); + yield return factory.CreateFormatItemCompletionData("F", "flags value", TestEnum.Flags); + yield return factory.CreateFormatItemCompletionData("D", "integer value", TestEnum.Flags); + yield return factory.CreateFormatItemCompletionData("X", "hexadecimal", TestEnum.Flags); + } + + IEnumerable GenerateTimeSpanFormatitems() + { + yield return factory.CreateFormatItemCompletionData("c", "invariant", new TimeSpan(0, 1, 23, 456)); + yield return factory.CreateFormatItemCompletionData("G", "general long", new TimeSpan(0, 1, 23, 456)); + yield return factory.CreateFormatItemCompletionData("g", "general short", new TimeSpan(0, 1, 23, 456)); + } + + static Guid defaultGuid = Guid.NewGuid(); + + IEnumerable GenerateGuidFormatitems() + { + yield return factory.CreateFormatItemCompletionData("N", "digits", defaultGuid); + yield return factory.CreateFormatItemCompletionData("D", "hypens", defaultGuid); + yield return factory.CreateFormatItemCompletionData("B", "braces", defaultGuid); + yield return factory.CreateFormatItemCompletionData("P", "parentheses", defaultGuid); + } + + int GetFormatItemNumber() + { + int number = 0; + var o = offset - 2; + while (o > 0) { + char ch = document.GetCharAt(o); + if (ch == '{') + return number; + if (!char.IsDigit(ch)) + break; + number = number * 10 + ch - '0'; + o--; + } + return -1; + } + + IEnumerable HandleStringFormatItems() { - Tuple resolveResult; + var formatArgument = GetFormatItemNumber(); + if (formatArgument < 0) + return Enumerable.Empty(); + var followUp = new StringBuilder(); + + var o = offset; + while (o < document.TextLength) { + char ch = document.GetCharAt(o); + followUp.Append(ch); + o++; + if (ch == ';') + break; + } + var unit = ParseStub(followUp.ToString(), false); + + var invoke = unit.GetNodeAt(location); + + if (invoke != null) { + var resolveResult = ResolveExpression(new ExpressionResult(invoke, unit)); + var invokeResult = resolveResult.Result as InvocationResolveResult; + if (invokeResult != null) { + var arg = formatArgument + 1; // First argument is the format string + if (arg < invoke.Arguments.Count) { + var invokeArgument = ResolveExpression(new ExpressionResult(invoke.Arguments.ElementAt(arg), unit)); + if (invokeArgument != null) { + var provider = GetFormatCompletionData(invokeArgument.Result.Type); + if (provider != null) + return provider; + if (!invokeArgument.Result.Type.IsKnownType(KnownTypeCode.Object)) + return Enumerable.Empty(); + } + } + } + } + return HandleStringFormatItemsFallback(); + } + + IEnumerable HandleStringFormatItemsFallback() + { + var unit = ParseStub("a}\");", false); + + var invoke = unit.GetNodeAt(location); + + if (invoke == null) + return Enumerable.Empty(); + + var resolveResult = ResolveExpression(new ExpressionResult(invoke, unit)); + var invokeResult = resolveResult.Result as CSharpInvocationResolveResult; + if (invokeResult == null) + return Enumerable.Empty(); + + Expression fmtArgumets; + IList args; + if (FormatStringHelper.TryGetFormattingParameters(invokeResult, invoke, out fmtArgumets, out args, null)) { + return GenerateNumberFormatitems(false) + .Concat(GenerateDateTimeFormatitems()) + .Concat(GenerateTimeSpanFormatitems()) + .Concat(GenerateEnumFormatitems()) + .Concat(GenerateGuidFormatitems()); + } + return Enumerable.Empty(); + + } + + IEnumerable GetFormatCompletionData(IType type) + { + if (type.Namespace != "System") + return null; + switch (type.Name) { + case "Int64": + case "UInt64": + case "Int32": + case "UInt32": + case "Int16": + case "UInt16": + case "Byte": + case "SByte": + return GenerateNumberFormatitems(false); + case "Single": + case "Double": + case "Decimal": + return GenerateNumberFormatitems(true); + case "Enum": + return GenerateEnumFormatitems(); + case "DateTime": + return GenerateDateTimeFormatitems(); + case "TimeSpan": + return GenerateTimeSpanFormatitems(); + case "Guid": + return GenerateGuidFormatitems(); + } + return null; + } + + IEnumerable HandleToStringFormatItems() + { + var unit = ParseStub("\");", false); + + var invoke = unit.GetNodeAt(location); + if (invoke == null) + return Enumerable.Empty(); + + var resolveResult = ResolveExpression(new ExpressionResult(invoke, unit)); + var invokeResult = resolveResult.Result as InvocationResolveResult; + if (invokeResult == null) + return Enumerable.Empty(); + if (invokeResult.Member.Name == "ToString") + return GetFormatCompletionData(invokeResult.Member.DeclaringType) ?? Enumerable.Empty(); + return Enumerable.Empty(); + } + + IEnumerable MagicKeyCompletion(char completionChar, bool controlSpace, out bool isComplete) + { + isComplete = false; + ExpressionResolveResult resolveResult; switch (completionChar) { - // Magic key completion + // Magic key completion case ':': + var text = GetMemberTextToCaret(); + var lexer = new MiniLexer(text.Item1); + lexer.Parse(); + if (lexer.IsInSingleComment || + lexer.IsInChar || + lexer.IsInMultiLineComment || + lexer.IsInPreprocessorDirective) { + return Enumerable.Empty(); + } + + if (lexer.IsInString || lexer.IsInVerbatimString) + return HandleStringFormatItems(); + return HandleMemberReferenceCompletion(GetExpressionBeforeCursor()); + case '"': + text = GetMemberTextToCaret(); + lexer = new MiniLexer(text.Item1); + lexer.Parse(); + if (lexer.IsInSingleComment || + lexer.IsInChar || + lexer.IsInMultiLineComment || + lexer.IsInPreprocessorDirective) { + return Enumerable.Empty(); + } + + if (lexer.IsInString || lexer.IsInVerbatimString) + return HandleToStringFormatItems(); + return Enumerable.Empty(); case '.': if (IsInsideCommentStringOrDirective()) { return Enumerable.Empty(); @@ -303,13 +660,13 @@ namespace ICSharpCode.NRefactory.CSharp.Completion if (!IsInPreprocessorDirective()) return null; return GetDirectiveCompletionData(); - // XML doc completion + // XML doc completion case '<': if (IsInsideDocComment()) { return GetXmlDocumentationCompletionData(); } if (controlSpace) { - return DefaultControlSpaceItems(); + return DefaultControlSpaceItems(ref isComplete); } return null; case '>': @@ -319,33 +676,9 @@ namespace ICSharpCode.NRefactory.CSharp.Completion } return null; } - string lineText = document.GetText(document.GetLineByNumber(location.Line)); - int startIndex = Math.Min(location.Column - 1, lineText.Length - 1); - while (startIndex >= 0 && lineText [startIndex] != '<') { - --startIndex; - if (lineText [startIndex] == '/') { - // already closed. - startIndex = -1; - break; - } - } - - if (startIndex >= 0) { - int endIndex = startIndex; - while (endIndex <= location.Column && endIndex < lineText.Length && !Char.IsWhiteSpace (lineText [endIndex])) { - endIndex++; - } - string tag = endIndex - startIndex - 1 > 0 ? lineText.Substring( - startIndex + 1, - endIndex - startIndex - 2 - ) : null; - if (!string.IsNullOrEmpty(tag) && commentTags.IndexOf(tag) >= 0) { - document.Insert(offset, "", AnchorMovementType.BeforeInsertion); - } - } return null; - - // Parameter completion + + // Parameter completion case '(': if (IsInsideCommentStringOrDirective()) { return null; @@ -353,7 +686,7 @@ namespace ICSharpCode.NRefactory.CSharp.Completion var invoke = GetInvocationBeforeCursor(true); if (invoke == null) { if (controlSpace) - return DefaultControlSpaceItems(invoke); + return DefaultControlSpaceItems(ref isComplete, invoke); return null; } if (invoke.Node is TypeOfExpression) { @@ -363,75 +696,74 @@ namespace ICSharpCode.NRefactory.CSharp.Completion if (invocationResult == null) { return null; } - var methodGroup = invocationResult.Item1 as MethodGroupResolveResult; + var methodGroup = invocationResult.Result as MethodGroupResolveResult; if (methodGroup != null) { return CreateParameterCompletion( - methodGroup, - invocationResult.Item2, - invoke.Node, - invoke.Unit, - 0, - controlSpace + methodGroup, + invocationResult.Resolver, + invoke.Node, + invoke.Unit, + 0, + controlSpace ); } - + if (controlSpace) { - return DefaultControlSpaceItems(invoke); + return DefaultControlSpaceItems(ref isComplete, invoke); } return null; case '=': - return controlSpace ? DefaultControlSpaceItems() : null; + return controlSpace ? DefaultControlSpaceItems(ref isComplete) : null; case ',': int cpos2; if (!GetParameterCompletionCommandOffset(out cpos2)) { return null; } - // completionContext = CompletionWidget.CreateCodeCompletionContext (cpos2); - // int currentParameter2 = MethodParameterDataProvider.GetCurrentParameterIndex (CompletionWidget, completionContext) - 1; - // return CreateParameterCompletion (CreateResolver (), location, ExpressionContext.MethodBody, provider.Methods, currentParameter); + // completionContext = CompletionWidget.CreateCodeCompletionContext (cpos2); + // int currentParameter2 = MethodParameterDataProvider.GetCurrentParameterIndex (CompletionWidget, completionContext) - 1; + // return CreateParameterCompletion (CreateResolver (), location, ExpressionContext.MethodBody, provider.Methods, currentParameter); break; - - // Completion on space: + + // Completion on space: case ' ': int tokenIndex = offset; string token = GetPreviousToken(ref tokenIndex, false); if (IsInsideCommentStringOrDirective()) { - if (IsInPreprocessorDirective()) - return HandleKeywordCompletion(tokenIndex, token); return null; } - // check propose name, for context (but only in control space context) - //IType isAsType = null; + // check propose name, for context (but only in control space context) + //IType isAsType = null; var isAsExpression = GetExpressionAt(offset); if (controlSpace && isAsExpression != null && isAsExpression.Node is VariableDeclarationStatement && token != "new") { var parent = isAsExpression.Node as VariableDeclarationStatement; var proposeNameList = new CompletionDataWrapper(this); if (parent.Variables.Count != 1) - return DefaultControlSpaceItems(isAsExpression, controlSpace); - + return DefaultControlSpaceItems(ref isComplete, isAsExpression, controlSpace); + foreach (var possibleName in GenerateNameProposals (parent.Type)) { if (possibleName.Length > 0) { proposeNameList.Result.Add(factory.CreateLiteralCompletionData(possibleName.ToString())); } } - + AutoSelect = false; AutoCompleteEmptyMatch = false; + isComplete = true; return proposeNameList.Result; } - // int tokenIndex = offset; - // string token = GetPreviousToken (ref tokenIndex, false); - // if (result.ExpressionContext == ExpressionContext.ObjectInitializer) { - // resolver = CreateResolver (); - // ExpressionContext exactContext = new NewCSharpExpressionFinder (dom).FindExactContextForObjectInitializer (document, resolver.Unit, Document.FileName, resolver.CallingType); - // IReturnType objectInitializer = ((ExpressionContext.TypeExpressionContext)exactContext).UnresolvedType; - // if (objectInitializer != null && objectInitializer.ArrayDimensions == 0 && objectInitializer.PointerNestingLevel == 0 && (token == "{" || token == ",")) - // return CreateCtrlSpaceCompletionData (completionContext, result); - // } + // int tokenIndex = offset; + // string token = GetPreviousToken (ref tokenIndex, false); + // if (result.ExpressionContext == ExpressionContext.ObjectInitializer) { + // resolver = CreateResolver (); + // ExpressionContext exactContext = new NewCSharpExpressionFinder (dom).FindExactContextForObjectInitializer (document, resolver.Unit, Document.FileName, resolver.CallingType); + // IReturnType objectInitializer = ((ExpressionContext.TypeExpressionContext)exactContext).UnresolvedType; + // if (objectInitializer != null && objectInitializer.ArrayDimensions == 0 && objectInitializer.PointerNestingLevel == 0 && (token == "{" || token == ",")) + // return CreateCtrlSpaceCompletionData (completionContext, result); + // } if (token == "=") { int j = tokenIndex; string prevToken = GetPreviousToken(ref j, false); - if (prevToken == "=" || prevToken == "+" || prevToken == "-") { + if (prevToken == "=" || prevToken == "+" || prevToken == "-" || prevToken == "!") { token = prevToken + token; tokenIndex = j; } @@ -455,81 +787,81 @@ namespace ICSharpCode.NRefactory.CSharp.Completion if (invocationResult == null) { return null; } - methodGroup = invocationResult.Item1 as MethodGroupResolveResult; + methodGroup = invocationResult.Result as MethodGroupResolveResult; if (methodGroup != null) { return CreateParameterCompletion( - methodGroup, - invocationResult.Item2, - invoke.Node, - invoke.Unit, - currentParameter, - controlSpace); + methodGroup, + invocationResult.Resolver, + invoke.Node, + invoke.Unit, + currentParameter, + controlSpace); } return null; case "=": case "==": + case "!=": GetPreviousToken(ref tokenIndex, false); var expressionOrVariableDeclaration = GetExpressionAt(tokenIndex); if (expressionOrVariableDeclaration == null) { return null; } - resolveResult = ResolveExpression(expressionOrVariableDeclaration); - if (resolveResult == null) { return null; } - if (resolveResult.Item1.Type.Kind == TypeKind.Enum) { + if (resolveResult.Result.Type.Kind == TypeKind.Enum) { var wrapper = new CompletionDataWrapper(this); AddContextCompletion( - wrapper, - resolveResult.Item2, - expressionOrVariableDeclaration.Node); - AddEnumMembers(wrapper, resolveResult.Item1.Type, resolveResult.Item2); + wrapper, + resolveResult.Resolver, + expressionOrVariableDeclaration.Node); + AddEnumMembers(wrapper, resolveResult.Result.Type, resolveResult.Resolver); AutoCompleteEmptyMatch = false; return wrapper.Result; } - // - // if (resolvedType.FullName == DomReturnType.Bool.FullName) { - // CompletionDataList completionList = new ProjectDomCompletionDataList (); - // CompletionDataCollector cdc = new CompletionDataCollector (this, dom, completionList, Document.CompilationUnit, resolver.CallingType, location); - // completionList.AutoCompleteEmptyMatch = false; - // cdc.Add ("true", "md-keyword"); - // cdc.Add ("false", "md-keyword"); - // resolver.AddAccessibleCodeCompletionData (result.ExpressionContext, cdc); - // return completionList; - // } - // if (resolvedType.ClassType == ClassType.Delegate && token == "=") { - // CompletionDataList completionList = new ProjectDomCompletionDataList (); - // string parameterDefinition = AddDelegateHandlers (completionList, resolvedType); - // string varName = GetPreviousMemberReferenceExpression (tokenIndex); - // completionList.Add (new EventCreationCompletionData (document, varName, resolvedType, null, parameterDefinition, resolver.CallingMember, resolvedType)); - // - // CompletionDataCollector cdc = new CompletionDataCollector (this, dom, completionList, Document.CompilationUnit, resolver.CallingType, location); - // resolver.AddAccessibleCodeCompletionData (result.ExpressionContext, cdc); - // foreach (var data in completionList) { - // if (data is MemberCompletionData) - // ((MemberCompletionData)data).IsDelegateExpected = true; - // } - // return completionList; - // } + // + // if (resolvedType.FullName == DomReturnType.Bool.FullName) { + // CompletionDataList completionList = new ProjectDomCompletionDataList (); + // CompletionDataCollector cdc = new CompletionDataCollector (this, dom, completionList, Document.CompilationUnit, resolver.CallingType, location); + // completionList.AutoCompleteEmptyMatch = false; + // cdc.Add ("true", "md-keyword"); + // cdc.Add ("false", "md-keyword"); + // resolver.AddAccessibleCodeCompletionData (result.ExpressionContext, cdc); + // return completionList; + // } + // if (resolvedType.ClassType == ClassType.Delegate && token == "=") { + // CompletionDataList completionList = new ProjectDomCompletionDataList (); + // string parameterDefinition = AddDelegateHandlers (completionList, resolvedType); + // string varName = GetPreviousMemberReferenceExpression (tokenIndex); + // completionList.Add (new EventCreationCompletionData (document, varName, resolvedType, null, parameterDefinition, resolver.CallingMember, resolvedType)); + // + // CompletionDataCollector cdc = new CompletionDataCollector (this, dom, completionList, Document.CompilationUnit, resolver.CallingType, location); + // resolver.AddAccessibleCodeCompletionData (result.ExpressionContext, cdc); + // foreach (var data in completionList) { + // if (data is MemberCompletionData) + // ((MemberCompletionData)data).IsDelegateExpected = true; + // } + // return completionList; + // } return null; case "+=": case "-=": + var curTokenIndex = tokenIndex; GetPreviousToken(ref tokenIndex, false); - + expressionOrVariableDeclaration = GetExpressionAt(tokenIndex); if (expressionOrVariableDeclaration == null) { return null; } - + resolveResult = ResolveExpression(expressionOrVariableDeclaration); if (resolveResult == null) { return null; } - - - var mrr = resolveResult.Item1 as MemberResolveResult; + + + var mrr = resolveResult.Result as MemberResolveResult; if (mrr != null) { var evt = mrr.Member as IEvent; if (evt == null) { @@ -539,12 +871,12 @@ namespace ICSharpCode.NRefactory.CSharp.Completion if (delegateType.Kind != TypeKind.Delegate) { return null; } - + var wrapper = new CompletionDataWrapper(this); if (currentType != null) { // bool includeProtected = DomType.IncludeProtected (dom, typeFromDatabase, resolver.CallingType); foreach (var method in ctx.CurrentTypeDefinition.Methods) { - if (MatchDelegate(delegateType, method) /*&& method.IsAccessibleFrom (dom, resolver.CallingType, resolver.CallingMember, includeProtected) &&*/) { + if (MatchDelegate(delegateType, method) /* && method.IsAccessibleFrom (dom, resolver.CallingType, resolver.CallingMember, includeProtected) &&*/) { wrapper.AddMember(method); // data.SetText (data.CompletionText + ";"); } @@ -552,21 +884,12 @@ namespace ICSharpCode.NRefactory.CSharp.Completion } if (token == "+=") { string parameterDefinition = AddDelegateHandlers( - wrapper, - delegateType - ); - string varName = GetPreviousMemberReferenceExpression(tokenIndex); - wrapper.Result.Add( - factory.CreateEventCreationCompletionData( - varName, - delegateType, - evt, - parameterDefinition, - currentMember, - currentType) + wrapper, + delegateType, + optDelegateName: GuessEventHandlerMethodName(curTokenIndex) ); } - + return wrapper.Result; } return null; @@ -577,28 +900,52 @@ namespace ICSharpCode.NRefactory.CSharp.Completion if (token == "enum") return HandleEnumContext(); var wrapper = new CompletionDataWrapper(this); - AddTypesAndNamespaces( - wrapper, - GetState(), - null, - t => currentType != null && !currentType.ReflectionName.Equals(t.ReflectionName) ? t : null + wrapper, + GetState(), + null, + t => { + if (currentType != null && currentType.ReflectionName.Equals(t.ReflectionName)) + return null; + var def = t.GetDefinition(); + if (def != null && t.Kind != TypeKind.Interface && (def.IsSealed ||def.IsStatic)) + return null; + return t; + } ); return wrapper.Result; } return null; } - + var keywordCompletion = HandleKeywordCompletion(tokenIndex, token); if (keywordCompletion == null && controlSpace) { goto default; } return keywordCompletion; - // Automatic completion + // Automatic completion default: if (IsInsideCommentStringOrDirective()) { + tokenIndex = offset; + token = GetPreviousToken(ref tokenIndex, false); + if (IsInPreprocessorDirective() && (token.Length == 1 && char.IsLetter(completionChar) || controlSpace)) { + while (token != null && document.GetCharAt(tokenIndex - 1) != '#') { + token = GetPreviousToken(ref tokenIndex, false); + } + if (token != null) + return HandleKeywordCompletion(tokenIndex, token); + } return null; } + char prevCh = offset > 2 ? document.GetCharAt(offset - 2) : ';'; + char nextCh = offset < document.TextLength ? document.GetCharAt(offset) : ' '; + const string allowedChars = ";,.[](){}+-*/%^?:&|~!<>="; + + if ((!Char.IsWhiteSpace(nextCh) && allowedChars.IndexOf(nextCh) < 0) || !(Char.IsWhiteSpace(prevCh) || allowedChars.IndexOf(prevCh) >= 0)) { + if (!controlSpace) + return null; + } + if (IsInLinqContext(offset)) { if (!controlSpace && !(char.IsLetter(completionChar) || completionChar == '_')) { return null; @@ -610,67 +957,70 @@ namespace ICSharpCode.NRefactory.CSharp.Completion token = GetPreviousToken(ref tokenIndex, false); } // token last typed - + if (linqKeywords.Contains(token)) { if (token == "from") { // after from no auto code completion. return null; } - return DefaultControlSpaceItems(); + return DefaultControlSpaceItems(ref isComplete); } var dataList = new CompletionDataWrapper(this); AddKeywords(dataList, linqKeywords); return dataList.Result; } if (currentType != null && currentType.Kind == TypeKind.Enum) { + if (!char.IsLetter(completionChar)) + return null; return HandleEnumContext(); } var contextList = new CompletionDataWrapper(this); var identifierStart = GetExpressionAtCursor(); + if (!(char.IsLetter(completionChar) || completionChar == '_') && (!controlSpace || identifierStart == null)) { + return controlSpace ? HandleAccessorContext() ?? DefaultControlSpaceItems(ref isComplete, identifierStart) : null; + } + if (identifierStart != null) { if (identifierStart.Node is TypeParameterDeclaration) { return null; } - + if (identifierStart.Node is MemberReferenceExpression) { return HandleMemberReferenceCompletion( - new ExpressionResult( - ((MemberReferenceExpression)identifierStart.Node).Target, - identifierStart.Unit - ) + new ExpressionResult( + ((MemberReferenceExpression)identifierStart.Node).Target, + identifierStart.Unit + ) ); } - + if (identifierStart.Node is Identifier) { + if (identifierStart.Node.Parent is GotoStatement) + return null; + // May happen in variable names - return controlSpace ? DefaultControlSpaceItems(identifierStart) : null; + return controlSpace ? DefaultControlSpaceItems(ref isComplete, identifierStart) : null; } if (identifierStart.Node is VariableInitializer && location <= ((VariableInitializer)identifierStart.Node).NameToken.EndLocation) { - return controlSpace ? HandleAccessorContext() ?? DefaultControlSpaceItems(identifierStart) : null; + return controlSpace ? HandleAccessorContext() ?? DefaultControlSpaceItems(ref isComplete, identifierStart) : null; } - if (identifierStart.Node is CatchClause) { - if (((CatchClause)identifierStart.Node).VariableNameToken.Contains(location)) { + if (((CatchClause)identifierStart.Node).VariableNameToken.IsInside(location)) { return null; } + } + if (identifierStart.Node is AstType && identifierStart.Node.Parent is CatchClause) { return HandleCatchClauseType(identifierStart); } + + var pDecl = identifierStart.Node as ParameterDeclaration; + if (pDecl != null && pDecl.Parent is LambdaExpression) { + return null; + } } - if (!(char.IsLetter(completionChar) || completionChar == '_') && (!controlSpace || identifierStart == null || !(identifierStart.Node.Parent is ArrayInitializerExpression))) { - return controlSpace ? HandleAccessorContext() ?? DefaultControlSpaceItems(identifierStart) : null; - } - - char prevCh = offset > 2 ? document.GetCharAt(offset - 2) : ';'; - char nextCh = offset < document.TextLength ? document.GetCharAt(offset) : ' '; - const string allowedChars = ";,.[](){}+-*/%^?:&|~!<>="; - if (!Char.IsWhiteSpace(nextCh) && allowedChars.IndexOf(nextCh) < 0) { - return null; - } - if (!(Char.IsWhiteSpace(prevCh) || allowedChars.IndexOf(prevCh) >= 0)) { - return null; - } - - // Do not pop up completion on identifier identifier (should be handled by keyword completion). + + + // Do not pop up completion on identifier identifier (should be handled by keyword completion). tokenIndex = offset - 1; token = GetPreviousToken(ref tokenIndex, false); if (token == "class" || token == "interface" || token == "struct" || token == "enum" || token == "namespace") { @@ -681,73 +1031,72 @@ namespace ICSharpCode.NRefactory.CSharp.Completion if (keywordresult != null) { return keywordresult; } - + + if ((!Char.IsWhiteSpace(nextCh) && allowedChars.IndexOf(nextCh) < 0) || !(Char.IsWhiteSpace(prevCh) || allowedChars.IndexOf(prevCh) >= 0)) { + if (controlSpace) + return DefaultControlSpaceItems(ref isComplete, identifierStart); + } + int prevTokenIndex = tokenIndex; var prevToken2 = GetPreviousToken(ref prevTokenIndex, false); if (prevToken2 == "delegate") { // after these always follows a name return null; } - + if (identifierStart == null && !string.IsNullOrEmpty(token) && !IsInsideCommentStringOrDirective() && (prevToken2 == ";" || prevToken2 == "{" || prevToken2 == "}")) { char last = token [token.Length - 1]; if (char.IsLetterOrDigit(last) || last == '_' || token == ">") { return HandleKeywordCompletion(tokenIndex, token); } } - if (identifierStart == null) { var accCtx = HandleAccessorContext(); if (accCtx != null) { return accCtx; } - return DefaultControlSpaceItems(null, controlSpace); + return DefaultControlSpaceItems(ref isComplete, null, controlSpace); } CSharpResolver csResolver; AstNode n = identifierStart.Node; + if (n.Parent is NamedArgumentExpression) + n = n.Parent; + if (n != null && n.Parent is AnonymousTypeCreateExpression) { AutoSelect = false; } - - // Handle foreach (type name _ + + // new { b$ } + if (n is IdentifierExpression && n.Parent is AnonymousTypeCreateExpression) + return null; + + // Handle foreach (type name _ if (n is IdentifierExpression) { var prev = n.GetPrevNode() as ForeachStatement; + while (prev != null && prev.EmbeddedStatement is ForeachStatement) + prev = (ForeachStatement)prev.EmbeddedStatement; if (prev != null && prev.InExpression.IsNull) { - if (controlSpace) { + if (IncludeKeywordsInCompletionList) contextList.AddCustom("in"); - return contextList.Result; - } - return null; + return contextList.Result; } - - // var astResolver = new CSharpAstResolver( - // GetState(), - // identifierStart.Unit, - // CSharpUnresolvedFile - // ); - // - // foreach (var type in CreateFieldAction.GetValidTypes(astResolver, (Expression)n)) { - // if (type.Kind == TypeKind.Delegate) { - // AddDelegateHandlers(contextList, type, false, false); - // AutoSelect = false; - // AutoCompleteEmptyMatch = false; - // } - // } } - - // Handle object/enumerable initialzer expressions: "new O () { P$" - if (n is IdentifierExpression && n.Parent is ArrayInitializerExpression) { + // Handle object/enumerable initialzer expressions: "new O () { P$" + if (n is IdentifierExpression && n.Parent is ArrayInitializerExpression && !(n.Parent.Parent is ArrayCreateExpression)) { var result = HandleObjectInitializer(identifierStart.Unit, n); if (result != null) return result; } - - if (n != null && n.Parent is InvocationExpression) { + + if (n != null && n.Parent is InvocationExpression || + n.Parent is ParenthesizedExpression && n.Parent.Parent is InvocationExpression) { + if (n.Parent is ParenthesizedExpression) + n = n.Parent; var invokeParent = (InvocationExpression)n.Parent; var invokeResult = ResolveExpression( - invokeParent.Target + invokeParent.Target ); - var mgr = invokeResult != null ? invokeResult.Item1 as MethodGroupResolveResult : null; + var mgr = invokeResult != null ? invokeResult.Result as MethodGroupResolveResult : null; if (mgr != null) { int idx = 0; foreach (var arg in invokeParent.Arguments) { @@ -756,7 +1105,7 @@ namespace ICSharpCode.NRefactory.CSharp.Completion } idx++; } - + foreach (var method in mgr.Methods) { if (idx < method.Parameters.Count && method.Parameters [idx].Type.Kind == TypeKind.Delegate) { AutoSelect = false; @@ -777,10 +1126,10 @@ namespace ICSharpCode.NRefactory.CSharp.Completion } } } - + if (n != null && n.Parent is ObjectCreateExpression) { var invokeResult = ResolveExpression(n.Parent); - var mgr = invokeResult != null ? invokeResult.Item1 as ResolveResult : null; + var mgr = invokeResult != null ? invokeResult.Result as ResolveResult : null; if (mgr != null) { foreach (var constructor in mgr.Type.GetConstructors ()) { foreach (var p in constructor.Parameters) { @@ -789,70 +1138,75 @@ namespace ICSharpCode.NRefactory.CSharp.Completion } } } - + if (n is IdentifierExpression) { var bop = n.Parent as BinaryOperatorExpression; Expression evaluationExpr = null; - + if (bop != null && bop.Right == n && (bop.Operator == BinaryOperatorType.Equality || bop.Operator == BinaryOperatorType.InEquality)) { evaluationExpr = bop.Left; } // check for compare to enum case if (evaluationExpr != null) { resolveResult = ResolveExpression(evaluationExpr); - if (resolveResult != null && resolveResult.Item1.Type.Kind == TypeKind.Enum) { + if (resolveResult != null && resolveResult.Result.Type.Kind == TypeKind.Enum) { var wrapper = new CompletionDataWrapper(this); AddContextCompletion( - wrapper, - resolveResult.Item2, - evaluationExpr + wrapper, + resolveResult.Resolver, + evaluationExpr ); - AddEnumMembers(wrapper, resolveResult.Item1.Type, resolveResult.Item2); + AddEnumMembers(wrapper, resolveResult.Result.Type, resolveResult.Resolver); AutoCompleteEmptyMatch = false; return wrapper.Result; } } } - + if (n is Identifier && n.Parent is ForeachStatement) { if (controlSpace) { - return DefaultControlSpaceItems(); + return DefaultControlSpaceItems(ref isComplete); } return null; } - + if (n is ArrayInitializerExpression) { // check for new [] {...} expression -> no need to resolve the type there var parent = n.Parent as ArrayCreateExpression; if (parent != null && parent.Type.IsNull) { - return DefaultControlSpaceItems(); + return DefaultControlSpaceItems(ref isComplete); } - + var initalizerResult = ResolveExpression(n.Parent); - + var concreteNode = identifierStart.Unit.GetNodeAt(location); // check if we're on the right side of an initializer expression if (concreteNode != null && concreteNode.Parent != null && concreteNode.Parent.Parent != null && concreteNode.Identifier != "a" && concreteNode.Parent.Parent is NamedExpression) { - return DefaultControlSpaceItems(); + return DefaultControlSpaceItems(ref isComplete); } - if (initalizerResult != null && initalizerResult.Item1.Type.Kind != TypeKind.Unknown) { - - foreach (var property in initalizerResult.Item1.Type.GetProperties ()) { + if (initalizerResult != null && initalizerResult.Result.Type.Kind != TypeKind.Unknown) { + + foreach (var property in initalizerResult.Result.Type.GetProperties ()) { if (!property.IsPublic) { continue; } - contextList.AddMember(property); + var data = contextList.AddMember(property); + if (data != null) + data.DisplayFlags |= DisplayFlags.NamedArgument; } - foreach (var field in initalizerResult.Item1.Type.GetFields ()) { + foreach (var field in initalizerResult.Result.Type.GetFields ()) { if (!field.IsPublic) { continue; } - contextList.AddMember(field); + var data = contextList.AddMember(field); + if (data != null) + data.DisplayFlags |= DisplayFlags.NamedArgument; } return contextList.Result; } - return DefaultControlSpaceItems(); + return DefaultControlSpaceItems(ref isComplete); } + if (IsAttributeContext(n)) { // add attribute targets if (currentType == null) { @@ -870,16 +1224,16 @@ namespace ICSharpCode.NRefactory.CSharp.Completion } if (n is MemberType) { resolveResult = ResolveExpression( - ((MemberType)n).Target + ((MemberType)n).Target ); return CreateTypeAndNamespaceCompletionData( - location, - resolveResult.Item1, - ((MemberType)n).Target, - resolveResult.Item2 + location, + resolveResult.Result, + ((MemberType)n).Target, + resolveResult.Resolver ); } - if (n != null/* && !(identifierStart.Item2 is TypeDeclaration)*/) { + if (n != null/* && !(identifierStart.Item2 is TypeDeclaration)*/) { csResolver = new CSharpResolver(ctx); var nodes = new List(); nodes.Add(n); @@ -895,96 +1249,91 @@ namespace ICSharpCode.NRefactory.CSharp.Completion } // add attribute properties. if (n.Parent is ICSharpCode.NRefactory.CSharp.Attribute) { - var resolved = astResolver.Resolve(n.Parent); - if (resolved != null && resolved.Type != null) { - foreach (var property in resolved.Type.GetProperties (p => p.Accessibility == Accessibility.Public)) { - contextList.AddMember(property); - } - foreach (var field in resolved.Type.GetFields (p => p.Accessibility == Accessibility.Public)) { - contextList.AddMember(field); - } - } + var rr = ResolveExpression(n.Parent); + if (rr != null) + AddAttributeProperties(contextList, rr.Result); } } else { csResolver = GetState(); } - // identifier has already started with the first letter + // identifier has already started with the first letter offset--; AddContextCompletion( - contextList, - csResolver, - identifierStart.Node + contextList, + csResolver, + identifierStart.Node ); return contextList.Result; - // if (stub.Parent is BlockStatement) - - // result = FindExpression (dom, completionContext, -1); - // if (result == null) - // return null; - // else if (result.ExpressionContext != ExpressionContext.IdentifierExpected) { - // triggerWordLength = 1; - // bool autoSelect = true; - // IType returnType = null; - // if ((prevCh == ',' || prevCh == '(') && GetParameterCompletionCommandOffset (out cpos)) { - // ctx = CompletionWidget.CreateCodeCompletionContext (cpos); - // NRefactoryParameterDataProvider dataProvider = ParameterCompletionCommand (ctx) as NRefactoryParameterDataProvider; - // if (dataProvider != null) { - // int i = dataProvider.GetCurrentParameterIndex (CompletionWidget, ctx) - 1; - // foreach (var method in dataProvider.Methods) { - // if (i < method.Parameters.Count) { - // returnType = dom.GetType (method.Parameters [i].ReturnType); - // autoSelect = returnType == null || returnType.ClassType != ClassType.Delegate; - // break; - // } - // } - // } - // } - // // Bug 677531 - Auto-complete doesn't always highlight generic parameter in method signature - // //if (result.ExpressionContext == ExpressionContext.TypeName) - // // autoSelect = false; - // CompletionDataList dataList = CreateCtrlSpaceCompletionData (completionContext, result); - // AddEnumMembers (dataList, returnType); - // dataList.AutoSelect = autoSelect; - // return dataList; - // } else { - // result = FindExpression (dom, completionContext, 0); - // tokenIndex = offset; - // - // // check foreach case, unfortunately the expression finder is too dumb to handle full type names - // // should be overworked if the expression finder is replaced with a mcs ast based analyzer. - // var possibleForeachToken = GetPreviousToken (ref tokenIndex, false); // starting letter - // possibleForeachToken = GetPreviousToken (ref tokenIndex, false); // varname - // - // // read return types to '(' token - // possibleForeachToken = GetPreviousToken (ref tokenIndex, false); // varType - // if (possibleForeachToken == ">") { - // while (possibleForeachToken != null && possibleForeachToken != "(") { - // possibleForeachToken = GetPreviousToken (ref tokenIndex, false); - // } - // } else { - // possibleForeachToken = GetPreviousToken (ref tokenIndex, false); // ( - // if (possibleForeachToken == ".") - // while (possibleForeachToken != null && possibleForeachToken != "(") - // possibleForeachToken = GetPreviousToken (ref tokenIndex, false); - // } - // possibleForeachToken = GetPreviousToken (ref tokenIndex, false); // foreach - // - // if (possibleForeachToken == "foreach") { - // result.ExpressionContext = ExpressionContext.ForeachInToken; - // } else { - // return null; - // // result.ExpressionContext = ExpressionContext.IdentifierExpected; - // } - // result.Expression = ""; - // result.Region = DomRegion.Empty; - // - // return CreateCtrlSpaceCompletionData (completionContext, result); - // } - // break; + // if (stub.Parent is BlockStatement) + + // result = FindExpression (dom, completionContext, -1); + // if (result == null) + // return null; + // else if (result.ExpressionContext != ExpressionContext.IdentifierExpected) { + // triggerWordLength = 1; + // bool autoSelect = true; + // IType returnType = null; + // if ((prevCh == ',' || prevCh == '(') && GetParameterCompletionCommandOffset (out cpos)) { + // ctx = CompletionWidget.CreateCodeCompletionContext (cpos); + // NRefactoryParameterDataProvider dataProvider = ParameterCompletionCommand (ctx) as NRefactoryParameterDataProvider; + // if (dataProvider != null) { + // int i = dataProvider.GetCurrentParameterIndex (CompletionWidget, ctx) - 1; + // foreach (var method in dataProvider.Methods) { + // if (i < method.Parameters.Count) { + // returnType = dom.GetType (method.Parameters [i].ReturnType); + // autoSelect = returnType == null || returnType.ClassType != ClassType.Delegate; + // break; + // } + // } + // } + // } + // // Bug 677531 - Auto-complete doesn't always highlight generic parameter in method signature + // //if (result.ExpressionContext == ExpressionContext.TypeName) + // // autoSelect = false; + // CompletionDataList dataList = CreateCtrlSpaceCompletionData (completionContext, result); + // AddEnumMembers (dataList, returnType); + // dataList.AutoSelect = autoSelect; + // return dataList; + // } else { + // result = FindExpression (dom, completionContext, 0); + // tokenIndex = offset; + // + // // check foreach case, unfortunately the expression finder is too dumb to handle full type names + // // should be overworked if the expression finder is replaced with a mcs ast based analyzer. + // var possibleForeachToken = GetPreviousToken (ref tokenIndex, false); // starting letter + // possibleForeachToken = GetPreviousToken (ref tokenIndex, false); // varname + // + // // read return types to '(' token + // possibleForeachToken = GetPreviousToken (ref tokenIndex, false); // varType + // if (possibleForeachToken == ">") { + // while (possibleForeachToken != null && possibleForeachToken != "(") { + // possibleForeachToken = GetPreviousToken (ref tokenIndex, false); + // } + // } else { + // possibleForeachToken = GetPreviousToken (ref tokenIndex, false); // ( + // if (possibleForeachToken == ".") + // while (possibleForeachToken != null && possibleForeachToken != "(") + // possibleForeachToken = GetPreviousToken (ref tokenIndex, false); + // } + // possibleForeachToken = GetPreviousToken (ref tokenIndex, false); // foreach + // + // if (possibleForeachToken == "foreach") { + // result.ExpressionContext = ExpressionContext.ForeachInToken; + // } else { + // return null; + // // result.ExpressionContext = ExpressionContext.IdentifierExpected; + // } + // result.Expression = ""; + // result.Region = DomRegion.Empty; + // + // return CreateCtrlSpaceCompletionData (completionContext, result); + // } + // break; } return null; + } - + IEnumerable HandleCatchClauseType(ExpressionResult identifierStart) { Func typePred = delegate (IType type) { @@ -992,7 +1341,7 @@ namespace ICSharpCode.NRefactory.CSharp.Completion return type; return null; }; - if (identifierStart.Node is CatchClause) { + if (identifierStart.Node.Parent is CatchClause) { var wrapper = new CompletionDataWrapper(this); AddTypesAndNamespaces( wrapper, @@ -1003,17 +1352,17 @@ namespace ICSharpCode.NRefactory.CSharp.Completion ); return wrapper.Result; } - + var resolveResult = ResolveExpression(identifierStart); return CreateCompletionData( location, - resolveResult.Item1, + resolveResult.Result, identifierStart.Node, - resolveResult.Item2, + resolveResult.Resolver, typePred ); } - + string[] validEnumBaseTypes = { "byte", "sbyte", @@ -1024,14 +1373,14 @@ namespace ICSharpCode.NRefactory.CSharp.Completion "uint", "ulong" }; - + IEnumerable HandleEnumContext() { var syntaxTree = ParseStub("a", false); if (syntaxTree == null) { return null; } - + var curType = syntaxTree.GetNodeAt(location); if (curType == null || curType.ClassType != ClassType.Enum) { syntaxTree = ParseStub("a {}", false); @@ -1042,19 +1391,38 @@ namespace ICSharpCode.NRefactory.CSharp.Completion return wrapper.Result; } } - + var member = syntaxTree.GetNodeAt(location); if (member != null && member.NameToken.EndLocation < location) { - return DefaultControlSpaceItems(); + if (currentMember == null && currentType != null) { + foreach (var a in currentType.Members) + if (a.Region.Begin < location && (currentMember == null || a.Region.Begin > currentMember.Region.Begin)) + currentMember = a; + } + bool isComplete = false; + return DefaultControlSpaceItems(ref isComplete); + } + + var attribute = syntaxTree.GetNodeAt(location); + if (attribute != null) { + var contextList = new CompletionDataWrapper(this); + var astResolver = CompletionContextProvider.GetResolver(GetState(), syntaxTree); + var csResolver = astResolver.GetResolverStateBefore(attribute); + AddContextCompletion( + contextList, + csResolver, + attribute + ); + return contextList.Result; } return null; } - + bool IsInLinqContext(int offset) { string token; - while (null != (token = GetPreviousToken (ref offset, true)) && !IsInsideCommentStringOrDirective ()) { - + while (null != (token = GetPreviousToken(ref offset, true)) && !IsInsideCommentStringOrDirective()) { + if (token == "from") { return !IsInsideCommentStringOrDirective(offset); } @@ -1064,7 +1432,7 @@ namespace ICSharpCode.NRefactory.CSharp.Completion } return false; } - + IEnumerable HandleAccessorContext() { var unit = ParseStub("get; }", false); @@ -1073,37 +1441,90 @@ namespace ICSharpCode.NRefactory.CSharp.Completion node = node.Parent; } var contextList = new CompletionDataWrapper(this); - if (node is PropertyDeclaration) { - contextList.AddCustom("get"); - contextList.AddCustom("set"); - AddKeywords(contextList, accessorModifierKeywords); + if (node is PropertyDeclaration || node is IndexerDeclaration) { + if (IncludeKeywordsInCompletionList) { + contextList.AddCustom("get"); + contextList.AddCustom("set"); + AddKeywords(contextList, accessorModifierKeywords); + } } else if (node is CustomEventDeclaration) { - contextList.AddCustom("add"); - contextList.AddCustom("remove"); + if (IncludeKeywordsInCompletionList) { + contextList.AddCustom("add"); + contextList.AddCustom("remove"); + } } else { return null; } - + return contextList.Result; } - - IEnumerable DefaultControlSpaceItems(ExpressionResult xp = null, bool controlSpace = true) + + class IfVisitor :DepthFirstAstVisitor + { + TextLocation loc; + ICompletionContextProvider completionContextProvider; + public bool IsValid; + + public IfVisitor(TextLocation loc, ICompletionContextProvider completionContextProvider) + { + this.loc = loc; + this.completionContextProvider = completionContextProvider; + + this.IsValid = true; + } + + void Check(string argument) + { + // TODO: evaluate #if epressions + if (argument.Any(c => !(char.IsLetterOrDigit(c) || c == '_'))) + return; + IsValid &= completionContextProvider.ConditionalSymbols.Contains(argument); + } + + Stack ifStack = new Stack(); + + public override void VisitPreProcessorDirective(PreProcessorDirective preProcessorDirective) + { + if (preProcessorDirective.Type == PreProcessorDirectiveType.If) { + ifStack.Push(preProcessorDirective); + } else if (preProcessorDirective.Type == PreProcessorDirectiveType.Endif) { + if (ifStack.Count == 0) + return; + var ifDirective = ifStack.Pop(); + if (ifDirective.StartLocation < loc && loc < preProcessorDirective.EndLocation) { + Check(ifDirective.Argument); + } + + } + + base.VisitPreProcessorDirective(preProcessorDirective); + } + + public void End() + { + while (ifStack.Count > 0) { + Check(ifStack.Pop().Argument); + } + } + } + + IEnumerable DefaultControlSpaceItems(ref bool isComplete, ExpressionResult xp = null, bool controlSpace = true) { var wrapper = new CompletionDataWrapper(this); if (offset >= document.TextLength) { offset = document.TextLength - 1; } - while (offset > 1 && char.IsWhiteSpace (document.GetCharAt (offset))) { + while (offset > 1 && char.IsWhiteSpace(document.GetCharAt(offset))) { offset--; } location = document.GetLocation(offset); - + if (xp == null) { xp = GetExpressionAtCursor(); } AstNode node; SyntaxTree unit; - Tuple rr; + ExpressionResolveResult rr; if (xp != null) { node = xp.Node; rr = ResolveExpression(node); @@ -1113,10 +1534,22 @@ namespace ICSharpCode.NRefactory.CSharp.Completion node = unit.GetNodeAt( location.Line, location.Column + 2, - n => n is Expression || n is AstType + n => n is Expression || n is AstType || n is NamespaceDeclaration || n is Attribute ); rr = ResolveExpression(node); } + var ifvisitor = new IfVisitor(location, CompletionContextProvider); + unit.AcceptVisitor(ifvisitor); + ifvisitor.End(); + if (!ifvisitor.IsValid) + return null; + // namespace name case + var ns = node as NamespaceDeclaration; + if (ns != null) { + var last = ns.NamespaceName; + if (last != null && location < last.EndLocation) + return null; + } if (node is Identifier && node.Parent is ForeachStatement) { var foreachStmt = (ForeachStatement)node.Parent; foreach (var possibleName in GenerateNameProposals (foreachStmt.VariableType)) { @@ -1124,12 +1557,13 @@ namespace ICSharpCode.NRefactory.CSharp.Completion wrapper.Result.Add(factory.CreateLiteralCompletionData(possibleName.ToString())); } } - + AutoSelect = false; AutoCompleteEmptyMatch = false; + isComplete = true; return wrapper.Result; } - + if (node is Identifier && node.Parent is ParameterDeclaration) { if (!controlSpace) { return null; @@ -1144,10 +1578,15 @@ namespace ICSharpCode.NRefactory.CSharp.Completion } AutoSelect = false; AutoCompleteEmptyMatch = false; + isComplete = true; return wrapper.Result; } } - /* if (Unit != null && (node == null || node is TypeDeclaration)) { + var pDecl = node as ParameterDeclaration; + if (pDecl != null && pDecl.Parent is LambdaExpression) { + return null; + } + /* if (Unit != null && (node == null || node is TypeDeclaration)) { var constructor = Unit.GetNodeAt( location.Line, location.Column - 3 @@ -1158,7 +1597,7 @@ namespace ICSharpCode.NRefactory.CSharp.Completion return wrapper.Result; } }*/ - + var initializer = node != null ? node.Parent as ArrayInitializerExpression : null; if (initializer != null) { var result = HandleObjectInitializer(unit, initializer); @@ -1167,31 +1606,82 @@ namespace ICSharpCode.NRefactory.CSharp.Completion } CSharpResolver csResolver = null; if (rr != null) { - csResolver = rr.Item2; + csResolver = rr.Resolver; } + if (csResolver == null) { if (node != null) { csResolver = GetState(); //var astResolver = new CSharpAstResolver (csResolver, node, xp != null ? xp.Item1 : CSharpUnresolvedFile); - + try { //csResolver = astResolver.GetResolverStateBefore (node); Console.WriteLine(csResolver.LocalVariables.Count()); } catch (Exception e) { Console.WriteLine("E!!!" + e); } - + } else { csResolver = GetState(); } } + + if (node is Attribute) { + // add attribute properties. + var astResolver = CompletionContextProvider.GetResolver(csResolver, unit); + var resolved = astResolver.Resolve(node); + AddAttributeProperties(wrapper, resolved); + } + + + if (node == null) { + // try lambda + unit = ParseStub("foo) => {}", true); + var pd = unit.GetNodeAt( + location.Line, + location.Column + ); + if (pd != null) { + var astResolver = unit != null ? CompletionContextProvider.GetResolver(GetState(), unit) : null; + var parameterType = astResolver.Resolve(pd.Type); + // Type is always a name context -> return null + if (parameterType != null && !parameterType.IsError) + return null; + } + } + AddContextCompletion(wrapper, csResolver, node); - + return wrapper.Result; } - + + static void AddAttributeProperties(CompletionDataWrapper wrapper, ResolveResult resolved) + { + if (resolved == null || resolved.Type.Kind == TypeKind.Unknown) + return; + + foreach (var property in resolved.Type.GetProperties (p => p.Accessibility == Accessibility.Public)) { + var data = wrapper.AddMember(property); + if (data != null) + data.DisplayFlags |= DisplayFlags.NamedArgument; + } + foreach (var field in resolved.Type.GetFields (p => p.Accessibility == Accessibility.Public)) { + var data = wrapper.AddMember(field); + if (data != null) + data.DisplayFlags |= DisplayFlags.NamedArgument; + } + foreach (var constructor in resolved.Type.GetConstructors (p => p.Accessibility == Accessibility.Public)) { + foreach (var p in constructor.Parameters) { + wrapper.AddNamedParameterVariable(p); + } + } + } + void AddContextCompletion(CompletionDataWrapper wrapper, CSharpResolver state, AstNode node) { + int i = offset - 1; + var isInGlobalDelegate = node == null && state.CurrentTypeDefinition == null && GetPreviousToken(ref i, true) == "delegate"; + if (state != null && !(node is AstType)) { foreach (var variable in state.LocalVariables) { if (variable.Region.IsInside(location.Line, location.Column - 1)) { @@ -1207,35 +1697,47 @@ namespace ICSharpCode.NRefactory.CSharp.Completion wrapper.AddVariable(p); } } - + if (state.CurrentMember is IMethod) { var method = (IMethod)state.CurrentMember; foreach (var p in method.TypeParameters) { wrapper.AddTypeParameter(p); } } - + Func typePred = null; if (IsAttributeContext(node)) { var attribute = Compilation.FindType(KnownTypeCode.Attribute); + typePred = t => t.GetAllBaseTypeDefinitions().Any(bt => bt.Equals(attribute)) ? t : null; + } + if (node != null && node.Role == Roles.BaseType) { typePred = t => { - return t.GetAllBaseTypeDefinitions().Any(bt => bt.Equals(attribute)) ? t : null; + var def = t.GetDefinition(); + if (def != null && t.Kind != TypeKind.Interface && (def.IsSealed || def.IsStatic)) + return null; + return t; }; } - AddTypesAndNamespaces(wrapper, state, node, typePred); - - wrapper.Result.Add(factory.CreateLiteralCompletionData("global")); - + + if (node != null && !(node is NamespaceDeclaration) || state.CurrentTypeDefinition != null || isInGlobalDelegate) { + AddTypesAndNamespaces(wrapper, state, node, typePred); + + wrapper.Result.Add(factory.CreateLiteralCompletionData("global")); + } + if (!(node is AstType)) { if (currentMember != null || node is Expression) { AddKeywords(wrapper, statementStartKeywords); + if (LanguageVersion.Major >= 5) + AddKeywords(wrapper, new [] { "await" }); AddKeywords(wrapper, expressionLevelKeywords); if (node == null || node is TypeDeclaration) AddKeywords(wrapper, typeLevelKeywords); } else if (currentType != null) { AddKeywords(wrapper, typeLevelKeywords); } else { - AddKeywords(wrapper, globalLevelKeywords); + if (!isInGlobalDelegate && !(node is Attribute)) + AddKeywords(wrapper, globalLevelKeywords); } var prop = currentMember as IUnresolvedProperty; if (prop != null && prop.Setter != null && prop.Setter.Region.IsInside(location)) { @@ -1244,24 +1746,29 @@ namespace ICSharpCode.NRefactory.CSharp.Completion if (currentMember is IUnresolvedEvent) { wrapper.AddCustom("value"); } - + if (IsInSwitchContext(node)) { - wrapper.AddCustom("case"); + if (IncludeKeywordsInCompletionList) + wrapper.AddCustom("case"); } } else { if (((AstType)node).Parent is ParameterDeclaration) { AddKeywords(wrapper, parameterTypePredecessorKeywords); } } - AddKeywords(wrapper, primitiveTypesKeywords); + + if (node != null || state.CurrentTypeDefinition != null || isInGlobalDelegate) + AddKeywords(wrapper, primitiveTypesKeywords); if (currentMember != null && (node is IdentifierExpression || node is SimpleType) && (node.Parent is ExpressionStatement || node.Parent is ForeachStatement || node.Parent is UsingStatement)) { - wrapper.AddCustom("var"); - wrapper.AddCustom("dynamic"); + if (IncludeKeywordsInCompletionList) { + wrapper.AddCustom("var"); + wrapper.AddCustom("dynamic"); + } } wrapper.Result.AddRange(factory.CreateCodeTemplateCompletionData()); if (node != null && node.Role == Roles.Argument) { var resolved = ResolveExpression(node.Parent); - var invokeResult = resolved != null ? resolved.Item1 as CSharpInvocationResolveResult : null; + var invokeResult = resolved != null ? resolved.Result as CSharpInvocationResolveResult : null; if (invokeResult != null) { int argNum = 0; foreach (var arg in node.Parent.Children.Where (c => c.Role == Roles.Argument)) { @@ -1276,30 +1783,30 @@ namespace ICSharpCode.NRefactory.CSharp.Completion } } } - + if (node is Expression) { var root = node; while (root.Parent != null) root = root.Parent; var astResolver = CompletionContextProvider.GetResolver(state, root); - foreach (var type in CreateFieldAction.GetValidTypes(astResolver, (Expression)node)) { + foreach (var type in TypeGuessing.GetValidTypes(astResolver, (Expression)node)) { if (type.Kind == TypeKind.Enum) { AddEnumMembers(wrapper, type, state); } else if (type.Kind == TypeKind.Delegate) { - AddDelegateHandlers(wrapper, type, true, true); + AddDelegateHandlers(wrapper, type, false, true); AutoSelect = false; AutoCompleteEmptyMatch = false; } } } - + // Add 'this' keyword for first parameter (extension method case) - if (node != null && node.Parent is ParameterDeclaration && - node.Parent.PrevSibling != null && node.Parent.PrevSibling.Role == Roles.LPar) { + if (node != null && node.Parent is ParameterDeclaration && + node.Parent.PrevSibling != null && node.Parent.PrevSibling.Role == Roles.LPar && IncludeKeywordsInCompletionList) { wrapper.AddCustom("this"); } } - + static bool IsInSwitchContext(AstNode node) { var n = node; @@ -1314,26 +1821,44 @@ namespace ICSharpCode.NRefactory.CSharp.Completion } return false; } - - void AddTypesAndNamespaces(CompletionDataWrapper wrapper, CSharpResolver state, AstNode node, Func typePred = null, Predicate memberPred = null, Action callback = null) + + static bool ListEquals(List curNamespaces, List oldNamespaces) + { + if (oldNamespaces == null || curNamespaces.Count != oldNamespaces.Count) + return false; + for (int i = 0; i < curNamespaces.Count; i++) { + if (curNamespaces [i].FullName != oldNamespaces [i].FullName) { + return false; + } + } + return true; + } + + void AddTypesAndNamespaces(CompletionDataWrapper wrapper, CSharpResolver state, AstNode node, Func typePred = null, Predicate memberPred = null, Action callback = null, bool onlyAddConstructors = false) { var lookup = new MemberLookup(ctx.CurrentTypeDefinition, Compilation.MainAssembly); + if (currentType != null) { for (var ct = ctx.CurrentTypeDefinition; ct != null; ct = ct.DeclaringTypeDefinition) { - foreach (var nestedType in ct.NestedTypes) { - string name = nestedType.Name; - if (IsAttributeContext(node) && name.EndsWith("Attribute") && name.Length > "Attribute".Length) { - name = name.Substring(0, name.Length - "Attribute".Length); + foreach (var nestedType in ct.GetNestedTypes ()) { + if (!lookup.IsAccessible(nestedType.GetDefinition(), true)) + continue; + if (onlyAddConstructors) { + if (!nestedType.GetConstructors().Any(c => lookup.IsAccessible(c, true))) + continue; } - + if (typePred == null) { - wrapper.AddType(nestedType, name); + if (onlyAddConstructors) + wrapper.AddConstructors(nestedType, false, IsAttributeContext(node)); + else + wrapper.AddType(nestedType, false, IsAttributeContext(node)); continue; } - + var type = typePred(nestedType); if (type != null) { - var a2 = wrapper.AddType(type, name); + var a2 = onlyAddConstructors ? wrapper.AddConstructors(type, false, IsAttributeContext(node)) : wrapper.AddType(type, false, IsAttributeContext(node)); if (a2 != null && callback != null) { callback(a2, type); } @@ -1341,15 +1866,19 @@ namespace ICSharpCode.NRefactory.CSharp.Completion continue; } } + if (this.currentMember != null && !(node is AstType)) { - var def = ctx.CurrentTypeDefinition ?? Compilation.MainAssembly.GetTypeDefinition(currentType); + var def = ctx.CurrentTypeDefinition; + if (def == null && currentType != null) + def = Compilation.MainAssembly.GetTypeDefinition(currentType.FullTypeName); if (def != null) { bool isProtectedAllowed = true; - foreach (var member in def.GetMembers ()) { + + foreach (var member in def.GetMembers (m => currentMember.IsStatic ? m.IsStatic : true)) { if (member is IMethod && ((IMethod)member).FullName == "System.Object.Finalize") { continue; } - if (member.EntityType == EntityType.Operator) { + if (member.SymbolKind == SymbolKind.Operator) { continue; } if (member.IsExplicitInterfaceImplementation) { @@ -1358,7 +1887,6 @@ namespace ICSharpCode.NRefactory.CSharp.Completion if (!lookup.IsAccessible(member, isProtectedAllowed)) { continue; } - if (memberPred == null || memberPred(member)) { wrapper.AddMember(member); } @@ -1381,48 +1909,128 @@ namespace ICSharpCode.NRefactory.CSharp.Completion } } var scope = ctx.CurrentUsingScope; - + for (var n = scope; n != null; n = n.Parent) { foreach (var pair in n.UsingAliases) { wrapper.AddAlias(pair.Key); } + foreach (var alias in n.ExternAliases) { + wrapper.AddAlias(alias); + } foreach (var u in n.Usings) { foreach (var type in u.Types) { if (!lookup.IsAccessible(type, false)) continue; - + IType addType = typePred != null ? typePred(type) : type; + + if (onlyAddConstructors && addType != null) { + if (!addType.GetConstructors().Any(c => lookup.IsAccessible(c, true))) + continue; + } + if (addType != null) { - string name = type.Name; - if (IsAttributeContext(node) && name.EndsWith("Attribute") && name.Length > "Attribute".Length) { - name = name.Substring(0, name.Length - "Attribute".Length); - } - var a = wrapper.AddType(addType, name); + var a = onlyAddConstructors ? wrapper.AddConstructors(addType, false, IsAttributeContext(node)) : wrapper.AddType(addType, false, IsAttributeContext(node)); if (a != null && callback != null) { callback(a, type); } } } } - + foreach (var type in n.Namespace.Types) { if (!lookup.IsAccessible(type, false)) continue; IType addType = typePred != null ? typePred(type) : type; + + if (onlyAddConstructors && addType != null) { + if (!addType.GetConstructors().Any(c => lookup.IsAccessible(c, true))) + continue; + } + if (addType != null) { - var a2 = wrapper.AddType(addType, addType.Name); + var a2 = onlyAddConstructors ? wrapper.AddConstructors(addType, false, IsAttributeContext(node)) : wrapper.AddType(addType, false); if (a2 != null && callback != null) { callback(a2, type); } } } - + } + + for (var n = scope; n != null; n = n.Parent) { foreach (var curNs in n.Namespace.ChildNamespaces) { - wrapper.AddNamespace(curNs); + wrapper.AddNamespace(lookup, curNs); } } + + if (node is AstType && node.Parent is Constraint && IncludeKeywordsInCompletionList) { + wrapper.AddCustom("new()"); + } + + if (AutomaticallyAddImports) { + state = GetState(); + ICompletionData[] importData; + + var namespaces = new List(); + for (var n = ctx.CurrentUsingScope; n != null; n = n.Parent) { + namespaces.Add(n.Namespace); + foreach (var u in n.Usings) + namespaces.Add(u); + } + + if (this.CompletionEngineCache != null && ListEquals(namespaces, CompletionEngineCache.namespaces)) { + importData = CompletionEngineCache.importCompletion; + } else { + // flatten usings + var importList = new List(); + var dict = new Dictionary>(); + foreach (var type in Compilation.GetTopLevelTypeDefinitons ()) { + if (!lookup.IsAccessible(type, false)) + continue; + if (namespaces.Any(n => n.FullName == type.Namespace)) + continue; + bool useFullName = false; + foreach (var ns in namespaces) { + if (ns.GetTypeDefinition(type.Name, type.TypeParameterCount) != null) { + useFullName = true; + break; + } + } + + if (onlyAddConstructors) { + if (!type.GetConstructors().Any(c => lookup.IsAccessible(c, true))) + continue; + } + var data = factory.CreateImportCompletionData(type, useFullName, onlyAddConstructors); + Dictionary createdDict; + if (!dict.TryGetValue(type.Name, out createdDict)) { + createdDict = new Dictionary(); + dict.Add(type.Name, createdDict); + } + ICompletionData oldData; + if (!createdDict.TryGetValue(type.Namespace, out oldData)) { + importList.Add(data); + createdDict.Add(type.Namespace, data); + } else { + oldData.AddOverload(data); + } + } + + importData = importList.ToArray(); + if (CompletionEngineCache != null) { + CompletionEngineCache.namespaces = namespaces; + CompletionEngineCache.importCompletion = importData; + } + } + foreach (var data in importData) { + wrapper.Result.Add(data); + } + + + } + } - + IEnumerable HandleKeywordCompletion(int wordStart, string word) { if (IsInsideCommentStringOrDirective()) { @@ -1447,65 +2055,65 @@ namespace ICSharpCode.NRefactory.CSharp.Completion return wrapper.Result; case "case": return CreateCaseCompletionData(location); - // case ",": - // case ":": - // if (result.ExpressionContext == ExpressionContext.InheritableType) { - // IType cls = NRefactoryResolver.GetTypeAtCursor (Document.CompilationUnit, Document.FileName, new TextLocation (completionContext.TriggerLine, completionContext.TriggerLineOffset)); - // CompletionDataList completionList = new ProjectDomCompletionDataList (); - // List namespaceList = GetUsedNamespaces (); - // var col = new CSharpTextEditorCompletion.CompletionDataCollector (this, dom, completionList, Document.CompilationUnit, null, location); - // bool isInterface = false; - // HashSet baseTypeNames = new HashSet (); - // if (cls != null) { - // baseTypeNames.Add (cls.Name); - // if (cls.ClassType == ClassType.Struct) - // isInterface = true; - // } - // int tokenIndex = offset; - // - // // Search base types " : [Type1, ... ,TypeN,] " - // string token = null; - // do { - // token = GetPreviousToken (ref tokenIndex, false); - // if (string.IsNullOrEmpty (token)) - // break; - // token = token.Trim (); - // if (Char.IsLetterOrDigit (token [0]) || token [0] == '_') { - // IType baseType = dom.SearchType (Document.CompilationUnit, cls, result.Region.Start, token); - // if (baseType != null) { - // if (baseType.ClassType != ClassType.Interface) - // isInterface = true; - // baseTypeNames.Add (baseType.Name); - // } - // } - // } while (token != ":"); - // foreach (object o in dom.GetNamespaceContents (namespaceList, true, true)) { - // IType type = o as IType; - // if (type != null && (type.IsStatic || type.IsSealed || baseTypeNames.Contains (type.Name) || isInterface && type.ClassType != ClassType.Interface)) { - // continue; - // } - // if (o is Namespace && !namespaceList.Any (ns => ns.StartsWith (((Namespace)o).FullName))) - // continue; - // col.Add (o); - // } - // // Add inner classes - // Stack innerStack = new Stack (); - // innerStack.Push (cls); - // while (innerStack.Count > 0) { - // IType curType = innerStack.Pop (); - // if (curType == null) - // continue; - // foreach (IType innerType in curType.InnerTypes) { - // if (innerType != cls) - // // don't add the calling class as possible base type - // col.Add (innerType); - // } - // if (curType.DeclaringType != null) - // innerStack.Push (curType.DeclaringType); - // } - // return completionList; - // } - // break; + // case ",": + // case ":": + // if (result.ExpressionContext == ExpressionContext.InheritableType) { + // IType cls = NRefactoryResolver.GetTypeAtCursor (Document.CompilationUnit, Document.FileName, new TextLocation (completionContext.TriggerLine, completionContext.TriggerLineOffset)); + // CompletionDataList completionList = new ProjectDomCompletionDataList (); + // List namespaceList = GetUsedNamespaces (); + // var col = new CSharpTextEditorCompletion.CompletionDataCollector (this, dom, completionList, Document.CompilationUnit, null, location); + // bool isInterface = false; + // HashSet baseTypeNames = new HashSet (); + // if (cls != null) { + // baseTypeNames.Add (cls.Name); + // if (cls.ClassType == ClassType.Struct) + // isInterface = true; + // } + // int tokenIndex = offset; + // + // // Search base types " : [Type1, ... ,TypeN,] " + // string token = null; + // do { + // token = GetPreviousToken (ref tokenIndex, false); + // if (string.IsNullOrEmpty (token)) + // break; + // token = token.Trim (); + // if (Char.IsLetterOrDigit (token [0]) || token [0] == '_') { + // IType baseType = dom.SearchType (Document.CompilationUnit, cls, result.Region.Start, token); + // if (baseType != null) { + // if (baseType.ClassType != ClassType.Interface) + // isInterface = true; + // baseTypeNames.Add (baseType.Name); + // } + // } + // } while (token != ":"); + // foreach (object o in dom.GetNamespaceContents (namespaceList, true, true)) { + // IType type = o as IType; + // if (type != null && (type.IsStatic || type.IsSealed || baseTypeNames.Contains (type.Name) || isInterface && type.ClassType != ClassType.Interface)) { + // continue; + // } + // if (o is Namespace && !namespaceList.Any (ns => ns.StartsWith (((Namespace)o).FullName))) + // continue; + // col.Add (o); + // } + // // Add inner classes + // Stack innerStack = new Stack (); + // innerStack.Push (cls); + // while (innerStack.Count > 0) { + // IType curType = innerStack.Pop (); + // if (curType == null) + // continue; + // foreach (IType innerType in curType.InnerTypes) { + // if (innerType != cls) + // // don't add the calling class as possible base type + // col.Add (innerType); + // } + // if (curType.DeclaringType != null) + // innerStack.Push (curType.DeclaringType); + // } + // return completionList; + // } + // break; case "is": case "as": if (currentType == null) { @@ -1521,70 +2129,71 @@ namespace ICSharpCode.NRefactory.CSharp.Completion if (parent is VariableDeclarationStatement) { var resolved = ResolveExpression(parent); if (resolved != null) { - isAsType = resolved.Item1.Type; + isAsType = resolved.Result.Type; } } } var isAsWrapper = new CompletionDataWrapper(this); var def = isAsType != null ? isAsType.GetDefinition() : null; AddTypesAndNamespaces( - isAsWrapper, - GetState(), - null, - t => t.GetDefinition() == null || def == null || t.GetDefinition().IsDerivedFrom(def) ? t : null, - m => false); + isAsWrapper, + GetState(), + null, + t => t.GetDefinition() == null || def == null || t.GetDefinition().IsDerivedFrom(def) ? t : null, + m => false); + AddKeywords(isAsWrapper, primitiveTypesKeywords); return isAsWrapper.Result; - // { - // CompletionDataList completionList = new ProjectDomCompletionDataList (); - // ExpressionResult expressionResult = FindExpression (dom, completionContext, wordStart - document.Caret.Offset); - // NRefactoryResolver resolver = CreateResolver (); - // ResolveResult resolveResult = resolver.Resolve (expressionResult, new TextLocation (completionContext.TriggerLine, completionContext.TriggerLineOffset)); - // if (resolveResult != null && resolveResult.ResolvedType != null) { - // CompletionDataCollector col = new CompletionDataCollector (this, dom, completionList, Document.CompilationUnit, resolver.CallingType, location); - // IType foundType = null; - // if (word == "as") { - // ExpressionContext exactContext = new NewCSharpExpressionFinder (dom).FindExactContextForAsCompletion (document, Document.CompilationUnit, Document.FileName, resolver.CallingType); - // if (exactContext is ExpressionContext.TypeExpressionContext) { - // foundType = resolver.SearchType (((ExpressionContext.TypeExpressionContext)exactContext).Type); - // AddAsCompletionData (col, foundType); - // } - // } - // - // if (foundType == null) - // foundType = resolver.SearchType (resolveResult.ResolvedType); - // - // if (foundType != null) { - // if (foundType.ClassType == ClassType.Interface) - // foundType = resolver.SearchType (DomReturnType.Object); - // - // foreach (IType type in dom.GetSubclasses (foundType)) { - // if (type.IsSpecialName || type.Name.StartsWith ("<")) - // continue; - // AddAsCompletionData (col, type); - // } - // } - // List namespaceList = GetUsedNamespaces (); - // foreach (object o in dom.GetNamespaceContents (namespaceList, true, true)) { - // if (o is IType) { - // IType type = (IType)o; - // if (type.ClassType != ClassType.Interface || type.IsSpecialName || type.Name.StartsWith ("<")) - // continue; - // // if (foundType != null && !dom.GetInheritanceTree (foundType).Any (x => x.FullName == type.FullName)) - // // continue; - // AddAsCompletionData (col, type); - // continue; - // } - // if (o is Namespace) - // continue; - // col.Add (o); - // } - // return completionList; - // } - // result.ExpressionContext = ExpressionContext.TypeName; - // return CreateCtrlSpaceCompletionData (completionContext, result); - // } + // { + // CompletionDataList completionList = new ProjectDomCompletionDataList (); + // ExpressionResult expressionResult = FindExpression (dom, completionContext, wordStart - document.Caret.Offset); + // NRefactoryResolver resolver = CreateResolver (); + // ResolveResult resolveResult = resolver.Resolve (expressionResult, new TextLocation (completionContext.TriggerLine, completionContext.TriggerLineOffset)); + // if (resolveResult != null && resolveResult.ResolvedType != null) { + // CompletionDataCollector col = new CompletionDataCollector (this, dom, completionList, Document.CompilationUnit, resolver.CallingType, location); + // IType foundType = null; + // if (word == "as") { + // ExpressionContext exactContext = new NewCSharpExpressionFinder (dom).FindExactContextForAsCompletion (document, Document.CompilationUnit, Document.FileName, resolver.CallingType); + // if (exactContext is ExpressionContext.TypeExpressionContext) { + // foundType = resolver.SearchType (((ExpressionContext.TypeExpressionContext)exactContext).Type); + // AddAsCompletionData (col, foundType); + // } + // } + // + // if (foundType == null) + // foundType = resolver.SearchType (resolveResult.ResolvedType); + // + // if (foundType != null) { + // if (foundType.ClassType == ClassType.Interface) + // foundType = resolver.SearchType (DomReturnType.Object); + // + // foreach (IType type in dom.GetSubclasses (foundType)) { + // if (type.IsSpecialName || type.Name.StartsWith ("<")) + // continue; + // AddAsCompletionData (col, type); + // } + // } + // List namespaceList = GetUsedNamespaces (); + // foreach (object o in dom.GetNamespaceContents (namespaceList, true, true)) { + // if (o is IType) { + // IType type = (IType)o; + // if (type.ClassType != ClassType.Interface || type.IsSpecialName || type.Name.StartsWith ("<")) + // continue; + // // if (foundType != null && !dom.GetInheritanceTree (foundType).Any (x => x.FullName == type.FullName)) + // // continue; + // AddAsCompletionData (col, type); + // continue; + // } + // if (o is Namespace) + // continue; + // col.Add (o); + // } + // return completionList; + // } + // result.ExpressionContext = ExpressionContext.TypeName; + // return CreateCtrlSpaceCompletionData (completionContext, result); + // } case "override": - // Look for modifiers, in order to find the beginning of the declaration + // Look for modifiers, in order to find the beginning of the declaration int firstMod = wordStart; int i = wordStart; for (int n = 0; n < 3; n++) { @@ -1607,7 +2216,7 @@ namespace ICSharpCode.NRefactory.CSharp.Completion } return null; case "partial": - // Look for modifiers, in order to find the beginning of the declaration + // Look for modifiers, in order to find the beginning of the declaration firstMod = wordStart; i = wordStart; for (int n = 0; n < 3; n++) { @@ -1625,13 +2234,13 @@ namespace ICSharpCode.NRefactory.CSharp.Completion return null; } var state = GetState(); - + if (state.CurrentTypeDefinition != null && (state.CurrentTypeDefinition.Kind == TypeKind.Class || state.CurrentTypeDefinition.Kind == TypeKind.Struct)) { string modifiers = document.GetText(firstMod, wordStart - firstMod); return GetPartialCompletionData(state.CurrentTypeDefinition, modifiers); } return null; - + case "public": case "protected": case "private": @@ -1642,52 +2251,48 @@ namespace ICSharpCode.NRefactory.CSharp.Completion if (accessorContext != null) { return accessorContext; } - wrapper = new CompletionDataWrapper(this); - state = GetState(); - if (currentType != null) { - AddTypesAndNamespaces(wrapper, state, null, null, m => false); - AddKeywords(wrapper, primitiveTypesKeywords); - } - AddKeywords(wrapper, typeLevelKeywords); - return wrapper.Result; + return null; case "new": int j = offset - 4; - // string token = GetPreviousToken (ref j, true); - + // string token = GetPreviousToken (ref j, true); + IType hintType = null; var expressionOrVariableDeclaration = GetNewExpressionAt(j); if (expressionOrVariableDeclaration == null) return null; - var astResolver = CompletionContextProvider.GetResolver(GetState(), expressionOrVariableDeclaration.Unit); - hintType = CreateFieldAction.GetValidTypes( - astResolver, - expressionOrVariableDeclaration.Node as Expression - ) - .FirstOrDefault(); - - return CreateTypeCompletionData(hintType); + var astResolver = CompletionContextProvider.GetResolver(GetState(), expressionOrVariableDeclaration.Node.Ancestors.FirstOrDefault(n => n is EntityDeclaration || n is SyntaxTree)); + hintType = TypeGuessing.GetValidTypes( + astResolver, + expressionOrVariableDeclaration.Node + ).FirstOrDefault(); + + return CreateConstructorCompletionData(hintType); case "yield": var yieldDataList = new CompletionDataWrapper(this); DefaultCompletionString = "return"; - yieldDataList.AddCustom("break"); - yieldDataList.AddCustom("return"); + if (IncludeKeywordsInCompletionList) { + yieldDataList.AddCustom("break"); + yieldDataList.AddCustom("return"); + } return yieldDataList.Result; case "in": var inList = new CompletionDataWrapper(this); - + var expr = GetExpressionAtCursor(); + if (expr == null) + return null; var rr = ResolveExpression(expr); - + AddContextCompletion( - inList, - rr != null ? rr.Item2 : GetState(), - expr.Node + inList, + rr != null ? rr.Resolver : GetState(), + expr.Node ); return inList.Result; } return null; } - + bool IsLineEmptyUpToEol() { var line = document.GetLineByNumber(location.Line); @@ -1699,34 +2304,32 @@ namespace ICSharpCode.NRefactory.CSharp.Completion } return true; } - + string GetLineIndent(int lineNr) { var line = document.GetLineByNumber(lineNr); for (int j = line.Offset; j < line.EndOffset; j++) { char ch = document.GetCharAt(j); if (!char.IsWhiteSpace(ch)) { - return document.GetText(line.Offset, j - line.Offset - 1); + return document.GetText(line.Offset, j - line.Offset); } } return ""; } - - static CSharpAmbience amb = new CSharpAmbience(); - + // static CSharpAmbience amb = new CSharpAmbience(); class Category : CompletionCategory { - public Category(string displayText, string icon) : base (displayText, icon) + public Category(string displayText, string icon) : base(displayText, icon) { } - + public override int CompareTo(CompletionCategory other) { return 0; } } - - IEnumerable CreateTypeCompletionData(IType hintType) + + IEnumerable CreateConstructorCompletionData(IType hintType) { var wrapper = new CompletionDataWrapper(this); var state = GetState(); @@ -1734,8 +2337,8 @@ namespace ICSharpCode.NRefactory.CSharp.Completion Action typeCallback = null; var inferredTypesCategory = new Category("Inferred Types", null); var derivedTypesCategory = new Category("Derived Types", null); - - if (hintType != null) { + + if (hintType != null && (hintType.Kind != TypeKind.TypeParameter || IsTypeParameterInScope(hintType))) { if (hintType.Kind != TypeKind.Unknown) { var lookup = new MemberLookup( ctx.CurrentTypeDefinition, @@ -1754,27 +2357,31 @@ namespace ICSharpCode.NRefactory.CSharp.Completion return null; } // check for valid constructors - if (t.GetConstructors().Count() > 0) { + if (t.GetConstructors().Any()) { bool isProtectedAllowed = currentType != null ? - currentType.Resolve(ctx).GetDefinition().IsDerivedFrom(t.GetDefinition()) : - false; - if (!t.GetConstructors().Any(m => lookup.IsAccessible( - m, - isProtectedAllowed - ) - )) { + currentType.Resolve(ctx).GetDefinition().IsDerivedFrom(t.GetDefinition()) : false; + if (!t.GetConstructors().Any(m => lookup.IsAccessible(m, isProtectedAllowed))) { return null; } } - + + // check derived types + var typeDef = t.GetDefinition(); + var hintDef = hintType.GetDefinition(); + if (typeDef != null && hintDef != null && typeDef.IsDerivedFrom(hintDef)) { + var newType = wrapper.AddType(t, true); + if (newType != null) { + newType.CompletionCategory = inferredTypesCategory; + } + } + + // check type inference var typeInference = new TypeInference(Compilation); typeInference.Algorithm = TypeInferenceAlgorithm.ImprovedReturnAllResults; - var inferedType = typeInference.FindTypeInBounds( - new [] { t }, - new [] { hintType } - ); + + var inferedType = typeInference.FindTypeInBounds(new [] { t }, new [] { hintType }); if (inferedType != SpecialType.UnknownType) { - var newType = wrapper.AddType(inferedType, amb.ConvertType(inferedType)); + var newType = wrapper.AddType(inferedType, true); if (newType != null) { newType.CompletionCategory = inferredTypesCategory; } @@ -1783,41 +2390,59 @@ namespace ICSharpCode.NRefactory.CSharp.Completion return t; }; if (!(hintType.Kind == TypeKind.Interface && hintType.Kind != TypeKind.Array)) { - DefaultCompletionString = GetShortType(hintType, GetState()); - var hint = wrapper.AddType(hintType, DefaultCompletionString); + var hint = wrapper.AddType(hintType, true); if (hint != null) { + DefaultCompletionString = hint.DisplayText; hint.CompletionCategory = derivedTypesCategory; } } if (hintType is ParameterizedType && hintType.TypeParameterCount == 1 && hintType.FullName == "System.Collections.Generic.IEnumerable") { var arg = ((ParameterizedType)hintType).TypeArguments.FirstOrDefault(); - var array = new ArrayTypeReference(arg.ToTypeReference(), 1).Resolve(ctx); - wrapper.AddType(array, amb.ConvertType(array)); + if (arg.Kind != TypeKind.TypeParameter) { + var array = new ArrayType(ctx.Compilation, arg, 1); + wrapper.AddType(array, true); + } } } else { - var hint = wrapper.AddType(hintType, DefaultCompletionString); + var hint = wrapper.AddType(hintType, true); if (hint != null) { DefaultCompletionString = hint.DisplayText; hint.CompletionCategory = derivedTypesCategory; } } } - AddTypesAndNamespaces(wrapper, state, null, pred, m => false, typeCallback); + AddTypesAndNamespaces(wrapper, state, null, pred, m => false, typeCallback, true); if (hintType == null || hintType == SpecialType.UnknownType) { AddKeywords(wrapper, primitiveTypesKeywords.Where(k => k != "void")); } - + CloseOnSquareBrackets = true; AutoCompleteEmptyMatch = true; + AutoCompleteEmptyMatchOnCurlyBracket = false; return wrapper.Result; } - + + bool IsTypeParameterInScope(IType hintType) + { + var tp = hintType as ITypeParameter; + var ownerName = tp.Owner.ReflectionName; + if (currentMember != null && ownerName == currentMember.ReflectionName) + return true; + var ot = currentType; + while (ot != null) { + if (ownerName == ot.ReflectionName) + return true; + ot = ot.DeclaringTypeDefinition; + } + return false; + } + IEnumerable GetOverrideCompletionData(IUnresolvedTypeDefinition type, string modifiers) { var wrapper = new CompletionDataWrapper(this); var alreadyInserted = new List(); //bool addedVirtuals = false; - + int declarationBegin = offset; int j = declarationBegin; for (int i = 0; i < 3; i++) { @@ -1828,6 +2453,8 @@ namespace ICSharpCode.NRefactory.CSharp.Completion case "internal": case "sealed": case "override": + case "partial": + case "async": declarationBegin = j; break; case "static": @@ -1843,7 +2470,7 @@ namespace ICSharpCode.NRefactory.CSharp.Completion ); return wrapper.Result; } - + IEnumerable GetPartialCompletionData(ITypeDefinition type, string modifiers) { var wrapper = new CompletionDataWrapper(this); @@ -1857,15 +2484,17 @@ namespace ICSharpCode.NRefactory.CSharp.Completion case "internal": case "sealed": case "override": + case "partial": + case "async": declarationBegin = j; break; case "static": return null; // don't add override completion for static members } } - + var methods = new List(); - + foreach (var part in type.Parts) { foreach (var method in part.Methods) { if (method.BodyRegion.IsEmpty) { @@ -1876,7 +2505,7 @@ namespace ICSharpCode.NRefactory.CSharp.Completion } } } - + foreach (var method in methods) { wrapper.Add(factory.CreateNewPartialCompletionData( declarationBegin, @@ -1885,16 +2514,16 @@ namespace ICSharpCode.NRefactory.CSharp.Completion ) ); } - + return wrapper.Result; } - + IMethod GetImplementation(ITypeDefinition type, IUnresolvedMethod method) { foreach (var cur in type.Methods) { if (cur.Name == method.Name && cur.Parameters.Count == method.Parameters.Count && !cur.BodyRegion.IsEmpty) { bool equal = true; - /*for (int i = 0; i < cur.Parameters.Count; i++) { + /* for (int i = 0; i < cur.Parameters.Count; i++) { if (!cur.Parameters [i].Type.Equals (method.Parameters [i].Type)) { equal = false; break; @@ -1907,8 +2536,8 @@ namespace ICSharpCode.NRefactory.CSharp.Completion } return null; } - - void AddVirtuals(List alreadyInserted, CompletionDataWrapper col, string modifiers, IType curType, int declarationBegin) + + protected virtual void AddVirtuals(List alreadyInserted, CompletionDataWrapper col, string modifiers, IType curType, int declarationBegin) { if (curType == null) { return; @@ -1921,7 +2550,7 @@ namespace ICSharpCode.NRefactory.CSharp.Completion if (m is IMethod && m.Name == "Finalize") { continue; } - + var data = factory.CreateNewOverrideCompletionData( declarationBegin, currentType, @@ -1943,55 +2572,33 @@ namespace ICSharpCode.NRefactory.CSharp.Completion col.Add(data); } } - - static void AddKeywords(CompletionDataWrapper wrapper, IEnumerable keywords) + + void AddKeywords(CompletionDataWrapper wrapper, IEnumerable keywords) { + if (!IncludeKeywordsInCompletionList) + return; foreach (string keyword in keywords) { if (wrapper.Result.Any(data => data.DisplayText == keyword)) continue; wrapper.AddCustom(keyword); } } - - public string GetPreviousMemberReferenceExpression(int tokenIndex) + + public string GuessEventHandlerMethodName(int tokenIndex) { string result = GetPreviousToken(ref tokenIndex, false); - result = GetPreviousToken(ref tokenIndex, false); - if (result != ".") { - result = null; - } else { - var names = new List(); - while (result == ".") { - result = GetPreviousToken(ref tokenIndex, false); - if (result == "this") { - names.Add("handle"); - } else if (result != null) { - string trimmedName = result.Trim(); - if (trimmedName.Length == 0) { - break; - } - names.Insert(0, trimmedName); - } - result = GetPreviousToken(ref tokenIndex, false); - } - result = String.Join("", names.ToArray()); - foreach (char ch in result) { - if (!char.IsLetterOrDigit(ch) && ch != '_') { - result = ""; - break; - } - } - } - return result; + return "Handle" + result; } - + bool MatchDelegate(IType delegateType, IMethod method) { + if (method.SymbolKind != SymbolKind.Method) + return false; var delegateMethod = delegateType.GetDelegateInvokeMethod(); if (delegateMethod == null || delegateMethod.Parameters.Count != method.Parameters.Count) { return false; } - + for (int i = 0; i < delegateMethod.Parameters.Count; i++) { if (!delegateMethod.Parameters [i].Type.Equals(method.Parameters [i].Type)) { return false; @@ -1999,14 +2606,16 @@ namespace ICSharpCode.NRefactory.CSharp.Completion } return true; } - - string AddDelegateHandlers(CompletionDataWrapper completionList, IType delegateType, bool addSemicolon = true, bool addDefault = true) + + string AddDelegateHandlers(CompletionDataWrapper completionList, IType delegateType, bool addSemicolon = true, bool addDefault = true, string optDelegateName = null) { IMethod delegateMethod = delegateType.GetDelegateInvokeMethod(); + PossibleDelegates.Add(delegateMethod); var thisLineIndent = GetLineIndent(location.Line); string delegateEndString = EolMarker + thisLineIndent + "}" + (addSemicolon ? ";" : ""); //bool containsDelegateData = completionList.Result.Any(d => d.DisplayText.StartsWith("delegate(")); - if (addDefault) { + if (addDefault && !completionList.AnonymousDelegateAdded) { + completionList.AnonymousDelegateAdded = true; var oldDelegate = completionList.Result.FirstOrDefault(cd => cd.DisplayText == "delegate"); if (oldDelegate != null) completionList.Result.Remove(oldDelegate); @@ -2014,58 +2623,89 @@ namespace ICSharpCode.NRefactory.CSharp.Completion "delegate", "Creates anonymous delegate.", "delegate {" + EolMarker + thisLineIndent + IndentString + "|" + delegateEndString - ); + ).DisplayFlags |= DisplayFlags.MarkedBold; + if (LanguageVersion.Major >= 5) { + completionList.AddCustom( + "async delegate", + "Creates anonymous async delegate.", + "async delegate {" + EolMarker + thisLineIndent + IndentString + "|" + delegateEndString + ).DisplayFlags |= DisplayFlags.MarkedBold; + } } var sb = new StringBuilder("("); var sbWithoutTypes = new StringBuilder("("); var state = GetState(); var builder = new TypeSystemAstBuilder(state); - + for (int k = 0; k < delegateMethod.Parameters.Count; k++) { + if (k > 0) { sb.Append(", "); sbWithoutTypes.Append(", "); } - var convertedParameter = builder.ConvertParameter (delegateMethod.Parameters [k]); + var convertedParameter = builder.ConvertParameter(delegateMethod.Parameters [k]); if (convertedParameter.ParameterModifier == ParameterModifier.Params) convertedParameter.ParameterModifier = ParameterModifier.None; - sb.Append(convertedParameter.GetText (FormattingPolicy)); + sb.Append(convertedParameter.ToString(FormattingPolicy)); sbWithoutTypes.Append(delegateMethod.Parameters [k].Name); } - + sb.Append(")"); sbWithoutTypes.Append(")"); - completionList.AddCustom( - "delegate" + sb, - "Creates anonymous delegate.", - "delegate" + sb + " {" + EolMarker + thisLineIndent + IndentString + "|" + delegateEndString - ); + var signature = sb.ToString(); + if (!completionList.HasAnonymousDelegateAdded(signature)) { + completionList.AddAnonymousDelegateAdded(signature); - if (!completionList.Result.Any(data => data.DisplayText == sb.ToString())) { completionList.AddCustom( - sb.ToString(), - "Creates typed lambda expression.", - sb + " => |" + (addSemicolon ? ";" : "") - ); - } + "delegate" + signature, + "Creates anonymous delegate.", + "delegate" + signature + " {" + EolMarker + thisLineIndent + IndentString + "|" + delegateEndString + ).DisplayFlags |= DisplayFlags.MarkedBold; + if (LanguageVersion.Major >= 5) { + completionList.AddCustom( + "async delegate" + signature, + "Creates anonymous async delegate.", + "async delegate" + signature + " {" + EolMarker + thisLineIndent + IndentString + "|" + delegateEndString + ).DisplayFlags |= DisplayFlags.MarkedBold; + } + if (!completionList.Result.Any(data => data.DisplayText == sb.ToString())) { + completionList.AddCustom( + signature, + "Creates typed lambda expression.", + signature + " => |" + (addSemicolon ? ";" : "") + ).DisplayFlags |= DisplayFlags.MarkedBold; + if (LanguageVersion.Major >= 5) { + completionList.AddCustom( + "async " + signature, + "Creates typed async lambda expression.", + "async " + signature + " => |" + (addSemicolon ? ";" : "") + ).DisplayFlags |= DisplayFlags.MarkedBold; + } + + if (!delegateMethod.Parameters.Any(p => p.IsOut || p.IsRef) && !completionList.Result.Any(data => data.DisplayText == sbWithoutTypes.ToString())) { + completionList.AddCustom( + sbWithoutTypes.ToString(), + "Creates lambda expression.", + sbWithoutTypes + " => |" + (addSemicolon ? ";" : "") + ).DisplayFlags |= DisplayFlags.MarkedBold; + if (LanguageVersion.Major >= 5) { + completionList.AddCustom( + "async " + sbWithoutTypes, + "Creates async lambda expression.", + "async " + sbWithoutTypes + " => |" + (addSemicolon ? ";" : "") + ).DisplayFlags |= DisplayFlags.MarkedBold; + } + } + } - if (!delegateMethod.Parameters.Any (p => p.IsOut || p.IsRef) && !completionList.Result.Any(data => data.DisplayText == sbWithoutTypes.ToString())) { - completionList.AddCustom( - sbWithoutTypes.ToString(), - "Creates lambda expression.", - sbWithoutTypes + " => |" + (addSemicolon ? ";" : "") - ); } - /* TODO:Make factory method out of it. - // It's needed to temporarly disable inserting auto matching bracket because the anonymous delegates are selectable with '(' - // otherwise we would end up with () => ) - if (!containsDelegateData) { - var savedValue = MonoDevelop.SourceEditor.DefaultSourceEditorOptions.Instance.AutoInsertMatchingBracket; - MonoDevelop.SourceEditor.DefaultSourceEditorOptions.Instance.AutoInsertMatchingBracket = false; - completionList.Result.CompletionListClosed += delegate { - MonoDevelop.SourceEditor.DefaultSourceEditorOptions.Instance.AutoInsertMatchingBracket = savedValue; - }; - }*/ + + string varName = optDelegateName ?? "Handle" + delegateType.Name; + + var ecd = factory.CreateEventCreationCompletionData(varName, delegateType, null, signature, currentMember, currentType); + ecd.DisplayFlags |= DisplayFlags.MarkedBold; + completionList.Add(ecd); + return sb.ToString(); } @@ -2090,7 +2730,7 @@ namespace ICSharpCode.NRefactory.CSharp.Completion includeProtected ); } - + if (member.IsProtected && !(member.DeclaringTypeDefinition.IsProtectedOrInternal && !includeProtected)) { return includeProtected; } @@ -2100,7 +2740,7 @@ namespace ICSharpCode.NRefactory.CSharp.Completion //var type2 = currentMember is ITypeDefinition ? (ITypeDefinition)currentMember : currentMember.DeclaringTypeDefinition; bool result = true; // easy case, projects are the same - /*// if (type1.ProjectContent == type2.ProjectContent) { + /* // if (type1.ProjectContent == type2.ProjectContent) { // result = true; // } else if (type1.ProjectContent != null) { @@ -2118,11 +2758,11 @@ namespace ICSharpCode.NRefactory.CSharp.Completion }*/ return member.IsProtectedAndInternal ? includeProtected && result : result; } - + if (!(currentMember is IType) && (currentMember.DeclaringTypeDefinition == null || member.DeclaringTypeDefinition == null)) { return false; } - + // inner class var declaringType = currentMember.DeclaringTypeDefinition; while (declaringType != null) { @@ -2131,11 +2771,11 @@ namespace ICSharpCode.NRefactory.CSharp.Completion } declaringType = declaringType.DeclaringTypeDefinition; } - - + + return currentMember.DeclaringTypeDefinition != null && member.DeclaringTypeDefinition.FullName == currentMember.DeclaringTypeDefinition.FullName; } - + static bool IsAttributeContext(AstNode node) { AstNode n = node; @@ -2144,7 +2784,7 @@ namespace ICSharpCode.NRefactory.CSharp.Completion } return n is Attribute; } - + IEnumerable CreateTypeAndNamespaceCompletionData(TextLocation location, ResolveResult resolveResult, AstNode resolvedNode, CSharpResolver state) { if (resolveResult == null || resolveResult.IsError) { @@ -2152,28 +2792,30 @@ namespace ICSharpCode.NRefactory.CSharp.Completion } var exprParent = resolvedNode.GetParent(); var unit = exprParent != null ? exprParent.GetParent() : null; - + var astResolver = unit != null ? CompletionContextProvider.GetResolver(state, unit) : null; IType hintType = exprParent != null && astResolver != null ? - CreateFieldAction.GetValidTypes(astResolver, exprParent) .FirstOrDefault() : - null; + TypeGuessing.GetValidTypes(astResolver, exprParent).FirstOrDefault() : + null; var result = new CompletionDataWrapper(this); + var lookup = new MemberLookup( + ctx.CurrentTypeDefinition, + Compilation.MainAssembly + ); if (resolveResult is NamespaceResolveResult) { var nr = (NamespaceResolveResult)resolveResult; if (!(resolvedNode.Parent is UsingDeclaration || resolvedNode.Parent != null && resolvedNode.Parent.Parent is UsingDeclaration)) { foreach (var cl in nr.Namespace.Types) { - string name = cl.Name; if (hintType != null && hintType.Kind != TypeKind.Array && cl.Kind == TypeKind.Interface) { continue; } - if (IsAttributeContext(resolvedNode) && name.EndsWith("Attribute") && name.Length > "Attribute".Length) { - name = name.Substring(0, name.Length - "Attribute".Length); - } - result.AddType(cl, name); + if (!lookup.IsAccessible(cl, false)) + continue; + result.AddType(cl, false, IsAttributeContext(resolvedNode)); } } foreach (var ns in nr.Namespace.ChildNamespaces) { - result.AddNamespace(ns); + result.AddNamespace(lookup, ns); } } else if (resolveResult is TypeResolveResult) { var type = resolveResult.Type; @@ -2181,57 +2823,65 @@ namespace ICSharpCode.NRefactory.CSharp.Completion if (hintType != null && hintType.Kind != TypeKind.Array && nested.Kind == TypeKind.Interface) { continue; } - result.AddType(nested, nested.Name); + var def = nested.GetDefinition(); + if (def != null && !lookup.IsAccessible(def, false)) + continue; + result.AddType(nested, false); } } return result.Result; } - + IEnumerable CreateTypeList() { foreach (var cl in Compilation.RootNamespace.Types) { - yield return factory.CreateTypeCompletionData(cl, cl.Name); + yield return factory.CreateTypeCompletionData(cl, false, false, false); } - + foreach (var ns in Compilation.RootNamespace.ChildNamespaces) { yield return factory.CreateNamespaceCompletionData(ns); } } - + + void CreateParameterForInvocation(CompletionDataWrapper result, IMethod method, CSharpResolver state, int parameter, HashSet addedEnums, HashSet addedDelegates) + { + if (method.Parameters.Count <= parameter) { + return; + } + var resolvedType = method.Parameters [parameter].Type; + if (resolvedType.Kind == TypeKind.Enum) { + if (addedEnums.Contains(resolvedType.ReflectionName)) { + return; + } + addedEnums.Add(resolvedType.ReflectionName); + AddEnumMembers(result, resolvedType, state); + return; + } + + if (resolvedType.Kind == TypeKind.Delegate) { + if (addedDelegates.Contains(resolvedType.ReflectionName)) + return; + AddDelegateHandlers(result, resolvedType, false, true, "Handle" + method.Parameters [parameter].Type.Name + method.Parameters [parameter].Name); + } + } + IEnumerable CreateParameterCompletion(MethodGroupResolveResult resolveResult, CSharpResolver state, AstNode invocation, SyntaxTree unit, int parameter, bool controlSpace) { var result = new CompletionDataWrapper(this); var addedEnums = new HashSet(); var addedDelegates = new HashSet(); - + foreach (var method in resolveResult.Methods) { - if (method.Parameters.Count <= parameter) { - continue; - } - var resolvedType = method.Parameters [parameter].Type; - if (resolvedType.Kind == TypeKind.Enum) { - if (addedEnums.Contains(resolvedType.ReflectionName)) { - continue; - } - addedEnums.Add(resolvedType.ReflectionName); - AddEnumMembers(result, resolvedType, state); - } else if (resolvedType.Kind == TypeKind.Delegate) { - if (addedDelegates.Contains(resolvedType.ReflectionName)) + CreateParameterForInvocation(result, method, state, parameter, addedEnums, addedDelegates); + } + foreach (var methods in resolveResult.GetEligibleExtensionMethods (true)) { + foreach (var method in methods) { + if (resolveResult.Methods.Contains(method)) continue; - string parameterDefinition = AddDelegateHandlers(result, resolvedType); - string varName = "Handle" + method.Parameters [parameter].Type.Name + method.Parameters [parameter].Name; - result.Result.Add( - factory.CreateEventCreationCompletionData( - varName, - resolvedType, - null, - parameterDefinition, - currentMember, - currentType) - ); + CreateParameterForInvocation(result, new ReducedExtensionMethod(method), state, parameter, addedEnums, addedDelegates); } } - + foreach (var method in resolveResult.Methods) { if (parameter < method.Parameters.Count && method.Parameters [parameter].Type.Kind == TypeKind.Delegate) { AutoSelect = false; @@ -2241,7 +2891,7 @@ namespace ICSharpCode.NRefactory.CSharp.Completion result.AddNamedParameterVariable(p); } } - + if (!controlSpace) { if (addedEnums.Count + addedDelegates.Count == 0) { return Enumerable.Empty(); @@ -2250,7 +2900,7 @@ namespace ICSharpCode.NRefactory.CSharp.Completion AutoSelect = false; } AddContextCompletion(result, state, invocation); - + // resolver.AddAccessibleCodeCompletionData (ExpressionContext.MethodBody, cdc); // if (addedDelegates.Count > 0) { // foreach (var data in result.Result) { @@ -2260,72 +2910,58 @@ namespace ICSharpCode.NRefactory.CSharp.Completion // } return result.Result; } - - string GetShortType(IType type, CSharpResolver state) - { - var builder = new TypeSystemAstBuilder(state); - var dt = state.CurrentTypeDefinition; - var declaring = type.DeclaringType != null ? type.DeclaringType.GetDefinition() : null; - if (declaring != null) { - while (dt != null) { - if (dt.Equals(declaring)) { - builder.AlwaysUseShortTypeNames = true; - break; - } - dt = dt.DeclaringTypeDefinition; - } - } - var shortType = builder.ConvertType(type); - return shortType.GetText(FormattingPolicy); - } - + void AddEnumMembers(CompletionDataWrapper completionList, IType resolvedType, CSharpResolver state) { if (resolvedType.Kind != TypeKind.Enum) { return; } - string typeString = GetShortType(resolvedType, state); - completionList.AddEnumMembers(resolvedType, state, typeString); - DefaultCompletionString = typeString; + var type = completionList.AddEnumMembers(resolvedType, state); + if (type != null) + DefaultCompletionString = type.DisplayText; } - + IEnumerable CreateCompletionData(TextLocation location, ResolveResult resolveResult, AstNode resolvedNode, CSharpResolver state, Func typePred = null) { - if (resolveResult == null /*|| resolveResult.IsError*/) { + if (resolveResult == null /* || resolveResult.IsError*/) { return null; } - + + var lookup = new MemberLookup( + ctx.CurrentTypeDefinition, + Compilation.MainAssembly + ); + if (resolveResult is NamespaceResolveResult) { var nr = (NamespaceResolveResult)resolveResult; var namespaceContents = new CompletionDataWrapper(this); - + foreach (var cl in nr.Namespace.Types) { + if (!lookup.IsAccessible(cl, false)) + continue; IType addType = typePred != null ? typePred(cl) : cl; if (addType != null) - namespaceContents.AddType(addType, addType.Name); + namespaceContents.AddType(addType, false); } - + foreach (var ns in nr.Namespace.ChildNamespaces) { - namespaceContents.AddNamespace(ns); + namespaceContents.AddNamespace(lookup, ns); } return namespaceContents.Result; } - IType type = resolveResult.Type; + + if (type.Namespace == "System" && type.Name == "Void") + return null; + if (resolvedNode.Parent is PointerReferenceExpression && (type is PointerType)) { - type = ((PointerType)type).ElementType; + resolveResult = new OperatorResolveResult(((PointerType)type).ElementType, System.Linq.Expressions.ExpressionType.Extension, resolveResult); } - + //var typeDef = resolveResult.Type.GetDefinition(); var result = new CompletionDataWrapper(this); bool includeStaticMembers = false; - - var lookup = new MemberLookup( - ctx.CurrentTypeDefinition, - Compilation.MainAssembly - ); - - + if (resolveResult is LocalResolveResult) { if (resolvedNode is IdentifierExpression) { var mrr = (LocalResolveResult)resolveResult; @@ -2340,14 +2976,14 @@ namespace ICSharpCode.NRefactory.CSharp.Completion } return result.Result; } - - bool isProtectedAllowed = resolveResult is ThisResolveResult ? true : lookup.IsProtectedAccessAllowed(type); + + bool isProtectedAllowed = lookup.IsProtectedAccessAllowed(resolveResult); bool skipNonStaticMembers = (resolveResult is TypeResolveResult); - + if (resolveResult is MemberResolveResult && resolvedNode is IdentifierExpression) { var mrr = (MemberResolveResult)resolveResult; includeStaticMembers = mrr.Member.Name == mrr.Type.Name; - + TypeResolveResult trr; if (state.IsVariableReferenceWithSameType( resolveResult, @@ -2356,10 +2992,11 @@ namespace ICSharpCode.NRefactory.CSharp.Completion )) { if (currentMember != null && mrr.Member.IsStatic ^ currentMember.IsStatic) { skipNonStaticMembers = true; - + if (trr.Type.Kind == TypeKind.Enum) { foreach (var field in trr.Type.GetFields ()) { - result.AddMember(field); + if (lookup.IsAccessible(field, false)) + result.AddMember(field); } return result.Result; } @@ -2367,7 +3004,7 @@ namespace ICSharpCode.NRefactory.CSharp.Completion } // ADD Aliases var scope = ctx.CurrentUsingScope; - + for (var n = scope; n != null; n = n.Parent) { foreach (var pair in n.UsingAliases) { if (pair.Key == mrr.Member.Name) { @@ -2381,91 +3018,84 @@ namespace ICSharpCode.NRefactory.CSharp.Completion } } } - - + + } if (resolveResult is TypeResolveResult && (resolvedNode is IdentifierExpression || resolvedNode is MemberReferenceExpression)) { includeStaticMembers = true; } - + // Console.WriteLine ("type:" + type +"/"+type.GetType ()); // Console.WriteLine ("current:" + ctx.CurrentTypeDefinition); // Console.WriteLine ("IS PROT ALLOWED:" + isProtectedAllowed + " static: "+ includeStaticMembers); // Console.WriteLine (resolveResult); // Console.WriteLine ("node:" + resolvedNode); // Console.WriteLine (currentMember != null ? currentMember.IsStatic : "currentMember == null"); - + if (resolvedNode.Annotation() == null) { //tags the created expression as part of an object create expression. - + /* var filteredList = new List(); foreach (var member in type.GetMembers ()) { - if (member.EntityType == EntityType.Indexer || member.EntityType == EntityType.Operator || member.EntityType == EntityType.Constructor || member.EntityType == EntityType.Destructor) { - continue; - } - if (member.IsExplicitInterfaceImplementation) { - continue; - } - // Console.WriteLine ("member:" + member + member.IsShadowing); - if (!lookup.IsAccessible(member, isProtectedAllowed)) { - // Console.WriteLine ("skip access: " + member.FullName); + filteredList.Add(member); + } + + foreach (var member in filteredList) { + // Console.WriteLine ("add:" + member + "/" + member.IsStatic); + result.AddMember(member); + }*/ + foreach (var member in lookup.GetAccessibleMembers (resolveResult)) { + if (member.SymbolKind == SymbolKind.Indexer || member.SymbolKind == SymbolKind.Operator || member.SymbolKind == SymbolKind.Constructor || member.SymbolKind == SymbolKind.Destructor) { continue; } if (resolvedNode is BaseReferenceExpression && member.IsAbstract) { continue; } + if (member is IType) { + if (resolveResult is TypeResolveResult || includeStaticMembers) { + if (!lookup.IsAccessible(member, isProtectedAllowed)) + continue; + result.AddType((IType)member, false); + continue; + } + } bool memberIsStatic = member.IsStatic; if (!includeStaticMembers && memberIsStatic && !(resolveResult is TypeResolveResult)) { // Console.WriteLine ("skip static member: " + member.FullName); continue; } + var field = member as IField; if (field != null) { memberIsStatic |= field.IsConst; } - if (!memberIsStatic && skipNonStaticMembers) { continue; } - + if (member is IMethod && ((IMethod)member).FullName == "System.Object.Finalize") { continue; } - if (member.EntityType == EntityType.Operator) { - continue; - } - if (member.IsExplicitInterfaceImplementation) { + if (member.SymbolKind == SymbolKind.Operator) { continue; } - if (member.IsShadowing) { - filteredList.RemoveAll(m => m.Name == member.Name); + + if (member is IMember) { + result.AddMember((IMember)member); } - filteredList.Add(member); - } - - foreach (var member in filteredList) { - // Console.WriteLine ("add:" + member + "/" + member.IsStatic); - result.AddMember(member); } } - - if (resolveResult is TypeResolveResult || includeStaticMembers) { - foreach (var nested in type.GetNestedTypes ()) { - if (!lookup.IsAccessible(nested.GetDefinition(), isProtectedAllowed)) - continue; - IType addType = typePred != null ? typePred(nested) : nested; - if (addType != null) - result.AddType(addType, addType.Name); - } - - } else { + + if (!(resolveResult is TypeResolveResult || includeStaticMembers)) { foreach (var meths in state.GetExtensionMethods (type)) { foreach (var m in meths) { - result.AddMember(m); + if (!lookup.IsAccessible(m, isProtectedAllowed)) + continue; + result.AddMember(new ReducedExtensionMethod(m)); } } } - + // IEnumerable objects = resolveResult.CreateResolveResult (dom, resolver != null ? resolver.CallingMember : null); // CompletionDataCollector col = new CompletionDataCollector (this, dom, result, Document.CompilationUnit, resolver != null ? resolver.CallingType : null, location); // col.HideExtensionParameter = !resolveResult.StaticResolve; @@ -2486,10 +3116,10 @@ namespace ICSharpCode.NRefactory.CSharp.Completion // } // } // } - + return result.Result; } - + IEnumerable CreateCaseCompletionData(TextLocation location) { var unit = ParseStub("a: break;"); @@ -2500,24 +3130,25 @@ namespace ICSharpCode.NRefactory.CSharp.Completion if (s == null) { return null; } - + var offset = document.GetOffset(s.Expression.StartLocation); var expr = GetExpressionAt(offset); if (expr == null) { return null; } - + var resolveResult = ResolveExpression(expr); - if (resolveResult == null || resolveResult.Item1.Type.Kind != TypeKind.Enum) { + if (resolveResult == null || resolveResult.Result.Type.Kind != TypeKind.Enum) { return null; } var wrapper = new CompletionDataWrapper(this); - AddEnumMembers(wrapper, resolveResult.Item1.Type, resolveResult.Item2); + AddEnumMembers(wrapper, resolveResult.Result.Type, resolveResult.Resolver); AutoCompleteEmptyMatch = false; return wrapper.Result; } - + #region Parsing methods + ExpressionResult GetExpressionBeforeCursor() { SyntaxTree baseUnit; @@ -2528,7 +3159,7 @@ namespace ICSharpCode.NRefactory.CSharp.Completion baseUnit = ParseStub("a;", false); type = baseUnit.GetNodeAt(location); } - + if (type == null) { baseUnit = ParseStub("A a;", false); type = baseUnit.GetNodeAt(location); @@ -2537,15 +3168,15 @@ namespace ICSharpCode.NRefactory.CSharp.Completion return new ExpressionResult((AstNode)type.Target, baseUnit); } } - - baseUnit = ParseStub("a", false); + + baseUnit = ParseStub("ToString()", false); var curNode = baseUnit.GetNodeAt(location); // hack for local variable declaration missing ';' issue - remove that if it works. if (curNode is EntityDeclaration || baseUnit.GetNodeAt(location) == null && baseUnit.GetNodeAt(location) == null) { baseUnit = ParseStub("a"); curNode = baseUnit.GetNodeAt(location); } - + // Hack for handle object initializer continuation expressions if (curNode is EntityDeclaration || baseUnit.GetNodeAt(location) == null && baseUnit.GetNodeAt(location) == null) { baseUnit = ParseStub("a};"); @@ -2557,19 +3188,28 @@ namespace ICSharpCode.NRefactory.CSharp.Completion } return null; } - + //var memberLocation = currentMember != null ? currentMember.Region.Begin : currentType.Region.Begin; if (mref == null) { var type = baseUnit.GetNodeAt(location); if (type != null) { return new ExpressionResult((AstNode)type.Target, baseUnit); } - + var pref = baseUnit.GetNodeAt(location); if (pref != null) { return new ExpressionResult((AstNode)pref.Target, baseUnit); } } + + if (mref == null) { + baseUnit = ParseStub("A a;", false); + var type = baseUnit.GetNodeAt(location); + if (type != null) { + return new ExpressionResult((AstNode)type.Target, baseUnit); + } + } + AstNode expr = null; if (mref != null) { expr = mref.Target; @@ -2591,25 +3231,25 @@ namespace ICSharpCode.NRefactory.CSharp.Completion memberType.Parent.AddChild(tref, Roles.Expression); } if (tref is ObjectCreateExpression) { - expr = new TypeReferenceExpression(memberType.Target.Clone()); + expr = memberType.Target.Clone(); expr.AddAnnotation(new ObjectCreateExpression()); } } } } - + if (memberType == null) { return null; } if (expr == null) { - expr = new TypeReferenceExpression(memberType.Target.Clone()); + expr = memberType.Target.Clone(); } tref.ReplaceWith(expr); } exit: return new ExpressionResult((AstNode)expr, baseUnit); } - + ExpressionResult GetExpressionAtCursor() { // TextLocation memberLocation; @@ -2626,24 +3266,21 @@ namespace ICSharpCode.NRefactory.CSharp.Completion location, n => n is IdentifierExpression || n is MemberReferenceExpression ); - + if (expr == null) { expr = baseUnit.GetNodeAt(location.Line, location.Column - 1); } if (expr == null) expr = baseUnit.GetNodeAt(location.Line, location.Column - 1); // try insertStatement - if (expr == null && baseUnit.GetNodeAt( - location.Line, - location.Column - ) != null) { + if (expr == null && baseUnit.GetNodeAt(location.Line, location.Column) != null) { tmpUnit = baseUnit = ParseStub("a();", false); expr = baseUnit.GetNodeAt( location.Line, location.Column + 1 ); } - + if (expr == null) { baseUnit = ParseStub("()"); expr = baseUnit.GetNodeAt( @@ -2654,7 +3291,7 @@ namespace ICSharpCode.NRefactory.CSharp.Completion expr = baseUnit.GetNodeAt(location.Line, location.Column - 1); } } - + if (expr == null) { baseUnit = ParseStub("a", false); expr = baseUnit.GetNodeAt( @@ -2662,7 +3299,7 @@ namespace ICSharpCode.NRefactory.CSharp.Completion n => n is IdentifierExpression || n is MemberReferenceExpression || n is CatchClause ); } - + // try statement if (expr == null) { expr = tmpUnit.GetNodeAt( @@ -2671,21 +3308,21 @@ namespace ICSharpCode.NRefactory.CSharp.Completion ); baseUnit = tmpUnit; } - + if (expr == null) { var block = tmpUnit.GetNodeAt(location); var node = block != null ? block.Statements.LastOrDefault() : null; - + var forStmt = node != null ? node.PrevSibling as ForStatement : null; if (forStmt != null && forStmt.EmbeddedStatement.IsNull) { expr = forStmt; var id = new IdentifierExpression("stub"); - forStmt.EmbeddedStatement = new BlockStatement() { Statements = { new ExpressionStatement (id) }}; + forStmt.EmbeddedStatement = new BlockStatement() { Statements = { new ExpressionStatement(id) } }; expr = id; baseUnit = tmpUnit; } } - + if (expr == null) { var forStmt = tmpUnit.GetNodeAt( location.Line, @@ -2704,7 +3341,7 @@ namespace ICSharpCode.NRefactory.CSharp.Completion ); baseUnit = tmpUnit; } - + // try parameter declaration type if (expr == null) { baseUnit = ParseStub(">", false, "{}"); @@ -2713,7 +3350,7 @@ namespace ICSharpCode.NRefactory.CSharp.Completion location.Column - 1 ); } - + // try parameter declaration method if (expr == null) { baseUnit = ParseStub("> ()", false, "{}"); @@ -2722,7 +3359,7 @@ namespace ICSharpCode.NRefactory.CSharp.Completion location.Column - 1 ); } - + // try expression in anonymous type "new { sample = x$" case if (expr == null) { baseUnit = ParseStub("a", false); @@ -2737,53 +3374,59 @@ namespace ICSharpCode.NRefactory.CSharp.Completion expr = baseUnit.GetNodeAt(location.Line, location.Column); } } - + + // try lambda if (expr == null) { - return null; + baseUnit = ParseStub("foo) => {}", false); + expr = baseUnit.GetNodeAt( + location.Line, + location.Column + ); } + + if (expr == null) + return null; return new ExpressionResult(expr, baseUnit); } - + ExpressionResult GetExpressionAt(int offset) { var parser = new CSharpParser(); - string text = this.document.GetText(0, this.offset); - var sb = new StringBuilder(text); - sb.Append("a;"); - AppendMissingClosingBrackets(sb, text, false); + var text = GetMemberTextToCaret(); + + int closingBrackets = 0, generatedLines = 0; + var sb = CreateWrapper("a;", false, "", text.Item1, text.Item2, ref closingBrackets, ref generatedLines); + var completionUnit = parser.Parse(sb.ToString()); - var loc = document.GetLocation(offset); - + var offsetLocation = document.GetLocation(offset); + var loc = new TextLocation(offsetLocation.Line - text.Item2.Line + generatedLines + 1, offsetLocation.Column); + var expr = completionUnit.GetNodeAt( loc, n => n is Expression || n is VariableDeclarationStatement ); - if (expr == null) { + if (expr == null) return null; - } return new ExpressionResult(expr, completionUnit); } - + ExpressionResult GetNewExpressionAt(int offset) { var parser = new CSharpParser(); - string text = this.document.GetText(0, this.offset); - var sb = new StringBuilder(text); - sb.Append("a ();"); - AppendMissingClosingBrackets(sb, text, false); - + var text = GetMemberTextToCaret(); + int closingBrackets = 0, generatedLines = 0; + var sb = CreateWrapper("a ();", false, "", text.Item1, text.Item2, ref closingBrackets, ref generatedLines); + var completionUnit = parser.Parse(sb.ToString()); - var loc = document.GetLocation(offset); - + var offsetLocation = document.GetLocation(offset); + var loc = new TextLocation(offsetLocation.Line - text.Item2.Line + generatedLines + 1, offsetLocation.Column); + var expr = completionUnit.GetNodeAt(loc, n => n is Expression); if (expr == null) { // try without ";" - sb = new StringBuilder(text); - sb.Append("a ()"); - AppendMissingClosingBrackets(sb, text, false); + sb = CreateWrapper("a ()", false, "", text.Item1, text.Item2, ref closingBrackets, ref generatedLines); completionUnit = parser.Parse(sb.ToString()); - loc = document.GetLocation(offset); - + expr = completionUnit.GetNodeAt(loc, n => n is Expression); if (expr == null) { return null; @@ -2791,48 +3434,48 @@ namespace ICSharpCode.NRefactory.CSharp.Completion } return new ExpressionResult(expr, completionUnit); } - - -#endregion - + + #endregion + #region Helper methods + string GetPreviousToken(ref int i, bool allowLineChange) { char c; if (i <= 0) { return null; } - + do { c = document.GetCharAt(--i); - } while (i > 0 && char.IsWhiteSpace (c) && (allowLineChange ? true : c != '\n')); - + } while (i > 0 && char.IsWhiteSpace(c) && (allowLineChange ? true : c != '\n')); + if (i == 0) { return null; } - + if (!char.IsLetterOrDigit(c)) { return new string(c, 1); } - + int endOffset = i + 1; - + do { c = document.GetCharAt(i - 1); if (!(char.IsLetterOrDigit(c) || c == '_')) { break; } - + i--; } while (i > 0); - + return document.GetText(i, endOffset - i); } - -#endregion - + + #endregion + #region Preprocessor - + IEnumerable GetDirectiveCompletionData() { yield return factory.CreateLiteralCompletionData("if"); @@ -2850,9 +3493,11 @@ namespace ICSharpCode.NRefactory.CSharp.Completion yield return factory.CreateLiteralCompletionData("region"); yield return factory.CreateLiteralCompletionData("endregion"); } -#endregion - + + #endregion + #region Xml Comments + static readonly List commentTags = new List(new string[] { "c", "code", @@ -2875,15 +3520,21 @@ namespace ICSharpCode.NRefactory.CSharp.Completion "summary", "value" } - ); - + ); + + public static IEnumerable CommentTags { + get { + return commentTags; + } + } + string GetLastClosingXmlCommentTag() { var line = document.GetLineByNumber(location.Line); - + restart: string lineText = document.GetText(line); - if (!lineText.Trim().StartsWith("///")) + if (!lineText.Trim().StartsWith("///", StringComparison.Ordinal)) return null; int startIndex = Math.Min(location.Column - 1, lineText.Length - 1) - 1; while (startIndex > 0 && lineText [startIndex] != '<') { @@ -2898,10 +3549,10 @@ namespace ICSharpCode.NRefactory.CSharp.Completion line = line.PreviousLine; goto restart; } - + if (startIndex >= 0) { int endIndex = startIndex; - while (endIndex + 1 < lineText.Length && lineText [endIndex] != '>' && !Char.IsWhiteSpace (lineText [endIndex + 1])) { + while (endIndex + 1 < lineText.Length && lineText [endIndex] != '>' && !char.IsWhiteSpace(lineText [endIndex])) { endIndex++; } string tag = endIndex - startIndex - 1 > 0 ? lineText.Substring( @@ -2914,7 +3565,7 @@ namespace ICSharpCode.NRefactory.CSharp.Completion } return null; } - + IEnumerable GetXmlDocumentationCompletionData() { var closingTag = GetLastClosingXmlCommentTag(); @@ -2923,108 +3574,115 @@ namespace ICSharpCode.NRefactory.CSharp.Completion "/" + closingTag + ">" ); } - - yield return factory.CreateLiteralCompletionData( + + yield return factory.CreateXmlDocCompletionData( "c", "Set text in a code-like font" ); - yield return factory.CreateLiteralCompletionData( + yield return factory.CreateXmlDocCompletionData( "code", "Set one or more lines of source code or program output" ); - yield return factory.CreateLiteralCompletionData( + yield return factory.CreateXmlDocCompletionData( "example", "Indicate an example" ); - yield return factory.CreateLiteralCompletionData( + yield return factory.CreateXmlDocCompletionData( "exception", "Identifies the exceptions a method can throw", - "exception cref=\"|\">" + "exception cref=\"|\">" + "include file=\"|\" path=\"\"" ); - yield return factory.CreateLiteralCompletionData( + yield return factory.CreateXmlDocCompletionData( + "inheritdoc", + "Inherit documentation from a base class or interface", + "inheritdoc/" + ); + yield return factory.CreateXmlDocCompletionData( "list", "Create a list or table", - "list type=\"|\">" + "list type=\"|\"" ); - yield return factory.CreateLiteralCompletionData( + yield return factory.CreateXmlDocCompletionData( "listheader", "Define the heading row" ); - yield return factory.CreateLiteralCompletionData( + yield return factory.CreateXmlDocCompletionData( "item", "Defines list or table item" ); - - yield return factory.CreateLiteralCompletionData("term", "A term to define"); - yield return factory.CreateLiteralCompletionData( + + yield return factory.CreateXmlDocCompletionData("term", "A term to define"); + yield return factory.CreateXmlDocCompletionData( "description", "Describes a list item" ); - yield return factory.CreateLiteralCompletionData( + yield return factory.CreateXmlDocCompletionData( "para", "Permit structure to be added to text" ); - - yield return factory.CreateLiteralCompletionData( + + yield return factory.CreateXmlDocCompletionData( "param", "Describe a parameter for a method or constructor", - "param name=\"|\">" + "param name=\"|\"" ); - yield return factory.CreateLiteralCompletionData( + yield return factory.CreateXmlDocCompletionData( "paramref", "Identify that a word is a parameter name", - "paramref name=\"|\"/>" + "paramref name=\"|\"/" ); - - yield return factory.CreateLiteralCompletionData( + + yield return factory.CreateXmlDocCompletionData( "permission", "Document the security accessibility of a member", "permission cref=\"|\"" ); - yield return factory.CreateLiteralCompletionData( + yield return factory.CreateXmlDocCompletionData( "remarks", "Describe a type" ); - yield return factory.CreateLiteralCompletionData( + yield return factory.CreateXmlDocCompletionData( "returns", "Describe the return value of a method" ); - yield return factory.CreateLiteralCompletionData( + yield return factory.CreateXmlDocCompletionData( "see", "Specify a link", - "see cref=\"|\"/>" + "see cref=\"|\"/" ); - yield return factory.CreateLiteralCompletionData( + yield return factory.CreateXmlDocCompletionData( "seealso", "Generate a See Also entry", - "seealso cref=\"|\"/>" + "seealso cref=\"|\"/" ); - yield return factory.CreateLiteralCompletionData( + yield return factory.CreateXmlDocCompletionData( "summary", "Describe a member of a type" ); - yield return factory.CreateLiteralCompletionData( + yield return factory.CreateXmlDocCompletionData( "typeparam", "Describe a type parameter for a generic type or method" ); - yield return factory.CreateLiteralCompletionData( + yield return factory.CreateXmlDocCompletionData( "typeparamref", "Identify that a word is a type parameter name" ); - yield return factory.CreateLiteralCompletionData( + yield return factory.CreateXmlDocCompletionData( "value", "Describe a property" ); - + } -#endregion - + + #endregion + #region Keywords + static string[] expressionLevelKeywords = new string [] { "as", "is", @@ -3066,13 +3724,13 @@ namespace ICSharpCode.NRefactory.CSharp.Completion "abstract", "sealed", "static", "unsafe", "partial" }; static string[] accessorModifierKeywords = new string [] { - "public", "internal", "protected", "private" + "public", "internal", "protected", "private", "async" }; static string[] typeLevelKeywords = new string [] { - "public", "internal", "protected", "private", + "public", "internal", "protected", "private", "async", "class", "interface", "struct", "enum", "delegate", "abstract", "sealed", "static", "unsafe", "partial", - "const", "event", "extern", "fixed","new", + "const", "event", "extern", "fixed", "new", "operator", "explicit", "implicit", "override", "readonly", "virtual", "volatile" }; @@ -3097,7 +3755,9 @@ namespace ICSharpCode.NRefactory.CSharp.Completion "ref", "params" }; -#endregion + + #endregion + } } diff --git a/NRefactory/ICSharpCode.NRefactory.CSharp/Completion/CSharpCompletionEngineBase.cs b/NRefactory/ICSharpCode.NRefactory.CSharp/Completion/CSharpCompletionEngineBase.cs index 85cf16368..c61f77bc5 100644 --- a/NRefactory/ICSharpCode.NRefactory.CSharp/Completion/CSharpCompletionEngineBase.cs +++ b/NRefactory/ICSharpCode.NRefactory.CSharp/Completion/CSharpCompletionEngineBase.cs @@ -62,6 +62,16 @@ namespace ICSharpCode.NRefactory.CSharp.Completion return compilation; } } + + Version languageVersion = new Version (5, 0); + public Version LanguageVersion { + get { + return languageVersion; + } + set { + languageVersion = value; + } + } #endregion protected CSharpCompletionEngineBase(IProjectContent content, ICompletionContextProvider completionContextProvider, CSharpTypeResolveContext ctx) @@ -99,7 +109,7 @@ namespace ICSharpCode.NRefactory.CSharp.Completion // current member, instead of the beginning of the file. cpos = offset - 1; var mem = currentMember; - if (mem == null || (mem is IType)) { + if (mem == null || (mem is IType) || IsInsideCommentStringOrDirective ()) { return false; } int startPos = document.GetOffset (mem.Region.BeginLine, mem.Region.BeginColumn); @@ -146,143 +156,169 @@ namespace ICSharpCode.NRefactory.CSharp.Completion return false; } - public int GetCurrentParameterIndex (int triggerOffset, int endOffset) + public int GetCurrentParameterIndex(int triggerOffset, int endOffset) { - char lastChar = document.GetCharAt (endOffset - 1); - if (lastChar == '(' || lastChar == '<') { - return 0; - } + List list; + return GetCurrentParameterIndex (triggerOffset, endOffset, out list); + } + + public int GetCurrentParameterIndex (int triggerOffset, int endOffset, out List usedNamedParameters) + { + usedNamedParameters =new List (); var parameter = new Stack (); var bracketStack = new Stack> (); bool inSingleComment = false, inString = false, inVerbatimString = false, inChar = false, inMultiLineComment = false; + var word = new StringBuilder (); + bool foundCharAfterOpenBracket = false; for (int i = triggerOffset; i < endOffset; i++) { char ch = document.GetCharAt (i); char nextCh = i + 1 < document.TextLength ? document.GetCharAt (i + 1) : '\0'; + if (ch == ':') { + usedNamedParameters.Add (word.ToString ()); + word.Length = 0; + } else if (char.IsLetterOrDigit (ch) || ch =='_') { + word.Append (ch); + } else if (char.IsWhiteSpace (ch)) { + + } else { + word.Length = 0; + } + if (!char.IsWhiteSpace(ch) && parameter.Count > 0) + foundCharAfterOpenBracket = true; + switch (ch) { - case '{': - if (inString || inChar || inVerbatimString || inSingleComment || inMultiLineComment) { - break; - } - bracketStack.Push (parameter); - parameter = new Stack (); - break; - case '[': - case '(': - if (inString || inChar || inVerbatimString || inSingleComment || inMultiLineComment) { + case '{': + if (inString || inChar || inVerbatimString || inSingleComment || inMultiLineComment) { + break; + } + bracketStack.Push (parameter); + parameter = new Stack (); break; - } - parameter.Push (0); - break; - case '}': - if (inString || inChar || inVerbatimString || inSingleComment || inMultiLineComment) { + case '[': + case '(': + if (inString || inChar || inVerbatimString || inSingleComment || inMultiLineComment) { + break; + } + parameter.Push (0); break; - } - if (bracketStack.Count > 0) { - parameter = bracketStack.Pop (); - } else { - return -1; - } - break; - case ']': - case ')': - if (inString || inChar || inVerbatimString || inSingleComment || inMultiLineComment) { + case '}': + if (inString || inChar || inVerbatimString || inSingleComment || inMultiLineComment) { + break; + } + if (bracketStack.Count > 0) { + parameter = bracketStack.Pop (); + } else { + return -1; + } break; - } - if (parameter.Count > 0) { - parameter.Pop (); - } else { - return -1; - } - break; - case '<': - if (inString || inChar || inVerbatimString || inSingleComment || inMultiLineComment) { + case ']': + case ')': + if (inString || inChar || inVerbatimString || inSingleComment || inMultiLineComment) { + break; + } + if (parameter.Count > 0) { + parameter.Pop (); + } else { + return -1; + } break; - } - parameter.Push (0); - break; - case '>': - if (inString || inChar || inVerbatimString || inSingleComment || inMultiLineComment) { + case '<': + if (inString || inChar || inVerbatimString || inSingleComment || inMultiLineComment) { + break; + } + parameter.Push (0); break; - } - if (parameter.Count > 0) { - parameter.Pop (); - } - break; - case ',': - if (inString || inChar || inVerbatimString || inSingleComment || inMultiLineComment) { + case '=': + if (nextCh == '>') { + i++; + continue; + } break; - } - if (parameter.Count > 0) { - parameter.Push (parameter.Pop () + 1); - } - break; - case '/': - if (inString || inChar || inVerbatimString) { + case '>': + if (inString || inChar || inVerbatimString || inSingleComment || inMultiLineComment) { + break; + } + if (parameter.Count > 0) { + parameter.Pop (); + } break; - } - if (nextCh == '/') { - i++; - inSingleComment = true; - } - if (nextCh == '*') { - inMultiLineComment = true; - } - break; - case '*': - if (inString || inChar || inVerbatimString || inSingleComment) { + case ',': + if (inString || inChar || inVerbatimString || inSingleComment || inMultiLineComment) { + break; + } + if (parameter.Count > 0) { + parameter.Push (parameter.Pop () + 1); + } break; - } - if (nextCh == '/') { - i++; - inMultiLineComment = false; - } - break; - case '@': - if (inString || inChar || inVerbatimString || inSingleComment || inMultiLineComment) { + case '/': + if (inString || inChar || inVerbatimString) { + break; + } + if (nextCh == '/') { + i++; + inSingleComment = true; + } + if (nextCh == '*') { + inMultiLineComment = true; + } 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) { + case '*': + if (inString || inChar || inVerbatimString || inSingleComment) { + break; + } + if (nextCh == '/') { + i++; + inMultiLineComment = false; + } break; - } - if (inVerbatimString) { + case '@': + if (inString || inChar || inVerbatimString || inSingleComment || inMultiLineComment) { + break; + } if (nextCh == '"') { i++; + inVerbatimString = true; + } + break; + case '\\': + if (inString || inChar) { + i++; + } + break; + case '"': + if (inSingleComment || inMultiLineComment || inChar) { break; } - inVerbatimString = false; + if (inVerbatimString) { + if (nextCh == '"') { + i++; + break; + } + inVerbatimString = false; + break; + } + inString = !inString; break; - } - inString = !inString; - break; - case '\'': - if (inSingleComment || inMultiLineComment || inString || inVerbatimString) { + case '\'': + if (inSingleComment || inMultiLineComment || inString || inVerbatimString) { + break; + } + inChar = !inChar; + break; + default: + if (NewLine.IsNewLine(ch)) { + inSingleComment = false; + inString = false; + inChar = false; + } break; - } - inChar = !inChar; - break; } } - if (parameter.Count == 0 || bracketStack.Count > 0) { + if (parameter.Count != 1 || bracketStack.Count > 0) { return -1; } - + if (!foundCharAfterOpenBracket) + return 0; return parameter.Pop() + 1; } @@ -291,12 +327,12 @@ namespace ICSharpCode.NRefactory.CSharp.Completion { readonly string text; - public bool IsFistNonWs = true; - public bool IsInSingleComment = false; - public bool IsInString = false; - public bool IsInVerbatimString = false; - public bool IsInChar = false; - public bool IsInMultiLineComment = false; + public bool IsFistNonWs = true; + public bool IsInSingleComment = false; + public bool IsInString = false; + public bool IsInVerbatimString = false; + public bool IsInChar = false; + public bool IsInMultiLineComment = false; public bool IsInPreprocessorDirective = false; public MiniLexer(string text) @@ -304,12 +340,27 @@ namespace ICSharpCode.NRefactory.CSharp.Completion this.text = text; } - public void Parse(Action act = null) + /// + /// Parsing all text and calling act delegate on almost every character. + /// Skipping begining of comments, begining of verbatim strings and escaped characters. + /// + /// Return true to abort parsing. Integer argument represent offset in text. + /// True if aborted. + public bool Parse(Func act = null) { - Parse(0, text.Length, act); + return Parse(0, text.Length, act); } - public void Parse(int start, int length, Action act = null) + + /// + /// Parsing text from start to start+length and calling act delegate on almost every character. + /// Skipping begining of comments, begining of verbatim strings and escaped characters. + /// + /// Start offset. + /// Lenght to parse. + /// Return true to abort parsing. Integer argument represent offset in text. + /// True if aborted. + public bool Parse(int start, int length, Func act = null) { for (int i = start; i < length; i++) { char ch = text [i]; @@ -318,16 +369,19 @@ namespace ICSharpCode.NRefactory.CSharp.Completion case '#': if (IsFistNonWs) IsInPreprocessorDirective = true; - break; + break; case '/': - if (IsInString || IsInChar || IsInVerbatimString) + if (IsInString || IsInChar || IsInVerbatimString || IsInSingleComment || IsInMultiLineComment) break; if (nextCh == '/') { i++; IsInSingleComment = true; + IsInPreprocessorDirective = false; } - if (nextCh == '*') + if (nextCh == '*' && !IsInPreprocessorDirective) { IsInMultiLineComment = true; + i++; + } break; case '*': if (IsInString || IsInChar || IsInVerbatimString || IsInSingleComment) @@ -377,9 +431,11 @@ namespace ICSharpCode.NRefactory.CSharp.Completion break; } if (act != null) - act(ch); + if (act (ch, i)) + return true; IsFistNonWs &= ch == ' ' || ch == '\t' || ch == '\n' || ch == '\r'; } + return false; } } @@ -405,11 +461,11 @@ namespace ICSharpCode.NRefactory.CSharp.Completion lexer.Parse(); return lexer.IsInSingleComment || - lexer.IsInString || - lexer.IsInVerbatimString || - lexer.IsInChar || - lexer.IsInMultiLineComment || - lexer.IsInPreprocessorDirective; + lexer.IsInString || + lexer.IsInVerbatimString || + lexer.IsInChar || + lexer.IsInMultiLineComment || + lexer.IsInPreprocessorDirective; } protected bool IsInsideDocComment () @@ -566,12 +622,6 @@ namespace ICSharpCode.NRefactory.CSharp.Completion inVerbatimString = true; } break; - case '\n': - case '\r': - inSingleComment = false; - inString = false; - inChar = false; - break; case '\\': if (inString || inChar) i++; @@ -595,15 +645,21 @@ namespace ICSharpCode.NRefactory.CSharp.Completion inChar = !inChar; break; default : + if (NewLine.IsNewLine(ch)) { + inSingleComment = false; + inString = false; + inChar = false; + } break; } } return bracketStack; } - public static void AppendMissingClosingBrackets (StringBuilder wrapper, string memberText, bool appendSemicolon) + public static void AppendMissingClosingBrackets (StringBuilder wrapper, bool appendSemicolon) { - var bracketStack = GetBracketStack (memberText); + var memberText = wrapper.ToString(); + var bracketStack = GetBracketStack(memberText); bool didAppendSemicolon = !appendSemicolon; //char lastBracket = '\0'; while (bracketStack.Count > 0) { @@ -638,7 +694,7 @@ namespace ICSharpCode.NRefactory.CSharp.Completion while (o >= "try".Length) { char ch = memberText [o]; if (!char.IsWhiteSpace (ch)) { - if (ch == 'y' && memberText [o - 1] == 'r' && memberText [o - 2] == 't') { + if (ch == 'y' && memberText [o - 1] == 'r' && memberText [o - 2] == 't' && (o - 3 < 0 || !char.IsLetterOrDigit(memberText [o - 3]))) { wrapper.Append ("} catch {}"); didAppendCatch = true; } @@ -655,17 +711,8 @@ namespace ICSharpCode.NRefactory.CSharp.Completion wrapper.Append (';'); } - protected SyntaxTree ParseStub(string continuation, bool appendSemicolon = true, string afterContinuation = null) + protected StringBuilder CreateWrapper(string continuation, bool appendSemicolon, string afterContinuation, string memberText, TextLocation memberLocation, ref int closingBrackets, ref int generatedLines) { - var mt = GetMemberTextToCaret(); - if (mt == null) { - return null; - } - - string memberText = mt.Item1; - var memberLocation = mt.Item2; - int closingBrackets = 1; - int generatedLines = 0; var wrapper = new StringBuilder(); bool wrapInClass = memberLocation != new TextLocation(1, 1); if (wrapInClass) { @@ -676,11 +723,26 @@ namespace ICSharpCode.NRefactory.CSharp.Completion } wrapper.Append(memberText); wrapper.Append(continuation); - AppendMissingClosingBrackets(wrapper, memberText, appendSemicolon); + AppendMissingClosingBrackets(wrapper, appendSemicolon); wrapper.Append(afterContinuation); - if (closingBrackets > 0) { + if (closingBrackets > 0) { wrapper.Append(new string('}', closingBrackets)); } + return wrapper; + } + + protected SyntaxTree ParseStub(string continuation, bool appendSemicolon = true, string afterContinuation = null) + { + var mt = GetMemberTextToCaret(); + if (mt == null) { + return null; + } + + string memberText = mt.Item1; + var memberLocation = mt.Item2; + int closingBrackets = 1; + int generatedLines = 0; + var wrapper = CreateWrapper(continuation, appendSemicolon, afterContinuation, memberText, memberLocation, ref closingBrackets, ref generatedLines); var parser = new CSharpParser (); foreach (var sym in CompletionContextProvider.ConditionalSymbols) parser.CompilerSettings.ConditionalSymbols.Add (sym); @@ -689,23 +751,24 @@ namespace ICSharpCode.NRefactory.CSharp.Completion return result; } -// string cachedText = null; - protected virtual void Reset () { -// cachedText = null; + memberText = null; } - + + Tuple memberText; protected Tuple GetMemberTextToCaret() { - return CompletionContextProvider.GetMemberTextToCaret(offset, currentType, currentMember); + if (memberText == null) + memberText = CompletionContextProvider.GetMemberTextToCaret(offset, currentType, currentMember); + return memberText; } - + protected ExpressionResult GetInvocationBeforeCursor(bool afterBracket) { SyntaxTree baseUnit; baseUnit = ParseStub("a", false); - + var section = baseUnit.GetNodeAt(location.Line, location.Column - 2); var attr = section != null ? section.Attributes.LastOrDefault() : null; if (attr != null) { @@ -773,12 +836,26 @@ namespace ICSharpCode.NRefactory.CSharp.Completion } } - protected Tuple ResolveExpression (ExpressionResult tuple) + protected ExpressionResolveResult ResolveExpression (ExpressionResult tuple) { return ResolveExpression (tuple.Node); } - protected Tuple ResolveExpression(AstNode expr) + protected class ExpressionResolveResult + { + public ResolveResult Result { get; set; } + public CSharpResolver Resolver { get; set; } + public CSharpAstResolver AstResolver { get; set; } + + public ExpressionResolveResult(ResolveResult item1, CSharpResolver item2, CSharpAstResolver item3) + { + this.Result = item1; + this.Resolver = item2; + this.AstResolver = item3; + } + } + + protected ExpressionResolveResult ResolveExpression(AstNode expr) { if (expr == null) { return null; @@ -796,12 +873,29 @@ namespace ICSharpCode.NRefactory.CSharp.Completion if (root == null) { return null; } - if (root is Accessor) - root = root.Parent; - var csResolver = CompletionContextProvider.GetResolver (GetState(), root); + var curState = GetState(); + // current member needs to be in the setter because of the 'value' parameter + if (root is Accessor) { + var prop = curState.CurrentMember as IProperty; + if (prop != null && prop.CanSet && (root.Role == IndexerDeclaration.SetterRole || root.Role == PropertyDeclaration.SetterRole)) + curState = curState.WithCurrentMember(prop.Setter); + } + + // Rood should be the 'body' - otherwise the state -> current member isn't correct. + var body = root.Children.FirstOrDefault(r => r.Role == Roles.Body); + if (body != null && body.Contains(expr.StartLocation)) + root = body; + + var csResolver = CompletionContextProvider.GetResolver (curState, root); var result = csResolver.Resolve(resolveNode); var state = csResolver.GetResolverStateBefore(resolveNode); - return Tuple.Create(result, state); + if (state.CurrentMember == null) + state = state.WithCurrentMember(curState.CurrentMember); + if (state.CurrentTypeDefinition == null) + state = state.WithCurrentTypeDefinition(curState.CurrentTypeDefinition); + if (state.CurrentUsingScope == null) + state = state.WithCurrentUsingScope(curState.CurrentUsingScope); + return new ExpressionResolveResult(result, state, csResolver); } catch (Exception e) { Console.WriteLine(e); return null; diff --git a/NRefactory/ICSharpCode.NRefactory.CSharp/Completion/CSharpParameterCompletionEngine.cs b/NRefactory/ICSharpCode.NRefactory.CSharp/Completion/CSharpParameterCompletionEngine.cs index 721c0f0a8..e5919834e 100644 --- a/NRefactory/ICSharpCode.NRefactory.CSharp/Completion/CSharpParameterCompletionEngine.cs +++ b/NRefactory/ICSharpCode.NRefactory.CSharp/Completion/CSharpParameterCompletionEngine.cs @@ -57,7 +57,7 @@ namespace ICSharpCode.NRefactory.CSharp.Completion if (currentMember == null && currentType == null) { return null; } - baseUnit = ParseStub("x] = a[1"); + baseUnit = ParseStub("x]"); //var memberLocation = currentMember != null ? currentMember.Region.Begin : currentType.Region.Begin; var mref = baseUnit.GetNodeAt(location, n => n is IndexerExpression); @@ -102,6 +102,23 @@ namespace ICSharpCode.NRefactory.CSharp.Completion return new ExpressionResult((AstNode)expr, baseUnit); } + public ExpressionResult GetMethodTypeArgumentInvocationBeforeCursor() + { + SyntaxTree baseUnit; + if (currentMember == null && currentType == null) { + return null; + } + baseUnit = ParseStub("x>.A ()"); + + //var memberLocation = currentMember != null ? currentMember.Region.Begin : currentType.Region.Begin; + var expr = baseUnit.GetNodeAt(location.Line, location.Column + 1); + if (expr == null) + return null; + return new ExpressionResult((AstNode)expr, baseUnit); + } + + + IEnumerable CollectMethods(AstNode resolvedNode, MethodGroupResolveResult resolveResult) { var lookup = new MemberLookup(ctx.CurrentTypeDefinition, Compilation.MainAssembly); @@ -109,6 +126,7 @@ namespace ICSharpCode.NRefactory.CSharp.Completion if (resolvedNode is IdentifierExpression && currentMember != null && currentMember.IsStatic || resolveResult.TargetResult is TypeResolveResult) { onlyStatic = true; } + var methods = new List(); foreach (var method in resolveResult.Methods) { if (method.IsConstructor) { continue; @@ -118,32 +136,140 @@ namespace ICSharpCode.NRefactory.CSharp.Completion if (onlyStatic && !method.IsStatic) { continue; } - yield return method; + if (method.IsShadowing) { + for (int j = 0; j < methods.Count; j++) { + if (ParameterListComparer.Instance.Equals(methods[j].Parameters, method.Parameters)) { + methods.RemoveAt (j); + j--; + } + } + } + methods.Add (method); + } + foreach (var m in methods) { + yield return m; } - foreach (var extMethods in resolveResult.GetEligibleExtensionMethods (true)) { foreach (var method in extMethods) { - yield return method; + if (methods.Contains (method)) + continue; + yield return new ReducedExtensionMethod (method); } } } + + IEnumerable GetAccessibleIndexers(IType type) + { + var lookup = new MemberLookup(ctx.CurrentTypeDefinition, Compilation.MainAssembly); + var properties = new List(); + foreach (var property in type.GetProperties ()) { + if (!property.IsIndexer) + continue; + if (!lookup.IsAccessible (property, true)) + continue; + if (property.IsShadowing) { + for (int j = 0; j < properties.Count; j++) { + if (ParameterListComparer.Instance.Equals(properties[j].Parameters, property.Parameters)) { + properties.RemoveAt (j); + j--; + } + } + } + + properties.Add (property); + } + return properties; + } public IParameterDataProvider GetParameterDataProvider(int offset, char completionChar) { - if (offset <= 0) { + //Ignoring completionChar == '\0' because it usually means moving with arrow keys, tab or enter + //we don't want to trigger on those events but it probably should be handled somewhere else + //since our job is to resolve method and not to decide when to display tooltip or not + if (offset <= 0 || completionChar == '\0') { return null; } - if (completionChar != '(' && completionChar != '<' && completionChar != '[' && completionChar != ',') { - return null; + SetOffset (offset); + int startOffset; + string text; + if (currentMember == null && currentType == null) { + //In case of attributes parse all file + startOffset = 0; + text = document.Text; + } else { + var memberText = GetMemberTextToCaret (); + text = memberText.Item1; + startOffset = document.GetOffset (memberText.Item2); } - - SetOffset(offset); - if (IsInsideCommentStringOrDirective()) { + + var parenStack = new Stack (); + var chevronStack = new Stack (); + var squareStack = new Stack (); + var bracketStack = new Stack (); + + var lex = new MiniLexer (text); + bool failed = lex.Parse ((ch, off) => { + if (lex.IsInString || lex.IsInChar || lex.IsInVerbatimString || lex.IsInSingleComment || lex.IsInMultiLineComment || lex.IsInPreprocessorDirective) + return false; + switch (ch) { + case '(': + parenStack.Push (startOffset + off); + break; + case ')': + if (parenStack.Count == 0) { + return true; + } + parenStack.Pop (); + break; + case '<': + chevronStack.Push (startOffset + off); + break; + case '>': + //Don't abort if we don't have macthing '<' for '>' it could be if (i > 0) Foo($ + if (chevronStack.Count == 0) { + return false; + } + chevronStack.Pop (); + break; + case '[': + squareStack.Push (startOffset + off); + break; + case ']': + if (squareStack.Count == 0) { + return true; + } + squareStack.Pop (); + break; + case '{': + bracketStack.Push (startOffset + off); + break; + case '}': + if (bracketStack.Count == 0) { + return true; + } + bracketStack.Pop (); + break; + } + return false; + }); + if (failed) return null; - } + int result = -1; + if (parenStack.Count > 0) + result = parenStack.Pop (); + if (squareStack.Count > 0) + result = Math.Max (result, squareStack.Pop ()); + if (chevronStack.Count > 0) + result = Math.Max (result, chevronStack.Pop ()); + //If we are inside { bracket we don't want to display anything + if (bracketStack.Count > 0 && bracketStack.Pop () > result) + return null; + if (result == -1) + return null; + SetOffset (result + 1); ResolveResult resolveResult; - switch (completionChar) { + switch (document.GetCharAt (result)) { case '(': var invoke = GetInvocationBeforeCursor(true) ?? GetConstructorInitializerBeforeCursor(); if (invoke == null) { @@ -152,7 +278,7 @@ namespace ICSharpCode.NRefactory.CSharp.Completion if (invoke.Node is ConstructorInitializer) { var init = (ConstructorInitializer)invoke.Node; if (init.ConstructorInitializerType == ConstructorInitializerType.This) { - return factory.CreateConstructorProvider(document.GetOffset(invoke.Node.StartLocation), ctx.CurrentTypeDefinition); + return factory.CreateConstructorProvider(document.GetOffset(invoke.Node.StartLocation), ctx.CurrentTypeDefinition, init); } else { var baseType = ctx.CurrentTypeDefinition.DirectBaseTypes.FirstOrDefault(bt => bt.Kind != TypeKind.Interface); if (baseType == null) { @@ -163,23 +289,23 @@ namespace ICSharpCode.NRefactory.CSharp.Completion } if (invoke.Node is ObjectCreateExpression) { var createType = ResolveExpression(((ObjectCreateExpression)invoke.Node).Type); - if (createType.Item1.Type.Kind == TypeKind.Unknown) + if (createType.Result.Type.Kind == TypeKind.Unknown) return null; - return factory.CreateConstructorProvider(document.GetOffset(invoke.Node.StartLocation), createType.Item1.Type); + return factory.CreateConstructorProvider(document.GetOffset(invoke.Node.StartLocation), createType.Result.Type); } - + if (invoke.Node is ICSharpCode.NRefactory.CSharp.Attribute) { var attribute = ResolveExpression(invoke); - if (attribute == null || attribute.Item1 == null) { + if (attribute == null || attribute.Result == null) { return null; } - return factory.CreateConstructorProvider(document.GetOffset(invoke.Node.StartLocation), attribute.Item1.Type); + return factory.CreateConstructorProvider(document.GetOffset(invoke.Node.StartLocation), attribute.Result.Type); } var invocationExpression = ResolveExpression(invoke); - if (invocationExpression == null || invocationExpression.Item1 == null || invocationExpression.Item1.IsError) { + if (invocationExpression == null || invocationExpression.Result == null || invocationExpression.Result.IsError) { return null; } - resolveResult = invocationExpression.Item1; + resolveResult = invocationExpression.Result; if (resolveResult is MethodGroupResolveResult) { return factory.CreateMethodDataProvider(document.GetOffset(invoke.Node.StartLocation), CollectMethods(invoke.Node, resolveResult as MethodGroupResolveResult)); } @@ -189,98 +315,54 @@ namespace ICSharpCode.NRefactory.CSharp.Completion return factory.CreateMethodDataProvider(document.GetOffset(invoke.Node.StartLocation), new [] { (IMethod)mr.Member }); } } - + if (resolveResult.Type.Kind == TypeKind.Delegate) { return factory.CreateDelegateDataProvider(document.GetOffset(invoke.Node.StartLocation), resolveResult.Type); } - -// -// if (result.ExpressionContext == ExpressionContext.BaseConstructorCall) { -// if (resolveResult is ThisResolveResult) -// return new NRefactoryParameterDataProvider (textEditorData, resolver, resolveResult as ThisResolveResult); -// if (resolveResult is BaseResolveResult) -// return new NRefactoryParameterDataProvider (textEditorData, resolver, resolveResult as BaseResolveResult); -// } -// IType resolvedType = resolver.SearchType (resolveResult.ResolvedType); -// if (resolvedType != null && resolvedType.ClassType == ClassType.Delegate) { -// return new NRefactoryParameterDataProvider (textEditorData, result.Expression, resolvedType); -// } + + // + // if (result.ExpressionContext == ExpressionContext.BaseConstructorCall) { + // if (resolveResult is ThisResolveResult) + // return new NRefactoryParameterDataProvider (textEditorData, resolver, resolveResult as ThisResolveResult); + // if (resolveResult is BaseResolveResult) + // return new NRefactoryParameterDataProvider (textEditorData, resolver, resolveResult as BaseResolveResult); + // } + // IType resolvedType = resolver.SearchType (resolveResult.ResolvedType); + // if (resolvedType != null && resolvedType.ClassType == ClassType.Delegate) { + // return new NRefactoryParameterDataProvider (textEditorData, result.Expression, resolvedType); + // } break; - case ',': - invoke = GetInvocationBeforeCursor(true) ?? GetIndexerBeforeCursor(); - if (invoke == null) { - invoke = GetTypeBeforeCursor(); - if (invoke != null) { - if (GetCurrentParameterIndex(document.GetOffset(invoke.Node.StartLocation), offset) < 0) - return null; - var typeExpression = ResolveExpression(invoke); - if (typeExpression == null || typeExpression.Item1 == null || typeExpression.Item1.IsError) { - return null; - } - - return factory.CreateTypeParameterDataProvider(document.GetOffset(invoke.Node.StartLocation), CollectAllTypes(typeExpression.Item1.Type)); - } - return null; - } - if (GetCurrentParameterIndex(document.GetOffset(invoke.Node.StartLocation), offset) < 0) - return null; - if (invoke.Node is ObjectCreateExpression) { - var createType = ResolveExpression(((ObjectCreateExpression)invoke.Node).Type); - return factory.CreateConstructorProvider(document.GetOffset(invoke.Node.StartLocation), createType.Item1.Type); - } - - if (invoke.Node is ICSharpCode.NRefactory.CSharp.Attribute) { - var attribute = ResolveExpression(invoke); - if (attribute == null || attribute.Item1 == null) { - return null; - } - return factory.CreateConstructorProvider(document.GetOffset(invoke.Node.StartLocation), attribute.Item1.Type); - } - - invocationExpression = ResolveExpression(invoke); - - if (invocationExpression == null || invocationExpression.Item1 == null || invocationExpression.Item1.IsError) { - return null; - } - - resolveResult = invocationExpression.Item1; - if (resolveResult is MethodGroupResolveResult) { - return factory.CreateMethodDataProvider(document.GetOffset(invoke.Node.StartLocation), CollectMethods(invoke.Node, resolveResult as MethodGroupResolveResult)); - } - if (resolveResult is MemberResolveResult) { - if (resolveResult.Type.Kind == TypeKind.Delegate) { - return factory.CreateDelegateDataProvider(document.GetOffset(invoke.Node.StartLocation), resolveResult.Type); - } - var mr = resolveResult as MemberResolveResult; - if (mr.Member is IMethod) { - return factory.CreateMethodDataProvider(document.GetOffset(invoke.Node.StartLocation), new [] { (IMethod)mr.Member }); + case '<': + invoke = GetMethodTypeArgumentInvocationBeforeCursor(); + if (invoke != null) { + var tExpr2 = ResolveExpression(invoke); + if (tExpr2 != null && tExpr2.Result is MethodGroupResolveResult && !tExpr2.Result.IsError) { + return factory.CreateTypeParameterDataProvider(document.GetOffset(invoke.Node.StartLocation), CollectMethods(invoke.Node, tExpr2.Result as MethodGroupResolveResult)); } } - if (resolveResult != null) { - return factory.CreateIndexerParameterDataProvider(document.GetOffset(invoke.Node.StartLocation), resolveResult.Type, invoke.Node); - } - break; - case '<': invoke = GetTypeBeforeCursor(); - if (invoke == null) { + if (invoke == null || invoke.Node.StartLocation.IsEmpty) { return null; } var tExpr = ResolveExpression(invoke); - if (tExpr == null || tExpr.Item1 == null || tExpr.Item1.IsError) { + if (tExpr == null || tExpr.Result == null || tExpr.Result.IsError) { return null; } - - return factory.CreateTypeParameterDataProvider(document.GetOffset(invoke.Node.StartLocation), CollectAllTypes(tExpr.Item1.Type)); + + return factory.CreateTypeParameterDataProvider(document.GetOffset(invoke.Node.StartLocation), CollectAllTypes(tExpr.Result.Type)); case '[': invoke = GetIndexerBeforeCursor(); if (invoke == null) { return null; } + if (invoke.Node is ArrayCreateExpression) { + return null; + } var indexerExpression = ResolveExpression(invoke); - if (indexerExpression == null || indexerExpression.Item1 == null || indexerExpression.Item1.IsError) { + if (indexerExpression == null || indexerExpression.Result == null || indexerExpression.Result.IsError) { return null; } - return factory.CreateIndexerParameterDataProvider(document.GetOffset(invoke.Node.StartLocation), indexerExpression.Item1.Type, invoke.Node); + return factory.CreateIndexerParameterDataProvider(document.GetOffset(invoke.Node.StartLocation), indexerExpression.Result.Type, GetAccessibleIndexers (indexerExpression.Result.Type), invoke.Node); } return null; } @@ -320,7 +402,7 @@ namespace ICSharpCode.NRefactory.CSharp.Completion return result; } - + } } diff --git a/NRefactory/ICSharpCode.NRefactory.CSharp/Completion/CompletionDataWrapper.cs b/NRefactory/ICSharpCode.NRefactory.CSharp/Completion/CompletionDataWrapper.cs index 5455faa85..4bf10d937 100644 --- a/NRefactory/ICSharpCode.NRefactory.CSharp/Completion/CompletionDataWrapper.cs +++ b/NRefactory/ICSharpCode.NRefactory.CSharp/Completion/CompletionDataWrapper.cs @@ -1,4 +1,4 @@ -// +// // CompletionDataWrapper.cs // // Author: @@ -32,7 +32,7 @@ using ICSharpCode.NRefactory.CSharp.Resolver; namespace ICSharpCode.NRefactory.CSharp.Completion { - class CompletionDataWrapper + public class CompletionDataWrapper { CSharpCompletionEngine completion; List result = new List (); @@ -48,6 +48,11 @@ namespace ICSharpCode.NRefactory.CSharp.Completion return completion.factory; } } + + internal bool AnonymousDelegateAdded { + get; + set; + } public CompletionDataWrapper (CSharpCompletionEngine completion) { @@ -60,17 +65,33 @@ namespace ICSharpCode.NRefactory.CSharp.Completion } - public void AddCustom (string displayText, string description = null, string completionText = null) + public ICompletionData AddCustom (string displayText, string description = null, string completionText = null) { - result.Add (Factory.CreateLiteralCompletionData (displayText, description, completionText)); + var literalCompletionData = Factory.CreateLiteralCompletionData(displayText, description, completionText); + result.Add(literalCompletionData); + return literalCompletionData; } HashSet usedNamespaces = new HashSet (); + + bool IsAccessible(MemberLookup lookup, INamespace ns) + { + if (ns.Types.Any (t => lookup.IsAccessible (t, false))) + return true; + foreach (var child in ns.ChildNamespaces) + if (IsAccessible (lookup, child)) + return true; + return false; + } - public void AddNamespace (INamespace ns) + public void AddNamespace (MemberLookup lookup, INamespace ns) { if (usedNamespaces.Contains (ns.Name)) return; + if (!IsAccessible (lookup, ns)) { + usedNamespaces.Add (ns.Name); + return; + } usedNamespaces.Add (ns.Name); result.Add (Factory.CreateNamespaceCompletionData (ns)); } @@ -80,24 +101,57 @@ namespace ICSharpCode.NRefactory.CSharp.Completion result.Add (Factory.CreateLiteralCompletionData (alias)); } + Dictionary typeDisplayText = new Dictionary (); + Dictionary addedTypes = new Dictionary (); - HashSet usedTypes = new HashSet (); + public ICompletionData AddConstructors(IType type, bool showFullName, bool isInAttributeContext = false) + { + return InternalAddType(type, showFullName, isInAttributeContext, true); + } - public ICompletionData AddType(IType type, string shortType) + public ICompletionData AddType(IType type, bool showFullName, bool isInAttributeContext = false) { - if (type == null || string.IsNullOrEmpty(shortType) || usedTypes.Contains(shortType)) - return null; - if (type.Name == "Void" && type.Namespace == "System") - return null; + return InternalAddType(type, showFullName, isInAttributeContext, false); + } - var def = type.GetDefinition (); - if (def != null && def.ParentAssembly != completion.ctx.CurrentAssembly && !def.IsBrowsable ()) + ICompletionData InternalAddType(IType type, bool showFullName, bool isInAttributeContext, bool addConstrurs) + { + if (type == null) + throw new ArgumentNullException("type"); + if (type.Name == "Void" && type.Namespace == "System" || type.Kind == TypeKind.Unknown) return null; - - usedTypes.Add(shortType); - var iCompletionData = Factory.CreateTypeCompletionData(type, shortType); - result.Add(iCompletionData); - return iCompletionData; + if (addedTypes.ContainsKey (type)) + return addedTypes[type]; + usedNamespaces.Add(type.Name); + var def = type.GetDefinition(); + if (def != null && def.ParentAssembly != completion.ctx.CurrentAssembly) { + switch (completion.EditorBrowsableBehavior) { + case EditorBrowsableBehavior.Ignore: + break; + case EditorBrowsableBehavior.Normal: + var state = def.GetEditorBrowsableState(); + if (state != System.ComponentModel.EditorBrowsableState.Always) + return null; + break; + case EditorBrowsableBehavior.IncludeAdvanced: + if (!def.IsBrowsable()) + return null; + break; + default: + throw new ArgumentOutOfRangeException(); + } + } + ICompletionData usedType; + var data = Factory.CreateTypeCompletionData(type, showFullName, isInAttributeContext, addConstrurs); + var text = data.DisplayText; + if (typeDisplayText.TryGetValue(text, out usedType)) { + usedType.AddOverload(data); + return usedType; + } + typeDisplayText [text] = data; + result.Add(data); + addedTypes[type] = data; + return data; } Dictionary> data = new Dictionary> (); @@ -134,30 +188,49 @@ namespace ICSharpCode.NRefactory.CSharp.Completion result.Add (Factory.CreateVariableCompletionData (variable)); } + public void AddTypeImport(ITypeDefinition type, bool useFullName, bool addForTypeCreation) + { + result.Add(Factory.CreateImportCompletionData(type, useFullName, addForTypeCreation)); + } + public ICompletionData AddMember (IMember member) { var newData = Factory.CreateEntityCompletionData (member); - if (member.ParentAssembly != completion.ctx.CurrentAssembly && !member.IsBrowsable ()) - return null; - + if (member.ParentAssembly != completion.ctx.CurrentAssembly) { + switch (completion.EditorBrowsableBehavior) { + case EditorBrowsableBehavior.Ignore: + break; + case EditorBrowsableBehavior.Normal: + var state = member.GetEditorBrowsableState(); + if (state != System.ComponentModel.EditorBrowsableState.Always) + return null; + break; + case EditorBrowsableBehavior.IncludeAdvanced: + if (!member.IsBrowsable()) + return null; + break; + default: + throw new ArgumentOutOfRangeException(); + } + } string memberKey = newData.DisplayText; if (memberKey == null) return null; - if (member is IMember) { - newData.CompletionCategory = GetCompletionCategory (member.DeclaringTypeDefinition); - } + newData.CompletionCategory = GetCompletionCategory (member.DeclaringTypeDefinition); + List existingData; data.TryGetValue (memberKey, out existingData); - if (existingData != null) { + if (member.SymbolKind == SymbolKind.Field || member.SymbolKind == SymbolKind.Property || member.SymbolKind == SymbolKind.Event) + return 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) { + if (a == null || b == null || a.SymbolKind == b.SymbolKind) { d.AddOverload (newData); return d; } @@ -201,33 +274,53 @@ 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; + int result; + if (Type.ReflectionName == compareCategory.Type.ReflectionName) { + result = 0; + } else if (Type.GetAllBaseTypes().Any(t => t.ReflectionName == compareCategory.Type.ReflectionName)) { + result = -1; + } else if (compareCategory.Type.GetAllBaseTypes().Any(t => t.ReflectionName == Type.ReflectionName)) { + result = 1; + } else { + var d = Type.GetDefinition (); + var ct = compareCategory.Type.GetDefinition(); + if (ct.IsStatic && d.IsStatic) { + result = d.FullName.CompareTo (ct.FullName); + } else if (d.IsStatic) { + result = 1; + }else if (ct.IsStatic) { + result = -1; + } else { + result = 0; + } + } + return result; } } HashSet addedEnums = new HashSet (); - public void AddEnumMembers (IType resolvedType, CSharpResolver state, string typeString) + public ICompletionData AddEnumMembers (IType resolvedType, CSharpResolver state) { if (addedEnums.Contains (resolvedType)) - return; + return null; addedEnums.Add (resolvedType); - if (typeString.Contains(".")) { - AddType(resolvedType, typeString); - } + var result = AddType(resolvedType, true); foreach (var field in resolvedType.GetFields ()) { if (field.IsPublic && (field.IsConst || field.IsStatic)) { - Result.Add(Factory.CreateEntityCompletionData( - field, - typeString + "." + field.Name - ) - ); + Result.Add(Factory.CreateMemberCompletionData(resolvedType, field)); } } + return result; + } + HashSet anonymousSignatures = new HashSet (); + + public bool HasAnonymousDelegateAdded(string signature) + { + return anonymousSignatures.Contains(signature); + } + + public void AddAnonymousDelegateAdded(string signature) + { + anonymousSignatures.Add(signature); } } } diff --git a/NRefactory/ICSharpCode.NRefactory.CSharp/Completion/ICompletionContextProvider.cs b/NRefactory/ICSharpCode.NRefactory.CSharp/Completion/ICompletionContextProvider.cs index c590007fb..ed70580e6 100644 --- a/NRefactory/ICSharpCode.NRefactory.CSharp/Completion/ICompletionContextProvider.cs +++ b/NRefactory/ICSharpCode.NRefactory.CSharp/Completion/ICompletionContextProvider.cs @@ -149,10 +149,6 @@ namespace ICSharpCode.NRefactory.CSharp.Completion if (bracketStack.Count > 0) bracketStack.Pop (); break; - case '\r': - case '\n': - isInLineComment = false; - break; case '/': if (isInBlockComment) { if (i > 0 && document.GetCharAt (i - 1) == '*') @@ -173,7 +169,10 @@ namespace ICSharpCode.NRefactory.CSharp.Completion if (!(isInString || isInLineComment || isInBlockComment)) isInChar = !isInChar; break; - default : + default : + if (NewLine.IsNewLine(ch)) { + isInLineComment = false; + } break; } } diff --git a/NRefactory/ICSharpCode.NRefactory.CSharp/Completion/ICompletionDataFactory.cs b/NRefactory/ICSharpCode.NRefactory.CSharp/Completion/ICompletionDataFactory.cs index 95309db44..da61f8907 100644 --- a/NRefactory/ICSharpCode.NRefactory.CSharp/Completion/ICompletionDataFactory.cs +++ b/NRefactory/ICSharpCode.NRefactory.CSharp/Completion/ICompletionDataFactory.cs @@ -1,4 +1,4 @@ -// +// // ICompletionDataFactory.cs // // Author: @@ -35,12 +35,19 @@ namespace ICSharpCode.NRefactory.CSharp.Completion ICompletionData CreateEntityCompletionData (IEntity entity); ICompletionData CreateEntityCompletionData (IEntity entity, string text); - ICompletionData CreateTypeCompletionData (IType type, string shortType); + ICompletionData CreateTypeCompletionData (IType type, bool showFullName, bool isInAttributeContext, bool addForTypeCreation); + + /// + /// Creates the member completion data. + /// Form: Type.Member + /// Used for generating enum members Foo.A, Foo.B where the enum 'Foo' is valid. + /// + ICompletionData CreateMemberCompletionData(IType type, IEntity member); /// /// Creates a generic completion data. /// - /// + /// /// The title of the completion data /// /// @@ -57,7 +64,7 @@ namespace ICSharpCode.NRefactory.CSharp.Completion ICompletionData CreateVariableCompletionData (ITypeParameter parameter); - ICompletionData CreateEventCreationCompletionData (string varName, IType delegateType, IEvent evt, string parameterDefinition, IUnresolvedMember currentMember, IUnresolvedTypeDefinition currentType); + ICompletionData CreateEventCreationCompletionData (string delegateMethodName, IType delegateType, IEvent evt, string parameterDefinition, IUnresolvedMember currentMember, IUnresolvedTypeDefinition currentType); ICompletionData CreateNewOverrideCompletionData (int declarationBegin, IUnresolvedTypeDefinition type, IMember m); ICompletionData CreateNewPartialCompletionData (int declarationBegin, IUnresolvedTypeDefinition type, IUnresolvedMember m); @@ -65,5 +72,18 @@ namespace ICSharpCode.NRefactory.CSharp.Completion IEnumerable CreateCodeTemplateCompletionData (); IEnumerable CreatePreProcessorDefinesCompletionData (); + + /// + /// Creates a completion data that adds the required using for the created type. + /// + /// The type to import + /// If set to true the full name of the type needs to be used. + /// If true the completion data is used in 'new' context. + ICompletionData CreateImportCompletionData(IType type, bool useFullName, bool addForTypeCreation); + + ICompletionData CreateFormatItemCompletionData(string format, string description, object example); + + ICompletionData CreateXmlDocCompletionData (string tag, string description = null, string tagInsertionText = null); + } } diff --git a/NRefactory/ICSharpCode.NRefactory.CSharp/Completion/IParameterCompletionDataFactory.cs b/NRefactory/ICSharpCode.NRefactory.CSharp/Completion/IParameterCompletionDataFactory.cs index 54ebe1c84..5bbb64e40 100644 --- a/NRefactory/ICSharpCode.NRefactory.CSharp/Completion/IParameterCompletionDataFactory.cs +++ b/NRefactory/ICSharpCode.NRefactory.CSharp/Completion/IParameterCompletionDataFactory.cs @@ -35,13 +35,20 @@ namespace ICSharpCode.NRefactory.CSharp.Completion { IParameterDataProvider CreateConstructorProvider (int startOffset, IType type); + /// + /// Creates a constructor provider skipping the parent of thisInitializer. + /// + IParameterDataProvider CreateConstructorProvider (int startOffset, IType type, AstNode thisInitializer); + IParameterDataProvider CreateMethodDataProvider (int startOffset, IEnumerable methods); IParameterDataProvider CreateDelegateDataProvider (int startOffset, IType type); - IParameterDataProvider CreateIndexerParameterDataProvider (int startOffset, IType type, AstNode resolvedNode); + IParameterDataProvider CreateIndexerParameterDataProvider (int startOffset, IType type, IEnumerable accessibleIndexers, AstNode resolvedNode); IParameterDataProvider CreateTypeParameterDataProvider (int startOffset, IEnumerable types); + + IParameterDataProvider CreateTypeParameterDataProvider (int startOffset, IEnumerable methods); } } diff --git a/NRefactory/ICSharpCode.NRefactory.CSharp/Formatter/AstFormattingVisitor.cs b/NRefactory/ICSharpCode.NRefactory.CSharp/Formatter/AstFormattingVisitor.cs deleted file mode 100644 index 8a12bc84a..000000000 --- a/NRefactory/ICSharpCode.NRefactory.CSharp/Formatter/AstFormattingVisitor.cs +++ /dev/null @@ -1,2181 +0,0 @@ -// -// AstFormattingVisitor.cs -// -// Author: -// Mike Krüger -// -// Copyright (c) 2010 Novell, Inc (http://www.novell.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 System.Diagnostics; -using System.Text; -using System.Collections.Generic; -using System.Linq; -using ICSharpCode.NRefactory.Editor; -using ICSharpCode.NRefactory.TypeSystem; -using ICSharpCode.NRefactory.CSharp.Refactoring; - -namespace ICSharpCode.NRefactory.CSharp -{ - public enum FormattingMode { - OnTheFly, - Intrusive - } - - public class AstFormattingVisitor : DepthFirstAstVisitor - { - sealed class TextReplaceAction - { - internal readonly int Offset; - internal readonly int RemovalLength; - internal readonly string NewText; - internal TextReplaceAction DependsOn; - -#if DEBUG - internal readonly string StackTrace; -#endif - - public TextReplaceAction (int offset, int removalLength, string newText) - { - this.Offset = offset; - this.RemovalLength = removalLength; - this.NewText = newText ?? string.Empty; - #if DEBUG - this.StackTrace = Environment.StackTrace; - #endif - } - - public override bool Equals(object obj) - { - TextReplaceAction other = obj as TextReplaceAction; - if (other == null) { - return false; - } - return this.Offset == other.Offset && this.RemovalLength == other.RemovalLength && this.NewText == other.NewText; - } - - public override int GetHashCode() - { - return 0; - } - - public override string ToString() - { - return string.Format("[TextReplaceAction: Offset={0}, RemovalLength={1}, NewText={2}]", Offset, RemovalLength, NewText); - } - } - - CSharpFormattingOptions policy; - IDocument document; - List changes = new List (); - Indent curIndent; - readonly TextEditorOptions options; - - public FormattingMode FormattingMode { - get; - set; - } - - public bool HadErrors { - get; - set; - } - - public DomRegion FormattingRegion { - get; - set; - } - - public AstFormattingVisitor(CSharpFormattingOptions policy, IDocument document, TextEditorOptions options = null) - { - if (policy == null) { - throw new ArgumentNullException("policy"); - } - if (document == null) { - throw new ArgumentNullException("document"); - } - this.policy = policy; - this.document = document; - 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); - } - } - - /// - /// Applies the changes to the input document. - /// - public void ApplyChanges() - { - ApplyChanges(0, document.TextLength, document.Replace, (o, l, v) => document.GetText(o, l) == v); - } - - public void ApplyChanges(int startOffset, int length) - { - ApplyChanges(startOffset, length, document.Replace, (o, l, v) => document.GetText(o, l) == v); - } - - /// - /// Applies the changes to the given Script instance. - /// - public void ApplyChanges(Script script) - { - ApplyChanges(0, document.TextLength, script.Replace); - } - - public void ApplyChanges(int startOffset, int length, Script script) - { - ApplyChanges(startOffset, length, script.Replace); - } - - public void ApplyChanges(int startOffset, int length, Action documentReplace, Func filter = null) - { - int endOffset = startOffset + length; - TextReplaceAction previousChange = null; - int delta = 0; - var depChanges = new List (); - foreach (var change in changes.OrderBy(c => c.Offset)) { - if (previousChange != null) { - if (change.Equals(previousChange)) { - // ignore duplicate changes - continue; - } - if (change.Offset < previousChange.Offset + previousChange.RemovalLength) { - #if DEBUG - Console.WriteLine ("change 1:" + change + " at " + document.GetLocation (change.Offset)); - Console.WriteLine (change.StackTrace); - - Console.WriteLine ("change 2:" + previousChange + " at " + document.GetLocation (previousChange.Offset)); - Console.WriteLine (previousChange.StackTrace); - #endif - throw new InvalidOperationException ("Detected overlapping changes " + change + "/" + previousChange); - } - } - previousChange = change; - - bool skipChange = change.Offset < startOffset || change.Offset > endOffset; - skipChange |= filter != null && filter(change.Offset + delta, change.RemovalLength, change.NewText); - skipChange &= !depChanges.Contains(change); - - if (!skipChange) { - documentReplace(change.Offset + delta, change.RemovalLength, change.NewText); - delta += change.NewText.Length - change.RemovalLength; - if (change.DependsOn != null) { - depChanges.Add(change.DependsOn); - } - } - } - changes.Clear(); - } - - public override void VisitSyntaxTree(SyntaxTree unit) - { - base.VisitSyntaxTree(unit); - } - - public void EnsureBlankLinesAfter(AstNode node, int blankLines) - { - if (FormattingMode != FormattingMode.Intrusive) - return; - var loc = node.EndLocation; - int line = loc.Line; - do { - line++; - } while (line < document.LineCount && IsSpacing(document.GetLineByNumber(line))); - var start = document.GetOffset(node.EndLocation); - - int foundBlankLines = line - loc.Line - 1; - - StringBuilder sb = new StringBuilder(); - for (int i = 0; i < blankLines - foundBlankLines; i++) { - sb.Append(this.options.EolMarker); - } - - int ws = start; - while (ws < document.TextLength && IsSpacing (document.GetCharAt (ws))) { - ws++; - } - int removedChars = ws - start; - if (foundBlankLines > blankLines) { - removedChars += document.GetLineByNumber(loc.Line + foundBlankLines - blankLines).EndOffset - - document.GetLineByNumber(loc.Line).EndOffset; - } - AddChange(start, removedChars, sb.ToString()); - } - - public void EnsureBlankLinesBefore(AstNode node, int blankLines) - { - if (FormattingMode != FormattingMode.Intrusive) - return; - var loc = node.StartLocation; - int line = loc.Line; - do { - line--; - } while (line > 0 && IsSpacing(document.GetLineByNumber(line))); - int end = document.GetOffset(loc.Line, 1); - int start = document.GetOffset(line + 1, 1); - StringBuilder sb = new StringBuilder (); - 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 != null && !(usingDeclaration.PrevSibling is UsingDeclaration || usingDeclaration.PrevSibling is UsingAliasDeclaration)) { - EnsureBlankLinesBefore(usingDeclaration, policy.BlankLinesBeforeUsings); - } 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 != null && !(usingDeclaration.PrevSibling is UsingDeclaration || usingDeclaration.PrevSibling is UsingAliasDeclaration)) { - EnsureBlankLinesBefore(usingDeclaration, policy.BlankLinesBeforeUsings); - } else if (!(usingDeclaration.NextSibling is UsingDeclaration || usingDeclaration.NextSibling is UsingAliasDeclaration)) { - FixIndentationForceNewLine(usingDeclaration.StartLocation); - EnsureBlankLinesAfter(usingDeclaration, policy.BlankLinesAfterUsings); - } else { - FixIndentationForceNewLine(usingDeclaration.StartLocation); - } - } - - public override void VisitNamespaceDeclaration(NamespaceDeclaration namespaceDeclaration) - { - var firstNsMember = namespaceDeclaration.Members.FirstOrDefault(); - if (firstNsMember != null) { - EnsureBlankLinesBefore(firstNsMember, policy.BlankLinesBeforeFirstDeclaration); - } - FixIndentationForceNewLine(namespaceDeclaration.StartLocation); - EnforceBraceStyle(policy.NamespaceBraceStyle, namespaceDeclaration.LBraceToken, namespaceDeclaration.RBraceToken); - if (policy.IndentNamespaceBody) { - curIndent.Push(IndentType.Block); - } - base.VisitNamespaceDeclaration(namespaceDeclaration); - if (policy.IndentNamespaceBody) { - curIndent.Pop (); - } - FixIndentation(namespaceDeclaration.RBraceToken.StartLocation); - } - - public override void VisitTypeDeclaration(TypeDeclaration typeDeclaration) - { - FormatAttributedNode(typeDeclaration); - BraceStyle braceStyle; - bool indentBody = false; - switch (typeDeclaration.ClassType) { - case ClassType.Class: - braceStyle = policy.ClassBraceStyle; - indentBody = policy.IndentClassBody; - break; - case ClassType.Struct: - braceStyle = policy.StructBraceStyle; - indentBody = policy.IndentStructBody; - break; - case ClassType.Interface: - braceStyle = policy.InterfaceBraceStyle; - indentBody = policy.IndentInterfaceBody; - break; - case ClassType.Enum: - braceStyle = policy.EnumBraceStyle; - indentBody = policy.IndentEnumBody; - break; - default: - throw new InvalidOperationException("unsupported class type : " + typeDeclaration.ClassType); - } - - EnforceBraceStyle(braceStyle, typeDeclaration.LBraceToken, typeDeclaration.RBraceToken); - - if (indentBody) { - curIndent.Push(IndentType.Block); - } - base.VisitTypeDeclaration(typeDeclaration); - if (indentBody) { - curIndent.Pop (); - } - - if (typeDeclaration.NextSibling is TypeDeclaration || typeDeclaration.NextSibling is DelegateDeclaration) { - EnsureBlankLinesAfter(typeDeclaration, policy.BlankLinesBetweenTypes); - } - - } - - bool IsSimpleAccessor(Accessor accessor) - { - if (accessor.IsNull || accessor.Body.IsNull || accessor.Body.FirstChild == null) { - return true; - } - if (accessor.Body.Statements.Count() != 1) { - return false; - } - return !(accessor.Body.Statements.FirstOrDefault() is BlockStatement); - - } - - bool IsSpacing(char ch) - { - return ch == ' ' || ch == '\t'; - } - - bool IsSpacing(ISegment segment) - { - int endOffset = segment.EndOffset; - for (int i = segment.Offset; i < endOffset; i++) { - if (!IsSpacing(document.GetCharAt(i))) { - return false; - } - } - return true; - } - - int SearchLastNonWsChar(int startOffset, int endOffset) - { - startOffset = System.Math.Max(0, startOffset); - endOffset = System.Math.Max(startOffset, endOffset); - if (startOffset >= endOffset) { - return startOffset; - } - int result = -1; - bool inComment = false; - - for (int i = startOffset; i < endOffset && i < document.TextLength; i++) { - char ch = document.GetCharAt(i); - if (IsSpacing(ch)) { - continue; - } - if (ch == '/' && i + 1 < document.TextLength && document.GetCharAt(i + 1) == '/') { - return result; - } - if (ch == '/' && i + 1 < document.TextLength && document.GetCharAt(i + 1) == '*') { - inComment = true; - i++; - continue; - } - if (inComment && ch == '*' && i + 1 < document.TextLength && document.GetCharAt(i + 1) == '/') { - inComment = false; - i++; - continue; - } - if (!inComment) { - result = i; - } - } - return result; - } - - void ForceSpace(int startOffset, int endOffset, bool forceSpace) - { - int lastNonWs = SearchLastNonWsChar(startOffset, endOffset); - AddChange(lastNonWs + 1, System.Math.Max(0, endOffset - lastNonWs - 1), forceSpace ? " " : ""); - } -// void ForceSpacesAfter (AstNode n, bool forceSpaces) -// { -// if (n == null) -// return; -// AstLocation location = n.EndLocation; -// int offset = data.LocationToOffset (location.Line, location.Column); -// int i = offset; -// while (i < data.Length && IsSpacing (data.GetCharAt (i))) { -// i++; -// } -// ForceSpace (offset - 1, i, forceSpaces); -// } - - void ForceSpacesAfter(AstNode n, bool forceSpaces) - { - if (n == null) { - return; - } - TextLocation location = n.EndLocation; - int offset = document.GetOffset(location); - if (location.Column > document.GetLineByNumber(location.Line).Length) { - return; - } - int i = offset; - while (i < document.TextLength && IsSpacing (document.GetCharAt (i))) { - i++; - } - ForceSpace(offset - 1, i, forceSpaces); - } - -// int ForceSpacesBefore (AstNode n, bool forceSpaces) -// { -// if (n == null || n.IsNull) -// return 0; -// AstLocation location = n.StartLocation; -// -// int offset = data.LocationToOffset (location.Line, location.Column); -// int i = offset - 1; -// -// while (i >= 0 && IsSpacing (data.GetCharAt (i))) { -// i--; -// } -// ForceSpace (i, offset, forceSpaces); -// return i; -// } - - int ForceSpacesBefore(AstNode n, bool forceSpaces) - { - if (n == null || n.IsNull) { - return 0; - } - TextLocation location = n.StartLocation; - // respect manual line breaks. - if (location.Column <= 1 || GetIndentation(location.Line).Length == location.Column - 1) { - return 0; - } - - int offset = document.GetOffset(location); - int i = offset - 1; - while (i >= 0 && IsSpacing (document.GetCharAt (i))) { - i--; - } - ForceSpace(i, offset, forceSpaces); - return i; - } - - int ForceSpacesBeforeRemoveNewLines(AstNode n, bool forceSpace = true) - { - if (n == null || n.IsNull) { - return 0; - } - int offset = document.GetOffset(n.StartLocation); - int i = offset - 1; - while (i >= 0) { - char ch = document.GetCharAt(i); - if (!IsSpacing(ch) && ch != '\r' && ch != '\n') - break; - i--; - } - var length = System.Math.Max(0, (offset - 1) - i); - AddChange(i + 1, length, forceSpace ? " " : ""); - return i; - } - - public override void VisitPropertyDeclaration(PropertyDeclaration propertyDeclaration) - { - FormatAttributedNode(propertyDeclaration); - bool oneLine = false; - switch (policy.PropertyFormatting) { - case PropertyFormatting.AllowOneLine: - bool isSimple = IsSimpleAccessor(propertyDeclaration.Getter) && IsSimpleAccessor(propertyDeclaration.Setter); - 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); - ForceSpacesBeforeRemoveNewLines(propertyDeclaration.RBraceToken, true); - oneLine = true; - } - break; - case PropertyFormatting.ForceNewLine: - EnforceBraceStyle(policy.PropertyBraceStyle, propertyDeclaration.LBraceToken, propertyDeclaration.RBraceToken); - break; - case PropertyFormatting.ForceOneLine: - isSimple = IsSimpleAccessor(propertyDeclaration.Getter) && IsSimpleAccessor(propertyDeclaration.Setter); - if (isSimple) { - int offset = this.document.GetOffset(propertyDeclaration.LBraceToken.StartLocation); - - int start = SearchWhitespaceStart(offset); - int end = SearchWhitespaceEnd(offset); - AddChange(start, offset - start, " "); - AddChange(offset + 1, end - offset - 2, " "); - - offset = this.document.GetOffset(propertyDeclaration.RBraceToken.StartLocation); - start = SearchWhitespaceStart(offset); - AddChange(start, offset - start, " "); - oneLine = true; - - } else { - EnforceBraceStyle(policy.PropertyBraceStyle, propertyDeclaration.LBraceToken, propertyDeclaration.RBraceToken); - } - break; - } - if (policy.IndentPropertyBody) { - curIndent.Push(IndentType.Block); - } - ///System.Console.WriteLine ("one line: " + oneLine); - if (!propertyDeclaration.Getter.IsNull) { - if (!oneLine) { - if (!IsLineIsEmptyUpToEol(propertyDeclaration.Getter.StartLocation)) { - int offset = this.document.GetOffset(propertyDeclaration.Getter.StartLocation); - int start = SearchWhitespaceStart(offset); - string indentString = this.curIndent.IndentString; - AddChange(start, offset - start, this.options.EolMarker + indentString); - } else { - FixIndentation(propertyDeclaration.Getter.StartLocation); - } - } else { - int offset = this.document.GetOffset(propertyDeclaration.Getter.StartLocation); - int start = SearchWhitespaceStart(offset); - AddChange(start, offset - start, " "); - - ForceSpacesBefore(propertyDeclaration.Getter.Body.LBraceToken, true); - ForceSpacesBefore(propertyDeclaration.Getter.Body.RBraceToken, true); - } - if (!propertyDeclaration.Getter.Body.IsNull) { - if (!policy.AllowPropertyGetBlockInline || propertyDeclaration.Getter.Body.LBraceToken.StartLocation.Line != propertyDeclaration.Getter.Body.RBraceToken.StartLocation.Line) { - EnforceBraceStyle(policy.PropertyGetBraceStyle, propertyDeclaration.Getter.Body.LBraceToken, propertyDeclaration.Getter.Body.RBraceToken); - } else { - nextStatementIndent = " "; - } - VisitBlockWithoutFixingBraces(propertyDeclaration.Getter.Body, policy.IndentBlocks); - } - } - - if (!propertyDeclaration.Setter.IsNull) { - if (!oneLine) { - if (!IsLineIsEmptyUpToEol(propertyDeclaration.Setter.StartLocation)) { - int offset = this.document.GetOffset(propertyDeclaration.Setter.StartLocation); - int start = SearchWhitespaceStart(offset); - string indentString = this.curIndent.IndentString; - AddChange(start, offset - start, this.options.EolMarker + indentString); - } else { - FixIndentation(propertyDeclaration.Setter.StartLocation); - } - } else { - int offset = this.document.GetOffset(propertyDeclaration.Setter.StartLocation); - int start = SearchWhitespaceStart(offset); - AddChange(start, offset - start, " "); - - ForceSpacesBefore(propertyDeclaration.Setter.Body.LBraceToken, true); - ForceSpacesBefore(propertyDeclaration.Setter.Body.RBraceToken, true); - } - if (!propertyDeclaration.Setter.Body.IsNull) { - if (!policy.AllowPropertySetBlockInline || propertyDeclaration.Setter.Body.LBraceToken.StartLocation.Line != propertyDeclaration.Setter.Body.RBraceToken.StartLocation.Line) { - EnforceBraceStyle(policy.PropertySetBraceStyle, propertyDeclaration.Setter.Body.LBraceToken, propertyDeclaration.Setter.Body.RBraceToken); - } else { - nextStatementIndent = " "; - } - VisitBlockWithoutFixingBraces(propertyDeclaration.Setter.Body, policy.IndentBlocks); - } - } - - if (policy.IndentPropertyBody) { - curIndent.Pop (); - } - if (IsMember(propertyDeclaration.NextSibling)) { - EnsureBlankLinesAfter(propertyDeclaration, policy.BlankLinesBetweenMembers); - } - } - - public override void VisitIndexerDeclaration(IndexerDeclaration indexerDeclaration) - { - ForceSpacesBefore(indexerDeclaration.LBracketToken, policy.SpaceBeforeIndexerDeclarationBracket); - ForceSpacesAfter(indexerDeclaration.LBracketToken, policy.SpaceWithinIndexerDeclarationBracket); - - FormatParameters(indexerDeclaration); - - FormatAttributedNode(indexerDeclaration); - EnforceBraceStyle(policy.PropertyBraceStyle, indexerDeclaration.LBraceToken, indexerDeclaration.RBraceToken); - if (policy.IndentPropertyBody) { - curIndent.Push(IndentType.Block); - } - - if (!indexerDeclaration.Getter.IsNull) { - FixIndentation(indexerDeclaration.Getter.StartLocation); - if (!indexerDeclaration.Getter.Body.IsNull) { - if (!policy.AllowPropertyGetBlockInline || indexerDeclaration.Getter.Body.LBraceToken.StartLocation.Line != indexerDeclaration.Getter.Body.RBraceToken.StartLocation.Line) { - EnforceBraceStyle(policy.PropertyGetBraceStyle, indexerDeclaration.Getter.Body.LBraceToken, indexerDeclaration.Getter.Body.RBraceToken); - } else { - nextStatementIndent = " "; - } - VisitBlockWithoutFixingBraces(indexerDeclaration.Getter.Body, policy.IndentBlocks); - } - } - - if (!indexerDeclaration.Setter.IsNull) { - FixIndentation(indexerDeclaration.Setter.StartLocation); - if (!indexerDeclaration.Setter.Body.IsNull) { - if (!policy.AllowPropertySetBlockInline || indexerDeclaration.Setter.Body.LBraceToken.StartLocation.Line != indexerDeclaration.Setter.Body.RBraceToken.StartLocation.Line) { - EnforceBraceStyle(policy.PropertySetBraceStyle, indexerDeclaration.Setter.Body.LBraceToken, indexerDeclaration.Setter.Body.RBraceToken); - } else { - nextStatementIndent = " "; - } - VisitBlockWithoutFixingBraces(indexerDeclaration.Setter.Body, policy.IndentBlocks); - } - } - if (policy.IndentPropertyBody) { - curIndent.Pop (); - } - if (IsMember(indexerDeclaration.NextSibling)) { - EnsureBlankLinesAfter(indexerDeclaration, policy.BlankLinesBetweenMembers); - } - } - - static bool IsSimpleEvent(AstNode node) - { - return node is EventDeclaration; - } - - public override void VisitCustomEventDeclaration(CustomEventDeclaration eventDeclaration) - { - FormatAttributedNode(eventDeclaration); - EnforceBraceStyle(policy.EventBraceStyle, eventDeclaration.LBraceToken, eventDeclaration.RBraceToken); - if (policy.IndentEventBody) { - curIndent.Push(IndentType.Block); - } - - if (!eventDeclaration.AddAccessor.IsNull) { - FixIndentation(eventDeclaration.AddAccessor.StartLocation); - if (!eventDeclaration.AddAccessor.Body.IsNull) { - if (!policy.AllowEventAddBlockInline || eventDeclaration.AddAccessor.Body.LBraceToken.StartLocation.Line != eventDeclaration.AddAccessor.Body.RBraceToken.StartLocation.Line) { - EnforceBraceStyle(policy.EventAddBraceStyle, eventDeclaration.AddAccessor.Body.LBraceToken, eventDeclaration.AddAccessor.Body.RBraceToken); - } else { - nextStatementIndent = " "; - } - - VisitBlockWithoutFixingBraces(eventDeclaration.AddAccessor.Body, policy.IndentBlocks); - } - } - - if (!eventDeclaration.RemoveAccessor.IsNull) { - FixIndentation(eventDeclaration.RemoveAccessor.StartLocation); - if (!eventDeclaration.RemoveAccessor.Body.IsNull) { - if (!policy.AllowEventRemoveBlockInline || eventDeclaration.RemoveAccessor.Body.LBraceToken.StartLocation.Line != eventDeclaration.RemoveAccessor.Body.RBraceToken.StartLocation.Line) { - EnforceBraceStyle(policy.EventRemoveBraceStyle, eventDeclaration.RemoveAccessor.Body.LBraceToken, eventDeclaration.RemoveAccessor.Body.RBraceToken); - } else { - nextStatementIndent = " "; - } - VisitBlockWithoutFixingBraces(eventDeclaration.RemoveAccessor.Body, policy.IndentBlocks); - } - } - - if (policy.IndentEventBody) { - curIndent.Pop (); - } - - if (eventDeclaration.NextSibling is EventDeclaration && IsSimpleEvent(eventDeclaration) && IsSimpleEvent(eventDeclaration.NextSibling)) { - EnsureBlankLinesAfter(eventDeclaration, policy.BlankLinesBetweenEventFields); - } else if (IsMember(eventDeclaration.NextSibling)) { - EnsureBlankLinesAfter(eventDeclaration, policy.BlankLinesBetweenMembers); - } - } - - public override void VisitEventDeclaration(EventDeclaration eventDeclaration) - { - FormatAttributedNode(eventDeclaration); - if (eventDeclaration.NextSibling is EventDeclaration && IsSimpleEvent(eventDeclaration) && IsSimpleEvent(eventDeclaration.NextSibling)) { - EnsureBlankLinesAfter(eventDeclaration, policy.BlankLinesBetweenEventFields); - } else if (IsMember(eventDeclaration.NextSibling)) { - EnsureBlankLinesAfter(eventDeclaration, policy.BlankLinesBetweenMembers); - } - - var lastLoc = eventDeclaration.StartLocation; - curIndent.Push(IndentType.Block); - foreach (var initializer in eventDeclaration.Variables) { - if (lastLoc.Line != initializer.StartLocation.Line) { - FixStatementIndentation(initializer.StartLocation); - lastLoc = initializer.StartLocation; - } - initializer.AcceptVisitor(this); - } - curIndent.Pop (); - } - - public override void VisitAccessor(Accessor accessor) - { - FixIndentationForceNewLine(accessor.StartLocation); - base.VisitAccessor(accessor); - } - - public override void VisitFieldDeclaration(FieldDeclaration fieldDeclaration) - { - FormatAttributedNode(fieldDeclaration); - fieldDeclaration.ReturnType.AcceptVisitor(this); - FormatCommas(fieldDeclaration, policy.SpaceBeforeFieldDeclarationComma, policy.SpaceAfterFieldDeclarationComma); - if (fieldDeclaration.NextSibling is FieldDeclaration || fieldDeclaration.NextSibling is FixedFieldDeclaration) { - EnsureBlankLinesAfter(fieldDeclaration, policy.BlankLinesBetweenFields); - } else if (IsMember(fieldDeclaration.NextSibling)) { - EnsureBlankLinesAfter(fieldDeclaration, policy.BlankLinesBetweenMembers); - } - - var lastLoc = fieldDeclaration.StartLocation; - curIndent.Push(IndentType.Block); - foreach (var initializer in fieldDeclaration.Variables) { - if (lastLoc.Line != initializer.StartLocation.Line) { - FixStatementIndentation(initializer.StartLocation); - lastLoc = initializer.StartLocation; - } - initializer.AcceptVisitor(this); - } - curIndent.Pop (); - } - - public override void VisitFixedFieldDeclaration(FixedFieldDeclaration fixedFieldDeclaration) - { - FormatAttributedNode(fixedFieldDeclaration); - FormatCommas(fixedFieldDeclaration, policy.SpaceBeforeFieldDeclarationComma, policy.SpaceAfterFieldDeclarationComma); - if (fixedFieldDeclaration.NextSibling is FieldDeclaration || fixedFieldDeclaration.NextSibling is FixedFieldDeclaration) { - EnsureBlankLinesAfter(fixedFieldDeclaration, policy.BlankLinesBetweenFields); - } else if (IsMember(fixedFieldDeclaration.NextSibling)) { - EnsureBlankLinesAfter(fixedFieldDeclaration, policy.BlankLinesBetweenMembers); - } - - var lastLoc = fixedFieldDeclaration.StartLocation; - curIndent.Push(IndentType.Block); - foreach (var initializer in fixedFieldDeclaration.Variables) { - if (lastLoc.Line != initializer.StartLocation.Line) { - FixStatementIndentation(initializer.StartLocation); - lastLoc = initializer.StartLocation; - } - initializer.AcceptVisitor(this); - } - curIndent.Pop (); - } - - public override void VisitEnumMemberDeclaration(EnumMemberDeclaration enumMemberDeclaration) - { - FormatAttributedNode(enumMemberDeclaration); - base.VisitEnumMemberDeclaration(enumMemberDeclaration); - } - - public override void VisitDelegateDeclaration(DelegateDeclaration delegateDeclaration) - { - FormatAttributedNode(delegateDeclaration); - - ForceSpacesBefore(delegateDeclaration.LParToken, policy.SpaceBeforeDelegateDeclarationParentheses); - if (delegateDeclaration.Parameters.Any()) { - ForceSpacesAfter(delegateDeclaration.LParToken, policy.SpaceWithinDelegateDeclarationParentheses); - ForceSpacesBefore(delegateDeclaration.RParToken, policy.SpaceWithinDelegateDeclarationParentheses); - } else { - ForceSpacesAfter(delegateDeclaration.LParToken, policy.SpaceBetweenEmptyDelegateDeclarationParentheses); - ForceSpacesBefore(delegateDeclaration.RParToken, policy.SpaceBetweenEmptyDelegateDeclarationParentheses); - } - FormatCommas(delegateDeclaration, policy.SpaceBeforeDelegateDeclarationParameterComma, policy.SpaceAfterDelegateDeclarationParameterComma); - - if (delegateDeclaration.NextSibling is TypeDeclaration || delegateDeclaration.NextSibling is DelegateDeclaration) { - EnsureBlankLinesAfter(delegateDeclaration, policy.BlankLinesBetweenTypes); - } else if (IsMember(delegateDeclaration.NextSibling)) { - EnsureBlankLinesAfter(delegateDeclaration, policy.BlankLinesBetweenMembers); - } - - base.VisitDelegateDeclaration(delegateDeclaration); - } - - static bool IsMember(AstNode nextSibling) - { - return nextSibling != null && nextSibling.NodeType == NodeType.Member; - } - - void FormatAttributedNode(AstNode node) - { - if (node == null) { - return; - } - AstNode child = node.FirstChild; - while (child != null && child is AttributeSection) { - FixIndentationForceNewLine(child.StartLocation); - child = child.NextSibling; - } - if (child != null) { - FixIndentationForceNewLine(child.StartLocation); - } - } - - - void FormatParameters(AstNode node) - { - Wrapping methodCallArgumentWrapping; - bool newLineAferMethodCallOpenParentheses; - bool methodClosingParenthesesOnNewLine; - bool spaceWithinMethodCallParentheses; - bool spaceAfterMethodCallParameterComma; - bool spaceBeforeMethodCallParameterComma; - - CSharpTokenNode rParToken; - AstNodeCollection 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); - - ForceSpacesBefore(methodDeclaration.LParToken, policy.SpaceBeforeMethodDeclarationParentheses); - if (methodDeclaration.Parameters.Any()) { - ForceSpacesAfter(methodDeclaration.LParToken, policy.SpaceWithinMethodDeclarationParentheses); - FormatParameters(methodDeclaration); - } else { - ForceSpacesAfter(methodDeclaration.LParToken, policy.SpaceBetweenEmptyMethodDeclarationParentheses); - ForceSpacesBefore(methodDeclaration.RParToken, policy.SpaceBetweenEmptyMethodDeclarationParentheses); - } - - if (!methodDeclaration.Body.IsNull) { - EnforceBraceStyle(policy.MethodBraceStyle, methodDeclaration.Body.LBraceToken, methodDeclaration.Body.RBraceToken); - VisitBlockWithoutFixingBraces(methodDeclaration.Body, policy.IndentMethodBody); - } - if (IsMember(methodDeclaration.NextSibling)) { - EnsureBlankLinesAfter(methodDeclaration, policy.BlankLinesBetweenMembers); - } - } - - public override void VisitOperatorDeclaration(OperatorDeclaration operatorDeclaration) - { - FormatAttributedNode(operatorDeclaration); - - ForceSpacesBefore(operatorDeclaration.LParToken, policy.SpaceBeforeMethodDeclarationParentheses); - if (operatorDeclaration.Parameters.Any()) { - ForceSpacesAfter(operatorDeclaration.LParToken, policy.SpaceWithinMethodDeclarationParentheses); - FormatParameters(operatorDeclaration); - } else { - ForceSpacesAfter(operatorDeclaration.LParToken, policy.SpaceBetweenEmptyMethodDeclarationParentheses); - ForceSpacesBefore(operatorDeclaration.RParToken, policy.SpaceBetweenEmptyMethodDeclarationParentheses); - } - - if (!operatorDeclaration.Body.IsNull) { - EnforceBraceStyle(policy.MethodBraceStyle, operatorDeclaration.Body.LBraceToken, operatorDeclaration.Body.RBraceToken); - VisitBlockWithoutFixingBraces(operatorDeclaration.Body, policy.IndentMethodBody); - } - if (IsMember(operatorDeclaration.NextSibling)) { - EnsureBlankLinesAfter(operatorDeclaration, policy.BlankLinesBetweenMembers); - } - } - - public override void VisitConstructorDeclaration(ConstructorDeclaration constructorDeclaration) - { - FormatAttributedNode(constructorDeclaration); - - ForceSpacesBefore(constructorDeclaration.LParToken, policy.SpaceBeforeConstructorDeclarationParentheses); - if (constructorDeclaration.Parameters.Any()) { - ForceSpacesAfter(constructorDeclaration.LParToken, policy.SpaceWithinConstructorDeclarationParentheses); - FormatParameters(constructorDeclaration); - } else { - ForceSpacesAfter(constructorDeclaration.LParToken, policy.SpaceBetweenEmptyConstructorDeclarationParentheses); - ForceSpacesBefore(constructorDeclaration.RParToken, policy.SpaceBetweenEmptyConstructorDeclarationParentheses); - } - - if (!constructorDeclaration.Body.IsNull) { - EnforceBraceStyle(policy.ConstructorBraceStyle, constructorDeclaration.Body.LBraceToken, constructorDeclaration.Body.RBraceToken); - VisitBlockWithoutFixingBraces(constructorDeclaration.Body, policy.IndentMethodBody); - } - if (IsMember(constructorDeclaration.NextSibling)) { - EnsureBlankLinesAfter(constructorDeclaration, policy.BlankLinesBetweenMembers); - } - } - - public override void VisitDestructorDeclaration(DestructorDeclaration destructorDeclaration) - { - FormatAttributedNode(destructorDeclaration); - - CSharpTokenNode lParen = destructorDeclaration.LParToken; - int offset = this.document.GetOffset(lParen.StartLocation); - ForceSpaceBefore(offset, policy.SpaceBeforeConstructorDeclarationParentheses); - - if (!destructorDeclaration.Body.IsNull) { - EnforceBraceStyle(policy.DestructorBraceStyle, destructorDeclaration.Body.LBraceToken, destructorDeclaration.Body.RBraceToken); - VisitBlockWithoutFixingBraces(destructorDeclaration.Body, policy.IndentMethodBody); - } - if (IsMember(destructorDeclaration.NextSibling)) { - EnsureBlankLinesAfter(destructorDeclaration, policy.BlankLinesBetweenMembers); - } - } - - #region Statements - public override void VisitExpressionStatement(ExpressionStatement expressionStatement) - { - base.VisitExpressionStatement(expressionStatement); - FixSemicolon(expressionStatement.SemicolonToken); - } - - void VisitBlockWithoutFixingBraces(BlockStatement blockStatement, bool indent) - { - if (indent) { - curIndent.Push(IndentType.Block); - } - foreach (var child in blockStatement.Children) { - if (child.Role == Roles.LBrace || child.Role == Roles.RBrace) { - continue; - } - if (child is Statement) { - FixStatementIndentation(child.StartLocation); - child.AcceptVisitor(this); - } else if (child is Comment) { - child.AcceptVisitor(this); - } else { - // pre processor directives at line start, if they are there. - if (child.StartLocation.Column > 1) - FixStatementIndentation(child.StartLocation); - } - } - if (indent) { - curIndent.Pop (); - } - } - - public override void VisitBlockStatement(BlockStatement blockStatement) - { - FixIndentation(blockStatement.StartLocation); - VisitBlockWithoutFixingBraces(blockStatement, policy.IndentBlocks); - FixIndentation(blockStatement.EndLocation, -1); - } - - public override void VisitComment(Comment comment) - { - if (comment.StartsLine && !HadErrors && (!policy.KeepCommentsAtFirstColumn || comment.StartLocation.Column > 1)) { - FixIndentation(comment.StartLocation); - } - } - - public override void VisitBreakStatement(BreakStatement breakStatement) - { - FixSemicolon(breakStatement.SemicolonToken); - } - - public override void VisitCheckedStatement(CheckedStatement checkedStatement) - { - FixEmbeddedStatment(policy.StatementBraceStyle, policy.FixedBraceForcement, checkedStatement.Body); - } - - public override void VisitContinueStatement(ContinueStatement continueStatement) - { - FixSemicolon(continueStatement.SemicolonToken); - } - - public override void VisitEmptyStatement(EmptyStatement emptyStatement) - { - // Empty - } - - public override void VisitFixedStatement(FixedStatement fixedStatement) - { - FixEmbeddedStatment(policy.StatementBraceStyle, policy.FixedBraceForcement, fixedStatement.EmbeddedStatement); - } - - public override void VisitForeachStatement(ForeachStatement foreachStatement) - { - ForceSpacesBefore(foreachStatement.LParToken, policy.SpaceBeforeForeachParentheses); - - ForceSpacesAfter(foreachStatement.LParToken, policy.SpacesWithinForeachParentheses); - ForceSpacesBefore(foreachStatement.RParToken, policy.SpacesWithinForeachParentheses); - - FixEmbeddedStatment(policy.StatementBraceStyle, policy.ForEachBraceForcement, foreachStatement.EmbeddedStatement); - } - - void FixEmbeddedStatment(BraceStyle braceStyle, BraceForcement braceForcement, AstNode node) - { - FixEmbeddedStatment(braceStyle, braceForcement, null, false, node); - } - - void FixEmbeddedStatment(BraceStyle braceStyle, BraceForcement braceForcement, CSharpTokenNode token, bool allowInLine, AstNode node, bool statementAlreadyIndented = false) - { - if (node == null) { - return; - } - bool isBlock = node is BlockStatement; - TextReplaceAction beginBraceAction = null; - TextReplaceAction endBraceAction = null; - - switch (braceForcement) { - case BraceForcement.DoNotChange: - //nothing - break; - case BraceForcement.AddBraces: - if (!isBlock) { - AstNode n = node.Parent.GetCSharpNodeBefore(node); - int start = document.GetOffset(n.EndLocation); - string startBrace = ""; - switch (braceStyle) { - case BraceStyle.EndOfLineWithoutSpace: - startBrace = "{"; - break; - case BraceStyle.BannerStyle: - case BraceStyle.EndOfLine: - startBrace = " {"; - break; - case BraceStyle.NextLine: - startBrace = this.options.EolMarker + curIndent.IndentString + "{"; - break; - case BraceStyle.NextLineShifted2: - case BraceStyle.NextLineShifted: - curIndent.Push(IndentType.Block); - startBrace = this.options.EolMarker + curIndent.IndentString + "{"; - curIndent.Pop(); - break; - } - beginBraceAction = AddChange(start, 0, startBrace); - } - break; - case BraceForcement.RemoveBraces: - if (isBlock) { - BlockStatement block = node as BlockStatement; - if (block.Statements.Count() == 1) { - int offset1 = document.GetOffset(node.StartLocation); - int start = SearchWhitespaceStart(offset1); - - int offset2 = document.GetOffset(node.EndLocation); - int end = SearchWhitespaceStart(offset2 - 1); - - beginBraceAction = AddChange(start, offset1 - start + 1, null); - endBraceAction = AddChange(end + 1, offset2 - end, null); - node = block.FirstChild; - isBlock = false; - } - } - break; - } - if (isBlock) { - BlockStatement block = node as BlockStatement; - if (allowInLine && block.StartLocation.Line == block.EndLocation.Line && block.Statements.Count() <= 1) { - if (block.Statements.Count() == 1) { - nextStatementIndent = " "; - } - } else { - if (!statementAlreadyIndented) { - EnforceBraceStyle(braceStyle, block.LBraceToken, block.RBraceToken); - } - } - if (braceStyle == BraceStyle.NextLineShifted2) { - curIndent.Push(IndentType.Block); - } - } else { - if (allowInLine && token.StartLocation.Line == node.EndLocation.Line) { - nextStatementIndent = " "; - } - } - if (policy.IndentBlocks && !(policy.AlignEmbeddedIfStatements && node is IfElseStatement && node.Parent is IfElseStatement || policy.AlignEmbeddedUsingStatements && node is UsingStatement && node.Parent is UsingStatement)) { - curIndent.Push(IndentType.Block); - } - if (isBlock) { - VisitBlockWithoutFixingBraces((BlockStatement)node, false); - } else { - if (!statementAlreadyIndented) { - FixStatementIndentation(node.StartLocation); - } - node.AcceptVisitor(this); - } - if (policy.IndentBlocks && !(policy.AlignEmbeddedIfStatements && node is IfElseStatement && node.Parent is IfElseStatement || policy.AlignEmbeddedUsingStatements && node is UsingStatement && node.Parent is UsingStatement)) { - curIndent.Pop(); - } - switch (braceForcement) { - case BraceForcement.DoNotChange: - break; - case BraceForcement.AddBraces: - if (!isBlock) { - int offset = document.GetOffset(node.EndLocation); - if (!char.IsWhiteSpace(document.GetCharAt(offset))) { - offset++; - } - string startBrace = ""; - switch (braceStyle) { - case BraceStyle.DoNotChange: - startBrace = null; - break; - case BraceStyle.EndOfLineWithoutSpace: - startBrace = this.options.EolMarker + curIndent.IndentString + "}"; - break; - case BraceStyle.EndOfLine: - startBrace = this.options.EolMarker + curIndent.IndentString + "}"; - break; - case BraceStyle.NextLine: - startBrace = this.options.EolMarker + curIndent.IndentString + "}"; - break; - case BraceStyle.BannerStyle: - case BraceStyle.NextLineShifted2: - case BraceStyle.NextLineShifted: - curIndent.Push(IndentType.Block); - startBrace = this.options.EolMarker + curIndent.IndentString + "}"; - curIndent.Pop (); - break; - - } - if (startBrace != null) { - endBraceAction = AddChange(offset, 0, startBrace); - } - } - break; - } - if (beginBraceAction != null && endBraceAction != null) { - beginBraceAction.DependsOn = endBraceAction; - endBraceAction.DependsOn = beginBraceAction; - } - } - - void EnforceBraceStyle(BraceStyle braceStyle, AstNode lbrace, AstNode rbrace) - { - if (lbrace.IsNull || rbrace.IsNull) { - return; - } - - // LineSegment lbraceLineSegment = data.Document.GetLine (lbrace.StartLocation.Line); - int lbraceOffset = document.GetOffset(lbrace.StartLocation); - - // LineSegment rbraceLineSegment = data.Document.GetLine (rbrace.StartLocation.Line); - int rbraceOffset = document.GetOffset(rbrace.StartLocation); - int whitespaceStart = SearchWhitespaceStart(lbraceOffset); - int whitespaceEnd = SearchWhitespaceLineStart(rbraceOffset); - string startIndent = ""; - string endIndent = ""; - switch (braceStyle) { - case BraceStyle.DoNotChange: - startIndent = endIndent = null; - break; - case BraceStyle.EndOfLineWithoutSpace: - startIndent = ""; - endIndent = IsLineIsEmptyUpToEol(rbraceOffset) ? curIndent.IndentString : this.options.EolMarker + curIndent.IndentString; - break; - case BraceStyle.BannerStyle: - var prevNode = lbrace.GetPrevNode(); - if (prevNode is Comment) { - // delete old bracket - AddChange(whitespaceStart, lbraceOffset - whitespaceStart + 1, ""); - - while (prevNode is Comment) { - prevNode = prevNode.GetPrevNode(); - } - whitespaceStart = document.GetOffset(prevNode.EndLocation); - lbraceOffset = whitespaceStart; - startIndent = " {"; - } else { - startIndent = " "; - } - curIndent.Push(IndentType.Block); - endIndent = IsLineIsEmptyUpToEol(rbraceOffset) ? curIndent.IndentString : this.options.EolMarker + curIndent.IndentString; - curIndent.Pop(); - break; - case BraceStyle.EndOfLine: - prevNode = lbrace.GetPrevNode(); - if (prevNode is Comment) { - // delete old bracket - AddChange(whitespaceStart, lbraceOffset - whitespaceStart + 1, ""); - - while (prevNode is Comment) { - prevNode = prevNode.GetPrevNode(); - } - whitespaceStart = document.GetOffset(prevNode.EndLocation); - lbraceOffset = whitespaceStart; - startIndent = " {"; - } else { - startIndent = " "; - } - endIndent = IsLineIsEmptyUpToEol(rbraceOffset) ? curIndent.IndentString : this.options.EolMarker + curIndent.IndentString; - break; - case BraceStyle.NextLine: - startIndent = this.options.EolMarker + curIndent.IndentString; - endIndent = IsLineIsEmptyUpToEol(rbraceOffset) ? curIndent.IndentString : this.options.EolMarker + curIndent.IndentString; - break; - case BraceStyle.NextLineShifted2: - case BraceStyle.NextLineShifted: - curIndent.Push(IndentType.Block); - startIndent = this.options.EolMarker + curIndent.IndentString; - endIndent = IsLineIsEmptyUpToEol(rbraceOffset) ? curIndent.IndentString : this.options.EolMarker + curIndent.IndentString; - curIndent.Pop (); - break; - } - - if (lbraceOffset > 0 && startIndent != null) { - AddChange(whitespaceStart, lbraceOffset - whitespaceStart, startIndent); - } - if (rbraceOffset > 0 && endIndent != null) { - AddChange(whitespaceEnd, rbraceOffset - whitespaceEnd, endIndent); - } - } - - 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; - } - - public bool IsLineIsEmptyUpToEol(TextLocation startLocation) - { - return IsLineIsEmptyUpToEol(document.GetOffset(startLocation) - 1); - } - - bool IsLineIsEmptyUpToEol(int startOffset) - { - for (int offset = startOffset - 1; offset >= 0; offset--) { - char ch = document.GetCharAt(offset); - if (ch != ' ' && ch != '\t') { - return ch == '\n' || ch == '\r'; - } - } - return true; - } - - int SearchWhitespaceStart(int startOffset) - { - if (startOffset < 0) { - throw new ArgumentOutOfRangeException ("startoffset", "value : " + startOffset); - } - for (int offset = startOffset - 1; offset >= 0; offset--) { - char ch = document.GetCharAt(offset); - if (!Char.IsWhiteSpace(ch)) { - return offset + 1; - } - } - return 0; - } - - int SearchWhitespaceEnd(int startOffset) - { - if (startOffset > document.TextLength) { - throw new ArgumentOutOfRangeException ("startoffset", "value : " + startOffset); - } - for (int offset = startOffset + 1; offset < document.TextLength; offset++) { - char ch = document.GetCharAt(offset); - if (!Char.IsWhiteSpace(ch)) { - return offset + 1; - } - } - return document.TextLength - 1; - } - - int SearchWhitespaceLineStart(int startOffset) - { - if (startOffset < 0) { - throw new ArgumentOutOfRangeException ("startoffset", "value : " + startOffset); - } - for (int offset = startOffset - 1; offset >= 0; offset--) { - char ch = document.GetCharAt(offset); - if (ch != ' ' && ch != '\t') { - return offset + 1; - } - } - return 0; - } - - public override void VisitForStatement(ForStatement forStatement) - { - foreach (AstNode node in forStatement.Children) { - if (node.Role == Roles.Semicolon) { - if (node.NextSibling is CSharpTokenNode || node.NextSibling is EmptyStatement) { - continue; - } - ForceSpacesBefore(node, policy.SpaceBeforeForSemicolon); - ForceSpacesAfter(node, policy.SpaceAfterForSemicolon); - } - } - - ForceSpacesBefore(forStatement.LParToken, policy.SpaceBeforeForParentheses); - - ForceSpacesAfter(forStatement.LParToken, policy.SpacesWithinForParentheses); - ForceSpacesBefore(forStatement.RParToken, policy.SpacesWithinForParentheses); - - FixEmbeddedStatment(policy.StatementBraceStyle, policy.ForBraceForcement, forStatement.EmbeddedStatement); - } - - public override void VisitGotoStatement(GotoStatement gotoStatement) - { - VisitChildren(gotoStatement); - FixSemicolon(gotoStatement.SemicolonToken); - } - - public override void VisitIfElseStatement(IfElseStatement ifElseStatement) - { - ForceSpacesBefore(ifElseStatement.LParToken, policy.SpaceBeforeIfParentheses); - - ForceSpacesAfter(ifElseStatement.LParToken, policy.SpacesWithinIfParentheses); - ForceSpacesBefore(ifElseStatement.RParToken, policy.SpacesWithinIfParentheses); - - if (!(ifElseStatement.Parent is IfElseStatement && ((IfElseStatement)ifElseStatement.Parent).FalseStatement == ifElseStatement)) { - FixStatementIndentation(ifElseStatement.StartLocation); - } - - if (!ifElseStatement.Condition.IsNull) { - ifElseStatement.Condition.AcceptVisitor(this); - } - - if (!ifElseStatement.TrueStatement.IsNull) { - FixEmbeddedStatment(policy.StatementBraceStyle, policy.IfElseBraceForcement, ifElseStatement.IfToken, policy.AllowIfBlockInline, ifElseStatement.TrueStatement); - } - - if (!ifElseStatement.FalseStatement.IsNull) { - 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.ElseIfNewLinePlacement, ((IfElseStatement)ifElseStatement.FalseStatement).IfToken); - } - FixEmbeddedStatment(policy.StatementBraceStyle, forcement, ifElseStatement.ElseToken, policy.AllowIfBlockInline, ifElseStatement.FalseStatement, ifElseStatement.FalseStatement is IfElseStatement); - } - } - - public override void VisitLabelStatement(LabelStatement labelStatement) - { - // TODO - VisitChildren(labelStatement); - } - - public override void VisitLockStatement(LockStatement lockStatement) - { - ForceSpacesBefore(lockStatement.LParToken, policy.SpaceBeforeLockParentheses); - - ForceSpacesAfter(lockStatement.LParToken, policy.SpacesWithinLockParentheses); - ForceSpacesBefore(lockStatement.RParToken, policy.SpacesWithinLockParentheses); - - FixEmbeddedStatment(policy.StatementBraceStyle, policy.FixedBraceForcement, lockStatement.EmbeddedStatement); - } - - public override void VisitReturnStatement(ReturnStatement returnStatement) - { - VisitChildren(returnStatement); - FixSemicolon(returnStatement.SemicolonToken); - } - - public override void VisitSwitchStatement(SwitchStatement switchStatement) - { - ForceSpacesBefore(switchStatement.LParToken, policy.SpaceBeforeSwitchParentheses); - - ForceSpacesAfter(switchStatement.LParToken, policy.SpacesWithinSwitchParentheses); - ForceSpacesBefore(switchStatement.RParToken, policy.SpacesWithinSwitchParentheses); - - EnforceBraceStyle(policy.StatementBraceStyle, switchStatement.LBraceToken, switchStatement.RBraceToken); - VisitChildren(switchStatement); - } - - public override void VisitSwitchSection(SwitchSection switchSection) - { - if (policy.IndentSwitchBody) { - curIndent.Push(IndentType.Block); - } - - foreach (CaseLabel label in switchSection.CaseLabels) { - FixStatementIndentation(label.StartLocation); - label.AcceptVisitor(this); - } - if (policy.IndentCaseBody) { - curIndent.Push(IndentType.Block); - } - - foreach (var stmt in switchSection.Statements) { - if (stmt is BreakStatement && !policy.IndentBreakStatements && policy.IndentCaseBody) { - curIndent.Pop(); - FixStatementIndentation(stmt.StartLocation); - stmt.AcceptVisitor(this); - curIndent.Push(IndentType.Block); - continue; - } - FixStatementIndentation(stmt.StartLocation); - stmt.AcceptVisitor(this); - } - if (policy.IndentCaseBody) { - curIndent.Pop (); - } - - if (policy.IndentSwitchBody) { - curIndent.Pop (); - } - } - - public override void VisitCaseLabel(CaseLabel caseLabel) - { - FixSemicolon(caseLabel.ColonToken); - } - - public override void VisitThrowStatement(ThrowStatement throwStatement) - { - VisitChildren(throwStatement); - FixSemicolon(throwStatement.SemicolonToken); - } - - public override void VisitTryCatchStatement(TryCatchStatement tryCatchStatement) - { - if (!tryCatchStatement.TryBlock.IsNull) { - FixEmbeddedStatment(policy.StatementBraceStyle, BraceForcement.DoNotChange, tryCatchStatement.TryBlock); - } - - foreach (CatchClause clause in tryCatchStatement.CatchClauses) { - PlaceOnNewLine(policy.CatchNewLinePlacement, clause.CatchToken); - if (!clause.LParToken.IsNull) { - ForceSpacesBefore(clause.LParToken, policy.SpaceBeforeCatchParentheses); - - ForceSpacesAfter(clause.LParToken, policy.SpacesWithinCatchParentheses); - ForceSpacesBefore(clause.RParToken, policy.SpacesWithinCatchParentheses); - } - FixEmbeddedStatment(policy.StatementBraceStyle, BraceForcement.DoNotChange, clause.Body); - } - - if (!tryCatchStatement.FinallyBlock.IsNull) { - PlaceOnNewLine(policy.FinallyNewLinePlacement, tryCatchStatement.FinallyToken); - - FixEmbeddedStatment(policy.StatementBraceStyle, BraceForcement.DoNotChange, tryCatchStatement.FinallyBlock); - } - - } - - public override void VisitCatchClause(CatchClause catchClause) - { - // Handled in TryCatchStatement - } - - public override void VisitUncheckedStatement(UncheckedStatement uncheckedStatement) - { - FixEmbeddedStatment(policy.StatementBraceStyle, policy.FixedBraceForcement, uncheckedStatement.Body); - } - - public override void VisitUnsafeStatement(UnsafeStatement unsafeStatement) - { - FixEmbeddedStatment(policy.StatementBraceStyle, BraceForcement.DoNotChange, unsafeStatement.Body); - } - - public override void VisitUsingStatement(UsingStatement usingStatement) - { - ForceSpacesBefore(usingStatement.LParToken, policy.SpaceBeforeUsingParentheses); - - ForceSpacesAfter(usingStatement.LParToken, policy.SpacesWithinUsingParentheses); - ForceSpacesBefore(usingStatement.RParToken, policy.SpacesWithinUsingParentheses); - - FixEmbeddedStatment(policy.StatementBraceStyle, policy.UsingBraceForcement, usingStatement.EmbeddedStatement); - } - - public override void VisitVariableDeclarationStatement(VariableDeclarationStatement variableDeclarationStatement) - { - if ((variableDeclarationStatement.Modifiers & Modifiers.Const) == Modifiers.Const) { - ForceSpacesAround(variableDeclarationStatement.Type, true); - } else { - ForceSpacesAfter(variableDeclarationStatement.Type, true); - } - var lastLoc = variableDeclarationStatement.StartLocation; - foreach (var initializer in variableDeclarationStatement.Variables) { - if (lastLoc.Line != initializer.StartLocation.Line) { - FixStatementIndentation(initializer.StartLocation); - lastLoc = initializer.StartLocation; - } - initializer.AcceptVisitor(this); - } - - FormatCommas(variableDeclarationStatement, policy.SpaceBeforeLocalVariableDeclarationComma, policy.SpaceAfterLocalVariableDeclarationComma); - FixSemicolon(variableDeclarationStatement.SemicolonToken); - } - - public override void VisitDoWhileStatement(DoWhileStatement doWhileStatement) - { - PlaceOnNewLine(policy.WhileNewLinePlacement, doWhileStatement.WhileToken); - FixEmbeddedStatment(policy.StatementBraceStyle, policy.WhileBraceForcement, doWhileStatement.EmbeddedStatement); - } - - public override void VisitWhileStatement(WhileStatement whileStatement) - { - ForceSpacesBefore(whileStatement.LParToken, policy.SpaceBeforeWhileParentheses); - - ForceSpacesAfter(whileStatement.LParToken, policy.SpacesWithinWhileParentheses); - ForceSpacesBefore(whileStatement.RParToken, policy.SpacesWithinWhileParentheses); - - FixEmbeddedStatment(policy.StatementBraceStyle, policy.WhileBraceForcement, whileStatement.EmbeddedStatement); - } - - public override void VisitYieldBreakStatement(YieldBreakStatement yieldBreakStatement) - { - FixSemicolon(yieldBreakStatement.SemicolonToken); - } - - public override void VisitYieldReturnStatement(YieldReturnStatement yieldStatement) - { - yieldStatement.Expression.AcceptVisitor(this); - FixSemicolon(yieldStatement.SemicolonToken); - } - - public override void VisitVariableInitializer(VariableInitializer variableInitializer) - { - if (!variableInitializer.AssignToken.IsNull) { - ForceSpacesAround(variableInitializer.AssignToken, policy.SpaceAroundAssignment); - } - if (!variableInitializer.Initializer.IsNull) { - variableInitializer.Initializer.AcceptVisitor(this); - } - } - - #endregion - - #region Expressions - public override void VisitComposedType(ComposedType composedType) - { - var spec = composedType.ArraySpecifiers.FirstOrDefault(); - if (spec != null) { - ForceSpacesBefore(spec.LBracketToken, policy.SpaceBeforeArrayDeclarationBrackets); - } - - base.VisitComposedType(composedType); - } - - public override void VisitAnonymousMethodExpression(AnonymousMethodExpression anonymousMethodExpression) - { - if (!anonymousMethodExpression.Body.IsNull) { - EnforceBraceStyle(policy.AnonymousMethodBraceStyle, anonymousMethodExpression.Body.LBraceToken, anonymousMethodExpression.Body.RBraceToken); - VisitBlockWithoutFixingBraces(anonymousMethodExpression.Body, policy.IndentBlocks); - return; - } - base.VisitAnonymousMethodExpression(anonymousMethodExpression); - } - - public override void VisitAssignmentExpression(AssignmentExpression assignmentExpression) - { - ForceSpacesAround(assignmentExpression.OperatorToken, policy.SpaceAroundAssignment); - base.VisitAssignmentExpression(assignmentExpression); - } - - public override void VisitBinaryOperatorExpression(BinaryOperatorExpression binaryOperatorExpression) - { - bool forceSpaces = false; - switch (binaryOperatorExpression.Operator) { - case BinaryOperatorType.Equality: - case BinaryOperatorType.InEquality: - forceSpaces = policy.SpaceAroundEqualityOperator; - break; - case BinaryOperatorType.GreaterThan: - case BinaryOperatorType.GreaterThanOrEqual: - case BinaryOperatorType.LessThan: - case BinaryOperatorType.LessThanOrEqual: - forceSpaces = policy.SpaceAroundRelationalOperator; - break; - case BinaryOperatorType.ConditionalAnd: - case BinaryOperatorType.ConditionalOr: - forceSpaces = policy.SpaceAroundLogicalOperator; - break; - case BinaryOperatorType.BitwiseAnd: - case BinaryOperatorType.BitwiseOr: - case BinaryOperatorType.ExclusiveOr: - forceSpaces = policy.SpaceAroundBitwiseOperator; - break; - case BinaryOperatorType.Add: - case BinaryOperatorType.Subtract: - forceSpaces = policy.SpaceAroundAdditiveOperator; - break; - case BinaryOperatorType.Multiply: - case BinaryOperatorType.Divide: - case BinaryOperatorType.Modulus: - forceSpaces = policy.SpaceAroundMultiplicativeOperator; - break; - case BinaryOperatorType.ShiftLeft: - case BinaryOperatorType.ShiftRight: - forceSpaces = policy.SpaceAroundShiftOperator; - break; - case BinaryOperatorType.NullCoalescing: - forceSpaces = policy.SpaceAroundNullCoalescingOperator; - break; - } - ForceSpacesAround(binaryOperatorExpression.OperatorToken, forceSpaces); - - base.VisitBinaryOperatorExpression(binaryOperatorExpression); - // Handle line breaks in binary opeartor expression. - if (binaryOperatorExpression.Left.EndLocation.Line != binaryOperatorExpression.Right.StartLocation.Line) { - curIndent.Push(IndentType.Block); - if (binaryOperatorExpression.OperatorToken.StartLocation.Line == binaryOperatorExpression.Right.StartLocation.Line) { - FixStatementIndentation(binaryOperatorExpression.OperatorToken.StartLocation); - } else { - FixStatementIndentation(binaryOperatorExpression.Right.StartLocation); - } - curIndent.Pop (); - } - } - - public override void VisitConditionalExpression(ConditionalExpression conditionalExpression) - { - ForceSpacesBefore(conditionalExpression.QuestionMarkToken, policy.SpaceBeforeConditionalOperatorCondition); - ForceSpacesAfter(conditionalExpression.QuestionMarkToken, policy.SpaceAfterConditionalOperatorCondition); - ForceSpacesBefore(conditionalExpression.ColonToken, policy.SpaceBeforeConditionalOperatorSeparator); - ForceSpacesAfter(conditionalExpression.ColonToken, policy.SpaceAfterConditionalOperatorSeparator); - base.VisitConditionalExpression(conditionalExpression); - } - - public override void VisitCastExpression(CastExpression castExpression) - { - if (castExpression.RParToken != null) { - ForceSpacesAfter(castExpression.LParToken, policy.SpacesWithinCastParentheses); - ForceSpacesBefore(castExpression.RParToken, policy.SpacesWithinCastParentheses); - - ForceSpacesAfter(castExpression.RParToken, policy.SpaceAfterTypecast); - } - base.VisitCastExpression(castExpression); - } - - void ForceSpacesAround(AstNode node, bool forceSpaces) - { - if (node.IsNull) { - return; - } - ForceSpacesBefore(node, forceSpaces); - ForceSpacesAfter(node, forceSpaces); - } - - void FormatCommas(AstNode parent, bool before, bool after) - { - if (parent.IsNull) { - return; - } - foreach (CSharpTokenNode comma in parent.Children.Where (node => node.Role == Roles.Comma)) { - ForceSpacesAfter(comma, after); - ForceSpacesBefore(comma, before); - } - } - - 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 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); - } else { - ForceSpacesAfter(invocationExpression.LParToken, policy.SpaceBetweenEmptyMethodCallParentheses); - ForceSpacesBefore(invocationExpression.RParToken, policy.SpaceBetweenEmptyMethodCallParentheses); - } - - 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); - - if (!indexerExpression.Target.IsNull) - indexerExpression.Target.AcceptVisitor(this); - - FormatArguments(indexerExpression); - - - - } - - public override void VisitParenthesizedExpression(ParenthesizedExpression parenthesizedExpression) - { - ForceSpacesAfter(parenthesizedExpression.LParToken, policy.SpacesWithinParentheses); - ForceSpacesBefore(parenthesizedExpression.RParToken, policy.SpacesWithinParentheses); - base.VisitParenthesizedExpression(parenthesizedExpression); - } - - public override void VisitSizeOfExpression(SizeOfExpression sizeOfExpression) - { - ForceSpacesBefore(sizeOfExpression.LParToken, policy.SpaceBeforeSizeOfParentheses); - ForceSpacesAfter(sizeOfExpression.LParToken, policy.SpacesWithinSizeOfParentheses); - ForceSpacesBefore(sizeOfExpression.RParToken, policy.SpacesWithinSizeOfParentheses); - base.VisitSizeOfExpression(sizeOfExpression); - } - - public override void VisitTypeOfExpression(TypeOfExpression typeOfExpression) - { - ForceSpacesBefore(typeOfExpression.LParToken, policy.SpaceBeforeTypeOfParentheses); - ForceSpacesAfter(typeOfExpression.LParToken, policy.SpacesWithinTypeOfParentheses); - ForceSpacesBefore(typeOfExpression.RParToken, policy.SpacesWithinTypeOfParentheses); - base.VisitTypeOfExpression(typeOfExpression); - } - - public override void VisitCheckedExpression(CheckedExpression checkedExpression) - { - ForceSpacesAfter(checkedExpression.LParToken, policy.SpacesWithinCheckedExpressionParantheses); - ForceSpacesBefore(checkedExpression.RParToken, policy.SpacesWithinCheckedExpressionParantheses); - base.VisitCheckedExpression(checkedExpression); - } - - public override void VisitUncheckedExpression(UncheckedExpression uncheckedExpression) - { - ForceSpacesAfter(uncheckedExpression.LParToken, policy.SpacesWithinCheckedExpressionParantheses); - ForceSpacesBefore(uncheckedExpression.RParToken, policy.SpacesWithinCheckedExpressionParantheses); - base.VisitUncheckedExpression(uncheckedExpression); - } - - public override void VisitObjectCreateExpression(ObjectCreateExpression objectCreateExpression) - { - ForceSpacesBefore(objectCreateExpression.LParToken, policy.SpaceBeforeNewParentheses); - - if (objectCreateExpression.Arguments.Any()) { - if (!objectCreateExpression.LParToken.IsNull) - ForceSpacesAfter(objectCreateExpression.LParToken, policy.SpacesWithinNewParentheses); - } else { - if (!objectCreateExpression.LParToken.IsNull) - ForceSpacesAfter(objectCreateExpression.LParToken, policy.SpacesBetweenEmptyNewParentheses); - } - - if (!objectCreateExpression.Type.IsNull) - objectCreateExpression.Type.AcceptVisitor(this); - - FormatArguments(objectCreateExpression); - - } - - public override void VisitArrayCreateExpression(ArrayCreateExpression arrayObjectCreateExpression) - { - FormatCommas(arrayObjectCreateExpression, policy.SpaceBeforeMethodCallParameterComma, policy.SpaceAfterMethodCallParameterComma); - base.VisitArrayCreateExpression(arrayObjectCreateExpression); - } - - public override void VisitArrayInitializerExpression(ArrayInitializerExpression arrayInitializerExpression) - { - 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) { - FixStatementIndentation(init.StartLocation); - init.AcceptVisitor(this); - } - curIndent.Pop(); - } else if (policy.ArrayInitializerWrapping == Wrapping.DoNotWrap) { - ForceSpacesBeforeRemoveNewLines(arrayInitializerExpression.LBraceToken); - ForceSpacesBeforeRemoveNewLines(arrayInitializerExpression.RBraceToken); - foreach (var init in arrayInitializerExpression.Elements) { - ForceSpacesBeforeRemoveNewLines(init); - init.AcceptVisitor(this); - } - } else { - base.VisitArrayInitializerExpression(arrayInitializerExpression); - } - } - - public override void VisitLambdaExpression(LambdaExpression lambdaExpression) - { - ForceSpacesAfter(lambdaExpression.ArrowToken, true); - ForceSpacesBefore(lambdaExpression.ArrowToken, true); - - base.VisitLambdaExpression(lambdaExpression); - } - - public override void VisitNamedArgumentExpression(NamedArgumentExpression namedArgumentExpression) - { - ForceSpacesAfter(namedArgumentExpression.ColonToken, policy.SpaceInNamedArgumentAfterDoubleColon); - base.VisitNamedArgumentExpression(namedArgumentExpression); - } - - public override void VisitMemberReferenceExpression(MemberReferenceExpression memberReferenceExpression) - { - ForceSpacesAfter(memberReferenceExpression.DotToken, false); - base.VisitMemberReferenceExpression(memberReferenceExpression); - } - - #endregion - - void ForceSpaceBefore(int offset, bool forceSpace) - { - bool insertedSpace = false; - do { - char ch = document.GetCharAt(offset); - //Console.WriteLine (ch); - if (!IsSpacing(ch) && (insertedSpace || !forceSpace)) { - break; - } - if (ch == ' ' && forceSpace) { - if (insertedSpace) { - AddChange(offset, 1, null); - } else { - insertedSpace = true; - } - } else if (forceSpace) { - if (!insertedSpace) { - AddChange(offset, IsSpacing(ch) ? 1 : 0, " "); - insertedSpace = true; - } else if (IsSpacing(ch)) { - AddChange(offset, 1, null); - } - } - - offset--; - } while (offset >= 0); - } - - - - /* - int GetLastNonWsChar (LineSegment line, int lastColumn) - { - int result = -1; - bool inComment = false; - for (int i = 0; i < lastColumn; i++) { - char ch = data.GetCharAt (line.Offset + i); - if (Char.IsWhiteSpace (ch)) - continue; - if (ch == '/' && i + 1 < line.EditableLength && data.GetCharAt (line.Offset + i + 1) == '/') - return result; - if (ch == '/' && i + 1 < line.EditableLength && data.GetCharAt (line.Offset + i + 1) == '*') { - inComment = true; - i++; - continue; - } - if (inComment && ch == '*' && i + 1 < line.EditableLength && data.GetCharAt (line.Offset + i + 1) == '/') { - inComment = false; - i++; - continue; - } - if (!inComment) - result = i; - } - return result; - } - */ - - - public void FixSemicolon(CSharpTokenNode semicolon) - { - if (semicolon.IsNull) { - return; - } - int endOffset = document.GetOffset(semicolon.StartLocation); - int offset = endOffset; - while (offset - 1 > 0 && char.IsWhiteSpace (document.GetCharAt (offset - 1))) { - offset--; - } - if (offset < endOffset) { - AddChange(offset, endOffset - offset, null); - } - } - - void PlaceOnNewLine(NewLinePlacement newLine, AstNode keywordNode) - { - 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 == NewLinePlacement.NewLine ? this.options.EolMarker + this.curIndent.IndentString : " "; - AddChange(whitespaceStart, offset - whitespaceStart, indentString); - } - - string nextStatementIndent = null; - - void FixStatementIndentation(TextLocation location) - { - int offset = document.GetOffset(location); - if (offset <= 0) { - Console.WriteLine("possible wrong offset"); - Console.WriteLine(Environment.StackTrace); - return; - } - bool isEmpty = IsLineIsEmptyUpToEol(offset); - int lineStart = SearchWhitespaceLineStart(offset); - string indentString = nextStatementIndent == null ? (isEmpty ? "" : this.options.EolMarker) + this.curIndent.IndentString : nextStatementIndent; - nextStatementIndent = null; - AddChange(lineStart, offset - lineStart, indentString); - } - - void FixIndentation(TextLocation location) - { - FixIndentation(location, 0); - } - - void FixIndentation(TextLocation location, int relOffset) - { - if (location.Line < 1 || location.Line > document.LineCount) { - Console.WriteLine("Invalid location " + location); - Console.WriteLine(Environment.StackTrace); - return; - } - - string lineIndent = GetIndentation(location.Line); - string indentString = this.curIndent.IndentString; - if (indentString != lineIndent && location.Column - 1 + relOffset == lineIndent.Length) { - AddChange(document.GetOffset(location.Line, 1), lineIndent.Length, indentString); - } - } - - void FixIndentationForceNewLine(TextLocation location) - { - string lineIndent = GetIndentation(location.Line); - string indentString = this.curIndent.IndentString; - if (location.Column - 1 == lineIndent.Length) { - AddChange(document.GetOffset(location.Line, 1), lineIndent.Length, indentString); - } else { - int offset = document.GetOffset(location); - int start = SearchWhitespaceLineStart(offset); - if (start > 0) { - char ch = document.GetCharAt(start - 1); - if (ch == '\n') { - start--; - if (start > 1 && document.GetCharAt(start - 1) == '\r') { - start--; - } - } else if (ch == '\r') { - start--; - } - AddChange(start, offset - start, this.options.EolMarker + indentString); - } - } - } - - string GetIndentation(int lineNumber) - { - IDocumentLine line = document.GetLineByNumber(lineNumber); - StringBuilder b = new StringBuilder (); - int endOffset = line.EndOffset; - for (int i = line.Offset; i < endOffset; i++) { - char c = document.GetCharAt(i); - if (!IsSpacing(c)) { - break; - } - b.Append(c); - } - return b.ToString(); - } - } -} - diff --git a/NRefactory/ICSharpCode.NRefactory.CSharp/Formatter/CSharpFormatter.cs b/NRefactory/ICSharpCode.NRefactory.CSharp/Formatter/CSharpFormatter.cs new file mode 100644 index 000000000..a6969fea7 --- /dev/null +++ b/NRefactory/ICSharpCode.NRefactory.CSharp/Formatter/CSharpFormatter.cs @@ -0,0 +1,159 @@ +// +// CSharpFormatter.cs +// +// Author: +// Mike Krüger +// +// Copyright (c) 2013 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.Threading; +using System.Linq; +using ICSharpCode.NRefactory.CSharp.Refactoring; +using ICSharpCode.NRefactory.TypeSystem; +using System.Collections.Generic; + +namespace ICSharpCode.NRefactory.CSharp +{ + public enum FormattingMode { + OnTheFly, + Intrusive + } + + /// + /// The C# Formatter generates a set of text replace actions to format a region in a C# document. + /// + public class CSharpFormatter + { + readonly CSharpFormattingOptions policy; + readonly TextEditorOptions options; + + /// + /// Gets the formatting policy the formatter uses. + /// + public CSharpFormattingOptions Policy { + get { + return policy; + } + } + + /// + /// Gets the text editor options the formatter uses. + /// Note: If none was specified TextEditorOptions.Default gets used. + /// + public TextEditorOptions TextEditorOptions { + get { + return options; + } + } + + List formattingRegions = new List (); + internal TextLocation lastFormattingLocation = new TextLocation(int.MaxValue, int.MaxValue); + + /// + /// Gets the formatting regions. NOTE: Will get changed to IReadOnlyList. + /// + public IList FormattingRegions { + get { + return formattingRegions; + } + } + + /// + /// Gets or sets the formatting mode. For on the fly formatting a lightweight formatting mode + /// gives better results. + /// + public FormattingMode FormattingMode { + get; + set; + } + + /// + /// Initializes a new instance of the class. + /// + /// The formatting policy to use. + /// The text editor options (optional). Default is: TextEditorOptions.Default + public CSharpFormatter(CSharpFormattingOptions policy, TextEditorOptions options = null) + { + if (policy == null) + throw new ArgumentNullException("policy"); + this.policy = policy; + this.options = options ?? TextEditorOptions.Default; + } + + /// + /// Format the specified document and gives back the formatted text as result. + /// + public string Format(IDocument document) + { + return InternalFormat (new StringBuilderDocument (document.Text)); + } + + /// + /// Format the specified text and gives back the formatted text as result. + /// + public string Format(string text) + { + return InternalFormat (new StringBuilderDocument (text)); + } + + string InternalFormat(IDocument document) + { + var syntaxTree = SyntaxTree.Parse (document, document.FileName); + var changes = AnalyzeFormatting(document, syntaxTree); + changes.ApplyChanges(); + return document.Text; + } + + /// + /// Analyzes the formatting of a given document and syntax tree. + /// + /// Document. + /// Syntax tree. + /// The cancellation token. + public FormattingChanges AnalyzeFormatting(IDocument document, SyntaxTree syntaxTree, CancellationToken token = default (CancellationToken)) + { + if (document == null) + throw new ArgumentNullException("document"); + if (syntaxTree == null) + throw new ArgumentNullException("syntaxTree"); + var result = new FormattingChanges(document); + var visitor = new FormattingVisitor(this, document, result, token); + syntaxTree.AcceptVisitor(visitor); + return result; + } + + /// + /// Adds a region in the document that should be formatted. + /// + public void AddFormattingRegion (DomRegion region) + { + formattingRegions.Add(region); + if (formattingRegions.Count == 1) { + lastFormattingLocation = region.End; + } else { + lastFormattingLocation = lastFormattingLocation < region.End ? region.End : lastFormattingLocation; + } + } + + } +} + diff --git a/NRefactory/ICSharpCode.NRefactory.CSharp/Formatter/CSharpFormattingOptions.cs b/NRefactory/ICSharpCode.NRefactory.CSharp/Formatter/CSharpFormattingOptions.cs index 23152e5bd..0a97a1c0b 100644 --- a/NRefactory/ICSharpCode.NRefactory.CSharp/Formatter/CSharpFormattingOptions.cs +++ b/NRefactory/ICSharpCode.NRefactory.CSharp/Formatter/CSharpFormattingOptions.cs @@ -1,4 +1,4 @@ -// +// // CSharpFormattingOptions.cs // // Author: @@ -41,13 +41,6 @@ namespace ICSharpCode.NRefactory.CSharp BannerStyle } - public enum BraceForcement - { - DoNotChange, - RemoveBraces, - AddBraces - } - public enum PropertyFormatting { AllowOneLine, @@ -68,6 +61,17 @@ namespace ICSharpCode.NRefactory.CSharp SameLine } + public enum UsingPlacement { + TopOfFile, + InsideNamespace + } + + public enum EmptyLineFormatting { + DoNotChange, + Indent, + DoNotIndent + } + public class CSharpFormattingOptions { public string Name { @@ -146,21 +150,47 @@ namespace ICSharpCode.NRefactory.CSharp set; } - public bool AlignEmbeddedUsingStatements { // tested + public bool AlignEmbeddedStatements { // tested + get; + set; + } + + public bool AlignElseInIfStatements { + get; + set; + } + + + + public PropertyFormatting AutoPropertyFormatting { // tested + get; + set; + } + + public PropertyFormatting SimplePropertyFormatting { // tested get; set; } - public bool AlignEmbeddedIfStatements { // tested + public EmptyLineFormatting EmptyLineFormatting { get; set; } - public PropertyFormatting PropertyFormatting { // tested + public bool IndentPreprocessorDirectives { // tested get; set; } + public bool AlignToMemberReferenceDot { // TODO! + get; + set; + } + + public bool IndentBlocksInsideExpressions { + get; + set; + } #endregion #region Braces @@ -224,12 +254,12 @@ namespace ICSharpCode.NRefactory.CSharp set; } - public bool AllowPropertyGetBlockInline { // tested + public PropertyFormatting SimpleGetBlockFormatting { // tested get; set; } - public bool AllowPropertySetBlockInline { // tested + public PropertyFormatting SimpleSetBlockFormatting { // tested get; set; } @@ -269,41 +299,17 @@ namespace ICSharpCode.NRefactory.CSharp set; } - #endregion - - #region Force Braces - public BraceForcement IfElseBraceForcement { // tested - get; - set; - } - - public BraceForcement ForBraceForcement { // tested - get; - set; - } - - public BraceForcement ForEachBraceForcement { // tested - get; - set; - } - - public BraceForcement WhileBraceForcement { // tested - get; - set; - } - - public BraceForcement UsingBraceForcement { // tested - get; - set; - } - - public BraceForcement FixedBraceForcement { // tested - get; - set; + bool allowOneLinedArrayInitialziers = true; + public bool AllowOneLinedArrayInitialziers { + get { + return allowOneLinedArrayInitialziers; + } + set { + allowOneLinedArrayInitialziers = value; + } } - #endregion - + #region NewLines public NewLinePlacement ElseNewLinePlacement { // tested get; @@ -329,6 +335,16 @@ namespace ICSharpCode.NRefactory.CSharp get; set; } + + NewLinePlacement embeddedStatementPlacement = NewLinePlacement.NewLine; + public NewLinePlacement EmbeddedStatementPlacement { + get { + return embeddedStatementPlacement; + } + set { + embeddedStatementPlacement = value; + } + } #endregion #region Spaces @@ -434,6 +450,16 @@ namespace ICSharpCode.NRefactory.CSharp get; set; } + + public NewLinePlacement NewLineBeforeConstructorInitializerColon { + get; + set; + } + + public NewLinePlacement NewLineAfterConstructorInitializerColon { + get; + set; + } // indexer public bool SpaceBeforeIndexerDeclarationBracket { // tested @@ -568,7 +594,22 @@ namespace ICSharpCode.NRefactory.CSharp set; } - public bool SpaceAroundNullCoalescingOperator { + public bool SpaceAroundNullCoalescingOperator { // Tested + get; + set; + } + + public bool SpaceAfterUnsafeAddressOfOperator { // Tested + get; + set; + } + + public bool SpaceAfterUnsafeAsteriskOfOperator { // Tested + get; + set; + } + + public bool SpaceAroundUnsafeArrowOperator { // Tested get; set; } @@ -733,40 +774,60 @@ namespace ICSharpCode.NRefactory.CSharp get; set; } + + public bool RemoveEndOfLineWhiteSpace { + get; + set; + } + + public bool SpaceBeforeSemicolon { + get; + set; + } #endregion #region Blank Lines - public int BlankLinesBeforeUsings { + public int MinimumBlankLinesBeforeUsings { get; set; } - public int BlankLinesAfterUsings { + public int MinimumBlankLinesAfterUsings { get; set; } - public int BlankLinesBeforeFirstDeclaration { + public int MinimumBlankLinesBeforeFirstDeclaration { get; set; } - public int BlankLinesBetweenTypes { + public int MinimumBlankLinesBetweenTypes { get; set; } - public int BlankLinesBetweenFields { + public int MinimumBlankLinesBetweenFields { get; set; } - public int BlankLinesBetweenEventFields { + public int MinimumBlankLinesBetweenEventFields { get; set; } - public int BlankLinesBetweenMembers { + public int MinimumBlankLinesBetweenMembers { + get; + set; + } + + public int MinimumBlankLinesAroundRegion { + get; + set; + } + + public int MinimumBlankLinesInsideRegion { get; set; } @@ -803,12 +864,12 @@ namespace ICSharpCode.NRefactory.CSharp set; } - public bool NewLineAferMethodCallOpenParentheses { + public NewLinePlacement NewLineAferMethodCallOpenParentheses { get; set; } - public bool MethodCallClosingParenthesesOnNewLine { + public NewLinePlacement MethodCallClosingParenthesesOnNewLine { get; set; } @@ -818,12 +879,12 @@ namespace ICSharpCode.NRefactory.CSharp set; } - public bool NewLineAferIndexerOpenBracket { + public NewLinePlacement NewLineAferIndexerOpenBracket { get; set; } - public bool IndexerClosingBracketOnNewLine { + public NewLinePlacement IndexerClosingBracketOnNewLine { get; set; } @@ -833,12 +894,12 @@ namespace ICSharpCode.NRefactory.CSharp set; } - public bool NewLineAferMethodDeclarationOpenParentheses { + public NewLinePlacement NewLineAferMethodDeclarationOpenParentheses { get; set; } - public bool MethodDeclarationClosingParenthesesOnNewLine { + public NewLinePlacement MethodDeclarationClosingParenthesesOnNewLine { get; set; } @@ -848,12 +909,45 @@ namespace ICSharpCode.NRefactory.CSharp set; } - public bool NewLineAferIndexerDeclarationOpenBracket { + public NewLinePlacement NewLineAferIndexerDeclarationOpenBracket { + get; + set; + } + + public NewLinePlacement IndexerDeclarationClosingBracketOnNewLine { + get; + set; + } + + public bool AlignToFirstIndexerArgument { get; set; } - public bool IndexerDeclarationClosingBracketOnNewLine { + public bool AlignToFirstIndexerDeclarationParameter { + get; + set; + } + + public bool AlignToFirstMethodCallArgument { + get; + set; + } + + public bool AlignToFirstMethodDeclarationParameter { + get; + set; + } + + public NewLinePlacement NewLineBeforeNewQueryClause { + get; + set; + } + + #endregion + + #region Using Declarations + public UsingPlacement UsingPlacement { get; set; } diff --git a/NRefactory/ICSharpCode.NRefactory.CSharp/Formatter/ConstructFixer.cs b/NRefactory/ICSharpCode.NRefactory.CSharp/Formatter/ConstructFixer.cs new file mode 100644 index 000000000..f2fd87547 --- /dev/null +++ b/NRefactory/ICSharpCode.NRefactory.CSharp/Formatter/ConstructFixer.cs @@ -0,0 +1,514 @@ +// +// ConstructFixer.cs +// +// Author: +// Mike Krüger +// +// Copyright (c) 2014 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.Text; +using System.Reflection; +using System.Linq; + +namespace ICSharpCode.NRefactory.CSharp +{ + abstract class ConstructCompleter + { + public abstract bool TryFix (ConstructFixer fixer, SyntaxTree syntaxTree, IDocument document, TextLocation location, ref int newOffset); + + protected AstNode GetLastNonErrorChild (AstNode node) + { + var lastNode = node.LastChild; + + while (lastNode is ErrorNode) { + lastNode = lastNode.GetPrevNode(FormattingVisitor.NoWhitespacePredicate); + } + return lastNode; + } + } + + class TypeDeclarationCompleter : ConstructCompleter + { + public override bool TryFix(ConstructFixer fixer, SyntaxTree syntaxTree, IDocument document, TextLocation location, ref int newOffset) + { + var typeDeclaration = syntaxTree.GetNodeAt(location); + if (typeDeclaration != null) { + if (typeDeclaration.LBraceToken.IsNull && typeDeclaration.RBraceToken.IsNull) { + if (typeDeclaration.Members.Any()) + return false; + var lastNode = GetLastNonErrorChild (typeDeclaration); + if (lastNode == null) + return false; + var insertionOffset = document.GetOffset(lastNode.EndLocation); + document.Insert(insertionOffset, fixer.GenerateBody (typeDeclaration, fixer.Options.ClassBraceStyle, false, ref newOffset)); + return true; + } + } + return false; + } + } + + class DelegateDeclarationCompleter : ConstructCompleter + { + public override bool TryFix(ConstructFixer fixer, SyntaxTree syntaxTree, IDocument document, TextLocation location, ref int newOffset) + { + var typeDeclaration = syntaxTree.GetNodeAt(location); + if (typeDeclaration != null) { + if (typeDeclaration.RParToken.IsNull) { + var lastNode = GetLastNonErrorChild (typeDeclaration); + if (lastNode == null) + return false; + var insertionOffset = document.GetOffset(lastNode.EndLocation); + document.Insert(insertionOffset, ");\n"); + newOffset += ");\n".Length; + return true; + } + } + return false; + } + } + + class MethodDeclarationCompleter : ConstructCompleter + { + public override bool TryFix(ConstructFixer fixer, SyntaxTree syntaxTree, IDocument document, TextLocation location, ref int newOffset) + { + var methodDeclaration = syntaxTree.GetNodeAt(location); + if (methodDeclaration != null) { + if (!methodDeclaration.LParToken.IsNull && methodDeclaration.RParToken.IsNull) { + var lastNode = GetLastNonErrorChild (methodDeclaration); + if (lastNode == null) + return false; + + var insertionOffset = document.GetOffset(lastNode.EndLocation); + document.Insert(insertionOffset, ")\n\t{\t\t\n\t}"); + newOffset += ")\n\t{\t\t".Length; + return true; + } + } + return false; + } + } + + class IfStatementCompleter : ConstructCompleter + { + public override bool TryFix(ConstructFixer fixer, SyntaxTree syntaxTree, IDocument document, TextLocation location, ref int newOffset) + { + var ifStatement = syntaxTree.GetNodeAt(location); + if (ifStatement != null) { + if (!ifStatement.LParToken.IsNull && ifStatement.RParToken.IsNull) { + var lastNode = GetLastNonErrorChild (ifStatement); + if (lastNode == null) + return false; + + var insertionOffset = document.GetOffset(lastNode.EndLocation); + document.Insert(insertionOffset, fixer.GenerateBody (ifStatement, fixer.Options.StatementBraceStyle, true, ref newOffset)); + return true; + } + } + return false; + } + } + + class ForeachStatementCompleter : ConstructCompleter + { + public override bool TryFix(ConstructFixer fixer, SyntaxTree syntaxTree, IDocument document, TextLocation location, ref int newOffset) + { + var ifStatement = syntaxTree.GetNodeAt(location); + if (ifStatement != null) { + if (!ifStatement.LParToken.IsNull && ifStatement.RParToken.IsNull) { + var lastNode = GetLastNonErrorChild (ifStatement); + if (lastNode == null) + return false; + + var insertionOffset = document.GetOffset(lastNode.EndLocation); + document.Insert(insertionOffset, fixer.GenerateBody (ifStatement, fixer.Options.StatementBraceStyle, true, ref newOffset)); + return true; + } + } + return false; + } + } + + class WhileStatementCompleter : ConstructCompleter + { + public override bool TryFix(ConstructFixer fixer, SyntaxTree syntaxTree, IDocument document, TextLocation location, ref int newOffset) + { + var ifStatement = syntaxTree.GetNodeAt(location); + if (ifStatement != null) { + if (!ifStatement.LParToken.IsNull && ifStatement.RParToken.IsNull) { + var lastNode = GetLastNonErrorChild (ifStatement); + if (lastNode == null) + return false; + + var insertionOffset = document.GetOffset(lastNode.EndLocation); + document.Insert(insertionOffset, fixer.GenerateBody (ifStatement, fixer.Options.StatementBraceStyle, true, ref newOffset)); + return true; + } + } + return false; + } + } + + class DoWhileStatementCompleter : ConstructCompleter + { + public override bool TryFix(ConstructFixer fixer, SyntaxTree syntaxTree, IDocument document, TextLocation location, ref int newOffset) + { + var stmt = syntaxTree.GetNodeAt(location); + if (stmt != null) { + if (!stmt.LParToken.IsNull && stmt.RParToken.IsNull) { + var lastNode = GetLastNonErrorChild (stmt); + if (lastNode == null) + return false; + + var insertionOffset = document.GetOffset(lastNode.EndLocation); + document.Insert(insertionOffset, ");"); + newOffset = insertionOffset + 2; + return true; + } + } + return false; + } + } + + class FixedStatementCompleter : ConstructCompleter + { + public override bool TryFix(ConstructFixer fixer, SyntaxTree syntaxTree, IDocument document, TextLocation location, ref int newOffset) + { + var stmt = syntaxTree.GetNodeAt(location); + if (stmt != null) { + if (!stmt.LParToken.IsNull && stmt.RParToken.IsNull) { + var lastNode = GetLastNonErrorChild (stmt); + if (lastNode == null) + return false; + + var insertionOffset = document.GetOffset(lastNode.EndLocation); + document.Insert(insertionOffset, fixer.GenerateBody (stmt, fixer.Options.StatementBraceStyle, true, ref newOffset)); + return true; + } + } + return false; + } + } + + class SwitchStatementCompleter : ConstructCompleter + { + public override bool TryFix(ConstructFixer fixer, SyntaxTree syntaxTree, IDocument document, TextLocation location, ref int newOffset) + { + var switchStatement = syntaxTree.GetNodeAt(location); + if (switchStatement != null) { + if (!switchStatement.LParToken.IsNull && switchStatement.RParToken.IsNull) { + var lastNode = GetLastNonErrorChild (switchStatement); + if (lastNode == null) + return false; + + var insertionOffset = document.GetOffset(lastNode.EndLocation); + document.Insert(insertionOffset, fixer.GenerateBody (switchStatement, fixer.Options.StatementBraceStyle, true, ref newOffset)); + return true; + } + } + return false; + } + } + + class InvocationCompleter : ConstructCompleter + { + public override bool TryFix(ConstructFixer fixer, SyntaxTree syntaxTree, IDocument document, TextLocation location, ref int newOffset) + { + var invocationExpression = syntaxTree.GetNodeAt(location); + + if (invocationExpression != null) { + if (!invocationExpression.LParToken.IsNull && invocationExpression.RParToken.IsNull) { + var lastNode = GetLastNonErrorChild (invocationExpression); + if (lastNode == null) + return false; + + var insertionOffset = document.GetOffset(lastNode.EndLocation); + + newOffset = insertionOffset; + + + var text = ")"; + newOffset++; + var expressionStatement = invocationExpression.Parent as ExpressionStatement; + if (expressionStatement != null) { + if (expressionStatement.SemicolonToken.IsNull) + text = ");"; + newOffset ++; + } + document.Insert(insertionOffset, text); + + + return true; + } + + } + return false; + } + } + + class BreakStatementCompleter : ConstructCompleter + { + public override bool TryFix(ConstructFixer fixer, SyntaxTree syntaxTree, IDocument document, TextLocation location, ref int newOffset) + { + var stmt = syntaxTree.GetNodeAt(location); + + if (stmt != null && stmt.SemicolonToken.IsNull) { + // TODO !!!! + return true; + } + return false; + } + } + + class CheckedStatementCompleter : ConstructCompleter + { + public override bool TryFix(ConstructFixer fixer, SyntaxTree syntaxTree, IDocument document, TextLocation location, ref int newOffset) + { + var stmt = syntaxTree.GetNodeAt(location); + + if (stmt != null && stmt.Parent is ExpressionStatement) { + var insertionOffset = document.GetOffset(stmt.EndLocation); + document.Insert(insertionOffset, fixer.GenerateBody (stmt, fixer.Options.StatementBraceStyle, false, ref newOffset)); + return true; + } + return false; + } + } + + class UncheckedStatementCompleter : ConstructCompleter + { + public override bool TryFix(ConstructFixer fixer, SyntaxTree syntaxTree, IDocument document, TextLocation location, ref int newOffset) + { + var stmt = syntaxTree.GetNodeAt(location); + + if (stmt != null && stmt.Parent is ExpressionStatement) { + var insertionOffset = document.GetOffset(stmt.EndLocation); + document.Insert(insertionOffset, fixer.GenerateBody (stmt, fixer.Options.StatementBraceStyle, false, ref newOffset)); + return true; + } + return false; + } + } + + class ExpressionStatementCompleter : ConstructCompleter + { + public override bool TryFix(ConstructFixer fixer, SyntaxTree syntaxTree, IDocument document, TextLocation location, ref int newOffset) + { + var expressionStatement = syntaxTree.GetNodeAt(location); + + if (expressionStatement != null) { + int offset = document.GetOffset(expressionStatement.Expression.EndLocation); + if (expressionStatement.SemicolonToken.IsNull) { + document.Insert(offset, ";"); + newOffset = offset + 1; + } + return true; + } + return false; + } + } + + class LockStatementCompleter : ConstructCompleter + { + public override bool TryFix(ConstructFixer fixer, SyntaxTree syntaxTree, IDocument document, TextLocation location, ref int newOffset) + { + var stmt = syntaxTree.GetNodeAt(location); + if (stmt != null) { + if (!stmt.LParToken.IsNull && stmt.RParToken.IsNull) { + var lastNode = GetLastNonErrorChild (stmt); + if (lastNode == null) + return false; + + var insertionOffset = document.GetOffset(lastNode.EndLocation); + document.Insert(insertionOffset, fixer.GenerateBody (stmt, fixer.Options.StatementBraceStyle, true, ref newOffset)); + return true; + } + } + return false; + } + } + + class ReturnStatementCompleter : ConstructCompleter + { + public override bool TryFix(ConstructFixer fixer, SyntaxTree syntaxTree, IDocument document, TextLocation location, ref int newOffset) + { + var stmt = syntaxTree.GetNodeAt(location); + + if (stmt != null && stmt.SemicolonToken.IsNull) { + var insertionOffset = document.GetOffset(stmt.EndLocation); + document.Insert(insertionOffset, ";"); + newOffset = insertionOffset + 1; + return true; + } + return false; + } + } + + class YieldReturnStatementCompleter : ConstructCompleter + { + public override bool TryFix(ConstructFixer fixer, SyntaxTree syntaxTree, IDocument document, TextLocation location, ref int newOffset) + { + var stmt = syntaxTree.GetNodeAt(location); + + if (stmt != null && stmt.SemicolonToken.IsNull) { + var insertionOffset = document.GetOffset(stmt.EndLocation); + document.Insert(insertionOffset, ";"); + newOffset = insertionOffset + 1; + return true; + } + return false; + } + } + + class ThrowStatementCompleter : ConstructCompleter + { + public override bool TryFix(ConstructFixer fixer, SyntaxTree syntaxTree, IDocument document, TextLocation location, ref int newOffset) + { + var stmt = syntaxTree.GetNodeAt(location); + + if (stmt != null && stmt.SemicolonToken.IsNull) { + var insertionOffset = document.GetOffset(stmt.EndLocation); + document.Insert(insertionOffset, ";"); + newOffset = insertionOffset + 1; + return true; + } + return false; + } + } + + + public class ConstructFixer + { + static readonly ConstructCompleter[] completer = { + new TypeDeclarationCompleter(), + new DelegateDeclarationCompleter (), + new MethodDeclarationCompleter (), + new IfStatementCompleter (), + new ForeachStatementCompleter (), + new WhileStatementCompleter (), + new LockStatementCompleter (), + new FixedStatementCompleter (), + new DoWhileStatementCompleter (), + new SwitchStatementCompleter (), + new BreakStatementCompleter (), + new ThrowStatementCompleter (), + new ReturnStatementCompleter (), + new YieldReturnStatementCompleter (), + new CheckedStatementCompleter (), + new UncheckedStatementCompleter (), + + new InvocationCompleter (), + new ExpressionStatementCompleter () + }; + + readonly CSharpFormattingOptions options; + readonly TextEditorOptions textEditorOptions; + + public CSharpFormattingOptions Options { + get { + return options; + } + } + + public ConstructFixer(CSharpFormattingOptions options, TextEditorOptions textEditorOptions) + { + this.options = options; + this.textEditorOptions = textEditorOptions; + } + + + string GetIndent(AstNode node) + { + if (node == null || node is SyntaxTree) + return ""; + if (node is BlockStatement || node is TypeDeclaration || node is NamespaceDeclaration) + return "\t" + GetIndent(node.Parent); + return GetIndent(node.Parent); + } + + internal string GenerateBody(AstNode node, BraceStyle braceStyle, bool addClosingBracket, ref int newOffset) + { + StringBuilder result = new StringBuilder(); + if (addClosingBracket) + result.Append(")"); + var nodeIndent = GetIndent(node.Parent); + switch (braceStyle) { + case BraceStyle.DoNotChange: + case BraceStyle.BannerStyle: + case BraceStyle.EndOfLine: + result.Append(" "); + result.Append("{"); + result.Append(textEditorOptions.EolMarker); + result.Append(nodeIndent + "\t"); + break; + case BraceStyle.EndOfLineWithoutSpace: + result.Append("{"); + result.Append(textEditorOptions.EolMarker); + result.Append(nodeIndent + "\t"); + break; + case BraceStyle.NextLine: + result.Append(textEditorOptions.EolMarker); + result.Append(nodeIndent); + result.Append("{"); + result.Append(textEditorOptions.EolMarker); + result.Append(nodeIndent + "\t"); + break; + case BraceStyle.NextLineShifted: + result.Append(textEditorOptions.EolMarker); + result.Append(nodeIndent + "\t"); + result.Append("{"); + result.Append(textEditorOptions.EolMarker); + result.Append(nodeIndent + "\t"); + break; + case BraceStyle.NextLineShifted2: + result.Append(textEditorOptions.EolMarker); + result.Append(nodeIndent + "\t"); + result.Append("{"); + result.Append(textEditorOptions.EolMarker); + result.Append(nodeIndent + "\t" + "\t"); + break; + } + + newOffset += result.Length; + result.Append(textEditorOptions.EolMarker); + result.Append(nodeIndent); + result.Append("}"); + + return result.ToString(); + } + + public bool TryFix (IDocument document, int offset, out int newOffset) + { + newOffset = offset; + + var syntaxTree = SyntaxTree.Parse(document, "a.cs"); + var location = document.GetLocation(offset - 1); + foreach (var c in completer) { + if (c.TryFix(this, syntaxTree, document, location, ref newOffset)) { + return true; + } + } + return false; + } + } +} + diff --git a/NRefactory/ICSharpCode.NRefactory.CSharp/Formatter/FormattingChanges.cs b/NRefactory/ICSharpCode.NRefactory.CSharp/Formatter/FormattingChanges.cs new file mode 100644 index 000000000..f60b58bbd --- /dev/null +++ b/NRefactory/ICSharpCode.NRefactory.CSharp/Formatter/FormattingChanges.cs @@ -0,0 +1,169 @@ +// +// CSharpFormatter.cs +// +// Author: +// Mike Krüger +// +// Copyright (c) 2013 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.Threading; +using System.Linq; +using ICSharpCode.NRefactory.CSharp.Refactoring; +using ICSharpCode.NRefactory.TypeSystem; +using System.Collections.Generic; + +namespace ICSharpCode.NRefactory.CSharp +{ + /// + /// The formatting changes are used to format a specific region inside a document and apply a minimal formatting + /// changeset to a given document. This is useful for a text editor environment. + /// + public class FormattingChanges + { + readonly IDocument document; + readonly internal List changes = new List (); + + internal FormattingChanges (IDocument document) + { + if (document == null) + throw new ArgumentNullException("document"); + this.document = document; + } + + public int Count { + get { + return changes.Count; + } + } + + /// + /// Applies the changes to the input document. + /// + public void ApplyChanges() + { + ApplyChanges(0, document.TextLength, document.Replace, (o, l, v) => document.GetText(o, l) == v); + } + + public void ApplyChanges(int startOffset, int length) + { + ApplyChanges(startOffset, length, document.Replace, (o, l, v) => document.GetText(o, l) == v); + } + + /// + /// Applies the changes to the given Script instance. + /// + public void ApplyChanges(Script script) + { + ApplyChanges(0, document.TextLength, script.Replace); + } + + public void ApplyChanges(int startOffset, int length, Script script) + { + ApplyChanges(startOffset, length, script.Replace); + } + + public void ApplyChanges(int startOffset, int length, Action documentReplace, Func filter = null) + { + int endOffset = startOffset + length; + // Console.WriteLine ("apply:"+ startOffset + "->" + endOffset); + // Console.WriteLine (document.Text.Substring (0, startOffset) + new string ('x',length) + document.Text.Substring (startOffset+ length)); + + TextReplaceAction previousChange = null; + int delta = 0; + var depChanges = new List (); + foreach (var change in changes.OrderBy(c => c.Offset)) { + if (previousChange != null) { + if (change.Equals(previousChange)) { + // ignore duplicate changes + continue; + } + if (change.Offset < previousChange.Offset + previousChange.RemovalLength) { + throw new InvalidOperationException ("Detected overlapping changes " + change + "/" + previousChange); + } + } + previousChange = change; + bool skipChange = change.Offset + change.RemovalLength < startOffset || change.Offset > endOffset; + skipChange |= filter != null && filter(change.Offset + delta, change.RemovalLength, change.NewText); + skipChange &= !depChanges.Contains(change); + if (!skipChange) { + documentReplace(change.Offset + delta, change.RemovalLength, change.NewText); + delta += change.NewText.Length - change.RemovalLength; + if (change.DependsOn != null) { + depChanges.Add(change.DependsOn); + } + } + } + changes.Clear(); + } + + internal TextReplaceAction AddChange(int offset, int removedChars, string insertedText) + { + if (offset < 0) + throw new ArgumentOutOfRangeException("offset", "Should be >= 0"); + if (offset >= document.TextLength) + throw new ArgumentOutOfRangeException("offset", "Should be < document.TextLength"); + if (removedChars < 0) + throw new ArgumentOutOfRangeException("removedChars", "Should be >= 0"); + if (removedChars > offset + document.TextLength) + throw new ArgumentOutOfRangeException("removedChars", "Tried to remove beyond end of text"); + if (removedChars == 0 && string.IsNullOrEmpty (insertedText)) + return null; + var action = new TextReplaceAction (offset, removedChars, insertedText); + changes.Add(action); + return action; + } + + internal sealed class TextReplaceAction + { + internal readonly int Offset; + internal readonly int RemovalLength; + internal readonly string NewText; + internal TextReplaceAction DependsOn; + + public TextReplaceAction (int offset, int removalLength, string newText) + { + this.Offset = offset; + this.RemovalLength = removalLength; + this.NewText = newText ?? string.Empty; + } + + public override bool Equals(object obj) + { + TextReplaceAction other = obj as TextReplaceAction; + if (other == null) { + return false; + } + return this.Offset == other.Offset && this.RemovalLength == other.RemovalLength && this.NewText == other.NewText; + } + + public override int GetHashCode() + { + return 0; + } + + public override string ToString() + { + return string.Format("[TextReplaceAction: Offset={0}, RemovalLength={1}, NewText={2}]", Offset, RemovalLength, NewText); + } + } + } +} diff --git a/NRefactory/ICSharpCode.NRefactory.CSharp/Formatter/FormattingOptionsFactory.cs b/NRefactory/ICSharpCode.NRefactory.CSharp/Formatter/FormattingOptionsFactory.cs index 354d5865f..ff32c1f8c 100644 --- a/NRefactory/ICSharpCode.NRefactory.CSharp/Formatter/FormattingOptionsFactory.cs +++ b/NRefactory/ICSharpCode.NRefactory.CSharp/Formatter/FormattingOptionsFactory.cs @@ -1,4 +1,4 @@ -// +// // FormattingOptionsFactory.cs // // Author: @@ -43,9 +43,9 @@ namespace ICSharpCode.NRefactory.CSharp /// /// Creates mono indent style CSharpFormatting options. /// - public static CSharpFormattingOptions CreateMono () + public static CSharpFormattingOptions CreateMono() { - return new CSharpFormattingOptions () { + return new CSharpFormattingOptions { IndentNamespaceBody = true, IndentClassBody = true, IndentInterfaceBody = true, @@ -58,6 +58,8 @@ namespace ICSharpCode.NRefactory.CSharp IndentSwitchBody = false, IndentCaseBody = true, IndentBreakStatements = true, + IndentPreprocessorDirectives = true, + IndentBlocksInsideExpressions = false, NamespaceBraceStyle = BraceStyle.NextLine, ClassBraceStyle = BraceStyle.NextLine, InterfaceBraceStyle = BraceStyle.NextLine, @@ -71,9 +73,9 @@ namespace ICSharpCode.NRefactory.CSharp PropertyBraceStyle = BraceStyle.EndOfLine, PropertyGetBraceStyle = BraceStyle.EndOfLine, PropertySetBraceStyle = BraceStyle.EndOfLine, - AllowPropertyGetBlockInline = true, - AllowPropertySetBlockInline = true, - + SimpleGetBlockFormatting = PropertyFormatting.AllowOneLine, + SimpleSetBlockFormatting = PropertyFormatting.AllowOneLine, + EventBraceStyle = BraceStyle.EndOfLine, EventAddBraceStyle = BraceStyle.EndOfLine, EventRemoveBraceStyle = BraceStyle.EndOfLine, @@ -82,12 +84,14 @@ namespace ICSharpCode.NRefactory.CSharp StatementBraceStyle = BraceStyle.EndOfLine, ElseNewLinePlacement = NewLinePlacement.SameLine, + ElseIfNewLinePlacement = NewLinePlacement.SameLine, CatchNewLinePlacement = NewLinePlacement.SameLine, FinallyNewLinePlacement = NewLinePlacement.SameLine, WhileNewLinePlacement = NewLinePlacement.SameLine, ArrayInitializerWrapping = Wrapping.WrapIfTooLong, ArrayInitializerBraceStyle = BraceStyle.EndOfLine, - + AllowOneLinedArrayInitialziers = true, + SpaceBeforeMethodCallParentheses = true, SpaceBeforeMethodDeclarationParentheses = true, SpaceBeforeConstructorDeclarationParentheses = true, @@ -147,9 +151,10 @@ namespace ICSharpCode.NRefactory.CSharp SpaceAfterForSemicolon = true, SpaceAfterTypecast = false, - AlignEmbeddedIfStatements = true, - AlignEmbeddedUsingStatements = true, - PropertyFormatting = PropertyFormatting.AllowOneLine, + AlignEmbeddedStatements = true, + SimplePropertyFormatting = PropertyFormatting.AllowOneLine, + AutoPropertyFormatting = PropertyFormatting.AllowOneLine, + EmptyLineFormatting = EmptyLineFormatting.DoNotIndent, SpaceBeforeMethodDeclarationParameterComma = false, SpaceAfterMethodDeclarationParameterComma = true, SpaceAfterDelegateDeclarationParameterComma = true, @@ -162,35 +167,36 @@ namespace ICSharpCode.NRefactory.CSharp SpaceWithinIndexerDeclarationBracket = false, SpaceBeforeIndexerDeclarationParameterComma = false, SpaceInNamedArgumentAfterDoubleColon = true, + RemoveEndOfLineWhiteSpace = true, SpaceAfterIndexerDeclarationParameterComma = true, - BlankLinesBeforeUsings = 0, - BlankLinesAfterUsings = 1, + MinimumBlankLinesBeforeUsings = 0, + MinimumBlankLinesAfterUsings = 1, + UsingPlacement = UsingPlacement.TopOfFile, - - BlankLinesBeforeFirstDeclaration = 0, - BlankLinesBetweenTypes = 1, - BlankLinesBetweenFields = 0, - BlankLinesBetweenEventFields = 0, - BlankLinesBetweenMembers = 1, - + MinimumBlankLinesBeforeFirstDeclaration = 0, + MinimumBlankLinesBetweenTypes = 1, + MinimumBlankLinesBetweenFields = 0, + MinimumBlankLinesBetweenEventFields = 0, + MinimumBlankLinesBetweenMembers = 1, + MinimumBlankLinesAroundRegion = 1, + MinimumBlankLinesInsideRegion = 1, + AlignToFirstIndexerArgument = false, + AlignToFirstIndexerDeclarationParameter = true, + AlignToFirstMethodCallArgument = false, + AlignToFirstMethodDeclarationParameter = true, KeepCommentsAtFirstColumn = true, ChainedMethodCallWrapping = Wrapping.DoNotChange, MethodCallArgumentWrapping = Wrapping.DoNotChange, - NewLineAferMethodCallOpenParentheses = true, - MethodCallClosingParenthesesOnNewLine = true, + NewLineAferMethodCallOpenParentheses = NewLinePlacement.DoNotCare, + MethodCallClosingParenthesesOnNewLine = NewLinePlacement.DoNotCare, IndexerArgumentWrapping = Wrapping.DoNotChange, - NewLineAferIndexerOpenBracket = false, - IndexerClosingBracketOnNewLine = false, + NewLineAferIndexerOpenBracket = NewLinePlacement.DoNotCare, + IndexerClosingBracketOnNewLine = NewLinePlacement.DoNotCare, - IfElseBraceForcement = BraceForcement.DoNotChange, - ForBraceForcement = BraceForcement.DoNotChange, - ForEachBraceForcement = BraceForcement.DoNotChange, - WhileBraceForcement = BraceForcement.DoNotChange, - UsingBraceForcement = BraceForcement.DoNotChange, - FixedBraceForcement = BraceForcement.DoNotChange + NewLineBeforeNewQueryClause = NewLinePlacement.NewLine }; } @@ -200,12 +206,6 @@ namespace ICSharpCode.NRefactory.CSharp public static CSharpFormattingOptions CreateSharpDevelop() { 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; } @@ -213,9 +213,9 @@ namespace ICSharpCode.NRefactory.CSharp /// 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. /// - public static CSharpFormattingOptions CreateKRStyle () + public static CSharpFormattingOptions CreateKRStyle() { - return new CSharpFormattingOptions () { + return new CSharpFormattingOptions() { IndentNamespaceBody = true, IndentClassBody = true, IndentInterfaceBody = true, @@ -228,7 +228,7 @@ namespace ICSharpCode.NRefactory.CSharp IndentSwitchBody = true, IndentCaseBody = true, IndentBreakStatements = true, - + IndentPreprocessorDirectives = true, NamespaceBraceStyle = BraceStyle.NextLine, ClassBraceStyle = BraceStyle.NextLine, InterfaceBraceStyle = BraceStyle.NextLine, @@ -241,8 +241,8 @@ namespace ICSharpCode.NRefactory.CSharp PropertyBraceStyle = BraceStyle.EndOfLine, PropertyGetBraceStyle = BraceStyle.EndOfLine, PropertySetBraceStyle = BraceStyle.EndOfLine, - AllowPropertyGetBlockInline = true, - AllowPropertySetBlockInline = true, + SimpleGetBlockFormatting = PropertyFormatting.AllowOneLine, + SimpleSetBlockFormatting = PropertyFormatting.AllowOneLine, EventBraceStyle = BraceStyle.EndOfLine, EventAddBraceStyle = BraceStyle.EndOfLine, @@ -252,6 +252,7 @@ namespace ICSharpCode.NRefactory.CSharp StatementBraceStyle = BraceStyle.EndOfLine, ElseNewLinePlacement = NewLinePlacement.SameLine, + ElseIfNewLinePlacement = NewLinePlacement.SameLine, CatchNewLinePlacement = NewLinePlacement.SameLine, FinallyNewLinePlacement = NewLinePlacement.SameLine, WhileNewLinePlacement = NewLinePlacement.SameLine, @@ -262,8 +263,11 @@ namespace ICSharpCode.NRefactory.CSharp SpaceBeforeMethodDeclarationParentheses = false, SpaceBeforeConstructorDeclarationParentheses = false, SpaceBeforeDelegateDeclarationParentheses = false, + SpaceBeforeIndexerDeclarationBracket = false, SpaceAfterMethodCallParameterComma = true, SpaceAfterConstructorDeclarationParameterComma = true, + NewLineBeforeConstructorInitializerColon = NewLinePlacement.NewLine, + NewLineAfterConstructorInitializerColon = NewLinePlacement.SameLine, SpaceBeforeNewParentheses = false, SpacesWithinNewParentheses = false, @@ -308,9 +312,10 @@ namespace ICSharpCode.NRefactory.CSharp SpaceAfterConditionalOperatorCondition = true, SpaceBeforeConditionalOperatorSeparator = true, SpaceAfterConditionalOperatorSeparator = true, - + SpaceBeforeArrayDeclarationBrackets = false, + SpacesWithinBrackets = false, - SpacesBeforeBrackets = true, + SpacesBeforeBrackets = false, SpaceBeforeBracketComma = false, SpaceAfterBracketComma = true, @@ -318,9 +323,10 @@ namespace ICSharpCode.NRefactory.CSharp SpaceAfterForSemicolon = true, SpaceAfterTypecast = false, - AlignEmbeddedIfStatements = true, - AlignEmbeddedUsingStatements = true, - PropertyFormatting = PropertyFormatting.AllowOneLine, + AlignEmbeddedStatements = true, + SimplePropertyFormatting = PropertyFormatting.AllowOneLine, + AutoPropertyFormatting = PropertyFormatting.AllowOneLine, + EmptyLineFormatting = EmptyLineFormatting.DoNotIndent, SpaceBeforeMethodDeclarationParameterComma = false, SpaceAfterMethodDeclarationParameterComma = true, SpaceAfterDelegateDeclarationParameterComma = true, @@ -329,38 +335,35 @@ namespace ICSharpCode.NRefactory.CSharp SpaceBeforeLocalVariableDeclarationComma = false, SpaceAfterLocalVariableDeclarationComma = true, - SpaceBeforeIndexerDeclarationBracket = true, SpaceWithinIndexerDeclarationBracket = false, SpaceBeforeIndexerDeclarationParameterComma = false, SpaceInNamedArgumentAfterDoubleColon = true, SpaceAfterIndexerDeclarationParameterComma = true, + RemoveEndOfLineWhiteSpace = true, - BlankLinesBeforeUsings = 0, - BlankLinesAfterUsings = 1, + MinimumBlankLinesBeforeUsings = 0, + MinimumBlankLinesAfterUsings = 1, - BlankLinesBeforeFirstDeclaration = 0, - BlankLinesBetweenTypes = 1, - BlankLinesBetweenFields = 0, - BlankLinesBetweenEventFields = 0, - BlankLinesBetweenMembers = 1, + MinimumBlankLinesBeforeFirstDeclaration = 0, + MinimumBlankLinesBetweenTypes = 1, + MinimumBlankLinesBetweenFields = 0, + MinimumBlankLinesBetweenEventFields = 0, + MinimumBlankLinesBetweenMembers = 1, + MinimumBlankLinesAroundRegion = 1, + MinimumBlankLinesInsideRegion = 1, KeepCommentsAtFirstColumn = true, ChainedMethodCallWrapping = Wrapping.DoNotChange, MethodCallArgumentWrapping = Wrapping.DoNotChange, - NewLineAferMethodCallOpenParentheses = true, - MethodCallClosingParenthesesOnNewLine = true, + NewLineAferMethodCallOpenParentheses = NewLinePlacement.DoNotCare, + MethodCallClosingParenthesesOnNewLine = NewLinePlacement.DoNotCare, IndexerArgumentWrapping = Wrapping.DoNotChange, - NewLineAferIndexerOpenBracket = false, - IndexerClosingBracketOnNewLine = false, + NewLineAferIndexerOpenBracket = NewLinePlacement.DoNotCare, + IndexerClosingBracketOnNewLine = NewLinePlacement.DoNotCare, - IfElseBraceForcement = BraceForcement.DoNotChange, - ForBraceForcement = BraceForcement.DoNotChange, - ForEachBraceForcement = BraceForcement.DoNotChange, - WhileBraceForcement = BraceForcement.DoNotChange, - UsingBraceForcement = BraceForcement.DoNotChange, - FixedBraceForcement = BraceForcement.DoNotChange + NewLineBeforeNewQueryClause = NewLinePlacement.NewLine }; } @@ -380,9 +383,19 @@ namespace ICSharpCode.NRefactory.CSharp baseOptions.EventRemoveBraceStyle = BraceStyle.NextLine; baseOptions.StatementBraceStyle = BraceStyle.NextLine; baseOptions.ArrayInitializerBraceStyle = BraceStyle.NextLine; + + baseOptions.CatchNewLinePlacement = NewLinePlacement.NewLine; + baseOptions.ElseNewLinePlacement = NewLinePlacement.NewLine; + baseOptions.ElseIfNewLinePlacement = NewLinePlacement.SameLine; + + baseOptions.FinallyNewLinePlacement = NewLinePlacement.NewLine; + baseOptions.WhileNewLinePlacement = NewLinePlacement.DoNotCare; + baseOptions.ArrayInitializerWrapping = Wrapping.DoNotChange; + baseOptions.IndentBlocksInsideExpressions = true; + return baseOptions; } - + /// /// 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. /// @@ -407,6 +420,7 @@ namespace ICSharpCode.NRefactory.CSharp baseOptions.EventAddBraceStyle = BraceStyle.NextLineShifted; baseOptions.EventRemoveBraceStyle = BraceStyle.NextLineShifted; baseOptions.StatementBraceStyle = BraceStyle.NextLineShifted; + baseOptions.IndentBlocksInsideExpressions = true; return baseOptions; } @@ -427,7 +441,6 @@ namespace ICSharpCode.NRefactory.CSharp baseOptions.StatementBraceStyle = BraceStyle.NextLineShifted2; return baseOptions; } - } } diff --git a/NRefactory/ICSharpCode.NRefactory.CSharp/Formatter/FormattingVisitor.cs b/NRefactory/ICSharpCode.NRefactory.CSharp/Formatter/FormattingVisitor.cs new file mode 100644 index 000000000..2a445a596 --- /dev/null +++ b/NRefactory/ICSharpCode.NRefactory.CSharp/Formatter/FormattingVisitor.cs @@ -0,0 +1,661 @@ +// +// FormattingVisitor.cs +// +// Author: +// Mike Krüger +// +// Copyright (c) 2010 Novell, Inc (http://www.novell.com) +// Copyright (c) 2013 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 System.Text; +using System.Linq; +using ICSharpCode.NRefactory.Editor; +using ICSharpCode.NRefactory.TypeSystem; +using System.Threading; +using System.Collections.Generic; +using ICSharpCode.NRefactory.Utils; + +namespace ICSharpCode.NRefactory.CSharp +{ + [Obsolete("This class was replaced by CSharpFormatter.")] + public class AstFormattingVisitor {} + + partial class FormattingVisitor + { + readonly CSharpFormatter formatter; + readonly FormattingChanges changes; + readonly IDocument document; + readonly CancellationToken token; + + Indent curIndent; + + public bool HadErrors { + get; + set; + } + + + CSharpFormattingOptions policy { + get { + return formatter.Policy; + } + } + + TextEditorOptions options { + get { + return formatter.TextEditorOptions; + } + } + + FormattingChanges.TextReplaceAction AddChange(int offset, int removedChars, string insertedText) + { + return changes.AddChange(offset, removedChars, insertedText); + } + + public FormattingVisitor(CSharpFormatter formatter, IDocument document, FormattingChanges changes, CancellationToken token) + { + if (formatter == null) + throw new ArgumentNullException("formatter"); + if (document == null) + throw new ArgumentNullException("document"); + if (changes == null) + throw new ArgumentNullException("changes"); + + this.formatter = formatter; + this.changes = changes; + this.document = document; + this.token = token; + + curIndent = new Indent(formatter.TextEditorOptions); + } + + void VisitChildrenToFormat (AstNode parent, Action callback) + { + AstNode next; + for (var child = parent.FirstChild; child != null; child = next) { + token.ThrowIfCancellationRequested(); + // Store next to allow the loop to continue + // if the visitor removes/replaces child. + next = child.GetNextSibling(NoWhitespacePredicate); + + if (formatter.FormattingRegions.Count > 0) { + if (formatter.FormattingRegions.Any(r => r.IsInside(child.StartLocation) || r.IsInside(child.EndLocation))) { + callback(child); + } else { + var childRegion = child.Region; + if (formatter.FormattingRegions.Any(r => childRegion.IsInside(r.Begin) || childRegion.IsInside(r.End))) + callback(child); + } + if (child.StartLocation > formatter.lastFormattingLocation) + break; + } else { + callback(child); + } + } + } + + protected override void VisitChildren (AstNode node) + { + VisitChildrenToFormat (node, n => n.AcceptVisitor (this)); + } + + #region NewLines + + void AdjustNewLineBlock(AstNode startNode, int targetMinimumNewLineCount) + { + var indentString = policy.EmptyLineFormatting == EmptyLineFormatting.Indent ? curIndent.IndentString : ""; + + TextLocation newLineInsertPosition = startNode.EndLocation; + var node = startNode.NextSibling; + int currentNewLineCount = 0; + // Check the existing newlines + for (; currentNewLineCount < targetMinimumNewLineCount; node = node.NextSibling) { + if (node is WhitespaceNode) + continue; + if (!(node is NewLineNode)) + break; + newLineInsertPosition = node.EndLocation; + currentNewLineCount++; + if (policy.EmptyLineFormatting == EmptyLineFormatting.DoNotChange) { + if (node.NextSibling == null) + // end of file/block etc, nothing more to do but break before assigning null to node + break; + continue; + } + var isBlankLine = IsSpacing(document.GetLineByNumber(node.StartLocation.Line)); + if (!isBlankLine) { + // remove EOL whitespace if appropriate + if (policy.RemoveEndOfLineWhiteSpace) { + var offset = document.GetOffset(node.StartLocation); + var start = SearchWhitespaceStart(offset); + if (start != offset) + AddChange(start, offset - start, null); + } + } else { + var actualIndent = GetIndentation(node.StartLocation.Line); + if (actualIndent != indentString) { + var start = document.GetOffset(new TextLocation(node.StartLocation.Line, 0)); + AddChange(start, actualIndent.Length, indentString); + } + } + if (node.NextSibling == null) + // end of file/block etc, nothing more to do but break before assigning null to node + break; + } + if (currentNewLineCount < targetMinimumNewLineCount) { + // We need to add more newlines + var builder = new StringBuilder(); + for (; currentNewLineCount < targetMinimumNewLineCount; currentNewLineCount++) { + if (currentNewLineCount > 0) + // Don't indent the first line in the block since that is not an empty line. + builder.Append(indentString); + builder.Append(options.EolMarker); + } + var offset = document.GetOffset(newLineInsertPosition); + AddChange(offset, 0, builder.ToString()); + } else if (currentNewLineCount == targetMinimumNewLineCount && node is NewLineNode){ +// // Check to see if there are any newlines to remove +// var endNode = node.GetNextSibling(n => !(n is NewLineNode || n is WhitespaceNode)); +// if (endNode != null) { +// var startOffset = document.GetOffset(newLineInsertPosition); +// var endOffset = document.GetOffset(new TextLocation(endNode.StartLocation.Line, 0)); +// EnsureText(startOffset, endOffset, null); +// } + } + } + + public void EnsureMinimumNewLinesAfter(AstNode node, int blankLines) + { + if (node is PreProcessorDirective) { + var directive = (PreProcessorDirective)node; + if (directive.Type == PreProcessorDirectiveType.Pragma) + return; + } + if (blankLines < 0) + return; + if (formatter.FormattingMode != FormattingMode.Intrusive) + blankLines = Math.Min(1, blankLines); + AdjustNewLineBlock(node, blankLines); + } + + public void EnsureMinimumBlankLinesBefore(AstNode node, int blankLines) + { + if (formatter.FormattingMode != FormattingMode.Intrusive) + return; + var loc = node.StartLocation; + int line = loc.Line; + do { + line--; + } while (line > 0 && IsSpacing(document.GetLineByNumber(line))); + if (line > 0 && !IsSpacing(document.GetLineByNumber(line))) + line++; + + if (loc.Line - line >= blankLines) + return; + + var sb = new StringBuilder (); + for (int i = 0; i < blankLines; i++) + sb.Append(options.EolMarker); + int end = document.GetOffset(loc.Line, 1); + if (loc.Line == line) { + AddChange(end, 0, sb.ToString()); + return; + } + if (line + 1 > document.LineCount) + return; + int start = document.GetOffset(line + 1, 1); + if (end - start <= 0 && sb.Length == 0) + return; + AddChange(start, end - start, sb.ToString()); + } + + #endregion + + bool IsSimpleAccessor(Accessor accessor) + { + if (accessor.IsNull || accessor.Body.IsNull || accessor.Body.FirstChild == null) { + return true; + } + var firstStatement = accessor.Body.Statements.FirstOrDefault(); + if (firstStatement == null) + return true; + + if (!(firstStatement is ReturnStatement || firstStatement is ExpressionStatement|| firstStatement is EmptyStatement || firstStatement is ThrowStatement)) + return false; + + if (firstStatement.GetNextSibling(s => s.Role == BlockStatement.StatementRole) != null) + return false; + + return !(accessor.Body.Statements.FirstOrDefault() is BlockStatement); + } + + static bool IsSpacing(char ch) + { + return ch == ' ' || ch == '\t'; + } + + bool IsSpacing(ISegment segment) + { + int endOffset = segment.EndOffset; + for (int i = segment.Offset; i < endOffset; i++) { + if (!IsSpacing(document.GetCharAt(i))) { + return false; + } + } + return true; + } + + int SearchLastNonWsChar(int startOffset, int endOffset) + { + startOffset = Math.Max(0, startOffset); + endOffset = Math.Max(startOffset, endOffset); + if (startOffset >= endOffset) { + return startOffset; + } + int result = -1; + bool inComment = false; + + for (int i = startOffset; i < endOffset && i < document.TextLength; i++) { + char ch = document.GetCharAt(i); + if (IsSpacing(ch)) { + continue; + } + if (ch == '/' && i + 1 < document.TextLength && document.GetCharAt(i + 1) == '/') { + return result; + } + if (ch == '/' && i + 1 < document.TextLength && document.GetCharAt(i + 1) == '*') { + inComment = true; + i++; + continue; + } + if (inComment && ch == '*' && i + 1 < document.TextLength && document.GetCharAt(i + 1) == '/') { + inComment = false; + i++; + continue; + } + if (!inComment) { + result = i; + } + } + return result; + } + + void ForceSpace(int startOffset, int endOffset, bool forceSpace) + { + int lastNonWs = SearchLastNonWsChar(startOffset, endOffset); + if (lastNonWs < 0) + return; + + var spaceCount = Math.Max(0, endOffset - lastNonWs - 1); + if (forceSpace) { + if (spaceCount != 1) { + // Here we could technically remove spaceCount - 1 chars instead + // and skip replacing that with new space, but we want to trigger the + // overlap detection if this space is changed again for some reason + AddChange(lastNonWs + 1, spaceCount, " "); + } + } else if (spaceCount > 0 && !forceSpace) { + AddChange(lastNonWs + 1, spaceCount, ""); + } + } + + void ForceSpacesAfter(AstNode n, bool forceSpaces) + { + if (n == null) { + return; + } + TextLocation location = n.EndLocation; + int offset = document.GetOffset(location); + if (location.Column > document.GetLineByNumber(location.Line).Length) { + return; + } + int i = offset; + while (i < document.TextLength && IsSpacing (document.GetCharAt (i))) { + i++; + } + ForceSpace(offset - 1, i, forceSpaces); + } + + int ForceSpacesBefore(AstNode n, bool forceSpaces) + { + if (n == null || n.IsNull) { + return 0; + } + TextLocation location = n.StartLocation; + // respect manual line breaks. + if (location.Column <= 1 || GetIndentation(location.Line).Length == location.Column - 1) { + return 0; + } + + int offset = document.GetOffset(location); + int i = offset - 1; + while (i >= 0 && IsSpacing (document.GetCharAt (i))) { + i--; + } + ForceSpace(i, offset, forceSpaces); + return i; + } + + int ForceSpacesBeforeRemoveNewLines(AstNode n, bool forceSpace = true) + { + if (n == null || n.IsNull) { + return 0; + } + int offset = document.GetOffset(n.StartLocation); + int i = offset - 1; + while (i >= 0) { + char ch = document.GetCharAt(i); + if (!IsSpacing(ch) && ch != '\r' && ch != '\n') + break; + i--; + } + var length = Math.Max(0, (offset - 1) - i); + AddChange(i + 1, length, forceSpace ? " " : ""); + return i; + } + + internal static bool NoWhitespacePredicate(AstNode arg) + { + return !(arg is NewLineNode || arg is WhitespaceNode); + } + + static bool IsMember(AstNode nextSibling) + { + return nextSibling != null && nextSibling.NodeType == NodeType.Member; + } + + static bool ShouldBreakLine(NewLinePlacement placement, CSharpTokenNode token) + { + if (placement == NewLinePlacement.NewLine) + return true; + if (placement == NewLinePlacement.SameLine) + return false; + if (token.IsNull) + return false; + var prevMeaningfulNode = token.GetPrevNode (n =>n.Role !=Roles.NewLine && n.Role != Roles.Whitespace && n.Role !=Roles.Comment); + return prevMeaningfulNode.EndLocation.Line != token.StartLocation.Line; + } + + void ForceSpaceBefore(AstNode node, bool forceSpace) + { + var offset = document.GetOffset(node.StartLocation); + int end = offset; + // ForceSpace inserts a space one char after start in the case of a missing space + // Therefore, make sure that start < offset by starting at offset - 1 + int start = SearchWhitespaceStart(offset - 1); + ForceSpace(start, end, forceSpace); + } + + public void FixSemicolon(CSharpTokenNode semicolon) + { + if (semicolon.IsNull) + return; + int endOffset = document.GetOffset(semicolon.StartLocation); + int offset = endOffset; + while (offset - 1 > 0 && char.IsWhiteSpace (document.GetCharAt (offset - 1))) { + offset--; + } + if (policy.SpaceBeforeSemicolon) { + AddChange(offset, endOffset - offset, " "); + } else { + if (offset < endOffset) + AddChange(offset, endOffset - offset, null); + } + } + + void PlaceOnNewLine(NewLinePlacement newLine, AstNode keywordNode) + { + if (keywordNode == null || keywordNode.StartLocation.IsEmpty) + return; + + var prev = keywordNode.GetPrevNode (NoWhitespacePredicate); + if (prev is Comment || prev is PreProcessorDirective) + return; + + if (newLine == NewLinePlacement.DoNotCare) + newLine = prev.EndLocation.Line == keywordNode.StartLocation.Line ? NewLinePlacement.SameLine : NewLinePlacement.NewLine; + + int offset = document.GetOffset(keywordNode.StartLocation); + + int whitespaceStart = SearchWhitespaceStart(offset); + string indentString = newLine == NewLinePlacement.NewLine ? options.EolMarker + curIndent.IndentString : " "; + AddChange(whitespaceStart, offset - whitespaceStart, indentString); + } + + string nextStatementIndent; + + void FixStatementIndentation(TextLocation location) + { + if (location.Line < 1 || location.Column < 1) { + Console.WriteLine("invalid location!"); + return; + } + int offset = document.GetOffset(location); + if (offset <= 0) { + Console.WriteLine("possible wrong offset"); + Console.WriteLine(Environment.StackTrace); + return; + } + bool isEmpty = IsLineIsEmptyUpToEol(offset); + int lineStart = SearchWhitespaceLineStart(offset); + string indentString = nextStatementIndent ?? (isEmpty ? "" : options.EolMarker) + curIndent.IndentString; + nextStatementIndent = null; + EnsureText(lineStart, offset, indentString); + } + + void FixIndentation (AstNode node) + { + FixIndentation(node.StartLocation, 0); + } + + void FixIndentation(TextLocation location, int relOffset) + { + if (location.Line < 1 || location.Line > document.LineCount) { + Console.WriteLine("Invalid location " + location); + Console.WriteLine(Environment.StackTrace); + return; + } + + string lineIndent = GetIndentation(location.Line); + string indentString = curIndent.IndentString; + if (indentString != lineIndent && location.Column - 1 + relOffset == lineIndent.Length) { + AddChange(document.GetOffset(location.Line, 1), lineIndent.Length, indentString); + } + } + + void FixIndentationForceNewLine(AstNode node) + { + var directive = node as PreProcessorDirective; + if (node.GetPrevNode () is NewLineNode) { + if (directive != null && !policy.IndentPreprocessorDirectives) { + var startNode = node.GetPrevNode (); + var startOffset = document.GetOffset(startNode.EndLocation); + int endOffset = document.GetOffset(node.StartLocation); + AddChange(startOffset, endOffset - startOffset, ""); + return; + } else { + FixIndentation(node); + } + } else { + // if no new line preceeds an #endif directive it's excluded + if (directive != null) { + if (directive.Type == PreProcessorDirectiveType.Endif) + return; + } + var startNode = node.GetPrevSibling(n => !(n is WhitespaceNode)) ?? node; + var startOffset = document.GetOffset(startNode.EndLocation); + int endOffset = document.GetOffset(node.StartLocation); + if (startOffset >= endOffset) + return; + if (directive != null && !policy.IndentPreprocessorDirectives) { + AddChange(startOffset, endOffset - startOffset, ""); + return; + } + + AddChange(startOffset, endOffset - startOffset, curIndent.IndentString); + } + } + + string GetIndentation(int lineNumber) + { + var line = document.GetLineByNumber(lineNumber); + var b = new StringBuilder (); + int endOffset = line.EndOffset; + for (int i = line.Offset; i < endOffset; i++) { + char c = document.GetCharAt(i); + if (!IsSpacing(c)) { + break; + } + b.Append(c); + } + return b.ToString(); + } + + void EnsureText(int start, int end, string replacementText) + { + var length = end - start; + if (length == 0 && string.IsNullOrEmpty(replacementText)) + return; + if (replacementText == null || replacementText.Length != length) { + AddChange(start, length, replacementText); + return; + } + for (int i = 0; i < length; i++) { + if (document.GetCharAt(start + i) != replacementText[i]) { + AddChange(start, length, replacementText); + break; + } + } + } + + void FixOpenBrace(BraceStyle braceStyle, AstNode lbrace) + { + if (lbrace.IsNull) + return; + switch (braceStyle) { + case BraceStyle.DoNotChange: + return; + + case BraceStyle.BannerStyle: + case BraceStyle.EndOfLine: + var prev = lbrace.GetPrevNode (NoWhitespacePredicate); + if (prev is PreProcessorDirective) + return; + int prevOffset = document.GetOffset(prev.EndLocation); + + if (prev is Comment || prev is PreProcessorDirective) { + int next = document.GetOffset(lbrace.GetNextNode ().StartLocation); + EnsureText(prevOffset, next, ""); + while (prev is Comment || prev is PreProcessorDirective) + prev = prev.GetPrevNode(); + prevOffset = document.GetOffset(prev.EndLocation); + AddChange(prevOffset, 0, " {"); + } else { + int braceOffset2 = document.GetOffset(lbrace.StartLocation); + EnsureText(prevOffset, braceOffset2, " "); + } + break; + case BraceStyle.EndOfLineWithoutSpace: + prev = lbrace.GetPrevNode (NoWhitespacePredicate); + if (prev is PreProcessorDirective) + return; + prevOffset = document.GetOffset(prev.EndLocation); + int braceOffset = document.GetOffset(lbrace.StartLocation); + EnsureText(prevOffset, braceOffset, ""); + break; + + case BraceStyle.NextLine: + prev = lbrace.GetPrevNode (NoWhitespacePredicate); + if (prev is PreProcessorDirective) + return; + prevOffset = document.GetOffset(prev.EndLocation); + braceOffset = document.GetOffset(lbrace.StartLocation); + EnsureText(prevOffset, braceOffset, options.EolMarker + curIndent.IndentString); + break; + case BraceStyle.NextLineShifted: + prev = lbrace.GetPrevNode (NoWhitespacePredicate); + if (prev is PreProcessorDirective) + return; + prevOffset = document.GetOffset(prev.EndLocation); + braceOffset = document.GetOffset(lbrace.StartLocation); + curIndent.Push(IndentType.Block); + EnsureText(prevOffset, braceOffset, options.EolMarker + curIndent.IndentString); + curIndent.Pop(); + break; + case BraceStyle.NextLineShifted2: + prev = lbrace.GetPrevNode (NoWhitespacePredicate); + if (prev is PreProcessorDirective) + return; + prevOffset = document.GetOffset(prev.EndLocation); + braceOffset = document.GetOffset(lbrace.StartLocation); + curIndent.Push(IndentType.Block); + EnsureText(prevOffset, braceOffset, options.EolMarker + curIndent.IndentString); + curIndent.Pop(); + break; + } + } + + void CorrectClosingBrace (AstNode rbrace) + { + if (rbrace.IsNull) + return; + int braceOffset = document.GetOffset(rbrace.StartLocation); + var prevNode = rbrace.GetPrevNode(); + int prevNodeOffset = prevNode != null ? document.GetOffset(prevNode.EndLocation) : 0; + if (prevNode is NewLineNode) { + EnsureText(prevNodeOffset, braceOffset, curIndent.IndentString); + } else { + EnsureText(prevNodeOffset, braceOffset, options.EolMarker + curIndent.IndentString); + } + } + + void FixClosingBrace(BraceStyle braceStyle, AstNode rbrace) + { + if (rbrace.IsNull) + return; + switch (braceStyle) { + case BraceStyle.DoNotChange: + return; + + case BraceStyle.NextLineShifted: + case BraceStyle.BannerStyle: + curIndent.Push(IndentType.Block); + CorrectClosingBrace (rbrace); + curIndent.Pop (); + break; + case BraceStyle.EndOfLineWithoutSpace: + case BraceStyle.EndOfLine: + case BraceStyle.NextLine: + CorrectClosingBrace (rbrace); + break; + + case BraceStyle.NextLineShifted2: + curIndent.Push(IndentType.Block); + CorrectClosingBrace (rbrace); + curIndent.Pop (); + break; + } + + } + + } +} + diff --git a/NRefactory/ICSharpCode.NRefactory.CSharp/Formatter/FormattingVisitor_Expressions.cs b/NRefactory/ICSharpCode.NRefactory.CSharp/Formatter/FormattingVisitor_Expressions.cs new file mode 100644 index 000000000..582e26fea --- /dev/null +++ b/NRefactory/ICSharpCode.NRefactory.CSharp/Formatter/FormattingVisitor_Expressions.cs @@ -0,0 +1,735 @@ +// +// AstFormattingVisitor_Expressions.cs +// +// Author: +// Mike Krüger +// +// Copyright (c) 2013 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 System.Linq; +using System.Collections.Generic; + +namespace ICSharpCode.NRefactory.CSharp +{ + partial class FormattingVisitor : DepthFirstAstVisitor + { + public override void VisitComposedType(ComposedType composedType) + { + var spec = composedType.ArraySpecifiers.FirstOrDefault(); + if (spec != null) + ForceSpacesBefore(spec.LBracketToken, policy.SpaceBeforeArrayDeclarationBrackets); + + if (composedType.HasNullableSpecifier) + ForceSpacesBefore(composedType.NullableSpecifierToken, false); + + if (composedType.PointerRank > 0) + foreach (var token in composedType.PointerTokens) + ForceSpacesBefore(token, false); + + base.VisitComposedType(composedType); + } + + public override void VisitAnonymousMethodExpression(AnonymousMethodExpression lambdaExpression) + { + FormatArguments(lambdaExpression); + + if (!lambdaExpression.Body.IsNull) { + var old = curIndent; + this.curIndent = curIndent.GetIndentWithoutSpace (); + FixOpenBrace(policy.AnonymousMethodBraceStyle, lambdaExpression.Body.LBraceToken); + VisitBlockWithoutFixingBraces(lambdaExpression.Body, policy.IndentBlocks); + FixClosingBrace(policy.AnonymousMethodBraceStyle, lambdaExpression.Body.RBraceToken); + curIndent = old; + } + + } + + public override void VisitAssignmentExpression(AssignmentExpression assignmentExpression) + { + ForceSpacesAround(assignmentExpression.OperatorToken, policy.SpaceAroundAssignment); + base.VisitAssignmentExpression(assignmentExpression); + } + + public override void VisitBinaryOperatorExpression(BinaryOperatorExpression binaryOperatorExpression) + { + bool forceSpaces = false; + switch (binaryOperatorExpression.Operator) { + case BinaryOperatorType.Equality: + case BinaryOperatorType.InEquality: + forceSpaces = policy.SpaceAroundEqualityOperator; + break; + case BinaryOperatorType.GreaterThan: + case BinaryOperatorType.GreaterThanOrEqual: + case BinaryOperatorType.LessThan: + case BinaryOperatorType.LessThanOrEqual: + forceSpaces = policy.SpaceAroundRelationalOperator; + break; + case BinaryOperatorType.ConditionalAnd: + case BinaryOperatorType.ConditionalOr: + forceSpaces = policy.SpaceAroundLogicalOperator; + break; + case BinaryOperatorType.BitwiseAnd: + case BinaryOperatorType.BitwiseOr: + case BinaryOperatorType.ExclusiveOr: + forceSpaces = policy.SpaceAroundBitwiseOperator; + break; + case BinaryOperatorType.Add: + case BinaryOperatorType.Subtract: + forceSpaces = policy.SpaceAroundAdditiveOperator; + break; + case BinaryOperatorType.Multiply: + case BinaryOperatorType.Divide: + case BinaryOperatorType.Modulus: + forceSpaces = policy.SpaceAroundMultiplicativeOperator; + break; + case BinaryOperatorType.ShiftLeft: + case BinaryOperatorType.ShiftRight: + forceSpaces = policy.SpaceAroundShiftOperator; + break; + case BinaryOperatorType.NullCoalescing: + forceSpaces = policy.SpaceAroundNullCoalescingOperator; + break; + } + var opToken = binaryOperatorExpression.OperatorToken; + if (opToken.PrevSibling != null && opToken.PrevSibling.Role != Roles.NewLine) { + ForceSpacesBefore(opToken, forceSpaces); + } else { + ForceSpacesAfter(binaryOperatorExpression.Left, false); + FixIndentation(opToken); + } + ForceSpacesAfter(opToken, opToken.NextSibling != null && opToken.NextSibling.Role != Roles.NewLine && forceSpaces); + + binaryOperatorExpression.Left.AcceptVisitor(this); + // Handle line breaks in binary opeartor expression. + if (binaryOperatorExpression.Left.EndLocation.Line != binaryOperatorExpression.Right.StartLocation.Line) { + if (opToken.StartLocation.Line == binaryOperatorExpression.Right.StartLocation.Line) { + FixStatementIndentation(opToken.StartLocation); + } else { + FixStatementIndentation(binaryOperatorExpression.Right.StartLocation); + } + } + binaryOperatorExpression.Right.AcceptVisitor(this); + } + + public override void VisitConditionalExpression(ConditionalExpression conditionalExpression) + { + ForceSpacesBefore(conditionalExpression.QuestionMarkToken, policy.SpaceBeforeConditionalOperatorCondition); + ForceSpacesAfter(conditionalExpression.QuestionMarkToken, policy.SpaceAfterConditionalOperatorCondition); + ForceSpacesBefore(conditionalExpression.ColonToken, policy.SpaceBeforeConditionalOperatorSeparator); + ForceSpacesAfter(conditionalExpression.ColonToken, policy.SpaceAfterConditionalOperatorSeparator); + base.VisitConditionalExpression(conditionalExpression); + } + + public override void VisitCastExpression(CastExpression castExpression) + { + if (castExpression.RParToken != null) { + ForceSpacesAfter(castExpression.LParToken, policy.SpacesWithinCastParentheses); + ForceSpacesBefore(castExpression.RParToken, policy.SpacesWithinCastParentheses); + + ForceSpacesAfter(castExpression.RParToken, policy.SpaceAfterTypecast); + } + base.VisitCastExpression(castExpression); + } + + void ForceSpacesAround(AstNode node, bool forceSpaces) + { + if (node.IsNull) + return; + ForceSpacesBefore(node, forceSpaces); + ForceSpacesAfter(node, forceSpaces); + } + + void FormatCommas(AstNode parent, bool before, bool after) + { + if (parent.IsNull) { + return; + } + foreach (CSharpTokenNode comma in parent.Children.Where (node => node.Role == Roles.Comma)) { + ForceSpacesAfter(comma, after); + ForceSpacesBefore(comma, before); + } + } + + 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; + NewLinePlacement newLineAferMethodCallOpenParentheses; + bool doAlignToFirstArgument; + NewLinePlacement methodClosingParenthesesOnNewLine; + bool spaceWithinMethodCallParentheses; + bool spaceWithinEmptyParentheses; + bool spaceAfterMethodCallParameterComma; + bool spaceBeforeMethodCallParameterComma; + + CSharpTokenNode rParToken, lParToken; + List arguments; + + var constructorDeclaration = node as ConstructorDeclaration; + if (constructorDeclaration != null) { + methodCallArgumentWrapping = policy.MethodDeclarationParameterWrapping; + newLineAferMethodCallOpenParentheses = policy.NewLineAferMethodDeclarationOpenParentheses; + methodClosingParenthesesOnNewLine = policy.MethodDeclarationClosingParenthesesOnNewLine; + doAlignToFirstArgument = policy.AlignToFirstMethodDeclarationParameter; + spaceWithinMethodCallParentheses = policy.SpaceWithinConstructorDeclarationParentheses; + spaceAfterMethodCallParameterComma = policy.SpaceAfterConstructorDeclarationParameterComma; + spaceBeforeMethodCallParameterComma = policy.SpaceBeforeConstructorDeclarationParameterComma; + spaceWithinEmptyParentheses = policy.SpaceBetweenEmptyMethodDeclarationParentheses; + lParToken = constructorDeclaration.LParToken; + rParToken = constructorDeclaration.RParToken; + arguments = constructorDeclaration.Parameters.Cast().ToList(); + } else if (node is IndexerDeclaration) { + var indexer = (IndexerDeclaration)node; + methodCallArgumentWrapping = policy.IndexerDeclarationParameterWrapping; + newLineAferMethodCallOpenParentheses = policy.NewLineAferIndexerDeclarationOpenBracket; + methodClosingParenthesesOnNewLine = policy.IndexerDeclarationClosingBracketOnNewLine; + doAlignToFirstArgument = policy.AlignToFirstIndexerDeclarationParameter; + spaceWithinMethodCallParentheses = policy.SpaceWithinIndexerDeclarationBracket; + spaceAfterMethodCallParameterComma = policy.SpaceAfterIndexerDeclarationParameterComma; + spaceBeforeMethodCallParameterComma = policy.SpaceBeforeIndexerDeclarationParameterComma; + spaceWithinEmptyParentheses = policy.SpaceBetweenEmptyMethodDeclarationParentheses; + lParToken = indexer.LBracketToken; + rParToken = indexer.RBracketToken; + arguments = indexer.Parameters.Cast().ToList(); + } else if (node is OperatorDeclaration) { + var op = (OperatorDeclaration)node; + methodCallArgumentWrapping = policy.MethodDeclarationParameterWrapping; + newLineAferMethodCallOpenParentheses = policy.NewLineAferMethodDeclarationOpenParentheses; + methodClosingParenthesesOnNewLine = policy.MethodDeclarationClosingParenthesesOnNewLine; + doAlignToFirstArgument = policy.AlignToFirstMethodDeclarationParameter; + spaceWithinMethodCallParentheses = policy.SpaceWithinMethodDeclarationParentheses; + spaceAfterMethodCallParameterComma = policy.SpaceAfterMethodDeclarationParameterComma; + spaceBeforeMethodCallParameterComma = policy.SpaceBeforeMethodDeclarationParameterComma; + spaceWithinEmptyParentheses = policy.SpaceBetweenEmptyMethodDeclarationParentheses; + lParToken = op.LParToken; + rParToken = op.RParToken; + arguments = op.Parameters.Cast().ToList(); + } else if (node is MethodDeclaration) { + var methodDeclaration = node as MethodDeclaration; + methodCallArgumentWrapping = policy.MethodDeclarationParameterWrapping; + newLineAferMethodCallOpenParentheses = policy.NewLineAferMethodDeclarationOpenParentheses; + methodClosingParenthesesOnNewLine = policy.MethodDeclarationClosingParenthesesOnNewLine; + doAlignToFirstArgument = policy.AlignToFirstMethodDeclarationParameter; + spaceWithinMethodCallParentheses = policy.SpaceWithinMethodDeclarationParentheses; + spaceAfterMethodCallParameterComma = policy.SpaceAfterMethodDeclarationParameterComma; + spaceBeforeMethodCallParameterComma = policy.SpaceBeforeMethodDeclarationParameterComma; + spaceWithinEmptyParentheses = policy.SpaceBetweenEmptyMethodDeclarationParentheses; + lParToken = methodDeclaration.LParToken; + rParToken = methodDeclaration.RParToken; + arguments = methodDeclaration.Parameters.Cast().ToList(); + } else if (node is IndexerExpression) { + var indexer = (IndexerExpression)node; + methodCallArgumentWrapping = policy.IndexerArgumentWrapping; + newLineAferMethodCallOpenParentheses = policy.NewLineAferIndexerOpenBracket; + doAlignToFirstArgument = policy.AlignToFirstIndexerArgument; + methodClosingParenthesesOnNewLine = policy.IndexerClosingBracketOnNewLine; + spaceWithinMethodCallParentheses = policy.SpacesWithinBrackets; + spaceAfterMethodCallParameterComma = policy.SpaceAfterBracketComma; + spaceWithinEmptyParentheses = spaceWithinMethodCallParentheses; + spaceBeforeMethodCallParameterComma = policy.SpaceBeforeBracketComma; + rParToken = indexer.RBracketToken; + lParToken = indexer.LBracketToken; + arguments = indexer.Arguments.Cast().ToList(); + } else if (node is ObjectCreateExpression) { + var oce = node as ObjectCreateExpression; + methodCallArgumentWrapping = policy.MethodCallArgumentWrapping; + newLineAferMethodCallOpenParentheses = policy.NewLineAferMethodCallOpenParentheses; + doAlignToFirstArgument = policy.AlignToFirstMethodCallArgument; + methodClosingParenthesesOnNewLine = policy.MethodCallClosingParenthesesOnNewLine; + spaceWithinMethodCallParentheses = policy.SpacesWithinNewParentheses; + spaceAfterMethodCallParameterComma = policy.SpaceAfterNewParameterComma; + spaceBeforeMethodCallParameterComma = policy.SpaceBeforeNewParameterComma; + spaceWithinEmptyParentheses = policy.SpacesBetweenEmptyNewParentheses; + + rParToken = oce.RParToken; + lParToken = oce.LParToken; + arguments = oce.Arguments.Cast().ToList(); + } else if (node is Attribute) { + var oce = node as Attribute; + methodCallArgumentWrapping = policy.MethodCallArgumentWrapping; + newLineAferMethodCallOpenParentheses = policy.NewLineAferMethodCallOpenParentheses; + doAlignToFirstArgument = policy.AlignToFirstMethodCallArgument; + methodClosingParenthesesOnNewLine = policy.MethodCallClosingParenthesesOnNewLine; + spaceWithinMethodCallParentheses = policy.SpacesWithinNewParentheses; + spaceAfterMethodCallParameterComma = policy.SpaceAfterNewParameterComma; + spaceBeforeMethodCallParameterComma = policy.SpaceBeforeNewParameterComma; + spaceWithinEmptyParentheses = policy.SpacesBetweenEmptyNewParentheses; + + rParToken = oce.RParToken; + lParToken = oce.LParToken; + arguments = oce.Arguments.Cast().ToList(); + } else if (node is LambdaExpression) { + var methodDeclaration = node as LambdaExpression; + methodCallArgumentWrapping = policy.MethodDeclarationParameterWrapping; + newLineAferMethodCallOpenParentheses = policy.NewLineAferMethodDeclarationOpenParentheses; + methodClosingParenthesesOnNewLine = policy.MethodDeclarationClosingParenthesesOnNewLine; + doAlignToFirstArgument = policy.AlignToFirstMethodDeclarationParameter; + spaceWithinMethodCallParentheses = policy.SpaceWithinMethodDeclarationParentheses; + spaceAfterMethodCallParameterComma = policy.SpaceAfterMethodDeclarationParameterComma; + spaceBeforeMethodCallParameterComma = policy.SpaceBeforeMethodDeclarationParameterComma; + spaceWithinEmptyParentheses = policy.SpaceBetweenEmptyMethodDeclarationParentheses; + lParToken = methodDeclaration.LParToken; + rParToken = methodDeclaration.RParToken; + arguments = methodDeclaration.Parameters.Cast().ToList(); + } else if (node is AnonymousMethodExpression) { + var methodDeclaration = node as AnonymousMethodExpression; + methodCallArgumentWrapping = policy.MethodDeclarationParameterWrapping; + newLineAferMethodCallOpenParentheses = policy.NewLineAferMethodDeclarationOpenParentheses; + methodClosingParenthesesOnNewLine = policy.MethodDeclarationClosingParenthesesOnNewLine; + doAlignToFirstArgument = policy.AlignToFirstMethodDeclarationParameter; + spaceWithinMethodCallParentheses = policy.SpaceWithinMethodDeclarationParentheses; + spaceAfterMethodCallParameterComma = policy.SpaceAfterMethodDeclarationParameterComma; + spaceBeforeMethodCallParameterComma = policy.SpaceBeforeMethodDeclarationParameterComma; + spaceWithinEmptyParentheses = policy.SpaceBetweenEmptyMethodDeclarationParentheses; + lParToken = methodDeclaration.LParToken; + rParToken = methodDeclaration.RParToken; + arguments = methodDeclaration.Parameters.Cast().ToList(); + } else if (node is ConstructorInitializer) { + var constructorInitializer = node as ConstructorInitializer; + methodCallArgumentWrapping = policy.MethodDeclarationParameterWrapping; + newLineAferMethodCallOpenParentheses = policy.NewLineAferMethodDeclarationOpenParentheses; + methodClosingParenthesesOnNewLine = policy.MethodDeclarationClosingParenthesesOnNewLine; + doAlignToFirstArgument = policy.AlignToFirstMethodDeclarationParameter; + spaceWithinMethodCallParentheses = policy.SpaceWithinMethodDeclarationParentheses; + spaceAfterMethodCallParameterComma = policy.SpaceAfterMethodDeclarationParameterComma; + spaceBeforeMethodCallParameterComma = policy.SpaceBeforeMethodDeclarationParameterComma; + spaceWithinEmptyParentheses = policy.SpaceBetweenEmptyMethodDeclarationParentheses; + lParToken = constructorInitializer.LParToken; + rParToken = constructorInitializer.RParToken; + arguments = constructorInitializer.Arguments.Cast().ToList(); + } else { + InvocationExpression invocationExpression = node as InvocationExpression; + methodCallArgumentWrapping = policy.MethodCallArgumentWrapping; + newLineAferMethodCallOpenParentheses = policy.NewLineAferMethodCallOpenParentheses; + methodClosingParenthesesOnNewLine = policy.MethodCallClosingParenthesesOnNewLine; + doAlignToFirstArgument = policy.AlignToFirstMethodCallArgument; + spaceWithinMethodCallParentheses = policy.SpaceWithinMethodCallParentheses; + spaceAfterMethodCallParameterComma = policy.SpaceAfterMethodCallParameterComma; + spaceBeforeMethodCallParameterComma = policy.SpaceBeforeMethodCallParameterComma; + spaceWithinEmptyParentheses = policy.SpaceBetweenEmptyMethodCallParentheses; + + rParToken = invocationExpression.RParToken; + lParToken = invocationExpression.LParToken; + arguments = invocationExpression.Arguments.Cast().ToList(); + } + + if (formatter.FormattingMode == ICSharpCode.NRefactory.CSharp.FormattingMode.OnTheFly) + methodCallArgumentWrapping = Wrapping.DoNotChange; + int argumentStart = 1; + var firstarg = arguments.FirstOrDefault(); + if (firstarg != null && firstarg.GetPrevNode().Role == Roles.NewLine) { + doAlignToFirstArgument = false; + argumentStart = 0; + } + bool wrapMethodCall = DoWrap(methodCallArgumentWrapping, rParToken, arguments.Count); + if (wrapMethodCall && arguments.Any()) { + if (ShouldBreakLine(newLineAferMethodCallOpenParentheses, lParToken)) { + curIndent.Push(IndentType.Continuation); + foreach (var arg in arguments) { + FixStatementIndentation(arg.StartLocation); + arg.AcceptVisitor(this); + } + curIndent.Pop(); + } else { + if (!doAlignToFirstArgument) { + curIndent.Push(IndentType.Continuation); + foreach (var arg in arguments.Take (argumentStart)) { + FixStatementIndentation(arg.StartLocation); + arg.AcceptVisitor(this); + } + foreach (var arg in arguments.Skip (argumentStart)) { + FixStatementIndentation(arg.StartLocation); + arg.AcceptVisitor(this); + } + curIndent.Pop(); + } else { + int extraSpaces = Math.Max(0, arguments.First().StartLocation.Column - 1 - curIndent.IndentString.Length); + curIndent.ExtraSpaces += extraSpaces; + foreach (var arg in arguments.Take (argumentStart)) { + arg.AcceptVisitor(this); + } + foreach (var arg in arguments.Skip(argumentStart)) { + FixStatementIndentation(arg.StartLocation); + arg.AcceptVisitor(this); + } + curIndent.ExtraSpaces -= extraSpaces; + } + } + + if (!rParToken.IsNull) { + if (ShouldBreakLine(methodClosingParenthesesOnNewLine, rParToken)) { + FixStatementIndentation(rParToken.StartLocation); + } else if (methodClosingParenthesesOnNewLine == NewLinePlacement.SameLine) { + ForceSpacesBeforeRemoveNewLines(rParToken, spaceWithinMethodCallParentheses); + } + } + } else { + + foreach (var arg in arguments.Take (argumentStart)) { + if (policy.IndentBlocksInsideExpressions) + curIndent.Push(IndentType.Continuation); + arg.AcceptVisitor(this); + if (policy.IndentBlocksInsideExpressions) + curIndent.Pop(); + } + foreach (var arg in arguments.Skip(argumentStart)) { + if (arg.GetPrevSibling(NoWhitespacePredicate) != null) { + if (methodCallArgumentWrapping == Wrapping.DoNotWrap) { + ForceSpacesBeforeRemoveNewLines(arg, spaceAfterMethodCallParameterComma && arg.GetPrevSibling(NoWhitespacePredicate).Role == Roles.Comma); + if (policy.IndentBlocksInsideExpressions) + curIndent.Push(IndentType.Continuation); + arg.AcceptVisitor(this); + if (policy.IndentBlocksInsideExpressions) + curIndent.Pop(); + } else { + if (!doAlignToFirstArgument && arg.PrevSibling.Role == Roles.NewLine) { + curIndent.Push(IndentType.Continuation); + FixStatementIndentation(arg.StartLocation); + arg.AcceptVisitor(this); + curIndent.Pop(); + } else { + if (arg.PrevSibling.StartLocation.Line == arg.StartLocation.Line) { + ForceSpacesBefore(arg, spaceAfterMethodCallParameterComma && arg.GetPrevSibling(NoWhitespacePredicate).Role == Roles.Comma); + if (policy.IndentBlocksInsideExpressions) + curIndent.Push(IndentType.Continuation); + arg.AcceptVisitor(this); + if (policy.IndentBlocksInsideExpressions) + curIndent.Pop(); + } else { + int extraSpaces = Math.Max(0, arguments.First().StartLocation.Column - 1 - curIndent.IndentString.Length); + curIndent.ExtraSpaces += extraSpaces; + FixStatementIndentation(arg.StartLocation); + arg.AcceptVisitor(this); + curIndent.ExtraSpaces -= extraSpaces; + } + } + } + } else { + arg.AcceptVisitor(this); + } + } + if (!rParToken.IsNull) { + if (methodCallArgumentWrapping == Wrapping.DoNotWrap) { + ForceSpacesBeforeRemoveNewLines(rParToken, arguments.Any() ? spaceWithinMethodCallParentheses : spaceWithinEmptyParentheses); + } else { + bool sameLine = rParToken.GetPrevNode(n => n.Role == Roles.Argument || n.Role == Roles.Parameter || n.Role == Roles.LPar || n.Role == Roles.Comma).EndLocation.Line == rParToken.StartLocation.Line; + if (sameLine) { + ForceSpacesBeforeRemoveNewLines(rParToken, arguments.Any() ? spaceWithinMethodCallParentheses : spaceWithinEmptyParentheses); + } 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) + { + if (!invocationExpression.Target.IsNull) + invocationExpression.Target.AcceptVisitor(this); + + ForceSpacesBefore(invocationExpression.LParToken, policy.SpaceBeforeMethodCallParentheses); + if (invocationExpression.Arguments.Any()) { + ForceSpacesAfter(invocationExpression.LParToken, policy.SpaceWithinMethodCallParentheses); + } else { + ForceSpacesAfter(invocationExpression.LParToken, policy.SpaceBetweenEmptyMethodCallParentheses); + ForceSpacesBefore(invocationExpression.RParToken, policy.SpaceBetweenEmptyMethodCallParentheses); + } + bool popIndent = false; + 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.Block); + popIndent = true; + FixStatementIndentation(mt.DotToken.StartLocation); + } else { + if (policy.ChainedMethodCallWrapping == Wrapping.DoNotWrap) + ForceSpacesBeforeRemoveNewLines(mt.DotToken, false); + } + } + } + FormatArguments(invocationExpression); + if (popIndent) + curIndent.Pop(); + } + + public override void VisitIndexerExpression(IndexerExpression indexerExpression) + { + ForceSpacesBeforeRemoveNewLines(indexerExpression.LBracketToken, policy.SpacesBeforeBrackets); + ForceSpacesAfter(indexerExpression.LBracketToken, policy.SpacesWithinBrackets); + + if (!indexerExpression.Target.IsNull) + indexerExpression.Target.AcceptVisitor(this); + + FormatArguments(indexerExpression); + + + + } + + public override void VisitParenthesizedExpression(ParenthesizedExpression parenthesizedExpression) + { + var lp = parenthesizedExpression.LParToken; + var expr = parenthesizedExpression.Expression; + int extraSpaces = 0; + if (lp.StartLocation.Line == expr.StartLocation.Line) { + ForceSpacesAfter(lp, policy.SpacesWithinParentheses); + } else { + extraSpaces += options.IndentSize; + curIndent.ExtraSpaces += extraSpaces; + FixIndentation(expr); + } + + base.VisitParenthesizedExpression(parenthesizedExpression); + + var rp = parenthesizedExpression.RParToken; + + curIndent.ExtraSpaces -= extraSpaces; + if (rp.StartLocation.Line == expr.EndLocation.Line) { + ForceSpacesBefore(rp, policy.SpacesWithinParentheses); + } else { + FixIndentation(rp); + } + } + + public override void VisitSizeOfExpression(SizeOfExpression sizeOfExpression) + { + ForceSpacesBeforeRemoveNewLines(sizeOfExpression.LParToken, policy.SpaceBeforeSizeOfParentheses); + ForceSpacesAfter(sizeOfExpression.LParToken, policy.SpacesWithinSizeOfParentheses); + ForceSpacesBeforeRemoveNewLines(sizeOfExpression.RParToken, policy.SpacesWithinSizeOfParentheses); + base.VisitSizeOfExpression(sizeOfExpression); + } + + public override void VisitTypeOfExpression(TypeOfExpression typeOfExpression) + { + ForceSpacesBeforeRemoveNewLines(typeOfExpression.LParToken, policy.SpaceBeforeTypeOfParentheses); + ForceSpacesAfter(typeOfExpression.LParToken, policy.SpacesWithinTypeOfParentheses); + ForceSpacesBeforeRemoveNewLines(typeOfExpression.RParToken, policy.SpacesWithinTypeOfParentheses); + base.VisitTypeOfExpression(typeOfExpression); + } + + public override void VisitCheckedExpression(CheckedExpression checkedExpression) + { + ForceSpacesAfter(checkedExpression.LParToken, policy.SpacesWithinCheckedExpressionParantheses); + ForceSpacesBeforeRemoveNewLines(checkedExpression.RParToken, policy.SpacesWithinCheckedExpressionParantheses); + base.VisitCheckedExpression(checkedExpression); + } + + public override void VisitUncheckedExpression(UncheckedExpression uncheckedExpression) + { + ForceSpacesAfter(uncheckedExpression.LParToken, policy.SpacesWithinCheckedExpressionParantheses); + ForceSpacesBeforeRemoveNewLines(uncheckedExpression.RParToken, policy.SpacesWithinCheckedExpressionParantheses); + base.VisitUncheckedExpression(uncheckedExpression); + } + + public override void VisitObjectCreateExpression(ObjectCreateExpression objectCreateExpression) + { + ForceSpacesBeforeRemoveNewLines(objectCreateExpression.LParToken, policy.SpaceBeforeNewParentheses); + + if (objectCreateExpression.Arguments.Any()) { + if (!objectCreateExpression.LParToken.IsNull) + ForceSpacesAfter(objectCreateExpression.LParToken, policy.SpacesWithinNewParentheses); + } else { + if (!objectCreateExpression.LParToken.IsNull) + ForceSpacesAfter(objectCreateExpression.LParToken, policy.SpacesBetweenEmptyNewParentheses); + } + + if (!objectCreateExpression.Type.IsNull) + objectCreateExpression.Type.AcceptVisitor(this); + objectCreateExpression.Initializer.AcceptVisitor(this); + FormatArguments(objectCreateExpression); + } + + public override void VisitArrayCreateExpression(ArrayCreateExpression arrayObjectCreateExpression) + { + FormatCommas(arrayObjectCreateExpression, policy.SpaceBeforeMethodCallParameterComma, policy.SpaceAfterMethodCallParameterComma); + base.VisitArrayCreateExpression(arrayObjectCreateExpression); + } + + public override void VisitArrayInitializerExpression(ArrayInitializerExpression arrayInitializerExpression) + { + var old = curIndent; + curIndent = curIndent.Clone(); + curIndent.ExtraSpaces = 0; + + if (DoWrap(policy.ArrayInitializerWrapping, arrayInitializerExpression.RBraceToken, arrayInitializerExpression.Elements.Count)) { + FixOpenBrace(policy.ArrayInitializerBraceStyle, arrayInitializerExpression.LBraceToken); + curIndent.Push(IndentType.Block); + foreach (var init in arrayInitializerExpression.Elements) { + FixStatementIndentation(init.StartLocation); + init.AcceptVisitor(this); + } + curIndent.Pop(); + FixClosingBrace(policy.ArrayInitializerBraceStyle, arrayInitializerExpression.RBraceToken); + } else if (policy.ArrayInitializerWrapping == Wrapping.DoNotWrap) { + ForceSpacesBeforeRemoveNewLines(arrayInitializerExpression.LBraceToken); + foreach (var init in arrayInitializerExpression.Elements) { + ForceSpacesBeforeRemoveNewLines(init); + init.AcceptVisitor(this); + } + ForceSpacesBeforeRemoveNewLines(arrayInitializerExpression.RBraceToken); + } else { + var lBrace = arrayInitializerExpression.LBraceToken; + var rBrace = arrayInitializerExpression.RBraceToken; + + foreach (var child in arrayInitializerExpression.Children) { + if (child.Role == Roles.LBrace) { + if (lBrace.StartLocation.Line == rBrace.StartLocation.Line && policy.AllowOneLinedArrayInitialziers) { + ForceSpacesAfter(child, true); + } else { + FixOpenBrace(policy.ArrayInitializerBraceStyle, child); + } + curIndent.Push(IndentType.Block); + continue; + } + if (child.Role == Roles.RBrace) { + curIndent.Pop(); + if (lBrace.StartLocation.Line == rBrace.StartLocation.Line && policy.AllowOneLinedArrayInitialziers) { + ForceSpaceBefore(child, true); + + } else { + FixClosingBrace(policy.ArrayInitializerBraceStyle, child); + } + continue; + } + if (child.Role == Roles.Expression) { + if (child.PrevSibling != null) { + if (child.PrevSibling.Role == Roles.NewLine) { + FixIndentation(child); + } + if (child.PrevSibling.Role == Roles.Comma) { + ForceSpaceBefore(child, true); + } + } + child.AcceptVisitor(this); + if (child.NextSibling != null && child.NextSibling.Role == Roles.Comma) + ForceSpacesAfter(child, false); + continue; + } + + child.AcceptVisitor(this); + } + } + curIndent = old; + } + + public override void VisitParameterDeclaration(ParameterDeclaration parameterDeclaration) + { + var assignToken = parameterDeclaration.AssignToken; + if (!assignToken.IsNull) + ForceSpacesAround(assignToken, policy.SpaceAroundAssignment); + base.VisitParameterDeclaration(parameterDeclaration); + } + + public override void VisitLambdaExpression(LambdaExpression lambdaExpression) + { + FormatArguments(lambdaExpression); + ForceSpacesBeforeRemoveNewLines(lambdaExpression.ArrowToken, true); + + if (!lambdaExpression.Body.IsNull) { + var body = lambdaExpression.Body as BlockStatement; + if (body != null) { + var old = curIndent; + this.curIndent = curIndent.GetIndentWithoutSpace (); + FixOpenBrace(policy.AnonymousMethodBraceStyle, body.LBraceToken); + VisitBlockWithoutFixingBraces(body, policy.IndentMethodBody); + FixClosingBrace(policy.AnonymousMethodBraceStyle, body.RBraceToken); + curIndent = old; + } else { + ForceSpacesAfter(lambdaExpression.ArrowToken, true); + lambdaExpression.Body.AcceptVisitor(this); + } + } + } + + public override void VisitNamedExpression(NamedExpression namedExpression) + { + ForceSpacesAround(namedExpression.AssignToken, policy.SpaceAroundAssignment); + base.VisitNamedExpression(namedExpression); + } + + public override void VisitNamedArgumentExpression(NamedArgumentExpression namedArgumentExpression) + { + ForceSpacesAfter(namedArgumentExpression.ColonToken, policy.SpaceInNamedArgumentAfterDoubleColon); + + base.VisitNamedArgumentExpression(namedArgumentExpression); + } + + public override void VisitMemberReferenceExpression(MemberReferenceExpression memberReferenceExpression) + { + var dot = memberReferenceExpression.DotToken; + if (dot.PrevSibling.EndLocation.Line == dot.StartLocation.Line) + ForceSpacesBefore(dot, false); + ForceSpacesAfter(dot, false); + base.VisitMemberReferenceExpression(memberReferenceExpression); + } + + public override void VisitPointerReferenceExpression(PointerReferenceExpression pointerReferenceExpression) + { + ForceSpacesAround(pointerReferenceExpression.ArrowToken, policy.SpaceAroundUnsafeArrowOperator); + base.VisitPointerReferenceExpression(pointerReferenceExpression); + } + + public override void VisitUnaryOperatorExpression(UnaryOperatorExpression unaryOperatorExpression) + { + base.VisitUnaryOperatorExpression(unaryOperatorExpression); + switch (unaryOperatorExpression.Operator) { + case UnaryOperatorType.Any: + break; + case UnaryOperatorType.Not: + case UnaryOperatorType.BitNot: + case UnaryOperatorType.Minus: + case UnaryOperatorType.Plus: + case UnaryOperatorType.Increment: + case UnaryOperatorType.Decrement: + ForceSpacesBeforeRemoveNewLines(unaryOperatorExpression.Expression, false); + break; + case UnaryOperatorType.PostIncrement: + case UnaryOperatorType.PostDecrement: + ForceSpacesBeforeRemoveNewLines(unaryOperatorExpression.OperatorToken, false); + break; + case UnaryOperatorType.Dereference: + ForceSpacesAfter(unaryOperatorExpression.OperatorToken, policy.SpaceAfterUnsafeAsteriskOfOperator); + break; + case UnaryOperatorType.AddressOf: + ForceSpacesAfter(unaryOperatorExpression.OperatorToken, policy.SpaceAfterUnsafeAddressOfOperator); + break; + case UnaryOperatorType.Await: + ForceSpacesBeforeRemoveNewLines(unaryOperatorExpression.Expression, true); + break; + default: + throw new ArgumentOutOfRangeException(); + } + } + } +} + diff --git a/NRefactory/ICSharpCode.NRefactory.CSharp/Formatter/FormattingVisitor_Global.cs b/NRefactory/ICSharpCode.NRefactory.CSharp/Formatter/FormattingVisitor_Global.cs new file mode 100644 index 000000000..b91cbdd9a --- /dev/null +++ b/NRefactory/ICSharpCode.NRefactory.CSharp/Formatter/FormattingVisitor_Global.cs @@ -0,0 +1,351 @@ +// +// AstFormattingVisitor_Global.cs +// +// Author: +// Mike Krüger +// +// Copyright (c) 2013 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 System.Linq; + +namespace ICSharpCode.NRefactory.CSharp +{ + partial class FormattingVisitor : DepthFirstAstVisitor + { + int GetGlobalNewLinesFor(AstNode child) + { + if (child.NextSibling == null) + // last node in the document => no extra newlines + return 0; + if (child.NextSibling.Role == Roles.RBrace) + // Last node in a block => no extra newlines, it's handled later by FixClosingBrace() + return 0; + + int newLines = 1; + var nextSibling = child.GetNextSibling(NoWhitespacePredicate); + if (nextSibling is PreProcessorDirective) { + var directive = (PreProcessorDirective)nextSibling; + if (directive.Type == PreProcessorDirectiveType.Endif) + return -1; + if (directive.Type == PreProcessorDirectiveType.Undef) + return -1; + } + if ((child is UsingDeclaration || child is UsingAliasDeclaration) && !(nextSibling is UsingDeclaration || nextSibling is UsingAliasDeclaration)) { + newLines += policy.MinimumBlankLinesAfterUsings; + } else if ((child is TypeDeclaration) && (nextSibling is TypeDeclaration)) { + newLines += policy.MinimumBlankLinesBetweenTypes; + } + + return newLines; + } + + public override void VisitSyntaxTree(SyntaxTree unit) + { + bool first = true; + VisitChildrenToFormat(unit, child => { + if (first && (child is UsingDeclaration || child is UsingAliasDeclaration)) { + EnsureMinimumBlankLinesBefore(child, policy.MinimumBlankLinesBeforeUsings); + first = false; + } + if (NoWhitespacePredicate(child)) + FixIndentation(child); + child.AcceptVisitor(this); + if (NoWhitespacePredicate(child) && !first) + EnsureMinimumNewLinesAfter(child, GetGlobalNewLinesFor(child)); + }); + } + + public override void VisitAttributeSection(AttributeSection attributeSection) + { + VisitChildrenToFormat(attributeSection, child => { + child.AcceptVisitor(this); + if (child.NextSibling != null && child.NextSibling.Role == Roles.RBracket) { + ForceSpacesAfter(child, false); + } + }); + } + + public override void VisitAttribute(Attribute attribute) + { + if (attribute.HasArgumentList) { + ForceSpacesBefore(attribute.LParToken, policy.SpaceBeforeMethodCallParentheses); + if (attribute.Arguments.Any()) { + ForceSpacesAfter(attribute.LParToken, policy.SpaceWithinMethodCallParentheses); + } else { + ForceSpacesAfter(attribute.LParToken, policy.SpaceBetweenEmptyMethodCallParentheses); + ForceSpacesBefore(attribute.RParToken, policy.SpaceBetweenEmptyMethodCallParentheses); + } + FormatArguments(attribute); + } + } + + public override void VisitUsingDeclaration(UsingDeclaration usingDeclaration) + { + ForceSpacesAfter(usingDeclaration.UsingToken, true); + FixSemicolon(usingDeclaration.SemicolonToken); + } + + public override void VisitUsingAliasDeclaration(UsingAliasDeclaration usingDeclaration) + { + ForceSpacesAfter(usingDeclaration.UsingToken, true); + ForceSpacesAround(usingDeclaration.AssignToken, policy.SpaceAroundAssignment); + FixSemicolon(usingDeclaration.SemicolonToken); + } + + public override void VisitNamespaceDeclaration(NamespaceDeclaration namespaceDeclaration) + { + FixOpenBrace(policy.NamespaceBraceStyle, namespaceDeclaration.LBraceToken); + if (policy.IndentNamespaceBody) + curIndent.Push(IndentType.Block); + + bool first = true; + bool startFormat = false; + VisitChildrenToFormat(namespaceDeclaration, child => { + if (first) { + startFormat = child.StartLocation > namespaceDeclaration.LBraceToken.StartLocation; + } + if (child.Role == Roles.LBrace) { + var next = child.GetNextSibling(NoWhitespacePredicate); + var blankLines = 1; + if (next is UsingDeclaration || next is UsingAliasDeclaration) { + blankLines += policy.MinimumBlankLinesBeforeUsings; + } else { + blankLines += policy.MinimumBlankLinesBeforeFirstDeclaration; + } + EnsureMinimumNewLinesAfter(child, blankLines); + startFormat = true; + return; + } + if (child.Role == Roles.RBrace) { + startFormat = false; + return; + } + if (!startFormat || !NoWhitespacePredicate (child)) + return; + if (first && (child is UsingDeclaration || child is UsingAliasDeclaration)) { + // TODO: policy.BlankLinesBeforeUsings + first = false; + } + if (NoWhitespacePredicate(child)) + FixIndentationForceNewLine(child); + child.AcceptVisitor(this); + if (NoWhitespacePredicate(child)) + EnsureMinimumNewLinesAfter(child, GetGlobalNewLinesFor(child)); + }); + + if (policy.IndentNamespaceBody) + curIndent.Pop(); + + FixClosingBrace(policy.NamespaceBraceStyle, namespaceDeclaration.RBraceToken); + } + + void FixAttributesAndDocComment(EntityDeclaration entity) + { + var node = entity.FirstChild; + while (node != null && node.Role == Roles.Comment) { + node = node.GetNextSibling(NoWhitespacePredicate); + FixIndentation(node); + } + if (entity.Attributes.Count > 0) { + AstNode n = null; + entity.Attributes.First().AcceptVisitor(this); + foreach (var attr in entity.Attributes.Skip (1)) { + FixIndentation(attr); + attr.AcceptVisitor(this); + n = attr; + } + if (n != null) { + FixIndentation(n.GetNextNode(NoWhitespacePredicate)); + } else { + FixIndentation(entity.Attributes.First().GetNextNode(NoWhitespacePredicate)); + } + } + } + + public override void VisitTypeDeclaration(TypeDeclaration typeDeclaration) + { + FixAttributesAndDocComment(typeDeclaration); + BraceStyle braceStyle; + bool indentBody = false; + switch (typeDeclaration.ClassType) { + case ClassType.Class: + braceStyle = policy.ClassBraceStyle; + indentBody = policy.IndentClassBody; + break; + case ClassType.Struct: + braceStyle = policy.StructBraceStyle; + indentBody = policy.IndentStructBody; + break; + case ClassType.Interface: + braceStyle = policy.InterfaceBraceStyle; + indentBody = policy.IndentInterfaceBody; + break; + case ClassType.Enum: + braceStyle = policy.EnumBraceStyle; + indentBody = policy.IndentEnumBody; + break; + default: + throw new InvalidOperationException("unsupported class type : " + typeDeclaration.ClassType); + } + + foreach (var constraint in typeDeclaration.Constraints) + constraint.AcceptVisitor (this); + + FixOpenBrace(braceStyle, typeDeclaration.LBraceToken); + + if (indentBody) + curIndent.Push(IndentType.Block); + bool startFormat = true; + bool first = true; + VisitChildrenToFormat(typeDeclaration, child => { + if (first) { + startFormat = child.StartLocation > typeDeclaration.LBraceToken.StartLocation; + first = false; + } + if (child.Role == Roles.LBrace) { + startFormat = true; + if (braceStyle != BraceStyle.DoNotChange) + EnsureMinimumNewLinesAfter(child, GetTypeLevelNewLinesFor(child)); + return; + } + if (child.Role == Roles.RBrace) { + startFormat = false; + return; + } + if (!startFormat || !NoWhitespacePredicate (child)) + return; + if (child.Role == Roles.Comma) { + ForceSpacesBeforeRemoveNewLines (child, false); + EnsureMinimumNewLinesAfter(child, 1); + return; + } + if (NoWhitespacePredicate(child)) + FixIndentationForceNewLine(child); + child.AcceptVisitor(this); + if (NoWhitespacePredicate(child) && child.GetNextSibling (NoWhitespacePredicate).Role != Roles.Comma) + EnsureMinimumNewLinesAfter(child, GetTypeLevelNewLinesFor(child)); + }); + + if (indentBody) + curIndent.Pop(); + + FixClosingBrace(braceStyle, typeDeclaration.RBraceToken); + } + + int GetTypeLevelNewLinesFor(AstNode child) + { + var blankLines = 1; + var nextSibling = child.GetNextSibling(NoWhitespacePredicate); + if (child is PreProcessorDirective) { + var directive = (PreProcessorDirective)child; + if (directive.Type == PreProcessorDirectiveType.Region) { + blankLines += policy.MinimumBlankLinesInsideRegion; + } + if (directive.Type == PreProcessorDirectiveType.Endregion) { + if (child.GetNextSibling(NoWhitespacePredicate) is CSharpTokenNode) + return 1; + blankLines += policy.MinimumBlankLinesAroundRegion; + } + return blankLines; + } + + if (nextSibling is PreProcessorDirective) { + var directive = (PreProcessorDirective)nextSibling; + if (directive.Type == PreProcessorDirectiveType.Region) { + if (child is CSharpTokenNode) + return 1; + blankLines += policy.MinimumBlankLinesAroundRegion; + } + if (directive.Type == PreProcessorDirectiveType.Endregion) + blankLines += policy.MinimumBlankLinesInsideRegion; + if (directive.Type == PreProcessorDirectiveType.Endif) + return -1; + if (directive.Type == PreProcessorDirectiveType.Undef) + return -1; + return blankLines; + } + if (child.Role == Roles.LBrace) + return 1; + if (child is Comment) + return 1; + if (child is EventDeclaration) { + if (nextSibling is EventDeclaration) { + blankLines += policy.MinimumBlankLinesBetweenEventFields; + return blankLines; + } + } + + if (child is FieldDeclaration || child is FixedFieldDeclaration) { + if (nextSibling is FieldDeclaration || nextSibling is FixedFieldDeclaration) { + blankLines += policy.MinimumBlankLinesBetweenFields; + return blankLines; + } + } + + if (child is TypeDeclaration) { + if (nextSibling is TypeDeclaration) { + blankLines += policy.MinimumBlankLinesBetweenTypes; + return blankLines; + } + } + + if (nextSibling.Role == Roles.TypeMemberRole) + blankLines += policy.MinimumBlankLinesBetweenMembers; + return blankLines; + } + + public override void VisitDelegateDeclaration(DelegateDeclaration delegateDeclaration) + { + ForceSpacesBefore(delegateDeclaration.LParToken, policy.SpaceBeforeDelegateDeclarationParentheses); + if (delegateDeclaration.Parameters.Any()) { + ForceSpacesAfter(delegateDeclaration.LParToken, policy.SpaceWithinDelegateDeclarationParentheses); + ForceSpacesBefore(delegateDeclaration.RParToken, policy.SpaceWithinDelegateDeclarationParentheses); + } else { + ForceSpacesAfter(delegateDeclaration.LParToken, policy.SpaceBetweenEmptyDelegateDeclarationParentheses); + ForceSpacesBefore(delegateDeclaration.RParToken, policy.SpaceBetweenEmptyDelegateDeclarationParentheses); + } + FormatCommas(delegateDeclaration, policy.SpaceBeforeDelegateDeclarationParameterComma, policy.SpaceAfterDelegateDeclarationParameterComma); + + base.VisitDelegateDeclaration(delegateDeclaration); + } + + public override void VisitComment(Comment comment) + { + if (comment.StartsLine && !HadErrors && (!policy.KeepCommentsAtFirstColumn || comment.StartLocation.Column > 1)) + FixIndentation(comment); + } + + public override void VisitConstraint(Constraint constraint) + { + VisitChildrenToFormat (constraint, node => { + if (node is AstType) { + node.AcceptVisitor (this); + } else if (node.Role == Roles.LPar) { + ForceSpacesBefore (node, false); + ForceSpacesAfter (node, false); + } else if (node.Role ==Roles.Comma) { + ForceSpacesBefore (node, false); + ForceSpacesAfter (node, true); + } + }); + } + } +} \ No newline at end of file diff --git a/NRefactory/ICSharpCode.NRefactory.CSharp/Formatter/FormattingVisitor_Query.cs b/NRefactory/ICSharpCode.NRefactory.CSharp/Formatter/FormattingVisitor_Query.cs new file mode 100644 index 000000000..bfdc47640 --- /dev/null +++ b/NRefactory/ICSharpCode.NRefactory.CSharp/Formatter/FormattingVisitor_Query.cs @@ -0,0 +1,124 @@ +// +// AstFormattingVisitor_Query.cs +// +// Author: +// Luís Reis +// +// Copyright (c) 2013 Luís Reis +// +// 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.Linq; + +namespace ICSharpCode.NRefactory.CSharp +{ + partial class FormattingVisitor + { + int GetUpdatedStartLocation(QueryExpression queryExpression) + { + //TODO + return queryExpression.StartLocation.Column; + } + + public override void VisitQueryExpression(QueryExpression queryExpression) + { + var oldIndent = curIndent.Clone(); + + var column = GetUpdatedStartLocation(queryExpression); + + int extraSpaces = column - 1 - (curIndent.CurIndent / options.TabSize); + if (extraSpaces < 0) { + //This check should probably be removed in the future, when GetUpdatedStartLocation is implemented + extraSpaces = 0; + } + + curIndent.ExtraSpaces = extraSpaces; + VisitChildren(queryExpression); + + curIndent = oldIndent; + } + + public override void VisitQueryFromClause(QueryFromClause queryFromClause) + { + FixClauseIndentation(queryFromClause, queryFromClause.FromKeyword); + } + + public override void VisitQueryContinuationClause(QueryContinuationClause queryContinuationClause) + { + VisitChildren(queryContinuationClause); + } + + public override void VisitQueryGroupClause(QueryGroupClause queryGroupClause) + { + FixClauseIndentation(queryGroupClause, queryGroupClause.GroupKeyword); + } + + public override void VisitQueryJoinClause(QueryJoinClause queryJoinClause) + { + FixClauseIndentation(queryJoinClause, queryJoinClause.JoinKeyword); + } + + public override void VisitQueryLetClause(QueryLetClause queryLetClause) + { + FixClauseIndentation(queryLetClause, queryLetClause.LetKeyword); + } + + public override void VisitQuerySelectClause(QuerySelectClause querySelectClause) + { + FixClauseIndentation(querySelectClause, querySelectClause.SelectKeyword); + } + + public override void VisitQueryOrderClause(QueryOrderClause queryOrderClause) + { + FixClauseIndentation(queryOrderClause, queryOrderClause.OrderbyToken); + } + + public override void VisitQueryWhereClause(QueryWhereClause queryWhereClause) + { + FixClauseIndentation(queryWhereClause, queryWhereClause.WhereKeyword); + } + + void FixClauseIndentation(QueryClause clause, AstNode keyword) { + var parentExpression = clause.GetParent(); + bool isFirstClause = parentExpression.Clauses.First() == clause; + if (!isFirstClause) { + PlaceOnNewLine(policy.NewLineBeforeNewQueryClause, keyword); + } + + int extraSpaces = options.IndentSize; + curIndent.ExtraSpaces += extraSpaces; + foreach (var child in clause.Children) { + var expression = child as Expression; + if (expression != null) { + FixIndentation(child); + child.AcceptVisitor(this); + } + + var tokenNode = child as CSharpTokenNode; + if (tokenNode != null) { + if (tokenNode.GetNextSibling(NoWhitespacePredicate).StartLocation.Line != tokenNode.EndLocation.Line) { + ForceSpacesAfter(tokenNode, false); + } + } + } + curIndent.ExtraSpaces -= extraSpaces; + } + } +} + diff --git a/NRefactory/ICSharpCode.NRefactory.CSharp/Formatter/FormattingVisitor_Statements.cs b/NRefactory/ICSharpCode.NRefactory.CSharp/Formatter/FormattingVisitor_Statements.cs new file mode 100644 index 000000000..3c5c92095 --- /dev/null +++ b/NRefactory/ICSharpCode.NRefactory.CSharp/Formatter/FormattingVisitor_Statements.cs @@ -0,0 +1,517 @@ +// +// AstFormattingVisitor_Statements.cs +// +// Author: +// Mike Krüger +// +// Copyright (c) 2013 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 System.Linq; +using ICSharpCode.NRefactory.Editor; + +namespace ICSharpCode.NRefactory.CSharp +{ + partial class FormattingVisitor : DepthFirstAstVisitor + { + public override void VisitExpressionStatement(ExpressionStatement expressionStatement) + { + base.VisitExpressionStatement(expressionStatement); + FixSemicolon(expressionStatement.SemicolonToken); + } + + void VisitBlockWithoutFixingBraces(BlockStatement blockStatement, bool indent) + { + if (indent) { + curIndent.Push(IndentType.Block); + } + + VisitChildrenToFormat (blockStatement, child => { + if (child.Role == Roles.LBrace || child.Role == Roles.RBrace) { + return; + } + + if (child is Statement) { + FixStatementIndentation(child.StartLocation); + child.AcceptVisitor(this); + } else if (child is Comment) { + child.AcceptVisitor(this); + } else if (child is NewLineNode) { + // ignore + } else { + // pre processor directives at line start, if they are there. + if (child.StartLocation.Column > 1) + FixStatementIndentation(child.StartLocation); + } + }); + + if (indent) { + curIndent.Pop (); + } + } + + public override void VisitBlockStatement(BlockStatement blockStatement) + { + FixIndentation(blockStatement); + VisitBlockWithoutFixingBraces(blockStatement, policy.IndentBlocks); + FixIndentation(blockStatement.RBraceToken); + } + + public override void VisitBreakStatement(BreakStatement breakStatement) + { + FixSemicolon(breakStatement.SemicolonToken); + } + + public override void VisitCheckedStatement(CheckedStatement checkedStatement) + { + FixEmbeddedStatment(policy.StatementBraceStyle, checkedStatement.Body); + } + + public override void VisitContinueStatement(ContinueStatement continueStatement) + { + FixSemicolon(continueStatement.SemicolonToken); + } + + public override void VisitEmptyStatement(EmptyStatement emptyStatement) + { + // Empty + } + + public override void VisitFixedStatement(FixedStatement fixedStatement) + { + FixEmbeddedStatment(policy.StatementBraceStyle, fixedStatement.EmbeddedStatement); + } + + public override void VisitForeachStatement(ForeachStatement foreachStatement) + { + ForceSpacesBeforeRemoveNewLines(foreachStatement.LParToken, policy.SpaceBeforeForeachParentheses); + + ForceSpacesAfter(foreachStatement.LParToken, policy.SpacesWithinForeachParentheses); + ForceSpacesBeforeRemoveNewLines(foreachStatement.RParToken, policy.SpacesWithinForeachParentheses); + + FixEmbeddedStatment(policy.StatementBraceStyle, foreachStatement.EmbeddedStatement); + } + + void FixEmbeddedStatment(BraceStyle braceStyle, AstNode node) + { + FixEmbeddedStatment(braceStyle, null, false, node); + } + + void FixEmbeddedStatment(BraceStyle braceStyle, CSharpTokenNode token, bool allowInLine, AstNode node, bool statementAlreadyIndented = false) + { + if (node == null) + return; + bool isBlock = node is BlockStatement; + FormattingChanges.TextReplaceAction beginBraceAction = null; + FormattingChanges.TextReplaceAction endBraceAction = null; + BlockStatement closeBlockToBeFixed = null; + if (isBlock) { + BlockStatement block = node as BlockStatement; + if (allowInLine && block.StartLocation.Line == block.EndLocation.Line && block.Statements.Count() <= 1) { + if (block.Statements.Count() == 1) + nextStatementIndent = " "; + } else { + if (!statementAlreadyIndented) + FixOpenBrace(braceStyle, block.LBraceToken); + closeBlockToBeFixed = block; + } + + if (braceStyle == BraceStyle.NextLineShifted2) + curIndent.Push(IndentType.Block); + } else { + if (allowInLine && token.StartLocation.Line == node.EndLocation.Line) { + nextStatementIndent = " "; + } + } + bool pushed = false; + + if (policy.IndentBlocks && !( + policy.AlignEmbeddedStatements && node is IfElseStatement && node.Parent is IfElseStatement || + policy.AlignEmbeddedStatements && node is UsingStatement && node.Parent is UsingStatement || + policy.AlignEmbeddedStatements && node is LockStatement && node.Parent is LockStatement)) { + curIndent.Push(IndentType.Block); + pushed = true; + } + if (isBlock) { + VisitBlockWithoutFixingBraces((BlockStatement)node, false); + } else { + if (!statementAlreadyIndented) { + PlaceOnNewLine(policy.EmbeddedStatementPlacement, node); + nextStatementIndent = null; + } + node.AcceptVisitor(this); + } + nextStatementIndent = null; + if (pushed) + curIndent.Pop(); + if (beginBraceAction != null && endBraceAction != null) { + beginBraceAction.DependsOn = endBraceAction; + endBraceAction.DependsOn = beginBraceAction; + } + + if (isBlock && braceStyle == BraceStyle.NextLineShifted2) + curIndent.Pop(); + if (closeBlockToBeFixed != null) { + FixClosingBrace(braceStyle, closeBlockToBeFixed.RBraceToken); + } + + } + + public bool IsLineIsEmptyUpToEol(TextLocation startLocation) + { + return IsLineIsEmptyUpToEol(document.GetOffset(startLocation) - 1); + } + + bool IsLineIsEmptyUpToEol(int startOffset) + { + for (int offset = startOffset - 1; offset >= 0; offset--) { + char ch = document.GetCharAt(offset); + if (ch != ' ' && ch != '\t') { + return NewLine.IsNewLine (ch); + } + } + return true; + } + + int SearchWhitespaceStart(int startOffset) + { + if (startOffset < 0) { + throw new ArgumentOutOfRangeException ("startoffset", "value : " + startOffset); + } + for (int offset = startOffset - 1; offset >= 0; offset--) { + char ch = document.GetCharAt(offset); + if (!Char.IsWhiteSpace(ch)) { + return offset + 1; + } + } + return 0; + } + + int SearchWhitespaceEnd(int startOffset) + { + if (startOffset > document.TextLength) { + throw new ArgumentOutOfRangeException ("startoffset", "value : " + startOffset); + } + for (int offset = startOffset + 1; offset < document.TextLength; offset++) { + char ch = document.GetCharAt(offset); + if (!Char.IsWhiteSpace(ch)) { + return offset + 1; + } + } + return document.TextLength - 1; + } + + int SearchWhitespaceLineStart(int startOffset) + { + if (startOffset < 0) { + throw new ArgumentOutOfRangeException ("startoffset", "value : " + startOffset); + } + for (int offset = startOffset - 1; offset >= 0; offset--) { + char ch = document.GetCharAt(offset); + if (ch != ' ' && ch != '\t') { + return offset + 1; + } + } + return 0; + } + + public override void VisitForStatement(ForStatement forStatement) + { + foreach (AstNode node in forStatement.Children) { + if (node.Role == Roles.Semicolon) { + if (node.GetNextSibling(NoWhitespacePredicate) is CSharpTokenNode || node.GetNextSibling(NoWhitespacePredicate) is EmptyStatement) { + continue; + } + ForceSpacesBefore(node, policy.SpaceBeforeForSemicolon); + ForceSpacesAfter(node, policy.SpaceAfterForSemicolon); + } else if (node.Role == Roles.LPar) { + ForceSpacesBeforeRemoveNewLines(node, policy.SpaceBeforeForParentheses); + ForceSpacesAfter(node, policy.SpacesWithinForParentheses); + } else if (node.Role == Roles.RPar) { + ForceSpacesBeforeRemoveNewLines(node, policy.SpacesWithinForParentheses); + } else if (node.Role == Roles.EmbeddedStatement) { + FixEmbeddedStatment(policy.StatementBraceStyle, node); + } else { + node.AcceptVisitor(this); + } + } + } + + public override void VisitGotoStatement(GotoStatement gotoStatement) + { + VisitChildren(gotoStatement); + FixSemicolon(gotoStatement.SemicolonToken); + } + + public override void VisitIfElseStatement(IfElseStatement ifElseStatement) + { + ForceSpacesBeforeRemoveNewLines(ifElseStatement.LParToken, policy.SpaceBeforeIfParentheses); + Align(ifElseStatement.LParToken, ifElseStatement.Condition, policy.SpacesWithinIfParentheses); + ForceSpacesBeforeRemoveNewLines(ifElseStatement.RParToken, policy.SpacesWithinIfParentheses); + + + if (!ifElseStatement.TrueStatement.IsNull) { + FixEmbeddedStatment(policy.StatementBraceStyle, ifElseStatement.IfToken, policy.AllowIfBlockInline, ifElseStatement.TrueStatement); + } + + if (!ifElseStatement.FalseStatement.IsNull) { + var placeElseOnNewLine = policy.ElseNewLinePlacement; + if (!(ifElseStatement.TrueStatement is BlockStatement)) { + placeElseOnNewLine = NewLinePlacement.NewLine; + } + PlaceOnNewLine(placeElseOnNewLine, ifElseStatement.ElseToken); + if (ifElseStatement.FalseStatement is IfElseStatement) { + PlaceOnNewLine(policy.ElseIfNewLinePlacement, ((IfElseStatement)ifElseStatement.FalseStatement).IfToken); + } + FixEmbeddedStatment(policy.StatementBraceStyle, ifElseStatement.ElseToken, policy.AllowIfBlockInline, ifElseStatement.FalseStatement, ifElseStatement.FalseStatement is IfElseStatement); + } + } + + public override void VisitLabelStatement(LabelStatement labelStatement) + { + // TODO + VisitChildren(labelStatement); + } + + public override void VisitLockStatement(LockStatement lockStatement) + { + ForceSpacesBeforeRemoveNewLines(lockStatement.LParToken, policy.SpaceBeforeLockParentheses); + + ForceSpacesAfter(lockStatement.LParToken, policy.SpacesWithinLockParentheses); + ForceSpacesBeforeRemoveNewLines(lockStatement.RParToken, policy.SpacesWithinLockParentheses); + + FixEmbeddedStatment(policy.StatementBraceStyle, lockStatement.EmbeddedStatement); + } + + public override void VisitReturnStatement(ReturnStatement returnStatement) + { + VisitChildren(returnStatement); + FixSemicolon(returnStatement.SemicolonToken); + } + + public override void VisitSwitchStatement(SwitchStatement switchStatement) + { + ForceSpacesBeforeRemoveNewLines(switchStatement.LParToken, policy.SpaceBeforeSwitchParentheses); + + ForceSpacesAfter(switchStatement.LParToken, policy.SpacesWithinSwitchParentheses); + ForceSpacesBeforeRemoveNewLines(switchStatement.RParToken, policy.SpacesWithinSwitchParentheses); + + FixOpenBrace(policy.StatementBraceStyle, switchStatement.LBraceToken); + VisitChildren(switchStatement); + FixClosingBrace(policy.StatementBraceStyle, switchStatement.RBraceToken); + } + + public override void VisitSwitchSection(SwitchSection switchSection) + { + if (policy.IndentSwitchBody) { + curIndent.Push(IndentType.Block); + } + + foreach (CaseLabel label in switchSection.CaseLabels) { + FixStatementIndentation(label.StartLocation); + label.AcceptVisitor(this); + } + if (policy.IndentCaseBody) { + curIndent.Push(IndentType.Block); + } + + foreach (var stmt in switchSection.Statements) { + if (stmt is BreakStatement && !policy.IndentBreakStatements && policy.IndentCaseBody) { + curIndent.Pop(); + FixStatementIndentation(stmt.StartLocation); + stmt.AcceptVisitor(this); + curIndent.Push(IndentType.Block); + continue; + } + FixStatementIndentation(stmt.StartLocation); + stmt.AcceptVisitor(this); + } + if (policy.IndentCaseBody) { + curIndent.Pop (); + } + + if (policy.IndentSwitchBody) { + curIndent.Pop (); + } + } + + public override void VisitCaseLabel(CaseLabel caseLabel) + { + ForceSpacesBefore(caseLabel.ColonToken, false); + } + + public override void VisitThrowStatement(ThrowStatement throwStatement) + { + VisitChildren(throwStatement); + FixSemicolon(throwStatement.SemicolonToken); + } + + public override void VisitTryCatchStatement(TryCatchStatement tryCatchStatement) + { + if (!tryCatchStatement.TryBlock.IsNull) { + FixEmbeddedStatment(policy.StatementBraceStyle, tryCatchStatement.TryBlock); + } + + foreach (CatchClause clause in tryCatchStatement.CatchClauses) { + PlaceOnNewLine(policy.CatchNewLinePlacement, clause.CatchToken); + if (!clause.LParToken.IsNull) { + ForceSpacesBeforeRemoveNewLines(clause.LParToken, policy.SpaceBeforeCatchParentheses); + + ForceSpacesAfter(clause.LParToken, policy.SpacesWithinCatchParentheses); + ForceSpacesBeforeRemoveNewLines(clause.RParToken, policy.SpacesWithinCatchParentheses); + } + FixEmbeddedStatment(policy.StatementBraceStyle, clause.Body); + } + + if (!tryCatchStatement.FinallyBlock.IsNull) { + PlaceOnNewLine(policy.FinallyNewLinePlacement, tryCatchStatement.FinallyToken); + + FixEmbeddedStatment(policy.StatementBraceStyle, tryCatchStatement.FinallyBlock); + } + + } + + public override void VisitCatchClause(CatchClause catchClause) + { + // Handled in TryCatchStatement + } + + public override void VisitUncheckedStatement(UncheckedStatement uncheckedStatement) + { + FixEmbeddedStatment(policy.StatementBraceStyle, uncheckedStatement.Body); + } + + public override void VisitUnsafeStatement(UnsafeStatement unsafeStatement) + { + FixEmbeddedStatment(policy.StatementBraceStyle, unsafeStatement.Body); + } + + public override void VisitUsingStatement(UsingStatement usingStatement) + { + ForceSpacesBeforeRemoveNewLines(usingStatement.LParToken, policy.SpaceBeforeUsingParentheses); + + Align(usingStatement.LParToken, usingStatement.ResourceAcquisition, policy.SpacesWithinUsingParentheses); + + ForceSpacesBeforeRemoveNewLines(usingStatement.RParToken, policy.SpacesWithinUsingParentheses); + + FixEmbeddedStatment(policy.StatementBraceStyle, usingStatement.EmbeddedStatement); + } + + public override void VisitVariableDeclarationStatement(VariableDeclarationStatement variableDeclarationStatement) + { + var returnType = variableDeclarationStatement.Type; + returnType.AcceptVisitor(this); + if ((variableDeclarationStatement.Modifiers & Modifiers.Const) == Modifiers.Const) { + ForceSpacesAround(returnType, true); + } else { + ForceSpacesAfter(returnType, true); + } + var lastLoc = variableDeclarationStatement.StartLocation; + foreach (var initializer in variableDeclarationStatement.Variables) { + if (lastLoc.Line != initializer.StartLocation.Line) { + FixStatementIndentation(initializer.StartLocation); + lastLoc = initializer.StartLocation; + } + initializer.AcceptVisitor(this); + } + + FormatCommas(variableDeclarationStatement, policy.SpaceBeforeLocalVariableDeclarationComma, policy.SpaceAfterLocalVariableDeclarationComma); + FixSemicolon(variableDeclarationStatement.SemicolonToken); + } + + public override void VisitDoWhileStatement(DoWhileStatement doWhileStatement) + { + FixEmbeddedStatment(policy.StatementBraceStyle, doWhileStatement.EmbeddedStatement); + PlaceOnNewLine(doWhileStatement.EmbeddedStatement is BlockStatement ? policy.WhileNewLinePlacement : NewLinePlacement.NewLine, doWhileStatement.WhileToken); + + Align(doWhileStatement.LParToken, doWhileStatement.Condition, policy.SpacesWithinWhileParentheses); + ForceSpacesBeforeRemoveNewLines(doWhileStatement.RParToken, policy.SpacesWithinWhileParentheses); + } + + void Align(AstNode lPar, AstNode alignNode, bool space) + { + int extraSpaces = 0; + var useExtraSpaces = lPar.StartLocation.Line == alignNode.StartLocation.Line; + if (useExtraSpaces) { + extraSpaces = Math.Max(0, lPar.StartLocation.Column + (space ? 1 : 0) - curIndent.IndentString.Length); + curIndent.ExtraSpaces += extraSpaces; + ForceSpacesAfter(lPar, space); + } else { + curIndent.Push(IndentType.Continuation); + FixIndentation(alignNode); + } + alignNode.AcceptVisitor(this); + + if (useExtraSpaces) { + curIndent.ExtraSpaces -= extraSpaces; + } else { + curIndent.Pop(); + } + + } + + public override void VisitWhileStatement(WhileStatement whileStatement) + { + ForceSpacesBeforeRemoveNewLines(whileStatement.LParToken, policy.SpaceBeforeWhileParentheses); + Align(whileStatement.LParToken, whileStatement.Condition, policy.SpacesWithinWhileParentheses); + ForceSpacesBeforeRemoveNewLines(whileStatement.RParToken, policy.SpacesWithinWhileParentheses); + + FixEmbeddedStatment(policy.StatementBraceStyle, whileStatement.EmbeddedStatement); + } + + public override void VisitYieldBreakStatement(YieldBreakStatement yieldBreakStatement) + { + FixSemicolon(yieldBreakStatement.SemicolonToken); + } + + public override void VisitYieldReturnStatement(YieldReturnStatement yieldStatement) + { + yieldStatement.Expression.AcceptVisitor(this); + FixSemicolon(yieldStatement.SemicolonToken); + } + + public override void VisitVariableInitializer(VariableInitializer variableInitializer) + { + if (!variableInitializer.AssignToken.IsNull) { + ForceSpacesAround(variableInitializer.AssignToken, policy.SpaceAroundAssignment); + } + if (!variableInitializer.Initializer.IsNull) { + int extraSpaces = 0; + var useExtraSpaces = variableInitializer.AssignToken.StartLocation.Line == variableInitializer.Initializer.StartLocation.Line; + if (useExtraSpaces) { + extraSpaces = Math.Max(0, variableInitializer.AssignToken.StartLocation.Column + 1 - curIndent.IndentString.Length); + curIndent.ExtraSpaces += extraSpaces; + } else { + curIndent.Push(IndentType.Continuation); + FixIndentation(variableInitializer.Initializer); + } + variableInitializer.Initializer.AcceptVisitor(this); + + if (useExtraSpaces) { + curIndent.ExtraSpaces -= extraSpaces; + } else { + curIndent.Pop(); + } + } + + } + } +} + diff --git a/NRefactory/ICSharpCode.NRefactory.CSharp/Formatter/FormattingVisitor_TypeMembers.cs b/NRefactory/ICSharpCode.NRefactory.CSharp/Formatter/FormattingVisitor_TypeMembers.cs new file mode 100644 index 000000000..913a61e2e --- /dev/null +++ b/NRefactory/ICSharpCode.NRefactory.CSharp/Formatter/FormattingVisitor_TypeMembers.cs @@ -0,0 +1,477 @@ +// +// AstFormattingVisitor_TypeMembers.cs +// +// Author: +// Mike Krüger +// +// Copyright (c) 2013 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 System.Linq; + +namespace ICSharpCode.NRefactory.CSharp +{ + partial class FormattingVisitor : DepthFirstAstVisitor + { + public override void VisitPropertyDeclaration(PropertyDeclaration propertyDeclaration) + { + FixAttributesAndDocComment(propertyDeclaration); + bool oneLine = false; + bool fixClosingBrace = false; + PropertyFormatting propertyFormatting; + + if ((propertyDeclaration.Getter.IsNull || propertyDeclaration.Getter.Body.IsNull) && + (propertyDeclaration.Setter.IsNull || propertyDeclaration.Setter.Body.IsNull)) { + propertyFormatting = policy.AutoPropertyFormatting; + } else { + propertyFormatting = policy.SimplePropertyFormatting; + } + + switch (propertyFormatting) { + case PropertyFormatting.AllowOneLine: + bool isSimple = IsSimpleAccessor(propertyDeclaration.Getter) && IsSimpleAccessor(propertyDeclaration.Setter); + 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 && + Math.Min(propertyDeclaration.Getter.StartLocation.Line, propertyDeclaration.Setter.StartLocation.Line) == propertyDeclaration.LBraceToken.StartLocation.Line && + propertyDeclaration.Getter.StartLocation.Line != propertyDeclaration.Setter.StartLocation.Line) + goto case PropertyFormatting.ForceOneLine; + if (!isSimple || propertyDeclaration.LBraceToken.StartLocation.Line != accessorLine) { + fixClosingBrace = true; + FixOpenBrace(policy.PropertyBraceStyle, propertyDeclaration.LBraceToken); + } else { + ForceSpacesBefore(propertyDeclaration.Getter, true); + ForceSpacesBefore(propertyDeclaration.Setter, true); + ForceSpacesBeforeRemoveNewLines(propertyDeclaration.RBraceToken, true); + oneLine = true; + } + break; + case PropertyFormatting.ForceNewLine: + fixClosingBrace = true; + FixOpenBrace(policy.PropertyBraceStyle, propertyDeclaration.LBraceToken); + break; + case PropertyFormatting.ForceOneLine: + isSimple = IsSimpleAccessor(propertyDeclaration.Getter) && IsSimpleAccessor(propertyDeclaration.Setter); + if (isSimple) { + var lBraceToken = propertyDeclaration.LBraceToken; + var rBraceToken = propertyDeclaration.RBraceToken; + ForceSpacesBeforeRemoveNewLines(lBraceToken, true); + if (!propertyDeclaration.Getter.IsNull) + ForceSpacesBeforeRemoveNewLines(propertyDeclaration.Getter, true); + if (!propertyDeclaration.Setter.IsNull) + ForceSpacesBeforeRemoveNewLines(propertyDeclaration.Setter, true); + + ForceSpacesBeforeRemoveNewLines(rBraceToken, true); + oneLine = true; + } else { + fixClosingBrace = true; + FixOpenBrace(policy.PropertyBraceStyle, propertyDeclaration.LBraceToken); + } + break; + } + if (policy.IndentPropertyBody) + curIndent.Push(IndentType.Block); + + FormatAccessor(propertyDeclaration.Getter, policy.PropertyGetBraceStyle, policy.SimpleGetBlockFormatting, oneLine); + FormatAccessor(propertyDeclaration.Setter, policy.PropertySetBraceStyle, policy.SimpleSetBlockFormatting, oneLine); + + if (policy.IndentPropertyBody) { + curIndent.Pop(); + } + if (fixClosingBrace) + FixClosingBrace(policy.PropertyBraceStyle, propertyDeclaration.RBraceToken); + + } + + void FormatAccessor(Accessor accessor, BraceStyle braceStyle, PropertyFormatting blockFormatting, bool oneLine) + { + if (accessor.IsNull) + return; + if (!oneLine) { + if (!IsLineIsEmptyUpToEol(accessor.StartLocation)) { + int offset = this.document.GetOffset(accessor.StartLocation); + int start = SearchWhitespaceStart(offset); + string indentString = this.curIndent.IndentString; + AddChange(start, offset - start, this.options.EolMarker + indentString); + } else { + FixIndentation(accessor); + } + } else { + blockFormatting = PropertyFormatting.ForceOneLine; + if (!accessor.Body.IsNull) { + ForceSpacesBeforeRemoveNewLines(accessor.Body.LBraceToken, true); + ForceSpacesBeforeRemoveNewLines(accessor.Body.RBraceToken, true); + } + } + + + if (!accessor.IsNull) { + if (!accessor.Body.IsNull) { + if (IsSimpleAccessor (accessor)) { + switch (blockFormatting) { + case PropertyFormatting.AllowOneLine: + if (accessor.Body.LBraceToken.StartLocation.Line != accessor.Body.RBraceToken.StartLocation.Line) + goto case PropertyFormatting.ForceNewLine; + nextStatementIndent = " "; + VisitBlockWithoutFixingBraces(accessor.Body, policy.IndentBlocks); + nextStatementIndent = null; + if (!oneLine) + ForceSpacesBeforeRemoveNewLines(accessor.Body.RBraceToken, true); + break; + case PropertyFormatting.ForceOneLine: + FixOpenBrace(BraceStyle.EndOfLine, accessor.Body.LBraceToken); + + + var statement = accessor.Body.Statements.FirstOrDefault(); + if (statement != null) { + ForceSpacesBeforeRemoveNewLines(statement, true); + statement.AcceptVisitor(this); + } + if (!oneLine) + ForceSpacesBeforeRemoveNewLines(accessor.Body.RBraceToken, true); + break; + case PropertyFormatting.ForceNewLine: + FixOpenBrace(braceStyle, accessor.Body.LBraceToken); + VisitBlockWithoutFixingBraces(accessor.Body, policy.IndentBlocks); + if (!oneLine) + FixClosingBrace(braceStyle, accessor.Body.RBraceToken); + break; + } + } else { + FixOpenBrace(braceStyle, accessor.Body.LBraceToken); + VisitBlockWithoutFixingBraces(accessor.Body, policy.IndentBlocks); + FixClosingBrace(braceStyle, accessor.Body.RBraceToken); + } + } + } + } + + public override void VisitAccessor(Accessor accessor) + { + FixAttributesAndDocComment(accessor); + + base.VisitAccessor(accessor); + } + + public override void VisitIndexerDeclaration(IndexerDeclaration indexerDeclaration) + { + FixAttributesAndDocComment(indexerDeclaration); + + ForceSpacesBefore(indexerDeclaration.LBracketToken, policy.SpaceBeforeIndexerDeclarationBracket); + ForceSpacesAfter(indexerDeclaration.LBracketToken, policy.SpaceWithinIndexerDeclarationBracket); + + FormatArguments(indexerDeclaration); + + bool oneLine = false; + bool fixClosingBrace = false; + switch (policy.SimplePropertyFormatting) { + case PropertyFormatting.AllowOneLine: + bool isSimple = IsSimpleAccessor(indexerDeclaration.Getter) && IsSimpleAccessor(indexerDeclaration.Setter); + int accessorLine = indexerDeclaration.RBraceToken.StartLocation.Line; + if (!indexerDeclaration.Getter.IsNull && indexerDeclaration.Setter.IsNull) { + accessorLine = indexerDeclaration.Getter.StartLocation.Line; + } else if (indexerDeclaration.Getter.IsNull && !indexerDeclaration.Setter.IsNull) { + accessorLine = indexerDeclaration.Setter.StartLocation.Line; + } else { + var acc = indexerDeclaration.Getter.StartLocation < indexerDeclaration.Setter.StartLocation ? + indexerDeclaration.Getter : indexerDeclaration.Setter; + accessorLine = acc.StartLocation.Line; + } + if (!isSimple || indexerDeclaration.LBraceToken.StartLocation.Line != accessorLine) { + fixClosingBrace = true; + FixOpenBrace(policy.PropertyBraceStyle, indexerDeclaration.LBraceToken); + } else { + ForceSpacesBefore(indexerDeclaration.Getter, true); + ForceSpacesBefore(indexerDeclaration.Setter, true); + ForceSpacesBeforeRemoveNewLines(indexerDeclaration.RBraceToken, true); + oneLine = true; + } + break; + case PropertyFormatting.ForceNewLine: + fixClosingBrace = true; + FixOpenBrace(policy.PropertyBraceStyle, indexerDeclaration.LBraceToken); + break; + case PropertyFormatting.ForceOneLine: + isSimple = IsSimpleAccessor(indexerDeclaration.Getter) && IsSimpleAccessor(indexerDeclaration.Setter); + if (isSimple) { + int offset = this.document.GetOffset(indexerDeclaration.LBraceToken.StartLocation); + + int start = SearchWhitespaceStart(offset); + int end = SearchWhitespaceEnd(offset); + AddChange(start, offset - start, " "); + AddChange(offset + 1, end - offset - 2, " "); + + offset = this.document.GetOffset(indexerDeclaration.RBraceToken.StartLocation); + start = SearchWhitespaceStart(offset); + AddChange(start, offset - start, " "); + oneLine = true; + + } else { + fixClosingBrace = true; + FixOpenBrace(policy.PropertyBraceStyle, indexerDeclaration.LBraceToken); + } + break; + } + + if (policy.IndentPropertyBody) + curIndent.Push(IndentType.Block); + + FormatAccessor(indexerDeclaration.Getter, policy.PropertyGetBraceStyle, policy.SimpleGetBlockFormatting, oneLine); + FormatAccessor(indexerDeclaration.Setter, policy.PropertySetBraceStyle, policy.SimpleSetBlockFormatting, oneLine); + if (policy.IndentPropertyBody) + curIndent.Pop(); + + if (fixClosingBrace) + FixClosingBrace(policy.PropertyBraceStyle, indexerDeclaration.RBraceToken); + } + + static bool IsSimpleEvent(AstNode node) + { + return node is EventDeclaration; + } + + public override void VisitCustomEventDeclaration(CustomEventDeclaration eventDeclaration) + { + FixAttributesAndDocComment(eventDeclaration); + + FixOpenBrace(policy.EventBraceStyle, eventDeclaration.LBraceToken); + if (policy.IndentEventBody) + curIndent.Push(IndentType.Block); + + if (!eventDeclaration.AddAccessor.IsNull) { + FixIndentation(eventDeclaration.AddAccessor); + if (!eventDeclaration.AddAccessor.Body.IsNull) { + if (!policy.AllowEventAddBlockInline || eventDeclaration.AddAccessor.Body.LBraceToken.StartLocation.Line != eventDeclaration.AddAccessor.Body.RBraceToken.StartLocation.Line) { + FixOpenBrace(policy.EventAddBraceStyle, eventDeclaration.AddAccessor.Body.LBraceToken); + VisitBlockWithoutFixingBraces(eventDeclaration.AddAccessor.Body, policy.IndentBlocks); + FixClosingBrace(policy.EventAddBraceStyle, eventDeclaration.AddAccessor.Body.RBraceToken); + } else { + nextStatementIndent = " "; + VisitBlockWithoutFixingBraces(eventDeclaration.AddAccessor.Body, policy.IndentBlocks); + nextStatementIndent = null; + } + } + } + + if (!eventDeclaration.RemoveAccessor.IsNull) { + FixIndentation(eventDeclaration.RemoveAccessor); + if (!eventDeclaration.RemoveAccessor.Body.IsNull) { + if (!policy.AllowEventRemoveBlockInline || eventDeclaration.RemoveAccessor.Body.LBraceToken.StartLocation.Line != eventDeclaration.RemoveAccessor.Body.RBraceToken.StartLocation.Line) { + FixOpenBrace(policy.EventRemoveBraceStyle, eventDeclaration.RemoveAccessor.Body.LBraceToken); + VisitBlockWithoutFixingBraces(eventDeclaration.RemoveAccessor.Body, policy.IndentBlocks); + FixClosingBrace(policy.EventRemoveBraceStyle, eventDeclaration.RemoveAccessor.Body.RBraceToken); + } else { + nextStatementIndent = " "; + VisitBlockWithoutFixingBraces(eventDeclaration.RemoveAccessor.Body, policy.IndentBlocks); + nextStatementIndent = null; + } + } + } + + if (policy.IndentEventBody) + curIndent.Pop(); + + FixClosingBrace(policy.EventBraceStyle, eventDeclaration.RBraceToken); + } + + public override void VisitEventDeclaration(EventDeclaration eventDeclaration) + { + FixAttributesAndDocComment(eventDeclaration); + + foreach (var m in eventDeclaration.ModifierTokens) { + ForceSpacesAfter(m, true); + } + + ForceSpacesBeforeRemoveNewLines(eventDeclaration.EventToken.GetNextSibling(NoWhitespacePredicate), true); + eventDeclaration.ReturnType.AcceptVisitor(this); + ForceSpacesAfter(eventDeclaration.ReturnType, true); + /* + var lastLoc = eventDeclaration.StartLocation; + curIndent.Push(IndentType.Block); + foreach (var initializer in eventDeclaration.Variables) { + if (lastLoc.Line != initializer.StartLocation.Line) { + FixStatementIndentation(initializer.StartLocation); + lastLoc = initializer.StartLocation; + } + initializer.AcceptVisitor(this); + } + curIndent.Pop (); + */ + FixSemicolon(eventDeclaration.SemicolonToken); + } + + public override void VisitFieldDeclaration(FieldDeclaration fieldDeclaration) + { + FixAttributesAndDocComment(fieldDeclaration); + + fieldDeclaration.ReturnType.AcceptVisitor(this); + ForceSpacesAfter(fieldDeclaration.ReturnType, true); + + FormatCommas(fieldDeclaration, policy.SpaceBeforeFieldDeclarationComma, policy.SpaceAfterFieldDeclarationComma); + + var lastLoc = fieldDeclaration.ReturnType.StartLocation; + foreach (var initializer in fieldDeclaration.Variables) { + if (lastLoc.Line != initializer.StartLocation.Line) { + curIndent.Push(IndentType.Block); + FixStatementIndentation(initializer.StartLocation); + curIndent.Pop(); + lastLoc = initializer.StartLocation; + } + initializer.AcceptVisitor(this); + } + FixSemicolon(fieldDeclaration.SemicolonToken); + } + + public override void VisitFixedFieldDeclaration(FixedFieldDeclaration fixedFieldDeclaration) + { + FixAttributesAndDocComment(fixedFieldDeclaration); + + FormatCommas(fixedFieldDeclaration, policy.SpaceBeforeFieldDeclarationComma, policy.SpaceAfterFieldDeclarationComma); + + var lastLoc = fixedFieldDeclaration.StartLocation; + curIndent.Push(IndentType.Block); + foreach (var initializer in fixedFieldDeclaration.Variables) { + if (lastLoc.Line != initializer.StartLocation.Line) { + FixStatementIndentation(initializer.StartLocation); + lastLoc = initializer.StartLocation; + } + initializer.AcceptVisitor(this); + } + curIndent.Pop(); + FixSemicolon(fixedFieldDeclaration.SemicolonToken); + } + + public override void VisitEnumMemberDeclaration(EnumMemberDeclaration enumMemberDeclaration) + { + FixAttributesAndDocComment(enumMemberDeclaration); + var initializer = enumMemberDeclaration.Initializer; + if (!initializer.IsNull) { + ForceSpacesAround(enumMemberDeclaration.AssignToken, policy.SpaceAroundAssignment); + initializer.AcceptVisitor(this); + } + } + + public override void VisitMethodDeclaration(MethodDeclaration methodDeclaration) + { + FixAttributesAndDocComment(methodDeclaration); + + ForceSpacesBefore(methodDeclaration.LParToken, policy.SpaceBeforeMethodDeclarationParentheses); + if (methodDeclaration.Parameters.Any()) { + ForceSpacesAfter(methodDeclaration.LParToken, policy.SpaceWithinMethodDeclarationParentheses); + FormatArguments(methodDeclaration); + } else { + ForceSpacesAfter(methodDeclaration.LParToken, policy.SpaceBetweenEmptyMethodDeclarationParentheses); + ForceSpacesBefore(methodDeclaration.RParToken, policy.SpaceBetweenEmptyMethodDeclarationParentheses); + } + + foreach (var constraint in methodDeclaration.Constraints) + constraint.AcceptVisitor(this); + + if (!methodDeclaration.Body.IsNull) { + FixOpenBrace(policy.MethodBraceStyle, methodDeclaration.Body.LBraceToken); + VisitBlockWithoutFixingBraces(methodDeclaration.Body, policy.IndentMethodBody); + FixClosingBrace(policy.MethodBraceStyle, methodDeclaration.Body.RBraceToken); + } + } + + public override void VisitOperatorDeclaration(OperatorDeclaration operatorDeclaration) + { + FixAttributesAndDocComment(operatorDeclaration); + + ForceSpacesBefore(operatorDeclaration.LParToken, policy.SpaceBeforeMethodDeclarationParentheses); + if (operatorDeclaration.Parameters.Any()) { + ForceSpacesAfter(operatorDeclaration.LParToken, policy.SpaceWithinMethodDeclarationParentheses); + FormatArguments(operatorDeclaration); + } else { + ForceSpacesAfter(operatorDeclaration.LParToken, policy.SpaceBetweenEmptyMethodDeclarationParentheses); + ForceSpacesBefore(operatorDeclaration.RParToken, policy.SpaceBetweenEmptyMethodDeclarationParentheses); + } + + if (!operatorDeclaration.Body.IsNull) { + FixOpenBrace(policy.MethodBraceStyle, operatorDeclaration.Body.LBraceToken); + VisitBlockWithoutFixingBraces(operatorDeclaration.Body, policy.IndentMethodBody); + FixClosingBrace(policy.MethodBraceStyle, operatorDeclaration.Body.RBraceToken); + } + } + + public override void VisitConstructorDeclaration(ConstructorDeclaration constructorDeclaration) + { + FixAttributesAndDocComment(constructorDeclaration); + + ForceSpacesBefore(constructorDeclaration.LParToken, policy.SpaceBeforeConstructorDeclarationParentheses); + if (constructorDeclaration.Parameters.Any()) { + ForceSpacesAfter(constructorDeclaration.LParToken, policy.SpaceWithinConstructorDeclarationParentheses); + FormatArguments(constructorDeclaration); + } else { + ForceSpacesAfter(constructorDeclaration.LParToken, policy.SpaceBetweenEmptyConstructorDeclarationParentheses); + ForceSpacesBefore(constructorDeclaration.RParToken, policy.SpaceBetweenEmptyConstructorDeclarationParentheses); + } + + var initializer = constructorDeclaration.Initializer; + if (!initializer.IsNull) { + curIndent.Push(IndentType.Block); + PlaceOnNewLine(policy.NewLineBeforeConstructorInitializerColon, constructorDeclaration.ColonToken); + PlaceOnNewLine(policy.NewLineAfterConstructorInitializerColon, initializer); + initializer.AcceptVisitor(this); + curIndent.Pop(); + } + if (!constructorDeclaration.Body.IsNull) { + FixOpenBrace(policy.ConstructorBraceStyle, constructorDeclaration.Body.LBraceToken); + VisitBlockWithoutFixingBraces(constructorDeclaration.Body, policy.IndentMethodBody); + FixClosingBrace(policy.ConstructorBraceStyle, constructorDeclaration.Body.RBraceToken); + } + } + public override void VisitConstructorInitializer(ConstructorInitializer constructorInitializer) + { + ForceSpacesBefore(constructorInitializer.LParToken, policy.SpaceBeforeMethodCallParentheses); + if (constructorInitializer.Arguments.Any()) { + ForceSpacesAfter(constructorInitializer.LParToken, policy.SpaceWithinMethodCallParentheses); + } else { + ForceSpacesAfter(constructorInitializer.LParToken, policy.SpaceBetweenEmptyMethodCallParentheses); + ForceSpacesBefore(constructorInitializer.RParToken, policy.SpaceBetweenEmptyMethodCallParentheses); + } + + FormatArguments(constructorInitializer); + + } + public override void VisitDestructorDeclaration(DestructorDeclaration destructorDeclaration) + { + FixAttributesAndDocComment(destructorDeclaration); + + CSharpTokenNode lParen = destructorDeclaration.LParToken; + ForceSpaceBefore(lParen, policy.SpaceBeforeConstructorDeclarationParentheses); + + if (!destructorDeclaration.Body.IsNull) { + FixOpenBrace(policy.DestructorBraceStyle, destructorDeclaration.Body.LBraceToken); + VisitBlockWithoutFixingBraces(destructorDeclaration.Body, policy.IndentMethodBody); + FixClosingBrace(policy.DestructorBraceStyle, destructorDeclaration.Body.RBraceToken); + } + } + } +} + diff --git a/NRefactory/ICSharpCode.NRefactory.CSharp/Formatter/GeneratedCodeSettings.cs b/NRefactory/ICSharpCode.NRefactory.CSharp/Formatter/GeneratedCodeSettings.cs index 2095b0d33..dd2df993e 100644 --- a/NRefactory/ICSharpCode.NRefactory.CSharp/Formatter/GeneratedCodeSettings.cs +++ b/NRefactory/ICSharpCode.NRefactory.CSharp/Formatter/GeneratedCodeSettings.cs @@ -164,7 +164,7 @@ namespace ICSharpCode.NRefactory.CSharp var curCat = GeneratedCodeMember.Unknown; foreach (var mem in entities) { if (mem.NextSibling is EntityDeclaration) - mem.Parent.InsertChildAfter (mem, new UnixNewLine (), Roles.NewLine); + mem.Parent.InsertChildAfter (mem, new NewLineNode (), Roles.NewLine); var cat = GetCodeMemberCategory (mem); if (cat == curCat) @@ -181,9 +181,7 @@ namespace ICSharpCode.NRefactory.CSharp 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); - - mem.Parent.InsertChildAfter (cmt3, new UnixNewLine (), Roles.NewLine); + mem.Parent.InsertChildBefore (cmt, new NewLineNode (), Roles.NewLine); } } } diff --git a/NRefactory/ICSharpCode.NRefactory.CSharp/Formatter/Indent.cs b/NRefactory/ICSharpCode.NRefactory.CSharp/Formatter/Indent.cs index 1db659b8f..347e66f6e 100644 --- a/NRefactory/ICSharpCode.NRefactory.CSharp/Formatter/Indent.cs +++ b/NRefactory/ICSharpCode.NRefactory.CSharp/Formatter/Indent.cs @@ -25,27 +25,60 @@ // THE SOFTWARE. using System; using System.Collections.Generic; +using System.Linq; namespace ICSharpCode.NRefactory.CSharp { - public enum IndentType { + public enum IndentType + { Block, + DoubleBlock, Continuation, - Label + Alignment, + Label, + Empty } public class Indent { - readonly Stack indentStack = new Stack (); + readonly CloneableStack indentStack = new CloneableStack(); readonly TextEditorOptions options; - int curIndent; + int extraSpaces; + string indentString; + + public int CurIndent { + get { + return curIndent; + } + } public Indent(TextEditorOptions options) { this.options = options; + Reset(); + } + + Indent(Indent engine) + { + this.indentStack = engine.indentStack.Clone(); + this.options = engine.options; + this.curIndent = engine.curIndent; + this.extraSpaces = engine.extraSpaces; + this.indentString = engine.indentString; + } + + public Indent Clone() + { + return new Indent(this); } + public void Reset() + { + curIndent = 0; + indentString = ""; + indentStack.Clear(); + } public void Push(IndentType type) { @@ -54,21 +87,73 @@ namespace ICSharpCode.NRefactory.CSharp Update(); } + public void Push(Indent indent) + { + foreach (var i in indent.indentStack) + Push(i); + } + public void Pop() { curIndent -= GetIndent(indentStack.Pop()); Update(); } + public bool PopIf(IndentType type) + { + if (Count > 0 && Peek() == type) + { + Pop(); + return true; + } + + return false; + } + + public void PopWhile(IndentType type) + { + while (Count > 0 && Peek() == type) + { + Pop(); + } + } + + public bool PopTry() + { + if (Count > 0) + { + Pop(); + return true; + } + + return false; + } + + public int Count { + get { + return indentStack.Count; + } + } + + public IndentType Peek() + { + return indentStack.Peek(); + } + int GetIndent(IndentType indentType) { switch (indentType) { case IndentType.Block: return options.IndentSize; + case IndentType.DoubleBlock: + return options.IndentSize * 2; + case IndentType.Alignment: case IndentType.Continuation: return options.ContinuationIndent; case IndentType.Label: return options.LabelIndent; + case IndentType.Empty: + return 0; default: throw new ArgumentOutOfRangeException(); } @@ -77,25 +162,25 @@ namespace ICSharpCode.NRefactory.CSharp void Update() { if (options.TabsToSpaces) { - indentString = new string(' ', curIndent); + indentString = new string(' ', curIndent + ExtraSpaces); return; } - indentString = new string('\t', curIndent / options.TabSize) + new string(' ', curIndent % options.TabSize) + new string (' ', ExtraSpaces); + indentString = new string('\t', curIndent / options.TabSize) + new string(' ', curIndent % options.TabSize) + new string(' ', ExtraSpaces); } - int extraSpaces; - public int ExtraSpaces { get { return extraSpaces; } set { + if (value < 0) + throw new ArgumentOutOfRangeException("ExtraSpaces >= 0 but was " + value); extraSpaces = value; Update(); } } - string indentString; + public string IndentString { get { return indentString; @@ -106,5 +191,56 @@ namespace ICSharpCode.NRefactory.CSharp { return string.Format("[Indent: curIndent={0}]", curIndent); } + + public Indent GetIndentWithoutSpace () + { + var result = new Indent(options); + foreach (var i in indentStack) + result.Push(i); + return result; + } + + public static Indent ConvertFrom(string indentString, Indent correctIndent, TextEditorOptions options = null) + { + options = options ?? TextEditorOptions.Default; + var result = new Indent(options); + + var indent = string.Concat(indentString.Where(c => c == ' ' || c == '\t')); + var indentTypes = new Stack(correctIndent.indentStack); + + foreach (var _ in indent.TakeWhile(c => c == '\t')) + { + if (indentTypes.Count > 0) + result.Push(indentTypes.Pop()); + else + result.Push(IndentType.Continuation); + } + + result.ExtraSpaces = indent + .SkipWhile(c => c == '\t') + .TakeWhile(c => c == ' ') + .Count(); + + return result; + } + + public void RemoveAlignment() + { + ExtraSpaces = 0; + if (Count > 0 && Peek() == IndentType.Alignment) + Pop(); + } + + public void SetAlignment(int i, bool forceSpaces = false) + { + var alignChars = Math.Max(0, i); + if (forceSpaces) { + ExtraSpaces = alignChars; + return; + } + RemoveAlignment(); + Push(IndentType.Alignment); + } + } } diff --git a/NRefactory/ICSharpCode.NRefactory.CSharp/ICSharpCode.NRefactory.CSharp.csproj b/NRefactory/ICSharpCode.NRefactory.CSharp/ICSharpCode.NRefactory.CSharp.csproj index deb12f6ee..4c53d5ff5 100644 --- a/NRefactory/ICSharpCode.NRefactory.CSharp/ICSharpCode.NRefactory.CSharp.csproj +++ b/NRefactory/ICSharpCode.NRefactory.CSharp/ICSharpCode.NRefactory.CSharp.csproj @@ -11,16 +11,18 @@ False False 4 - false - 10.0.0 + False + 8.0.30703 2.0 - True + true ..\ICSharpCode.NRefactory.snk False File ..\bin\$(Configuration)\ICSharpCode.NRefactory.CSharp.xml 1591,1587,1570 ..\bin\$(Configuration)\ + False + obj\$(Configuration)\ AnyCPU @@ -38,14 +40,18 @@ True False TRACE;FULL_AST;NET_4_0 + obj\ PdbOnly - false + True + ..\bin\Release\ - Full - true + full + True + True + ..\bin\Debug\ False @@ -54,8 +60,11 @@ v4.5 - Full - true + full + True + True + v4.5 + ..\bin\net_4_5_Debug\ True @@ -64,18 +73,16 @@ v4.5 - PdbOnly - false + none + True + v4.5 + ..\bin\net_4_5_Release\ - - 3.5 - + - - 3.5 - + @@ -84,11 +91,13 @@ + + @@ -98,7 +107,9 @@ - + + ArrayInitializerExpression.cs + @@ -109,7 +120,6 @@ - @@ -150,7 +160,6 @@ - @@ -195,14 +204,16 @@ - + - + + + @@ -264,15 +275,16 @@ + - + @@ -281,6 +293,7 @@ + @@ -292,9 +305,12 @@ + + + @@ -314,6 +330,10 @@ + + + + @@ -322,19 +342,53 @@ - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -359,4 +413,8 @@ + + + + \ No newline at end of file diff --git a/NRefactory/ICSharpCode.NRefactory.CSharp/IndentEngine/CSharpIndentEngine.cs b/NRefactory/ICSharpCode.NRefactory.CSharp/IndentEngine/CSharpIndentEngine.cs new file mode 100644 index 000000000..478bc45c6 --- /dev/null +++ b/NRefactory/ICSharpCode.NRefactory.CSharp/IndentEngine/CSharpIndentEngine.cs @@ -0,0 +1,557 @@ +// +// CSharpIndentEngine.cs +// +// Author: +// Matej Miklečić +// +// Copyright (c) 2013 Matej Miklečić (matej.miklecic@gmail.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 ICSharpCode.NRefactory.Editor; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace ICSharpCode.NRefactory.CSharp +{ + /// + /// Indentation engine based on a state machine. + /// Supports only pushing new chars to the end. + /// + /// + /// Represents the context for transitions between . + /// Delegates the responsibility for pushing a new char to the current + /// state and changes between states depending on the pushed chars. + /// + public class CSharpIndentEngine : IStateMachineIndentEngine + { + #region Properties + + /// + /// Formatting options. + /// + internal readonly CSharpFormattingOptions formattingOptions; + + /// + /// Text editor options. + /// + internal readonly TextEditorOptions textEditorOptions; + + /// + /// A readonly reference to the document that's parsed + /// by the engine. + /// + internal readonly IDocument document; + + /// + /// Represents the new line character. + /// + internal readonly char newLineChar; + + /// + /// The current indentation state. + /// + internal IndentState currentState; + + /// + /// Stores conditional symbols of #define directives. + /// + internal HashSet conditionalSymbols; + + /// + /// Stores custom conditional symbols. + /// + internal HashSet customConditionalSymbols; + + /// + /// Stores the results of evaluations of the preprocessor if/elif directives + /// in the current block (between #if and #endif). + /// + internal CloneableStack ifDirectiveEvalResults = new CloneableStack (); + + /// + /// Stores the indentation levels of the if directives in the current block. + /// + internal CloneableStack ifDirectiveIndents = new CloneableStack(); + + /// + /// Stores the last sequence of characters that can form a + /// valid keyword or variable name. + /// + internal StringBuilder wordToken; + + /// + /// Stores the previous sequence of chars that formed a + /// valid keyword or variable name. + /// + internal string previousKeyword; + + #endregion + + #region IDocumentIndentEngine + + /// + public IDocument Document + { + get { return document; } + } + + /// + public string ThisLineIndent + { + get + { + // OPTION: IndentBlankLines + // remove the indentation of this line if isLineStart is true +// if (!textEditorOptions.IndentBlankLines && isLineStart) +// { +// return string.Empty; +// } + + return currentState.ThisLineIndent.IndentString; + } + } + + /// + public string NextLineIndent + { + get + { + return currentState.NextLineIndent.IndentString; + } + } + + /// + public string CurrentIndent + { + get + { + return currentIndent.ToString(); + } + } + + /// + /// + /// This is set depending on the current and + /// can change its value until the char is + /// pushed. If this is true, that doesn't necessarily mean that the + /// current line has an incorrect indent (this can be determined + /// only at the end of the current line). + /// + public bool NeedsReindent + { + get + { + // return true if it's the first column of the line and it has an indent + if (Location.Column == 1) + { + return ThisLineIndent.Length > 0; + } + + // ignore incorrect indentations when there's only ws on this line + if (isLineStart) + { + return false; + } + + return ThisLineIndent != CurrentIndent.ToString(); + } + } + + /// + public int Offset + { + get + { + return offset; + } + } + + /// + public TextLocation Location + { + get + { + return new TextLocation(line, column); + } + } + + /// + public bool EnableCustomIndentLevels + { + get; + set; + } + + #endregion + + #region Fields + + /// + /// Represents the number of pushed chars. + /// + internal int offset = 0; + + /// + /// The current line number. + /// + internal int line = 1; + + /// + /// The current column number. + /// + /// + /// One char can take up multiple columns (e.g. \t). + /// + internal int column = 1; + + /// + /// True if is true for all + /// chars at the current line. + /// + internal bool isLineStart = true; + + /// + /// True if was true before the current + /// . + /// + internal bool isLineStartBeforeWordToken = true; + + /// + /// Current char that's being pushed. + /// + internal char currentChar = '\0'; + + /// + /// Last non-whitespace char that has been pushed. + /// + internal char previousChar = '\0'; + + /// + /// Previous new line char + /// + internal char previousNewline = '\0'; + + /// + /// Current indent level on this line. + /// + internal StringBuilder currentIndent = new StringBuilder(); + + /// + /// True if this line began in . + /// + internal bool lineBeganInsideVerbatimString = false; + + /// + /// True if this line began in . + /// + internal bool lineBeganInsideMultiLineComment = false; + + #endregion + + #region Constructors + + /// + /// Creates a new CSharpIndentEngine instance. + /// + /// + /// An instance of which is being parsed. + /// + /// + /// C# formatting options. + /// + /// + /// Text editor options for indentation. + /// + public CSharpIndentEngine(IDocument document, TextEditorOptions textEditorOptions, CSharpFormattingOptions formattingOptions) + { + this.formattingOptions = formattingOptions; + this.textEditorOptions = textEditorOptions; + this.document = document; + + this.currentState = new GlobalBodyState(this); + + this.conditionalSymbols = new HashSet(); + this.customConditionalSymbols = new HashSet(); + this.wordToken = new StringBuilder(); + this.previousKeyword = string.Empty; + this.newLineChar = textEditorOptions.EolMarker[0]; + } + + /// + /// Creates a new CSharpIndentEngine instance from the given prototype. + /// + /// + /// An CSharpIndentEngine instance. + /// + public CSharpIndentEngine(CSharpIndentEngine prototype) + { + this.formattingOptions = prototype.formattingOptions; + this.textEditorOptions = prototype.textEditorOptions; + this.document = prototype.document; + + this.newLineChar = prototype.newLineChar; + this.currentState = prototype.currentState.Clone(this); + this.conditionalSymbols = new HashSet(prototype.conditionalSymbols); + this.customConditionalSymbols = new HashSet(prototype.customConditionalSymbols); + + this.wordToken = new StringBuilder(prototype.wordToken.ToString()); + this.previousKeyword = string.Copy(prototype.previousKeyword); + + this.offset = prototype.offset; + this.line = prototype.line; + this.column = prototype.column; + this.isLineStart = prototype.isLineStart; + this.isLineStartBeforeWordToken = prototype.isLineStartBeforeWordToken; + this.currentChar = prototype.currentChar; + this.previousChar = prototype.previousChar; + this.previousNewline = prototype.previousNewline; + this.currentIndent = new StringBuilder(prototype.CurrentIndent.ToString()); + this.lineBeganInsideMultiLineComment = prototype.lineBeganInsideMultiLineComment; + this.lineBeganInsideVerbatimString = prototype.lineBeganInsideVerbatimString; + this.ifDirectiveEvalResults = prototype.ifDirectiveEvalResults.Clone(); + this.ifDirectiveIndents = prototype.ifDirectiveIndents.Clone(); + + this.EnableCustomIndentLevels = prototype.EnableCustomIndentLevels; + } + + #endregion + + #region IClonable + + object ICloneable.Clone() + { + return Clone(); + } + + /// + IDocumentIndentEngine IDocumentIndentEngine.Clone() + { + return Clone(); + } + + public IStateMachineIndentEngine Clone() + { + return new CSharpIndentEngine(this); + } + + #endregion + + #region Methods + + /// + public void Push(char ch) + { + // append this char to the wordbuf if it can form a valid keyword, otherwise check + // if the last sequence of chars form a valid keyword and reset the wordbuf. + if ((wordToken.Length == 0 ? char.IsLetter(ch) : char.IsLetterOrDigit(ch)) || ch == '_') + { + wordToken.Append(ch); + } + else if (wordToken.Length > 0) + { + currentState.CheckKeyword(wordToken.ToString()); + previousKeyword = wordToken.ToString(); + wordToken.Length = 0; + isLineStartBeforeWordToken = false; + } + + var isNewLine = NewLine.IsNewLine(ch); + if (!isNewLine) { + currentState.Push(currentChar = ch); + offset++; + previousNewline = '\0'; + // ignore whitespace and newline chars + var isWhitespace = currentChar == ' ' || currentChar == '\t'; + if (!isWhitespace) + { + previousChar = currentChar; + isLineStart = false; + } + + if (isLineStart) + { + currentIndent.Append(ch); + } + + if (ch == '\t') + { + var nextTabStop = (column - 1 + textEditorOptions.IndentSize) / textEditorOptions.IndentSize; + column = 1 + nextTabStop * textEditorOptions.IndentSize; + } + else + { + column++; + } + } else { + if (ch == NewLine.LF && previousNewline == NewLine.CR) { + offset++; + return; + } + currentState.Push(currentChar = newLineChar); + offset++; + + previousNewline = ch; + // there can be more than one chars that determine the EOL, + // the engine uses only one of them defined with newLineChar + if (currentChar != newLineChar) + { + return; + } + currentIndent.Length = 0; + isLineStart = true; + isLineStartBeforeWordToken = true; + column = 1; + line++; + + lineBeganInsideMultiLineComment = IsInsideMultiLineComment; + lineBeganInsideVerbatimString = IsInsideVerbatimString; + } + } + + /// + public void Reset() + { + currentState = new GlobalBodyState(this); + conditionalSymbols.Clear(); + ifDirectiveEvalResults.Clear(); + ifDirectiveIndents.Clear(); + + offset = 0; + line = 1; + column = 1; + isLineStart = true; + currentChar = '\0'; + previousChar = '\0'; + currentIndent.Length = 0; + lineBeganInsideMultiLineComment = false; + lineBeganInsideVerbatimString = false; + } + + /// + public void Update(int offset) + { + if (Offset > offset) + { + Reset(); + } + + while (Offset < offset) + { + Push(Document.GetCharAt(Offset)); + } + } + + /// + /// Defines the conditional symbol. + /// + /// The symbol to define. + public void DefineSymbol(string defineSymbol) + { + if (!customConditionalSymbols.Contains(defineSymbol)) + customConditionalSymbols.Add(defineSymbol); + } + + /// + /// Removes the symbol. + /// + /// The symbol to undefine. + public void RemoveSymbol(string undefineSymbol) + { + if (customConditionalSymbols.Contains(undefineSymbol)) + customConditionalSymbols.Remove(undefineSymbol); + } + #endregion + + #region IStateMachineIndentEngine + + public bool IsInsidePreprocessorDirective + { + get { return currentState is PreProcessorState; } + } + + public bool IsInsidePreprocessorComment + { + get { return currentState is PreProcessorCommentState; } + } + + public bool IsInsideStringLiteral + { + get { return currentState is StringLiteralState; } + } + + public bool IsInsideVerbatimString + { + get { return currentState is VerbatimStringState; } + } + + public bool IsInsideCharacter + { + get { return currentState is CharacterState; } + } + + public bool IsInsideString + { + get { return IsInsideStringLiteral || IsInsideVerbatimString || IsInsideCharacter; } + } + + public bool IsInsideLineComment + { + get { return currentState is LineCommentState; } + } + + public bool IsInsideMultiLineComment + { + get { return currentState is MultiLineCommentState; } + } + + public bool IsInsideDocLineComment + { + get { return currentState is DocCommentState; } + } + + public bool IsInsideComment + { + get { return IsInsideLineComment || IsInsideMultiLineComment || IsInsideDocLineComment; } + } + + public bool IsInsideOrdinaryComment + { + get { return IsInsideLineComment || IsInsideMultiLineComment; } + } + + public bool IsInsideOrdinaryCommentOrString + { + get { return IsInsideOrdinaryComment || IsInsideString; } + } + + public bool LineBeganInsideVerbatimString + { + get { return lineBeganInsideVerbatimString; } + } + + public bool LineBeganInsideMultiLineComment + { + get { return lineBeganInsideMultiLineComment; } + } + + #endregion + } +} diff --git a/NRefactory/ICSharpCode.NRefactory.CSharp/IndentEngine/CacheIndentEngine.cs b/NRefactory/ICSharpCode.NRefactory.CSharp/IndentEngine/CacheIndentEngine.cs new file mode 100644 index 000000000..b19f38868 --- /dev/null +++ b/NRefactory/ICSharpCode.NRefactory.CSharp/IndentEngine/CacheIndentEngine.cs @@ -0,0 +1,627 @@ +// +// CacheIndentEngine.cs +// +// Author: +// Matej Miklečić +// +// Copyright (c) 2013 Matej Miklečić (matej.miklecic@gmail.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 ICSharpCode.NRefactory.Editor; +using System; +using System.Collections.Generic; +using System.Linq; + +namespace ICSharpCode.NRefactory.CSharp +{ + /// + /// Represents a decorator of an IStateMachineIndentEngine instance that provides + /// logic for reseting and updating the engine on text changed events. + /// + /// + /// The decorator is based on periodical caching of the engine's state and + /// delegating all logic behind indentation to the currently active engine. + /// + public class CacheIndentEngine : IStateMachineIndentEngine + { + + #region Properties + + IStateMachineIndentEngine currentEngine; + Stack cachedEngines = new Stack(); + + #endregion + + #region Constructors + + /// + /// Creates a new CacheIndentEngine instance. + /// + /// + /// An instance of to which the + /// logic for indentation will be delegated. + /// + /// + /// The number of chars between caching. + /// + public CacheIndentEngine(IStateMachineIndentEngine decoratedEngine, int cacheRate = 2000) + { + this.currentEngine = decoratedEngine; + } + + /// + /// Creates a new CacheIndentEngine instance from the given prototype. + /// + /// + /// A CacheIndentEngine instance. + /// + public CacheIndentEngine(CacheIndentEngine prototype) + { + this.currentEngine = prototype.currentEngine.Clone(); + } + + #endregion + + #region IDocumentIndentEngine + + /// + public IDocument Document { + get { return currentEngine.Document; } + } + + /// + public string ThisLineIndent { + get { return currentEngine.ThisLineIndent; } + } + + /// + public string NextLineIndent { + get { return currentEngine.NextLineIndent; } + } + + /// + public string CurrentIndent { + get { return currentEngine.CurrentIndent; } + } + + /// + public bool NeedsReindent { + get { return currentEngine.NeedsReindent; } + } + + /// + public int Offset { + get { return currentEngine.Offset; } + } + + /// + public TextLocation Location { + get { return currentEngine.Location; } + } + + /// + public bool EnableCustomIndentLevels + { + get { return currentEngine.EnableCustomIndentLevels; } + set { currentEngine.EnableCustomIndentLevels = value; } + } + + /// + public void Push(char ch) + { + currentEngine.Push(ch); + } + + /// + public void Reset() + { + currentEngine.Reset(); + cachedEngines.Clear(); + } + + /// + /// Resets the engine to offset. Clears all cached engines after the given offset. + /// + public void ResetEngineToPosition(int offset) + { + // We are already there + if (currentEngine.Offset <= offset) + return; + + bool gotCachedEngine = false; + while (cachedEngines.Count > 0) { + var topEngine = cachedEngines.Peek(); + if (topEngine.Offset <= offset) { + currentEngine = topEngine.Clone(); + gotCachedEngine = true; + break; + } else { + cachedEngines.Pop(); + } + } + if (!gotCachedEngine) + currentEngine.Reset(); + } + + /// + /// + /// If the is negative, the engine will + /// update to: document.TextLength + (offset % document.TextLength+1) + /// Otherwise it will update to: offset % document.TextLength+1 + /// + public void Update(int position) + { + const int BUFFER_SIZE = 2000; + + if (currentEngine.Offset == position) { + //positions match, nothing to be done + return; + } else if (currentEngine.Offset > position) { + //moving backwards, so reset from previous saved location + ResetEngineToPosition(position); + } + + // get the engine caught up + int nextSave = (cachedEngines.Count == 0) ? BUFFER_SIZE : cachedEngines.Peek().Offset + BUFFER_SIZE; + if (currentEngine.Offset + 1 == position) { + char ch = currentEngine.Document.GetCharAt(currentEngine.Offset); + currentEngine.Push(ch); + if (currentEngine.Offset == nextSave) + cachedEngines.Push(currentEngine.Clone()); + } else { + //bulk copy characters in case buffer is unmanaged + //(faster if we reduce managed/unmanaged transitions) + while (currentEngine.Offset < position) { + int endCut = currentEngine.Offset + BUFFER_SIZE; + if (endCut > position) + endCut = position; + string buffer = currentEngine.Document.GetText(currentEngine.Offset, endCut - currentEngine.Offset); + foreach (char ch in buffer) { + currentEngine.Push(ch); + //ConsoleWrite ("pushing character '{0}'", ch); + if (currentEngine.Offset == nextSave) { + cachedEngines.Push(currentEngine.Clone()); + nextSave += BUFFER_SIZE; + } + } + } + } + } + + public IStateMachineIndentEngine GetEngine(int offset) + { + ResetEngineToPosition(offset); + return currentEngine; + } + + #endregion + + #region IClonable + + /// + public IStateMachineIndentEngine Clone() + { + return new CacheIndentEngine(this); + } + + /// + IDocumentIndentEngine IDocumentIndentEngine.Clone() + { + return Clone(); + } + + object ICloneable.Clone() + { + return Clone(); + } + + #endregion + + #region IStateMachineIndentEngine + + public bool IsInsidePreprocessorDirective { + get { return currentEngine.IsInsidePreprocessorDirective; } + } + + public bool IsInsidePreprocessorComment { + get { return currentEngine.IsInsidePreprocessorComment; } + } + + public bool IsInsideStringLiteral { + get { return currentEngine.IsInsideStringLiteral; } + } + + public bool IsInsideVerbatimString { + get { return currentEngine.IsInsideVerbatimString; } + } + + public bool IsInsideCharacter { + get { return currentEngine.IsInsideCharacter; } + } + + public bool IsInsideString { + get { return currentEngine.IsInsideString; } + } + + public bool IsInsideLineComment { + get { return currentEngine.IsInsideLineComment; } + } + + public bool IsInsideMultiLineComment { + get { return currentEngine.IsInsideMultiLineComment; } + } + + public bool IsInsideDocLineComment { + get { return currentEngine.IsInsideDocLineComment; } + } + + public bool IsInsideComment { + get { return currentEngine.IsInsideComment; } + } + + public bool IsInsideOrdinaryComment { + get { return currentEngine.IsInsideOrdinaryComment; } + } + + public bool IsInsideOrdinaryCommentOrString { + get { return currentEngine.IsInsideOrdinaryCommentOrString; } + } + + public bool LineBeganInsideVerbatimString { + get { return currentEngine.LineBeganInsideVerbatimString; } + } + + public bool LineBeganInsideMultiLineComment { + get { return currentEngine.LineBeganInsideMultiLineComment; } + } + + #endregion + + } + /* +/ // + /// Represents a decorator of an IStateMachineIndentEngine instance that provides + /// logic for reseting and updating the engine on text changed events. + /// + /// + /// The decorator is based on periodical caching of the engine's state and + /// delegating all logic behind indentation to the currently active engine. + /// + public class CacheIndentEngine : IStateMachineIndentEngine + { + #region Properties + + /// + /// Represents the cache interval in number of chars pushed to the engine. + /// + /// + /// When this many new chars are pushed to the engine, the currently active + /// engine gets cloned and added to the end of . + /// + readonly int cacheRate; + + /// + /// Determines how much memory to reserve on initialization for the + /// cached engines. + /// + const int cacheCapacity = 25; + + /// + /// Currently active engine. + /// + /// + /// Should be equal to the last engine in . + /// + IStateMachineIndentEngine currentEngine; + + /// + /// List of cached engines sorted ascending by + /// . + /// + IStateMachineIndentEngine[] cachedEngines; + + /// + /// The index of the last cached engine in cachedEngines. + /// + /// + /// Should be equal to: currentEngine.Offset / CacheRate + /// + int lastCachedEngine; + + #endregion + + #region Constructors + + /// + /// Creates a new CacheIndentEngine instance. + /// + /// + /// An instance of to which the + /// logic for indentation will be delegated. + /// + /// + /// The number of chars between caching. + /// + public CacheIndentEngine(IStateMachineIndentEngine decoratedEngine, int cacheRate = 2000) + { + this.cachedEngines = new IStateMachineIndentEngine[cacheCapacity]; + + this.cachedEngines[0] = decoratedEngine.Clone(); + this.currentEngine = this.cachedEngines[0].Clone(); + this.cacheRate = cacheRate; + } + + /// + /// Creates a new CacheIndentEngine instance from the given prototype. + /// + /// + /// A CacheIndentEngine instance. + /// + public CacheIndentEngine(CacheIndentEngine prototype) + { + this.cachedEngines = new IStateMachineIndentEngine[prototype.cachedEngines.Length]; + Array.Copy(prototype.cachedEngines, this.cachedEngines, prototype.cachedEngines.Length); + + this.lastCachedEngine = prototype.lastCachedEngine; + this.currentEngine = prototype.currentEngine.Clone(); + this.cacheRate = prototype.cacheRate; + } + + #endregion + + #region Methods + + /// + /// Performs caching of the . + /// + void cache() + { + if (currentEngine.Offset % cacheRate != 0) + { + throw new Exception("The current engine's offset is not divisable with the cacheRate."); + } + + // determine the new current engine from cachedEngines + lastCachedEngine = currentEngine.Offset / cacheRate; + + if (cachedEngines.Length < lastCachedEngine + 1) + { + Array.Resize(ref cachedEngines, lastCachedEngine * 2); + } + + cachedEngines[lastCachedEngine] = currentEngine.Clone(); + } + + #endregion + + #region IDocumentIndentEngine + + /// + public IDocument Document + { + get { return currentEngine.Document; } + } + + /// + public string ThisLineIndent + { + get { return currentEngine.ThisLineIndent; } + } + + /// + public string NextLineIndent + { + get { return currentEngine.NextLineIndent; } + } + + /// + public string CurrentIndent + { + get { return currentEngine.CurrentIndent; } + } + + /// + public bool NeedsReindent + { + get { return currentEngine.NeedsReindent; } + } + + /// + public int Offset + { + get { return currentEngine.Offset; } + } + + /// + public TextLocation Location + { + get { return currentEngine.Location; } + } + + /// + public void Push(char ch) + { + currentEngine.Push(ch); + + if (currentEngine.Offset % cacheRate == 0) + { + cache(); + } + } + + /// + public void Reset() + { + currentEngine = cachedEngines[lastCachedEngine = 0]; + } + + /// + /// + /// If the is negative, the engine will + /// update to: document.TextLength + (offset % document.TextLength+1) + /// Otherwise it will update to: offset % document.TextLength+1 + /// + public void Update(int offset) + { + // map the given offset to the [0, document.TextLength] interval + // using modulo arithmetics + offset %= Document.TextLength + 1; + if (offset < 0) + { + offset += Document.TextLength + 1; + } + + // check if the engine has to be updated to some previous offset + if (currentEngine.Offset > offset) + { + // replace the currentEngine with the first one whose offset + // is less then the given + lastCachedEngine = offset / cacheRate; + currentEngine = cachedEngines[lastCachedEngine].Clone(); + } + + // update the engine to the given offset + while (Offset < offset) + { + Push(Document.GetCharAt(Offset)); + } + } + + public IStateMachineIndentEngine GetEngine(int offset) + { + // map the given offset to the [0, document.TextLength] interval + // using modulo arithmetics + offset %= Document.TextLength + 1; + if (offset < 0) + { + offset += Document.TextLength + 1; + } + + // check if the engine has to be updated to some previous offset + if (currentEngine.Offset > offset) + { + // replace the currentEngine with the first one whose offset + // is less then the given + lastCachedEngine = offset / cacheRate; + return cachedEngines[lastCachedEngine].Clone(); + } + + return currentEngine; + } + + #endregion + + #region IClonable + + /// + public IStateMachineIndentEngine Clone() + { + return new CacheIndentEngine(this); + } + + /// + IDocumentIndentEngine IDocumentIndentEngine.Clone() + { + return Clone(); + } + + object ICloneable.Clone() + { + return Clone(); + } + + #endregion + + #region IStateMachineIndentEngine + + public bool IsInsidePreprocessorDirective + { + get { return currentEngine.IsInsidePreprocessorDirective; } + } + + public bool IsInsidePreprocessorComment + { + get { return currentEngine.IsInsidePreprocessorComment; } + } + + public bool IsInsideStringLiteral + { + get { return currentEngine.IsInsideStringLiteral; } + } + + public bool IsInsideVerbatimString + { + get { return currentEngine.IsInsideVerbatimString; } + } + + public bool IsInsideCharacter + { + get { return currentEngine.IsInsideCharacter; } + } + + public bool IsInsideString + { + get { return currentEngine.IsInsideString; } + } + + public bool IsInsideLineComment + { + get { return currentEngine.IsInsideLineComment; } + } + + public bool IsInsideMultiLineComment + { + get { return currentEngine.IsInsideMultiLineComment; } + } + + public bool IsInsideDocLineComment + { + get { return currentEngine.IsInsideDocLineComment; } + } + + public bool IsInsideComment + { + get { return currentEngine.IsInsideComment; } + } + + public bool IsInsideOrdinaryComment + { + get { return currentEngine.IsInsideOrdinaryComment; } + } + + public bool IsInsideOrdinaryCommentOrString + { + get { return currentEngine.IsInsideOrdinaryCommentOrString; } + } + + public bool LineBeganInsideVerbatimString + { + get { return currentEngine.LineBeganInsideVerbatimString; } + } + + public bool LineBeganInsideMultiLineComment + { + get { return currentEngine.LineBeganInsideMultiLineComment; } + } + + #endregion + } + + */ +} \ No newline at end of file diff --git a/NRefactory/ICSharpCode.NRefactory.CSharp/IndentEngine/IDocumentIndentEngine.cs b/NRefactory/ICSharpCode.NRefactory.CSharp/IndentEngine/IDocumentIndentEngine.cs new file mode 100644 index 000000000..821aa0bc8 --- /dev/null +++ b/NRefactory/ICSharpCode.NRefactory.CSharp/IndentEngine/IDocumentIndentEngine.cs @@ -0,0 +1,108 @@ +// +// IDocumentIndentEngine.cs +// +// Author: +// Matej Miklečić +// +// Copyright (c) 2013 Matej Miklečić (matej.miklecic@gmail.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 ICSharpCode.NRefactory.Editor; +using System; + +namespace ICSharpCode.NRefactory.CSharp +{ + /// + /// The base interface for all indent engines. + /// + public interface IDocumentIndentEngine : ICloneable + { + /// + /// A reference to the document that's parsed by the engine. + /// + IDocument Document { get; } + + /// + /// The indentation string of the current line. + /// + string ThisLineIndent { get; } + + /// + /// The indentation string of the next line. + /// + string NextLineIndent { get; } + + /// + /// The indent string on the beginning of the current line. + /// + string CurrentIndent { get; } + + /// + /// True if the current line needs to be reindented. + /// + bool NeedsReindent { get; } + + /// + /// The current offset of the engine. + /// + int Offset { get; } + + /// + /// The current location of the engine. + /// + TextLocation Location { get; } + + /// + /// If this is true, the engine should try to adjust its indent + /// levels to manual user's corrections, even if they are wrong. + /// + bool EnableCustomIndentLevels { get; set; } + + /// + /// Pushes a new char into the engine which calculates the new + /// indentation levels. + /// + /// + /// A new character. + /// + void Push(char ch); + + /// + /// Resets the engine. + /// + void Reset(); + + /// + /// Updates the engine to the given offset. + /// + /// + /// Valid offset in . + /// + void Update(int offset); + + /// + /// Clones the engine and preserves the current state. + /// + /// + /// An indentical clone which can operate without interference + /// with this engine. + /// + new IDocumentIndentEngine Clone(); + } +} diff --git a/NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/CodeIssues/IssueCategories.cs b/NRefactory/ICSharpCode.NRefactory.CSharp/IndentEngine/IStateMachineIndentEngine.cs similarity index 57% rename from NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/CodeIssues/IssueCategories.cs rename to NRefactory/ICSharpCode.NRefactory.CSharp/IndentEngine/IStateMachineIndentEngine.cs index 6ac8d9de9..44c3949cf 100644 --- a/NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/CodeIssues/IssueCategories.cs +++ b/NRefactory/ICSharpCode.NRefactory.CSharp/IndentEngine/IStateMachineIndentEngine.cs @@ -1,21 +1,21 @@ -// -// IssueCategories.cs -// +// +// IStateMachineIndentEngine.cs +// // Author: -// Mike Krüger -// -// Copyright (c) 2012 Xamarin Inc. (http://xamarin.com) -// +// Matej Miklečić +// +// Copyright (c) 2013 Matej Miklečić (matej.miklecic@gmail.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 @@ -23,21 +23,38 @@ // 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; - namespace ICSharpCode.NRefactory.CSharp { - public class IssueCategories + public interface IStateMachineIndentEngine : IDocumentIndentEngine { - public const string Improvements = "Code Improvements"; - public const string CodeQualityIssues = "Code Quality Issues"; - public const string ConstraintViolations = "Constraint Violations"; - public const string Redundancies = "Redundancies"; - public const string Opportunities = "Language Usage Opportunities"; - public const string Notifications = "Code Notifications"; - public const string CompilerWarnings = "Compiler Warnings"; - public const string CompilerErrors = "Compiler Errors"; - } -} + bool IsInsidePreprocessorDirective { get; } + + bool IsInsidePreprocessorComment { get; } + + bool IsInsideStringLiteral { get; } + + bool IsInsideVerbatimString { get; } + + bool IsInsideCharacter { get; } + + bool IsInsideString { get; } + + bool IsInsideLineComment { get; } + bool IsInsideMultiLineComment { get; } + bool IsInsideDocLineComment { get; } + + bool IsInsideComment { get; } + + bool IsInsideOrdinaryComment { get; } + + bool IsInsideOrdinaryCommentOrString { get; } + + bool LineBeganInsideVerbatimString { get; } + + bool LineBeganInsideMultiLineComment { get; } + + new IStateMachineIndentEngine Clone(); + } +} diff --git a/NRefactory/ICSharpCode.NRefactory.CSharp/IndentEngine/IndentState.cs b/NRefactory/ICSharpCode.NRefactory.CSharp/IndentEngine/IndentState.cs new file mode 100644 index 000000000..6b05ce36c --- /dev/null +++ b/NRefactory/ICSharpCode.NRefactory.CSharp/IndentEngine/IndentState.cs @@ -0,0 +1,2014 @@ +// +// IndentState.cs +// +// Author: +// Matej Miklečić +// +// Copyright (c) 2013 Matej Miklečić (matej.miklecic@gmail.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 System.Collections.Generic; +using System.Globalization; +using System.Linq; +using System.Text; + +namespace ICSharpCode.NRefactory.CSharp +{ + #region IndentState + + /// + /// The base class for all indentation states. + /// Each state defines the logic for indentation based on chars that + /// are pushed to it. + /// + public abstract class IndentState : ICloneable + { + #region Properties + + /// + /// The indentation engine using this state. + /// + public CSharpIndentEngine Engine; + + /// + /// The parent state. + /// This state can use the indentation levels of its parent. + /// When this state exits, the engine returns to the parent. + /// + public IndentState Parent; + + /// + /// The indentation of the current line. + /// This is set when the state is created and will be changed to + /// when the + /// is pushed. + /// + public Indent ThisLineIndent; + + /// + /// The indentation of the next line. + /// This is set when the state is created and can change depending + /// on the pushed chars. + /// + public Indent NextLineIndent; + + #endregion + + #region Constructors + + protected IndentState() + { + } + + /// + /// Creates a new indentation state that is a copy of the given + /// prototype. + /// + /// + /// The prototype state. + /// + /// + /// The engine of the new state. + /// + protected IndentState(IndentState prototype, CSharpIndentEngine engine) + { + Engine = engine; + Parent = prototype.Parent != null ? prototype.Parent.Clone(engine) : null; + + ThisLineIndent = prototype.ThisLineIndent.Clone(); + NextLineIndent = prototype.NextLineIndent.Clone(); + } + + #endregion + + #region IClonable + + object ICloneable.Clone() + { + return Clone(Engine); + } + + public abstract IndentState Clone(CSharpIndentEngine engine); + + #endregion + + #region Methods + + internal void Initialize (CSharpIndentEngine engine, IndentState parent = null) + { + Parent = parent; + Engine = engine; + + InitializeState(); + } + + /// + /// Initializes the state: + /// - sets the default indentation levels. + /// + /// + /// Each state can override this method if it needs a different + /// logic for setting up the default indentations. + /// + public virtual void InitializeState() + { + ThisLineIndent = new Indent(Engine.textEditorOptions); + NextLineIndent = ThisLineIndent.Clone(); + } + + /// + /// Actions performed when this state exits. + /// + public virtual void OnExit() + { + if (Parent != null) + { + // if a state exits on the newline character, it has to push + // it back to its parent (and so on recursively if the parent + // state also exits). Otherwise, the parent state wouldn't + // know that the engine isn't on the same line anymore. + if (Engine.currentChar == Engine.newLineChar) + { + Parent.Push(Engine.newLineChar); + } + + // when a state exits the engine stays on the same line and this + // state has to override the Parent.ThisLineIndent. + Parent.ThisLineIndent = ThisLineIndent.Clone(); + } + } + + /// + /// Changes the current state of the using the current + /// state as the parent for the new one. + /// + /// + /// The type of the new state. Must be assignable from . + /// + public void ChangeState() + where T : IndentState, new () + { + var t = new T(); + t.Initialize(Engine, Engine.currentState); + Engine.currentState = t; + } + + /// + /// Exits this state by setting the current state of the + /// to this state's parent. + /// + public void ExitState() + { + OnExit(); + Engine.currentState = Engine.currentState.Parent ?? new GlobalBodyState(Engine); + } + + /// + /// Common logic behind the push method. + /// Each state can override this method and implement its own logic. + /// + /// + /// The current character that's being pushed. + /// + public virtual void Push(char ch) + { + // replace ThisLineIndent with NextLineIndent if the newLineChar is pushed + if (ch == Engine.newLineChar) + { + var delta = Engine.textEditorOptions.ContinuationIndent; + while (NextLineIndent.CurIndent - ThisLineIndent.CurIndent > delta && + NextLineIndent.PopIf(IndentType.Continuation)) ; + ThisLineIndent = NextLineIndent.Clone(); + } + } + + /// + /// When derived, checks if the given sequence of chars form + /// a valid keyword or variable name, depending on the state. + /// + /// + /// A possible keyword. + /// + public virtual void CheckKeyword(string keyword) + { } + + /// + /// When derived, checks if the given sequence of chars form + /// a valid keyword or variable name, depending on the state. + /// + /// + /// A possible keyword. + /// + /// + /// This method should be called from . + /// It is left to derived classes to call this method because of + /// performance issues. + /// + public virtual void CheckKeywordOnPush(string keyword) + { } + + #endregion + } + + #endregion + + #region Null state + + /// + /// Null state. + /// + /// + /// Doesn't define any transitions to new states. + /// + public class NullState : IndentState + { + public NullState() + { } + + public NullState(NullState prototype, CSharpIndentEngine engine) + : base(prototype, engine) + { } + + public override void Push(char ch) + { } + + public override IndentState Clone(CSharpIndentEngine engine) + { + return new NullState(this, engine); + } + } + + #endregion + + #region Brackets body states + + #region Brackets body base + + /// + /// The base for all brackets body states. + /// + /// + /// Represents a block of code between a pair of brackets. + /// + public abstract class BracketsBodyBaseState : IndentState + { + + /// + /// When derived in a concrete bracket body state, represents + /// the closed bracket character pair. + /// + public abstract char ClosedBracket { get; } + + protected BracketsBodyBaseState() + { } + + protected BracketsBodyBaseState(BracketsBodyBaseState prototype, CSharpIndentEngine engine) + : base(prototype, engine) + { } + + public override void Push(char ch) + { + base.Push(ch); + switch (ch) { + case '#': + if (Engine.isLineStart) + ChangeState(); + break; + case '/': + if (Engine.previousChar == '/') + ChangeState(); + break; + case '*': + if (Engine.previousChar == '/') + ChangeState(); + break; + case '"': + if (Engine.previousChar == '@') + { + ChangeState(); + } + else + { + ChangeState(); + } + break; + case '\'': + ChangeState(); + break; + case '{': + ChangeState(); + break; + case '(': + ChangeState(); + break; + case '[': + ChangeState(); + break; + default: + if (ch == ClosedBracket) + ExitState(); + break; + } + } + } + + #endregion + + #region Braces body state + + /// + /// Braces body state. + /// + /// + /// Represents a block of code between { and }. + /// + public class BracesBodyState : BracketsBodyBaseState + { + /// + /// Type of the current block body. + /// + public Body CurrentBody; + + /// + /// Type of the next block body. + /// Same as if none of the + /// keywords have been read. + /// + public Body NextBody; + + /// + /// Type of the current statement. + /// + public Statement CurrentStatement + { + get + { + return currentStatement; + } + set + { + // clear NestedIfStatementLevels if this statement breaks the sequence + if (currentStatement == Statement.None && value != Statement.Else) + { + NestedIfStatementLevels.Clear(); + } + + currentStatement = value; + } + } + Statement currentStatement; + + /// + /// Contains indent levels of nested if statements. + /// + internal CloneableStack NestedIfStatementLevels = new CloneableStack(); + + /// + /// Contains the indent level of the last statement or body keyword. + /// + public Indent LastBlockIndent; + + /// + /// True if the engine is on the right side of the equal operator '='. + /// + public bool IsRightHandExpression; + + /// + /// True if the '=' char has been pushed and it's not + /// a part of a relational operator (>=, <=, !=, ==). + /// + public bool IsEqualCharPushed; + + /// + /// The indentation of the previous line. + /// + public int PreviousLineIndent; + + /// + /// True if the dot member (e.g. method invocation) indentation has + /// been handled in the current statement. + /// + public bool IsMemberReferenceDotHandled; + + public override char ClosedBracket + { + get { return '}'; } + } + + public BracesBodyState() + { + } + + public BracesBodyState(BracesBodyState prototype, CSharpIndentEngine engine) + : base(prototype, engine) + { + CurrentBody = prototype.CurrentBody; + NextBody = prototype.NextBody; + CurrentStatement = prototype.CurrentStatement; + NestedIfStatementLevels = prototype.NestedIfStatementLevels.Clone(); + IsRightHandExpression = prototype.IsRightHandExpression; + IsEqualCharPushed = prototype.IsEqualCharPushed; + IsMemberReferenceDotHandled = prototype.IsMemberReferenceDotHandled; + LastBlockIndent = prototype.LastBlockIndent; + PreviousLineIndent = prototype.PreviousLineIndent; + } + + public override void Push(char ch) + { + // handle IsRightHandExpression property + if (IsEqualCharPushed) + { + if (IsRightHandExpression) + { + if (ch == Engine.newLineChar) + { + NextLineIndent.RemoveAlignment(); + NextLineIndent.Push(IndentType.Continuation); + } + } + // ignore "==" and "=>" operators + else if (ch != '=' && ch != '>') + { + IsRightHandExpression = true; + + if (ch == Engine.newLineChar) + { + NextLineIndent.Push(IndentType.Continuation); + } + else + { + NextLineIndent.SetAlignment(Engine.column - NextLineIndent.CurIndent); + } + } + + IsEqualCharPushed = ch == ' ' || ch == '\t'; + } + + if (ch == ';' || (ch == ',' && IsRightHandExpression)) + { + OnStatementExit(); + } + else if (ch == '=' && !(Engine.previousChar == '=' || Engine.previousChar == '<' || Engine.previousChar == '>' || Engine.previousChar == '!')) + { + IsEqualCharPushed = true; + } + else if (ch == '.' && !IsMemberReferenceDotHandled) + { + // OPTION: CSharpFormattingOptions.AlignToMemberReferenceDot + if (Engine.formattingOptions.AlignToMemberReferenceDot && !Engine.isLineStart) + { + IsMemberReferenceDotHandled = true; + NextLineIndent.RemoveAlignment(); + NextLineIndent.SetAlignment(Engine.column - NextLineIndent.CurIndent - 1, true); + } + else if (Engine.isLineStart) + { + IsMemberReferenceDotHandled = true; + + ThisLineIndent.RemoveAlignment(); + while (ThisLineIndent.CurIndent > PreviousLineIndent && + ThisLineIndent.PopIf(IndentType.Continuation)) ; + ThisLineIndent.Push(IndentType.Continuation); + NextLineIndent = ThisLineIndent.Clone(); + } + } + else if (ch == ':' && Engine.isLineStart && !IsRightHandExpression) + { + // try to capture ': base(...)', ': this(...)' and inherit statements when they are on a new line + ThisLineIndent.Push(IndentType.Continuation); + } + else if (ch == Engine.newLineChar) + { + PreviousLineIndent = ThisLineIndent.CurIndent; + } + + if (Engine.wordToken.ToString() == "else") + { + CheckKeywordOnPush("else"); + } + + base.Push(ch); + } + + public override void InitializeState() + { + ThisLineIndent = Parent.ThisLineIndent.Clone(); + NextLineIndent = Parent.NextLineIndent.Clone(); + + // OPTION: IDocumentIndentEngine.EnableCustomIndentLevels + var parent = Parent as BracesBodyState; + if (parent == null || parent.LastBlockIndent == null || !Engine.EnableCustomIndentLevels) + { + NextLineIndent.RemoveAlignment(); + NextLineIndent.PopIf(IndentType.Continuation); + } + else + { + NextLineIndent = parent.LastBlockIndent.Clone(); + } + + if (Engine.isLineStart) + { + ThisLineIndent = NextLineIndent.Clone(); + } + + CurrentBody = extractBody(Parent); + NextBody = Body.None; + CurrentStatement = Statement.None; + + AddIndentation(CurrentBody); + } + + public override IndentState Clone(CSharpIndentEngine engine) + { + return new BracesBodyState(this, engine); + } + + public override void OnExit() + { + if (Parent is BracesBodyState && !((BracesBodyState)Parent).IsRightHandExpression) + { + ((BracesBodyState)Parent).OnStatementExit(); + } + + if (Engine.isLineStart) + { + ThisLineIndent.RemoveAlignment(); + ThisLineIndent.PopTry(); + BraceStyle style; + if (TryGetBraceStyle(this.CurrentBody, out style)) { + if (style == BraceStyle.NextLineShifted || + style == BraceStyle.NextLineShifted2|| + style == BraceStyle.BannerStyle) { + ThisLineIndent.Push(IndentType.Block); + } + } + } + + base.OnExit(); + } + + /// + /// Actions performed when the current statement exits. + /// + public virtual void OnStatementExit() + { + IsRightHandExpression = false; + IsMemberReferenceDotHandled = false; + + NextLineIndent.RemoveAlignment(); + NextLineIndent.PopWhile(IndentType.Continuation); + + CurrentStatement = Statement.None; + NextBody = Body.None; + LastBlockIndent = null; + } + + #region Helpers + + /// + /// Types of braces bodies. + /// + public enum Body + { + None, + Namespace, + Class, + Struct, + Interface, + Enum, + Switch, + Case, + Try, + Catch, + Finally + } + + /// + /// Types of statements. + /// + public enum Statement + { + None, + If, + Else, + Do, + While, + For, + Foreach, + Lock, + Using, + Return + } + + static readonly Dictionary bodies = new Dictionary + { + { "namespace", Body.Namespace }, + { "class", Body.Class }, + { "struct", Body.Struct }, + { "interface", Body.Interface }, + { "enum", Body.Enum }, + { "switch", Body.Switch }, + { "try", Body.Try }, + { "catch", Body.Catch }, + { "finally", Body.Finally }, + }; + + static readonly Dictionary statements = new Dictionary + { + { "if", Statement.If }, + // { "else", Statement.Else }, // should be handled in CheckKeywordAtPush + { "do", Statement.Do }, + { "while", Statement.While }, + { "for", Statement.For }, + { "foreach", Statement.Foreach }, + { "lock", Statement.Lock }, + { "using", Statement.Using }, + { "return", Statement.Return }, + }; + + static readonly HashSet blocks = new HashSet + { + "namespace", + "class", + "struct", + "interface", + "enum", + "switch", + "try", + "catch", + "finally", + "if", + "else", + "do", + "while", + "for", + "foreach", + "lock", + "using", + }; + + readonly string[] caseDefaultKeywords = { + "case", + "default" + }; + + readonly string[] classStructKeywords = { + "class", + "struct" + }; + + /// + /// Checks if the given string is a keyword and sets the + /// and the + /// variables appropriately. + /// + /// + /// A possible keyword. + /// + /// + /// This method is called from + /// + public override void CheckKeywordOnPush(string keyword) + { + if (keyword == "else") + { + CurrentStatement = Statement.Else; + + // OPTION: CSharpFormattingOptions.AlignElseInIfStatements + if (!Engine.formattingOptions.AlignElseInIfStatements && NestedIfStatementLevels.Count > 0) + { + ThisLineIndent = NestedIfStatementLevels.Pop().Clone(); + NextLineIndent = ThisLineIndent.Clone(); + } + + NextLineIndent.Push(IndentType.Continuation); + } + + if (blocks.Contains(keyword) && Engine.NeedsReindent) + { + LastBlockIndent = Indent.ConvertFrom(Engine.CurrentIndent, ThisLineIndent, Engine.textEditorOptions); + } + } + + /// + /// Checks if the given string is a keyword and sets the + /// and the + /// variables appropriately. + /// + /// + /// A possible keyword. + /// + public override void CheckKeyword(string keyword) + { + if (bodies.ContainsKey(keyword)) + { + var isKeywordTemplateConstraint = + classStructKeywords.Contains(keyword) && + (NextBody == Body.Class || NextBody == Body.Struct || NextBody == Body.Interface); + + if (!isKeywordTemplateConstraint) + { + NextBody = bodies[keyword]; + } + } + else if (caseDefaultKeywords.Contains(keyword) && CurrentBody == Body.Switch && Engine.isLineStartBeforeWordToken) + { + ChangeState(); + } + else if (keyword == "where" && Engine.isLineStartBeforeWordToken) + { + // try to capture where (generic type constraint) + ThisLineIndent.Push(IndentType.Continuation); + } + else if (statements.ContainsKey(keyword)) + { + Statement previousStatement = CurrentStatement; + CurrentStatement = statements[keyword]; + + // return if this is a using declaration or alias + if (CurrentStatement == Statement.Using && + (this is GlobalBodyState || CurrentBody == Body.Namespace)) + { + return; + } + + // OPTION: CSharpFormattingOptions.AlignEmbeddedIfStatements + if (Engine.formattingOptions.AlignEmbeddedStatements && + previousStatement == Statement.If && + CurrentStatement == Statement.If) + { + ThisLineIndent.PopIf(IndentType.Continuation); + NextLineIndent.PopIf(IndentType.Continuation); + } + + // OPTION: CSharpFormattingOptions.AlignEmbeddedStatements + if (Engine.formattingOptions.AlignEmbeddedStatements && + previousStatement == Statement.Lock && + CurrentStatement == Statement.Lock) + { + ThisLineIndent.PopIf(IndentType.Continuation); + NextLineIndent.PopIf(IndentType.Continuation); + } + + // OPTION: CSharpFormattingOptions.AlignEmbeddedUsingStatements + if (Engine.formattingOptions.AlignEmbeddedStatements && + previousStatement == Statement.Using && + CurrentStatement == Statement.Using) + { + ThisLineIndent.PopIf(IndentType.Continuation); + NextLineIndent.PopIf(IndentType.Continuation); + } + + // only add continuation for 'else' in 'else if' statement. + if (!(CurrentStatement == Statement.If && previousStatement == Statement.Else && !Engine.isLineStartBeforeWordToken)) + { + NextLineIndent.Push(IndentType.Continuation); + } + + if (CurrentStatement == Statement.If) + { + NestedIfStatementLevels.Push(ThisLineIndent); + } + } + + if (blocks.Contains(keyword) && Engine.NeedsReindent) + { + LastBlockIndent = Indent.ConvertFrom(Engine.CurrentIndent, ThisLineIndent, Engine.textEditorOptions); + } + } + + /// + /// Pushes a new level of indentation depending on the given + /// . + /// + void AddIndentation(BraceStyle braceStyle) + { + switch (braceStyle) + { + case BraceStyle.NextLineShifted: + ThisLineIndent.Push(IndentType.Block); + NextLineIndent.Push(IndentType.Block); + break; + case BraceStyle.DoNotChange: + case BraceStyle.EndOfLine: + case BraceStyle.EndOfLineWithoutSpace: + case BraceStyle.NextLine: + case BraceStyle.BannerStyle: + NextLineIndent.Push(IndentType.Block); + break; + case BraceStyle.NextLineShifted2: + ThisLineIndent.Push(IndentType.Block); + NextLineIndent.Push(IndentType.DoubleBlock); + break; + } + } + + bool TryGetBraceStyle (Body body, out BraceStyle style) + { + style = BraceStyle.DoNotChange; + switch (body) + { + case Body.None: + if (!Engine.formattingOptions.IndentBlocks) + return false; + style = Engine.formattingOptions.StatementBraceStyle; + return true; + case Body.Namespace: + if (!Engine.formattingOptions.IndentNamespaceBody) + return false; + style = Engine.formattingOptions.NamespaceBraceStyle; + return true; + case Body.Class: + if (!Engine.formattingOptions.IndentClassBody) + return false; + style = Engine.formattingOptions.ClassBraceStyle; + return true; + case Body.Struct: + if (!Engine.formattingOptions.IndentStructBody) + return false; + style = Engine.formattingOptions.StructBraceStyle; + return true; + case Body.Interface: + if (!Engine.formattingOptions.IndentInterfaceBody) + return false; + style = Engine.formattingOptions.InterfaceBraceStyle; + return true; + case Body.Enum: + if (!Engine.formattingOptions.IndentEnumBody) + return false; + style = Engine.formattingOptions.EnumBraceStyle; + return true; + case Body.Switch: + if (!Engine.formattingOptions.IndentSwitchBody) + return false; + style = Engine.formattingOptions.StatementBraceStyle; + return true; + case Body.Try: + case Body.Catch: + case Body.Finally: + style = Engine.formattingOptions.StatementBraceStyle; + return true; + } + return false; + } + + /// + /// Pushes a new level of indentation depending on the given + /// . + /// + void AddIndentation(Body body) + { + var isExpression = Parent is ParenthesesBodyState || Parent is SquareBracketsBodyState || + (Parent is BracesBodyState && ((BracesBodyState)Parent).IsRightHandExpression); + if (isExpression && Engine.formattingOptions.IndentBlocksInsideExpressions && Engine.isLineStart) + { + AddIndentation(BraceStyle.NextLineShifted); + } + + BraceStyle style; + if (TryGetBraceStyle(body, out style)) + { + AddIndentation(style); + } else { + NextLineIndent.Push(IndentType.Empty); + } + } + + /// + /// Extracts the from the given state. + /// + /// + /// The correct type for this state. + /// + static Body extractBody(IndentState state) + { + if (state != null && state is BracesBodyState) + { + return ((BracesBodyState)state).NextBody; + } + + return Body.None; + } + + #endregion + } + + #endregion + + #region Global body state + + /// + /// Global body state. + /// + /// + /// Represents the global space of the program. + /// + public class GlobalBodyState : BracesBodyState + { + public override char ClosedBracket + { + get { return '\0'; } + } + + public GlobalBodyState() + { } + + + public GlobalBodyState(CSharpIndentEngine engine) + { + Initialize (engine, null); + } + + public GlobalBodyState(GlobalBodyState prototype, CSharpIndentEngine engine) + : base(prototype, engine) + { } + + public override IndentState Clone(CSharpIndentEngine engine) + { + return new GlobalBodyState(this, engine); + } + + public override void InitializeState() + { + ThisLineIndent = new Indent(Engine.textEditorOptions); + NextLineIndent = ThisLineIndent.Clone(); + } + } + + #endregion + + #region Switch-case body state + + /// + /// Switch-case statement state. + /// + /// + /// Represents the block of code in one switch case (including default). + /// + public class SwitchCaseState : BracesBodyState + { + public SwitchCaseState() + { } + + public SwitchCaseState(SwitchCaseState prototype, CSharpIndentEngine engine) + : base(prototype, engine) + { } + + public override void Push(char ch) + { + // on ClosedBracket both this state (a case or a default statement) + // and also the whole switch block (handled in the base class) must exit. + if (ch == ClosedBracket) + { + ExitState(); + if (Parent is BracesBodyState) + Parent.OnExit(); + } + + base.Push(ch); + } + + public override void InitializeState() + { + ThisLineIndent = Parent.ThisLineIndent.Clone(); + NextLineIndent = ThisLineIndent.Clone(); + + // remove all continuations and extra spaces + ThisLineIndent.RemoveAlignment(); + ThisLineIndent.PopWhile(IndentType.Continuation); + + NextLineIndent.RemoveAlignment(); + NextLineIndent.PopWhile(IndentType.Continuation); + + if (Engine.formattingOptions.IndentCaseBody) + { + NextLineIndent.Push(IndentType.Block); + } + else + { + NextLineIndent.Push(IndentType.Empty); + } + } + + static readonly string[] caseDefaultKeywords = { + "case", + "default" + }; + + static readonly string[] breakContinueReturnGotoKeywords = { + "break", + "continue", + "return", + "goto" + }; + + public override void CheckKeyword(string keyword) + { + if (caseDefaultKeywords.Contains(keyword) && Engine.isLineStartBeforeWordToken) + { + ExitState(); + ChangeState(); + } + else if (breakContinueReturnGotoKeywords.Contains(keyword) && Engine.isLineStartBeforeWordToken) + { + // OPTION: Engine.formattingOptions.IndentBreakStatements + if (!Engine.formattingOptions.IndentBreakStatements) + { + ThisLineIndent = Parent.ThisLineIndent.Clone(); + } + } + + base.CheckKeyword(keyword); + } + + + public override void OnExit() + { + //Parent.OnExit(); + } + + public override IndentState Clone(CSharpIndentEngine engine) + { + return new SwitchCaseState(this, engine); + } + } + + #endregion + + #region Parentheses body state + + /// + /// Parentheses body state. + /// + /// + /// Represents a block of code between ( and ). + /// + public class ParenthesesBodyState : BracketsBodyBaseState + { + /// + /// True if any char has been pushed. + /// + public bool IsSomethingPushed; + + public override char ClosedBracket + { + get { return ')'; } + } + + public ParenthesesBodyState() + { } + + public ParenthesesBodyState(ParenthesesBodyState prototype, CSharpIndentEngine engine) + : base(prototype, engine) + { + IsSomethingPushed = prototype.IsSomethingPushed; + } + + public override void Push(char ch) + { + if (ch == Engine.newLineChar) + { + if (Engine.formattingOptions.AnonymousMethodBraceStyle == BraceStyle.EndOfLine || + Engine.formattingOptions.AnonymousMethodBraceStyle == BraceStyle.EndOfLineWithoutSpace) { + if (NextLineIndent.PopIf(IndentType.Continuation)) { + NextLineIndent.Push(IndentType.Block); + } + } + } + else if (!IsSomethingPushed) + { + // OPTION: CSharpFormattingOptions.AlignToFirstMethodCallArgument + if (Engine.formattingOptions.AlignToFirstMethodCallArgument) + { + NextLineIndent.PopTry(); + // align the next line at the beginning of the open bracket + NextLineIndent.ExtraSpaces = Math.Max(0, Engine.column - NextLineIndent.CurIndent - 1); + } + } + + base.Push(ch); + IsSomethingPushed = true; + } + + public override void InitializeState() + { + ThisLineIndent = Parent.ThisLineIndent.Clone(); + NextLineIndent = ThisLineIndent.Clone(); + NextLineIndent.Push(IndentType.Continuation); + } + + public override IndentState Clone(CSharpIndentEngine engine) + { + return new ParenthesesBodyState(this, engine); + } + + public override void OnExit() + { + if (Engine.isLineStart) + { + if (ThisLineIndent.ExtraSpaces > 0) + { + ThisLineIndent.ExtraSpaces--; + } + else + { + ThisLineIndent.PopTry(); + } + } + + base.OnExit(); + } + } + + #endregion + + #region Square brackets body state + + /// + /// Square brackets body state. + /// + /// + /// Represents a block of code between [ and ]. + /// + public class SquareBracketsBodyState : BracketsBodyBaseState + { + /// + /// True if any char has been pushed. + /// + public bool IsSomethingPushed; + + public override char ClosedBracket + { + get { return ']'; } + } + + public SquareBracketsBodyState() + { } + + public SquareBracketsBodyState(SquareBracketsBodyState prototype, CSharpIndentEngine engine) + : base(prototype, engine) + { + IsSomethingPushed = prototype.IsSomethingPushed; + } + + public override void Push(char ch) + { + if (ch == Engine.newLineChar) + { + if (NextLineIndent.PopIf(IndentType.Continuation)) + { + NextLineIndent.Push(IndentType.Block); + } + } + else if (!IsSomethingPushed) + { + // OPTION: CSharpFormattingOptions.AlignToFirstIndexerArgument + if (Engine.formattingOptions.AlignToFirstIndexerArgument) + { + NextLineIndent.PopTry(); + // align the next line at the beginning of the open bracket + NextLineIndent.ExtraSpaces = Math.Max(0, Engine.column - NextLineIndent.CurIndent - 1); + } + } + + base.Push(ch); + IsSomethingPushed = true; + } + + public override void InitializeState() + { + ThisLineIndent = Parent.ThisLineIndent.Clone(); + NextLineIndent = ThisLineIndent.Clone(); + NextLineIndent.Push(IndentType.Continuation); + } + + public override IndentState Clone(CSharpIndentEngine engine) + { + return new SquareBracketsBodyState(this, engine); + } + + public override void OnExit() + { + if (Engine.isLineStart) + { + if (ThisLineIndent.ExtraSpaces > 0) + { + ThisLineIndent.ExtraSpaces--; + } + else + { + ThisLineIndent.PopTry(); + } + } + + base.OnExit(); + } + } + + #endregion + + #endregion + + #region PreProcessor state + + /// + /// PreProcessor directive state. + /// + /// + /// Activated when the '#' char is pushed and the + /// is true. + /// + public class PreProcessorState : IndentState + { + /// + /// The type of the preprocessor directive. + /// + public PreProcessorDirective DirectiveType; + + /// + /// If is set (not equal to 'None'), this + /// stores the expression of the directive. + /// + public StringBuilder DirectiveStatement; + + public PreProcessorState() + { + DirectiveType = PreProcessorDirective.None; + DirectiveStatement = new StringBuilder(); + } + + public PreProcessorState(PreProcessorState prototype, CSharpIndentEngine engine) + : base(prototype, engine) + { + DirectiveType = prototype.DirectiveType; + DirectiveStatement = new StringBuilder(prototype.DirectiveStatement.ToString()); + } + + public override void Push(char ch) + { + // HACK: if this change would be left for the CheckKeyword method, we will lose + // it if the next pushed char is newLineChar since ThisLineIndent will be + // immediately replaced with NextLineIndent. As this most likely will + // happen, we check for "endregion" on every push. + if (Engine.wordToken.ToString() == "endregion") + { + CheckKeywordOnPush("endregion"); + } + + base.Push(ch); + + if (DirectiveType != PreProcessorDirective.None) + { + DirectiveStatement.Append(ch); + } + + if (ch == Engine.newLineChar) + { + ExitState(); + switch (DirectiveType) + { + case PreProcessorDirective.If: + Engine.ifDirectiveEvalResults.Push(eval(DirectiveStatement.ToString())); + if (Engine.ifDirectiveEvalResults.Peek()) + { + // the if/elif directive is true -> continue with the previous state + } + else + { + // the if/elif directive is false -> change to a state that will + // ignore any chars until #endif or #elif + ChangeState(); + } + break; + case PreProcessorDirective.Elif: + if (Engine.ifDirectiveEvalResults.Count > 0) + { + if (!Engine.ifDirectiveEvalResults.Peek()) + { + Engine.ifDirectiveEvalResults.Pop(); + goto case PreProcessorDirective.If; + } + } + // previous if was true -> comment + ChangeState(); + break; + case PreProcessorDirective.Else: + if (Engine.ifDirectiveEvalResults.Count > 0 && Engine.ifDirectiveEvalResults.Peek()) + { + // some if/elif directive was true -> change to a state that will + // ignore any chars until #endif + ChangeState(); + } + else + { + // none if/elif directives were true -> continue with the previous state + } + break; + case PreProcessorDirective.Define: + var defineSymbol = DirectiveStatement.ToString().Trim(); + if (!Engine.conditionalSymbols.Contains(defineSymbol)) + { + Engine.conditionalSymbols.Add(defineSymbol); + } + break; + case PreProcessorDirective.Undef: + var undefineSymbol = DirectiveStatement.ToString().Trim(); + if (Engine.conditionalSymbols.Contains(undefineSymbol)) + { + Engine.conditionalSymbols.Remove(undefineSymbol); + } + break; + case PreProcessorDirective.Endif: + // marks the end of this block + Engine.ifDirectiveEvalResults.Pop(); + Engine.ifDirectiveIndents.Pop(); + break; + case PreProcessorDirective.Region: + case PreProcessorDirective.Pragma: + case PreProcessorDirective.Warning: + case PreProcessorDirective.Error: + case PreProcessorDirective.Line: + // continue with the previous state + break; + } + } + } + + public override void InitializeState() + { + // OPTION: IndentPreprocessorStatements + if (Engine.formattingOptions.IndentPreprocessorDirectives) + { + if (Engine.ifDirectiveIndents.Count > 0) + { + ThisLineIndent = Engine.ifDirectiveIndents.Peek().Clone(); + } + else + { + ThisLineIndent = Parent.ThisLineIndent.Clone(); + } + } + else + { + ThisLineIndent = new Indent(Engine.textEditorOptions); + } + + NextLineIndent = Parent.NextLineIndent.Clone(); + } + + static readonly Dictionary preProcessorDirectives = new Dictionary + { + { "if", PreProcessorDirective.If }, + { "elif", PreProcessorDirective.Elif }, + { "else", PreProcessorDirective.Else }, + { "endif", PreProcessorDirective.Endif }, + { "region", PreProcessorDirective.Region }, + { "endregion", PreProcessorDirective.Endregion }, + { "pragma", PreProcessorDirective.Pragma }, + { "warning", PreProcessorDirective.Warning }, + { "error", PreProcessorDirective.Error }, + { "line", PreProcessorDirective.Line }, + { "define", PreProcessorDirective.Define }, + { "undef", PreProcessorDirective.Undef } + }; + + public override void CheckKeywordOnPush(string keyword) + { + if (keyword == "endregion") + { + DirectiveType = PreProcessorDirective.Endregion; + ThisLineIndent = Parent.NextLineIndent.Clone(); + } + } + + public override void CheckKeyword(string keyword) + { + // check if the directive type has already been set + if (DirectiveType != PreProcessorDirective.None) + { + return; + } + + if (preProcessorDirectives.ContainsKey(keyword)) + { + DirectiveType = preProcessorDirectives[keyword]; + + // adjust the indentation for the region directive + if (DirectiveType == PreProcessorDirective.Region) + { + ThisLineIndent = Parent.NextLineIndent.Clone(); + } + else if (DirectiveType == PreProcessorDirective.If) + { + Engine.ifDirectiveIndents.Push(ThisLineIndent.Clone()); + } + } + } + + public override IndentState Clone(CSharpIndentEngine engine) + { + return new PreProcessorState(this, engine); + } + + /// + /// Types of preprocessor directives. + /// + public enum PreProcessorDirective + { + None, + If, + Elif, + Else, + Endif, + Region, + Endregion, + Pragma, + Warning, + Error, + Line, + Define, + Undef + } + + #region Pre processor evaluation (from cs-tokenizer.cs) + + static bool is_identifier_start_character(int c) + { + return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || c == '_' || Char.IsLetter((char)c); + } + + static bool is_identifier_part_character(char c) + { + if (c >= 'a' && c <= 'z') + return true; + + if (c >= 'A' && c <= 'Z') + return true; + + if (c == '_' || (c >= '0' && c <= '9')) + return true; + + if (c < 0x80) + return false; + + return Char.IsLetter(c) || Char.GetUnicodeCategory(c) == UnicodeCategory.ConnectorPunctuation; + } + + bool eval_val(string s) + { + if (s == "true") + return true; + if (s == "false") + return false; + + return Engine.conditionalSymbols != null && Engine.conditionalSymbols.Contains(s) || + Engine.customConditionalSymbols != null && Engine.customConditionalSymbols.Contains(s); + } + + bool pp_primary(ref string s) + { + s = s.Trim(); + int len = s.Length; + + if (len > 0) + { + char c = s[0]; + + if (c == '(') + { + s = s.Substring(1); + bool val = pp_expr(ref s, false); + if (s.Length > 0 && s[0] == ')') + { + s = s.Substring(1); + return val; + } + return false; + } + + if (is_identifier_start_character(c)) + { + int j = 1; + + while (j < len) + { + c = s[j]; + + if (is_identifier_part_character(c)) + { + j++; + continue; + } + bool v = eval_val(s.Substring(0, j)); + s = s.Substring(j); + return v; + } + bool vv = eval_val(s); + s = ""; + return vv; + } + } + return false; + } + + bool pp_unary(ref string s) + { + s = s.Trim(); + int len = s.Length; + + if (len > 0) + { + if (s[0] == '!') + { + if (len > 1 && s[1] == '=') + { + return false; + } + s = s.Substring(1); + return !pp_primary(ref s); + } + else + return pp_primary(ref s); + } + else + { + return false; + } + } + + bool pp_eq(ref string s) + { + bool va = pp_unary(ref s); + + s = s.Trim(); + int len = s.Length; + if (len > 0) + { + if (s[0] == '=') + { + if (len > 2 && s[1] == '=') + { + s = s.Substring(2); + return va == pp_unary(ref s); + } + else + { + return false; + } + } + else if (s[0] == '!' && len > 1 && s[1] == '=') + { + s = s.Substring(2); + + return va != pp_unary(ref s); + + } + } + + return va; + + } + + bool pp_and(ref string s) + { + bool va = pp_eq(ref s); + + s = s.Trim(); + int len = s.Length; + if (len > 0) + { + if (s[0] == '&') + { + if (len > 2 && s[1] == '&') + { + s = s.Substring(2); + return (va & pp_and(ref s)); + } + else + { + return false; + } + } + } + return va; + } + + // + // Evaluates an expression for `#if' or `#elif' + // + bool pp_expr(ref string s, bool isTerm) + { + bool va = pp_and(ref s); + s = s.Trim(); + int len = s.Length; + if (len > 0) + { + char c = s[0]; + + if (c == '|') + { + if (len > 2 && s[1] == '|') + { + s = s.Substring(2); + return va | pp_expr(ref s, isTerm); + } + else + { + + return false; + } + } + if (isTerm) + { + return false; + } + } + + return va; + } + + bool eval(string s) + { + bool v = pp_expr(ref s, true); + s = s.Trim(); + if (s.Length != 0) + { + return false; + } + + return v; + } + + #endregion + } + + #endregion + + #region PreProcessorComment state + + /// + /// PreProcessor comment state. + /// + /// + /// Activates when the #if or #elif directive is false and ignores + /// all pushed chars until the next '#'. + /// + public class PreProcessorCommentState : IndentState + { + public PreProcessorCommentState() + { } + + public PreProcessorCommentState(PreProcessorCommentState prototype, CSharpIndentEngine engine) + : base(prototype, engine) + { } + + public override void Push(char ch) + { + base.Push(ch); + + if (ch == '#' && Engine.isLineStart) + { + // TODO: Return back only on #if/#elif/#else/#endif + // Ignore any of the other directives (especially #define/#undef) + ExitState(); + ChangeState(); + } + } + + public override void InitializeState() + { + if (Engine.formattingOptions.IndentPreprocessorDirectives && + Engine.ifDirectiveIndents.Count > 0) + { + ThisLineIndent = Engine.ifDirectiveIndents.Peek().Clone(); + NextLineIndent = ThisLineIndent.Clone(); + } + else + { + ThisLineIndent = Parent.NextLineIndent.Clone(); + NextLineIndent = ThisLineIndent.Clone(); + } + } + + public override IndentState Clone(CSharpIndentEngine engine) + { + return new PreProcessorCommentState(this, engine); + } + } + + #endregion + + #region LineComment state + + /// + /// Single-line comment state. + /// + public class LineCommentState : IndentState + { + /// + /// It's possible that this should be the DocComment state: + /// check if the first next pushed char is equal to '/'. + /// + public bool CheckForDocComment = true; + + public LineCommentState() + { + /* if (engine.formattingOptions.KeepCommentsAtFirstColumn && engine.column == 2) + ThisLineIndent.Reset();*/ + } + + public LineCommentState(LineCommentState prototype, CSharpIndentEngine engine) + : base(prototype, engine) + { + CheckForDocComment = prototype.CheckForDocComment; + } + + public override void Push(char ch) + { + base.Push(ch); + + if (ch == Engine.newLineChar) + { + // to handle cases like //\n/* + // Otherwise line 2 would be treated as line comment. + Engine.previousChar = '\0'; + ExitState(); + } + else if (ch == '/' && CheckForDocComment) + { + // wrong state, should be DocComment. + ExitState(); + ChangeState(); + } + + CheckForDocComment = false; + } + + public override void InitializeState() + { + ThisLineIndent = Parent.ThisLineIndent.Clone(); + NextLineIndent = Parent.NextLineIndent.Clone(); + } + + public override IndentState Clone(CSharpIndentEngine engine) + { + return new LineCommentState(this, engine); + } + } + + #endregion + + #region DocComment state + + /// + /// XML documentation comment state. + /// + public class DocCommentState : IndentState + { + public DocCommentState() + { } + + public DocCommentState(DocCommentState prototype, CSharpIndentEngine engine) + : base(prototype, engine) + { } + + public override void Push(char ch) + { + base.Push(ch); + + if (ch == Engine.newLineChar) + { + ExitState(); + } + } + + public override void InitializeState() + { + ThisLineIndent = Parent.ThisLineIndent.Clone(); + NextLineIndent = Parent.NextLineIndent.Clone(); + } + + public override IndentState Clone(CSharpIndentEngine engine) + { + return new DocCommentState(this, engine); + } + } + + #endregion + + #region MultiLineComment state + + /// + /// Multi-line comment state. + /// + public class MultiLineCommentState : IndentState + { + /// + /// True if any char has been pushed to this state. + /// + /// + /// Needed to resolve an issue when the first pushed char is '/'. + /// The state would falsely exit on this sequence of chars '/*/', + /// since it only checks if the last two chars are '/' and '*'. + /// + public bool IsAnyCharPushed; + + public MultiLineCommentState() + { } + + public MultiLineCommentState(MultiLineCommentState prototype, CSharpIndentEngine engine) + : base(prototype, engine) + { + IsAnyCharPushed = prototype.IsAnyCharPushed; + } + + public override void Push(char ch) + { + base.Push(ch); + + if (ch == '/' && Engine.previousChar == '*' && IsAnyCharPushed) + { + ExitState(); + } + + IsAnyCharPushed = true; + } + + public override void InitializeState() + { + ThisLineIndent = Parent.ThisLineIndent.Clone(); + NextLineIndent = ThisLineIndent.Clone(); + } + + public override IndentState Clone(CSharpIndentEngine engine) + { + return new MultiLineCommentState(this, engine); + } + } + + #endregion + + #region StringLiteral state + + /// + /// StringLiteral state. + /// + public class StringLiteralState : IndentState + { + /// + /// True if the next char is escaped with '\'. + /// + public bool IsEscaped; + + public StringLiteralState() + { } + + public StringLiteralState(StringLiteralState prototype, CSharpIndentEngine engine) + : base(prototype, engine) + { + IsEscaped = prototype.IsEscaped; + } + + public override void Push(char ch) + { + base.Push(ch); + + if (ch == Engine.newLineChar || (!IsEscaped && ch == '"')) { + ExitState(); + } else { + IsEscaped = ch == '\\' && !IsEscaped; + } + } + + public override void InitializeState() + { + ThisLineIndent = Parent.ThisLineIndent.Clone(); + NextLineIndent = Parent.NextLineIndent.Clone(); + } + + public override IndentState Clone(CSharpIndentEngine engine) + { + return new StringLiteralState(this, engine); + } + } + + #endregion + + #region Verbatim string state + + /// + /// Verbatim string state. + /// + public class VerbatimStringState : IndentState + { + /// + /// True if there is an odd number of '"' in a row. + /// + public bool IsEscaped; + + public VerbatimStringState() + { } + + public VerbatimStringState(VerbatimStringState prototype, CSharpIndentEngine engine) + : base(prototype, engine) + { + IsEscaped = prototype.IsEscaped; + } + + public override void Push(char ch) + { + base.Push(ch); + + if (IsEscaped && ch != '"') + { + ExitState(); + // the char has been pushed to the wrong state, push it back + Engine.currentState.Push(ch); + } + + IsEscaped = ch == '"' && !IsEscaped; + } + + public override void InitializeState() + { + ThisLineIndent = Parent.ThisLineIndent.Clone(); + NextLineIndent = new Indent(Engine.textEditorOptions); + } + + public override IndentState Clone(CSharpIndentEngine engine) + { + return new VerbatimStringState(this, engine); + } + } + + #endregion + + #region Character state + + /// + /// Character state. + /// + public class CharacterState : IndentState + { + /// + /// True if the next char is escaped with '\'. + /// + public bool IsEscaped; + + public CharacterState() + { } + + public CharacterState(CharacterState prototype, CSharpIndentEngine engine) + : base(prototype, engine) + { + IsEscaped = prototype.IsEscaped; + } + + public override void Push(char ch) + { + base.Push(ch); + + if (ch == Engine.newLineChar) + { + ExitState(); + } + else if (!IsEscaped && ch == '\'') + { + ExitState(); + } + + IsEscaped = ch == '\\' && !IsEscaped; + } + + public override void InitializeState() + { + ThisLineIndent = Parent.ThisLineIndent.Clone(); + NextLineIndent = Parent.NextLineIndent.Clone(); + } + + public override IndentState Clone(CSharpIndentEngine engine) + { + return new CharacterState(this, engine); + } + } + + #endregion +} diff --git a/NRefactory/ICSharpCode.NRefactory.CSharp/IndentEngine/NullIStateMachineIndentEngine.cs b/NRefactory/ICSharpCode.NRefactory.CSharp/IndentEngine/NullIStateMachineIndentEngine.cs new file mode 100644 index 000000000..b62932e5b --- /dev/null +++ b/NRefactory/ICSharpCode.NRefactory.CSharp/IndentEngine/NullIStateMachineIndentEngine.cs @@ -0,0 +1,215 @@ +// +// NullIStateMachineIndentEngine.cs +// +// Author: +// Mike Krüger +// +// Copyright (c) 2013 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; + +namespace ICSharpCode.NRefactory.CSharp +{ + /// + /// An empty IStateMachineIndentEngine implementation that does nothing. + /// + public sealed class NullIStateMachineIndentEngine : IStateMachineIndentEngine + { + readonly ICSharpCode.NRefactory.Editor.IDocument document; + int offset; + + public NullIStateMachineIndentEngine(ICSharpCode.NRefactory.Editor.IDocument document) + { + if (document == null) + throw new ArgumentNullException("document"); + this.document = document; + } + + #region IStateMachineIndentEngine implementation + public IStateMachineIndentEngine Clone() + { + return new NullIStateMachineIndentEngine(document) { offset = this.offset }; + } + + bool IStateMachineIndentEngine.IsInsidePreprocessorDirective { + get { + return false; + } + } + + bool IStateMachineIndentEngine.IsInsidePreprocessorComment { + get { + return false; + } + } + + bool IStateMachineIndentEngine.IsInsideStringLiteral { + get { + return false; + } + } + + bool IStateMachineIndentEngine.IsInsideVerbatimString { + get { + return false; + } + } + + bool IStateMachineIndentEngine.IsInsideCharacter { + get { + return false; + } + } + + bool IStateMachineIndentEngine.IsInsideString { + get { + return false; + } + } + + bool IStateMachineIndentEngine.IsInsideLineComment { + get { + return false; + } + } + + bool IStateMachineIndentEngine.IsInsideMultiLineComment { + get { + return false; + } + } + + bool IStateMachineIndentEngine.IsInsideDocLineComment { + get { + return false; + } + } + + bool IStateMachineIndentEngine.IsInsideComment { + get { + return false; + } + } + + bool IStateMachineIndentEngine.IsInsideOrdinaryComment { + get { + return false; + } + } + + bool IStateMachineIndentEngine.IsInsideOrdinaryCommentOrString { + get { + return false; + } + } + + bool IStateMachineIndentEngine.LineBeganInsideVerbatimString { + get { + return false; + } + } + + bool IStateMachineIndentEngine.LineBeganInsideMultiLineComment { + get { + return false; + } + } + #endregion + + #region IDocumentIndentEngine implementation + void IDocumentIndentEngine.Push(char ch) + { + offset++; + } + + void IDocumentIndentEngine.Reset() + { + this.offset = 0; + } + + void IDocumentIndentEngine.Update(int offset) + { + this.offset = offset; + } + + IDocumentIndentEngine IDocumentIndentEngine.Clone() + { + return Clone(); + } + + ICSharpCode.NRefactory.Editor.IDocument IDocumentIndentEngine.Document { + get { + return document; + } + } + + string IDocumentIndentEngine.ThisLineIndent { + get { + return ""; + } + } + + string IDocumentIndentEngine.NextLineIndent { + get { + return ""; + } + } + + string IDocumentIndentEngine.CurrentIndent { + get { + return ""; + } + } + + bool IDocumentIndentEngine.NeedsReindent { + get { + return false; + } + } + + int IDocumentIndentEngine.Offset { + get { + return offset; + } + } + TextLocation IDocumentIndentEngine.Location { + get { + return TextLocation.Empty; + } + } + + /// + public bool EnableCustomIndentLevels + { + get { return false; } + set { } + } + + #endregion + + #region ICloneable implementation + object ICloneable.Clone() + { + return Clone(); + } + #endregion + } +} + diff --git a/NRefactory/ICSharpCode.NRefactory.CSharp/IndentEngine/TextPasteIndentEngine.cs b/NRefactory/ICSharpCode.NRefactory.CSharp/IndentEngine/TextPasteIndentEngine.cs new file mode 100644 index 000000000..9170b029f --- /dev/null +++ b/NRefactory/ICSharpCode.NRefactory.CSharp/IndentEngine/TextPasteIndentEngine.cs @@ -0,0 +1,632 @@ +// +// TextPasteIndentEngine.cs +// +// Author: +// Matej Miklečić +// +// Copyright (c) 2013 Matej Miklečić (matej.miklecic@gmail.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 ICSharpCode.NRefactory.Editor; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using System.Text; + +namespace ICSharpCode.NRefactory.CSharp +{ + /// + /// Represents a decorator of an IStateMachineIndentEngine instance + /// that provides logic for text paste events. + /// + public class TextPasteIndentEngine : IDocumentIndentEngine, ITextPasteHandler + { + + #region Properties + + /// + /// An instance of IStateMachineIndentEngine which handles + /// the indentation logic. + /// + IStateMachineIndentEngine engine; + /// + /// Text editor options. + /// + internal readonly TextEditorOptions textEditorOptions; + internal readonly CSharpFormattingOptions formattingOptions; + #endregion + + #region Constructors + + /// + /// Creates a new TextPasteIndentEngine instance. + /// + /// + /// An instance of to which the + /// logic for indentation will be delegated. + /// + /// + /// Text editor options for indentation. + /// + /// + /// C# formatting options. + /// + public TextPasteIndentEngine(IStateMachineIndentEngine decoratedEngine, TextEditorOptions textEditorOptions, CSharpFormattingOptions formattingOptions) + { + this.engine = decoratedEngine; + this.textEditorOptions = textEditorOptions; + this.formattingOptions = formattingOptions; + + this.engine.EnableCustomIndentLevels = false; + } + + #endregion + + #region ITextPasteHandler + + /// + string ITextPasteHandler.FormatPlainText(int offset, string text, byte[] copyData) + { + if (copyData != null && copyData.Length == 1) { + var strategy = TextPasteUtils.Strategies [(PasteStrategy)copyData [0]]; + text = strategy.Decode(text); + } + engine.Update(offset); + if (engine.IsInsideStringLiteral) { + int idx = text.IndexOf('"'); + if (idx > 0) { + var o = offset; + while (o < engine.Document.TextLength) { + char ch = engine.Document.GetCharAt(o); + engine.Push(ch); + if (NewLine.IsNewLine(ch)) + break; + o++; + if (!engine.IsInsideStringLiteral) + return TextPasteUtils.StringLiteralStrategy.Encode(text); + } + return TextPasteUtils.StringLiteralStrategy.Encode(text.Substring(0, idx)) + text.Substring(idx); + } + return TextPasteUtils.StringLiteralStrategy.Encode(text); + + } else if (engine.IsInsideVerbatimString) { + + int idx = text.IndexOf('"'); + if (idx > 0) { + var o = offset; + while (o < engine.Document.TextLength) { + char ch = engine.Document.GetCharAt(o); + engine.Push(ch); + o++; + if (!engine.IsInsideVerbatimString) + return TextPasteUtils.VerbatimStringStrategy.Encode(text); + } + return TextPasteUtils.VerbatimStringStrategy.Encode(text.Substring(0, idx)) + text.Substring(idx); + } + + return TextPasteUtils.VerbatimStringStrategy.Encode(text); + } + var line = engine.Document.GetLineByOffset(offset); + var pasteAtLineStart = line.Offset == offset; + var indentedText = new StringBuilder(); + var curLine = new StringBuilder(); + var clonedEngine = engine.Clone(); + bool isNewLine = false, gotNewLine = false; + for (int i = 0; i < text.Length; i++) { + var ch = text [i]; + if (clonedEngine.IsInsideVerbatimString || clonedEngine.IsInsideMultiLineComment) { + clonedEngine.Push(ch); + curLine.Append(ch); + continue; + } + + var delimiterLength = NewLine.GetDelimiterLength(ch, i + 1 < text.Length ? text[i + 1] : ' '); + if (delimiterLength > 0) { + isNewLine = true; + if (gotNewLine || pasteAtLineStart) { + if (curLine.Length > 0 || formattingOptions.EmptyLineFormatting == EmptyLineFormatting.Indent) + indentedText.Append(clonedEngine.ThisLineIndent); + } + indentedText.Append(curLine); + indentedText.Append(textEditorOptions.EolMarker); + curLine.Length = 0; + gotNewLine = true; + i += delimiterLength - 1; + // textEditorOptions.EolMarker[0] is the newLineChar used by the indentation engine. + clonedEngine.Push(textEditorOptions.EolMarker[0]); + } else { + if (isNewLine) { + if (ch == '\t' || ch == ' ') { + clonedEngine.Push(ch); + continue; + } + isNewLine = false; + } + curLine.Append(ch); + clonedEngine.Push(ch); + } + if (clonedEngine.IsInsideVerbatimString || clonedEngine.IsInsideMultiLineComment && + !(clonedEngine.LineBeganInsideVerbatimString || clonedEngine.LineBeganInsideMultiLineComment)) { + if (gotNewLine) { + if (curLine.Length > 0 || formattingOptions.EmptyLineFormatting == EmptyLineFormatting.Indent) + indentedText.Append(clonedEngine.ThisLineIndent); + } + pasteAtLineStart = false; + indentedText.Append(curLine); + curLine.Length = 0; + gotNewLine = false; + continue; + } + } + if (gotNewLine && (!pasteAtLineStart || curLine.Length > 0)) { + indentedText.Append(clonedEngine.ThisLineIndent); + } + if (curLine.Length > 0) { + indentedText.Append(curLine); + } + return indentedText.ToString(); + } + + /// + byte[] ITextPasteHandler.GetCopyData(ISegment segment) + { + engine.Update(segment.Offset); + + if (engine.IsInsideStringLiteral) { + return new[] { (byte)PasteStrategy.StringLiteral }; + } else if (engine.IsInsideVerbatimString) { + return new[] { (byte)PasteStrategy.VerbatimString }; + } + + return null; + } + + #endregion + + #region IDocumentIndentEngine + + /// + public IDocument Document { + get { return engine.Document; } + } + + /// + public string ThisLineIndent { + get { return engine.ThisLineIndent; } + } + + /// + public string NextLineIndent { + get { return engine.NextLineIndent; } + } + + /// + public string CurrentIndent { + get { return engine.CurrentIndent; } + } + + /// + public bool NeedsReindent { + get { return engine.NeedsReindent; } + } + + /// + public int Offset { + get { return engine.Offset; } + } + + /// + public TextLocation Location { + get { return engine.Location; } + } + + /// + public bool EnableCustomIndentLevels { + get { return engine.EnableCustomIndentLevels; } + set { engine.EnableCustomIndentLevels = value; } + } + + /// + public void Push(char ch) + { + engine.Push(ch); + } + + /// + public void Reset() + { + engine.Reset(); + } + + /// + public void Update(int offset) + { + engine.Update(offset); + } + + #endregion + + #region IClonable + + public IDocumentIndentEngine Clone() + { + return new TextPasteIndentEngine(engine, textEditorOptions, formattingOptions); + } + + object ICloneable.Clone() + { + return Clone(); + } + + #endregion + + } + + /// + /// Types of text-paste strategies. + /// + public enum PasteStrategy : byte + { + PlainText = 0, + StringLiteral = 1, + VerbatimString = 2 + } + + /// + /// Defines some helper methods for dealing with text-paste events. + /// + public static class TextPasteUtils + { + /// + /// Collection of text-paste strategies. + /// + public static TextPasteStrategies Strategies = new TextPasteStrategies(); + + /// + /// The interface for a text-paste strategy. + /// + public interface IPasteStrategy + { + /// + /// Formats the given text according with this strategy rules. + /// + /// + /// The text to format. + /// + /// + /// Formatted text. + /// + string Encode(string text); + + /// + /// Converts text formatted according with this strategy rules + /// to its original form. + /// + /// + /// Formatted text to convert. + /// + /// + /// Original form of the given formatted text. + /// + string Decode(string text); + + /// + /// Type of this strategy. + /// + PasteStrategy Type { get; } + } + + /// + /// Wrapper that discovers all defined text-paste strategies and defines a way + /// to easily access them through their type. + /// + public sealed class TextPasteStrategies + { + /// + /// Collection of discovered text-paste strategies. + /// + IDictionary strategies; + + /// + /// Uses reflection to find all types derived from + /// and adds an instance of each strategy to . + /// + public TextPasteStrategies() + { + strategies = Assembly.GetExecutingAssembly() + .GetTypes() + .Where(t => typeof(IPasteStrategy).IsAssignableFrom(t) && t.IsClass) + .Select(t => (IPasteStrategy)t.GetProperty("Instance").GetValue(null, null)) + .ToDictionary(s => s.Type); + } + + /// + /// Checks if there is a strategy of the given type and returns it. + /// + /// + /// Type of the strategy instance. + /// + /// + /// A strategy instance of the requested type, + /// or if it wasn't found. + /// + public IPasteStrategy this [PasteStrategy strategy] { + get { + if (strategies.ContainsKey(strategy)) { + return strategies [strategy]; + } + + return DefaultStrategy; + } + } + } + + /// + /// Doesn't do any formatting. Serves as the default strategy. + /// + public class PlainTextPasteStrategy : IPasteStrategy + { + + #region Singleton + + public static IPasteStrategy Instance { + get { + return instance ?? (instance = new PlainTextPasteStrategy()); + } + } + + static PlainTextPasteStrategy instance; + + protected PlainTextPasteStrategy() + { + } + + #endregion + + /// + public string Encode(string text) + { + return text; + } + + /// + public string Decode(string text) + { + return text; + } + + /// + public PasteStrategy Type { + get { return PasteStrategy.PlainText; } + } + } + + /// + /// Escapes chars in the given text so that they don't + /// break a valid string literal. + /// + public class StringLiteralPasteStrategy : IPasteStrategy + { + + #region Singleton + + public static IPasteStrategy Instance { + get { + return instance ?? (instance = new StringLiteralPasteStrategy()); + } + } + + static StringLiteralPasteStrategy instance; + + protected StringLiteralPasteStrategy() + { + } + + #endregion + + /// + public string Encode(string text) + { + return CSharpOutputVisitor.ConvertString(text); + } + + /// + public string Decode(string text) + { + var result = new StringBuilder(); + bool isEscaped = false; + + for (int i = 0; i < text.Length; i++) { + var ch = text[i]; + if (isEscaped) { + switch (ch) { + case 'a': + result.Append('\a'); + break; + case 'b': + result.Append('\b'); + break; + case 'n': + result.Append('\n'); + break; + case 't': + result.Append('\t'); + break; + case 'v': + result.Append('\v'); + break; + case 'r': + result.Append('\r'); + break; + case '\\': + result.Append('\\'); + break; + case 'f': + result.Append('\f'); + break; + case '0': + result.Append(0); + break; + case '"': + result.Append('"'); + break; + case '\'': + result.Append('\''); + break; + case 'x': + char r; + if (TryGetHex(text, -1, ref i, out r)) { + result.Append(r); + break; + } + goto default; + case 'u': + if (TryGetHex(text, 4, ref i, out r)) { + result.Append(r); + break; + } + goto default; + case 'U': + if (TryGetHex(text, 8, ref i, out r)) { + result.Append(r); + break; + } + goto default; + default: + result.Append('\\'); + result.Append(ch); + break; + } + isEscaped = false; + continue; + } + if (ch != '\\') { + result.Append(ch); + } + else { + isEscaped = true; + } + } + + return result.ToString(); + } + + static bool TryGetHex(string text, int count, ref int idx, out char r) + { + int i; + int total = 0; + int top = count != -1 ? count : 4; + + for (i = 0; i < top; i++) { + int c = text[idx + 1 + i]; + + if (c >= '0' && c <= '9') + c = (int) c - (int) '0'; + else if (c >= 'A' && c <= 'F') + c = (int) c - (int) 'A' + 10; + else if (c >= 'a' && c <= 'f') + c = (int) c - (int) 'a' + 10; + else { + r = '\0'; + return false; + } + total = (total * 16) + c; + } + + if (top == 8) { + if (total > 0x0010FFFF) { + r = '\0'; + return false; + } + + if (total >= 0x00010000) + total = ((total - 0x00010000) / 0x0400 + 0xD800); + } + r = (char)total; + idx += top; + return true; + } + + /// + public PasteStrategy Type { + get { return PasteStrategy.StringLiteral; } + } + } + + /// + /// Escapes chars in the given text so that they don't + /// break a valid verbatim string. + /// + public class VerbatimStringPasteStrategy : IPasteStrategy + { + + #region Singleton + + public static IPasteStrategy Instance { + get { + return instance ?? (instance = new VerbatimStringPasteStrategy()); + } + } + + static VerbatimStringPasteStrategy instance; + + protected VerbatimStringPasteStrategy() + { + } + + #endregion + + static readonly Dictionary> encodeReplace = new Dictionary> { + { '\"', "\"\"" }, + }; + + /// + public string Encode(string text) + { + return string.Concat(text.SelectMany(c => encodeReplace.ContainsKey(c) ? encodeReplace [c] : new[] { c })); + } + + /// + public string Decode(string text) + { + bool isEscaped = false; + return string.Concat(text.Where(c => !(isEscaped = !isEscaped && c == '"'))); + } + + /// + public PasteStrategy Type { + get { return PasteStrategy.VerbatimString; } + } + } + + /// + /// The default text-paste strategy. + /// + public static IPasteStrategy DefaultStrategy = PlainTextPasteStrategy.Instance; + /// + /// String literal text-paste strategy. + /// + public static IPasteStrategy StringLiteralStrategy = StringLiteralPasteStrategy.Instance; + /// + /// Verbatim string text-paste strategy. + /// + public static IPasteStrategy VerbatimStringStrategy = VerbatimStringPasteStrategy.Instance; + } +} diff --git a/NRefactory/ICSharpCode.NRefactory.CSharp/IntroduceQueryExpressions.cs b/NRefactory/ICSharpCode.NRefactory.CSharp/IntroduceQueryExpressions.cs new file mode 100644 index 000000000..d80ddb82c --- /dev/null +++ b/NRefactory/ICSharpCode.NRefactory.CSharp/IntroduceQueryExpressions.cs @@ -0,0 +1,386 @@ +// +// IntroduceQueryExpressions.cs +// +// Modified by Luís Reis (Copyright (C) 2013) +// +// Copyright header of the original version follows: +// +// Copyright (c) 2011 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.Diagnostics; +using System.Linq; +using ICSharpCode.NRefactory.CSharp; +using ICSharpCode.NRefactory.PatternMatching; + +namespace ICSharpCode.NRefactory.CSharp +{ + static class NRefactoryExtensions + { + public static T Detach(this T node) where T : AstNode + { + node.Remove(); + return node; + } + + public static T CopyAnnotationsFrom(this T node, AstNode other) where T : AstNode + { + foreach (object annotation in other.Annotations) { + node.AddAnnotation(annotation); + } + return node; + } + + public static Expression WithName(this Expression node, string patternGroupName) + { + return new NamedNode(patternGroupName, node); + } + } + + /// + /// Decompiles query expressions. + /// Based on C# 4.0 spec, §7.16.2 Query expression translation + /// + public class IntroduceQueryExpressions + { + static readonly InvocationExpression castPattern = new InvocationExpression { + Target = new MemberReferenceExpression { + Target = new AnyNode("inExpr"), + MemberName = "Cast", + TypeArguments = { new AnyNode("targetType") } + }}; + + public Expression ConvertFluentToQuery(Expression node) + { + node = node.Clone(); + + var artificialParent = new ExpressionStatement(); + artificialParent.Expression = node; + + DecompileQueries(node); + // After all queries were decompiled, detect degenerate queries (queries not property terminated with 'select' or 'group') + // and fix them, either by adding a degenerate select, or by combining them with another query. + foreach (QueryExpression query in artificialParent.Descendants.OfType()) { + QueryFromClause fromClause = (QueryFromClause)query.Clauses.First(); + if (IsDegenerateQuery(query)) { + string identifierName = fromClause.Identifier; + + // introduce select for degenerate query + query.Clauses.Add(new QuerySelectClause { Expression = new IdentifierExpression(identifierName) }); + } + + if (fromClause.Type.IsNull) { + // See if the data source of this query is a degenerate query, + // and combine the queries if possible. + QueryExpression innerQuery = fromClause.Expression as QueryExpression; + while (IsDegenerateQuery(innerQuery)) { + QueryFromClause innerFromClause = (QueryFromClause)innerQuery.Clauses.First(); + if (fromClause.Identifier != innerFromClause.Identifier && !innerFromClause.Identifier.StartsWith("<>")) + break; + // Replace the fromClause with all clauses from the inner query + fromClause.Remove(); + foreach (var identifierChild in innerQuery.Descendants.OfType().Where(identifier => identifier.Name == innerFromClause.Identifier)) { + //When the identifier is "<>X", then replace it with the outer one + identifierChild.ReplaceWith(fromClause.IdentifierToken.Clone()); + } + QueryClause insertionPos = null; + foreach (var clause in innerQuery.Clauses) { + query.Clauses.InsertAfter(insertionPos, insertionPos = clause.Detach()); + } + fromClause = innerFromClause; + innerQuery = fromClause.Expression as QueryExpression; + } + } + } + + return artificialParent.Expression.Clone(); + } + + bool IsDegenerateQuery(QueryExpression query) + { + if (query == null) + return false; + var lastClause = query.Clauses.LastOrDefault(); + return !(lastClause is QuerySelectClause || lastClause is QueryGroupClause); + } + + void DecompileQueries(AstNode node) + { + QueryExpression query = DecompileQuery(node as InvocationExpression); + if (query != null) + node.ReplaceWith(query); + } + + Expression ExtractQuery(MemberReferenceExpression mre) + { + var inExpression = mre.Target.Clone(); + var inContent = DecompileQuery(inExpression as InvocationExpression) ?? inExpression; + return inContent; + } + + QueryExpression DecompileQuery(InvocationExpression invocation) + { + if (invocation == null) + return null; + MemberReferenceExpression mre = invocation.Target as MemberReferenceExpression; + if (mre == null) + return null; + + switch (mre.MemberName) { + case "Select": + { + if (invocation.Arguments.Count != 1) + return null; + string parameterName; + Expression body; + if (MatchSimpleLambda(invocation.Arguments.Single(), out parameterName, out body)) { + QueryExpression query = new QueryExpression(); + query.Clauses.Add(new QueryFromClause { Identifier = parameterName, Expression = ExtractQuery(mre) }); + query.Clauses.Add(new QuerySelectClause { Expression = body.Detach() }); + return query; + } + return null; + } + case "Cast": + { + if (invocation.Arguments.Count == 0 && mre.TypeArguments.Count == 1) { + var typeArgument = mre.TypeArguments.First(); + + QueryExpression query = new QueryExpression(); + string varName = GenerateVariableName(); + query.Clauses.Add(new QueryFromClause { + Identifier = varName, + Expression = ExtractQuery(mre), + Type = typeArgument.Detach() + }); + return query; + + } + return null; + } + case "GroupBy": + { + if (invocation.Arguments.Count == 2) { + string parameterName1, parameterName2; + Expression keySelector, elementSelector; + if (MatchSimpleLambda(invocation.Arguments.ElementAt(0), out parameterName1, out keySelector) + && MatchSimpleLambda(invocation.Arguments.ElementAt(1), out parameterName2, out elementSelector) + && parameterName1 == parameterName2) { + QueryExpression query = new QueryExpression(); + query.Clauses.Add(new QueryFromClause { Identifier = parameterName1, Expression = ExtractQuery(mre) }); + query.Clauses.Add(new QueryGroupClause { Projection = elementSelector.Detach(), Key = keySelector.Detach() }); + return query; + } + } else if (invocation.Arguments.Count == 1) { + string parameterName; + Expression keySelector; + if (MatchSimpleLambda(invocation.Arguments.Single(), out parameterName, out keySelector)) { + QueryExpression query = new QueryExpression(); + query.Clauses.Add(new QueryFromClause { Identifier = parameterName, Expression = ExtractQuery(mre) }); + query.Clauses.Add(new QueryGroupClause { + Projection = new IdentifierExpression(parameterName), + Key = keySelector.Detach() + }); + return query; + } + } + return null; + } + case "SelectMany": + { + if (invocation.Arguments.Count != 2) + return null; + string parameterName; + Expression collectionSelector; + if (!MatchSimpleLambda(invocation.Arguments.ElementAt(0), out parameterName, out collectionSelector)) + return null; + LambdaExpression lambda = invocation.Arguments.ElementAt(1) as LambdaExpression; + if (lambda != null && lambda.Parameters.Count == 2 && lambda.Body is Expression) { + ParameterDeclaration p1 = lambda.Parameters.ElementAt(0); + ParameterDeclaration p2 = lambda.Parameters.ElementAt(1); + QueryExpression query = new QueryExpression(); + query.Clauses.Add(new QueryFromClause { Identifier = p1.Name, Expression = ExtractQuery(mre) }); + query.Clauses.Add(new QueryFromClause { Identifier = p2.Name, Expression = collectionSelector.Detach() }); + query.Clauses.Add(new QuerySelectClause { Expression = ((Expression)lambda.Body).Detach() }); + return query; + } + return null; + } + case "Where": + { + if (invocation.Arguments.Count != 1) + return null; + string parameterName; + Expression body; + if (MatchSimpleLambda(invocation.Arguments.Single(), out parameterName, out body)) { + QueryExpression query = new QueryExpression(); + query.Clauses.Add(new QueryFromClause { Identifier = parameterName, Expression = ExtractQuery(mre) }); + query.Clauses.Add(new QueryWhereClause { Condition = body.Detach() }); + return query; + } + return null; + } + case "OrderBy": + case "OrderByDescending": + case "ThenBy": + case "ThenByDescending": + { + if (invocation.Arguments.Count != 1) + return null; + string parameterName; + Expression orderExpression; + if (MatchSimpleLambda(invocation.Arguments.Single(), out parameterName, out orderExpression)) { + if (ValidateThenByChain(invocation, parameterName)) { + QueryOrderClause orderClause = new QueryOrderClause(); + InvocationExpression tmp = invocation; + while (mre.MemberName == "ThenBy" || mre.MemberName == "ThenByDescending") { + // insert new ordering at beginning + orderClause.Orderings.InsertAfter( + null, new QueryOrdering { + Expression = orderExpression.Detach(), + Direction = (mre.MemberName == "ThenBy" ? QueryOrderingDirection.None : QueryOrderingDirection.Descending) + }); + + tmp = (InvocationExpression)mre.Target; + mre = (MemberReferenceExpression)tmp.Target; + MatchSimpleLambda(tmp.Arguments.Single(), out parameterName, out orderExpression); + } + // insert new ordering at beginning + orderClause.Orderings.InsertAfter( + null, new QueryOrdering { + Expression = orderExpression.Detach(), + Direction = (mre.MemberName == "OrderBy" ? QueryOrderingDirection.None : QueryOrderingDirection.Descending) + }); + + QueryExpression query = new QueryExpression(); + query.Clauses.Add(new QueryFromClause { Identifier = parameterName, Expression = ExtractQuery(mre) }); + query.Clauses.Add(orderClause); + return query; + } + } + return null; + } + case "Join": + case "GroupJoin": + { + if (invocation.Arguments.Count != 4) + return null; + Expression source1 = mre.Target; + Expression source2 = invocation.Arguments.ElementAt(0); + string elementName1, elementName2; + Expression key1, key2; + if (!MatchSimpleLambda(invocation.Arguments.ElementAt(1), out elementName1, out key1)) + return null; + if (!MatchSimpleLambda(invocation.Arguments.ElementAt(2), out elementName2, out key2)) + return null; + LambdaExpression lambda = invocation.Arguments.ElementAt(3) as LambdaExpression; + if (lambda != null && lambda.Parameters.Count == 2 && lambda.Body is Expression) { + ParameterDeclaration p1 = lambda.Parameters.ElementAt(0); + ParameterDeclaration p2 = lambda.Parameters.ElementAt(1); + QueryExpression query = new QueryExpression(); + query.Clauses.Add(new QueryFromClause { Identifier = elementName1, Expression = source1.Detach() }); + QueryJoinClause joinClause = new QueryJoinClause(); + + joinClause.JoinIdentifier = elementName2; // join elementName2 + joinClause.InExpression = source2.Detach(); // in source2 + + Match castMatch = castPattern.Match(source2); + if (castMatch.Success) { + Expression target = castMatch.Get("inExpr").Single().Detach(); + joinClause.Type = castMatch.Get("targetType").Single().Detach(); + joinClause.InExpression = target; + } + + joinClause.OnExpression = key1.Detach(); // on key1 + joinClause.EqualsExpression = key2.Detach(); // equals key2 + if (mre.MemberName == "GroupJoin") { + joinClause.IntoIdentifier = p2.Name; // into p2.Name + } + query.Clauses.Add(joinClause); + Expression resultExpr = ((Expression)lambda.Body).Detach(); + if (p1.Name != elementName1) { + foreach (var identifier in resultExpr.Descendants.OfType().Where(id => id.Name == p1.Name)) + { + identifier.Name = elementName1; + } + } + if (p2.Name != elementName2 && mre.MemberName != "GroupJoin") { + foreach (var identifier in resultExpr.Descendants.OfType().Where(id => id.Name == p2.Name)) + { + identifier.Name = elementName2; + } + } + query.Clauses.Add(new QuerySelectClause { Expression = resultExpr }); + return query; + } + return null; + } + default: + return null; + } + } + + int id = 1; + string GenerateVariableName() + { + return "<>" + id++; + } + + /// + /// Ensure that all ThenBy's are correct, and that the list of ThenBy's is terminated by an 'OrderBy' invocation. + /// + bool ValidateThenByChain(InvocationExpression invocation, string expectedParameterName) + { + if (invocation == null || invocation.Arguments.Count != 1) + return false; + MemberReferenceExpression mre = invocation.Target as MemberReferenceExpression; + if (mre == null) + return false; + string parameterName; + Expression body; + if (!MatchSimpleLambda(invocation.Arguments.Single(), out parameterName, out body)) + return false; + if (parameterName != expectedParameterName) + return false; + + if (mre.MemberName == "OrderBy" || mre.MemberName == "OrderByDescending") + return true; + else if (mre.MemberName == "ThenBy" || mre.MemberName == "ThenByDescending") + return ValidateThenByChain(mre.Target as InvocationExpression, expectedParameterName); + else + return false; + } + + /// Matches simple lambdas of the form "a => b" + bool MatchSimpleLambda(Expression expr, out string parameterName, out Expression body) + { + LambdaExpression lambda = expr as LambdaExpression; + if (lambda != null && lambda.Parameters.Count == 1 && lambda.Body is Expression) { + ParameterDeclaration p = lambda.Parameters.Single(); + if (p.ParameterModifier == ParameterModifier.None) { + parameterName = p.Name; + body = (Expression)lambda.Body; + return true; + } + } + parameterName = null; + body = null; + return false; + } + } +} diff --git a/NRefactory/ICSharpCode.NRefactory.CSharp/NameLookupMode.cs b/NRefactory/ICSharpCode.NRefactory.CSharp/NameLookupMode.cs index 07165410e..3196dc583 100644 --- a/NRefactory/ICSharpCode.NRefactory.CSharp/NameLookupMode.cs +++ b/NRefactory/ICSharpCode.NRefactory.CSharp/NameLookupMode.cs @@ -1,4 +1,4 @@ -// Copyright (c) AlphaSierraPapa for the SharpDevelop Team +// Copyright (c) 2010-2013 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 diff --git a/NRefactory/ICSharpCode.NRefactory.CSharp/OutputVisitor/CSharpAmbience.cs b/NRefactory/ICSharpCode.NRefactory.CSharp/OutputVisitor/CSharpAmbience.cs index c370e58e4..f6c153b1a 100644 --- a/NRefactory/ICSharpCode.NRefactory.CSharp/OutputVisitor/CSharpAmbience.cs +++ b/NRefactory/ICSharpCode.NRefactory.CSharp/OutputVisitor/CSharpAmbience.cs @@ -1,4 +1,4 @@ -// Copyright (c) AlphaSierraPapa for the SharpDevelop Team +// Copyright (c) 2010-2013 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 @@ -20,130 +20,148 @@ using System; using System.IO; using ICSharpCode.NRefactory.CSharp.Refactoring; using ICSharpCode.NRefactory.TypeSystem; -using ICSharpCode.NRefactory.TypeSystem.Implementation; namespace ICSharpCode.NRefactory.CSharp { /// - /// C# ambience. + /// C# ambience. Used to convert type system symbols to text (usually for displaying the symbol to the user; e.g. in editor tooltips) /// public class CSharpAmbience : IAmbience { public ConversionFlags ConversionFlags { get; set; } - #region ConvertEntity + #region ConvertSymbol + [Obsolete("Use ConvertSymbol() instead")] public string ConvertEntity(IEntity entity) { - if (entity == null) - throw new ArgumentNullException("entity"); + return ConvertSymbol(entity); + } + + public string ConvertSymbol(ISymbol symbol) + { + if (symbol == null) + throw new ArgumentNullException("symbol"); StringWriter writer = new StringWriter(); - ConvertEntity(entity, new TextWriterOutputFormatter(writer), FormattingOptionsFactory.CreateMono ()); + ConvertSymbol(symbol, new TextWriterTokenWriter(writer), FormattingOptionsFactory.CreateMono ()); return writer.ToString(); } - public void ConvertEntity(IEntity entity, IOutputFormatter formatter, CSharpFormattingOptions formattingPolicy) + [Obsolete("Use ConvertSymbol() instead")] + public void ConvertEntity(IEntity entity, TokenWriter writer, CSharpFormattingOptions formattingPolicy) { - if (entity == null) - throw new ArgumentNullException("entity"); - if (formatter == null) - throw new ArgumentNullException("formatter"); + ConvertSymbol(entity, writer, formattingPolicy); + } + + public void ConvertSymbol(ISymbol symbol, TokenWriter writer, CSharpFormattingOptions formattingPolicy) + { + if (symbol == null) + throw new ArgumentNullException("symbol"); + if (writer == null) + throw new ArgumentNullException("writer"); if (formattingPolicy == null) - throw new ArgumentNullException("options"); + throw new ArgumentNullException("formattingPolicy"); TypeSystemAstBuilder astBuilder = CreateAstBuilder(); - EntityDeclaration node = astBuilder.ConvertEntity(entity); - PrintModifiers(node.Modifiers, formatter); + AstNode node = astBuilder.ConvertSymbol(symbol); + EntityDeclaration entityDecl = node as EntityDeclaration; + if (entityDecl != null) + PrintModifiers(entityDecl.Modifiers, writer); if ((ConversionFlags & ConversionFlags.ShowDefinitionKeyword) == ConversionFlags.ShowDefinitionKeyword) { if (node is TypeDeclaration) { switch (((TypeDeclaration)node).ClassType) { case ClassType.Class: - formatter.WriteKeyword("class"); + writer.WriteKeyword(Roles.ClassKeyword, "class"); break; case ClassType.Struct: - formatter.WriteKeyword("struct"); + writer.WriteKeyword(Roles.StructKeyword, "struct"); break; case ClassType.Interface: - formatter.WriteKeyword("interface"); + writer.WriteKeyword(Roles.InterfaceKeyword, "interface"); break; case ClassType.Enum: - formatter.WriteKeyword("enum"); + writer.WriteKeyword(Roles.EnumKeyword, "enum"); break; default: throw new Exception("Invalid value for ClassType"); } - formatter.Space(); + writer.Space(); } else if (node is DelegateDeclaration) { - formatter.WriteKeyword("delegate"); - formatter.Space(); + writer.WriteKeyword(Roles.DelegateKeyword, "delegate"); + writer.Space(); } else if (node is EventDeclaration) { - formatter.WriteKeyword("event"); - formatter.Space(); + writer.WriteKeyword(EventDeclaration.EventKeywordRole, "event"); + writer.Space(); + } else if (node is NamespaceDeclaration) { + writer.WriteKeyword(Roles.NamespaceKeyword, "namespace"); + writer.Space(); } } if ((ConversionFlags & ConversionFlags.ShowReturnType) == ConversionFlags.ShowReturnType) { var rt = node.GetChildByRole(Roles.Type); if (!rt.IsNull) { - rt.AcceptVisitor(new CSharpOutputVisitor(formatter, formattingPolicy)); - formatter.Space(); + rt.AcceptVisitor(new CSharpOutputVisitor(writer, formattingPolicy)); + writer.Space(); } } - if (entity is ITypeDefinition) - WriteTypeDeclarationName((ITypeDefinition)entity, formatter, formattingPolicy); + if (symbol is ITypeDefinition) + WriteTypeDeclarationName((ITypeDefinition)symbol, writer, formattingPolicy); + else if (symbol is IMember) + WriteMemberDeclarationName((IMember)symbol, writer, formattingPolicy); else - WriteMemberDeclarationName((IMember)entity, formatter, formattingPolicy); + writer.WriteIdentifier(Identifier.Create(symbol.Name)); - if ((ConversionFlags & ConversionFlags.ShowParameterList) == ConversionFlags.ShowParameterList && HasParameters(entity)) { - formatter.WriteToken(entity.EntityType == EntityType.Indexer ? "[" : "("); + if ((ConversionFlags & ConversionFlags.ShowParameterList) == ConversionFlags.ShowParameterList && HasParameters(symbol)) { + writer.WriteToken(symbol.SymbolKind == SymbolKind.Indexer ? Roles.LBracket : Roles.LPar, symbol.SymbolKind == SymbolKind.Indexer ? "[" : "("); bool first = true; foreach (var param in node.GetChildrenByRole(Roles.Parameter)) { if (first) { first = false; } else { - formatter.WriteToken(","); - formatter.Space(); + writer.WriteToken(Roles.Comma, ","); + writer.Space(); } - param.AcceptVisitor(new CSharpOutputVisitor(formatter, formattingPolicy)); + param.AcceptVisitor(new CSharpOutputVisitor(writer, formattingPolicy)); } - formatter.WriteToken(entity.EntityType == EntityType.Indexer ? "]" : ")"); + writer.WriteToken(symbol.SymbolKind == SymbolKind.Indexer ? Roles.RBracket : Roles.RPar, symbol.SymbolKind == SymbolKind.Indexer ? "]" : ")"); } if ((ConversionFlags & ConversionFlags.ShowBody) == ConversionFlags.ShowBody && !(node is TypeDeclaration)) { - IProperty property = entity as IProperty; + IProperty property = symbol as IProperty; if (property != null) { - formatter.Space(); - formatter.WriteToken("{"); - formatter.Space(); + writer.Space(); + writer.WriteToken(Roles.LBrace, "{"); + writer.Space(); if (property.CanGet) { - formatter.WriteKeyword("get"); - formatter.WriteToken(";"); - formatter.Space(); + writer.WriteKeyword(PropertyDeclaration.GetKeywordRole, "get"); + writer.WriteToken(Roles.Semicolon, ";"); + writer.Space(); } if (property.CanSet) { - formatter.WriteKeyword("set"); - formatter.WriteToken(";"); - formatter.Space(); + writer.WriteKeyword(PropertyDeclaration.SetKeywordRole, "set"); + writer.WriteToken(Roles.Semicolon, ";"); + writer.Space(); } - formatter.WriteToken("}"); + writer.WriteToken(Roles.RBrace, "}"); } else { - formatter.WriteToken(";"); + writer.WriteToken(Roles.Semicolon, ";"); } } } - bool HasParameters(IEntity e) + static bool HasParameters(ISymbol e) { - switch (e.EntityType) { - case EntityType.TypeDefinition: + switch (e.SymbolKind) { + case SymbolKind.TypeDefinition: return ((ITypeDefinition)e).Kind == TypeKind.Delegate; - case EntityType.Indexer: - case EntityType.Method: - case EntityType.Operator: - case EntityType.Constructor: - case EntityType.Destructor: + case SymbolKind.Indexer: + case SymbolKind.Method: + case SymbolKind.Operator: + case SymbolKind.Constructor: + case SymbolKind.Destructor: return true; default: return false; @@ -161,94 +179,105 @@ namespace ICSharpCode.NRefactory.CSharp return astBuilder; } - void WriteTypeDeclarationName(ITypeDefinition typeDef, IOutputFormatter formatter, CSharpFormattingOptions formattingPolicy) + void WriteTypeDeclarationName(ITypeDefinition typeDef, TokenWriter writer, CSharpFormattingOptions formattingPolicy) { TypeSystemAstBuilder astBuilder = CreateAstBuilder(); + EntityDeclaration node = astBuilder.ConvertEntity(typeDef); if (typeDef.DeclaringTypeDefinition != null) { - WriteTypeDeclarationName(typeDef.DeclaringTypeDefinition, formatter, formattingPolicy); - formatter.WriteToken("."); - } else if ((ConversionFlags & ConversionFlags.UseFullyQualifiedTypeNames) == ConversionFlags.UseFullyQualifiedTypeNames) { - formatter.WriteIdentifier(typeDef.Namespace); - formatter.WriteToken("."); + WriteTypeDeclarationName(typeDef.DeclaringTypeDefinition, writer, formattingPolicy); + writer.WriteToken(Roles.Dot, "."); + } else if ((ConversionFlags & ConversionFlags.UseFullyQualifiedEntityNames) == ConversionFlags.UseFullyQualifiedEntityNames) { + if (!string.IsNullOrEmpty(typeDef.Namespace)) { + WriteQualifiedName(typeDef.Namespace, writer, formattingPolicy); + writer.WriteToken(Roles.Dot, "."); + } } - formatter.WriteIdentifier(typeDef.Name); + writer.WriteIdentifier(node.NameToken); if ((ConversionFlags & ConversionFlags.ShowTypeParameterList) == ConversionFlags.ShowTypeParameterList) { - var outputVisitor = new CSharpOutputVisitor(formatter, formattingPolicy); - outputVisitor.WriteTypeParameters(astBuilder.ConvertEntity(typeDef).GetChildrenByRole(Roles.TypeParameter)); + var outputVisitor = new CSharpOutputVisitor(writer, formattingPolicy); + outputVisitor.WriteTypeParameters(node.GetChildrenByRole(Roles.TypeParameter)); } } - void WriteMemberDeclarationName(IMember member, IOutputFormatter formatter, CSharpFormattingOptions formattingPolicy) + void WriteMemberDeclarationName(IMember member, TokenWriter writer, CSharpFormattingOptions formattingPolicy) { TypeSystemAstBuilder astBuilder = CreateAstBuilder(); + EntityDeclaration node = astBuilder.ConvertEntity(member); if ((ConversionFlags & ConversionFlags.ShowDeclaringType) == ConversionFlags.ShowDeclaringType) { - ConvertType(member.DeclaringType, formatter, formattingPolicy); - formatter.WriteToken("."); + ConvertType(member.DeclaringType, writer, formattingPolicy); + writer.WriteToken(Roles.Dot, "."); } - switch (member.EntityType) { - case EntityType.Indexer: - formatter.WriteKeyword("this"); + switch (member.SymbolKind) { + case SymbolKind.Indexer: + writer.WriteKeyword(Roles.Identifier, "this"); break; - case EntityType.Constructor: - formatter.WriteIdentifier(member.DeclaringType.Name); + case SymbolKind.Constructor: + WriteQualifiedName(member.DeclaringType.Name, writer, formattingPolicy); break; - case EntityType.Destructor: - formatter.WriteToken("~"); - formatter.WriteIdentifier(member.DeclaringType.Name); + case SymbolKind.Destructor: + writer.WriteToken(DestructorDeclaration.TildeRole, "~"); + WriteQualifiedName(member.DeclaringType.Name, writer, formattingPolicy); break; - case EntityType.Operator: + case SymbolKind.Operator: switch (member.Name) { case "op_Implicit": - formatter.WriteKeyword("implicit"); - formatter.Space(); - formatter.WriteKeyword("operator"); - formatter.Space(); - ConvertType(member.ReturnType, formatter, formattingPolicy); + writer.WriteKeyword(OperatorDeclaration.ImplicitRole, "implicit"); + writer.Space(); + writer.WriteKeyword(OperatorDeclaration.OperatorKeywordRole, "operator"); + writer.Space(); + ConvertType(member.ReturnType, writer, formattingPolicy); break; case "op_Explicit": - formatter.WriteKeyword("explicit"); - formatter.Space(); - formatter.WriteKeyword("operator"); - formatter.Space(); - ConvertType(member.ReturnType, formatter, formattingPolicy); + writer.WriteKeyword(OperatorDeclaration.ExplicitRole, "explicit"); + writer.Space(); + writer.WriteKeyword(OperatorDeclaration.OperatorKeywordRole, "operator"); + writer.Space(); + ConvertType(member.ReturnType, writer, formattingPolicy); break; default: - formatter.WriteKeyword("operator"); - formatter.Space(); + writer.WriteKeyword(OperatorDeclaration.OperatorKeywordRole, "operator"); + writer.Space(); var operatorType = OperatorDeclaration.GetOperatorType(member.Name); if (operatorType.HasValue) - formatter.WriteToken(OperatorDeclaration.GetToken(operatorType.Value)); + writer.WriteToken(OperatorDeclaration.GetRole(operatorType.Value), OperatorDeclaration.GetToken(operatorType.Value)); else - formatter.WriteIdentifier(member.Name); + writer.WriteIdentifier(node.NameToken); break; } break; default: - formatter.WriteIdentifier(member.Name); + writer.WriteIdentifier(Identifier.Create(member.Name)); break; } - if ((ConversionFlags & ConversionFlags.ShowTypeParameterList) == ConversionFlags.ShowTypeParameterList && member.EntityType == EntityType.Method) { - var outputVisitor = new CSharpOutputVisitor(formatter, formattingPolicy); - outputVisitor.WriteTypeParameters(astBuilder.ConvertEntity(member).GetChildrenByRole(Roles.TypeParameter)); + if ((ConversionFlags & ConversionFlags.ShowTypeParameterList) == ConversionFlags.ShowTypeParameterList && member.SymbolKind == SymbolKind.Method) { + var outputVisitor = new CSharpOutputVisitor(writer, formattingPolicy); + outputVisitor.WriteTypeParameters(node.GetChildrenByRole(Roles.TypeParameter)); } } - void PrintModifiers(Modifiers modifiers, IOutputFormatter formatter) + void PrintModifiers(Modifiers modifiers, TokenWriter writer) { foreach (var m in CSharpModifierToken.AllModifiers) { if ((modifiers & m) == m) { - formatter.WriteKeyword(CSharpModifierToken.GetModifierName(m)); - formatter.Space(); + writer.WriteKeyword(EntityDeclaration.ModifierRole, CSharpModifierToken.GetModifierName(m)); + writer.Space(); } } } + + void WriteQualifiedName(string name, TokenWriter writer, CSharpFormattingOptions formattingPolicy) + { + var node = AstType.Create(name); + var outputVisitor = new CSharpOutputVisitor(writer, formattingPolicy); + node.AcceptVisitor(outputVisitor); + } #endregion public string ConvertVariable(IVariable v) { TypeSystemAstBuilder astBuilder = CreateAstBuilder(); AstNode astNode = astBuilder.ConvertVariable(v); - return astNode.GetText().TrimEnd(';', '\r', '\n'); + return astNode.ToString().TrimEnd(';', '\r', '\n', (char)8232); } public string ConvertType(IType type) @@ -257,15 +286,22 @@ namespace ICSharpCode.NRefactory.CSharp throw new ArgumentNullException("type"); TypeSystemAstBuilder astBuilder = CreateAstBuilder(); + astBuilder.AlwaysUseShortTypeNames = (ConversionFlags & ConversionFlags.UseFullyQualifiedEntityNames) != ConversionFlags.UseFullyQualifiedEntityNames; AstType astType = astBuilder.ConvertType(type); - return astType.GetText(); + return astType.ToString(); } - public void ConvertType(IType type, IOutputFormatter formatter, CSharpFormattingOptions formattingPolicy) + public void ConvertType(IType type, TokenWriter writer, CSharpFormattingOptions formattingPolicy) { TypeSystemAstBuilder astBuilder = CreateAstBuilder(); + astBuilder.AlwaysUseShortTypeNames = (ConversionFlags & ConversionFlags.UseFullyQualifiedEntityNames) != ConversionFlags.UseFullyQualifiedEntityNames; AstType astType = astBuilder.ConvertType(type); - astType.AcceptVisitor(new CSharpOutputVisitor(formatter, formattingPolicy)); + astType.AcceptVisitor(new CSharpOutputVisitor(writer, formattingPolicy)); + } + + public string ConvertConstantValue(object constantValue) + { + return TextWriterTokenWriter.PrintPrimitiveValue(constantValue); } public string WrapComment(string comment) diff --git a/NRefactory/ICSharpCode.NRefactory.CSharp/OutputVisitor/CSharpOutputVisitor.cs b/NRefactory/ICSharpCode.NRefactory.CSharp/OutputVisitor/CSharpOutputVisitor.cs index 2fd378017..3b8f12f55 100644 --- a/NRefactory/ICSharpCode.NRefactory.CSharp/OutputVisitor/CSharpOutputVisitor.cs +++ b/NRefactory/ICSharpCode.NRefactory.CSharp/OutputVisitor/CSharpOutputVisitor.cs @@ -1,4 +1,4 @@ -// Copyright (c) AlphaSierraPapa for the SharpDevelop Team +// Copyright (c) 2010-2013 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 @@ -25,6 +25,7 @@ using System.Text; using System.Threading.Tasks; using ICSharpCode.NRefactory.PatternMatching; using ICSharpCode.NRefactory.TypeSystem; +using ICSharpCode.NRefactory.CSharp; namespace ICSharpCode.NRefactory.CSharp { @@ -33,27 +34,9 @@ namespace ICSharpCode.NRefactory.CSharp /// public class CSharpOutputVisitor : IAstVisitor { - readonly IOutputFormatter formatter; + readonly TokenWriter writer; readonly CSharpFormattingOptions policy; readonly Stack containerStack = new Stack (); - readonly Stack positionStack = new Stack (); - - /// - /// Used to insert the minimal amount of spaces so that the lexer recognizes the tokens that were written. - /// - LastWritten lastWritten; - - enum LastWritten - { - Whitespace, - Other, - KeywordOrIdentifier, - Plus, - Minus, - Ampersand, - QuestionMark, - Division - } public CSharpOutputVisitor (TextWriter textWriter, CSharpFormattingOptions formattingPolicy) { @@ -63,19 +46,19 @@ namespace ICSharpCode.NRefactory.CSharp if (formattingPolicy == null) { throw new ArgumentNullException ("formattingPolicy"); } - this.formatter = new TextWriterOutputFormatter (textWriter); + this.writer = TokenWriter.Create(textWriter); this.policy = formattingPolicy; } - public CSharpOutputVisitor (IOutputFormatter formatter, CSharpFormattingOptions formattingPolicy) + public CSharpOutputVisitor (TokenWriter writer, CSharpFormattingOptions formattingPolicy) { - if (formatter == null) { - throw new ArgumentNullException ("formatter"); + if (writer == null) { + throw new ArgumentNullException ("writer"); } if (formattingPolicy == null) { throw new ArgumentNullException ("formattingPolicy"); } - this.formatter = formatter; + this.writer = new InsertSpecialsDecorator(new InsertRequiredSpacesDecorator(writer)); this.policy = formattingPolicy; } @@ -85,84 +68,15 @@ namespace ICSharpCode.NRefactory.CSharp // Ensure that nodes are visited in the proper nested order. // Jumps to different subtrees are allowed only for the child of a placeholder node. Debug.Assert(containerStack.Count == 0 || node.Parent == containerStack.Peek() || containerStack.Peek().NodeType == NodeType.Pattern); - if (positionStack.Count > 0) { - WriteSpecialsUpToNode(node); - } containerStack.Push(node); - positionStack.Push(node.FirstChild); - formatter.StartNode(node); + writer.StartNode(node); } void EndNode(AstNode node) { Debug.Assert(node == containerStack.Peek()); - AstNode pos = positionStack.Pop(); - Debug.Assert(pos == null || pos.Parent == node); - WriteSpecials(pos, null); containerStack.Pop(); - formatter.EndNode(node); - } - #endregion - - #region WriteSpecials - /// - /// Writes all specials from start to end (exclusive). Does not touch the positionStack. - /// - void WriteSpecials(AstNode start, AstNode end) - { - for (AstNode pos = start; pos != end; pos = pos.NextSibling) { - if (pos.Role == Roles.Comment || pos.Role == Roles.NewLine || pos.Role == Roles.PreProcessorDirective) { - pos.AcceptVisitor(this); - } - } - } - - /// - /// Writes all specials between the current position (in the positionStack) and the next - /// node with the specified role. Advances the current position. - /// - void WriteSpecialsUpToRole(Role role) - { - WriteSpecialsUpToRole(role, null); - } - - void WriteSpecialsUpToRole(Role role, AstNode nextNode) - { - if (positionStack.Count == 0) { - return; - } - // Look for the role between the current position and the nextNode. - for (AstNode pos = positionStack.Peek(); pos != null && pos != nextNode; pos = pos.NextSibling) { - if (pos.Role == role) { - WriteSpecials(positionStack.Pop(), pos); - // Push the next sibling because the node matching the role is not a special, - // and should be considered to be already handled. - positionStack.Push(pos.NextSibling); - // This is necessary for OptionalComma() to work correctly. - break; - } - } - } - - /// - /// Writes all specials between the current position (in the positionStack) and the specified node. - /// Advances the current position. - /// - void WriteSpecialsUpToNode(AstNode node) - { - if (positionStack.Count == 0) { - return; - } - for (AstNode pos = positionStack.Peek(); pos != null; pos = pos.NextSibling) { - if (pos == node) { - WriteSpecials(positionStack.Pop(), pos); - // Push the next sibling because the node itself is not a special, - // and should be considered to be already handled. - positionStack.Push(pos.NextSibling); - // This is necessary for OptionalComma() to work correctly. - break; - } - } + writer.EndNode(node); } #endregion @@ -174,11 +88,9 @@ namespace ICSharpCode.NRefactory.CSharp /// When set prevents printing a space after comma. void Comma(AstNode nextNode, bool noSpaceAfterComma = false) { - WriteSpecialsUpToRole(Roles.Comma, nextNode); Space(policy.SpaceBeforeBracketComma); // TODO: Comma policy has changed. - formatter.WriteToken(","); - lastWritten = LastWritten.Other; + writer.WriteToken(Roles.Comma, ","); Space(!noSpaceAfterComma && policy.SpaceAfterBracketComma); // TODO: Comma policy has changed. } @@ -186,10 +98,9 @@ namespace ICSharpCode.NRefactory.CSharp /// /// Writes an optional comma, e.g. at the end of an enum declaration or in an array initializer /// - void OptionalComma() + void OptionalComma(AstNode pos) { // Look if there's a comma after the current node, and insert it if it exists. - AstNode pos = positionStack.Peek(); while (pos != null && pos.NodeType == NodeType.Whitespace) { pos = pos.NextSibling; } @@ -201,12 +112,11 @@ namespace ICSharpCode.NRefactory.CSharp /// /// Writes an optional semicolon, e.g. at the end of a type or namespace declaration. /// - void OptionalSemicolon() + void OptionalSemicolon(AstNode pos) { // Look if there's a semicolon after the current node, and insert it if it exists. - AstNode pos = positionStack.Peek(); while (pos != null && pos.NodeType == NodeType.Whitespace) { - pos = pos.NextSibling; + pos = pos.PrevSibling; } if (pos != null && pos.Role == Roles.Semicolon) { Semicolon(); @@ -284,6 +194,8 @@ namespace ICSharpCode.NRefactory.CSharp #endregion #region Write tokens + bool isAtStartOfLine = true; + /// /// Writes a keyword, and all specials up to /// @@ -294,77 +206,31 @@ namespace ICSharpCode.NRefactory.CSharp void WriteKeyword(string token, Role tokenRole = null) { - if (tokenRole != null) { - WriteSpecialsUpToRole(tokenRole); - } - if (lastWritten == LastWritten.KeywordOrIdentifier) { - formatter.Space(); - } - formatter.WriteKeyword(token); - lastWritten = LastWritten.KeywordOrIdentifier; + writer.WriteKeyword(tokenRole, token); + isAtStartOfLine = false; } -/* void WriteKeyword (string keyword, Role tokenRole) + void WriteIdentifier(Identifier identifier) { - WriteSpecialsUpToRole (tokenRole); - if (lastWritten == LastWritten.KeywordOrIdentifier) - formatter.Space (); - formatter.WriteKeyword (keyword); - lastWritten = LastWritten.KeywordOrIdentifier; - }*/ + writer.WriteIdentifier(identifier); + isAtStartOfLine = false; + } - void WriteIdentifier(string identifier, Role identifierRole = null) + void WriteIdentifier(string identifier) { - WriteSpecialsUpToRole(identifierRole ?? Roles.Identifier); - if (IsKeyword(identifier, containerStack.Peek())) { - if (lastWritten == LastWritten.KeywordOrIdentifier) { - Space(); - } - // this space is not strictly required, so we call Space() - formatter.WriteToken("@"); - } else if (lastWritten == LastWritten.KeywordOrIdentifier) { - formatter.Space(); - // this space is strictly required, so we directly call the formatter - } - formatter.WriteIdentifier(identifier); - lastWritten = LastWritten.KeywordOrIdentifier; + AstType.Create(identifier).AcceptVisitor(this); + isAtStartOfLine = false; } void WriteToken(TokenRole tokenRole) { WriteToken(tokenRole.Token, tokenRole); } - + void WriteToken(string token, Role tokenRole) { - WriteSpecialsUpToRole(tokenRole); - // Avoid that two +, - or ? tokens are combined into a ++, -- or ?? token. - // Note that we don't need to handle tokens like = because there's no valid - // C# program that contains the single token twice in a row. - // (for +, - and &, this can happen with unary operators; - // for ?, this can happen in "a is int? ? b : c" or "a as int? ?? 0"; - // and for /, this can happen with "1/ *ptr" or "1/ //comment".) - if (lastWritten == LastWritten.Plus && token [0] == '+' - || lastWritten == LastWritten.Minus && token [0] == '-' - || lastWritten == LastWritten.Ampersand && token [0] == '&' - || lastWritten == LastWritten.QuestionMark && token [0] == '?' - || lastWritten == LastWritten.Division && token [0] == '*') { - formatter.Space(); - } - formatter.WriteToken(token); - if (token == "+") { - lastWritten = LastWritten.Plus; - } else if (token == "-") { - lastWritten = LastWritten.Minus; - } else if (token == "&") { - lastWritten = LastWritten.Ampersand; - } else if (token == "?") { - lastWritten = LastWritten.QuestionMark; - } else if (token == "/") { - lastWritten = LastWritten.Division; - } else { - lastWritten = LastWritten.Other; - } + writer.WriteToken(tokenRole, token); + isAtStartOfLine = false; } void LPar() @@ -396,29 +262,78 @@ namespace ICSharpCode.NRefactory.CSharp void Space(bool addSpace = true) { if (addSpace) { - formatter.Space(); - lastWritten = LastWritten.Whitespace; + writer.Space(); } } void NewLine() { - formatter.NewLine(); - lastWritten = LastWritten.Whitespace; + writer.NewLine(); + isAtStartOfLine = true; } void OpenBrace(BraceStyle style) { - WriteSpecialsUpToRole(Roles.LBrace); - formatter.OpenBrace(style); - lastWritten = LastWritten.Other; + switch (style) { + case BraceStyle.DoNotChange: + case BraceStyle.EndOfLine: + case BraceStyle.BannerStyle: + if (!isAtStartOfLine) + writer.Space(); + writer.WriteToken(Roles.LBrace, "{"); + break; + case BraceStyle.EndOfLineWithoutSpace: + writer.WriteToken(Roles.LBrace, "{"); + break; + case BraceStyle.NextLine: + if (!isAtStartOfLine) + NewLine(); + writer.WriteToken(Roles.LBrace, "{"); + break; + case BraceStyle.NextLineShifted: + NewLine(); + writer.Indent(); + writer.WriteToken(Roles.LBrace, "{"); + NewLine(); + return; + case BraceStyle.NextLineShifted2: + NewLine(); + writer.Indent(); + writer.WriteToken(Roles.LBrace, "{"); + break; + default: + throw new ArgumentOutOfRangeException (); + } + writer.Indent(); + NewLine(); } void CloseBrace(BraceStyle style) { - WriteSpecialsUpToRole(Roles.RBrace); - formatter.CloseBrace(style); - lastWritten = LastWritten.Other; + switch (style) { + case BraceStyle.DoNotChange: + case BraceStyle.EndOfLine: + case BraceStyle.EndOfLineWithoutSpace: + case BraceStyle.NextLine: + writer.Unindent(); + writer.WriteToken(Roles.RBrace, "}"); + isAtStartOfLine = false; + break; + case BraceStyle.BannerStyle: + case BraceStyle.NextLineShifted: + writer.WriteToken(Roles.RBrace, "}"); + isAtStartOfLine = false; + writer.Unindent(); + break; + case BraceStyle.NextLineShifted2: + writer.Unindent(); + writer.WriteToken(Roles.RBrace, "}"); + isAtStartOfLine = false; + writer.Unindent(); + break; + default: + throw new ArgumentOutOfRangeException(); + } } #endregion @@ -502,17 +417,10 @@ namespace ICSharpCode.NRefactory.CSharp foreach (Identifier ident in identifiers) { if (first) { first = false; - if (lastWritten == LastWritten.KeywordOrIdentifier) { - formatter.Space(); - } } else { - WriteSpecialsUpToRole(Roles.Dot, ident); - formatter.WriteToken("."); - lastWritten = LastWritten.Other; + writer.WriteToken(Roles.Dot, "."); } - WriteSpecialsUpToNode(ident); - formatter.WriteIdentifier(ident.Name); - lastWritten = LastWritten.KeywordOrIdentifier; + writer.WriteIdentifier(ident); } } @@ -527,9 +435,9 @@ namespace ICSharpCode.NRefactory.CSharp VisitBlockStatement(block); } else { NewLine(); - formatter.Indent(); + writer.Indent(); embeddedStatement.AcceptVisitor(this); - formatter.Unindent(); + writer.Unindent(); } } @@ -625,8 +533,8 @@ namespace ICSharpCode.NRefactory.CSharp // The output visitor will output nested braces only if they are necessary, // or if the braces tokens exist in the AST. bool bracesAreOptional = arrayInitializerExpression.Elements.Count == 1 - && IsObjectOrCollectionInitializer(arrayInitializerExpression.Parent) - && !CanBeConfusedWithObjectInitializer(arrayInitializerExpression.Elements.Single()); + && IsObjectOrCollectionInitializer(arrayInitializerExpression.Parent) + && !CanBeConfusedWithObjectInitializer(arrayInitializerExpression.Elements.Single()); if (bracesAreOptional && arrayInitializerExpression.LBraceToken.IsNull) { arrayInitializerExpression.Elements.Single().AcceptVisitor(this); } else { @@ -667,6 +575,7 @@ namespace ICSharpCode.NRefactory.CSharp } OpenBrace(style); bool isFirst = true; + AstNode last = null; foreach (AstNode node in elements) { if (isFirst) { isFirst = false; @@ -674,9 +583,11 @@ namespace ICSharpCode.NRefactory.CSharp Comma(node, noSpaceAfterComma: true); NewLine(); } + last = node; node.AcceptVisitor(this); } - OptionalComma(); + if (last != null) + OptionalComma(last.NextSibling); NewLine(); CloseBrace(style); } @@ -843,7 +754,7 @@ namespace ICSharpCode.NRefactory.CSharp public void VisitIdentifierExpression(IdentifierExpression identifierExpression) { StartNode(identifierExpression); - WriteIdentifier(identifierExpression.Identifier); + WriteIdentifier(identifierExpression.IdentifierToken); WriteTypeArguments(identifierExpression.TypeArguments); EndNode(identifierExpression); } @@ -909,7 +820,7 @@ namespace ICSharpCode.NRefactory.CSharp StartNode(memberReferenceExpression); memberReferenceExpression.Target.AcceptVisitor(this); WriteToken(Roles.Dot); - WriteIdentifier(memberReferenceExpression.MemberName); + WriteIdentifier(memberReferenceExpression.MemberNameToken); WriteTypeArguments(memberReferenceExpression.TypeArguments); EndNode(memberReferenceExpression); } @@ -917,7 +828,7 @@ namespace ICSharpCode.NRefactory.CSharp public void VisitNamedArgumentExpression(NamedArgumentExpression namedArgumentExpression) { StartNode(namedArgumentExpression); - namedArgumentExpression.NameToken.AcceptVisitor(this); + WriteIdentifier(namedArgumentExpression.NameToken); WriteToken(Roles.Colon); Space(); namedArgumentExpression.Expression.AcceptVisitor(this); @@ -927,7 +838,7 @@ namespace ICSharpCode.NRefactory.CSharp public void VisitNamedExpression(NamedExpression namedExpression) { StartNode(namedExpression); - namedExpression.NameToken.AcceptVisitor(this); + WriteIdentifier(namedExpression.NameToken); Space(); WriteToken(Roles.Assign); Space(); @@ -938,7 +849,7 @@ namespace ICSharpCode.NRefactory.CSharp public void VisitNullReferenceExpression(NullReferenceExpression nullReferenceExpression) { StartNode(nullReferenceExpression); - WriteKeyword("null", nullReferenceExpression.Role); + writer.WritePrimitiveValue(null); EndNode(nullReferenceExpression); } @@ -984,199 +895,18 @@ namespace ICSharpCode.NRefactory.CSharp StartNode(pointerReferenceExpression); pointerReferenceExpression.Target.AcceptVisitor(this); WriteToken(PointerReferenceExpression.ArrowRole); - WriteIdentifier(pointerReferenceExpression.MemberName); + WriteIdentifier(pointerReferenceExpression.MemberNameToken); WriteTypeArguments(pointerReferenceExpression.TypeArguments); EndNode(pointerReferenceExpression); } - public void VisitEmptyExpression(EmptyExpression emptyExpression) - { - StartNode(emptyExpression); - EndNode(emptyExpression); - } - #region VisitPrimitiveExpression public void VisitPrimitiveExpression(PrimitiveExpression primitiveExpression) { StartNode(primitiveExpression); - if (!string.IsNullOrEmpty(primitiveExpression.LiteralValue)) { - formatter.WriteToken(primitiveExpression.LiteralValue); - } else { - WritePrimitiveValue(primitiveExpression.Value); - } + writer.WritePrimitiveValue(primitiveExpression.Value, primitiveExpression.UnsafeLiteralValue); 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) { - // usually NullReferenceExpression should be used for this, but we'll handle it anyways - WriteKeyword("null"); - return; - } - - if (val is bool) { - if ((bool)val) { - WriteKeyword("true"); - } else { - WriteKeyword("false"); - } - return; - } - - if (val is string) { - formatter.WriteToken("\"" + ConvertString(val.ToString()) + "\""); - lastWritten = LastWritten.Other; - } else if (val is char) { - formatter.WriteToken("'" + ConvertCharLiteral((char)val) + "'"); - lastWritten = LastWritten.Other; - } else if (val is decimal) { - formatter.WriteToken(((decimal)val).ToString(NumberFormatInfo.InvariantInfo) + "m"); - lastWritten = LastWritten.Other; - } else if (val is float) { - float f = (float)val; - if (float.IsInfinity(f) || float.IsNaN(f)) { - // Strictly speaking, these aren't PrimitiveExpressions; - // but we still support writing these to make life easier for code generators. - WriteKeyword("float"); - WriteToken(Roles.Dot); - if (float.IsPositiveInfinity(f)) { - WriteIdentifier("PositiveInfinity"); - } else if (float.IsNegativeInfinity(f)) { - WriteIdentifier("NegativeInfinity"); - } else { - WriteIdentifier("NaN"); - } - return; - } - if (f == 0 && 1 / f == double.NegativeInfinity) { - // negative zero is a special case - // (again, not a primitive expression, but it's better to handle - // the special case here than to do it in all code generators) - formatter.WriteToken("-"); - } - formatter.WriteToken(f.ToString("R", NumberFormatInfo.InvariantInfo) + "f"); - lastWritten = LastWritten.Other; - } else if (val is double) { - double f = (double)val; - if (double.IsInfinity(f) || double.IsNaN(f)) { - // Strictly speaking, these aren't PrimitiveExpressions; - // but we still support writing these to make life easier for code generators. - WriteKeyword("double"); - WriteToken(Roles.Dot); - if (double.IsPositiveInfinity(f)) { - WriteIdentifier("PositiveInfinity"); - } else if (double.IsNegativeInfinity(f)) { - WriteIdentifier("NegativeInfinity"); - } else { - WriteIdentifier("NaN"); - } - return; - } - if (f == 0 && 1 / f == double.NegativeInfinity) { - // negative zero is a special case - // (again, not a primitive expression, but it's better to handle - // the special case here than to do it in all code generators) - formatter.WriteToken("-"); - } - string number = f.ToString("R", NumberFormatInfo.InvariantInfo); - if (number.IndexOf('.') < 0 && number.IndexOf('E') < 0) { - number += ".0"; - } - formatter.WriteToken(number); - // needs space if identifier follows number; this avoids mistaking the following identifier as type suffix - lastWritten = LastWritten.KeywordOrIdentifier; - } else if (val is IFormattable) { - StringBuilder b = new StringBuilder (); - // if (primitiveExpression.LiteralFormat == LiteralFormat.HexadecimalNumber) { - // b.Append("0x"); - // b.Append(((IFormattable)val).ToString("x", NumberFormatInfo.InvariantInfo)); - // } else { - b.Append(((IFormattable)val).ToString(null, NumberFormatInfo.InvariantInfo)); - // } - if (val is uint || val is ulong) { - b.Append("u"); - } - if (val is long || val is ulong) { - b.Append("L"); - } - formatter.WriteToken(b.ToString()); - // needs space if identifier follows number; this avoids mistaking the following identifier as type suffix - lastWritten = LastWritten.KeywordOrIdentifier; - } else { - formatter.WriteToken(val.ToString()); - lastWritten = LastWritten.Other; - } - } - - static string ConvertCharLiteral(char ch) - { - if (ch == '\'') { - return "\\'"; - } - return ConvertChar(ch); - } - - /// - /// Gets the escape sequence for the specified character. - /// - /// This method does not convert ' or ". - public static string ConvertChar(char ch) - { - switch (ch) { - case '\\': - return "\\\\"; - case '\0': - return "\\0"; - case '\a': - return "\\a"; - case '\b': - return "\\b"; - case '\f': - return "\\f"; - case '\n': - return "\\n"; - case '\r': - return "\\r"; - case '\t': - return "\\t"; - case '\v': - return "\\v"; - default: - if (char.IsControl(ch) || char.IsSurrogate(ch) || - // print all uncommon white spaces as numbers - (char.IsWhiteSpace(ch) && ch != ' ')) { - return "\\u" + ((int)ch).ToString("x4"); - } else { - return ch.ToString(); - } - } - } - - /// - /// Converts special characters to escape sequences within the given string. - /// - public static string ConvertString(string str) - { - StringBuilder sb = new StringBuilder (); - foreach (char ch in str) { - if (ch == '"') { - sb.Append("\\\""); - } else { - sb.Append(ConvertChar(ch)); - } - } - return sb.ToString(); - } - #endregion public void VisitSizeOfExpression(SizeOfExpression sizeOfExpression) @@ -1265,9 +995,9 @@ namespace ICSharpCode.NRefactory.CSharp public void VisitQueryExpression(QueryExpression queryExpression) { StartNode(queryExpression); - bool indent = !(queryExpression.Parent is QueryContinuationClause); + bool indent = queryExpression.Parent is QueryClause && !(queryExpression.Parent is QueryContinuationClause); if (indent) { - formatter.Indent(); + writer.Indent(); NewLine(); } bool first = true; @@ -1282,7 +1012,7 @@ namespace ICSharpCode.NRefactory.CSharp clause.AcceptVisitor(this); } if (indent) { - formatter.Unindent(); + writer.Unindent(); } EndNode(queryExpression); } @@ -1294,7 +1024,7 @@ namespace ICSharpCode.NRefactory.CSharp Space(); WriteKeyword(QueryContinuationClause.IntoKeywordRole); Space(); - queryContinuationClause.IdentifierToken.AcceptVisitor(this); + WriteIdentifier(queryContinuationClause.IdentifierToken); EndNode(queryContinuationClause); } @@ -1304,7 +1034,7 @@ namespace ICSharpCode.NRefactory.CSharp WriteKeyword(QueryFromClause.FromKeywordRole); queryFromClause.Type.AcceptVisitor(this); Space(); - queryFromClause.IdentifierToken.AcceptVisitor(this); + WriteIdentifier(queryFromClause.IdentifierToken); Space(); WriteKeyword(QueryFromClause.InKeywordRole); Space(); @@ -1317,7 +1047,7 @@ namespace ICSharpCode.NRefactory.CSharp StartNode(queryLetClause); WriteKeyword(QueryLetClause.LetKeywordRole); Space(); - queryLetClause.IdentifierToken.AcceptVisitor(this); + WriteIdentifier(queryLetClause.IdentifierToken); Space(policy.SpaceAroundAssignment); WriteToken(Roles.Assign); Space(policy.SpaceAroundAssignment); @@ -1340,7 +1070,7 @@ namespace ICSharpCode.NRefactory.CSharp WriteKeyword(QueryJoinClause.JoinKeywordRole); queryJoinClause.Type.AcceptVisitor(this); Space(); - WriteIdentifier(queryJoinClause.JoinIdentifier, QueryJoinClause.JoinIdentifierRole); + WriteIdentifier(queryJoinClause.JoinIdentifierToken); Space(); WriteKeyword(QueryJoinClause.InKeywordRole); Space(); @@ -1356,7 +1086,7 @@ namespace ICSharpCode.NRefactory.CSharp if (queryJoinClause.IsGroupJoin) { Space(); WriteKeyword(QueryJoinClause.IntoKeywordRole); - WriteIdentifier(queryJoinClause.IntoIdentifier, QueryJoinClause.IntoIdentifierRole); + WriteIdentifier(queryJoinClause.IntoIdentifierToken); } EndNode(queryJoinClause); } @@ -1428,7 +1158,7 @@ namespace ICSharpCode.NRefactory.CSharp StartNode(attributeSection); WriteToken(Roles.LBracket); if (!string.IsNullOrEmpty(attributeSection.AttributeTarget)) { - WriteToken(attributeSection.AttributeTarget, Roles.AttributeTargetRole); + WriteIdentifier(attributeSection.AttributeTargetToken); WriteToken(Roles.Colon); Space(); } @@ -1450,7 +1180,7 @@ namespace ICSharpCode.NRefactory.CSharp WriteKeyword(Roles.DelegateKeyword); delegateDeclaration.ReturnType.AcceptVisitor(this); Space(); - delegateDeclaration.NameToken.AcceptVisitor(this); + WriteIdentifier(delegateDeclaration.NameToken); WriteTypeParameters(delegateDeclaration.TypeParameters); Space(policy.SpaceBeforeDelegateDeclarationParentheses); WriteCommaSeparatedListInParenthesis(delegateDeclaration.Parameters, policy.SpaceWithinMethodDeclarationParentheses); @@ -1465,13 +1195,14 @@ namespace ICSharpCode.NRefactory.CSharp { StartNode(namespaceDeclaration); WriteKeyword(Roles.NamespaceKeyword); - WriteQualifiedIdentifier(namespaceDeclaration.Identifiers); + namespaceDeclaration.NamespaceName.AcceptVisitor (this); OpenBrace(policy.NamespaceBraceStyle); foreach (var member in namespaceDeclaration.Members) { member.AcceptVisitor(this); + MaybeNewLinesAfterUsings(member); } CloseBrace(policy.NamespaceBraceStyle); - OptionalSemicolon(); + OptionalSemicolon(namespaceDeclaration.LastChild); NewLine(); EndNode(namespaceDeclaration); } @@ -1500,7 +1231,7 @@ namespace ICSharpCode.NRefactory.CSharp braceStyle = policy.ClassBraceStyle; break; } - typeDeclaration.NameToken.AcceptVisitor(this); + WriteIdentifier(typeDeclaration.NameToken); WriteTypeParameters(typeDeclaration.TypeParameters); if (typeDeclaration.BaseTypes.Any()) { Space(); @@ -1514,6 +1245,7 @@ namespace ICSharpCode.NRefactory.CSharp OpenBrace(braceStyle); if (typeDeclaration.ClassType == ClassType.Enum) { bool first = true; + AstNode last = null; foreach (var member in typeDeclaration.Members) { if (first) { first = false; @@ -1521,17 +1253,25 @@ namespace ICSharpCode.NRefactory.CSharp Comma(member, noSpaceAfterComma: true); NewLine(); } + last = member; member.AcceptVisitor(this); } - OptionalComma(); + if (last != null) + OptionalComma(last.NextSibling); NewLine(); } else { + bool first = true; foreach (var member in typeDeclaration.Members) { + if (!first) { + for (int i = 0; i < policy.MinimumBlankLinesBetweenMembers; i++) + NewLine(); + } + first = false; member.AcceptVisitor(this); } } CloseBrace(braceStyle); - OptionalSemicolon(); + OptionalSemicolon(typeDeclaration.LastChild); NewLine(); EndNode(typeDeclaration); } @@ -1540,7 +1280,7 @@ namespace ICSharpCode.NRefactory.CSharp { StartNode(usingAliasDeclaration); WriteKeyword(UsingAliasDeclaration.UsingKeywordRole); - WriteIdentifier(usingAliasDeclaration.Alias, UsingAliasDeclaration.AliasRole); + WriteIdentifier(usingAliasDeclaration.GetChildByRole(UsingAliasDeclaration.AliasRole)); Space(policy.SpaceAroundEqualityOperator); WriteToken(Roles.Assign); Space(policy.SpaceAroundEqualityOperator); @@ -1565,7 +1305,7 @@ namespace ICSharpCode.NRefactory.CSharp Space(); WriteKeyword(Roles.AliasKeyword); Space(); - externAliasDeclaration.NameToken.AcceptVisitor(this); + WriteIdentifier(externAliasDeclaration.NameToken); Semicolon(); EndNode(externAliasDeclaration); } @@ -1604,16 +1344,16 @@ namespace ICSharpCode.NRefactory.CSharp foreach (var node in blockStatement.Statements) { node.AcceptVisitor(this); } + EndNode(blockStatement); CloseBrace(style); if (!(blockStatement.Parent is Expression)) NewLine(); - EndNode(blockStatement); } public void VisitBreakStatement(BreakStatement breakStatement) { StartNode(breakStatement); - WriteKeyword("break"); + WriteKeyword("break", BreakStatement.BreakKeywordRole); Semicolon(); EndNode(breakStatement); } @@ -1629,7 +1369,7 @@ namespace ICSharpCode.NRefactory.CSharp public void VisitContinueStatement(ContinueStatement continueStatement) { StartNode(continueStatement); - WriteKeyword("continue"); + WriteKeyword("continue", ContinueStatement.ContinueKeywordRole); Semicolon(); EndNode(continueStatement); } @@ -1690,7 +1430,7 @@ namespace ICSharpCode.NRefactory.CSharp Space(policy.SpacesWithinForeachParentheses); foreachStatement.VariableType.AcceptVisitor(this); Space(); - foreachStatement.VariableNameToken.AcceptVisitor(this); + WriteIdentifier(foreachStatement.VariableNameToken); WriteKeyword(ForeachStatement.InKeywordRole); Space(); foreachStatement.InExpression.AcceptVisitor(this); @@ -1751,7 +1491,7 @@ namespace ICSharpCode.NRefactory.CSharp { StartNode(gotoStatement); WriteKeyword(GotoStatement.GotoKeywordRole); - WriteIdentifier(gotoStatement.Label); + WriteIdentifier(gotoStatement.GetChildByRole(Roles.Identifier)); Semicolon(); EndNode(gotoStatement); } @@ -1777,7 +1517,7 @@ namespace ICSharpCode.NRefactory.CSharp public void VisitLabelStatement(LabelStatement labelStatement) { StartNode(labelStatement); - WriteIdentifier(labelStatement.Label); + WriteIdentifier(labelStatement.GetChildByRole(Roles.Identifier)); WriteToken(Roles.Colon); bool foundLabelledStatement = false; for (AstNode tmp = labelStatement.NextSibling; tmp != null; tmp = tmp.NextSibling) { @@ -1831,7 +1571,7 @@ namespace ICSharpCode.NRefactory.CSharp RPar(); OpenBrace(policy.StatementBraceStyle); if (!policy.IndentSwitchBody) { - formatter.Unindent(); + writer.Unindent(); } foreach (var section in switchStatement.SwitchSections) { @@ -1839,7 +1579,7 @@ namespace ICSharpCode.NRefactory.CSharp } if (!policy.IndentSwitchBody) { - formatter.Indent(); + writer.Indent(); } CloseBrace(policy.StatementBraceStyle); NewLine(); @@ -1859,7 +1599,7 @@ namespace ICSharpCode.NRefactory.CSharp } bool isBlock = switchSection.Statements.Count == 1 && switchSection.Statements.Single() is BlockStatement; if (policy.IndentCaseBody && !isBlock) { - formatter.Indent(); + writer.Indent(); } if (!isBlock) @@ -1870,7 +1610,7 @@ namespace ICSharpCode.NRefactory.CSharp } if (policy.IndentCaseBody && !isBlock) { - formatter.Unindent(); + writer.Unindent(); } EndNode(switchSection); @@ -1928,7 +1668,7 @@ namespace ICSharpCode.NRefactory.CSharp catchClause.Type.AcceptVisitor(this); if (!string.IsNullOrEmpty(catchClause.VariableName)) { Space(); - catchClause.VariableNameToken.AcceptVisitor(this); + WriteIdentifier(catchClause.VariableNameToken); } Space(policy.SpacesWithinCatchParentheses); RPar(); @@ -2025,13 +1765,13 @@ namespace ICSharpCode.NRefactory.CSharp WriteAttributes(accessor.Attributes); WriteModifiers(accessor.ModifierTokens); if (accessor.Role == PropertyDeclaration.GetterRole) { - WriteKeyword("get"); + WriteKeyword("get", PropertyDeclaration.GetKeywordRole); } else if (accessor.Role == PropertyDeclaration.SetterRole) { - WriteKeyword("set"); + WriteKeyword("set", PropertyDeclaration.SetKeywordRole); } else if (accessor.Role == CustomEventDeclaration.AddAccessorRole) { - WriteKeyword("add"); + WriteKeyword("add", CustomEventDeclaration.AddKeywordRole); } else if (accessor.Role == CustomEventDeclaration.RemoveAccessorRole) { - WriteKeyword("remove"); + WriteKeyword("remove", CustomEventDeclaration.RemoveKeywordRole); } WriteMethodBody(accessor.Body); EndNode(accessor); @@ -2043,9 +1783,10 @@ namespace ICSharpCode.NRefactory.CSharp WriteAttributes(constructorDeclaration.Attributes); WriteModifiers(constructorDeclaration.ModifierTokens); TypeDeclaration type = constructorDeclaration.Parent as TypeDeclaration; - StartNode(constructorDeclaration.NameToken); - WriteIdentifier(type != null ? type.Name : constructorDeclaration.Name); - EndNode(constructorDeclaration.NameToken); + if (type != null && type.Name != constructorDeclaration.Name) + WriteIdentifier((Identifier)type.NameToken.Clone()); + else + WriteIdentifier(constructorDeclaration.NameToken); Space(policy.SpaceBeforeConstructorDeclarationParentheses); WriteCommaSeparatedListInParenthesis(constructorDeclaration.Parameters, policy.SpaceWithinMethodDeclarationParentheses); if (!constructorDeclaration.Initializer.IsNull) { @@ -2078,9 +1819,10 @@ namespace ICSharpCode.NRefactory.CSharp WriteModifiers(destructorDeclaration.ModifierTokens); WriteToken(DestructorDeclaration.TildeRole); TypeDeclaration type = destructorDeclaration.Parent as TypeDeclaration; - StartNode(destructorDeclaration.NameToken); - WriteIdentifier(type != null ? type.Name : destructorDeclaration.Name); - EndNode(destructorDeclaration.NameToken); + if (type != null && type.Name != destructorDeclaration.Name) + WriteIdentifier((Identifier)type.NameToken.Clone()); + else + WriteIdentifier(destructorDeclaration.NameToken); Space(policy.SpaceBeforeConstructorDeclarationParentheses); LPar(); RPar(); @@ -2093,7 +1835,7 @@ namespace ICSharpCode.NRefactory.CSharp StartNode(enumMemberDeclaration); WriteAttributes(enumMemberDeclaration.Attributes); WriteModifiers(enumMemberDeclaration.ModifierTokens); - enumMemberDeclaration.NameToken.AcceptVisitor(this); + WriteIdentifier(enumMemberDeclaration.NameToken); if (!enumMemberDeclaration.Initializer.IsNull) { Space(policy.SpaceAroundAssignment); WriteToken(Roles.Assign); @@ -2125,7 +1867,7 @@ namespace ICSharpCode.NRefactory.CSharp customEventDeclaration.ReturnType.AcceptVisitor(this); Space(); WritePrivateImplementationType(customEventDeclaration.PrivateImplementationType); - customEventDeclaration.NameToken.AcceptVisitor(this); + WriteIdentifier(customEventDeclaration.NameToken); OpenBrace(policy.EventBraceStyle); // output add/remove in their original order foreach (AstNode node in customEventDeclaration.Children) { @@ -2167,7 +1909,7 @@ namespace ICSharpCode.NRefactory.CSharp public void VisitFixedVariableInitializer(FixedVariableInitializer fixedVariableInitializer) { StartNode(fixedVariableInitializer); - fixedVariableInitializer.NameToken.AcceptVisitor(this); + WriteIdentifier(fixedVariableInitializer.NameToken); if (!fixedVariableInitializer.CountExpression.IsNull) { WriteToken(Roles.LBracket); Space(policy.SpacesWithinBrackets); @@ -2209,7 +1951,7 @@ namespace ICSharpCode.NRefactory.CSharp methodDeclaration.ReturnType.AcceptVisitor(this); Space(); WritePrivateImplementationType(methodDeclaration.PrivateImplementationType); - methodDeclaration.NameToken.AcceptVisitor(this); + WriteIdentifier(methodDeclaration.NameToken); WriteTypeParameters(methodDeclaration.TypeParameters); Space(policy.SpaceBeforeMethodDeclarationParentheses); WriteCommaSeparatedListInParenthesis(methodDeclaration.Parameters, policy.SpaceWithinMethodDeclarationParentheses); @@ -2235,7 +1977,7 @@ namespace ICSharpCode.NRefactory.CSharp WriteKeyword(OperatorDeclaration.OperatorKeywordRole); Space(); if (operatorDeclaration.OperatorType == OperatorType.Explicit - || operatorDeclaration.OperatorType == OperatorType.Implicit) { + || operatorDeclaration.OperatorType == OperatorType.Implicit) { operatorDeclaration.ReturnType.AcceptVisitor(this); } else { WriteToken(OperatorDeclaration.GetToken(operatorDeclaration.OperatorType), OperatorDeclaration.GetRole(operatorDeclaration.OperatorType)); @@ -2269,7 +2011,7 @@ namespace ICSharpCode.NRefactory.CSharp Space(); } if (!string.IsNullOrEmpty(parameterDeclaration.Name)) { - parameterDeclaration.NameToken.AcceptVisitor(this); + WriteIdentifier(parameterDeclaration.NameToken); } if (!parameterDeclaration.DefaultExpression.IsNull) { Space(policy.SpaceAroundAssignment); @@ -2288,7 +2030,7 @@ namespace ICSharpCode.NRefactory.CSharp propertyDeclaration.ReturnType.AcceptVisitor(this); Space(); WritePrivateImplementationType(propertyDeclaration.PrivateImplementationType); - propertyDeclaration.NameToken.AcceptVisitor(this); + WriteIdentifier(propertyDeclaration.NameToken); OpenBrace(policy.PropertyBraceStyle); // output get/set in their original order foreach (AstNode node in propertyDeclaration.Children) { @@ -2307,7 +2049,7 @@ namespace ICSharpCode.NRefactory.CSharp public void VisitVariableInitializer(VariableInitializer variableInitializer) { StartNode(variableInitializer); - variableInitializer.NameToken.AcceptVisitor(this); + WriteIdentifier(variableInitializer.NameToken); if (!variableInitializer.Initializer.IsNull) { Space(policy.SpaceAroundAssignment); WriteToken(Roles.Assign); @@ -2316,19 +2058,32 @@ namespace ICSharpCode.NRefactory.CSharp } EndNode(variableInitializer); } + + void MaybeNewLinesAfterUsings(AstNode node) + { + var nextSibling = node.NextSibling; + while (nextSibling is WhitespaceNode || nextSibling is NewLineNode) + nextSibling = nextSibling.NextSibling; + + if ((node is UsingDeclaration || node is UsingAliasDeclaration) && !(nextSibling is UsingDeclaration || nextSibling is UsingAliasDeclaration)) { + for (int i = 0; i < policy.MinimumBlankLinesAfterUsings; i++) + NewLine(); + } + } public void VisitSyntaxTree(SyntaxTree syntaxTree) { // don't do node tracking as we visit all children directly foreach (AstNode node in syntaxTree.Children) { node.AcceptVisitor(this); + MaybeNewLinesAfterUsings(node); } } public void VisitSimpleType(SimpleType simpleType) { StartNode(simpleType); - WriteIdentifier(simpleType.Identifier); + WriteIdentifier(simpleType.IdentifierToken); WriteTypeArguments(simpleType.TypeArguments); EndNode(simpleType); } @@ -2342,7 +2097,7 @@ namespace ICSharpCode.NRefactory.CSharp } else { WriteToken(Roles.Dot); } - WriteIdentifier(memberType.MemberName); + WriteIdentifier(memberType.MemberNameToken); WriteTypeArguments(memberType.TypeArguments); EndNode(memberType); } @@ -2368,9 +2123,7 @@ namespace ICSharpCode.NRefactory.CSharp StartNode(arraySpecifier); WriteToken(Roles.LBracket); foreach (var comma in arraySpecifier.GetChildrenByRole(Roles.Comma)) { - WriteSpecialsUpToNode(comma); - formatter.WriteToken(","); - lastWritten = LastWritten.Other; + writer.WriteToken(Roles.Comma, ","); } WriteToken(Roles.RBracket); EndNode(arraySpecifier); @@ -2379,33 +2132,22 @@ namespace ICSharpCode.NRefactory.CSharp public void VisitPrimitiveType(PrimitiveType primitiveType) { StartNode(primitiveType); - WriteKeyword(primitiveType.Keyword); - if (primitiveType.Keyword == "new") { - // new() constraint - LPar(); - RPar(); - } + writer.WritePrimitiveType(primitiveType.Keyword); EndNode(primitiveType); } public void VisitComment(Comment comment) { - if (lastWritten == LastWritten.Division) { - // When there's a comment starting after a division operator - // "1.0 / /*comment*/a", then we need to insert a space in front of the comment. - formatter.Space(); - } - formatter.StartNode(comment); - formatter.WriteComment(comment.CommentType, comment.Content); - formatter.EndNode(comment); - lastWritten = LastWritten.Whitespace; + writer.StartNode(comment); + writer.WriteComment(comment.CommentType, comment.Content); + writer.EndNode(comment); } public void VisitNewLine(NewLineNode newLineNode) { - formatter.StartNode(newLineNode); - formatter.NewLine(); - formatter.EndNode(newLineNode); +// formatter.StartNode(newLineNode); +// formatter.NewLine(); +// formatter.EndNode(newLineNode); } public void VisitWhitespace(WhitespaceNode whitespaceNode) @@ -2420,10 +2162,9 @@ namespace ICSharpCode.NRefactory.CSharp public void VisitPreProcessorDirective(PreProcessorDirective preProcessorDirective) { - formatter.StartNode(preProcessorDirective); - formatter.WritePreProcessorDirective(preProcessorDirective.Type, preProcessorDirective.Argument); - formatter.EndNode(preProcessorDirective); - lastWritten = LastWritten.Whitespace; + writer.StartNode(preProcessorDirective); + writer.WritePreProcessorDirective(preProcessorDirective.Type, preProcessorDirective.Argument); + writer.EndNode(preProcessorDirective); } public void VisitTypeParameterDeclaration(TypeParameterDeclaration typeParameterDeclaration) @@ -2442,7 +2183,7 @@ namespace ICSharpCode.NRefactory.CSharp default: throw new NotSupportedException ("Invalid value for VarianceModifier"); } - typeParameterDeclaration.NameToken.AcceptVisitor(this); + WriteIdentifier(typeParameterDeclaration.NameToken); EndNode(typeParameterDeclaration); } @@ -2451,7 +2192,7 @@ namespace ICSharpCode.NRefactory.CSharp StartNode(constraint); Space(); WriteKeyword(Roles.WhereKeyword); - WriteIdentifier(constraint.TypeParameter.Identifier); + constraint.TypeParameter.AcceptVisitor(this); Space(); WriteToken(Roles.Colon); Space(); @@ -2463,9 +2204,9 @@ namespace ICSharpCode.NRefactory.CSharp { CSharpModifierToken mod = cSharpTokenNode as CSharpModifierToken; if (mod != null) { - StartNode(mod); - WriteKeyword(CSharpModifierToken.GetModifierName(mod.Modifier)); - EndNode(mod); + // ITokenWriter assumes that each node processed between a + // StartNode(parentNode)-EndNode(parentNode)-pair is a child of parentNode. + WriteKeyword(CSharpModifierToken.GetModifierName(mod.Modifier), cSharpTokenNode.Role); } else { throw new NotSupportedException ("Should never visit individual tokens"); } @@ -2473,11 +2214,15 @@ namespace ICSharpCode.NRefactory.CSharp public void VisitIdentifier(Identifier identifier) { - StartNode(identifier); - WriteIdentifier(identifier.Name); - EndNode(identifier); + // Do not call StartNode and EndNode for Identifier, because they are handled by the ITokenWriter. + // ITokenWriter assumes that each node processed between a + // StartNode(parentNode)-EndNode(parentNode)-pair is a child of parentNode. + WriteIdentifier(identifier); } + void IAstVisitor.VisitNullNode(AstNode nullNode) + { + } #endregion #region Pattern Nodes @@ -2518,7 +2263,7 @@ namespace ICSharpCode.NRefactory.CSharp Space(); LPar(); NewLine(); - formatter.Indent(); + writer.Indent(); foreach (INode alternative in choice) { VisitNodeInPattern(alternative); if (alternative != choice.Last()) { @@ -2526,7 +2271,7 @@ namespace ICSharpCode.NRefactory.CSharp } NewLine(); } - formatter.Unindent(); + writer.Unindent(); RPar(); } @@ -2580,7 +2325,7 @@ namespace ICSharpCode.NRefactory.CSharp } else if (childNode is Repeat) { VisitRepeat((Repeat)childNode); } else { - WritePrimitiveValue(childNode); + TextWriterTokenWriter.PrintPrimitiveValue(childNode); } } #endregion @@ -2591,18 +2336,18 @@ namespace ICSharpCode.NRefactory.CSharp StartNode(documentationReference); if (!documentationReference.DeclaringType.IsNull) { documentationReference.DeclaringType.AcceptVisitor(this); - if (documentationReference.EntityType != EntityType.TypeDefinition) { + if (documentationReference.SymbolKind != SymbolKind.TypeDefinition) { WriteToken(Roles.Dot); } } - switch (documentationReference.EntityType) { - case EntityType.TypeDefinition: + switch (documentationReference.SymbolKind) { + case SymbolKind.TypeDefinition: // we already printed the DeclaringType break; - case EntityType.Indexer: + case SymbolKind.Indexer: WriteKeyword(IndexerDeclaration.ThisKeywordRole); break; - case EntityType.Operator: + case SymbolKind.Operator: var opType = documentationReference.OperatorType; if (opType == OperatorType.Explicit) { WriteKeyword(OperatorDeclaration.ExplicitRole); @@ -2618,13 +2363,13 @@ namespace ICSharpCode.NRefactory.CSharp } break; default: - WriteIdentifier(documentationReference.MemberName); + WriteIdentifier(documentationReference.GetChildByRole(Roles.Identifier)); break; } WriteTypeArguments(documentationReference.TypeArguments); if (documentationReference.HasParameterList) { Space(policy.SpaceBeforeMethodDeclarationParentheses); - if (documentationReference.EntityType == EntityType.Indexer) { + if (documentationReference.SymbolKind == SymbolKind.Indexer) { WriteCommaSeparatedListInBrackets(documentationReference.Parameters, policy.SpaceWithinMethodDeclarationParentheses); } else { WriteCommaSeparatedListInParenthesis(documentationReference.Parameters, policy.SpaceWithinMethodDeclarationParentheses); @@ -2633,5 +2378,13 @@ namespace ICSharpCode.NRefactory.CSharp EndNode(documentationReference); } #endregion + + /// + /// Converts special characters to escape sequences within the given string. + /// + public static string ConvertString(string text) + { + return TextWriterTokenWriter.ConvertString(text); + } } } diff --git a/NRefactory/ICSharpCode.NRefactory.CSharp/OutputVisitor/CodeDomConvertVisitor.cs b/NRefactory/ICSharpCode.NRefactory.CSharp/OutputVisitor/CodeDomConvertVisitor.cs index b7db64702..fe55f90fa 100644 --- a/NRefactory/ICSharpCode.NRefactory.CSharp/OutputVisitor/CodeDomConvertVisitor.cs +++ b/NRefactory/ICSharpCode.NRefactory.CSharp/OutputVisitor/CodeDomConvertVisitor.cs @@ -1,4 +1,4 @@ -// Copyright (c) AlphaSierraPapa for the SharpDevelop Team +// Copyright (c) 2010-2013 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 @@ -38,18 +38,19 @@ namespace ICSharpCode.NRefactory.CSharp /// public class CodeDomConvertVisitor : IAstVisitor { - //ICompilation compilation = MinimalResolveContext.Instance; CSharpAstResolver resolver; /// - /// Gets/Sets whether the visitor should use fully-qualified type references. + /// Gets/Sets whether the visitor should convert short type names into + /// fully qualified type names. + /// The default is false. /// public bool UseFullyQualifiedTypeNames { get; set; } /// /// 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, + /// The default is true. If this property is set to false, /// unconvertible code will throw a NotSupportedException. /// public bool AllowSnippetNodes { get; set; } @@ -143,7 +144,7 @@ namespace ICSharpCode.NRefactory.CSharp return result.ToArray(); } - CodeTypeReference Convert(IType type) + public CodeTypeReference Convert(IType type) { if (type.Kind == TypeKind.Array) { ArrayType a = (ArrayType)type; @@ -212,6 +213,11 @@ namespace ICSharpCode.NRefactory.CSharp { return new CodeSnippetStatement(MakeSnippet(stmt)); } + + CodeObject IAstVisitor.VisitNullNode(AstNode nullNode) + { + return null; + } CodeObject IAstVisitor.VisitAnonymousMethodExpression(AnonymousMethodExpression anonymousMethodExpression) { @@ -464,8 +470,11 @@ namespace ICSharpCode.NRefactory.CSharp CodeExpression target = Convert(memberReferenceExpression.Target); ResolveResult rr = Resolve(memberReferenceExpression); MemberResolveResult mrr = rr as MemberResolveResult; + TypeResolveResult trr = rr as TypeResolveResult; if (mrr != null) { return HandleMemberReference(target, memberReferenceExpression.MemberName, memberReferenceExpression.TypeArguments, mrr); + } else if (trr != null) { + return new CodeTypeReferenceExpression(Convert(trr.Type)); } else { if (memberReferenceExpression.TypeArguments.Any() || rr is MethodGroupResolveResult) { return new CodeMethodReferenceExpression(target, memberReferenceExpression.MemberName, Convert(memberReferenceExpression.TypeArguments)); @@ -587,11 +596,6 @@ namespace ICSharpCode.NRefactory.CSharp return MakeSnippetExpression(uncheckedExpression); } - CodeObject IAstVisitor.VisitEmptyExpression(EmptyExpression emptyExpression) - { - return null; - } - CodeObject IAstVisitor.VisitQueryExpression(QueryExpression queryExpression) { return MakeSnippetExpression(queryExpression); @@ -681,7 +685,7 @@ namespace ICSharpCode.NRefactory.CSharp CodeObject IAstVisitor.VisitDelegateDeclaration(DelegateDeclaration delegateDeclaration) { CodeTypeDelegate d = new CodeTypeDelegate(delegateDeclaration.Name); - d.Attributes = ConvertMemberAttributes(delegateDeclaration.Modifiers, EntityType.TypeDefinition); + d.Attributes = ConvertMemberAttributes(delegateDeclaration.Modifiers, SymbolKind.TypeDefinition); d.CustomAttributes.AddRange(Convert(delegateDeclaration.Attributes)); d.ReturnType = Convert(delegateDeclaration.ReturnType); d.Parameters.AddRange(Convert(delegateDeclaration.Parameters)); @@ -689,14 +693,14 @@ namespace ICSharpCode.NRefactory.CSharp return d; } - MemberAttributes ConvertMemberAttributes(Modifiers modifiers, EntityType entityType) + MemberAttributes ConvertMemberAttributes(Modifiers modifiers, SymbolKind symbolKind) { 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) + if (symbolKind != SymbolKind.TypeDefinition && (modifiers & (Modifiers.Abstract | Modifiers.Override | Modifiers.Virtual)) == 0) a |= MemberAttributes.Final; if ((modifiers & Modifiers.Static) != 0) a |= MemberAttributes.Static; @@ -744,7 +748,7 @@ namespace ICSharpCode.NRefactory.CSharp { //bool isNestedType = typeStack.Count > 0; CodeTypeDeclaration typeDecl = new CodeTypeDeclaration(typeDeclaration.Name); - typeDecl.Attributes = ConvertMemberAttributes(typeDeclaration.Modifiers, EntityType.TypeDefinition); + typeDecl.Attributes = ConvertMemberAttributes(typeDeclaration.Modifiers, SymbolKind.TypeDefinition); typeDecl.CustomAttributes.AddRange(Convert(typeDeclaration.Attributes)); switch (typeDeclaration.ClassType) { @@ -888,6 +892,14 @@ namespace ICSharpCode.NRefactory.CSharp return new CodeAssignStatement(Convert(unary.Expression), cboe); } } + if (assignment != null && assignment.Operator == AssignmentOperatorType.Add) { + var rr = Resolve(assignment.Left); + if (!rr.IsError && rr.Type.Kind == TypeKind.Delegate) { + var expr = (MemberReferenceExpression)assignment.Left; + var memberRef = (CodeEventReferenceExpression)HandleMemberReference(Convert(expr.Target), expr.MemberName, expr.TypeArguments, (MemberResolveResult)rr); + return new CodeAttachEventStatement(memberRef, Convert(assignment.Right)); + } + } return new CodeExpressionStatement(Convert(expressionStatement.Expression)); } @@ -1052,7 +1064,7 @@ namespace ICSharpCode.NRefactory.CSharp CodeObject IAstVisitor.VisitConstructorDeclaration(ConstructorDeclaration constructorDeclaration) { CodeConstructor ctor = new CodeConstructor(); - ctor.Attributes = ConvertMemberAttributes(constructorDeclaration.Modifiers, EntityType.Constructor); + ctor.Attributes = ConvertMemberAttributes(constructorDeclaration.Modifiers, SymbolKind.Constructor); ctor.CustomAttributes.AddRange(Convert(constructorDeclaration.Attributes)); if (constructorDeclaration.Initializer.ConstructorInitializerType == ConstructorInitializerType.This) { ctor.ChainedConstructorArgs.AddRange(Convert(constructorDeclaration.Initializer.Arguments)); @@ -1094,7 +1106,7 @@ namespace ICSharpCode.NRefactory.CSharp } CodeMemberEvent e = new CodeMemberEvent(); - e.Attributes = ConvertMemberAttributes(eventDeclaration.Modifiers, EntityType.Event); + e.Attributes = ConvertMemberAttributes(eventDeclaration.Modifiers, SymbolKind.Event); e.CustomAttributes.AddRange(Convert(eventDeclaration.Attributes)); e.Name = vi.Name; e.Type = Convert(eventDeclaration.ReturnType); @@ -1112,7 +1124,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, EntityType.Field); + f.Attributes = ConvertMemberAttributes(fieldDeclaration.Modifiers, SymbolKind.Field); f.CustomAttributes.AddRange(Convert(fieldDeclaration.Attributes)); f.InitExpression = ConvertVariableInitializer(vi.Initializer, fieldDeclaration.ReturnType); AddTypeMember(f); @@ -1123,7 +1135,7 @@ namespace ICSharpCode.NRefactory.CSharp CodeObject IAstVisitor.VisitIndexerDeclaration(IndexerDeclaration indexerDeclaration) { CodeMemberProperty p = new CodeMemberProperty(); - p.Attributes = ConvertMemberAttributes(indexerDeclaration.Modifiers, EntityType.Indexer); + p.Attributes = ConvertMemberAttributes(indexerDeclaration.Modifiers, SymbolKind.Indexer); p.CustomAttributes.AddRange(Convert(indexerDeclaration.Attributes)); p.Name = "Items"; p.PrivateImplementationType = Convert(indexerDeclaration.PrivateImplementationType); @@ -1144,7 +1156,7 @@ namespace ICSharpCode.NRefactory.CSharp CodeObject IAstVisitor.VisitMethodDeclaration(MethodDeclaration methodDeclaration) { CodeMemberMethod m = new CodeMemberMethod(); - m.Attributes = ConvertMemberAttributes(methodDeclaration.Modifiers, EntityType.Method); + m.Attributes = ConvertMemberAttributes(methodDeclaration.Modifiers, SymbolKind.Method); m.CustomAttributes.AddRange(Convert(methodDeclaration.Attributes.Where(a => a.AttributeTarget != "return"))); m.ReturnTypeCustomAttributes.AddRange(Convert(methodDeclaration.Attributes.Where(a => a.AttributeTarget == "return"))); @@ -1162,7 +1174,7 @@ namespace ICSharpCode.NRefactory.CSharp CodeObject IAstVisitor.VisitOperatorDeclaration(OperatorDeclaration operatorDeclaration) { CodeMemberMethod m = new CodeMemberMethod(); - m.Attributes = ConvertMemberAttributes(operatorDeclaration.Modifiers, EntityType.Method); + m.Attributes = ConvertMemberAttributes(operatorDeclaration.Modifiers, SymbolKind.Method); m.CustomAttributes.AddRange(Convert(operatorDeclaration.Attributes.Where(a => a.AttributeTarget != "return"))); m.ReturnTypeCustomAttributes.AddRange(Convert(operatorDeclaration.Attributes.Where(a => a.AttributeTarget == "return"))); @@ -1204,7 +1216,7 @@ namespace ICSharpCode.NRefactory.CSharp CodeObject IAstVisitor.VisitPropertyDeclaration(PropertyDeclaration propertyDeclaration) { CodeMemberProperty p = new CodeMemberProperty(); - p.Attributes = ConvertMemberAttributes(propertyDeclaration.Modifiers, EntityType.Property); + p.Attributes = ConvertMemberAttributes(propertyDeclaration.Modifiers, SymbolKind.Property); p.CustomAttributes.AddRange(Convert(propertyDeclaration.Attributes)); p.Name = propertyDeclaration.Name; p.PrivateImplementationType = Convert(propertyDeclaration.PrivateImplementationType); @@ -1239,6 +1251,7 @@ namespace ICSharpCode.NRefactory.CSharp CodeObject IAstVisitor.VisitSyntaxTree(SyntaxTree syntaxTree) { CodeCompileUnit cu = new CodeCompileUnit(); + var globalImports = new List (); foreach (AstNode node in syntaxTree.Children) { CodeObject o = node.AcceptVisitor(this); @@ -1250,6 +1263,20 @@ namespace ICSharpCode.NRefactory.CSharp if (td != null) { cu.Namespaces.Add(new CodeNamespace() { Types = { td } }); } + + var import = o as CodeNamespaceImport; + if (import != null) + globalImports.Add (import); + } + foreach (var gi in globalImports) { + for (int j = 0; j < cu.Namespaces.Count; j++) { + var cn = cu.Namespaces [j]; + bool found = cn.Imports + .Cast () + .Any (ns => ns.Namespace == gi.Namespace); + if (!found) + cn.Imports.Add (gi); + } } return cu; } @@ -1322,12 +1349,12 @@ namespace ICSharpCode.NRefactory.CSharp CodeObject IAstVisitor.VisitNewLine(NewLineNode newLineNode) { - throw new NotSupportedException(); + return null; } CodeObject IAstVisitor.VisitWhitespace(WhitespaceNode whitespaceNode) { - throw new NotSupportedException(); + return null; } CodeObject IAstVisitor.VisitText(TextNode textNode) @@ -1337,7 +1364,7 @@ namespace ICSharpCode.NRefactory.CSharp CodeObject IAstVisitor.VisitPreProcessorDirective (PreProcessorDirective preProcessorDirective) { - return new CodeComment ("#" + preProcessorDirective.Type.ToString ().ToLower ()); + return new CodeComment ("#" + preProcessorDirective.Type.ToString ().ToLowerInvariant ()); } CodeObject IAstVisitor.VisitTypeParameterDeclaration(TypeParameterDeclaration typeParameterDeclaration) diff --git a/NRefactory/ICSharpCode.NRefactory.CSharp/OutputVisitor/IOutputFormatter.cs b/NRefactory/ICSharpCode.NRefactory.CSharp/OutputVisitor/IOutputFormatter.cs deleted file mode 100644 index 66a3ca810..000000000 --- a/NRefactory/ICSharpCode.NRefactory.CSharp/OutputVisitor/IOutputFormatter.cs +++ /dev/null @@ -1,60 +0,0 @@ -// Copyright (c) AlphaSierraPapa for the SharpDevelop Team -// -// Permission is hereby granted, free of charge, to any person obtaining a copy of this -// software and associated documentation files (the "Software"), to deal in the Software -// without restriction, including without limitation the rights to use, copy, modify, merge, -// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons -// to whom the Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all copies or -// substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, -// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE -// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. - -using System; - -namespace ICSharpCode.NRefactory.CSharp -{ - /// - /// Output formatter for the Output visitor. - /// - public interface IOutputFormatter - { - void StartNode(AstNode node); - void EndNode(AstNode node); - - /// - /// Writes an identifier. - /// If the identifier conflicts with a keyword, the output visitor will - /// call WriteToken("@") before calling WriteIdentifier(). - /// - void WriteIdentifier(string identifier); - - /// - /// Writes a keyword to the output. - /// - void WriteKeyword(string keyword); - - /// - /// Writes a token to the output. - /// - void WriteToken(string token); - void Space(); - - void OpenBrace(BraceStyle style); - void CloseBrace(BraceStyle style); - - void Indent(); - void Unindent(); - - void NewLine(); - - void WriteComment(CommentType commentType, string content); - void WritePreProcessorDirective(PreProcessorDirectiveType type, string argument); - } -} diff --git a/NRefactory/ICSharpCode.NRefactory.CSharp/OutputVisitor/ITokenWriter.cs b/NRefactory/ICSharpCode.NRefactory.CSharp/OutputVisitor/ITokenWriter.cs new file mode 100644 index 000000000..31b73f987 --- /dev/null +++ b/NRefactory/ICSharpCode.NRefactory.CSharp/OutputVisitor/ITokenWriter.cs @@ -0,0 +1,161 @@ +// Copyright (c) 2010-2013 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.IO; + +namespace ICSharpCode.NRefactory.CSharp +{ + public abstract class TokenWriter + { + public abstract void StartNode(AstNode node); + public abstract void EndNode(AstNode node); + + /// + /// Writes an identifier. + /// + public abstract void WriteIdentifier(Identifier identifier); + + /// + /// Writes a keyword to the output. + /// + public abstract void WriteKeyword(Role role, string keyword); + + /// + /// Writes a token to the output. + /// + public abstract void WriteToken(Role role, string token); + + /// + /// Writes a primitive/literal value + /// + public abstract void WritePrimitiveValue(object value, string literalValue = null); + + public abstract void WritePrimitiveType(string type); + + public abstract void Space(); + public abstract void Indent(); + public abstract void Unindent(); + public abstract void NewLine(); + + public abstract void WriteComment(CommentType commentType, string content); + public abstract void WritePreProcessorDirective(PreProcessorDirectiveType type, string argument); + + public static TokenWriter Create(TextWriter writer, string indentation = "\t") + { + return new InsertSpecialsDecorator(new InsertRequiredSpacesDecorator(new TextWriterTokenWriter(writer) { IndentationString = indentation })); + } + + public static TokenWriter CreateWriterThatSetsLocationsInAST(TextWriter writer, string indentation = "\t") + { + var target = new TextWriterTokenWriter(writer) { IndentationString = indentation }; + return new InsertSpecialsDecorator(new InsertRequiredSpacesDecorator(new InsertMissingTokensDecorator(target, target))); + } + + public static TokenWriter WrapInWriterThatSetsLocationsInAST(TokenWriter writer) + { + if (!(writer is ILocatable)) + throw new InvalidOperationException("writer does not provide locations!"); + return new InsertSpecialsDecorator(new InsertRequiredSpacesDecorator(new InsertMissingTokensDecorator(writer, (ILocatable)writer))); + } + } + + public interface ILocatable + { + TextLocation Location { get; } + } + + public abstract class DecoratingTokenWriter : TokenWriter + { + TokenWriter decoratedWriter; + + protected DecoratingTokenWriter(TokenWriter decoratedWriter) + { + if (decoratedWriter == null) + throw new ArgumentNullException("decoratedWriter"); + this.decoratedWriter = decoratedWriter; + } + + public override void StartNode(AstNode node) + { + decoratedWriter.StartNode(node); + } + + public override void EndNode(AstNode node) + { + decoratedWriter.EndNode(node); + } + + public override void WriteIdentifier(Identifier identifier) + { + decoratedWriter.WriteIdentifier(identifier); + } + + public override void WriteKeyword(Role role, string keyword) + { + decoratedWriter.WriteKeyword(role, keyword); + } + + public override void WriteToken(Role role, string token) + { + decoratedWriter.WriteToken(role, token); + } + + public override void WritePrimitiveValue(object value, string literalValue = null) + { + decoratedWriter.WritePrimitiveValue(value, literalValue); + } + + public override void WritePrimitiveType(string type) + { + decoratedWriter.WritePrimitiveType(type); + } + + public override void Space() + { + decoratedWriter.Space(); + } + + public override void Indent() + { + decoratedWriter.Indent(); + } + + public override void Unindent() + { + decoratedWriter.Unindent(); + } + + public override void NewLine() + { + decoratedWriter.NewLine(); + } + + public override void WriteComment(CommentType commentType, string content) + { + decoratedWriter.WriteComment(commentType, content); + } + + public override void WritePreProcessorDirective(PreProcessorDirectiveType type, string argument) + { + decoratedWriter.WritePreProcessorDirective(type, argument); + } + } +} + + diff --git a/NRefactory/ICSharpCode.NRefactory.CSharp/OutputVisitor/InsertMissingTokensDecorator.cs b/NRefactory/ICSharpCode.NRefactory.CSharp/OutputVisitor/InsertMissingTokensDecorator.cs new file mode 100644 index 000000000..3f9200145 --- /dev/null +++ b/NRefactory/ICSharpCode.NRefactory.CSharp/OutputVisitor/InsertMissingTokensDecorator.cs @@ -0,0 +1,123 @@ +// Copyright (c) 2010-2013 AlphaSierraPapa for the SharpDevelop Team +// +// Permission is hereby granted, free of charge, to any person obtaining a copy of this +// software and associated documentation files (the "Software"), to deal in the Software +// without restriction, including without limitation the rights to use, copy, modify, merge, +// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons +// to whom the Software is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all copies or +// substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, +// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE +// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS IN THE SOFTWARE. + +using System; +using System.Collections.Generic; +using System.Linq; + +namespace ICSharpCode.NRefactory.CSharp +{ + class InsertMissingTokensDecorator : DecoratingTokenWriter + { + readonly Stack> nodes = new Stack>(); + List currentList; + readonly ILocatable locationProvider; + + public InsertMissingTokensDecorator(TokenWriter writer, ILocatable locationProvider) + : base(writer) + { + this.locationProvider = locationProvider; + currentList = new List(); + } + + public override void StartNode(AstNode node) + { + currentList.Add(node); + nodes.Push(currentList); + currentList = new List(); + base.StartNode(node); + } + + public override void EndNode(AstNode node) + { + System.Diagnostics.Debug.Assert(currentList != null); + foreach (var removable in node.Children.Where(n => n is CSharpTokenNode)) { + removable.Remove(); + } + foreach (var child in currentList) { + System.Diagnostics.Debug.Assert(child.Parent == null || node == child.Parent); + child.Remove(); + node.AddChildWithExistingRole(child); + } + currentList = nodes.Pop(); + base.EndNode(node); + } + + public override void WriteToken(Role role, string token) + { + CSharpTokenNode t = new CSharpTokenNode(locationProvider.Location, (TokenRole)role); + t.Role = role; + EmptyStatement node = nodes.Peek().LastOrDefault() as EmptyStatement; + if (node == null) + currentList.Add(t); + else { + node.Location = locationProvider.Location; + } + base.WriteToken(role, token); + } + + public override void WriteKeyword(Role role, string keyword) + { + TextLocation start = locationProvider.Location; + CSharpTokenNode t = null; + if (role is TokenRole) + t = new CSharpTokenNode(start, (TokenRole)role); + else if (role == EntityDeclaration.ModifierRole) + t = new CSharpModifierToken(start, CSharpModifierToken.GetModifierValue(keyword)); + else if (keyword == "this") { + ThisReferenceExpression node = nodes.Peek().LastOrDefault() as ThisReferenceExpression; + if (node != null) + node.Location = start; + } else if (keyword == "base") { + BaseReferenceExpression node = nodes.Peek().LastOrDefault() as BaseReferenceExpression; + if (node != null) + node.Location = start; + } + if (t != null) currentList.Add(t); + base.WriteKeyword(role, keyword); + } + + public override void WriteIdentifier(Identifier identifier) + { + if (!identifier.IsNull) + identifier.SetStartLocation(locationProvider.Location); + currentList.Add(identifier); + base.WriteIdentifier(identifier); + } + + public override void WritePrimitiveValue(object value, string literalValue = null) + { + Expression node = nodes.Peek().LastOrDefault() as Expression; + if (node is PrimitiveExpression) { + ((PrimitiveExpression)node).SetStartLocation(locationProvider.Location); + } + if (node is NullReferenceExpression) { + ((NullReferenceExpression)node).SetStartLocation(locationProvider.Location); + } + base.WritePrimitiveValue(value, literalValue); + } + + public override void WritePrimitiveType(string type) + { + PrimitiveType node = nodes.Peek().LastOrDefault() as PrimitiveType; + if (node != null) + node.SetStartLocation(locationProvider.Location); + base.WritePrimitiveType(type); + } + } +} diff --git a/NRefactory/ICSharpCode.NRefactory.CSharp/OutputVisitor/InsertParenthesesVisitor.cs b/NRefactory/ICSharpCode.NRefactory.CSharp/OutputVisitor/InsertParenthesesVisitor.cs index 0b7e2424c..6d622de23 100644 --- a/NRefactory/ICSharpCode.NRefactory.CSharp/OutputVisitor/InsertParenthesesVisitor.cs +++ b/NRefactory/ICSharpCode.NRefactory.CSharp/OutputVisitor/InsertParenthesesVisitor.cs @@ -1,4 +1,4 @@ -// Copyright (c) AlphaSierraPapa for the SharpDevelop Team +// Copyright (c) 2010-2013 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 @@ -235,7 +235,7 @@ namespace ICSharpCode.NRefactory.CSharp ParenthesizeIfRequired(binaryOperatorExpression.Left, Primary); ParenthesizeIfRequired(binaryOperatorExpression.Right, Primary); } else { - // ?? is right-associate + // ?? is right-associative ParenthesizeIfRequired(binaryOperatorExpression.Left, precedence + 1); ParenthesizeIfRequired(binaryOperatorExpression.Right, precedence); } diff --git a/NRefactory/ICSharpCode.NRefactory.CSharp/OutputVisitor/InsertRequiredSpacesDecorator.cs b/NRefactory/ICSharpCode.NRefactory.CSharp/OutputVisitor/InsertRequiredSpacesDecorator.cs new file mode 100644 index 000000000..e9aca4bf5 --- /dev/null +++ b/NRefactory/ICSharpCode.NRefactory.CSharp/OutputVisitor/InsertRequiredSpacesDecorator.cs @@ -0,0 +1,184 @@ +// Copyright (c) 2010-2013 AlphaSierraPapa for the SharpDevelop Team +// +// Permission is hereby granted, free of charge, to any person obtaining a copy of this +// software and associated documentation files (the "Software"), to deal in the Software +// without restriction, including without limitation the rights to use, copy, modify, merge, +// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons +// to whom the Software is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all copies or +// substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, +// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE +// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS IN THE SOFTWARE. + +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Globalization; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using ICSharpCode.NRefactory.PatternMatching; +using ICSharpCode.NRefactory.TypeSystem; +using ICSharpCode.NRefactory.CSharp; + +namespace ICSharpCode.NRefactory.CSharp +{ + class InsertRequiredSpacesDecorator : DecoratingTokenWriter + { + /// + /// Used to insert the minimal amount of spaces so that the lexer recognizes the tokens that were written. + /// + LastWritten lastWritten; + + enum LastWritten + { + Whitespace, + Other, + KeywordOrIdentifier, + Plus, + Minus, + Ampersand, + QuestionMark, + Division + } + + public InsertRequiredSpacesDecorator(TokenWriter writer) + : base(writer) + { + } + + public override void WriteIdentifier(Identifier identifier) + { + if (identifier.IsVerbatim || CSharpOutputVisitor.IsKeyword(identifier.Name, identifier)) { + if (lastWritten == LastWritten.KeywordOrIdentifier) { + // this space is not strictly required, so we call Space() + Space(); + } + } else if (lastWritten == LastWritten.KeywordOrIdentifier) { + // this space is strictly required, so we directly call the formatter + base.Space(); + } + base.WriteIdentifier(identifier); + lastWritten = LastWritten.KeywordOrIdentifier; + } + + public override void WriteKeyword(Role role, string keyword) + { + if (lastWritten == LastWritten.KeywordOrIdentifier) { + Space(); + } + base.WriteKeyword(role, keyword); + lastWritten = LastWritten.KeywordOrIdentifier; + } + + public override void WriteToken(Role role, string token) + { + // Avoid that two +, - or ? tokens are combined into a ++, -- or ?? token. + // Note that we don't need to handle tokens like = because there's no valid + // C# program that contains the single token twice in a row. + // (for +, - and &, this can happen with unary operators; + // for ?, this can happen in "a is int? ? b : c" or "a as int? ?? 0"; + // and for /, this can happen with "1/ *ptr" or "1/ //comment".) + if (lastWritten == LastWritten.Plus && token[0] == '+' || + lastWritten == LastWritten.Minus && token[0] == '-' || + lastWritten == LastWritten.Ampersand && token[0] == '&' || + lastWritten == LastWritten.QuestionMark && token[0] == '?' || + lastWritten == LastWritten.Division && token[0] == '*') { + base.Space(); + } + base.WriteToken(role, token); + if (token == "+") { + lastWritten = LastWritten.Plus; + } else if (token == "-") { + lastWritten = LastWritten.Minus; + } else if (token == "&") { + lastWritten = LastWritten.Ampersand; + } else if (token == "?") { + lastWritten = LastWritten.QuestionMark; + } else if (token == "/") { + lastWritten = LastWritten.Division; + } else { + lastWritten = LastWritten.Other; + } + } + + public override void Space() + { + base.Space(); + lastWritten = LastWritten.Whitespace; + } + + public override void NewLine() + { + base.NewLine(); + lastWritten = LastWritten.Whitespace; + } + + public override void WriteComment(CommentType commentType, string content) + { + if (lastWritten == LastWritten.Division) { + // When there's a comment starting after a division operator + // "1.0 / /*comment*/a", then we need to insert a space in front of the comment. + base.Space(); + } + base.WriteComment(commentType, content); + lastWritten = LastWritten.Whitespace; + } + + public override void WritePreProcessorDirective(PreProcessorDirectiveType type, string argument) + { + base.WritePreProcessorDirective(type, argument); + lastWritten = LastWritten.Whitespace; + } + + public override void WritePrimitiveValue(object value, string literalValue = null) + { + base.WritePrimitiveValue(value, literalValue); + if (value == null || value is bool) + return; + if (value is string) { + lastWritten = LastWritten.Other; + } else if (value is char) { + lastWritten = LastWritten.Other; + } else if (value is decimal) { + lastWritten = LastWritten.Other; + } else if (value is float) { + float f = (float)value; + if (float.IsInfinity(f) || float.IsNaN(f)) return; + lastWritten = LastWritten.Other; + } else if (value is double) { + double f = (double)value; + if (double.IsInfinity(f) || double.IsNaN(f)) return; + // needs space if identifier follows number; + // this avoids mistaking the following identifier as type suffix + lastWritten = LastWritten.KeywordOrIdentifier; + } else if (value is IFormattable) { + // needs space if identifier follows number; + // this avoids mistaking the following identifier as type suffix + lastWritten = LastWritten.KeywordOrIdentifier; + } else { + lastWritten = LastWritten.Other; + } + } + + public override void WritePrimitiveType(string type) + { + if (lastWritten == LastWritten.KeywordOrIdentifier) { + Space(); + } + base.WritePrimitiveType(type); + if (type == "new") { + lastWritten = LastWritten.Other; + } else { + lastWritten = LastWritten.KeywordOrIdentifier; + } + } + } +} \ No newline at end of file diff --git a/NRefactory/ICSharpCode.NRefactory.CSharp/OutputVisitor/InsertSpecialsDecorator.cs b/NRefactory/ICSharpCode.NRefactory.CSharp/OutputVisitor/InsertSpecialsDecorator.cs new file mode 100644 index 000000000..0fafdeef0 --- /dev/null +++ b/NRefactory/ICSharpCode.NRefactory.CSharp/OutputVisitor/InsertSpecialsDecorator.cs @@ -0,0 +1,157 @@ +// Copyright (c) 2010-2013 AlphaSierraPapa for the SharpDevelop Team +// +// Permission is hereby granted, free of charge, to any person obtaining a copy of this +// software and associated documentation files (the "Software"), to deal in the Software +// without restriction, including without limitation the rights to use, copy, modify, merge, +// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons +// to whom the Software is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all copies or +// substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, +// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE +// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS IN THE SOFTWARE. + +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; +using ICSharpCode.NRefactory.CSharp; + +namespace ICSharpCode.NRefactory.CSharp +{ + class InsertSpecialsDecorator : DecoratingTokenWriter + { + readonly Stack positionStack = new Stack(); + int visitorWroteNewLine = 0; + + public InsertSpecialsDecorator(TokenWriter writer) : base(writer) + { + } + + public override void StartNode(AstNode node) + { + if (positionStack.Count > 0) { + WriteSpecialsUpToNode(node); + } + positionStack.Push(node.FirstChild); + base.StartNode(node); + } + + public override void EndNode(AstNode node) + { + base.EndNode(node); + AstNode pos = positionStack.Pop(); + Debug.Assert(pos == null || pos.Parent == node); + WriteSpecials(pos, null); + } + + public override void WriteKeyword(Role role, string keyword) + { + if (role != null) { + WriteSpecialsUpToRole(role); + } + base.WriteKeyword(role, keyword); + } + + public override void WriteIdentifier(Identifier identifier) + { + WriteSpecialsUpToRole(identifier.Role ?? Roles.Identifier); + base.WriteIdentifier(identifier); + } + + public override void WriteToken(Role role, string token) + { + WriteSpecialsUpToRole(role); + base.WriteToken(role, token); + } + + public override void NewLine() + { + if (visitorWroteNewLine >= 0) + base.NewLine(); + visitorWroteNewLine++; + } + + #region WriteSpecials + /// + /// Writes all specials from start to end (exclusive). Does not touch the positionStack. + /// + void WriteSpecials(AstNode start, AstNode end) + { + for (AstNode pos = start; pos != end; pos = pos.NextSibling) { + if (pos.Role == Roles.Comment) { + var node = (Comment)pos; + base.WriteComment(node.CommentType, node.Content); + } + // see CSharpOutputVisitor.VisitNewLine() + // if (pos.Role == Roles.NewLine) { + // if (visitorWroteNewLine <= 0) + // base.NewLine(); + // visitorWroteNewLine--; + // } + if (pos.Role == Roles.PreProcessorDirective) { + var node = (PreProcessorDirective)pos; + base.WritePreProcessorDirective(node.Type, node.Argument); + } + } + } + + /// + /// Writes all specials between the current position (in the positionStack) and the next + /// node with the specified role. Advances the current position. + /// + void WriteSpecialsUpToRole(Role role) + { + WriteSpecialsUpToRole(role, null); + } + + void WriteSpecialsUpToRole(Role role, AstNode nextNode) + { + if (positionStack.Count == 0) { + return; + } + // Look for the role between the current position and the nextNode. + for (AstNode pos = positionStack.Peek(); pos != null && pos != nextNode; pos = pos.NextSibling) { + if (pos.Role == role) { + WriteSpecials(positionStack.Pop(), pos); + // Push the next sibling because the node matching the role is not a special, + // and should be considered to be already handled. + positionStack.Push(pos.NextSibling); + // This is necessary for OptionalComma() to work correctly. + break; + } + } + } + + /// + /// Writes all specials between the current position (in the positionStack) and the specified node. + /// Advances the current position. + /// + void WriteSpecialsUpToNode(AstNode node) + { + if (positionStack.Count == 0) { + return; + } + for (AstNode pos = positionStack.Peek(); pos != null; pos = pos.NextSibling) { + if (pos == node) { + WriteSpecials(positionStack.Pop(), pos); + // Push the next sibling because the node itself is not a special, + // and should be considered to be already handled. + positionStack.Push(pos.NextSibling); + // This is necessary for OptionalComma() to work correctly. + break; + } + } + } + #endregion + } +} + + + + diff --git a/NRefactory/ICSharpCode.NRefactory.CSharp/OutputVisitor/TextWriterOutputFormatter.cs b/NRefactory/ICSharpCode.NRefactory.CSharp/OutputVisitor/TextWriterOutputFormatter.cs index e8d481b21..7e14ea190 100644 --- a/NRefactory/ICSharpCode.NRefactory.CSharp/OutputVisitor/TextWriterOutputFormatter.cs +++ b/NRefactory/ICSharpCode.NRefactory.CSharp/OutputVisitor/TextWriterOutputFormatter.cs @@ -1,4 +1,4 @@ -// Copyright (c) AlphaSierraPapa for the SharpDevelop Team +// Copyright (c) 2010-2013 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 @@ -17,139 +17,79 @@ // DEALINGS IN THE SOFTWARE. using System; +using System.Globalization; using System.IO; +using System.Text; namespace ICSharpCode.NRefactory.CSharp { /// /// Writes C# code into a TextWriter. /// - public class TextWriterOutputFormatter : IOutputFormatter + public class TextWriterTokenWriter : TokenWriter, ILocatable { readonly TextWriter textWriter; int indentation; bool needsIndent = true; bool isAtStartOfLine = true; + int line, column; public int Indentation { - get { - return this.indentation; - } - set { - this.indentation = value; - } + get { return this.indentation; } + set { this.indentation = value; } + } + + public TextLocation Location { + get { return new TextLocation(line, column + (needsIndent ? indentation * IndentationString.Length : 0)); } } public string IndentationString { get; set; } - public TextWriterOutputFormatter(TextWriter textWriter) + public TextWriterTokenWriter(TextWriter textWriter) { if (textWriter == null) throw new ArgumentNullException("textWriter"); this.textWriter = textWriter; this.IndentationString = "\t"; + this.line = 1; + this.column = 1; } - public void WriteIdentifier(string ident) + public override void WriteIdentifier(Identifier identifier) { WriteIndentation(); - textWriter.Write(ident); + if (identifier.IsVerbatim || CSharpOutputVisitor.IsKeyword(identifier.Name, identifier)) { + textWriter.Write('@'); + column++; + } + textWriter.Write(identifier.Name); + column += identifier.Name.Length; isAtStartOfLine = false; } - public void WriteKeyword(string keyword) + public override void WriteKeyword(Role role, string keyword) { WriteIndentation(); + column += keyword.Length; textWriter.Write(keyword); isAtStartOfLine = false; } - public void WriteToken(string token) + public override void WriteToken(Role role, string token) { WriteIndentation(); + column += token.Length; textWriter.Write(token); isAtStartOfLine = false; } - public void Space() + public override void Space() { WriteIndentation(); + column++; textWriter.Write(' '); } - public void OpenBrace(BraceStyle style) - { - switch (style) { - case BraceStyle.DoNotChange: - case BraceStyle.EndOfLine: - case BraceStyle.BannerStyle: - WriteIndentation(); - if (!isAtStartOfLine) - textWriter.Write(' '); - textWriter.Write('{'); - break; - case BraceStyle.EndOfLineWithoutSpace: - WriteIndentation(); - textWriter.Write('{'); - break; - case BraceStyle.NextLine: - if (!isAtStartOfLine) - NewLine(); - WriteIndentation(); - textWriter.Write('{'); - break; - - case BraceStyle.NextLineShifted: - NewLine (); - Indent(); - WriteIndentation(); - textWriter.Write('{'); - NewLine(); - return; - case BraceStyle.NextLineShifted2: - NewLine (); - Indent(); - WriteIndentation(); - textWriter.Write('{'); - break; - default: - throw new ArgumentOutOfRangeException (); - } - Indent(); - NewLine(); - } - - public void CloseBrace(BraceStyle style) - { - switch (style) { - case BraceStyle.DoNotChange: - case BraceStyle.EndOfLine: - case BraceStyle.EndOfLineWithoutSpace: - case BraceStyle.NextLine: - Unindent(); - WriteIndentation(); - textWriter.Write('}'); - isAtStartOfLine = false; - break; - case BraceStyle.BannerStyle: - case BraceStyle.NextLineShifted: - WriteIndentation(); - textWriter.Write('}'); - isAtStartOfLine = false; - Unindent(); - break; - case BraceStyle.NextLineShifted2: - Unindent(); - WriteIndentation(); - textWriter.Write('}'); - isAtStartOfLine = false; - Unindent(); - break; - default: - throw new ArgumentOutOfRangeException (); - } - } - protected void WriteIndentation() { if (needsIndent) { @@ -157,33 +97,37 @@ namespace ICSharpCode.NRefactory.CSharp for (int i = 0; i < indentation; i++) { textWriter.Write(this.IndentationString); } + column += indentation * IndentationString.Length; } } - public void NewLine() + public override void NewLine() { textWriter.WriteLine(); + column = 1; + line++; needsIndent = true; isAtStartOfLine = true; } - public void Indent() + public override void Indent() { indentation++; } - public void Unindent() + public override void Unindent() { indentation--; } - public void WriteComment(CommentType commentType, string content) + public override void WriteComment(CommentType commentType, string content) { WriteIndentation(); switch (commentType) { case CommentType.SingleLine: textWriter.Write("//"); textWriter.WriteLine(content); + column += 2 + content.Length; needsIndent = true; isAtStartOfLine = true; break; @@ -191,36 +135,267 @@ namespace ICSharpCode.NRefactory.CSharp textWriter.Write("/*"); textWriter.Write(content); textWriter.Write("*/"); + column += 2; + UpdateEndLocation(content, ref line, ref column); + column += 2; isAtStartOfLine = false; break; case CommentType.Documentation: textWriter.Write("///"); textWriter.WriteLine(content); + column += 3 + content.Length; needsIndent = true; isAtStartOfLine = true; break; default: textWriter.Write(content); + column += content.Length; break; } } - public void WritePreProcessorDirective(PreProcessorDirectiveType type, string argument) + static void UpdateEndLocation(string content, ref int line, ref int column) + { + if (string.IsNullOrEmpty(content)) + return; + for (int i = 0; i < content.Length; i++) { + char ch = content[i]; + switch (ch) { + case '\r': + if (i + 1 < content.Length && content[i + 1] == '\n') + i++; + goto case '\n'; + case '\n': + line++; + column = 0; + break; + } + column++; + } + } + + public override void WritePreProcessorDirective(PreProcessorDirectiveType type, string argument) { // pre-processor directive must start on its own line if (!isAtStartOfLine) NewLine(); WriteIndentation(); textWriter.Write('#'); - textWriter.Write(type.ToString().ToLowerInvariant()); + string directive = type.ToString().ToLowerInvariant(); + textWriter.Write(directive); + column += 1 + directive.Length; if (!string.IsNullOrEmpty(argument)) { textWriter.Write(' '); textWriter.Write(argument); + column += 1 + argument.Length; } NewLine(); } - public virtual void StartNode(AstNode node) + public static string PrintPrimitiveValue(object value) + { + TextWriter writer = new StringWriter(); + TextWriterTokenWriter tokenWriter = new TextWriterTokenWriter(writer); + tokenWriter.WritePrimitiveValue(value); + return writer.ToString(); + } + + public override void WritePrimitiveValue(object value, string literalValue = null) + { + if (literalValue != null) { + textWriter.Write(literalValue); + column += literalValue.Length; + return; + } + + if (value == null) { + // usually NullReferenceExpression should be used for this, but we'll handle it anyways + textWriter.Write("null"); + column += 4; + return; + } + + if (value is bool) { + if ((bool)value) { + textWriter.Write("true"); + column += 4; + } else { + textWriter.Write("false"); + column += 5; + } + return; + } + + if (value is string) { + string tmp = "\"" + ConvertString(value.ToString()) + "\""; + column += tmp.Length; + textWriter.Write(tmp); + } else if (value is char) { + string tmp = "'" + ConvertCharLiteral((char)value) + "'"; + column += tmp.Length; + textWriter.Write(tmp); + } else if (value is decimal) { + string str = ((decimal)value).ToString(NumberFormatInfo.InvariantInfo) + "m"; + column += str.Length; + textWriter.Write(str); + } else if (value is float) { + float f = (float)value; + if (float.IsInfinity(f) || float.IsNaN(f)) { + // Strictly speaking, these aren't PrimitiveExpressions; + // but we still support writing these to make life easier for code generators. + textWriter.Write("float"); + column += 5; + WriteToken(Roles.Dot, "."); + if (float.IsPositiveInfinity(f)) { + textWriter.Write("PositiveInfinity"); + column += "PositiveInfinity".Length; + } else if (float.IsNegativeInfinity(f)) { + textWriter.Write("NegativeInfinity"); + column += "NegativeInfinity".Length; + } else { + textWriter.Write("NaN"); + column += 3; + } + return; + } + if (f == 0 && 1 / f == float.NegativeInfinity) { + // negative zero is a special case + // (again, not a primitive expression, but it's better to handle + // the special case here than to do it in all code generators) + textWriter.Write("-"); + column++; + } + var str = f.ToString("R", NumberFormatInfo.InvariantInfo) + "f"; + column += str.Length; + textWriter.Write(str); + } else if (value is double) { + double f = (double)value; + if (double.IsInfinity(f) || double.IsNaN(f)) { + // Strictly speaking, these aren't PrimitiveExpressions; + // but we still support writing these to make life easier for code generators. + textWriter.Write("double"); + column += 6; + WriteToken(Roles.Dot, "."); + if (double.IsPositiveInfinity(f)) { + textWriter.Write("PositiveInfinity"); + column += "PositiveInfinity".Length; + } else if (double.IsNegativeInfinity(f)) { + textWriter.Write("NegativeInfinity"); + column += "NegativeInfinity".Length; + } else { + textWriter.Write("NaN"); + column += 3; + } + return; + } + if (f == 0 && 1 / f == double.NegativeInfinity) { + // negative zero is a special case + // (again, not a primitive expression, but it's better to handle + // the special case here than to do it in all code generators) + textWriter.Write("-"); + } + string number = f.ToString("R", NumberFormatInfo.InvariantInfo); + if (number.IndexOf('.') < 0 && number.IndexOf('E') < 0) { + number += ".0"; + } + textWriter.Write(number); + } else if (value is IFormattable) { + StringBuilder b = new StringBuilder (); +// if (primitiveExpression.LiteralFormat == LiteralFormat.HexadecimalNumber) { +// b.Append("0x"); +// b.Append(((IFormattable)val).ToString("x", NumberFormatInfo.InvariantInfo)); +// } else { + b.Append(((IFormattable)value).ToString(null, NumberFormatInfo.InvariantInfo)); +// } + if (value is uint || value is ulong) { + b.Append("u"); + } + if (value is long || value is ulong) { + b.Append("L"); + } + textWriter.Write(b.ToString()); + column += b.Length; + } else { + textWriter.Write(value.ToString()); + column += value.ToString().Length; + } + } + + /// + /// Gets the escape sequence for the specified character within a char literal. + /// Does not include the single quotes surrounding the char literal. + /// + public static string ConvertCharLiteral(char ch) + { + if (ch == '\'') { + return "\\'"; + } + return ConvertChar(ch); + } + + /// + /// Gets the escape sequence for the specified character. + /// + /// This method does not convert ' or ". + static string ConvertChar(char ch) + { + switch (ch) { + case '\\': + return "\\\\"; + case '\0': + return "\\0"; + case '\a': + return "\\a"; + case '\b': + return "\\b"; + case '\f': + return "\\f"; + case '\n': + return "\\n"; + case '\r': + return "\\r"; + case '\t': + return "\\t"; + case '\v': + return "\\v"; + default: + if (char.IsControl(ch) || char.IsSurrogate(ch) || + // print all uncommon white spaces as numbers + (char.IsWhiteSpace(ch) && ch != ' ')) { + return "\\u" + ((int)ch).ToString("x4"); + } else { + return ch.ToString(); + } + } + } + + /// + /// Converts special characters to escape sequences within the given string. + /// + public static string ConvertString(string str) + { + StringBuilder sb = new StringBuilder (); + foreach (char ch in str) { + if (ch == '"') { + sb.Append("\\\""); + } else { + sb.Append(ConvertChar(ch)); + } + } + return sb.ToString(); + } + + public override void WritePrimitiveType(string type) + { + textWriter.Write(type); + column += type.Length; + if (type == "new") { + textWriter.Write("()"); + column += 2; + } + } + + public override void StartNode(AstNode node) { // Write out the indentation, so that overrides of this method // can rely use the current output length to identify the position of the node @@ -228,7 +403,7 @@ namespace ICSharpCode.NRefactory.CSharp WriteIndentation(); } - public virtual void EndNode(AstNode node) + public override void EndNode(AstNode node) { } } diff --git a/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/CSharpParser.cs b/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/CSharpParser.cs index 2ac9f86e4..0eb2ff70c 100644 --- a/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/CSharpParser.cs +++ b/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/CSharpParser.cs @@ -1,4 +1,4 @@ -// +// // CSharpParser.cs // // Author: @@ -27,7 +27,6 @@ using System; using System.Linq; using System.Collections.Generic; using System.IO; -using System.Text; using ICSharpCode.NRefactory.Editor; using Mono.CSharp; using ICSharpCode.NRefactory.TypeSystem; @@ -37,12 +36,12 @@ namespace ICSharpCode.NRefactory.CSharp public class CSharpParser { CompilerSettings compilerSettings; - + class ConversionVisitor : StructuralVisitor { - SyntaxTree unit = new SyntaxTree (); + SyntaxTree unit = new SyntaxTree(); internal bool convertTypeSystemMode; - + public SyntaxTree Unit { get { return unit; @@ -51,23 +50,23 @@ namespace ICSharpCode.NRefactory.CSharp unit = value; } } - + public LocationsBag LocationsBag { get; private set; } - - public ConversionVisitor (bool convertTypeSystemMode, LocationsBag locationsBag) + + public ConversionVisitor(bool convertTypeSystemMode, LocationsBag locationsBag) { this.convertTypeSystemMode = convertTypeSystemMode; this.LocationsBag = locationsBag; } - - public static TextLocation Convert (Mono.CSharp.Location loc) + + public static TextLocation Convert(Location loc) { - return new TextLocation (loc.Row, loc.Column); + return new TextLocation(loc.Row, loc.Column); } - + public override void Visit(ModuleContainer mc) { bool first = true; @@ -81,13 +80,13 @@ namespace ICSharpCode.NRefactory.CSharp var loc = LocationsBag.GetLocations(nspace); if (nspace.NS != null && !string.IsNullOrEmpty(nspace.NS.Name)) { - nDecl = new NamespaceDeclaration (); + nDecl = new NamespaceDeclaration(); if (loc != null) { - nDecl.AddChild(new CSharpTokenNode (Convert(loc [0])), Roles.NamespaceKeyword); + nDecl.AddChild(new CSharpTokenNode(Convert(loc [0]), Roles.NamespaceKeyword), Roles.NamespaceKeyword); } - ConvertNamespaceName(nspace.RealMemberName, nDecl); + nDecl.AddChild(ConvertNamespaceName(nspace.RealMemberName), NamespaceDeclaration.NamespaceNameRole); if (loc != null && loc.Count > 1) { - nDecl.AddChild(new CSharpTokenNode (Convert(loc [1])), Roles.LBrace); + nDecl.AddChild(new CSharpTokenNode(Convert(loc [1]), Roles.LBrace), Roles.LBrace); } AddToNamespace(nDecl); namespaceStack.Push(nDecl); @@ -101,7 +100,13 @@ namespace ICSharpCode.NRefactory.CSharp if (first) { first = false; - AddAttributeSection(Unit, mc); + if (mc.OptAttributes != null) { + foreach (var attr in mc.OptAttributes.Sections) { + var section = ConvertAttributeSection(attr); + if (section != null) + unit.AddChild(section, SyntaxTree.MemberRole); + } + } } if (nspace.Containers != null) { @@ -110,436 +115,441 @@ namespace ICSharpCode.NRefactory.CSharp } } if (nDecl != null) { - AddAttributeSection (nDecl, nspace.UnattachedAttributes, EntityDeclaration.UnattachedAttributeRole); + AddAttributeSection(nDecl, nspace.UnattachedAttributes, EntityDeclaration.UnattachedAttributeRole); if (loc != null && loc.Count > 2) - nDecl.AddChild (new CSharpTokenNode (Convert (loc [2])), Roles.RBrace); + nDecl.AddChild(new CSharpTokenNode(Convert(loc [2]), Roles.RBrace), Roles.RBrace); if (loc != null && loc.Count > 3) - nDecl.AddChild (new CSharpTokenNode (Convert (loc [3])), Roles.Semicolon); + nDecl.AddChild(new CSharpTokenNode(Convert(loc [3]), Roles.Semicolon), Roles.Semicolon); - namespaceStack.Pop (); + namespaceStack.Pop(); } else { - AddAttributeSection (unit, nspace.UnattachedAttributes, EntityDeclaration.UnattachedAttributeRole); + AddAttributeSection(unit, nspace.UnattachedAttributes, EntityDeclaration.UnattachedAttributeRole); } } - AddAttributeSection (unit, mc.UnattachedAttributes, EntityDeclaration.UnattachedAttributeRole); + AddAttributeSection(unit, mc.UnattachedAttributes, EntityDeclaration.UnattachedAttributeRole); } - + #region Global - Stack namespaceStack = new Stack (); - - void AddTypeArguments (ATypeNameExpression texpr, AstType result) + + readonly Stack namespaceStack = new Stack(); + + void AddTypeArguments(ATypeNameExpression texpr, AstType result) { if (texpr.TypeArguments == null || texpr.TypeArguments.Args == null) return; - var loc = LocationsBag.GetLocations (texpr.TypeArguments); + var loc = LocationsBag.GetLocations(texpr.TypeArguments); if (loc != null && loc.Count >= 2) - result.AddChild (new CSharpTokenNode (Convert (loc [loc.Count - 2])), Roles.LChevron); + result.AddChild(new CSharpTokenNode(Convert(loc [loc.Count - 2]), Roles.LChevron), Roles.LChevron); int i = 0; foreach (var arg in texpr.TypeArguments.Args) { - result.AddChild (ConvertToType (arg), Roles.TypeArgument); + result.AddChild(ConvertToType(arg), Roles.TypeArgument); if (loc != null && i < loc.Count - 2) - result.AddChild (new CSharpTokenNode (Convert (loc [i++])), Roles.Comma); + result.AddChild(new CSharpTokenNode(Convert(loc [i++]), Roles.Comma), Roles.Comma); } if (loc != null && loc.Count >= 2) - result.AddChild (new CSharpTokenNode (Convert (loc [loc.Count - 1])), Roles.RChevron); + result.AddChild(new CSharpTokenNode(Convert(loc [loc.Count - 1]), Roles.RChevron), Roles.RChevron); } - - AstType ConvertToType (TypeParameter spec) + + static AstType ConvertToType(TypeParameter spec) { AstType result; - result = new SimpleType () { IdentifierToken = Identifier.Create (spec.Name, Convert (spec.Location)) }; + result = new SimpleType { IdentifierToken = Identifier.Create(spec.Name, Convert(spec.Location)) }; return result; } - - AstType ConvertToType (MemberName memberName) + + AstType ConvertToType(MemberName memberName) { AstType result; if (memberName.Left != null) { - result = new MemberType (); - result.AddChild (ConvertToType (memberName.Left), MemberType.TargetRole); - var loc = LocationsBag.GetLocations (memberName.Left); + result = new MemberType(); + result.AddChild(ConvertToType(memberName.Left), MemberType.TargetRole); + var loc = LocationsBag.GetLocations(memberName); if (loc != null) - result.AddChild (new CSharpTokenNode (Convert (loc [0])), Roles.Dot); - result.AddChild (Identifier.Create (memberName.Name, Convert (memberName.Location)), Roles.Identifier); + result.AddChild(new CSharpTokenNode(Convert(loc [0]), Roles.Dot), Roles.Dot); + result.AddChild(Identifier.Create(memberName.Name, Convert(memberName.Location)), Roles.Identifier); } else { - result = new SimpleType () { IdentifierToken = Identifier.Create (memberName.Name, Convert (memberName.Location)) }; + result = new SimpleType { IdentifierToken = Identifier.Create(memberName.Name, Convert(memberName.Location)) }; } if (memberName.TypeParameters != null) { - var chevronLocs = LocationsBag.GetLocations (memberName.TypeParameters); + var chevronLocs = LocationsBag.GetLocations(memberName.TypeParameters); if (chevronLocs != null) - result.AddChild (new CSharpTokenNode (Convert (chevronLocs [chevronLocs.Count - 2])), Roles.LChevron); + result.AddChild(new CSharpTokenNode(Convert(chevronLocs [chevronLocs.Count - 2]), Roles.LChevron), Roles.LChevron); for (int i = 0; i < memberName.TypeParameters.Count; i++) { var param = memberName.TypeParameters [i]; - result.AddChild (new SimpleType (Identifier.Create (param.Name, Convert (param.Location))), Roles.TypeArgument); + result.AddChild(new SimpleType(Identifier.Create(param.Name, Convert(param.Location))), Roles.TypeArgument); if (chevronLocs != null && i < chevronLocs.Count - 2) - result.AddChild (new CSharpTokenNode (Convert (chevronLocs [i])), Roles.Comma); + result.AddChild(new CSharpTokenNode(Convert(chevronLocs [i]), Roles.Comma), Roles.Comma); } if (chevronLocs != null) - result.AddChild (new CSharpTokenNode (Convert (chevronLocs [chevronLocs.Count - 1])), Roles.RChevron); + result.AddChild(new CSharpTokenNode(Convert(chevronLocs [chevronLocs.Count - 1]), Roles.RChevron), Roles.RChevron); } return result; } - - AstType ConvertToType (Mono.CSharp.Expression typeName) + + AstType ConvertToType(Mono.CSharp.Expression typeName) { if (typeName == null) // may happen in typeof(Generic<,,,,>) - return new SimpleType (); + return new SimpleType(); - if (typeName is TypeExpression) { - var typeExpr = (Mono.CSharp.TypeExpression)typeName; - return new PrimitiveType (typeExpr.GetSignatureForError (), Convert (typeExpr.Location)); + var typeExpr = typeName as TypeExpression; + if (typeExpr != null) { + return new PrimitiveType(typeExpr.GetSignatureForError(), Convert(typeExpr.Location)); } - if (typeName is Mono.CSharp.QualifiedAliasMember) { - var qam = (Mono.CSharp.QualifiedAliasMember)typeName; - var memberType = new MemberType (); - memberType.Target = new SimpleType (qam.alias, Convert (qam.Location)); + var qam = typeName as QualifiedAliasMember; + if (qam != null) { + var loc = LocationsBag.GetLocations(typeName); + var memberType = new MemberType(); + memberType.Target = new SimpleType(qam.alias, Convert(qam.Location)); memberType.IsDoubleColon = true; - memberType.MemberName = qam.Name; + + if (loc != null && loc.Count > 0) + memberType.AddChild(new CSharpTokenNode(Convert(loc [0]), Roles.DoubleColon), Roles.DoubleColon); + + memberType.MemberNameToken = Identifier.Create(qam.Name, loc != null ? Convert(loc [1]) : TextLocation.Empty); + AddTypeArguments(qam, memberType); return memberType; } - if (typeName is MemberAccess) { - MemberAccess ma = (MemberAccess)typeName; - - var memberType = new MemberType (); - memberType.AddChild (ConvertToType (ma.LeftExpression), MemberType.TargetRole); - memberType.AddChild (new CSharpTokenNode (Convert (ma.DotLocation)), Roles.Dot); - - memberType.MemberNameToken = Identifier.Create (ma.Name, Convert (ma.Location)); + var ma = typeName as MemberAccess; + if (ma != null) { + var memberType = new MemberType(); + memberType.AddChild(ConvertToType(ma.LeftExpression), MemberType.TargetRole); + var loc = LocationsBag.GetLocations(ma); + if (loc != null) + memberType.AddChild(new CSharpTokenNode(Convert(loc [0]), Roles.Dot), Roles.Dot); + + memberType.MemberNameToken = Identifier.Create(ma.Name, Convert(ma.Location)); - AddTypeArguments (ma, memberType); + AddTypeArguments(ma, memberType); return memberType; } - if (typeName is SimpleName) { - var sn = (SimpleName)typeName; - var result = new SimpleType (sn.Name, Convert (sn.Location)); - AddTypeArguments (sn, result); + var sn = typeName as SimpleName; + if (sn != null) { + var result = new SimpleType(sn.Name, Convert(sn.Location)); + AddTypeArguments(sn, result); return result; } - if (typeName is ComposedCast) { - var cc = (ComposedCast)typeName; - var baseType = ConvertToType (cc.Left); - var result = new ComposedType () { BaseType = baseType }; + var cc = typeName as ComposedCast; + if (cc != null) { + var baseType = ConvertToType(cc.Left); + var result = new ComposedType { BaseType = baseType }; var ccSpec = cc.Spec; while (ccSpec != null) { if (ccSpec.IsNullable) { - result.AddChild (new CSharpTokenNode (Convert (ccSpec.Location)), ComposedType.NullableRole); + result.AddChild(new CSharpTokenNode(Convert(ccSpec.Location), ComposedType.NullableRole), ComposedType.NullableRole); } else if (ccSpec.IsPointer) { - result.AddChild (new CSharpTokenNode (Convert (ccSpec.Location)), ComposedType.PointerRole); + result.AddChild(new CSharpTokenNode(Convert(ccSpec.Location), ComposedType.PointerRole), ComposedType.PointerRole); } else { - var location = LocationsBag.GetLocations (ccSpec); - var spec = new ArraySpecifier () { Dimensions = ccSpec.Dimension }; - spec.AddChild (new CSharpTokenNode (Convert (ccSpec.Location)), Roles.LBracket); + var location = LocationsBag.GetLocations(ccSpec); + var spec = new ArraySpecifier { Dimensions = ccSpec.Dimension }; + spec.AddChild(new CSharpTokenNode(Convert(ccSpec.Location), Roles.LBracket), Roles.LBracket); if (location != null) - spec.AddChild (new CSharpTokenNode (Convert (location [0])), Roles.RBracket); + spec.AddChild(new CSharpTokenNode(Convert(location [0]), Roles.RBracket), Roles.RBracket); - result.ArraySpecifiers.Add (spec); + result.ArraySpecifiers.Add(spec); } ccSpec = ccSpec.Next; } return result; } - if (typeName is SpecialContraintExpr) { - var sce = (SpecialContraintExpr)typeName; + var sce = typeName as SpecialContraintExpr; + if (sce != null) { switch (sce.Constraint) { case SpecialConstraint.Class: - return new PrimitiveType ("class", Convert (sce.Location)); + return new PrimitiveType("class", Convert(sce.Location)); case SpecialConstraint.Struct: - return new PrimitiveType ("struct", Convert (sce.Location)); + return new PrimitiveType("struct", Convert(sce.Location)); case SpecialConstraint.Constructor: - return new PrimitiveType ("new", Convert (sce.Location)); + return new PrimitiveType("new", Convert(sce.Location)); } } - return new SimpleType ("unknown"); + return new SimpleType("unknown"); } - - IEnumerable GetAttributes (IEnumerable optAttributes) + + IEnumerable GetAttributes(IEnumerable optAttributes) { if (optAttributes == null) yield break; foreach (var attr in optAttributes) { - Attribute result = new Attribute (); - result.Type = ConvertToType (attr.TypeNameExpression); - var loc = LocationsBag.GetLocations (attr); + var result = new Attribute(); + result.Type = ConvertToType(attr.TypeNameExpression); + var loc = LocationsBag.GetLocations(attr); result.HasArgumentList = loc != null; int pos = 0; if (loc != null) - result.AddChild (new CSharpTokenNode (Convert (loc [pos++])), Roles.LPar); + result.AddChild(new CSharpTokenNode(Convert(loc [pos++]), Roles.LPar), Roles.LPar); if (attr.PositionalArguments != null) { foreach (var arg in attr.PositionalArguments) { + if (arg == null) + continue; var na = arg as NamedArgument; if (na != null) { - var newArg = new NamedArgumentExpression (); - newArg.AddChild (Identifier.Create (na.Name, Convert (na.Location)), Roles.Identifier); + var newArg = new NamedArgumentExpression(); + newArg.AddChild(Identifier.Create(na.Name, Convert(na.Location)), Roles.Identifier); - var argLoc = LocationsBag.GetLocations (na); + var argLoc = LocationsBag.GetLocations(na); if (argLoc != null) - newArg.AddChild (new CSharpTokenNode (Convert (argLoc [0])), Roles.Colon); + newArg.AddChild(new CSharpTokenNode(Convert(argLoc [0]), Roles.Colon), Roles.Colon); if (na.Expr != null) - newArg.AddChild ((Expression)na.Expr.Accept (this), Roles.Expression); - result.AddChild (newArg, Roles.Argument); + newArg.AddChild((Expression)na.Expr.Accept(this), Roles.Expression); + result.AddChild(newArg, Roles.Argument); } else { if (arg.Expr != null) - result.AddChild ((Expression)arg.Expr.Accept (this), Roles.Argument); + result.AddChild((Expression)arg.Expr.Accept(this), Roles.Argument); } if (loc != null && pos + 1 < loc.Count) - result.AddChild (new CSharpTokenNode (Convert (loc [pos++])), Roles.Comma); + result.AddChild(new CSharpTokenNode(Convert(loc [pos++]), Roles.Comma), Roles.Comma); } } if (attr.NamedArguments != null) { - foreach (NamedArgument na in attr.NamedArguments) { - var newArg = new NamedExpression (); - newArg.AddChild (Identifier.Create (na.Name, Convert (na.Location)), Roles.Identifier); + foreach (var arg in attr.NamedArguments) { + var na = (NamedArgument)arg; + var newArg = new NamedExpression(); + newArg.AddChild(Identifier.Create(na.Name, Convert(na.Location)), Roles.Identifier); - var argLoc = LocationsBag.GetLocations (na); + var argLoc = LocationsBag.GetLocations(na); if (argLoc != null) - newArg.AddChild (new CSharpTokenNode (Convert (argLoc [0])), Roles.Assign); + newArg.AddChild(new CSharpTokenNode(Convert(argLoc [0]), Roles.Assign), Roles.Assign); if (na.Expr != null) - newArg.AddChild ((Expression)na.Expr.Accept (this), Roles.Expression); - result.AddChild (newArg, Roles.Argument); + newArg.AddChild((Expression)na.Expr.Accept(this), Roles.Expression); + result.AddChild(newArg, Roles.Argument); if (loc != null && pos + 1 < loc.Count) - result.AddChild (new CSharpTokenNode (Convert (loc [pos++])), Roles.Comma); + result.AddChild(new CSharpTokenNode(Convert(loc [pos++]), Roles.Comma), Roles.Comma); } } if (loc != null && pos < loc.Count) - result.AddChild (new CSharpTokenNode (Convert (loc [pos++])), Roles.RPar); + result.AddChild(new CSharpTokenNode(Convert(loc [pos++]), Roles.RPar), Roles.RPar); yield return result; } } - - AttributeSection ConvertAttributeSection (IEnumerable optAttributes) + + AttributeSection ConvertAttributeSection(IEnumerable optAttributes) { if (optAttributes == null) return null; - AttributeSection result = new AttributeSection (); - var loc = LocationsBag.GetLocations (optAttributes); + var result = new AttributeSection(); + var loc = LocationsBag.GetLocations(optAttributes); int pos = 0; if (loc != null) - result.AddChild (new CSharpTokenNode (Convert (loc [pos++])), Roles.LBracket); - - var first = optAttributes.FirstOrDefault (); + result.AddChild(new CSharpTokenNode(Convert(loc [pos++]), Roles.LBracket), Roles.LBracket); + var first = optAttributes.FirstOrDefault(); string target = first != null ? first.ExplicitTarget : null; - if (!string.IsNullOrEmpty (target)) { + if (!string.IsNullOrEmpty(target)) { if (loc != null && pos < loc.Count - 1) { - result.AddChild (Identifier.Create (target, Convert (loc [pos++])), Roles.Identifier); + result.AddChild(Identifier.Create(target, Convert(loc [pos++])), Roles.Identifier); } else { - result.AddChild (Identifier.Create (target), Roles.Identifier); + result.AddChild(Identifier.Create(target), Roles.Identifier); } if (loc != null && pos < loc.Count) - result.AddChild (new CSharpTokenNode (Convert (loc [pos++])), Roles.Colon); + result.AddChild(new CSharpTokenNode(Convert(loc [pos++]), Roles.Colon), Roles.Colon); } int attributeCount = 0; foreach (var attr in GetAttributes (optAttributes)) { - result.AddChild (attr, Roles.Attribute); + result.AddChild(attr, Roles.Attribute); + if (loc != null && pos + 1 < loc.Count) + result.AddChild(new CSharpTokenNode(Convert(loc [pos++]), Roles.Comma), Roles.Comma); + attributeCount++; } + if (attributeCount == 0) + return null; // Left and right bracket + commas between the attributes int locCount = 2 + attributeCount - 1; // optional comma if (loc != null && pos < loc.Count - 1 && loc.Count == locCount + 1) - result.AddChild (new CSharpTokenNode (Convert (loc [pos++])), Roles.Comma); + result.AddChild(new CSharpTokenNode(Convert(loc [pos++]), Roles.Comma), Roles.Comma); if (loc != null && pos < loc.Count) - result.AddChild (new CSharpTokenNode (Convert (loc [pos++])), Roles.RBracket); + result.AddChild(new CSharpTokenNode(Convert(loc [pos++]), Roles.RBracket), Roles.RBracket); return result; } - - public override void Visit(NamespaceContainer nspace) + + public override void Visit(NamespaceContainer ns) { NamespaceDeclaration nDecl = null; - var loc = LocationsBag.GetLocations(nspace); - - if (nspace.NS != null && !string.IsNullOrEmpty(nspace.NS.Name)) { - nDecl = new NamespaceDeclaration (); + var loc = LocationsBag.GetLocations(ns); + // is caused by the parser - see Bug 12383 - [AST] Non existing namespaces generated + if (ns.NS != null && !string.IsNullOrEmpty(ns.NS.Name) && !ns.NS.Name.EndsWith("", StringComparison.Ordinal)) { + nDecl = new NamespaceDeclaration(); if (loc != null) { - nDecl.AddChild(new CSharpTokenNode (Convert(loc [0])), Roles.NamespaceKeyword); + nDecl.AddChild(new CSharpTokenNode(Convert(loc [0]), Roles.NamespaceKeyword), Roles.NamespaceKeyword); } - ConvertNamespaceName(nspace.RealMemberName, nDecl); + nDecl.AddChild(ConvertNamespaceName(ns.RealMemberName), NamespaceDeclaration.NamespaceNameRole); if (loc != null && loc.Count > 1) { - nDecl.AddChild(new CSharpTokenNode (Convert(loc [1])), Roles.LBrace); + nDecl.AddChild(new CSharpTokenNode(Convert(loc [1]), Roles.LBrace), Roles.LBrace); } + AddToNamespace(nDecl); namespaceStack.Push(nDecl); } - if (nspace.Usings != null) { - foreach (var us in nspace.Usings) { + if (ns.Usings != null) { + foreach (var us in ns.Usings) { us.Accept(this); } } - if (nspace.Containers != null) { - foreach (var container in nspace.Containers) { + if (ns.Containers != null) { + foreach (var container in ns.Containers) { container.Accept(this); } } if (nDecl != null) { - AddAttributeSection(nDecl, nspace.UnattachedAttributes, EntityDeclaration.UnattachedAttributeRole); + AddAttributeSection(nDecl, ns.UnattachedAttributes, EntityDeclaration.UnattachedAttributeRole); if (loc != null && loc.Count > 2) - nDecl.AddChild (new CSharpTokenNode (Convert (loc [2])), Roles.RBrace); + nDecl.AddChild(new CSharpTokenNode(Convert(loc [2]), Roles.RBrace), Roles.RBrace); if (loc != null && loc.Count > 3) - nDecl.AddChild (new CSharpTokenNode (Convert (loc [3])), Roles.Semicolon); + nDecl.AddChild(new CSharpTokenNode(Convert(loc [3]), Roles.Semicolon), Roles.Semicolon); - namespaceStack.Pop (); + namespaceStack.Pop(); } } -// public override void Visit (UsingsBag.Namespace nspace) -// { -// -// -// VisitNamespaceUsings (nspace); -// VisitNamespaceBody (nspace); -// -// } -// - void ConvertNamespaceName (MemberName memberName, NamespaceDeclaration namespaceDecl) + // public override void Visit (UsingsBag.Namespace nspace) + // { + // + // + // VisitNamespaceUsings (nspace); + // VisitNamespaceBody (nspace); + // + // } + // + AstType ConvertNamespaceName(MemberName memberName) { - AstNode insertPos = null; - while (memberName != null) { - Identifier newIdent = Identifier.Create (memberName.Name, Convert (memberName.Location)); - namespaceDecl.InsertChildBefore (insertPos, newIdent, Roles.Identifier); - insertPos = newIdent; - - if (!memberName.DotLocation.IsNull) { - var dotToken = new CSharpTokenNode (Convert (memberName.DotLocation)); - namespaceDecl.InsertChildBefore (insertPos, dotToken, Roles.Dot); - insertPos = dotToken; - } - - memberName = memberName.Left; - } + // HACK for a parser 'bug' - sometimes it generates "" identifiers in namespace names (on certain bugs in the input file) + if (memberName.Name == "") + return AstType.Null; + return ConvertToType(memberName); } - - public override void Visit (UsingNamespace un) + + public override void Visit(UsingNamespace un) { - var ud = new UsingDeclaration (); - var loc = LocationsBag.GetLocations (un); - ud.AddChild (new CSharpTokenNode (Convert (un.Location)), UsingDeclaration.UsingKeywordRole); + var ud = new UsingDeclaration(); + var loc = LocationsBag.GetLocations(un); + ud.AddChild(new CSharpTokenNode(Convert(un.Location), UsingDeclaration.UsingKeywordRole), UsingDeclaration.UsingKeywordRole); if (un.NamespaceExpression != null) - ud.AddChild (ConvertToType (un.NamespaceExpression), UsingDeclaration.ImportRole); + ud.AddChild(ConvertToType(un.NamespaceExpression), UsingDeclaration.ImportRole); if (loc != null) - ud.AddChild (new CSharpTokenNode (Convert (loc [0])), Roles.Semicolon); - AddToNamespace (ud); + ud.AddChild(new CSharpTokenNode(Convert(loc [0]), Roles.Semicolon), Roles.Semicolon); + AddToNamespace(ud); } - public override void Visit (UsingAliasNamespace uan) + public override void Visit(UsingAliasNamespace uan) { - var ud = new UsingAliasDeclaration (); - var loc = LocationsBag.GetLocations (uan); + var ud = new UsingAliasDeclaration(); + var loc = LocationsBag.GetLocations(uan); - ud.AddChild (new CSharpTokenNode (Convert (uan.Location)), UsingAliasDeclaration.UsingKeywordRole); - ud.AddChild (Identifier.Create (uan.Alias.Value, Convert (uan.Alias.Location)), UsingAliasDeclaration.AliasRole); + ud.AddChild(new CSharpTokenNode(Convert(uan.Location), UsingAliasDeclaration.UsingKeywordRole), UsingAliasDeclaration.UsingKeywordRole); + ud.AddChild(Identifier.Create(uan.Alias.Value, Convert(uan.Alias.Location)), UsingAliasDeclaration.AliasRole); if (loc != null) - ud.AddChild (new CSharpTokenNode (Convert (loc [0])), Roles.Assign); + ud.AddChild(new CSharpTokenNode(Convert(loc [0]), Roles.Assign), Roles.Assign); if (uan.NamespaceExpression != null) - ud.AddChild (ConvertToType (uan.NamespaceExpression), UsingAliasDeclaration.ImportRole); + ud.AddChild(ConvertToType(uan.NamespaceExpression), UsingAliasDeclaration.ImportRole); if (loc != null && loc.Count > 1) - ud.AddChild (new CSharpTokenNode (Convert (loc [1])), Roles.Semicolon); - AddToNamespace (ud); + ud.AddChild(new CSharpTokenNode(Convert(loc [1]), Roles.Semicolon), Roles.Semicolon); + AddToNamespace(ud); } - - public override void Visit (UsingExternAlias uea) + + public override void Visit(UsingExternAlias uea) { - var ud = new ExternAliasDeclaration (); - var loc = LocationsBag.GetLocations (uea); - ud.AddChild (new CSharpTokenNode (Convert (uea.Location)), Roles.ExternKeyword); + var ud = new ExternAliasDeclaration(); + var loc = LocationsBag.GetLocations(uea); + ud.AddChild(new CSharpTokenNode(Convert(uea.Location), Roles.ExternKeyword), Roles.ExternKeyword); if (loc != null) - ud.AddChild (new CSharpTokenNode (Convert (loc [0])), Roles.AliasKeyword); - ud.AddChild (Identifier.Create (uea.Alias.Value, Convert (uea.Alias.Location)), Roles.Identifier); + ud.AddChild(new CSharpTokenNode(Convert(loc [0]), Roles.AliasKeyword), Roles.AliasKeyword); + ud.AddChild(Identifier.Create(uea.Alias.Value, Convert(uea.Alias.Location)), Roles.Identifier); if (loc != null && loc.Count > 1) - ud.AddChild (new CSharpTokenNode (Convert (loc [1])), Roles.Semicolon); - AddToNamespace (ud); + ud.AddChild(new CSharpTokenNode(Convert(loc [1]), Roles.Semicolon), Roles.Semicolon); + AddToNamespace(ud); } - AstType ConvertImport (MemberName memberName) + AstType ConvertImport(MemberName memberName) { if (memberName.Left != null) { // left.name - var t = new MemberType (); + var t = new MemberType(); // t.IsDoubleColon = memberName.IsDoubleColon; - t.AddChild (ConvertImport (memberName.Left), MemberType.TargetRole); - - if (!memberName.DotLocation.IsNull) - t.AddChild (new CSharpTokenNode (Convert (memberName.DotLocation)), Roles.Dot); + t.AddChild(ConvertImport(memberName.Left), MemberType.TargetRole); + var loc = LocationsBag.GetLocations(memberName); + if (loc != null) + t.AddChild(new CSharpTokenNode(Convert(loc [0]), Roles.Dot), Roles.Dot); - t.AddChild (Identifier.Create (memberName.Name, Convert (memberName.Location)), Roles.Identifier); - AddTypeArguments (t, memberName); + t.AddChild(Identifier.Create(memberName.Name, Convert(memberName.Location)), Roles.Identifier); + AddTypeArguments(t, memberName); return t; } else { - SimpleType t = new SimpleType (); - t.AddChild (Identifier.Create (memberName.Name, Convert (memberName.Location)), Roles.Identifier); - AddTypeArguments (t, memberName); + var t = new SimpleType(); + t.AddChild(Identifier.Create(memberName.Name, Convert(memberName.Location)), Roles.Identifier); + AddTypeArguments(t, memberName); return t; } } - - public override void Visit (MemberCore member) + + public override void Visit(MemberCore member) { - Console.WriteLine ("Unknown member:"); - Console.WriteLine (member.GetType () + "-> Member {0}", member.GetSignatureForError ()); + Console.WriteLine("Unknown member:"); + Console.WriteLine(member.GetType() + "-> Member {0}", member.GetSignatureForError()); } - - Stack typeStack = new Stack (); - + + readonly Stack typeStack = new Stack(); + public override void Visit(Class c) { - var newType = new TypeDeclaration (); + var newType = new TypeDeclaration(); newType.ClassType = ClassType.Class; AddAttributeSection(newType, c); - var location = LocationsBag.GetMemberLocation(c); AddModifiers(newType, location); int curLoc = 0; if (location != null && location.Count > 0) - newType.AddChild (new CSharpTokenNode (Convert (location [curLoc++])), Roles.ClassKeyword); + newType.AddChild(new CSharpTokenNode(Convert(location [curLoc++]), Roles.ClassKeyword), Roles.ClassKeyword); - newType.AddChild (Identifier.Create (c.MemberName.Name, Convert (c.MemberName.Location)), Roles.Identifier); - AddTypeParameters (newType, c.MemberName); + newType.AddChild(Identifier.Create(c.MemberName.Name, Convert(c.MemberName.Location)), Roles.Identifier); + AddTypeParameters(newType, c.MemberName); if (c.TypeBaseExpressions != null) { if (location != null && curLoc < location.Count) - newType.AddChild (new CSharpTokenNode (Convert (location [curLoc++])), Roles.Colon); + newType.AddChild(new CSharpTokenNode(Convert(location [curLoc++]), Roles.Colon), Roles.Colon); - var commaLocations = LocationsBag.GetLocations (c.TypeBaseExpressions); + var commaLocations = LocationsBag.GetLocations(c.TypeBaseExpressions); int i = 0; foreach (var baseTypes in c.TypeBaseExpressions) { - newType.AddChild (ConvertToType (baseTypes), Roles.BaseType); + newType.AddChild(ConvertToType(baseTypes), Roles.BaseType); if (commaLocations != null && i < commaLocations.Count) { - newType.AddChild (new CSharpTokenNode (Convert (commaLocations [i])), Roles.Comma); + newType.AddChild(new CSharpTokenNode(Convert(commaLocations [i]), Roles.Comma), Roles.Comma); i++; } } } - AddConstraints (newType, c.CurrentTypeParameters); + AddConstraints(newType, c.CurrentTypeParameters); if (location != null && curLoc < location.Count) - newType.AddChild (new CSharpTokenNode (Convert (location [curLoc++])), Roles.LBrace); - typeStack.Push (newType); - base.Visit (c); - AddAttributeSection (newType, c.UnattachedAttributes, EntityDeclaration.UnattachedAttributeRole); - + newType.AddChild(new CSharpTokenNode(Convert(location [curLoc++]), Roles.LBrace), Roles.LBrace); + typeStack.Push(newType); + base.Visit(c); + AddAttributeSection(newType, c.UnattachedAttributes, EntityDeclaration.UnattachedAttributeRole); + if (location != null && curLoc < location.Count) { - newType.AddChild (new CSharpTokenNode (Convert (location [curLoc++])), Roles.RBrace); + newType.AddChild(new CSharpTokenNode(Convert(location [curLoc++]), Roles.RBrace), Roles.RBrace); if (location != null && curLoc < location.Count) - newType.AddChild (new CSharpTokenNode (Convert (location [curLoc++])), Roles.Semicolon); + newType.AddChild(new CSharpTokenNode(Convert(location [curLoc++]), Roles.Semicolon), Roles.Semicolon); } else { // parser error, set end node to max value. - newType.AddChild (new ErrorNode (), Roles.Error); + newType.AddChild(new ErrorNode(), Roles.Error); } - typeStack.Pop (); - AddType (newType); + typeStack.Pop(); + AddType(newType); } - + public override void Visit(Struct s) { var newType = new TypeDeclaration(); @@ -549,42 +559,42 @@ namespace ICSharpCode.NRefactory.CSharp AddModifiers(newType, location); int curLoc = 0; if (location != null && location.Count > 0) - newType.AddChild (new CSharpTokenNode (Convert (location [curLoc++])), Roles.StructKeyword); - newType.AddChild (Identifier.Create (s.MemberName.Name, Convert (s.MemberName.Location)), Roles.Identifier); - AddTypeParameters (newType, s.MemberName); + newType.AddChild(new CSharpTokenNode(Convert(location [curLoc++]), Roles.StructKeyword), Roles.StructKeyword); + newType.AddChild(Identifier.Create(s.MemberName.Name, Convert(s.MemberName.Location)), Roles.Identifier); + AddTypeParameters(newType, s.MemberName); if (s.TypeBaseExpressions != null) { if (location != null && curLoc < location.Count) - newType.AddChild (new CSharpTokenNode (Convert (location [curLoc++])), Roles.Colon); - var commaLocations = LocationsBag.GetLocations (s.TypeBaseExpressions); + newType.AddChild(new CSharpTokenNode(Convert(location [curLoc++]), Roles.Colon), Roles.Colon); + var commaLocations = LocationsBag.GetLocations(s.TypeBaseExpressions); int i = 0; foreach (var baseTypes in s.TypeBaseExpressions) { - newType.AddChild (ConvertToType (baseTypes), Roles.BaseType); + newType.AddChild(ConvertToType(baseTypes), Roles.BaseType); if (commaLocations != null && i < commaLocations.Count) { - newType.AddChild (new CSharpTokenNode (Convert (commaLocations [i])), Roles.Comma); + newType.AddChild(new CSharpTokenNode(Convert(commaLocations [i]), Roles.Comma), Roles.Comma); i++; } } } - AddConstraints (newType, s.CurrentTypeParameters); + AddConstraints(newType, s.CurrentTypeParameters); if (location != null && curLoc < location.Count) - newType.AddChild (new CSharpTokenNode (Convert (location [curLoc++])), Roles.LBrace); - typeStack.Push (newType); - base.Visit (s); + newType.AddChild(new CSharpTokenNode(Convert(location [curLoc++]), Roles.LBrace), Roles.LBrace); + typeStack.Push(newType); + base.Visit(s); if (location != null && location.Count > 2) { if (location != null && curLoc < location.Count) - newType.AddChild (new CSharpTokenNode (Convert (location [curLoc++])), Roles.RBrace); + newType.AddChild(new CSharpTokenNode(Convert(location [curLoc++]), Roles.RBrace), Roles.RBrace); if (location != null && curLoc < location.Count) - newType.AddChild (new CSharpTokenNode (Convert (location [curLoc++])), Roles.Semicolon); + newType.AddChild(new CSharpTokenNode(Convert(location [curLoc++]), Roles.Semicolon), Roles.Semicolon); } else { // parser error, set end node to max value. - newType.AddChild (new ErrorNode (), Roles.Error); + newType.AddChild(new ErrorNode(), Roles.Error); } - typeStack.Pop (); - AddType (newType); + typeStack.Pop(); + AddType(newType); } - + public override void Visit(Interface i) { var newType = new TypeDeclaration(); @@ -594,88 +604,88 @@ namespace ICSharpCode.NRefactory.CSharp AddModifiers(newType, location); int curLoc = 0; if (location != null && location.Count > 0) - newType.AddChild (new CSharpTokenNode (Convert (location [curLoc++])), Roles.InterfaceKeyword); - newType.AddChild (Identifier.Create (i.MemberName.Name, Convert (i.MemberName.Location)), Roles.Identifier); - AddTypeParameters (newType, i.MemberName); + newType.AddChild(new CSharpTokenNode(Convert(location [curLoc++]), Roles.InterfaceKeyword), Roles.InterfaceKeyword); + newType.AddChild(Identifier.Create(i.MemberName.Name, Convert(i.MemberName.Location)), Roles.Identifier); + AddTypeParameters(newType, i.MemberName); if (i.TypeBaseExpressions != null) { if (location != null && curLoc < location.Count) - newType.AddChild (new CSharpTokenNode (Convert (location [curLoc++])), Roles.Colon); - var commaLocations = LocationsBag.GetLocations (i.TypeBaseExpressions); + newType.AddChild(new CSharpTokenNode(Convert(location [curLoc++]), Roles.Colon), Roles.Colon); + var commaLocations = LocationsBag.GetLocations(i.TypeBaseExpressions); int j = 0; foreach (var baseTypes in i.TypeBaseExpressions) { - newType.AddChild (ConvertToType (baseTypes), Roles.BaseType); + newType.AddChild(ConvertToType(baseTypes), Roles.BaseType); if (commaLocations != null && j < commaLocations.Count) { - newType.AddChild (new CSharpTokenNode (Convert (commaLocations [j])), Roles.Comma); + newType.AddChild(new CSharpTokenNode(Convert(commaLocations [j]), Roles.Comma), Roles.Comma); j++; } } } - AddConstraints (newType, i.CurrentTypeParameters); + AddConstraints(newType, i.CurrentTypeParameters); if (location != null && curLoc < location.Count) - newType.AddChild (new CSharpTokenNode (Convert (location [curLoc++])), Roles.LBrace); - typeStack.Push (newType); - base.Visit (i); + newType.AddChild(new CSharpTokenNode(Convert(location [curLoc++]), Roles.LBrace), Roles.LBrace); + typeStack.Push(newType); + base.Visit(i); if (location != null && location.Count > 2) { if (location != null && curLoc < location.Count) - newType.AddChild (new CSharpTokenNode (Convert (location [curLoc++])), Roles.RBrace); + newType.AddChild(new CSharpTokenNode(Convert(location [curLoc++]), Roles.RBrace), Roles.RBrace); if (location != null && curLoc < location.Count) - newType.AddChild (new CSharpTokenNode (Convert (location [curLoc++])), Roles.Semicolon); + newType.AddChild(new CSharpTokenNode(Convert(location [curLoc++]), Roles.Semicolon), Roles.Semicolon); } else { // parser error, set end node to max value. - newType.AddChild (new ErrorNode (), Roles.Error); + newType.AddChild(new ErrorNode(), Roles.Error); } - typeStack.Pop (); - AddType (newType); + typeStack.Pop(); + AddType(newType); } - + public override void Visit(Mono.CSharp.Delegate d) { - DelegateDeclaration newDelegate = new DelegateDeclaration (); + var newDelegate = new DelegateDeclaration(); var location = LocationsBag.GetMemberLocation(d); AddAttributeSection(newDelegate, d); AddModifiers(newDelegate, location); if (location != null && location.Count > 0) { - newDelegate.AddChild(new CSharpTokenNode (Convert(location [0])), Roles.DelegateKeyword); + newDelegate.AddChild(new CSharpTokenNode(Convert(location [0]), Roles.DelegateKeyword), Roles.DelegateKeyword); } if (d.ReturnType != null) - newDelegate.AddChild (ConvertToType (d.ReturnType), Roles.Type); - newDelegate.AddChild (Identifier.Create (d.MemberName.Name, Convert (d.MemberName.Location)), Roles.Identifier); - AddTypeParameters (newDelegate, d.MemberName); + newDelegate.AddChild(ConvertToType(d.ReturnType), Roles.Type); + newDelegate.AddChild(Identifier.Create(d.MemberName.Name, Convert(d.MemberName.Location)), Roles.Identifier); + AddTypeParameters(newDelegate, d.MemberName); if (location != null && location.Count > 1) - newDelegate.AddChild (new CSharpTokenNode (Convert (location [1])), Roles.LPar); - AddParameter (newDelegate, d.Parameters); + newDelegate.AddChild(new CSharpTokenNode(Convert(location [1]), Roles.LPar), Roles.LPar); + AddParameter(newDelegate, d.Parameters); if (location != null && location.Count > 2) { - newDelegate.AddChild (new CSharpTokenNode (Convert (location [2])), Roles.RPar); + newDelegate.AddChild(new CSharpTokenNode(Convert(location [2]), Roles.RPar), Roles.RPar); } - AddConstraints (newDelegate, d.CurrentTypeParameters); + AddConstraints(newDelegate, d.CurrentTypeParameters); if (location != null && location.Count > 3) { - newDelegate.AddChild (new CSharpTokenNode (Convert (location [3])), Roles.Semicolon); + newDelegate.AddChild(new CSharpTokenNode(Convert(location [3]), Roles.Semicolon), Roles.Semicolon); } - AddType (newDelegate); + AddType(newDelegate); } - - void AddType (EntityDeclaration child) + + void AddType(EntityDeclaration child) { if (typeStack.Count > 0) { - typeStack.Peek ().AddChild (child, Roles.TypeMemberRole); + typeStack.Peek().AddChild(child, Roles.TypeMemberRole); } else { - AddToNamespace (child); + AddToNamespace(child); } } - - void AddToNamespace (AstNode child) + + void AddToNamespace(AstNode child) { if (namespaceStack.Count > 0) { - namespaceStack.Peek ().AddChild (child, NamespaceDeclaration.MemberRole); + namespaceStack.Peek().AddChild(child, NamespaceDeclaration.MemberRole); } else { - unit.AddChild (child, SyntaxTree.MemberRole); + unit.AddChild(child, SyntaxTree.MemberRole); } } - + public override void Visit(Mono.CSharp.Enum e) { var newType = new TypeDeclaration(); @@ -686,110 +696,109 @@ namespace ICSharpCode.NRefactory.CSharp AddModifiers(newType, location); int curLoc = 0; if (location != null && location.Count > 0) - newType.AddChild(new CSharpTokenNode(Convert(location [curLoc++])), Roles.EnumKeyword); + newType.AddChild(new CSharpTokenNode(Convert(location [curLoc++]), Roles.EnumKeyword), Roles.EnumKeyword); newType.AddChild(Identifier.Create(e.MemberName.Name, Convert(e.MemberName.Location)), Roles.Identifier); if (e.BaseTypeExpression != null) { if (location != null && curLoc < location.Count) - newType.AddChild(new CSharpTokenNode(Convert(location [curLoc++])), Roles.Colon); + newType.AddChild(new CSharpTokenNode(Convert(location [curLoc++]), Roles.Colon), Roles.Colon); newType.AddChild(ConvertToType(e.BaseTypeExpression), Roles.BaseType); } if (location != null && curLoc < location.Count) - newType.AddChild(new CSharpTokenNode(Convert(location [curLoc++])), Roles.LBrace); + newType.AddChild(new CSharpTokenNode(Convert(location [curLoc++]), Roles.LBrace), Roles.LBrace); typeStack.Push(newType); foreach (var m in e.Members) { - EnumMember member = m as EnumMember; + var member = m as EnumMember; if (member == null) { Console.WriteLine("WARNING - ENUM MEMBER: " + m); continue; } Visit(member); if (location != null && curLoc < location.Count - 1) //last one is closing brace - newType.AddChild(new CSharpTokenNode(Convert(location [curLoc++])), Roles.Comma); + newType.AddChild(new CSharpTokenNode(Convert(location [curLoc++]), Roles.Comma), Roles.Comma); } if (location != null && location.Count > 2) { if (location != null && curLoc < location.Count) - newType.AddChild (new CSharpTokenNode (Convert (location [curLoc++])), Roles.RBrace); + newType.AddChild(new CSharpTokenNode(Convert(location [curLoc++]), Roles.RBrace), Roles.RBrace); if (location != null && curLoc < location.Count) - newType.AddChild (new CSharpTokenNode (Convert (location [curLoc++])), Roles.Semicolon); + newType.AddChild(new CSharpTokenNode(Convert(location [curLoc++]), Roles.Semicolon), Roles.Semicolon); } else { // parser error, set end node to max value. - newType.AddChild (new ErrorNode (), Roles.Error); + newType.AddChild(new ErrorNode(), Roles.Error); } - typeStack.Pop (); - AddType (newType); + + AddAttributeSection(newType, e.UnattachedAttributes, EntityDeclaration.UnattachedAttributeRole); + typeStack.Pop(); + AddType(newType); } - - public override void Visit (EnumMember em) + + public override void Visit(EnumMember em) { - EnumMemberDeclaration newField = new EnumMemberDeclaration (); - AddAttributeSection (newField, em); - newField.AddChild (Identifier.Create (em.Name, Convert (em.Location)), Roles.Identifier); + var newField = new EnumMemberDeclaration(); + AddAttributeSection(newField, em); + newField.AddChild(Identifier.Create(em.Name, Convert(em.Location)), Roles.Identifier); if (em.Initializer != null) { - newField.AddChild (new CSharpTokenNode (Convert (em.Initializer.Location)), Roles.Assign); - newField.AddChild ((Expression)em.Initializer.Accept (this), EnumMemberDeclaration.InitializerRole); + newField.AddChild(new CSharpTokenNode(Convert(em.Initializer.Location), Roles.Assign), Roles.Assign); + newField.AddChild((Expression)em.Initializer.Accept(this), EnumMemberDeclaration.InitializerRole); } //Console.WriteLine (newField.StartLocation +"-" + newField.EndLocation); - typeStack.Peek ().AddChild (newField, Roles.TypeMemberRole); + typeStack.Peek().AddChild(newField, Roles.TypeMemberRole); } + #endregion - + #region Type members - - - public override void Visit (FixedField f) + + public override void Visit(FixedField f) { - var location = LocationsBag.GetMemberLocation (f); + var location = LocationsBag.GetMemberLocation(f); int locationIdx = 0; - var newField = new FixedFieldDeclaration (); - AddAttributeSection (newField, f); - AddModifiers (newField, location); + var newField = new FixedFieldDeclaration(); + AddAttributeSection(newField, f); + AddModifiers(newField, location); if (location != null && location.Count > 0) - newField.AddChild (new CSharpTokenNode (Convert (location [locationIdx++])), FixedFieldDeclaration.FixedKeywordRole); + newField.AddChild(new CSharpTokenNode(Convert(location [locationIdx++]), FixedFieldDeclaration.FixedKeywordRole), FixedFieldDeclaration.FixedKeywordRole); if (f.TypeExpression != null) - newField.AddChild (ConvertToType (f.TypeExpression), Roles.Type); + newField.AddChild(ConvertToType(f.TypeExpression), Roles.Type); - var variable = new FixedVariableInitializer (); - variable.AddChild (Identifier.Create (f.MemberName.Name, Convert (f.MemberName.Location)), Roles.Identifier); + var variable = new FixedVariableInitializer(); + variable.AddChild(Identifier.Create(f.MemberName.Name, Convert(f.MemberName.Location)), Roles.Identifier); if (f.Initializer != null && !f.Initializer.IsNull) { - var bracketLocations = LocationsBag.GetLocations (f.Initializer); - if (bracketLocations != null && bracketLocations.Count > 1) - variable.AddChild (new CSharpTokenNode (Convert (bracketLocations [0])), Roles.LBracket); + variable.AddChild(new CSharpTokenNode(Convert(f.Initializer.Location), Roles.LBracket), Roles.LBracket); - variable.AddChild ((Expression)f.Initializer.Accept (this), Roles.Expression); - if (bracketLocations != null && bracketLocations.Count > 1) - variable.AddChild (new CSharpTokenNode (Convert (bracketLocations [0])), Roles.RBracket); + variable.AddChild((Expression)f.Initializer.Accept(this), Roles.Expression); + var bracketLocations = LocationsBag.GetLocations(f.Initializer); + if (bracketLocations != null) + variable.AddChild(new CSharpTokenNode(Convert(bracketLocations [0]), Roles.RBracket), Roles.RBracket); } - newField.AddChild (variable, FixedFieldDeclaration.VariableRole); + newField.AddChild(variable, FixedFieldDeclaration.VariableRole); if (f.Declarators != null) { foreach (var decl in f.Declarators) { - var declLoc = LocationsBag.GetLocations (decl); + var declLoc = LocationsBag.GetLocations(decl); if (declLoc != null) - newField.AddChild (new CSharpTokenNode (Convert (declLoc [0])), Roles.Comma); + newField.AddChild(new CSharpTokenNode(Convert(declLoc [0]), Roles.Comma), Roles.Comma); - variable = new FixedVariableInitializer (); - variable.AddChild (Identifier.Create (decl.Name.Value, Convert (decl.Name.Location)), Roles.Identifier); - if (!decl.Initializer.IsNull) { - var bracketLocations = LocationsBag.GetLocations (f.Initializer); - if (bracketLocations != null && bracketLocations.Count > 1) - variable.AddChild (new CSharpTokenNode (Convert (bracketLocations [0])), Roles.LBracket); - variable.AddChild ((Expression)decl.Initializer.Accept (this), Roles.Expression); - if (bracketLocations != null && bracketLocations.Count > 1) - variable.AddChild (new CSharpTokenNode (Convert (bracketLocations [0])), Roles.RBracket); - } - newField.AddChild (variable, FixedFieldDeclaration.VariableRole); + variable = new FixedVariableInitializer(); + variable.AddChild(Identifier.Create(decl.Name.Value, Convert(decl.Name.Location)), Roles.Identifier); + variable.AddChild(new CSharpTokenNode(Convert(decl.Initializer.Location), Roles.LBracket), Roles.LBracket); + variable.AddChild((Expression)decl.Initializer.Accept(this), Roles.Expression); + var bracketLocations = LocationsBag.GetLocations(decl.Initializer); + if (bracketLocations != null) + variable.AddChild(new CSharpTokenNode(Convert(bracketLocations [0]), Roles.RBracket), Roles.RBracket); + + newField.AddChild(variable, FixedFieldDeclaration.VariableRole); } } if (location != null && location.Count > locationIdx) - newField.AddChild (new CSharpTokenNode (Convert (location [locationIdx])), Roles.Semicolon); - typeStack.Peek ().AddChild (newField, Roles.TypeMemberRole); + newField.AddChild(new CSharpTokenNode(Convert(location [locationIdx]), Roles.Semicolon), Roles.Semicolon); + typeStack.Peek().AddChild(newField, Roles.TypeMemberRole); } @@ -797,275 +806,280 @@ namespace ICSharpCode.NRefactory.CSharp { var location = LocationsBag.GetMemberLocation(f); - FieldDeclaration newField = new FieldDeclaration (); - AddAttributeSection (newField, f); - AddModifiers (newField, location); - newField.AddChild (ConvertToType (f.TypeExpression), Roles.Type); + var newField = new FieldDeclaration(); + AddAttributeSection(newField, f); + AddModifiers(newField, location); + newField.AddChild(ConvertToType(f.TypeExpression), Roles.Type); - VariableInitializer variable = new VariableInitializer (); - variable.AddChild (Identifier.Create (f.MemberName.Name, Convert (f.MemberName.Location)), Roles.Identifier); + var variable = new VariableInitializer(); + variable.AddChild(Identifier.Create(f.MemberName.Name, Convert(f.MemberName.Location)), Roles.Identifier); int locationIdx = 0; if (f.Initializer != null) { if (location != null) - variable.AddChild (new CSharpTokenNode (Convert (location [locationIdx++])), Roles.Assign); - variable.AddChild ((Expression)f.Initializer.Accept (this), Roles.Expression); + variable.AddChild(new CSharpTokenNode(Convert(location [locationIdx++]), Roles.Assign), Roles.Assign); + variable.AddChild((Expression)f.Initializer.Accept(this), Roles.Expression); } - newField.AddChild (variable, Roles.Variable); + newField.AddChild(variable, Roles.Variable); if (f.Declarators != null) { foreach (var decl in f.Declarators) { - var declLoc = LocationsBag.GetLocations (decl); + var declLoc = LocationsBag.GetLocations(decl); if (declLoc != null) - newField.AddChild (new CSharpTokenNode (Convert (declLoc [0])), Roles.Comma); + newField.AddChild(new CSharpTokenNode(Convert(declLoc [0]), Roles.Comma), Roles.Comma); - variable = new VariableInitializer (); - variable.AddChild (Identifier.Create (decl.Name.Value, Convert (decl.Name.Location)), Roles.Identifier); + variable = new VariableInitializer(); + variable.AddChild(Identifier.Create(decl.Name.Value, Convert(decl.Name.Location)), Roles.Identifier); if (decl.Initializer != null) { if (declLoc != null) - variable.AddChild (new CSharpTokenNode (Convert (declLoc [1])), Roles.Assign); - variable.AddChild ((Expression)decl.Initializer.Accept (this), Roles.Expression); + variable.AddChild(new CSharpTokenNode(Convert(declLoc [1]), Roles.Assign), Roles.Assign); + variable.AddChild((Expression)decl.Initializer.Accept(this), Roles.Expression); } - newField.AddChild (variable, Roles.Variable); + newField.AddChild(variable, Roles.Variable); } } - if (location != null &&location.Count > locationIdx) - newField.AddChild (new CSharpTokenNode (Convert (location [locationIdx++])), Roles.Semicolon); + if (location != null && location.Count > locationIdx) + newField.AddChild(new CSharpTokenNode(Convert(location [locationIdx++]), Roles.Semicolon), Roles.Semicolon); - typeStack.Peek ().AddChild (newField, Roles.TypeMemberRole); + typeStack.Peek().AddChild(newField, Roles.TypeMemberRole); } - - public override void Visit (Const f) + + public override void Visit(Const c) { - var location = LocationsBag.GetMemberLocation (f); + var location = LocationsBag.GetMemberLocation(c); - FieldDeclaration newField = new FieldDeclaration (); - AddAttributeSection (newField, f); - AddModifiers (newField, location); + var newField = new FieldDeclaration(); + AddAttributeSection(newField, c); + AddModifiers(newField, location); if (location != null) - newField.AddChild (new CSharpModifierToken (Convert (location [0]), Modifiers.Const), EntityDeclaration.ModifierRole); - newField.AddChild (ConvertToType (f.TypeExpression), Roles.Type); + newField.AddChild(new CSharpModifierToken(Convert(location [0]), Modifiers.Const), EntityDeclaration.ModifierRole); + newField.AddChild(ConvertToType(c.TypeExpression), Roles.Type); - VariableInitializer variable = new VariableInitializer (); - variable.AddChild (Identifier.Create (f.MemberName.Name, Convert (f.MemberName.Location)), Roles.Identifier); + var variable = new VariableInitializer(); + variable.AddChild(Identifier.Create(c.MemberName.Name, Convert(c.MemberName.Location)), Roles.Identifier); - if (f.Initializer != null) { - variable.AddChild (new CSharpTokenNode (Convert (f.Initializer.Location)), Roles.Assign); - variable.AddChild ((Expression)f.Initializer.Accept (this), Roles.Expression); + if (c.Initializer != null) { + variable.AddChild(new CSharpTokenNode(Convert(c.Initializer.Location), Roles.Assign), Roles.Assign); + variable.AddChild((Expression)c.Initializer.Accept(this), Roles.Expression); } - newField.AddChild (variable, Roles.Variable); - if (f.Declarators != null) { - foreach (var decl in f.Declarators) { - var declLoc = LocationsBag.GetLocations (decl); + newField.AddChild(variable, Roles.Variable); + if (c.Declarators != null) { + foreach (var decl in c.Declarators) { + var declLoc = LocationsBag.GetLocations(decl); if (declLoc != null) - newField.AddChild (new CSharpTokenNode (Convert (declLoc [0])), Roles.Comma); + newField.AddChild(new CSharpTokenNode(Convert(declLoc [0]), Roles.Comma), Roles.Comma); - variable = new VariableInitializer (); - variable.AddChild (Identifier.Create (decl.Name.Value, Convert (decl.Name.Location)), Roles.Identifier); + variable = new VariableInitializer(); + variable.AddChild(Identifier.Create(decl.Name.Value, Convert(decl.Name.Location)), Roles.Identifier); if (decl.Initializer != null) { - variable.AddChild (new CSharpTokenNode (Convert (decl.Initializer.Location)), Roles.Assign); - variable.AddChild ((Expression)decl.Initializer.Accept (this), Roles.Expression); + variable.AddChild(new CSharpTokenNode(Convert(decl.Initializer.Location), Roles.Assign), Roles.Assign); + variable.AddChild((Expression)decl.Initializer.Accept(this), Roles.Expression); } - newField.AddChild (variable, Roles.Variable); + newField.AddChild(variable, Roles.Variable); } } if (location != null) - newField.AddChild (new CSharpTokenNode (Convert (location [1])), Roles.Semicolon); + newField.AddChild(new CSharpTokenNode(Convert(location [1]), Roles.Semicolon), Roles.Semicolon); - typeStack.Peek ().AddChild (newField, Roles.TypeMemberRole); + typeStack.Peek().AddChild(newField, Roles.TypeMemberRole); } - - public override void Visit (Operator o) + + public override void Visit(Operator o) { - OperatorDeclaration newOperator = new OperatorDeclaration (); + var newOperator = new OperatorDeclaration(); newOperator.OperatorType = (OperatorType)o.OperatorType; - var location = LocationsBag.GetMemberLocation (o); - AddAttributeSection (newOperator, o); - AddModifiers (newOperator, location); + var location = LocationsBag.GetMemberLocation(o); + AddAttributeSection(newOperator, o); + AddModifiers(newOperator, location); if (o.OperatorType == Operator.OpType.Implicit) { if (location != null && location.Count > 0) { - newOperator.AddChild (new CSharpTokenNode (Convert (location [0])), OperatorDeclaration.ImplicitRole); + newOperator.AddChild(new CSharpTokenNode(Convert(location [0]), OperatorDeclaration.ImplicitRole), OperatorDeclaration.ImplicitRole); if (location.Count > 1) - newOperator.AddChild (new CSharpTokenNode (Convert (location [1])), OperatorDeclaration.OperatorKeywordRole); + newOperator.AddChild(new CSharpTokenNode(Convert(location [1]), OperatorDeclaration.OperatorKeywordRole), OperatorDeclaration.OperatorKeywordRole); } - newOperator.AddChild (ConvertToType (o.TypeExpression), Roles.Type); + newOperator.AddChild(ConvertToType(o.TypeExpression), Roles.Type); } else if (o.OperatorType == Operator.OpType.Explicit) { if (location != null && location.Count > 0) { - newOperator.AddChild (new CSharpTokenNode (Convert (location [0])), OperatorDeclaration.ExplicitRole); + newOperator.AddChild(new CSharpTokenNode(Convert(location [0]), OperatorDeclaration.ExplicitRole), OperatorDeclaration.ExplicitRole); if (location.Count > 1) - newOperator.AddChild (new CSharpTokenNode (Convert (location [1])), OperatorDeclaration.OperatorKeywordRole); + newOperator.AddChild(new CSharpTokenNode(Convert(location [1]), OperatorDeclaration.OperatorKeywordRole), OperatorDeclaration.OperatorKeywordRole); } - newOperator.AddChild (ConvertToType (o.TypeExpression), Roles.Type); + newOperator.AddChild(ConvertToType(o.TypeExpression), Roles.Type); } else { - newOperator.AddChild (ConvertToType (o.TypeExpression), Roles.Type); + newOperator.AddChild(ConvertToType(o.TypeExpression), Roles.Type); if (location != null && location.Count > 0) - newOperator.AddChild (new CSharpTokenNode (Convert (location [0])), OperatorDeclaration.OperatorKeywordRole); + newOperator.AddChild(new CSharpTokenNode(Convert(location [0]), OperatorDeclaration.OperatorKeywordRole), OperatorDeclaration.OperatorKeywordRole); - if (location != null && location.Count > 1) - newOperator.AddChild (new CSharpTokenNode (Convert (location [1])), OperatorDeclaration.GetRole (newOperator.OperatorType)); + if (location != null && location.Count > 1) { + var r = OperatorDeclaration.GetRole(newOperator.OperatorType); + newOperator.AddChild(new CSharpTokenNode(Convert(location [1]), r), r); + } } if (location != null && location.Count > 2) - newOperator.AddChild (new CSharpTokenNode (Convert (location [2])), Roles.LPar); - AddParameter (newOperator, o.ParameterInfo); + newOperator.AddChild(new CSharpTokenNode(Convert(location [2]), Roles.LPar), Roles.LPar); + AddParameter(newOperator, o.ParameterInfo); if (location != null && location.Count > 3) - newOperator.AddChild (new CSharpTokenNode (Convert (location [3])), Roles.RPar); + newOperator.AddChild(new CSharpTokenNode(Convert(location [3]), Roles.RPar), Roles.RPar); if (o.Block != null) { - newOperator.AddChild ((BlockStatement)o.Block.Accept (this), Roles.Body); + newOperator.AddChild((BlockStatement)o.Block.Accept(this), Roles.Body); } else { if (location != null && location.Count >= 5) - newOperator.AddChild (new CSharpTokenNode (Convert (location [4])), Roles.Semicolon); + newOperator.AddChild(new CSharpTokenNode(Convert(location [4]), Roles.Semicolon), Roles.Semicolon); } - typeStack.Peek ().AddChild (newOperator, Roles.TypeMemberRole); + typeStack.Peek().AddChild(newOperator, Roles.TypeMemberRole); } - - public void AddAttributeSection (AstNode parent, Attributable a) + + public void AddAttributeSection(AstNode parent, Attributable a) { if (a == null || a.OptAttributes == null) return; - AddAttributeSection (parent, a.OptAttributes); + AddAttributeSection(parent, a.OptAttributes); } - - public void AddAttributeSection (AstNode parent, Attributes attrs, Role role) + + public void AddAttributeSection(AstNode parent, Attributes attrs, Role role) { if (attrs == null) return; foreach (var attr in attrs.Sections) { - parent.AddChild (ConvertAttributeSection (attr), EntityDeclaration.AttributeRole); + var section = ConvertAttributeSection(attr); + if (section == null) + continue; + parent.AddChild(section, role); } } - public void AddAttributeSection (AstNode parent, Attributes attrs) + public void AddAttributeSection(AstNode parent, Attributes attrs) { - AddAttributeSection (parent, attrs, EntityDeclaration.AttributeRole); + AddAttributeSection(parent, attrs, EntityDeclaration.AttributeRole); } - - public override void Visit (Indexer indexer) + + public override void Visit(Indexer i) { - IndexerDeclaration newIndexer = new IndexerDeclaration (); - AddAttributeSection (newIndexer, indexer); - var location = LocationsBag.GetMemberLocation (indexer); - AddModifiers (newIndexer, location); - newIndexer.AddChild (ConvertToType (indexer.TypeExpression), Roles.Type); - AddExplicitInterface (newIndexer, indexer.MemberName); - var name = indexer.MemberName; - newIndexer.AddChild (Identifier.Create ("this", Convert (name.Location)), Roles.Identifier); + var newIndexer = new IndexerDeclaration(); + AddAttributeSection(newIndexer, i); + var location = LocationsBag.GetMemberLocation(i); + AddModifiers(newIndexer, location); + newIndexer.AddChild(ConvertToType(i.TypeExpression), Roles.Type); + AddExplicitInterface(newIndexer, i.MemberName); + var name = i.MemberName; + newIndexer.AddChild(new CSharpTokenNode(Convert(name.Location), IndexerDeclaration.ThisKeywordRole), IndexerDeclaration.ThisKeywordRole); if (location != null && location.Count > 0) - newIndexer.AddChild (new CSharpTokenNode (Convert (location [0])), Roles.LBracket); - AddParameter (newIndexer, indexer.ParameterInfo); + newIndexer.AddChild(new CSharpTokenNode(Convert(location [0]), Roles.LBracket), Roles.LBracket); + AddParameter(newIndexer, i.ParameterInfo); if (location != null && location.Count > 1) - newIndexer.AddChild (new CSharpTokenNode (Convert (location [1])), Roles.RBracket); + newIndexer.AddChild(new CSharpTokenNode(Convert(location [1]), Roles.RBracket), Roles.RBracket); if (location != null && location.Count > 2) - newIndexer.AddChild (new CSharpTokenNode (Convert (location [2])), Roles.LBrace); - if (indexer.Get != null) { - Accessor getAccessor = new Accessor (); - var getLocation = LocationsBag.GetMemberLocation (indexer.Get); - AddAttributeSection (getAccessor, indexer.Get); - AddModifiers (getAccessor, getLocation); + newIndexer.AddChild(new CSharpTokenNode(Convert(location [2]), Roles.LBrace), Roles.LBrace); + if (i.Get != null) { + var getAccessor = new Accessor(); + var getLocation = LocationsBag.GetMemberLocation(i.Get); + AddAttributeSection(getAccessor, i.Get); + AddModifiers(getAccessor, getLocation); if (getLocation != null) - getAccessor.AddChild (new CSharpTokenNode (Convert (indexer.Get.Location)), PropertyDeclaration.GetKeywordRole); - if (indexer.Get.Block != null) { - getAccessor.AddChild ((BlockStatement)indexer.Get.Block.Accept (this), Roles.Body); + getAccessor.AddChild(new CSharpTokenNode(Convert(i.Get.Location), PropertyDeclaration.GetKeywordRole), PropertyDeclaration.GetKeywordRole); + if (i.Get.Block != null) { + getAccessor.AddChild((BlockStatement)i.Get.Block.Accept(this), Roles.Body); } else { if (getLocation != null && getLocation.Count > 0) - newIndexer.AddChild (new CSharpTokenNode (Convert (getLocation [0])), Roles.Semicolon); + newIndexer.AddChild(new CSharpTokenNode(Convert(getLocation [0]), Roles.Semicolon), Roles.Semicolon); } - newIndexer.AddChild (getAccessor, PropertyDeclaration.GetterRole); + newIndexer.AddChild(getAccessor, PropertyDeclaration.GetterRole); } - if (indexer.Set != null) { - Accessor setAccessor = new Accessor (); - var setLocation = LocationsBag.GetMemberLocation (indexer.Set); - AddAttributeSection (setAccessor, indexer.Set); - AddModifiers (setAccessor, setLocation); + if (i.Set != null) { + var setAccessor = new Accessor(); + var setLocation = LocationsBag.GetMemberLocation(i.Set); + AddAttributeSection(setAccessor, i.Set); + AddModifiers(setAccessor, setLocation); if (setLocation != null) - setAccessor.AddChild (new CSharpTokenNode (Convert (indexer.Set.Location)), PropertyDeclaration.SetKeywordRole); + setAccessor.AddChild(new CSharpTokenNode(Convert(i.Set.Location), PropertyDeclaration.SetKeywordRole), PropertyDeclaration.SetKeywordRole); - if (indexer.Set.Block != null) { - setAccessor.AddChild ((BlockStatement)indexer.Set.Block.Accept (this), Roles.Body); + if (i.Set.Block != null) { + setAccessor.AddChild((BlockStatement)i.Set.Block.Accept(this), Roles.Body); } else { if (setLocation != null && setLocation.Count > 0) - newIndexer.AddChild (new CSharpTokenNode (Convert (setLocation [0])), Roles.Semicolon); + newIndexer.AddChild(new CSharpTokenNode(Convert(setLocation [0]), Roles.Semicolon), Roles.Semicolon); } - newIndexer.AddChild (setAccessor, PropertyDeclaration.SetterRole); + newIndexer.AddChild(setAccessor, PropertyDeclaration.SetterRole); } if (location != null) { if (location.Count > 3) - newIndexer.AddChild (new CSharpTokenNode (Convert (location [3])), Roles.RBrace); + newIndexer.AddChild(new CSharpTokenNode(Convert(location [3]), Roles.RBrace), Roles.RBrace); } else { // parser error, set end node to max value. - newIndexer.AddChild (new ErrorNode (), Roles.Error); + newIndexer.AddChild(new ErrorNode(), Roles.Error); } - typeStack.Peek ().AddChild (newIndexer, Roles.TypeMemberRole); + typeStack.Peek().AddChild(newIndexer, Roles.TypeMemberRole); } - - public override void Visit (Method m) + + public override void Visit(Method m) { - MethodDeclaration newMethod = new MethodDeclaration (); - AddAttributeSection (newMethod, m); - var location = LocationsBag.GetMemberLocation (m); - AddModifiers (newMethod, location); - newMethod.AddChild (ConvertToType (m.TypeExpression), Roles.Type); - AddExplicitInterface (newMethod, m.MethodName); - newMethod.AddChild (Identifier.Create (m.MethodName.Name, Convert (m.Location)), Roles.Identifier); + var newMethod = new MethodDeclaration(); + AddAttributeSection(newMethod, m); + var location = LocationsBag.GetMemberLocation(m); + AddModifiers(newMethod, location); + newMethod.AddChild(ConvertToType(m.TypeExpression), Roles.Type); + AddExplicitInterface(newMethod, m.MethodName); + newMethod.AddChild(Identifier.Create(m.MethodName.Name, Convert(m.Location)), Roles.Identifier); - AddTypeParameters (newMethod, m.MemberName); + AddTypeParameters(newMethod, m.MemberName); if (location != null && location.Count > 0) - newMethod.AddChild (new CSharpTokenNode (Convert (location [0])), Roles.LPar); - AddParameter (newMethod, m.ParameterInfo); + newMethod.AddChild(new CSharpTokenNode(Convert(location [0]), Roles.LPar), Roles.LPar); + AddParameter(newMethod, m.ParameterInfo); if (location != null && location.Count > 1) - newMethod.AddChild (new CSharpTokenNode (Convert (location [1])), Roles.RPar); + newMethod.AddChild(new CSharpTokenNode(Convert(location [1]), Roles.RPar), Roles.RPar); - AddConstraints (newMethod, m.CurrentTypeParameters); + AddConstraints(newMethod, m.CurrentTypeParameters); if (m.Block != null) { - var bodyBlock = (BlockStatement)m.Block.Accept (this); + var bodyBlock = (BlockStatement)m.Block.Accept(this); // if (m.Block is ToplevelBlock) { // newMethod.AddChild (bodyBlock.FirstChild.NextSibling, Roles.Body); // } else { - newMethod.AddChild (bodyBlock, Roles.Body); + newMethod.AddChild(bodyBlock, Roles.Body); // } } else if (location != null) { if (location.Count < 3) { // parser error, set end node to max value. - newMethod.AddChild (new ErrorNode (), Roles.Error); + newMethod.AddChild(new ErrorNode(), Roles.Error); } else { - newMethod.AddChild (new CSharpTokenNode (Convert (location [2])), Roles.Semicolon); + newMethod.AddChild(new CSharpTokenNode(Convert(location [2]), Roles.Semicolon), Roles.Semicolon); } } - typeStack.Peek ().AddChild (newMethod, Roles.TypeMemberRole); + typeStack.Peek().AddChild(newMethod, Roles.TypeMemberRole); } - - static Dictionary modifierTable = new Dictionary (); - static string[] keywordTable; - - static ConversionVisitor () - { - modifierTable [Mono.CSharp.Modifiers.NEW] = ICSharpCode.NRefactory.CSharp.Modifiers.New; - modifierTable [Mono.CSharp.Modifiers.PUBLIC] = ICSharpCode.NRefactory.CSharp.Modifiers.Public; - modifierTable [Mono.CSharp.Modifiers.PROTECTED] = ICSharpCode.NRefactory.CSharp.Modifiers.Protected; - modifierTable [Mono.CSharp.Modifiers.PRIVATE] = ICSharpCode.NRefactory.CSharp.Modifiers.Private; - modifierTable [Mono.CSharp.Modifiers.INTERNAL] = ICSharpCode.NRefactory.CSharp.Modifiers.Internal; - modifierTable [Mono.CSharp.Modifiers.ABSTRACT] = ICSharpCode.NRefactory.CSharp.Modifiers.Abstract; - modifierTable [Mono.CSharp.Modifiers.VIRTUAL] = ICSharpCode.NRefactory.CSharp.Modifiers.Virtual; - modifierTable [Mono.CSharp.Modifiers.SEALED] = ICSharpCode.NRefactory.CSharp.Modifiers.Sealed; - modifierTable [Mono.CSharp.Modifiers.STATIC] = ICSharpCode.NRefactory.CSharp.Modifiers.Static; - modifierTable [Mono.CSharp.Modifiers.OVERRIDE] = ICSharpCode.NRefactory.CSharp.Modifiers.Override; - modifierTable [Mono.CSharp.Modifiers.READONLY] = ICSharpCode.NRefactory.CSharp.Modifiers.Readonly; - modifierTable [Mono.CSharp.Modifiers.PARTIAL] = ICSharpCode.NRefactory.CSharp.Modifiers.Partial; - modifierTable [Mono.CSharp.Modifiers.EXTERN] = ICSharpCode.NRefactory.CSharp.Modifiers.Extern; - modifierTable [Mono.CSharp.Modifiers.VOLATILE] = ICSharpCode.NRefactory.CSharp.Modifiers.Volatile; - modifierTable [Mono.CSharp.Modifiers.UNSAFE] = ICSharpCode.NRefactory.CSharp.Modifiers.Unsafe; - modifierTable [Mono.CSharp.Modifiers.ASYNC] = ICSharpCode.NRefactory.CSharp.Modifiers.Async; + + static readonly Dictionary modifierTable = new Dictionary(); + static readonly string[] keywordTable; + + static ConversionVisitor() + { + modifierTable [Mono.CSharp.Modifiers.NEW] = Modifiers.New; + modifierTable [Mono.CSharp.Modifiers.PUBLIC] = Modifiers.Public; + modifierTable [Mono.CSharp.Modifiers.PROTECTED] = Modifiers.Protected; + modifierTable [Mono.CSharp.Modifiers.PRIVATE] = Modifiers.Private; + modifierTable [Mono.CSharp.Modifiers.INTERNAL] = Modifiers.Internal; + modifierTable [Mono.CSharp.Modifiers.ABSTRACT] = Modifiers.Abstract; + modifierTable [Mono.CSharp.Modifiers.VIRTUAL] = Modifiers.Virtual; + modifierTable [Mono.CSharp.Modifiers.SEALED] = Modifiers.Sealed; + modifierTable [Mono.CSharp.Modifiers.STATIC] = Modifiers.Static; + modifierTable [Mono.CSharp.Modifiers.OVERRIDE] = Modifiers.Override; + modifierTable [Mono.CSharp.Modifiers.READONLY] = Modifiers.Readonly; + modifierTable [Mono.CSharp.Modifiers.PARTIAL] = Modifiers.Partial; + modifierTable [Mono.CSharp.Modifiers.EXTERN] = Modifiers.Extern; + modifierTable [Mono.CSharp.Modifiers.VOLATILE] = Modifiers.Volatile; + modifierTable [Mono.CSharp.Modifiers.UNSAFE] = Modifiers.Unsafe; + modifierTable [Mono.CSharp.Modifiers.ASYNC] = Modifiers.Async; keywordTable = new string[255]; for (int i = 0; i< keywordTable.Length; i++) @@ -1088,675 +1102,674 @@ namespace ICSharpCode.NRefactory.CSharp keywordTable [(int)BuiltinTypeSpec.Type.Char] = "char"; keywordTable [(int)BuiltinTypeSpec.Type.Bool] = "bool"; } - - void AddModifiers (EntityDeclaration parent, LocationsBag.MemberLocations location) + + static void AddModifiers(EntityDeclaration parent, LocationsBag.MemberLocations location) { if (location == null || location.Modifiers == null) return; foreach (var modifier in location.Modifiers) { - ICSharpCode.NRefactory.CSharp.Modifiers mod; - if (!modifierTable.TryGetValue (modifier.Item1, out mod)) { - Console.WriteLine ("modifier " + modifier.Item1 + " can't be converted,"); + Modifiers mod; + if (!modifierTable.TryGetValue(modifier.Item1, out mod)) { + Console.WriteLine("modifier " + modifier.Item1 + " can't be converted,"); } - parent.AddChild (new CSharpModifierToken (Convert (modifier.Item2), mod), EntityDeclaration.ModifierRole); + parent.AddChild(new CSharpModifierToken(Convert(modifier.Item2), mod), EntityDeclaration.ModifierRole); } } - - public override void Visit (Property p) + + public override void Visit(Property p) { - PropertyDeclaration newProperty = new PropertyDeclaration (); - AddAttributeSection (newProperty, p); - var location = LocationsBag.GetMemberLocation (p); - AddModifiers (newProperty, location); - newProperty.AddChild (ConvertToType (p.TypeExpression), Roles.Type); - AddExplicitInterface (newProperty, p.MemberName); - newProperty.AddChild (Identifier.Create (p.MemberName.Name, Convert (p.Location)), Roles.Identifier); + var newProperty = new PropertyDeclaration(); + AddAttributeSection(newProperty, p); + var location = LocationsBag.GetMemberLocation(p); + AddModifiers(newProperty, location); + newProperty.AddChild(ConvertToType(p.TypeExpression), Roles.Type); + AddExplicitInterface(newProperty, p.MemberName); + newProperty.AddChild(Identifier.Create(p.MemberName.Name, Convert(p.Location)), Roles.Identifier); if (location != null && location.Count > 0) - newProperty.AddChild (new CSharpTokenNode (Convert (location [0])), Roles.LBrace); + newProperty.AddChild(new CSharpTokenNode(Convert(location [0]), Roles.LBrace), Roles.LBrace); Accessor getAccessor = null; if (p.Get != null) { - getAccessor = new Accessor (); - AddAttributeSection (getAccessor, p.Get); - var getLocation = LocationsBag.GetMemberLocation (p.Get); - AddModifiers (getAccessor, getLocation); - getAccessor.AddChild (new CSharpTokenNode (Convert (p.Get.Location)), PropertyDeclaration.GetKeywordRole); + getAccessor = new Accessor(); + AddAttributeSection(getAccessor, p.Get); + var getLocation = LocationsBag.GetMemberLocation(p.Get); + AddModifiers(getAccessor, getLocation); + getAccessor.AddChild(new CSharpTokenNode(Convert(p.Get.Location), PropertyDeclaration.GetKeywordRole), PropertyDeclaration.GetKeywordRole); if (p.Get.Block != null) { - getAccessor.AddChild ((BlockStatement)p.Get.Block.Accept (this), Roles.Body); + getAccessor.AddChild((BlockStatement)p.Get.Block.Accept(this), Roles.Body); } else { if (getLocation != null && getLocation.Count > 0) - getAccessor.AddChild (new CSharpTokenNode (Convert (getLocation [0])), Roles.Semicolon); + getAccessor.AddChild(new CSharpTokenNode(Convert(getLocation [0]), Roles.Semicolon), Roles.Semicolon); } } Accessor setAccessor = null; if (p.Set != null) { - setAccessor = new Accessor (); - AddAttributeSection (setAccessor, p.Set); - var setLocation = LocationsBag.GetMemberLocation (p.Set); - AddModifiers (setAccessor, setLocation); - setAccessor.AddChild (new CSharpTokenNode (Convert (p.Set.Location)), PropertyDeclaration.SetKeywordRole); + setAccessor = new Accessor(); + AddAttributeSection(setAccessor, p.Set); + var setLocation = LocationsBag.GetMemberLocation(p.Set); + AddModifiers(setAccessor, setLocation); + setAccessor.AddChild(new CSharpTokenNode(Convert(p.Set.Location), PropertyDeclaration.SetKeywordRole), PropertyDeclaration.SetKeywordRole); if (p.Set.Block != null) { - setAccessor.AddChild ((BlockStatement)p.Set.Block.Accept (this), Roles.Body); + setAccessor.AddChild((BlockStatement)p.Set.Block.Accept(this), Roles.Body); } else { if (setLocation != null && setLocation.Count > 0) - setAccessor.AddChild (new CSharpTokenNode (Convert (setLocation [0])), Roles.Semicolon); + setAccessor.AddChild(new CSharpTokenNode(Convert(setLocation [0]), Roles.Semicolon), Roles.Semicolon); } } if (getAccessor != null && setAccessor != null) { if (getAccessor.StartLocation < setAccessor.StartLocation) { - newProperty.AddChild (getAccessor, PropertyDeclaration.GetterRole); - newProperty.AddChild (setAccessor, PropertyDeclaration.SetterRole); + newProperty.AddChild(getAccessor, PropertyDeclaration.GetterRole); + newProperty.AddChild(setAccessor, PropertyDeclaration.SetterRole); } else { - newProperty.AddChild (setAccessor, PropertyDeclaration.SetterRole); - newProperty.AddChild (getAccessor, PropertyDeclaration.GetterRole); + newProperty.AddChild(setAccessor, PropertyDeclaration.SetterRole); + newProperty.AddChild(getAccessor, PropertyDeclaration.GetterRole); } } else { if (getAccessor != null) - newProperty.AddChild (getAccessor, PropertyDeclaration.GetterRole); + newProperty.AddChild(getAccessor, PropertyDeclaration.GetterRole); if (setAccessor != null) - newProperty.AddChild (setAccessor, PropertyDeclaration.SetterRole); + newProperty.AddChild(setAccessor, PropertyDeclaration.SetterRole); } if (location != null && location.Count > 1) { - newProperty.AddChild (new CSharpTokenNode (Convert (location [1])), Roles.RBrace); + newProperty.AddChild(new CSharpTokenNode(Convert(location [1]), Roles.RBrace), Roles.RBrace); } else { // parser error, set end node to max value. - newProperty.AddChild (new ErrorNode (), Roles.Error); + newProperty.AddChild(new ErrorNode(), Roles.Error); } - typeStack.Peek ().AddChild (newProperty, Roles.TypeMemberRole); + typeStack.Peek().AddChild(newProperty, Roles.TypeMemberRole); } - - public override void Visit (Constructor c) + + public override void Visit(Constructor c) { - ConstructorDeclaration newConstructor = new ConstructorDeclaration (); - AddAttributeSection (newConstructor, c); - var location = LocationsBag.GetMemberLocation (c); - AddModifiers (newConstructor, location); - newConstructor.AddChild (Identifier.Create (c.MemberName.Name, Convert (c.MemberName.Location)), Roles.Identifier); + var newConstructor = new ConstructorDeclaration(); + AddAttributeSection(newConstructor, c); + var location = LocationsBag.GetMemberLocation(c); + AddModifiers(newConstructor, location); + newConstructor.AddChild(Identifier.Create(c.MemberName.Name, Convert(c.MemberName.Location)), Roles.Identifier); if (location != null && location.Count > 0) - newConstructor.AddChild (new CSharpTokenNode (Convert (location [0])), Roles.LPar); + newConstructor.AddChild(new CSharpTokenNode(Convert(location [0]), Roles.LPar), Roles.LPar); - AddParameter (newConstructor, c.ParameterInfo); + AddParameter(newConstructor, c.ParameterInfo); if (location != null && location.Count > 1) - newConstructor.AddChild (new CSharpTokenNode (Convert (location [1])), Roles.RPar); + newConstructor.AddChild(new CSharpTokenNode(Convert(location [1]), Roles.RPar), Roles.RPar); if (c.Initializer != null) { - var initializer = new ConstructorInitializer (); + var initializer = new ConstructorInitializer(); initializer.ConstructorInitializerType = c.Initializer is ConstructorBaseInitializer ? ConstructorInitializerType.Base : ConstructorInitializerType.This; - var initializerLocation = LocationsBag.GetLocations (c.Initializer); + var initializerLocation = LocationsBag.GetLocations(c.Initializer); if (initializerLocation != null) - newConstructor.AddChild (new CSharpTokenNode (Convert (initializerLocation [0])), Roles.Colon); + newConstructor.AddChild(new CSharpTokenNode(Convert(initializerLocation [0]), Roles.Colon), Roles.Colon); if (initializerLocation != null && initializerLocation.Count > 1) { // this and base has the same length - initializer.AddChild (new CSharpTokenNode (Convert (c.Initializer.Location)), initializer.ConstructorInitializerType == ConstructorInitializerType.This ? ConstructorInitializer.ThisKeywordRole : ConstructorInitializer.BaseKeywordRole); - initializer.AddChild (new CSharpTokenNode (Convert (initializerLocation [1])), Roles.LPar); - AddArguments (initializer, LocationsBag.GetLocations (c.Initializer.Arguments), c.Initializer.Arguments); - initializer.AddChild (new CSharpTokenNode (Convert (initializerLocation [2])), Roles.RPar); - newConstructor.AddChild (initializer, ConstructorDeclaration.InitializerRole); + var r = initializer.ConstructorInitializerType == ConstructorInitializerType.This ? ConstructorInitializer.ThisKeywordRole : ConstructorInitializer.BaseKeywordRole; + initializer.AddChild(new CSharpTokenNode(Convert(c.Initializer.Location), r), r); + initializer.AddChild(new CSharpTokenNode(Convert(initializerLocation [1]), Roles.LPar), Roles.LPar); + AddArguments(initializer, c.Initializer.Arguments); + initializer.AddChild(new CSharpTokenNode(Convert(initializerLocation [2]), Roles.RPar), Roles.RPar); + newConstructor.AddChild(initializer, ConstructorDeclaration.InitializerRole); } } if (c.Block != null) - newConstructor.AddChild ((BlockStatement)c.Block.Accept (this), Roles.Body); - typeStack.Peek ().AddChild (newConstructor, Roles.TypeMemberRole); + newConstructor.AddChild((BlockStatement)c.Block.Accept(this), Roles.Body); + typeStack.Peek().AddChild(newConstructor, Roles.TypeMemberRole); } - - public override void Visit (Destructor d) + + public override void Visit(Destructor d) { - DestructorDeclaration newDestructor = new DestructorDeclaration (); - AddAttributeSection (newDestructor, d); - var location = LocationsBag.GetMemberLocation (d); - AddModifiers (newDestructor, location); + var newDestructor = new DestructorDeclaration(); + AddAttributeSection(newDestructor, d); + var location = LocationsBag.GetMemberLocation(d); + AddModifiers(newDestructor, location); if (location != null && location.Count > 0) - newDestructor.AddChild (new CSharpTokenNode (Convert (location [0])), DestructorDeclaration.TildeRole); - newDestructor.AddChild (Identifier.Create (d.Identifier, Convert (d.MemberName.Location)), Roles.Identifier); + newDestructor.AddChild(new CSharpTokenNode(Convert(location [0]), DestructorDeclaration.TildeRole), DestructorDeclaration.TildeRole); + newDestructor.AddChild(Identifier.Create(d.Identifier, Convert(d.MemberName.Location)), Roles.Identifier); if (location != null && location.Count > 1) { - newDestructor.AddChild (new CSharpTokenNode (Convert (location [1])), Roles.LPar); + newDestructor.AddChild(new CSharpTokenNode(Convert(location [1]), Roles.LPar), Roles.LPar); if (location.Count > 2) - newDestructor.AddChild (new CSharpTokenNode (Convert (location [2])), Roles.RPar); + newDestructor.AddChild(new CSharpTokenNode(Convert(location [2]), Roles.RPar), Roles.RPar); } if (d.Block != null) - newDestructor.AddChild ((BlockStatement)d.Block.Accept (this), Roles.Body); + newDestructor.AddChild((BlockStatement)d.Block.Accept(this), Roles.Body); - typeStack.Peek ().AddChild (newDestructor, Roles.TypeMemberRole); + typeStack.Peek().AddChild(newDestructor, Roles.TypeMemberRole); } - - public override void Visit (EventField e) + + public override void Visit(EventField e) { - EventDeclaration newEvent = new EventDeclaration (); - AddAttributeSection (newEvent, e); - var location = LocationsBag.GetMemberLocation (e); - AddModifiers (newEvent, location); + var newEvent = new EventDeclaration(); + AddAttributeSection(newEvent, e); + var location = LocationsBag.GetMemberLocation(e); + int l = 0; + AddModifiers(newEvent, location); if (location != null && location.Count > 0) - newEvent.AddChild (new CSharpTokenNode (Convert (location [0])), EventDeclaration.EventKeywordRole); - newEvent.AddChild (ConvertToType (e.TypeExpression), Roles.Type); + newEvent.AddChild(new CSharpTokenNode(Convert(location [l++]), EventDeclaration.EventKeywordRole), EventDeclaration.EventKeywordRole); + newEvent.AddChild(ConvertToType(e.TypeExpression), Roles.Type); - VariableInitializer variable = new VariableInitializer (); - variable.AddChild (Identifier.Create (e.MemberName.Name, Convert (e.MemberName.Location)), Roles.Identifier); + var variable = new VariableInitializer(); + variable.AddChild(Identifier.Create(e.MemberName.Name, Convert(e.MemberName.Location)), Roles.Identifier); if (e.Initializer != null) { - if (location != null && location.Count > 0) - variable.AddChild (new CSharpTokenNode (Convert (location [0])), Roles.Assign); - variable.AddChild ((Expression)e.Initializer.Accept (this), Roles.Expression); + if (location != null && location.Count > l) + variable.AddChild(new CSharpTokenNode(Convert(location [l++]), Roles.Assign), Roles.Assign); + variable.AddChild((Expression)e.Initializer.Accept(this), Roles.Expression); } - newEvent.AddChild (variable, Roles.Variable); + newEvent.AddChild(variable, Roles.Variable); if (e.Declarators != null) { foreach (var decl in e.Declarators) { - var declLoc = LocationsBag.GetLocations (decl); + var declLoc = LocationsBag.GetLocations(decl); if (declLoc != null) - newEvent.AddChild (new CSharpTokenNode (Convert (declLoc [0])), Roles.Comma); + newEvent.AddChild(new CSharpTokenNode(Convert(declLoc [0]), Roles.Comma), Roles.Comma); - variable = new VariableInitializer (); - variable.AddChild (Identifier.Create (decl.Name.Value, Convert (decl.Name.Location)), Roles.Identifier); + variable = new VariableInitializer(); + variable.AddChild(Identifier.Create(decl.Name.Value, Convert(decl.Name.Location)), Roles.Identifier); if (decl.Initializer != null) { if (declLoc != null) - variable.AddChild (new CSharpTokenNode (Convert (declLoc [1])), Roles.Assign); - variable.AddChild ((Expression)decl.Initializer.Accept (this), Roles.Expression); + variable.AddChild(new CSharpTokenNode(Convert(declLoc [1]), Roles.Assign), Roles.Assign); + variable.AddChild((Expression)decl.Initializer.Accept(this), Roles.Expression); } - newEvent.AddChild (variable, Roles.Variable); + newEvent.AddChild(variable, Roles.Variable); } } - if (location != null && location.Count > 1) - newEvent.AddChild (new CSharpTokenNode (Convert (location [1])), Roles.Semicolon); + if (location != null && location.Count > l) + newEvent.AddChild(new CSharpTokenNode(Convert(location [l++]), Roles.Semicolon), Roles.Semicolon); - typeStack.Peek ().AddChild (newEvent, Roles.TypeMemberRole); + typeStack.Peek().AddChild(newEvent, Roles.TypeMemberRole); } - void AddExplicitInterface (AstNode parent, MemberName memberName) + void AddExplicitInterface(AstNode parent, MemberName memberName) { if (memberName == null || memberName.ExplicitInterface == null) return; - parent.AddChild (ConvertToType (memberName.ExplicitInterface), EntityDeclaration.PrivateImplementationTypeRole); - var privateImplTypeLoc = LocationsBag.GetLocations (memberName.ExplicitInterface); + parent.AddChild(ConvertToType(memberName.ExplicitInterface), EntityDeclaration.PrivateImplementationTypeRole); + var privateImplTypeLoc = LocationsBag.GetLocations(memberName.ExplicitInterface); if (privateImplTypeLoc != null) - parent.AddChild (new CSharpTokenNode (Convert (privateImplTypeLoc [0])), Roles.Dot); + parent.AddChild(new CSharpTokenNode(Convert(privateImplTypeLoc [0]), Roles.Dot), Roles.Dot); } - - public override void Visit (EventProperty ep) + + public override void Visit(EventProperty ep) { - CustomEventDeclaration newEvent = new CustomEventDeclaration (); - AddAttributeSection (newEvent, ep); - var location = LocationsBag.GetMemberLocation (ep); - AddModifiers (newEvent, location); + var newEvent = new CustomEventDeclaration(); + AddAttributeSection(newEvent, ep); + var location = LocationsBag.GetMemberLocation(ep); + AddModifiers(newEvent, location); if (location != null && location.Count > 0) - newEvent.AddChild (new CSharpTokenNode (Convert (location [0])), CustomEventDeclaration.EventKeywordRole); - newEvent.AddChild (ConvertToType (ep.TypeExpression), Roles.Type); + newEvent.AddChild(new CSharpTokenNode(Convert(location [0]), CustomEventDeclaration.EventKeywordRole), CustomEventDeclaration.EventKeywordRole); + newEvent.AddChild(ConvertToType(ep.TypeExpression), Roles.Type); - AddExplicitInterface (newEvent, ep.MemberName); + AddExplicitInterface(newEvent, ep.MemberName); - newEvent.AddChild (Identifier.Create (ep.MemberName.Name, Convert (ep.Location)), Roles.Identifier); + newEvent.AddChild(Identifier.Create(ep.MemberName.Name, Convert(ep.Location)), Roles.Identifier); if (location != null && location.Count >= 2) - newEvent.AddChild (new CSharpTokenNode (Convert (location [1])), Roles.LBrace); + newEvent.AddChild(new CSharpTokenNode(Convert(location [1]), Roles.LBrace), Roles.LBrace); if (ep.Add != null) { - Accessor addAccessor = new Accessor (); - AddAttributeSection (addAccessor, ep.Add); - var addLocation = LocationsBag.GetMemberLocation (ep.Add); - AddModifiers (addAccessor, addLocation); - addAccessor.AddChild (new CSharpTokenNode (Convert (ep.Add.Location)), CustomEventDeclaration.AddKeywordRole); + var addAccessor = new Accessor(); + AddAttributeSection(addAccessor, ep.Add); + var addLocation = LocationsBag.GetMemberLocation(ep.Add); + AddModifiers(addAccessor, addLocation); + addAccessor.AddChild(new CSharpTokenNode(Convert(ep.Add.Location), CustomEventDeclaration.AddKeywordRole), CustomEventDeclaration.AddKeywordRole); if (ep.Add.Block != null) - addAccessor.AddChild ((BlockStatement)ep.Add.Block.Accept (this), Roles.Body); - newEvent.AddChild (addAccessor, CustomEventDeclaration.AddAccessorRole); + addAccessor.AddChild((BlockStatement)ep.Add.Block.Accept(this), Roles.Body); + newEvent.AddChild(addAccessor, CustomEventDeclaration.AddAccessorRole); } if (ep.Remove != null) { - Accessor removeAccessor = new Accessor (); - AddAttributeSection (removeAccessor, ep.Remove); - var removeLocation = LocationsBag.GetMemberLocation (ep.Remove); - AddModifiers (removeAccessor, removeLocation); - removeAccessor.AddChild (new CSharpTokenNode (Convert (ep.Remove.Location)), CustomEventDeclaration.RemoveKeywordRole); + var removeAccessor = new Accessor(); + AddAttributeSection(removeAccessor, ep.Remove); + var removeLocation = LocationsBag.GetMemberLocation(ep.Remove); + AddModifiers(removeAccessor, removeLocation); + removeAccessor.AddChild(new CSharpTokenNode(Convert(ep.Remove.Location), CustomEventDeclaration.RemoveKeywordRole), CustomEventDeclaration.RemoveKeywordRole); if (ep.Remove.Block != null) - removeAccessor.AddChild ((BlockStatement)ep.Remove.Block.Accept (this), Roles.Body); - newEvent.AddChild (removeAccessor, CustomEventDeclaration.RemoveAccessorRole); + removeAccessor.AddChild((BlockStatement)ep.Remove.Block.Accept(this), Roles.Body); + newEvent.AddChild(removeAccessor, CustomEventDeclaration.RemoveAccessorRole); } if (location != null && location.Count >= 3) { - newEvent.AddChild (new CSharpTokenNode (Convert (location [2])), Roles.RBrace); + newEvent.AddChild(new CSharpTokenNode(Convert(location [2]), Roles.RBrace), Roles.RBrace); } else { // parser error, set end node to max value. - newEvent.AddChild (new ErrorNode (), Roles.Error); + newEvent.AddChild(new ErrorNode(), Roles.Error); } - typeStack.Peek ().AddChild (newEvent, Roles.TypeMemberRole); + typeStack.Peek().AddChild(newEvent, Roles.TypeMemberRole); } - + #endregion - + #region Statements - public override object Visit (Mono.CSharp.Statement stmt) + + public override object Visit(Mono.CSharp.Statement stmt) { - Console.WriteLine ("unknown statement:" + stmt); + Console.WriteLine("unknown statement:" + stmt); return null; } - - public override object Visit (BlockVariableDeclaration blockVariableDeclaration) + + public override object Visit(BlockVariable blockVariableDeclaration) { - var result = new VariableDeclarationStatement (); - result.AddChild (ConvertToType (blockVariableDeclaration.TypeExpression), Roles.Type); + var result = new VariableDeclarationStatement(); + result.AddChild(ConvertToType(blockVariableDeclaration.TypeExpression), Roles.Type); - var varInit = new VariableInitializer (); - var location = LocationsBag.GetLocations (blockVariableDeclaration); - varInit.AddChild (Identifier.Create (blockVariableDeclaration.Variable.Name, Convert (blockVariableDeclaration.Variable.Location)), Roles.Identifier); + var varInit = new VariableInitializer(); + var location = LocationsBag.GetLocations(blockVariableDeclaration); + varInit.AddChild(Identifier.Create(blockVariableDeclaration.Variable.Name, Convert(blockVariableDeclaration.Variable.Location)), Roles.Identifier); if (blockVariableDeclaration.Initializer != null) { if (location != null && location.Count > 0) - varInit.AddChild (new CSharpTokenNode (Convert (location [0])), Roles.Assign); - varInit.AddChild ((Expression)blockVariableDeclaration.Initializer.Accept (this), Roles.Expression); + varInit.AddChild(new CSharpTokenNode(Convert(location [0]), Roles.Assign), Roles.Assign); + varInit.AddChild((Expression)blockVariableDeclaration.Initializer.Accept(this), Roles.Expression); } - result.AddChild (varInit, Roles.Variable); + result.AddChild(varInit, Roles.Variable); if (blockVariableDeclaration.Declarators != null) { foreach (var decl in blockVariableDeclaration.Declarators) { - var loc = LocationsBag.GetLocations (decl); - var init = new VariableInitializer (); + var loc = LocationsBag.GetLocations(decl); + var init = new VariableInitializer(); if (loc != null && loc.Count > 0) - result.AddChild (new CSharpTokenNode (Convert (loc [0])), Roles.Comma); - init.AddChild (Identifier.Create (decl.Variable.Name, Convert (decl.Variable.Location)), Roles.Identifier); + result.AddChild(new CSharpTokenNode(Convert(loc [0]), Roles.Comma), Roles.Comma); + init.AddChild(Identifier.Create(decl.Variable.Name, Convert(decl.Variable.Location)), Roles.Identifier); if (decl.Initializer != null) { if (loc != null && loc.Count > 1) - init.AddChild (new CSharpTokenNode (Convert (loc [1])), Roles.Assign); - init.AddChild ((Expression)decl.Initializer.Accept (this), Roles.Expression); - } else { + init.AddChild(new CSharpTokenNode(Convert(loc [1]), Roles.Assign), Roles.Assign); + init.AddChild((Expression)decl.Initializer.Accept(this), Roles.Expression); } - result.AddChild (init, Roles.Variable); + result.AddChild(init, Roles.Variable); } } if (location != null && (blockVariableDeclaration.Initializer == null || location.Count > 1)) - result.AddChild (new CSharpTokenNode (Convert (location [location.Count - 1])), Roles.Semicolon); + result.AddChild(new CSharpTokenNode(Convert(location [location.Count - 1]), Roles.Semicolon), Roles.Semicolon); return result; } - - public override object Visit (BlockConstantDeclaration blockVariableDeclaration) + + public override object Visit(BlockConstant blockConstantDeclaration) { - var result = new VariableDeclarationStatement (); + var result = new VariableDeclarationStatement(); - var location = LocationsBag.GetLocations (blockVariableDeclaration); + var location = LocationsBag.GetLocations(blockConstantDeclaration); if (location != null && location.Count > 0) - result.AddChild (new CSharpModifierToken (Convert (location [0]), ICSharpCode.NRefactory.CSharp.Modifiers.Const), VariableDeclarationStatement.ModifierRole); + result.AddChild(new CSharpModifierToken(Convert(location [0]), Modifiers.Const), VariableDeclarationStatement.ModifierRole); - result.AddChild (ConvertToType (blockVariableDeclaration.TypeExpression), Roles.Type); + result.AddChild(ConvertToType(blockConstantDeclaration.TypeExpression), Roles.Type); - var varInit = new VariableInitializer (); - varInit.AddChild (Identifier.Create (blockVariableDeclaration.Variable.Name, Convert (blockVariableDeclaration.Variable.Location)), Roles.Identifier); - if (blockVariableDeclaration.Initializer != null) { + var varInit = new VariableInitializer(); + varInit.AddChild(Identifier.Create(blockConstantDeclaration.Variable.Name, Convert(blockConstantDeclaration.Variable.Location)), Roles.Identifier); + if (blockConstantDeclaration.Initializer != null) { if (location != null && location.Count > 1) - varInit.AddChild (new CSharpTokenNode (Convert (location [1])), Roles.Assign); - varInit.AddChild ((Expression)blockVariableDeclaration.Initializer.Accept (this), Roles.Expression); + varInit.AddChild(new CSharpTokenNode(Convert(location [1]), Roles.Assign), Roles.Assign); + varInit.AddChild((Expression)blockConstantDeclaration.Initializer.Accept(this), Roles.Expression); } - result.AddChild (varInit, Roles.Variable); + result.AddChild(varInit, Roles.Variable); - if (blockVariableDeclaration.Declarators != null) { - foreach (var decl in blockVariableDeclaration.Declarators) { - var loc = LocationsBag.GetLocations (decl); - var init = new VariableInitializer (); - init.AddChild (Identifier.Create (decl.Variable.Name, Convert (decl.Variable.Location)), Roles.Identifier); + if (blockConstantDeclaration.Declarators != null) { + foreach (var decl in blockConstantDeclaration.Declarators) { + var loc = LocationsBag.GetLocations(decl); + var init = new VariableInitializer(); + init.AddChild(Identifier.Create(decl.Variable.Name, Convert(decl.Variable.Location)), Roles.Identifier); if (decl.Initializer != null) { if (loc != null) - init.AddChild (new CSharpTokenNode (Convert (loc [0])), Roles.Assign); - init.AddChild ((Expression)decl.Initializer.Accept (this), Roles.Expression); + init.AddChild(new CSharpTokenNode(Convert(loc [0]), Roles.Assign), Roles.Assign); + init.AddChild((Expression)decl.Initializer.Accept(this), Roles.Expression); if (loc != null && loc.Count > 1) - result.AddChild (new CSharpTokenNode (Convert (loc [1])), Roles.Comma); + result.AddChild(new CSharpTokenNode(Convert(loc [1]), Roles.Comma), Roles.Comma); } else { if (loc != null && loc.Count > 0) - result.AddChild (new CSharpTokenNode (Convert (loc [0])), Roles.Comma); + result.AddChild(new CSharpTokenNode(Convert(loc [0]), Roles.Comma), Roles.Comma); } - result.AddChild (init, Roles.Variable); + result.AddChild(init, Roles.Variable); } } if (location != null) { - result.AddChild (new CSharpTokenNode (Convert (location [location.Count - 1])), Roles.Semicolon); + result.AddChild(new CSharpTokenNode(Convert(location [location.Count - 1]), Roles.Semicolon), Roles.Semicolon); } else { // parser error, set end node to max value. - result.AddChild (new ErrorNode (), Roles.Error); + result.AddChild(new ErrorNode(), Roles.Error); } return result; } - - public override object Visit (Mono.CSharp.EmptyStatement emptyStatement) + + public override object Visit(Mono.CSharp.EmptyStatement emptyStatement) { - var result = new EmptyStatement (); - result.Location = Convert (emptyStatement.loc); + var result = new EmptyStatement(); + result.Location = Convert(emptyStatement.loc); return result; } - - public override object Visit (Mono.CSharp.EmptyExpression emptyExpression) - { - return new ICSharpCode.NRefactory.CSharp.EmptyExpression (Convert (emptyExpression.Location)); - } - - public override object Visit (Mono.CSharp.ErrorExpression emptyExpression) + + public override object Visit(Mono.CSharp.ErrorExpression errorExpression) { - return new ICSharpCode.NRefactory.CSharp.ErrorExpression (Convert (emptyExpression.Location)); + return new ErrorExpression(Convert(errorExpression.Location)); } - - public override object Visit (EmptyExpressionStatement emptyExpressionStatement) + + public override object Visit(EmptyExpressionStatement emptyExpressionStatement) { - return new EmptyExpression (Convert (emptyExpressionStatement.Location)); + // Should never happen. + throw new NotSupportedException(); } - - public override object Visit (If ifStatement) + + public override object Visit(If ifStatement) { - var result = new IfElseStatement (); + var result = new IfElseStatement(); - var location = LocationsBag.GetLocations (ifStatement); + var location = LocationsBag.GetLocations(ifStatement); - result.AddChild (new CSharpTokenNode (Convert (ifStatement.loc)), IfElseStatement.IfKeywordRole); + result.AddChild(new CSharpTokenNode(Convert(ifStatement.loc), IfElseStatement.IfKeywordRole), IfElseStatement.IfKeywordRole); if (location != null) - result.AddChild (new CSharpTokenNode (Convert (location [0])), Roles.LPar); + result.AddChild(new CSharpTokenNode(Convert(location [0]), Roles.LPar), Roles.LPar); if (ifStatement.Expr != null) - result.AddChild ((Expression)ifStatement.Expr.Accept (this), Roles.Condition); + result.AddChild((Expression)ifStatement.Expr.Accept(this), Roles.Condition); if (location != null && location.Count > 1) - result.AddChild (new CSharpTokenNode (Convert (location [1])), Roles.RPar); + result.AddChild(new CSharpTokenNode(Convert(location [1]), Roles.RPar), Roles.RPar); if (ifStatement.TrueStatement != null) - result.AddChild ((Statement)ifStatement.TrueStatement.Accept (this), IfElseStatement.TrueRole); + result.AddChild((Statement)ifStatement.TrueStatement.Accept(this), IfElseStatement.TrueRole); if (ifStatement.FalseStatement != null) { if (location != null && location.Count > 2) - result.AddChild (new CSharpTokenNode (Convert (location [2])), IfElseStatement.ElseKeywordRole); - result.AddChild ((Statement)ifStatement.FalseStatement.Accept (this), IfElseStatement.FalseRole); + result.AddChild(new CSharpTokenNode(Convert(location [2]), IfElseStatement.ElseKeywordRole), IfElseStatement.ElseKeywordRole); + result.AddChild((Statement)ifStatement.FalseStatement.Accept(this), IfElseStatement.FalseRole); } return result; } - - public override object Visit (Do doStatement) + + public override object Visit(Do doStatement) { - var result = new DoWhileStatement (); - var location = LocationsBag.GetLocations (doStatement); - result.AddChild (new CSharpTokenNode (Convert (doStatement.loc)), DoWhileStatement.DoKeywordRole); - if (doStatement.EmbeddedStatement != null) - result.AddChild ((Statement)doStatement.EmbeddedStatement.Accept (this), Roles.EmbeddedStatement); + var result = new DoWhileStatement(); + var location = LocationsBag.GetLocations(doStatement); + result.AddChild(new CSharpTokenNode(Convert(doStatement.loc), DoWhileStatement.DoKeywordRole), DoWhileStatement.DoKeywordRole); + if (doStatement.Statement != null) + result.AddChild((Statement)doStatement.Statement.Accept(this), Roles.EmbeddedStatement); if (location != null) - result.AddChild (new CSharpTokenNode (Convert (location [0])), DoWhileStatement.WhileKeywordRole); + result.AddChild(new CSharpTokenNode(Convert(location [0]), DoWhileStatement.WhileKeywordRole), DoWhileStatement.WhileKeywordRole); if (location != null && location.Count > 1) - result.AddChild (new CSharpTokenNode (Convert (location [1])), Roles.LPar); + result.AddChild(new CSharpTokenNode(Convert(location [1]), Roles.LPar), Roles.LPar); if (doStatement.expr != null) - result.AddChild ((Expression)doStatement.expr.Accept (this), Roles.Condition); + result.AddChild((Expression)doStatement.expr.Accept(this), Roles.Condition); if (location != null && location.Count > 2) { - result.AddChild (new CSharpTokenNode (Convert (location [2])), Roles.RPar); + result.AddChild(new CSharpTokenNode(Convert(location [2]), Roles.RPar), Roles.RPar); if (location.Count > 3) - result.AddChild (new CSharpTokenNode (Convert (location [3])), Roles.Semicolon); + result.AddChild(new CSharpTokenNode(Convert(location [3]), Roles.Semicolon), Roles.Semicolon); } return result; } - - public override object Visit (While whileStatement) + + public override object Visit(While whileStatement) { - var result = new WhileStatement (); - var location = LocationsBag.GetLocations (whileStatement); - result.AddChild (new CSharpTokenNode (Convert (whileStatement.loc)), WhileStatement.WhileKeywordRole); + var result = new WhileStatement(); + var location = LocationsBag.GetLocations(whileStatement); + result.AddChild(new CSharpTokenNode(Convert(whileStatement.loc), WhileStatement.WhileKeywordRole), WhileStatement.WhileKeywordRole); if (location != null) - result.AddChild (new CSharpTokenNode (Convert (location [0])), Roles.LPar); + result.AddChild(new CSharpTokenNode(Convert(location [0]), Roles.LPar), Roles.LPar); if (whileStatement.expr != null) - result.AddChild ((Expression)whileStatement.expr.Accept (this), Roles.Condition); + result.AddChild((Expression)whileStatement.expr.Accept(this), Roles.Condition); if (location != null && location.Count > 1) - result.AddChild (new CSharpTokenNode (Convert (location [1])), Roles.RPar); + result.AddChild(new CSharpTokenNode(Convert(location [1]), Roles.RPar), Roles.RPar); if (whileStatement.Statement != null) - result.AddChild ((Statement)whileStatement.Statement.Accept (this), Roles.EmbeddedStatement); + result.AddChild((Statement)whileStatement.Statement.Accept(this), Roles.EmbeddedStatement); return result; } - - void AddStatementOrList (ForStatement forStatement, Mono.CSharp.Statement init, Role role) + + void AddStatementOrList(ForStatement forStatement, Mono.CSharp.Statement init, Role role) { if (init == null) return; - if (init is StatementList) { - foreach (var stmt in ((StatementList)init).Statements) { - forStatement.AddChild ((Statement)stmt.Accept (this), role); + var stmtList = init as StatementList; + if (stmtList != null) { + foreach (var stmt in stmtList.Statements) { + forStatement.AddChild((Statement)stmt.Accept(this), role); } } else if (init is Mono.CSharp.EmptyStatement) { } else { - forStatement.AddChild ((Statement)init.Accept (this), role); + forStatement.AddChild((Statement)init.Accept(this), role); } } - public override object Visit (For forStatement) + public override object Visit(For forStatement) { - var result = new ForStatement (); + var result = new ForStatement(); - var location = LocationsBag.GetLocations (forStatement); + var location = LocationsBag.GetLocations(forStatement); - result.AddChild (new CSharpTokenNode (Convert (forStatement.loc)), ForStatement.ForKeywordRole); + result.AddChild(new CSharpTokenNode(Convert(forStatement.loc), ForStatement.ForKeywordRole), ForStatement.ForKeywordRole); if (location != null) - result.AddChild (new CSharpTokenNode (Convert (location [0])), Roles.LPar); + result.AddChild(new CSharpTokenNode(Convert(location [0]), Roles.LPar), Roles.LPar); - AddStatementOrList (result, forStatement.Initializer, ForStatement.InitializerRole); + AddStatementOrList(result, forStatement.Initializer, ForStatement.InitializerRole); if (location != null && location.Count > 1) - result.AddChild (new CSharpTokenNode (Convert (location [1])), Roles.Semicolon); + result.AddChild(new CSharpTokenNode(Convert(location [1]), Roles.Semicolon), Roles.Semicolon); if (forStatement.Condition != null) - result.AddChild ((Expression)forStatement.Condition.Accept (this), Roles.Condition); + result.AddChild((Expression)forStatement.Condition.Accept(this), Roles.Condition); if (location != null && location.Count >= 3) - result.AddChild (new CSharpTokenNode (Convert (location [2])), Roles.Semicolon); + result.AddChild(new CSharpTokenNode(Convert(location [2]), Roles.Semicolon), Roles.Semicolon); - AddStatementOrList (result, forStatement.Iterator, ForStatement.IteratorRole); + AddStatementOrList(result, forStatement.Iterator, ForStatement.IteratorRole); if (location != null && location.Count >= 4) - result.AddChild (new CSharpTokenNode (Convert (location [3])), Roles.RPar); + result.AddChild(new CSharpTokenNode(Convert(location [3]), Roles.RPar), Roles.RPar); if (forStatement.Statement != null) - result.AddChild ((Statement)forStatement.Statement.Accept (this), Roles.EmbeddedStatement); + result.AddChild((Statement)forStatement.Statement.Accept(this), Roles.EmbeddedStatement); return result; } - - public override object Visit (StatementExpression statementExpression) + + public override object Visit(StatementExpression statementExpression) { - var result = new ExpressionStatement (); - var expr = statementExpression.Expr.Accept (this) as Expression; + var result = new ExpressionStatement(); + var expr = statementExpression.Expr.Accept(this) as Expression; if (expr != null) - result.AddChild ((Expression)expr, Roles.Expression); - var location = LocationsBag.GetLocations (statementExpression); + result.AddChild(expr, Roles.Expression); + var location = LocationsBag.GetLocations(statementExpression); if (location != null) - result.AddChild (new CSharpTokenNode (Convert (location [0])), Roles.Semicolon); + result.AddChild(new CSharpTokenNode(Convert(location [0]), Roles.Semicolon), Roles.Semicolon); return result; } - - public override object Visit (StatementErrorExpression statementErrorExpression) + + public override object Visit(StatementErrorExpression errorStatement) { - var result = new ExpressionStatement (); - var expr = statementErrorExpression.Expr.Accept (this) as Expression; + var result = new ExpressionStatement(); + var expr = errorStatement.Expr.Accept(this) as Expression; if (expr != null) - result.AddChild ((Expression)expr, Roles.Expression); - var location = LocationsBag.GetLocations (statementErrorExpression); + result.AddChild(expr, Roles.Expression); + var location = LocationsBag.GetLocations(errorStatement); if (location != null) - result.AddChild (new CSharpTokenNode (Convert (location [0])), Roles.Semicolon); + result.AddChild(new CSharpTokenNode(Convert(location [0]), Roles.Semicolon), Roles.Semicolon); return result; } - - public override object Visit (InvalidStatementExpression statementExpression) + + public override object Visit(InvalidStatementExpression invalidStatementExpression) { - var result = new ExpressionStatement (); - if (statementExpression.Expression == null) + var result = new ExpressionStatement(); + if (invalidStatementExpression.Expression == null) return result; - var expr = statementExpression.Expression.Accept (this) as Expression; + var expr = invalidStatementExpression.Expression.Accept(this) as Expression; if (expr != null) - result.AddChild (expr, Roles.Expression); - var location = LocationsBag.GetLocations (statementExpression); + result.AddChild(expr, Roles.Expression); + var location = LocationsBag.GetLocations(invalidStatementExpression); if (location != null) - result.AddChild (new CSharpTokenNode (Convert (location [0])), Roles.Semicolon); + result.AddChild(new CSharpTokenNode(Convert(location [0]), Roles.Semicolon), Roles.Semicolon); return result; } - - public override object Visit (Return returnStatement) + + public override object Visit(Return returnStatement) { - var result = new ReturnStatement (); + var result = new ReturnStatement(); - result.AddChild (new CSharpTokenNode (Convert (returnStatement.loc)), ReturnStatement.ReturnKeywordRole); + result.AddChild(new CSharpTokenNode(Convert(returnStatement.loc), ReturnStatement.ReturnKeywordRole), ReturnStatement.ReturnKeywordRole); if (returnStatement.Expr != null) - result.AddChild ((Expression)returnStatement.Expr.Accept (this), Roles.Expression); + result.AddChild((Expression)returnStatement.Expr.Accept(this), Roles.Expression); - var location = LocationsBag.GetLocations (returnStatement); + var location = LocationsBag.GetLocations(returnStatement); if (location != null) - result.AddChild (new CSharpTokenNode (Convert (location [0])), Roles.Semicolon); + result.AddChild(new CSharpTokenNode(Convert(location [0]), Roles.Semicolon), Roles.Semicolon); return result; } - - public override object Visit (Goto gotoStatement) + + public override object Visit(Goto gotoStatement) { - var result = new GotoStatement (); - var location = LocationsBag.GetLocations (gotoStatement); - result.AddChild (new CSharpTokenNode (Convert (gotoStatement.loc)), GotoStatement.GotoKeywordRole); - var loc = location != null ? Convert (location [0]) : TextLocation.Empty; - result.AddChild (Identifier.Create (gotoStatement.Target, loc), Roles.Identifier); + var result = new GotoStatement(); + var location = LocationsBag.GetLocations(gotoStatement); + result.AddChild(new CSharpTokenNode(Convert(gotoStatement.loc), GotoStatement.GotoKeywordRole), GotoStatement.GotoKeywordRole); + var loc = location != null ? Convert(location [0]) : TextLocation.Empty; + result.AddChild(Identifier.Create(gotoStatement.Target, loc), Roles.Identifier); if (location != null && location.Count > 1) - result.AddChild (new CSharpTokenNode (Convert (location [1])), Roles.Semicolon); + result.AddChild(new CSharpTokenNode(Convert(location [1]), Roles.Semicolon), Roles.Semicolon); return result; } - - public override object Visit (LabeledStatement labeledStatement) + + public override object Visit(LabeledStatement labeledStatement) { - var result = new LabelStatement (); - result.AddChild (Identifier.Create (labeledStatement.Name, Convert (labeledStatement.loc)), Roles.Identifier); - var location = LocationsBag.GetLocations (labeledStatement); + var result = new LabelStatement(); + result.AddChild(Identifier.Create(labeledStatement.Name, Convert(labeledStatement.loc)), Roles.Identifier); + var location = LocationsBag.GetLocations(labeledStatement); if (location != null) - result.AddChild (new CSharpTokenNode (Convert (location [0])), Roles.Colon); + result.AddChild(new CSharpTokenNode(Convert(location [0]), Roles.Colon), Roles.Colon); return result; } - - public override object Visit (GotoDefault gotoDefault) + + public override object Visit(GotoDefault gotoDefault) { - var result = new GotoDefaultStatement (); - result.AddChild (new CSharpTokenNode (Convert (gotoDefault.loc)), GotoDefaultStatement.GotoKeywordRole); - var location = LocationsBag.GetLocations (gotoDefault); + var result = new GotoDefaultStatement(); + result.AddChild(new CSharpTokenNode(Convert(gotoDefault.loc), GotoDefaultStatement.GotoKeywordRole), GotoDefaultStatement.GotoKeywordRole); + var location = LocationsBag.GetLocations(gotoDefault); if (location != null) { - result.AddChild (new CSharpTokenNode (Convert (location [0])), GotoDefaultStatement.DefaultKeywordRole); + result.AddChild(new CSharpTokenNode(Convert(location [0]), GotoDefaultStatement.DefaultKeywordRole), GotoDefaultStatement.DefaultKeywordRole); if (location.Count > 1) - result.AddChild (new CSharpTokenNode (Convert (location [1])), Roles.Semicolon); + result.AddChild(new CSharpTokenNode(Convert(location [1]), Roles.Semicolon), Roles.Semicolon); } return result; } - - public override object Visit (GotoCase gotoCase) + + public override object Visit(GotoCase gotoCase) { - var result = new GotoCaseStatement (); - result.AddChild (new CSharpTokenNode (Convert (gotoCase.loc)), GotoCaseStatement.GotoKeywordRole); + var result = new GotoCaseStatement(); + result.AddChild(new CSharpTokenNode(Convert(gotoCase.loc), GotoCaseStatement.GotoKeywordRole), GotoCaseStatement.GotoKeywordRole); - var location = LocationsBag.GetLocations (gotoCase); + var location = LocationsBag.GetLocations(gotoCase); if (location != null) - result.AddChild (new CSharpTokenNode (Convert (location [0])), GotoCaseStatement.CaseKeywordRole); + result.AddChild(new CSharpTokenNode(Convert(location [0]), GotoCaseStatement.CaseKeywordRole), GotoCaseStatement.CaseKeywordRole); if (gotoCase.Expr != null) - result.AddChild ((Expression)gotoCase.Expr.Accept (this), Roles.Expression); + result.AddChild((Expression)gotoCase.Expr.Accept(this), Roles.Expression); if (location != null && location.Count > 1) - result.AddChild (new CSharpTokenNode (Convert (location [1])), Roles.Semicolon); + result.AddChild(new CSharpTokenNode(Convert(location [1]), Roles.Semicolon), Roles.Semicolon); return result; } - - public override object Visit (Throw throwStatement) + + public override object Visit(Throw throwStatement) { - var result = new ThrowStatement (); - var location = LocationsBag.GetLocations (throwStatement); + var result = new ThrowStatement(); + var location = LocationsBag.GetLocations(throwStatement); - result.AddChild (new CSharpTokenNode (Convert (throwStatement.loc)), ThrowStatement.ThrowKeywordRole); + result.AddChild(new CSharpTokenNode(Convert(throwStatement.loc), ThrowStatement.ThrowKeywordRole), ThrowStatement.ThrowKeywordRole); if (throwStatement.Expr != null) - result.AddChild ((Expression)throwStatement.Expr.Accept (this), Roles.Expression); + result.AddChild((Expression)throwStatement.Expr.Accept(this), Roles.Expression); if (location != null) - result.AddChild (new CSharpTokenNode (Convert (location [0])), Roles.Semicolon); + result.AddChild(new CSharpTokenNode(Convert(location [0]), Roles.Semicolon), Roles.Semicolon); return result; } - - public override object Visit (Break breakStatement) + + public override object Visit(Break breakStatement) { - var result = new BreakStatement (); - var location = LocationsBag.GetLocations (breakStatement); + var result = new BreakStatement(); + var location = LocationsBag.GetLocations(breakStatement); - result.AddChild (new CSharpTokenNode (Convert (breakStatement.loc)), BreakStatement.BreakKeywordRole); + result.AddChild(new CSharpTokenNode(Convert(breakStatement.loc), BreakStatement.BreakKeywordRole), BreakStatement.BreakKeywordRole); if (location != null) - result.AddChild (new CSharpTokenNode (Convert (location [0])), Roles.Semicolon); + result.AddChild(new CSharpTokenNode(Convert(location [0]), Roles.Semicolon), Roles.Semicolon); return result; } - - public override object Visit (Continue continueStatement) + + public override object Visit(Continue continueStatement) { - var result = new ContinueStatement (); - var location = LocationsBag.GetLocations (continueStatement); - result.AddChild (new CSharpTokenNode (Convert (continueStatement.loc)), ContinueStatement.ContinueKeywordRole); + var result = new ContinueStatement(); + var location = LocationsBag.GetLocations(continueStatement); + result.AddChild(new CSharpTokenNode(Convert(continueStatement.loc), ContinueStatement.ContinueKeywordRole), ContinueStatement.ContinueKeywordRole); if (location != null) - result.AddChild (new CSharpTokenNode (Convert (location [0])), Roles.Semicolon); + result.AddChild(new CSharpTokenNode(Convert(location [0]), Roles.Semicolon), Roles.Semicolon); return result; } - - public static bool IsLower (Location left, Location right) + + public static bool IsLower(Location left, Location right) { return left.Row < right.Row || left.Row == right.Row && left.Column < right.Column; } - - public UsingStatement CreateUsingStatement (Block blockStatement) + + public UsingStatement CreateUsingStatement(Block blockStatement) { - var usingResult = new UsingStatement (); + var usingResult = new UsingStatement(); Mono.CSharp.Statement cur = blockStatement.Statements [0]; - if (cur is Using) { - Using u = (Using)cur; - usingResult.AddChild (new CSharpTokenNode (Convert (u.loc)), UsingStatement.UsingKeywordRole); - usingResult.AddChild (new CSharpTokenNode (Convert (blockStatement.StartLocation)), Roles.LPar); + var u = cur as Using; + if (u != null) { + usingResult.AddChild(new CSharpTokenNode(Convert(u.loc), UsingStatement.UsingKeywordRole), UsingStatement.UsingKeywordRole); + usingResult.AddChild(new CSharpTokenNode(Convert(blockStatement.StartLocation), Roles.LPar), Roles.LPar); if (u.Variables != null) { - var initializer = new VariableInitializer () { - NameToken = Identifier.Create (u.Variables.Variable.Name, Convert (u.Variables.Variable.Location)), + var initializer = new VariableInitializer { + NameToken = Identifier.Create(u.Variables.Variable.Name, Convert(u.Variables.Variable.Location)), }; - var loc = LocationsBag.GetLocations (u.Variables); + var loc = LocationsBag.GetLocations(u.Variables); if (loc != null) - initializer.AddChild (new CSharpTokenNode (Convert (loc [0])), Roles.Assign); + initializer.AddChild(new CSharpTokenNode(Convert(loc [0]), Roles.Assign), Roles.Assign); if (u.Variables.Initializer != null) - initializer.Initializer = u.Variables.Initializer.Accept (this) as Expression; + initializer.Initializer = u.Variables.Initializer.Accept(this) as Expression; - var varDec = new VariableDeclarationStatement () { - Type = ConvertToType (u.Variables.TypeExpression), + var varDec = new VariableDeclarationStatement { + Type = ConvertToType(u.Variables.TypeExpression), Variables = { initializer } }; if (u.Variables.Declarators != null) { foreach (var decl in u.Variables.Declarators) { - var declLoc = LocationsBag.GetLocations (decl); - var init = new VariableInitializer (); + var declLoc = LocationsBag.GetLocations(decl); + var init = new VariableInitializer(); if (declLoc != null && declLoc.Count > 0) - varDec.AddChild (new CSharpTokenNode (Convert (declLoc [0])), Roles.Comma); - init.AddChild (Identifier.Create (decl.Variable.Name, Convert (decl.Variable.Location)), Roles.Identifier); + varDec.AddChild(new CSharpTokenNode(Convert(declLoc [0]), Roles.Comma), Roles.Comma); + init.AddChild(Identifier.Create(decl.Variable.Name, Convert(decl.Variable.Location)), Roles.Identifier); if (decl.Initializer != null) { if (declLoc != null && declLoc.Count > 1) - init.AddChild (new CSharpTokenNode (Convert (declLoc [1])), Roles.Assign); - init.AddChild ((Expression)decl.Initializer.Accept (this), Roles.Expression); + init.AddChild(new CSharpTokenNode(Convert(declLoc [1]), Roles.Assign), Roles.Assign); + init.AddChild((Expression)decl.Initializer.Accept(this), Roles.Expression); } - varDec.AddChild (init, Roles.Variable); + varDec.AddChild(init, Roles.Variable); } } - usingResult.AddChild (varDec, UsingStatement.ResourceAcquisitionRole); + usingResult.AddChild(varDec, UsingStatement.ResourceAcquisitionRole); } cur = u.Statement; - usingResult.AddChild (new CSharpTokenNode (Convert (blockStatement.EndLocation)), Roles.RPar); + usingResult.AddChild(new CSharpTokenNode(Convert(blockStatement.EndLocation), Roles.RPar), Roles.RPar); if (cur != null) - usingResult.AddChild ((Statement)cur.Accept (this), Roles.EmbeddedStatement); + usingResult.AddChild((Statement)cur.Accept(this), Roles.EmbeddedStatement); } return usingResult; } - - void AddBlockChildren (BlockStatement result, Block blockStatement, ref int curLocal) + + void AddBlockChildren(BlockStatement result, Block blockStatement, ref int curLocal) { if (convertTypeSystemMode) { return; @@ -1769,235 +1782,243 @@ namespace ICSharpCode.NRefactory.CSharp curLocal++; }*/ if (stmt is Block && !(stmt is ToplevelBlock || stmt is ExplicitBlock)) { - AddBlockChildren (result, (Block)stmt, ref curLocal); + AddBlockChildren(result, (Block)stmt, ref curLocal); } else { - result.AddChild ((Statement)stmt.Accept (this), BlockStatement.StatementRole); + result.AddChild((Statement)stmt.Accept(this), BlockStatement.StatementRole); } } } - - public override object Visit (Block blockStatement) + + public override object Visit(Block blockStatement) { - if (blockStatement.IsCompilerGenerated && blockStatement.Statements.Any ()) { - if (blockStatement.Statements.First () is Using) - return CreateUsingStatement (blockStatement); - return blockStatement.Statements.Last ().Accept (this); + if (blockStatement.IsCompilerGenerated && blockStatement.Statements.Any()) { + if (blockStatement.Statements.First() is Using) + return CreateUsingStatement(blockStatement); + return blockStatement.Statements.Last().Accept(this); } - var result = new BlockStatement (); - result.AddChild (new CSharpTokenNode (Convert (blockStatement.StartLocation)), Roles.LBrace); + var result = new BlockStatement(); + result.AddChild(new CSharpTokenNode(Convert(blockStatement.StartLocation), Roles.LBrace), Roles.LBrace); int curLocal = 0; - AddBlockChildren (result, blockStatement, ref curLocal); + AddBlockChildren(result, blockStatement, ref curLocal); - result.AddChild (new CSharpTokenNode (Convert (blockStatement.EndLocation)), Roles.RBrace); + result.AddChild(new CSharpTokenNode(Convert(blockStatement.EndLocation), Roles.RBrace), Roles.RBrace); return result; } - public override object Visit (Switch switchStatement) + public override object Visit(Switch switchStatement) { - var result = new SwitchStatement (); + var result = new SwitchStatement(); - var location = LocationsBag.GetLocations (switchStatement); - result.AddChild (new CSharpTokenNode (Convert (switchStatement.loc)), SwitchStatement.SwitchKeywordRole); + var location = LocationsBag.GetLocations(switchStatement); + result.AddChild(new CSharpTokenNode(Convert(switchStatement.loc), SwitchStatement.SwitchKeywordRole), SwitchStatement.SwitchKeywordRole); if (location != null) - result.AddChild (new CSharpTokenNode (Convert (location [0])), Roles.LPar); + result.AddChild(new CSharpTokenNode(Convert(location [0]), Roles.LPar), Roles.LPar); if (switchStatement.Expr != null) - result.AddChild ((Expression)switchStatement.Expr.Accept (this), Roles.Expression); + result.AddChild((Expression)switchStatement.Expr.Accept(this), Roles.Expression); if (location != null && location.Count > 1) - result.AddChild (new CSharpTokenNode (Convert (location [1])), Roles.RPar); + result.AddChild(new CSharpTokenNode(Convert(location [1]), Roles.RPar), Roles.RPar); if (location != null && location.Count > 2) - result.AddChild (new CSharpTokenNode (Convert (location [2])), Roles.LBrace); - if (switchStatement.Sections != null) { - foreach (var section in switchStatement.Sections) { - var newSection = new SwitchSection (); - if (section.Labels != null) { - foreach (var caseLabel in section.Labels) { - var newLabel = new CaseLabel (); - if (caseLabel.Label != null) { - newLabel.AddChild (new CSharpTokenNode (Convert (caseLabel.Location)), CaseLabel.CaseKeywordRole); - if (caseLabel.Label != null) - newLabel.AddChild ((Expression)caseLabel.Label.Accept (this), Roles.Expression); - var colonLocation = LocationsBag.GetLocations (caseLabel); - if (colonLocation != null) - newLabel.AddChild (new CSharpTokenNode (Convert (colonLocation [0])), Roles.Colon); - } else { - newLabel.AddChild (new CSharpTokenNode (Convert (caseLabel.Location)), CaseLabel.DefaultKeywordRole); - newLabel.AddChild (new CSharpTokenNode (new TextLocation (caseLabel.Location.Row, caseLabel.Location.Column + "default".Length)), Roles.Colon); - } - newSection.AddChild (newLabel, SwitchSection.CaseLabelRole); + result.AddChild(new CSharpTokenNode(Convert(location [2]), Roles.LBrace), Roles.LBrace); + SwitchSection newSection = null; + bool lastWasCase = false, added = true; + if (switchStatement.Block != null) { + foreach (var child in switchStatement.Block.Statements) { + var statement = child.Accept(this); + var caseLabel = statement as CaseLabel; + if (caseLabel != null) { + if (!lastWasCase) { + newSection = new SwitchSection(); + added = false; } + newSection.AddChild(caseLabel, SwitchSection.CaseLabelRole); + lastWasCase = true; + } else { + if (lastWasCase) { + result.AddChild(newSection, SwitchStatement.SwitchSectionRole); + lastWasCase = false; + added = true; + } + newSection.AddChild((Statement)statement, Roles.EmbeddedStatement); } - - var blockStatement = section.Block; - var bodyBlock = new BlockStatement (); - int curLocal = 0; - AddBlockChildren (bodyBlock, blockStatement, ref curLocal); - foreach (var statement in bodyBlock.Statements) { - statement.Remove (); - newSection.AddChild (statement, Roles.EmbeddedStatement); - - } - result.AddChild (newSection, SwitchStatement.SwitchSectionRole); } } - + if (!added) + result.AddChild(newSection, SwitchStatement.SwitchSectionRole); + if (location != null && location.Count > 3) { - result.AddChild (new CSharpTokenNode (Convert (location [3])), Roles.RBrace); + result.AddChild(new CSharpTokenNode(Convert(location [3]), Roles.RBrace), Roles.RBrace); } else { // parser error, set end node to max value. - result.AddChild (new ErrorNode (), Roles.Error); + result.AddChild(new ErrorNode(), Roles.Error); } return result; } - - public override object Visit (Lock lockStatement) + + public override object Visit(SwitchLabel switchLabel) + { + var newLabel = new CaseLabel(); + if (!switchLabel.IsDefault) { + newLabel.AddChild(new CSharpTokenNode(Convert(switchLabel.Location), CaseLabel.CaseKeywordRole), CaseLabel.CaseKeywordRole); + if (switchLabel.Label != null) + newLabel.AddChild((Expression)switchLabel.Label.Accept(this), Roles.Expression); + var colonLocation = LocationsBag.GetLocations(switchLabel); + if (colonLocation != null) + newLabel.AddChild(new CSharpTokenNode(Convert(colonLocation [0]), Roles.Colon), Roles.Colon); + } else { + newLabel.AddChild(new CSharpTokenNode(Convert(switchLabel.Location), CaseLabel.DefaultKeywordRole), CaseLabel.DefaultKeywordRole); + newLabel.AddChild(new CSharpTokenNode(new TextLocation(switchLabel.Location.Row, switchLabel.Location.Column + "default".Length), Roles.Colon), Roles.Colon); + } + return newLabel; + } + + public override object Visit(Lock lockStatement) { - var result = new LockStatement (); - var location = LocationsBag.GetLocations (lockStatement); - result.AddChild (new CSharpTokenNode (Convert (lockStatement.loc)), LockStatement.LockKeywordRole); + var result = new LockStatement(); + var location = LocationsBag.GetLocations(lockStatement); + result.AddChild(new CSharpTokenNode(Convert(lockStatement.loc), LockStatement.LockKeywordRole), LockStatement.LockKeywordRole); if (location != null) - result.AddChild (new CSharpTokenNode (Convert (location [0])), Roles.LPar); + result.AddChild(new CSharpTokenNode(Convert(location [0]), Roles.LPar), Roles.LPar); if (lockStatement.Expr != null) - result.AddChild ((Expression)lockStatement.Expr.Accept (this), Roles.Expression); + result.AddChild((Expression)lockStatement.Expr.Accept(this), Roles.Expression); if (location != null && location.Count > 1) - result.AddChild (new CSharpTokenNode (Convert (location [1])), Roles.RPar); + result.AddChild(new CSharpTokenNode(Convert(location [1]), Roles.RPar), Roles.RPar); if (lockStatement.Statement != null) - result.AddChild ((Statement)lockStatement.Statement.Accept (this), Roles.EmbeddedStatement); + result.AddChild((Statement)lockStatement.Statement.Accept(this), Roles.EmbeddedStatement); return result; } - - public override object Visit (Unchecked uncheckedStatement) + + public override object Visit(Unchecked uncheckedStatement) { - var result = new UncheckedStatement (); - result.AddChild (new CSharpTokenNode (Convert (uncheckedStatement.loc)), UncheckedStatement.UncheckedKeywordRole); + var result = new UncheckedStatement(); + result.AddChild(new CSharpTokenNode(Convert(uncheckedStatement.loc), UncheckedStatement.UncheckedKeywordRole), UncheckedStatement.UncheckedKeywordRole); if (uncheckedStatement.Block != null) - result.AddChild ((BlockStatement)uncheckedStatement.Block.Accept (this), Roles.Body); + result.AddChild((BlockStatement)uncheckedStatement.Block.Accept(this), Roles.Body); return result; } - - public override object Visit (Checked checkedStatement) + + public override object Visit(Checked checkedStatement) { - var result = new CheckedStatement (); - result.AddChild (new CSharpTokenNode (Convert (checkedStatement.loc)), CheckedStatement.CheckedKeywordRole); + var result = new CheckedStatement(); + result.AddChild(new CSharpTokenNode(Convert(checkedStatement.loc), CheckedStatement.CheckedKeywordRole), CheckedStatement.CheckedKeywordRole); if (checkedStatement.Block != null) - result.AddChild ((BlockStatement)checkedStatement.Block.Accept (this), Roles.Body); + result.AddChild((BlockStatement)checkedStatement.Block.Accept(this), Roles.Body); return result; } - - public override object Visit (Unsafe unsafeStatement) + + public override object Visit(Unsafe unsafeStatement) { - var result = new UnsafeStatement (); - result.AddChild (new CSharpTokenNode (Convert (unsafeStatement.loc)), UnsafeStatement.UnsafeKeywordRole); + var result = new UnsafeStatement(); + result.AddChild(new CSharpTokenNode(Convert(unsafeStatement.loc), UnsafeStatement.UnsafeKeywordRole), UnsafeStatement.UnsafeKeywordRole); if (unsafeStatement.Block != null) - result.AddChild ((BlockStatement)unsafeStatement.Block.Accept (this), Roles.Body); + result.AddChild((BlockStatement)unsafeStatement.Block.Accept(this), Roles.Body); return result; } - - public override object Visit (Fixed fixedStatement) + + public override object Visit(Fixed fixedStatement) { - var result = new FixedStatement (); - var location = LocationsBag.GetLocations (fixedStatement); + var result = new FixedStatement(); + var location = LocationsBag.GetLocations(fixedStatement); - result.AddChild (new CSharpTokenNode (Convert (fixedStatement.loc)), FixedStatement.FixedKeywordRole); + result.AddChild(new CSharpTokenNode(Convert(fixedStatement.loc), FixedStatement.FixedKeywordRole), FixedStatement.FixedKeywordRole); if (location != null) - result.AddChild (new CSharpTokenNode (Convert (location [0])), Roles.LPar); + result.AddChild(new CSharpTokenNode(Convert(location [0]), Roles.LPar), Roles.LPar); if (fixedStatement.Variables != null) { var blockVariableDeclaration = fixedStatement.Variables; - result.AddChild (ConvertToType (blockVariableDeclaration.TypeExpression), Roles.Type); - var varInit = new VariableInitializer (); - var initLocation = LocationsBag.GetLocations (blockVariableDeclaration); - varInit.AddChild (Identifier.Create (blockVariableDeclaration.Variable.Name, Convert (blockVariableDeclaration.Variable.Location)), Roles.Identifier); + result.AddChild(ConvertToType(blockVariableDeclaration.TypeExpression), Roles.Type); + var varInit = new VariableInitializer(); + var initLocation = LocationsBag.GetLocations(blockVariableDeclaration); + varInit.AddChild(Identifier.Create(blockVariableDeclaration.Variable.Name, Convert(blockVariableDeclaration.Variable.Location)), Roles.Identifier); if (blockVariableDeclaration.Initializer != null) { if (initLocation != null) - varInit.AddChild (new CSharpTokenNode (Convert (initLocation [0])), Roles.Assign); - varInit.AddChild ((Expression)blockVariableDeclaration.Initializer.Accept (this), Roles.Expression); + varInit.AddChild(new CSharpTokenNode(Convert(initLocation [0]), Roles.Assign), Roles.Assign); + varInit.AddChild((Expression)blockVariableDeclaration.Initializer.Accept(this), Roles.Expression); } - result.AddChild (varInit, Roles.Variable); + result.AddChild(varInit, Roles.Variable); if (blockVariableDeclaration.Declarators != null) { foreach (var decl in blockVariableDeclaration.Declarators) { - var loc = LocationsBag.GetLocations (decl); - var init = new VariableInitializer (); + var loc = LocationsBag.GetLocations(decl); + var init = new VariableInitializer(); if (loc != null && loc.Count > 0) - result.AddChild (new CSharpTokenNode (Convert (loc [0])), Roles.Comma); - init.AddChild (Identifier.Create (decl.Variable.Name, Convert (decl.Variable.Location)), Roles.Identifier); + result.AddChild(new CSharpTokenNode(Convert(loc [0]), Roles.Comma), Roles.Comma); + init.AddChild(Identifier.Create(decl.Variable.Name, Convert(decl.Variable.Location)), Roles.Identifier); if (decl.Initializer != null) { if (loc != null && loc.Count > 1) - init.AddChild (new CSharpTokenNode (Convert (loc [1])), Roles.Assign); - init.AddChild ((Expression)decl.Initializer.Accept (this), Roles.Expression); - } else { + init.AddChild(new CSharpTokenNode(Convert(loc [1]), Roles.Assign), Roles.Assign); + init.AddChild((Expression)decl.Initializer.Accept(this), Roles.Expression); } - result.AddChild (init, Roles.Variable); + result.AddChild(init, Roles.Variable); } } } if (location != null && location.Count > 1) - result.AddChild (new CSharpTokenNode (Convert (location [1])), Roles.RPar); + result.AddChild(new CSharpTokenNode(Convert(location [1]), Roles.RPar), Roles.RPar); if (fixedStatement.Statement != null) - result.AddChild ((Statement)fixedStatement.Statement.Accept (this), Roles.EmbeddedStatement); + result.AddChild((Statement)fixedStatement.Statement.Accept(this), Roles.EmbeddedStatement); return result; } - - public override object Visit (TryFinally tryFinallyStatement) + + public override object Visit(TryFinally tryFinallyStatement) { TryCatchStatement result; - var location = LocationsBag.GetLocations (tryFinallyStatement); + var location = LocationsBag.GetLocations(tryFinallyStatement); if (tryFinallyStatement.Stmt is TryCatch) { - result = (TryCatchStatement)tryFinallyStatement.Stmt.Accept (this); + result = (TryCatchStatement)tryFinallyStatement.Stmt.Accept(this); } else { - result = new TryCatchStatement (); - result.AddChild (new CSharpTokenNode (Convert (tryFinallyStatement.loc)), TryCatchStatement.TryKeywordRole); + result = new TryCatchStatement(); + result.AddChild(new CSharpTokenNode(Convert(tryFinallyStatement.loc), TryCatchStatement.TryKeywordRole), TryCatchStatement.TryKeywordRole); if (tryFinallyStatement.Stmt != null) - result.AddChild ((BlockStatement)tryFinallyStatement.Stmt.Accept (this), TryCatchStatement.TryBlockRole); + result.AddChild((BlockStatement)tryFinallyStatement.Stmt.Accept(this), TryCatchStatement.TryBlockRole); } if (location != null) - result.AddChild (new CSharpTokenNode (Convert (location [0])), TryCatchStatement.FinallyKeywordRole); + result.AddChild(new CSharpTokenNode(Convert(location [0]), TryCatchStatement.FinallyKeywordRole), TryCatchStatement.FinallyKeywordRole); if (tryFinallyStatement.Fini != null) - result.AddChild ((BlockStatement)tryFinallyStatement.Fini.Accept (this), TryCatchStatement.FinallyBlockRole); + result.AddChild((BlockStatement)tryFinallyStatement.Fini.Accept(this), TryCatchStatement.FinallyBlockRole); return result; } - - CatchClause ConvertCatch (Catch ctch) + + CatchClause ConvertCatch(Catch ctch) { - CatchClause result = new CatchClause (); - var location = LocationsBag.GetLocations (ctch); - result.AddChild (new CSharpTokenNode (Convert (ctch.loc)), CatchClause.CatchKeywordRole); + var result = new CatchClause(); + var location = LocationsBag.GetLocations(ctch); + result.AddChild(new CSharpTokenNode(Convert(ctch.loc), CatchClause.CatchKeywordRole), CatchClause.CatchKeywordRole); if (ctch.TypeExpression != null) { if (location != null) - result.AddChild (new CSharpTokenNode (Convert (location [0])), Roles.LPar); + result.AddChild(new CSharpTokenNode(Convert(location [0]), Roles.LPar), Roles.LPar); if (ctch.TypeExpression != null) - result.AddChild (ConvertToType (ctch.TypeExpression), Roles.Type); - if (ctch.Variable != null && !string.IsNullOrEmpty (ctch.Variable.Name)) - result.AddChild (Identifier.Create (ctch.Variable.Name, Convert (ctch.Variable.Location)), Roles.Identifier); + result.AddChild(ConvertToType(ctch.TypeExpression), Roles.Type); + if (ctch.Variable != null && !string.IsNullOrEmpty(ctch.Variable.Name)) + result.AddChild(Identifier.Create(ctch.Variable.Name, Convert(ctch.Variable.Location)), Roles.Identifier); if (location != null && location.Count > 1) - result.AddChild (new CSharpTokenNode (Convert (location [1])), Roles.RPar); + result.AddChild(new CSharpTokenNode(Convert(location [1]), Roles.RPar), Roles.RPar); } if (ctch.Block != null) - result.AddChild ((BlockStatement)ctch.Block.Accept (this), Roles.Body); + result.AddChild((BlockStatement)ctch.Block.Accept(this), Roles.Body); return result; } - - public override object Visit (TryCatch tryCatchStatement) + + public override object Visit(TryCatch tryCatchStatement) { - var result = new TryCatchStatement (); - result.AddChild (new CSharpTokenNode (Convert (tryCatchStatement.loc)), TryCatchStatement.TryKeywordRole); + var result = new TryCatchStatement(); + result.AddChild(new CSharpTokenNode(Convert(tryCatchStatement.loc), TryCatchStatement.TryKeywordRole), TryCatchStatement.TryKeywordRole); if (tryCatchStatement.Block != null) - result.AddChild ((BlockStatement)tryCatchStatement.Block.Accept (this), TryCatchStatement.TryBlockRole); + result.AddChild((BlockStatement)tryCatchStatement.Block.Accept(this), TryCatchStatement.TryBlockRole); if (tryCatchStatement.Clauses != null) { foreach (var ctch in tryCatchStatement.Clauses) { - result.AddChild (ConvertCatch (ctch), TryCatchStatement.CatchClauseRole); + result.AddChild(ConvertCatch(ctch), TryCatchStatement.CatchClauseRole); } } // if (tryCatchStatement.General != null) @@ -2005,191 +2026,196 @@ namespace ICSharpCode.NRefactory.CSharp return result; } - - public override object Visit (Using usingStatement) + + public override object Visit(Using usingStatement) { - var result = new UsingStatement (); - var location = LocationsBag.GetLocations (usingStatement); + var result = new UsingStatement(); + var location = LocationsBag.GetLocations(usingStatement); - result.AddChild (new CSharpTokenNode (Convert (usingStatement.loc)), UsingStatement.UsingKeywordRole); + result.AddChild(new CSharpTokenNode(Convert(usingStatement.loc), UsingStatement.UsingKeywordRole), UsingStatement.UsingKeywordRole); if (location != null) - result.AddChild (new CSharpTokenNode (Convert (location [0])), Roles.LPar); + result.AddChild(new CSharpTokenNode(Convert(location [0]), Roles.LPar), Roles.LPar); if (usingStatement.Expr != null) - result.AddChild ((AstNode)usingStatement.Expr.Accept (this), UsingStatement.ResourceAcquisitionRole); + result.AddChild((AstNode)usingStatement.Expr.Accept(this), UsingStatement.ResourceAcquisitionRole); if (location != null && location.Count > 1) - result.AddChild (new CSharpTokenNode (Convert (location [1])), Roles.RPar); + result.AddChild(new CSharpTokenNode(Convert(location [1]), Roles.RPar), Roles.RPar); if (usingStatement.Statement != null) - result.AddChild ((Statement)usingStatement.Statement.Accept (this), Roles.EmbeddedStatement); + result.AddChild((Statement)usingStatement.Statement.Accept(this), Roles.EmbeddedStatement); return result; } - - public override object Visit (Foreach foreachStatement) + + public override object Visit(Foreach foreachStatement) { - var result = new ForeachStatement (); + var result = new ForeachStatement(); - var location = LocationsBag.GetLocations (foreachStatement); + var location = LocationsBag.GetLocations(foreachStatement); - result.AddChild (new CSharpTokenNode (Convert (foreachStatement.loc)), ForeachStatement.ForeachKeywordRole); + result.AddChild(new CSharpTokenNode(Convert(foreachStatement.loc), ForeachStatement.ForeachKeywordRole), ForeachStatement.ForeachKeywordRole); if (location != null) - result.AddChild (new CSharpTokenNode (Convert (location [0])), Roles.LPar); + result.AddChild(new CSharpTokenNode(Convert(location [0]), Roles.LPar), Roles.LPar); if (foreachStatement.TypeExpression != null) - result.AddChild (ConvertToType (foreachStatement.TypeExpression), Roles.Type); + result.AddChild(ConvertToType(foreachStatement.TypeExpression), Roles.Type); if (foreachStatement.Variable != null) - result.AddChild (Identifier.Create (foreachStatement.Variable.Name, Convert (foreachStatement.Variable.Location)), Roles.Identifier); + result.AddChild(Identifier.Create(foreachStatement.Variable.Name, Convert(foreachStatement.Variable.Location)), Roles.Identifier); if (location != null && location.Count > 1) - result.AddChild (new CSharpTokenNode (Convert (location [1])), ForeachStatement.InKeywordRole); + result.AddChild(new CSharpTokenNode(Convert(location [1]), ForeachStatement.InKeywordRole), ForeachStatement.InKeywordRole); if (foreachStatement.Expr != null) - result.AddChild ((Expression)foreachStatement.Expr.Accept (this), Roles.Expression); + result.AddChild((Expression)foreachStatement.Expr.Accept(this), Roles.Expression); if (location != null && location.Count > 2) - result.AddChild (new CSharpTokenNode (Convert (location [2])), Roles.RPar); + result.AddChild(new CSharpTokenNode(Convert(location [2]), Roles.RPar), Roles.RPar); if (foreachStatement.Statement != null) - result.AddChild ((Statement)foreachStatement.Statement.Accept (this), Roles.EmbeddedStatement); + result.AddChild((Statement)foreachStatement.Statement.Accept(this), Roles.EmbeddedStatement); return result; } - - public override object Visit (Yield yieldStatement) + + public override object Visit(Yield yieldStatement) { - var result = new YieldReturnStatement (); - var location = LocationsBag.GetLocations (yieldStatement); + var result = new YieldReturnStatement(); + var location = LocationsBag.GetLocations(yieldStatement); - result.AddChild (new CSharpTokenNode (Convert (yieldStatement.loc)), YieldReturnStatement.YieldKeywordRole); + result.AddChild(new CSharpTokenNode(Convert(yieldStatement.loc), YieldReturnStatement.YieldKeywordRole), YieldReturnStatement.YieldKeywordRole); if (location != null) - result.AddChild (new CSharpTokenNode (Convert (location [0])), YieldReturnStatement.ReturnKeywordRole); + result.AddChild(new CSharpTokenNode(Convert(location [0]), YieldReturnStatement.ReturnKeywordRole), YieldReturnStatement.ReturnKeywordRole); if (yieldStatement.Expr != null) - result.AddChild ((Expression)yieldStatement.Expr.Accept (this), Roles.Expression); + result.AddChild((Expression)yieldStatement.Expr.Accept(this), Roles.Expression); if (location != null && location.Count > 1) - result.AddChild (new CSharpTokenNode (Convert (location [1])), Roles.Semicolon); + result.AddChild(new CSharpTokenNode(Convert(location [1]), Roles.Semicolon), Roles.Semicolon); return result; } - - public override object Visit (YieldBreak yieldBreakStatement) + + public override object Visit(YieldBreak yieldBreakStatement) { - var result = new YieldBreakStatement (); - var location = LocationsBag.GetLocations (yieldBreakStatement); - result.AddChild (new CSharpTokenNode (Convert (yieldBreakStatement.loc)), YieldBreakStatement.YieldKeywordRole); + var result = new YieldBreakStatement(); + var location = LocationsBag.GetLocations(yieldBreakStatement); + result.AddChild(new CSharpTokenNode(Convert(yieldBreakStatement.loc), YieldBreakStatement.YieldKeywordRole), YieldBreakStatement.YieldKeywordRole); if (location != null) { - result.AddChild (new CSharpTokenNode (Convert (location [0])), YieldBreakStatement.BreakKeywordRole); + result.AddChild(new CSharpTokenNode(Convert(location [0]), YieldBreakStatement.BreakKeywordRole), YieldBreakStatement.BreakKeywordRole); if (location.Count > 1) - result.AddChild (new CSharpTokenNode (Convert (location [1])), Roles.Semicolon); + result.AddChild(new CSharpTokenNode(Convert(location [1]), Roles.Semicolon), Roles.Semicolon); } return result; } + #endregion - + #region Expression - public override object Visit (Mono.CSharp.Expression expression) + + public override object Visit(Mono.CSharp.Expression expression) { - Console.WriteLine ("Visit unknown expression:" + expression); - System.Console.WriteLine (Environment.StackTrace); + Console.WriteLine("Visit unknown expression:" + expression); + Console.WriteLine(Environment.StackTrace); return null; } - - public override object Visit (Mono.CSharp.DefaultParameterValueExpression defaultParameterValueExpression) + + public override object Visit(DefaultParameterValueExpression defaultParameterValueExpression) { - return defaultParameterValueExpression.Child.Accept (this); + return defaultParameterValueExpression.Child.Accept(this); } - public override object Visit (TypeExpression typeExpression) + public override object Visit(TypeExpression typeExpression) { - return new TypeReferenceExpression (new PrimitiveType (keywordTable [(int)typeExpression.Type.BuiltinType], Convert (typeExpression.Location))); + return new TypeReferenceExpression(new PrimitiveType(keywordTable [(int)typeExpression.Type.BuiltinType], Convert(typeExpression.Location))); } - public override object Visit (LocalVariableReference localVariableReference) + public override object Visit(LocalVariableReference localVariableReference) { - return Identifier.Create (localVariableReference.Name, Convert (localVariableReference.Location)); + return Identifier.Create(localVariableReference.Name, Convert(localVariableReference.Location)); } - public override object Visit (MemberAccess memberAccess) + public override object Visit(MemberAccess memberAccess) { Expression result; - if (memberAccess.LeftExpression is Indirection) { - var ind = memberAccess.LeftExpression as Indirection; - result = new PointerReferenceExpression (); - result.AddChild ((Expression)ind.Expr.Accept (this), Roles.TargetExpression); - result.AddChild (new CSharpTokenNode (Convert (ind.Location)), PointerReferenceExpression.ArrowRole); + var ind = memberAccess.LeftExpression as Indirection; + if (ind != null) { + result = new PointerReferenceExpression(); + result.AddChild((Expression)ind.Expr.Accept(this), Roles.TargetExpression); + result.AddChild(new CSharpTokenNode(Convert(ind.Location), PointerReferenceExpression.ArrowRole), PointerReferenceExpression.ArrowRole); } else { - result = new MemberReferenceExpression (); + result = new MemberReferenceExpression(); if (memberAccess.LeftExpression != null) { - var leftExpr = memberAccess.LeftExpression.Accept (this); - result.AddChild ((Expression)leftExpr, Roles.TargetExpression); + var leftExpr = memberAccess.LeftExpression.Accept(this); + result.AddChild((Expression)leftExpr, Roles.TargetExpression); } - if (!memberAccess.DotLocation.IsNull) { - result.AddChild (new CSharpTokenNode (Convert (memberAccess.DotLocation)), Roles.Dot); + var loc = LocationsBag.GetLocations(memberAccess); + + if (loc != null) { + result.AddChild(new CSharpTokenNode(Convert(loc [0]), Roles.Dot), Roles.Dot); } } - result.AddChild (Identifier.Create (memberAccess.Name, Convert (memberAccess.Location)), Roles.Identifier); + result.AddChild(Identifier.Create(memberAccess.Name, Convert(memberAccess.Location)), Roles.Identifier); - AddTypeArguments (result, memberAccess); + AddTypeArguments(result, memberAccess); return result; } - - public override object Visit (QualifiedAliasMember qualifiedAliasMember) + + public override object Visit(QualifiedAliasMember qualifiedAliasMember) { - var result = new MemberType (); - result.Target = new SimpleType (qualifiedAliasMember.alias, Convert (qualifiedAliasMember.Location)); + var result = new MemberType(); + result.Target = new SimpleType(qualifiedAliasMember.alias, Convert(qualifiedAliasMember.Location)); result.IsDoubleColon = true; - var location = LocationsBag.GetLocations (qualifiedAliasMember); - result.AddChild (Identifier.Create (qualifiedAliasMember.Name, location != null ? Convert (location [0]) : TextLocation.Empty), Roles.Identifier); - return new TypeReferenceExpression () { Type = result }; + var location = LocationsBag.GetLocations(qualifiedAliasMember); + if (location != null && location.Count > 0) + result.AddChild(new CSharpTokenNode(Convert(location [0]), Roles.DoubleColon), Roles.DoubleColon); + + AddTypeArguments(result, qualifiedAliasMember); + result.AddChild(Identifier.Create(qualifiedAliasMember.Name, location != null && location.Count > 1 ? Convert(location [1]) : TextLocation.Empty), Roles.Identifier); + return new TypeReferenceExpression { Type = result }; } - - public override object Visit (Constant constant) + + public override object Visit(Constant constant) { - if (constant.GetValue () == null) - return new NullReferenceExpression (Convert (constant.Location)); + if (constant.GetValue() == null) + return new NullReferenceExpression(Convert(constant.Location)); string literalValue; - if (constant is ILiteralConstant) { - literalValue = new string (((ILiteralConstant)constant).ParsedValue); - } else { - literalValue = constant.GetValueAsLiteral (); - } - object val = constant.GetValue (); + var literalConstant = constant as ILiteralConstant; + literalValue = literalConstant != null ? new string(literalConstant.ParsedValue) : constant.GetValueAsLiteral(); + object val = constant.GetValue(); if (val is bool) literalValue = (bool)val ? "true" : "false"; - var result = new PrimitiveExpression (val, Convert (constant.Location), literalValue); + var result = new PrimitiveExpression(val, Convert(constant.Location), literalValue); return result; } - public override object Visit (SimpleName simpleName) + public override object Visit(SimpleName simpleName) { - var result = new IdentifierExpression (); - result.AddChild (Identifier.Create (simpleName.Name, Convert (simpleName.Location)), Roles.Identifier); - AddTypeArguments (result, simpleName); + var result = new IdentifierExpression(); + result.AddChild(Identifier.Create(simpleName.Name, Convert(simpleName.Location)), Roles.Identifier); + AddTypeArguments(result, simpleName); return result; } - - public override object Visit (BooleanExpression booleanExpression) + + public override object Visit(BooleanExpression booleanExpression) { - return booleanExpression.Expr.Accept (this); + return booleanExpression.Expr.Accept(this); } - - public override object Visit (Mono.CSharp.ParenthesizedExpression parenthesizedExpression) + + public override object Visit(Mono.CSharp.ParenthesizedExpression parenthesizedExpression) { - var result = new ParenthesizedExpression (); - var location = LocationsBag.GetLocations (parenthesizedExpression); + var result = new ParenthesizedExpression(); + var location = LocationsBag.GetLocations(parenthesizedExpression); if (location != null) - result.AddChild (new CSharpTokenNode (Convert (location [0])), Roles.LPar); + result.AddChild(new CSharpTokenNode(Convert(location [0]), Roles.LPar), Roles.LPar); if (parenthesizedExpression.Expr != null) - result.AddChild ((Expression)parenthesizedExpression.Expr.Accept (this), Roles.Expression); + result.AddChild((Expression)parenthesizedExpression.Expr.Accept(this), Roles.Expression); if (location != null && location.Count > 1) - result.AddChild (new CSharpTokenNode (Convert (location [1])), Roles.RPar); + result.AddChild(new CSharpTokenNode(Convert(location [1]), Roles.RPar), Roles.RPar); return result; } - - public override object Visit (Unary unaryExpression) + + public override object Visit(Unary unaryExpression) { - var result = new UnaryOperatorExpression (); + var result = new UnaryOperatorExpression(); switch (unaryExpression.Oper) { case Unary.Operator.UnaryPlus: result.Operator = UnaryOperatorType.Plus; @@ -2207,134 +2233,135 @@ namespace ICSharpCode.NRefactory.CSharp result.Operator = UnaryOperatorType.AddressOf; break; } - result.AddChild (new CSharpTokenNode (Convert (unaryExpression.Location)), UnaryOperatorExpression.GetOperatorRole (result.Operator)); + var r = UnaryOperatorExpression.GetOperatorRole(result.Operator); + result.AddChild(new CSharpTokenNode(Convert(unaryExpression.Location), r), r); if (unaryExpression.Expr != null) - result.AddChild ((Expression)unaryExpression.Expr.Accept (this), Roles.Expression); + result.AddChild((Expression)unaryExpression.Expr.Accept(this), Roles.Expression); return result; } - - public override object Visit (UnaryMutator unaryMutatorExpression) + + public override object Visit(UnaryMutator unaryMutatorExpression) { - var result = new UnaryOperatorExpression (); + var result = new UnaryOperatorExpression(); if (unaryMutatorExpression.Expr == null) return result; - var expression = (Expression)unaryMutatorExpression.Expr.Accept (this); + var expression = (Expression)unaryMutatorExpression.Expr.Accept(this); switch (unaryMutatorExpression.UnaryMutatorMode) { case UnaryMutator.Mode.PostDecrement: result.Operator = UnaryOperatorType.PostDecrement; - result.AddChild (expression, Roles.Expression); - result.AddChild (new CSharpTokenNode (Convert (unaryMutatorExpression.Location)), UnaryOperatorExpression.DecrementRole); + result.AddChild(expression, Roles.Expression); + result.AddChild(new CSharpTokenNode(Convert(unaryMutatorExpression.Location), UnaryOperatorExpression.DecrementRole), UnaryOperatorExpression.DecrementRole); break; case UnaryMutator.Mode.PostIncrement: result.Operator = UnaryOperatorType.PostIncrement; - result.AddChild (expression, Roles.Expression); - result.AddChild (new CSharpTokenNode (Convert (unaryMutatorExpression.Location)), UnaryOperatorExpression.IncrementRole); + result.AddChild(expression, Roles.Expression); + result.AddChild(new CSharpTokenNode(Convert(unaryMutatorExpression.Location), UnaryOperatorExpression.IncrementRole), UnaryOperatorExpression.IncrementRole); break; case UnaryMutator.Mode.PreIncrement: result.Operator = UnaryOperatorType.Increment; - result.AddChild (new CSharpTokenNode (Convert (unaryMutatorExpression.Location)), UnaryOperatorExpression.IncrementRole); - result.AddChild (expression, Roles.Expression); + result.AddChild(new CSharpTokenNode(Convert(unaryMutatorExpression.Location), UnaryOperatorExpression.IncrementRole), UnaryOperatorExpression.IncrementRole); + result.AddChild(expression, Roles.Expression); break; case UnaryMutator.Mode.PreDecrement: result.Operator = UnaryOperatorType.Decrement; - result.AddChild (new CSharpTokenNode (Convert (unaryMutatorExpression.Location)), UnaryOperatorExpression.DecrementRole); - result.AddChild (expression, Roles.Expression); + result.AddChild(new CSharpTokenNode(Convert(unaryMutatorExpression.Location), UnaryOperatorExpression.DecrementRole), UnaryOperatorExpression.DecrementRole); + result.AddChild(expression, Roles.Expression); break; } return result; } - - public override object Visit (Indirection indirectionExpression) + + public override object Visit(Indirection indirectionExpression) { - var result = new UnaryOperatorExpression (); + var result = new UnaryOperatorExpression(); result.Operator = UnaryOperatorType.Dereference; - result.AddChild (new CSharpTokenNode (Convert (indirectionExpression.Location)), UnaryOperatorExpression.DereferenceRole); + result.AddChild(new CSharpTokenNode(Convert(indirectionExpression.Location), UnaryOperatorExpression.DereferenceRole), UnaryOperatorExpression.DereferenceRole); if (indirectionExpression.Expr != null) - result.AddChild ((Expression)indirectionExpression.Expr.Accept (this), Roles.Expression); + result.AddChild((Expression)indirectionExpression.Expr.Accept(this), Roles.Expression); return result; } - - public override object Visit (Is isExpression) + + public override object Visit(Is isExpression) { - var result = new IsExpression (); + var result = new IsExpression(); if (isExpression.Expr != null) - result.AddChild ((Expression)isExpression.Expr.Accept (this), Roles.Expression); - result.AddChild (new CSharpTokenNode (Convert (isExpression.Location)), IsExpression.IsKeywordRole); + result.AddChild((Expression)isExpression.Expr.Accept(this), Roles.Expression); + result.AddChild(new CSharpTokenNode(Convert(isExpression.Location), IsExpression.IsKeywordRole), IsExpression.IsKeywordRole); if (isExpression.ProbeType != null) - result.AddChild (ConvertToType (isExpression.ProbeType), Roles.Type); + result.AddChild(ConvertToType(isExpression.ProbeType), Roles.Type); return result; } - - public override object Visit (As asExpression) + + public override object Visit(As asExpression) { - var result = new AsExpression (); + var result = new AsExpression(); if (asExpression.Expr != null) - result.AddChild ((Expression)asExpression.Expr.Accept (this), Roles.Expression); - result.AddChild (new CSharpTokenNode (Convert (asExpression.Location)), AsExpression.AsKeywordRole); + result.AddChild((Expression)asExpression.Expr.Accept(this), Roles.Expression); + result.AddChild(new CSharpTokenNode(Convert(asExpression.Location), AsExpression.AsKeywordRole), AsExpression.AsKeywordRole); if (asExpression.ProbeType != null) - result.AddChild (ConvertToType (asExpression.ProbeType), Roles.Type); + result.AddChild(ConvertToType(asExpression.ProbeType), Roles.Type); return result; } - - public override object Visit (Cast castExpression) + + public override object Visit(Cast castExpression) { - var result = new CastExpression (); - var location = LocationsBag.GetLocations (castExpression); + var result = new CastExpression(); + var location = LocationsBag.GetLocations(castExpression); - result.AddChild (new CSharpTokenNode (Convert (castExpression.Location)), Roles.LPar); + result.AddChild(new CSharpTokenNode(Convert(castExpression.Location), Roles.LPar), Roles.LPar); if (castExpression.TargetType != null) - result.AddChild (ConvertToType (castExpression.TargetType), Roles.Type); + result.AddChild(ConvertToType(castExpression.TargetType), Roles.Type); if (location != null) - result.AddChild (new CSharpTokenNode (Convert (location [0])), Roles.RPar); + result.AddChild(new CSharpTokenNode(Convert(location [0]), Roles.RPar), Roles.RPar); if (castExpression.Expr != null) - result.AddChild ((Expression)castExpression.Expr.Accept (this), Roles.Expression); + result.AddChild((Expression)castExpression.Expr.Accept(this), Roles.Expression); return result; } - - public override object Visit (ComposedCast composedCast) + + public override object Visit(ComposedCast composedCast) { - var result = new ComposedType (); - result.AddChild (ConvertToType (composedCast.Left), Roles.Type); + var result = new ComposedType(); + result.AddChild(ConvertToType(composedCast.Left), Roles.Type); var spec = composedCast.Spec; while (spec != null) { if (spec.IsNullable) { - result.AddChild (new CSharpTokenNode (Convert (spec.Location)), ComposedType.NullableRole); + result.AddChild(new CSharpTokenNode(Convert(spec.Location), ComposedType.NullableRole), ComposedType.NullableRole); } else if (spec.IsPointer) { - result.AddChild (new CSharpTokenNode (Convert (spec.Location)), ComposedType.PointerRole); + result.AddChild(new CSharpTokenNode(Convert(spec.Location), ComposedType.PointerRole), ComposedType.PointerRole); } else { - var aSpec = new ArraySpecifier (); - aSpec.AddChild (new CSharpTokenNode (Convert (spec.Location)), Roles.LBracket); - var location = LocationsBag.GetLocations (spec); + var aSpec = new ArraySpecifier(); + aSpec.AddChild(new CSharpTokenNode(Convert(spec.Location), Roles.LBracket), Roles.LBracket); + var location = LocationsBag.GetLocations(spec); if (location != null) - aSpec.AddChild (new CSharpTokenNode (Convert (spec.Location)), Roles.RBracket); - result.AddChild (aSpec, ComposedType.ArraySpecifierRole); + aSpec.AddChild(new CSharpTokenNode(Convert(spec.Location), Roles.RBracket), Roles.RBracket); + result.AddChild(aSpec, ComposedType.ArraySpecifierRole); } spec = spec.Next; } return result; } - - public override object Visit (Mono.CSharp.DefaultValueExpression defaultValueExpression) + + public override object Visit(Mono.CSharp.DefaultValueExpression defaultValueExpression) { - var result = new DefaultValueExpression (); - result.AddChild (new CSharpTokenNode (Convert (defaultValueExpression.Location)), DefaultValueExpression.DefaultKeywordRole); - var location = LocationsBag.GetLocations (defaultValueExpression); + var result = new DefaultValueExpression(); + result.AddChild(new CSharpTokenNode(Convert(defaultValueExpression.Location), DefaultValueExpression.DefaultKeywordRole), DefaultValueExpression.DefaultKeywordRole); + var location = LocationsBag.GetLocations(defaultValueExpression); if (location != null) - result.AddChild (new CSharpTokenNode (Convert (location [0])), Roles.LPar); - result.AddChild (ConvertToType (defaultValueExpression.Expr), Roles.Type); + result.AddChild(new CSharpTokenNode(Convert(location [0]), Roles.LPar), Roles.LPar); + result.AddChild(ConvertToType(defaultValueExpression.Expr), Roles.Type); if (location != null && location.Count > 1) - result.AddChild (new CSharpTokenNode (Convert (location [1])), Roles.RPar); + result.AddChild(new CSharpTokenNode(Convert(location [1]), Roles.RPar), Roles.RPar); return result; } - - public override object Visit (Binary binaryExpression) + + public override object Visit(Binary binaryExpression) { - var result = new BinaryOperatorExpression (); + var result = new BinaryOperatorExpression(); switch (binaryExpression.Oper) { case Binary.Operator.Multiply: result.Operator = BinaryOperatorType.Multiply; @@ -2393,129 +2420,131 @@ namespace ICSharpCode.NRefactory.CSharp } if (binaryExpression.Left != null) - result.AddChild ((Expression)binaryExpression.Left.Accept (this), BinaryOperatorExpression.LeftRole); - var location = LocationsBag.GetLocations (binaryExpression); - if (location != null) - result.AddChild (new CSharpTokenNode (Convert (location[0])), BinaryOperatorExpression.GetOperatorRole (result.Operator)); + result.AddChild((Expression)binaryExpression.Left.Accept(this), BinaryOperatorExpression.LeftRole); + var location = LocationsBag.GetLocations(binaryExpression); + if (location != null) { + var r = BinaryOperatorExpression.GetOperatorRole(result.Operator); + result.AddChild(new CSharpTokenNode(Convert(location [0]), r), r); + } if (binaryExpression.Right != null) - result.AddChild ((Expression)binaryExpression.Right.Accept (this), BinaryOperatorExpression.RightRole); + result.AddChild((Expression)binaryExpression.Right.Accept(this), BinaryOperatorExpression.RightRole); return result; } - - public override object Visit (Mono.CSharp.Nullable.NullCoalescingOperator nullCoalescingOperator) + + public override object Visit(Mono.CSharp.Nullable.NullCoalescingOperator nullCoalescingOperator) { - var result = new BinaryOperatorExpression (); + var result = new BinaryOperatorExpression(); result.Operator = BinaryOperatorType.NullCoalescing; if (nullCoalescingOperator.LeftExpression != null) - result.AddChild ((Expression)nullCoalescingOperator.LeftExpression.Accept (this), BinaryOperatorExpression.LeftRole); - var location = LocationsBag.GetLocations (nullCoalescingOperator); + result.AddChild((Expression)nullCoalescingOperator.LeftExpression.Accept(this), BinaryOperatorExpression.LeftRole); + var location = LocationsBag.GetLocations(nullCoalescingOperator); if (location != null) - result.AddChild (new CSharpTokenNode (Convert (location[0])), BinaryOperatorExpression.NullCoalescingRole); + result.AddChild(new CSharpTokenNode(Convert(location [0]), BinaryOperatorExpression.NullCoalescingRole), BinaryOperatorExpression.NullCoalescingRole); if (nullCoalescingOperator.RightExpression != null) - result.AddChild ((Expression)nullCoalescingOperator.RightExpression.Accept (this), BinaryOperatorExpression.RightRole); + result.AddChild((Expression)nullCoalescingOperator.RightExpression.Accept(this), BinaryOperatorExpression.RightRole); return result; } - - public override object Visit (Conditional conditionalExpression) + + public override object Visit(Conditional conditionalExpression) { - var result = new ConditionalExpression (); + var result = new ConditionalExpression(); if (conditionalExpression.Expr != null) - result.AddChild ((Expression)conditionalExpression.Expr.Accept (this), Roles.Condition); - var location = LocationsBag.GetLocations (conditionalExpression); + result.AddChild((Expression)conditionalExpression.Expr.Accept(this), Roles.Condition); + var location = LocationsBag.GetLocations(conditionalExpression); - result.AddChild (new CSharpTokenNode (Convert (conditionalExpression.Location)), ConditionalExpression.QuestionMarkRole); + result.AddChild(new CSharpTokenNode(Convert(conditionalExpression.Location), ConditionalExpression.QuestionMarkRole), ConditionalExpression.QuestionMarkRole); if (conditionalExpression.TrueExpr != null) - result.AddChild ((Expression)conditionalExpression.TrueExpr.Accept (this), ConditionalExpression.TrueRole); + result.AddChild((Expression)conditionalExpression.TrueExpr.Accept(this), ConditionalExpression.TrueRole); if (location != null) - result.AddChild (new CSharpTokenNode (Convert (location [0])), ConditionalExpression.ColonRole); + result.AddChild(new CSharpTokenNode(Convert(location [0]), ConditionalExpression.ColonRole), ConditionalExpression.ColonRole); if (conditionalExpression.FalseExpr != null) - result.AddChild ((Expression)conditionalExpression.FalseExpr.Accept (this), ConditionalExpression.FalseRole); + result.AddChild((Expression)conditionalExpression.FalseExpr.Accept(this), ConditionalExpression.FalseRole); return result; } - - void AddParameter (AstNode parent, Mono.CSharp.AParametersCollection parameters) + + void AddParameter(AstNode parent, AParametersCollection parameters) { if (parameters == null) return; - var paramLocation = LocationsBag.GetLocations (parameters); + var paramLocation = LocationsBag.GetLocations(parameters); for (int i = 0; i < parameters.Count; i++) { var p = (Parameter)parameters.FixedParameters [i]; if (p == null) continue; - var location = LocationsBag.GetLocations (p); - ParameterDeclaration parameterDeclarationExpression = new ParameterDeclaration (); - AddAttributeSection (parameterDeclarationExpression, p); + var location = LocationsBag.GetLocations(p); + var parameterDeclarationExpression = new ParameterDeclaration(); + AddAttributeSection(parameterDeclarationExpression, p); switch (p.ModFlags) { case Parameter.Modifier.OUT: parameterDeclarationExpression.ParameterModifier = ParameterModifier.Out; if (location != null) - parameterDeclarationExpression.AddChild (new CSharpTokenNode (Convert (location [0])), ParameterDeclaration.OutModifierRole); + parameterDeclarationExpression.AddChild(new CSharpTokenNode(Convert(location [0]), ParameterDeclaration.OutModifierRole), ParameterDeclaration.OutModifierRole); break; case Parameter.Modifier.REF: parameterDeclarationExpression.ParameterModifier = ParameterModifier.Ref; if (location != null) - parameterDeclarationExpression.AddChild (new CSharpTokenNode (Convert (location [0])), ParameterDeclaration.RefModifierRole); + parameterDeclarationExpression.AddChild(new CSharpTokenNode(Convert(location [0]), ParameterDeclaration.RefModifierRole), ParameterDeclaration.RefModifierRole); break; case Parameter.Modifier.PARAMS: parameterDeclarationExpression.ParameterModifier = ParameterModifier.Params; if (location != null) - parameterDeclarationExpression.AddChild (new CSharpTokenNode (Convert (location [0])), ParameterDeclaration.ParamsModifierRole); + parameterDeclarationExpression.AddChild(new CSharpTokenNode(Convert(location [0]), ParameterDeclaration.ParamsModifierRole), ParameterDeclaration.ParamsModifierRole); break; default: if (p.HasExtensionMethodModifier) { parameterDeclarationExpression.ParameterModifier = ParameterModifier.This; if (location != null) { - parameterDeclarationExpression.AddChild (new CSharpTokenNode (Convert (location [0])), ParameterDeclaration.ThisModifierRole); + parameterDeclarationExpression.AddChild(new CSharpTokenNode(Convert(location [0]), ParameterDeclaration.ThisModifierRole), ParameterDeclaration.ThisModifierRole); } } break; } if (p.TypeExpression != null) // lambdas may have no types (a, b) => ... - parameterDeclarationExpression.AddChild (ConvertToType (p.TypeExpression), Roles.Type); + parameterDeclarationExpression.AddChild(ConvertToType(p.TypeExpression), Roles.Type); if (p.Name != null) - parameterDeclarationExpression.AddChild (Identifier.Create (p.Name, Convert (p.Location)), Roles.Identifier); + parameterDeclarationExpression.AddChild(Identifier.Create(p.Name, Convert(p.Location)), Roles.Identifier); if (p.HasDefaultValue) { if (location != null && location.Count > 1) - parameterDeclarationExpression.AddChild (new CSharpTokenNode (Convert (location [1])), Roles.Assign); - parameterDeclarationExpression.AddChild ((Expression)p.DefaultValue.Accept (this), Roles.Expression); + parameterDeclarationExpression.AddChild(new CSharpTokenNode(Convert(location [1]), Roles.Assign), Roles.Assign); + parameterDeclarationExpression.AddChild((Expression)p.DefaultValue.Accept(this), Roles.Expression); } - parent.AddChild (parameterDeclarationExpression, Roles.Parameter); + parent.AddChild(parameterDeclarationExpression, Roles.Parameter); if (paramLocation != null && i < paramLocation.Count) { - parent.AddChild (new CSharpTokenNode (Convert (paramLocation [i])), Roles.Comma); + parent.AddChild(new CSharpTokenNode(Convert(paramLocation [i]), Roles.Comma), Roles.Comma); } } } - - void AddTypeParameters (AstNode parent, MemberName memberName) + + void AddTypeParameters(AstNode parent, MemberName memberName) { if (memberName == null || memberName.TypeParameters == null) return; - var chevronLocs = LocationsBag.GetLocations (memberName.TypeParameters); + var chevronLocs = LocationsBag.GetLocations(memberName.TypeParameters); if (chevronLocs != null) - parent.AddChild (new CSharpTokenNode (Convert (chevronLocs [chevronLocs.Count - 2])), Roles.LChevron); + parent.AddChild(new CSharpTokenNode(Convert(chevronLocs [chevronLocs.Count - 2]), Roles.LChevron), Roles.LChevron); for (int i = 0; i < memberName.TypeParameters.Count; i++) { if (chevronLocs != null && i > 0 && i - 1 < chevronLocs.Count) - parent.AddChild (new CSharpTokenNode (Convert (chevronLocs [i - 1])), Roles.Comma); + parent.AddChild(new CSharpTokenNode(Convert(chevronLocs [i - 1]), Roles.Comma), Roles.Comma); var arg = memberName.TypeParameters [i]; if (arg == null) continue; - TypeParameterDeclaration tp = new TypeParameterDeclaration (); + var tp = new TypeParameterDeclaration(); List varianceLocation; switch (arg.Variance) { case Variance.Contravariant: tp.Variance = VarianceModifier.Contravariant; - varianceLocation = LocationsBag.GetLocations (arg); + varianceLocation = LocationsBag.GetLocations(arg); if (varianceLocation != null) - tp.AddChild (new CSharpTokenNode (Convert (varianceLocation [0])), TypeParameterDeclaration.InVarianceKeywordRole); + tp.AddChild(new CSharpTokenNode(Convert(varianceLocation [0]), TypeParameterDeclaration.InVarianceKeywordRole), TypeParameterDeclaration.InVarianceKeywordRole); break; case Variance.Covariant: tp.Variance = VarianceModifier.Covariant; - varianceLocation = LocationsBag.GetLocations (arg); + varianceLocation = LocationsBag.GetLocations(arg); if (varianceLocation != null) - tp.AddChild (new CSharpTokenNode (Convert (varianceLocation [0])), TypeParameterDeclaration.OutVarianceKeywordRole); + tp.AddChild(new CSharpTokenNode(Convert(varianceLocation [0]), TypeParameterDeclaration.OutVarianceKeywordRole), TypeParameterDeclaration.OutVarianceKeywordRole); break; default: tp.Variance = VarianceModifier.Invariant; @@ -2523,7 +2552,7 @@ namespace ICSharpCode.NRefactory.CSharp } - AddAttributeSection (tp, arg.OptAttributes); + AddAttributeSection(tp, arg.OptAttributes); switch (arg.Variance) { case Variance.Covariant: @@ -2533,201 +2562,226 @@ namespace ICSharpCode.NRefactory.CSharp tp.Variance = VarianceModifier.Contravariant; break; } - tp.AddChild (Identifier.Create (arg.Name, Convert (arg.Location)), Roles.Identifier); - parent.AddChild (tp, Roles.TypeParameter); + tp.AddChild(Identifier.Create(arg.Name, Convert(arg.Location)), Roles.Identifier); + parent.AddChild(tp, Roles.TypeParameter); } if (chevronLocs != null) - parent.AddChild (new CSharpTokenNode (Convert (chevronLocs [chevronLocs.Count - 1])), Roles.RChevron); + parent.AddChild(new CSharpTokenNode(Convert(chevronLocs [chevronLocs.Count - 1]), Roles.RChevron), Roles.RChevron); } - - void AddTypeArguments (AstNode parent, MemberName memberName) + + void AddTypeArguments(AstNode parent, MemberName memberName) { if (memberName == null || memberName.TypeParameters == null) return; - var chevronLocs = LocationsBag.GetLocations (memberName.TypeParameters); + var chevronLocs = LocationsBag.GetLocations(memberName.TypeParameters); if (chevronLocs != null) - parent.AddChild (new CSharpTokenNode (Convert (chevronLocs [chevronLocs.Count - 2])), Roles.LChevron); + parent.AddChild(new CSharpTokenNode(Convert(chevronLocs [chevronLocs.Count - 2]), Roles.LChevron), Roles.LChevron); for (int i = 0; i < memberName.TypeParameters.Count; i++) { var arg = memberName.TypeParameters [i]; if (arg == null) continue; - parent.AddChild (ConvertToType (arg), Roles.TypeArgument); + parent.AddChild(ConvertToType(arg), Roles.TypeArgument); if (chevronLocs != null && i < chevronLocs.Count - 2) - parent.AddChild (new CSharpTokenNode (Convert (chevronLocs [i])), Roles.Comma); + parent.AddChild(new CSharpTokenNode(Convert(chevronLocs [i]), Roles.Comma), Roles.Comma); } if (chevronLocs != null) - parent.AddChild (new CSharpTokenNode (Convert (chevronLocs [chevronLocs.Count - 1])), Roles.RChevron); + parent.AddChild(new CSharpTokenNode(Convert(chevronLocs [chevronLocs.Count - 1]), Roles.RChevron), Roles.RChevron); } - - void AddTypeArguments (AstNode parent, ATypeNameExpression memberName) + + void AddTypeArguments(AstNode parent, ATypeNameExpression memberName) { if (memberName == null || !memberName.HasTypeArguments) return; - var chevronLocs = LocationsBag.GetLocations (memberName.TypeArguments); + var chevronLocs = LocationsBag.GetLocations(memberName.TypeArguments); if (chevronLocs != null) - parent.AddChild (new CSharpTokenNode (Convert (chevronLocs [chevronLocs.Count - 2])), Roles.LChevron); + parent.AddChild(new CSharpTokenNode(Convert(chevronLocs [chevronLocs.Count - 2]), Roles.LChevron), Roles.LChevron); for (int i = 0; i < memberName.TypeArguments.Count; i++) { var arg = memberName.TypeArguments.Args [i]; if (arg == null) continue; - parent.AddChild (ConvertToType (arg), Roles.TypeArgument); + parent.AddChild(ConvertToType(arg), Roles.TypeArgument); if (chevronLocs != null && i < chevronLocs.Count - 2) - parent.AddChild (new CSharpTokenNode (Convert (chevronLocs [i])), Roles.Comma); + parent.AddChild(new CSharpTokenNode(Convert(chevronLocs [i]), Roles.Comma), Roles.Comma); } if (chevronLocs != null) - parent.AddChild (new CSharpTokenNode (Convert (chevronLocs [chevronLocs.Count - 1])), Roles.RChevron); + parent.AddChild(new CSharpTokenNode(Convert(chevronLocs [chevronLocs.Count - 1]), Roles.RChevron), Roles.RChevron); } - + void AddConstraints(AstNode parent, TypeParameters d) { if (d == null) return; - for (int i = d.Count - 1; i >= 0; i--) { + for (int i = 0; i < d.Count; i++) { var typeParameter = d [i]; if (typeParameter == null) continue; var c = typeParameter.Constraints; if (c == null) continue; - var location = LocationsBag.GetLocations (c); - var constraint = new Constraint (); - constraint.AddChild (new CSharpTokenNode (Convert (c.Location)), Roles.WhereKeyword); - constraint.AddChild (new SimpleType (Identifier.Create (c.TypeParameter.Value, Convert (c.TypeParameter.Location))), Roles.ConstraintTypeParameter); + var location = LocationsBag.GetLocations(c); + var constraint = new Constraint(); + constraint.AddChild(new CSharpTokenNode(Convert(c.Location), Roles.WhereKeyword), Roles.WhereKeyword); + constraint.AddChild(new SimpleType(Identifier.Create(c.TypeParameter.Value, Convert(c.TypeParameter.Location))), Roles.ConstraintTypeParameter); if (location != null) - constraint.AddChild (new CSharpTokenNode (Convert (location [0])), Roles.Colon); - var commaLocs = LocationsBag.GetLocations (c.ConstraintExpressions); + constraint.AddChild(new CSharpTokenNode(Convert(location [0]), Roles.Colon), Roles.Colon); + var commaLocs = LocationsBag.GetLocations(c.ConstraintExpressions); int curComma = 0; if (c.ConstraintExpressions != null) { foreach (var expr in c.ConstraintExpressions) { - constraint.AddChild (ConvertToType (expr), Roles.BaseType); + constraint.AddChild(ConvertToType(expr), Roles.BaseType); + var sce = expr as SpecialContraintExpr; + if (sce != null) { + switch (sce.Constraint) { + case SpecialConstraint.Class: + break; + case SpecialConstraint.Struct: + break; + case SpecialConstraint.Constructor: + var bl = LocationsBag.GetLocations(expr); + if (bl != null) { + constraint.AddChild(new CSharpTokenNode(Convert(bl [0]), Roles.LPar), Roles.LPar); + constraint.AddChild(new CSharpTokenNode(Convert(bl [1]), Roles.RPar), Roles.RPar); + } + break; + } + } + if (commaLocs != null && curComma < commaLocs.Count) - constraint.AddChild (new CSharpTokenNode (Convert (commaLocs [curComma++])), Roles.Comma); + constraint.AddChild(new CSharpTokenNode(Convert(commaLocs [curComma++]), Roles.Comma), Roles.Comma); } } - parent.AddChild (constraint, Roles.Constraint); + // We need to sort the constraints by position; as they might be in a different order than the type parameters + AstNode prevSibling = parent.LastChild; + while (prevSibling.StartLocation > constraint.StartLocation && prevSibling.PrevSibling != null) + prevSibling = prevSibling.PrevSibling; + parent.InsertChildAfter(prevSibling, constraint, Roles.Constraint); } } - - Expression ConvertArgument (Argument arg) + + Expression ConvertArgument(Argument arg) { - if (arg is NamedArgument) { - var na = (NamedArgument)arg; - NamedArgumentExpression newArg = new NamedArgumentExpression (); - newArg.AddChild (Identifier.Create (na.Name, Convert (na.Location)), Roles.Identifier); + var na = arg as NamedArgument; + if (na != null) { + var newArg = new NamedArgumentExpression(); + newArg.AddChild(Identifier.Create(na.Name, Convert(na.Location)), Roles.Identifier); - var loc = LocationsBag.GetLocations (na); + var loc = LocationsBag.GetLocations(na); if (loc != null) - newArg.AddChild (new CSharpTokenNode (Convert (loc [0])), Roles.Colon); + newArg.AddChild(new CSharpTokenNode(Convert(loc [0]), Roles.Colon), Roles.Colon); if (arg.ArgType == Argument.AType.Out || arg.ArgType == Argument.AType.Ref) { - DirectionExpression direction = new DirectionExpression (); + var direction = new DirectionExpression(); direction.FieldDirection = arg.ArgType == Argument.AType.Out ? FieldDirection.Out : FieldDirection.Ref; - var argLocation = LocationsBag.GetLocations (arg); - if (argLocation != null) - direction.AddChild (new CSharpTokenNode (Convert (argLocation [0])), arg.ArgType == Argument.AType.Out ? DirectionExpression.OutKeywordRole : DirectionExpression.RefKeywordRole); - direction.AddChild ((Expression)arg.Expr.Accept (this), Roles.Expression); - newArg.AddChild (direction, Roles.Expression); + var argLocation = LocationsBag.GetLocations(arg); + if (argLocation != null) { + var r = arg.ArgType == Argument.AType.Out ? DirectionExpression.OutKeywordRole : DirectionExpression.RefKeywordRole; + direction.AddChild(new CSharpTokenNode(Convert(argLocation [0]), r), r); + } + direction.AddChild((Expression)arg.Expr.Accept(this), Roles.Expression); + newArg.AddChild(direction, Roles.Expression); } else { - newArg.AddChild ((Expression)na.Expr.Accept (this), Roles.Expression); + newArg.AddChild(na.Expr != null ? (Expression)na.Expr.Accept(this) : new ErrorExpression("Named argument expression parse error"), Roles.Expression); } return newArg; } if (arg.ArgType == Argument.AType.Out || arg.ArgType == Argument.AType.Ref) { - DirectionExpression direction = new DirectionExpression (); + var direction = new DirectionExpression(); direction.FieldDirection = arg.ArgType == Argument.AType.Out ? FieldDirection.Out : FieldDirection.Ref; - var argLocation = LocationsBag.GetLocations (arg); - if (argLocation != null) - direction.AddChild (new CSharpTokenNode (Convert (argLocation [0])), arg.ArgType == Argument.AType.Out ? DirectionExpression.OutKeywordRole : DirectionExpression.RefKeywordRole); - direction.AddChild ((Expression)arg.Expr.Accept (this), Roles.Expression); + var argLocation = LocationsBag.GetLocations(arg); + if (argLocation != null) { + var r = arg.ArgType == Argument.AType.Out ? DirectionExpression.OutKeywordRole : DirectionExpression.RefKeywordRole; + direction.AddChild(new CSharpTokenNode(Convert(argLocation [0]), r), r); + } + direction.AddChild((Expression)arg.Expr.Accept(this), Roles.Expression); return direction; } - return (Expression)arg.Expr.Accept (this); + return (Expression)arg.Expr.Accept(this); } - - void AddArguments (AstNode parent, object location, Mono.CSharp.Arguments args) + + void AddArguments(AstNode parent, Arguments args) { if (args == null) return; - var commaLocations = LocationsBag.GetLocations (args); + var commaLocations = LocationsBag.GetLocations(args); for (int i = 0; i < args.Count; i++) { - parent.AddChild (ConvertArgument (args [i]), Roles.Argument); + parent.AddChild(ConvertArgument(args [i]), Roles.Argument); if (commaLocations != null && i < commaLocations.Count) { - parent.AddChild (new CSharpTokenNode (Convert (commaLocations [i])), Roles.Comma); + parent.AddChild(new CSharpTokenNode(Convert(commaLocations [i]), Roles.Comma), Roles.Comma); } } if (commaLocations != null && commaLocations.Count > args.Count) - parent.AddChild (new CSharpTokenNode (Convert (commaLocations [args.Count])), Roles.Comma); + parent.AddChild(new CSharpTokenNode(Convert(commaLocations [args.Count]), Roles.Comma), Roles.Comma); } - - public override object Visit (Invocation invocationExpression) + + public override object Visit(Invocation invocationExpression) { - var result = new InvocationExpression (); - var location = LocationsBag.GetLocations (invocationExpression); + var result = new InvocationExpression(); + var location = LocationsBag.GetLocations(invocationExpression); if (invocationExpression.Exp != null) - result.AddChild ((Expression)invocationExpression.Exp.Accept (this), Roles.TargetExpression); + result.AddChild((Expression)invocationExpression.Exp.Accept(this), Roles.TargetExpression); if (location != null) - result.AddChild (new CSharpTokenNode (Convert (location [0])), Roles.LPar); - AddArguments (result, location, invocationExpression.Arguments); + result.AddChild(new CSharpTokenNode(Convert(location [0]), Roles.LPar), Roles.LPar); + AddArguments(result, invocationExpression.Arguments); if (location != null && location.Count > 1) - result.AddChild (new CSharpTokenNode (Convert (location [1])), Roles.RPar); + result.AddChild(new CSharpTokenNode(Convert(location [1]), Roles.RPar), Roles.RPar); return result; } - - public override object Visit (New newExpression) + + public override object Visit(New newExpression) { - var result = new ObjectCreateExpression (); - var location = LocationsBag.GetLocations (newExpression); - result.AddChild (new CSharpTokenNode (Convert (newExpression.Location)), ObjectCreateExpression.NewKeywordRole); + var result = new ObjectCreateExpression(); + var location = LocationsBag.GetLocations(newExpression); + result.AddChild(new CSharpTokenNode(Convert(newExpression.Location), ObjectCreateExpression.NewKeywordRole), ObjectCreateExpression.NewKeywordRole); if (newExpression.TypeRequested != null) - result.AddChild (ConvertToType (newExpression.TypeRequested), Roles.Type); + result.AddChild(ConvertToType(newExpression.TypeRequested), Roles.Type); if (location != null) - result.AddChild (new CSharpTokenNode (Convert (location [0])), Roles.LPar); - AddArguments (result, location, newExpression.Arguments); + result.AddChild(new CSharpTokenNode(Convert(location [0]), Roles.LPar), Roles.LPar); + AddArguments(result, newExpression.Arguments); if (location != null && location.Count > 1) - result.AddChild (new CSharpTokenNode (Convert (location [1])), Roles.RPar); + result.AddChild(new CSharpTokenNode(Convert(location [1]), Roles.RPar), Roles.RPar); return result; } - - public override object Visit (NewAnonymousType newAnonymousType) + + public override object Visit(NewAnonymousType newAnonymousType) { - var result = new AnonymousTypeCreateExpression (); - var location = LocationsBag.GetLocations (newAnonymousType); - result.AddChild (new CSharpTokenNode (Convert (newAnonymousType.Location)), ObjectCreateExpression.NewKeywordRole); + var result = new AnonymousTypeCreateExpression(); + var location = LocationsBag.GetLocations(newAnonymousType); + result.AddChild(new CSharpTokenNode(Convert(newAnonymousType.Location), ObjectCreateExpression.NewKeywordRole), ObjectCreateExpression.NewKeywordRole); if (location != null) - result.AddChild (new CSharpTokenNode (Convert (location [0])), Roles.LBrace); + result.AddChild(new CSharpTokenNode(Convert(location [0]), Roles.LBrace), Roles.LBrace); if (newAnonymousType.Parameters != null) { foreach (var par in newAnonymousType.Parameters) { if (par == null) continue; - var parLocation = LocationsBag.GetLocations (par); + var parLocation = LocationsBag.GetLocations(par); if (parLocation == null) { if (par.Expr != null) - result.AddChild ((Expression)par.Expr.Accept (this), Roles.Expression); + result.AddChild((Expression)par.Expr.Accept(this), Roles.Expression); } else { - var namedExpression = new NamedExpression (); - namedExpression.AddChild (Identifier.Create (par.Name, Convert (par.Location)), Roles.Identifier); - namedExpression.AddChild (new CSharpTokenNode (Convert (parLocation [0])), Roles.Assign); + var namedExpression = new NamedExpression(); + namedExpression.AddChild(Identifier.Create(par.Name, Convert(par.Location)), Roles.Identifier); + namedExpression.AddChild(new CSharpTokenNode(Convert(parLocation [0]), Roles.Assign), Roles.Assign); if (par.Expr != null) - namedExpression.AddChild ((Expression)par.Expr.Accept (this), Roles.Expression); - result.AddChild (namedExpression, Roles.Expression); + namedExpression.AddChild((Expression)par.Expr.Accept(this), Roles.Expression); + result.AddChild(namedExpression, Roles.Expression); } } } if (location != null && location.Count > 1) - result.AddChild (new CSharpTokenNode (Convert (location [1])), Roles.RBrace); + result.AddChild(new CSharpTokenNode(Convert(location [1]), Roles.RBrace), Roles.RBrace); return result; } @@ -2745,8 +2799,7 @@ namespace ICSharpCode.NRefactory.CSharp var initLoc = LocationsBag.GetLocations(minit); var commaLoc = LocationsBag.GetLocations(minit.Initializers); int curComma = 0; - if (initLoc != null) - init.AddChild(new CSharpTokenNode(Convert(initLoc [0])), Roles.LBrace); + init.AddChild(new CSharpTokenNode(Convert(minit.Location), Roles.LBrace), Roles.LBrace); foreach (var expr in minit.Initializers) { var collectionInit = expr as CollectionElementInitializer; if (collectionInit != null) { @@ -2756,24 +2809,27 @@ namespace ICSharpCode.NRefactory.CSharp // can be identified by expr.IsSingleElement. if (!collectionInit.IsSingle) { parent = new ArrayInitializerExpression(); - parent.AddChild(new CSharpTokenNode(Convert(collectionInit.Location)), Roles.LBrace); + parent.AddChild(new CSharpTokenNode(Convert(collectionInit.Location), Roles.LBrace), Roles.LBrace); } else { - parent = ArrayInitializerExpression.CreateSingleElementInitializer (); + parent = ArrayInitializerExpression.CreateSingleElementInitializer(); } - for (int i = 0; i < collectionInit.Arguments.Count; i++) { - var arg = collectionInit.Arguments [i] as CollectionElementInitializer.ElementInitializerArgument; - if (arg == null) - continue; - parent.AddChild( - (ICSharpCode.NRefactory.CSharp.Expression)arg.Expr.Accept(this), - Roles.Expression - ); + + if (collectionInit.Arguments != null) { + for (int i = 0; i < collectionInit.Arguments.Count; i++) { + var arg = collectionInit.Arguments [i] as CollectionElementInitializer.ElementInitializerArgument; + if (arg == null || arg.Expr == null) + continue; + parent.AddChild( + (Expression)arg.Expr.Accept(this), + Roles.Expression + ); + } } if (!collectionInit.IsSingle) { var braceLocs = LocationsBag.GetLocations(expr); if (braceLocs != null) - parent.AddChild(new CSharpTokenNode(Convert(braceLocs [0])), Roles.RBrace); + parent.AddChild(new CSharpTokenNode(Convert(braceLocs [0]), Roles.RBrace), Roles.RBrace); } init.AddChild((ArrayInitializerExpression)parent, Roles.Expression); } else { @@ -2786,13 +2842,14 @@ namespace ICSharpCode.NRefactory.CSharp ); var assignLoc = LocationsBag.GetLocations(eleInit); if (assignLoc != null) - nexpr.AddChild(new CSharpTokenNode(Convert(assignLoc [0])), Roles.Assign); + nexpr.AddChild(new CSharpTokenNode(Convert(assignLoc [0]), Roles.Assign), Roles.Assign); if (eleInit.Source != null) { - if (eleInit.Source is CollectionOrObjectInitializers) { + var colInit = eleInit.Source as CollectionOrObjectInitializers; + if (colInit != null) { var arrInit = new ArrayInitializerExpression(); AddConvertCollectionOrObjectInitializers( arrInit, - eleInit.Source as CollectionOrObjectInitializers + colInit ); nexpr.AddChild(arrInit, Roles.Expression); } else { @@ -2804,47 +2861,46 @@ namespace ICSharpCode.NRefactory.CSharp } } if (commaLoc != null && curComma < commaLoc.Count) - init.AddChild(new CSharpTokenNode(Convert(commaLoc [curComma++])), Roles.Comma); + init.AddChild(new CSharpTokenNode(Convert(commaLoc [curComma++]), Roles.Comma), Roles.Comma); } if (initLoc != null) { - if (initLoc.Count == 3) // optional comma - init.AddChild(new CSharpTokenNode(Convert(initLoc [1])), Roles.Comma); - init.AddChild(new CSharpTokenNode(Convert(initLoc [initLoc.Count - 1])), Roles.RBrace); + if (initLoc.Count == 2) // optional comma + init.AddChild(new CSharpTokenNode(Convert(initLoc [0]), Roles.Comma), Roles.Comma); + init.AddChild(new CSharpTokenNode(Convert(initLoc [initLoc.Count - 1]), Roles.RBrace), Roles.RBrace); } } - - public override object Visit (NewInitialize newInitializeExpression) + public override object Visit(NewInitialize newInitializeExpression) { - var result = new ObjectCreateExpression (); - result.AddChild (new CSharpTokenNode (Convert (newInitializeExpression.Location)), ObjectCreateExpression.NewKeywordRole); + var result = new ObjectCreateExpression(); + result.AddChild(new CSharpTokenNode(Convert(newInitializeExpression.Location), ObjectCreateExpression.NewKeywordRole), ObjectCreateExpression.NewKeywordRole); if (newInitializeExpression.TypeRequested != null) - result.AddChild (ConvertToType (newInitializeExpression.TypeRequested), Roles.Type); + result.AddChild(ConvertToType(newInitializeExpression.TypeRequested), Roles.Type); - var location = LocationsBag.GetLocations (newInitializeExpression); + var location = LocationsBag.GetLocations(newInitializeExpression); if (location != null) - result.AddChild (new CSharpTokenNode (Convert (location [0])), Roles.LPar); - AddArguments (result, location, newInitializeExpression.Arguments); + result.AddChild(new CSharpTokenNode(Convert(location [0]), Roles.LPar), Roles.LPar); + AddArguments(result, newInitializeExpression.Arguments); if (location != null && location.Count > 1) - result.AddChild (new CSharpTokenNode (Convert (location [1])), Roles.RPar); + result.AddChild(new CSharpTokenNode(Convert(location [1]), Roles.RPar), Roles.RPar); - var init = ConvertCollectionOrObjectInitializers (newInitializeExpression.Initializers); + var init = ConvertCollectionOrObjectInitializers(newInitializeExpression.Initializers); if (init != null) - result.AddChild (init, ObjectCreateExpression.InitializerRole); + result.AddChild(init, ObjectCreateExpression.InitializerRole); return result; } - - public override object Visit (ArrayCreation arrayCreationExpression) + + public override object Visit(ArrayCreation arrayCreationExpression) { - var result = new ArrayCreateExpression (); + var result = new ArrayCreateExpression(); - var location = LocationsBag.GetLocations (arrayCreationExpression); - result.AddChild (new CSharpTokenNode (Convert (arrayCreationExpression.Location)), ArrayCreateExpression.NewKeywordRole); + var location = LocationsBag.GetLocations(arrayCreationExpression); + result.AddChild(new CSharpTokenNode(Convert(arrayCreationExpression.Location), ArrayCreateExpression.NewKeywordRole), ArrayCreateExpression.NewKeywordRole); if (arrayCreationExpression.TypeExpression != null) - result.AddChild (ConvertToType (arrayCreationExpression.TypeExpression), Roles.Type); + result.AddChild(ConvertToType(arrayCreationExpression.TypeExpression), Roles.Type); var next = arrayCreationExpression.Rank; if (arrayCreationExpression.Arguments != null) { @@ -2852,252 +2908,256 @@ namespace ICSharpCode.NRefactory.CSharp next = next.Next; if (location != null) - result.AddChild (new CSharpTokenNode (Convert (location [0])), Roles.LBracket); + result.AddChild(new CSharpTokenNode(Convert(location [0]), Roles.LBracket), Roles.LBracket); - var commaLocations = LocationsBag.GetLocations (arrayCreationExpression.Arguments); + var commaLocations = LocationsBag.GetLocations(arrayCreationExpression.Arguments); for (int i = 0; i < arrayCreationExpression.Arguments.Count; i++) { - result.AddChild ((Expression)arrayCreationExpression.Arguments [i].Accept (this), Roles.Argument); + var arg = arrayCreationExpression.Arguments [i]; + if (arg != null) + result.AddChild((Expression)arg.Accept(this), Roles.Argument); if (commaLocations != null && i < commaLocations.Count) - result.AddChild (new CSharpTokenNode (Convert (commaLocations [i])), Roles.Comma); + result.AddChild(new CSharpTokenNode(Convert(commaLocations [i]), Roles.Comma), Roles.Comma); } if (location != null && location.Count > 1) - result.AddChild (new CSharpTokenNode (Convert (location [1])), Roles.RBracket); + result.AddChild(new CSharpTokenNode(Convert(location [1]), Roles.RBracket), Roles.RBracket); } while (next != null) { - ArraySpecifier spec = new ArraySpecifier (next.Dimension); - var loc = LocationsBag.GetLocations (next); - spec.AddChild (new CSharpTokenNode (Convert (next.Location)), Roles.LBracket); - result.AddChild (spec, ArrayCreateExpression.AdditionalArraySpecifierRole); + var spec = new ArraySpecifier(next.Dimension); + var loc = LocationsBag.GetLocations(next); + spec.AddChild(new CSharpTokenNode(Convert(next.Location), Roles.LBracket), Roles.LBracket); + result.AddChild(spec, ArrayCreateExpression.AdditionalArraySpecifierRole); if (loc != null) - result.AddChild (new CSharpTokenNode (Convert (loc [0])), Roles.RBracket); + result.AddChild(new CSharpTokenNode(Convert(loc [0]), Roles.RBracket), Roles.RBracket); next = next.Next; } if (arrayCreationExpression.Initializers != null) { - var initLocation = LocationsBag.GetLocations (arrayCreationExpression.Initializers); - ArrayInitializerExpression initializer = new ArrayInitializerExpression (); + var initLocation = LocationsBag.GetLocations(arrayCreationExpression.Initializers); + var initializer = new ArrayInitializerExpression(); - initializer.AddChild (new CSharpTokenNode (Convert (arrayCreationExpression.Initializers.Location)), Roles.LBrace); - var commaLocations = LocationsBag.GetLocations (arrayCreationExpression.Initializers.Elements); + initializer.AddChild(new CSharpTokenNode(Convert(arrayCreationExpression.Initializers.Location), Roles.LBrace), Roles.LBrace); + var commaLocations = LocationsBag.GetLocations(arrayCreationExpression.Initializers.Elements); for (int i = 0; i < arrayCreationExpression.Initializers.Count; i++) { var init = arrayCreationExpression.Initializers [i]; if (init == null) continue; - initializer.AddChild ((Expression)init.Accept (this), Roles.Expression); + initializer.AddChild((Expression)init.Accept(this), Roles.Expression); if (commaLocations != null && i < commaLocations.Count) { - initializer.AddChild (new CSharpTokenNode (Convert (commaLocations [i])), Roles.Comma); + initializer.AddChild(new CSharpTokenNode(Convert(commaLocations [i]), Roles.Comma), Roles.Comma); } } if (initLocation != null) { if (initLocation.Count == 2) // optional comma - initializer.AddChild (new CSharpTokenNode(Convert(initLocation [0])), Roles.Comma); - initializer.AddChild (new CSharpTokenNode (Convert (initLocation [initLocation.Count - 1])), Roles.RBrace); + initializer.AddChild(new CSharpTokenNode(Convert(initLocation [0]), Roles.Comma), Roles.Comma); + initializer.AddChild(new CSharpTokenNode(Convert(initLocation [initLocation.Count - 1]), Roles.RBrace), Roles.RBrace); } - result.AddChild (initializer, ArrayCreateExpression.InitializerRole); + result.AddChild(initializer, ArrayCreateExpression.InitializerRole); } return result; } - - public override object Visit (This thisExpression) + + public override object Visit(This thisExpression) { - var result = new ThisReferenceExpression (); - result.Location = Convert (thisExpression.Location); + var result = new ThisReferenceExpression(); + result.Location = Convert(thisExpression.Location); return result; } - - public override object Visit (ArglistAccess argListAccessExpression) + + public override object Visit(ArglistAccess argListAccessExpression) { - var result = new UndocumentedExpression () { + var result = new UndocumentedExpression { UndocumentedExpressionType = UndocumentedExpressionType.ArgListAccess }; - result.AddChild (new CSharpTokenNode (Convert (argListAccessExpression.Location)), UndocumentedExpression.ArglistKeywordRole); + result.AddChild(new CSharpTokenNode(Convert(argListAccessExpression.Location), UndocumentedExpression.ArglistKeywordRole), UndocumentedExpression.ArglistKeywordRole); return result; } - + #region Undocumented expressions - public override object Visit (Arglist argListExpression) + + public override object Visit(Arglist argListExpression) { - var result = new UndocumentedExpression () { UndocumentedExpressionType = UndocumentedExpressionType.ArgList }; - result.AddChild (new CSharpTokenNode (Convert (argListExpression.Location)), UndocumentedExpression.ArglistKeywordRole); - var location = LocationsBag.GetLocations (argListExpression); + var result = new UndocumentedExpression { UndocumentedExpressionType = UndocumentedExpressionType.ArgList }; + result.AddChild(new CSharpTokenNode(Convert(argListExpression.Location), UndocumentedExpression.ArglistKeywordRole), UndocumentedExpression.ArglistKeywordRole); + var location = LocationsBag.GetLocations(argListExpression); if (location != null) - result.AddChild (new CSharpTokenNode (Convert (location [0])), Roles.LPar); + result.AddChild(new CSharpTokenNode(Convert(location [0]), Roles.LPar), Roles.LPar); - AddArguments (result, location, argListExpression.Arguments); + AddArguments(result, argListExpression.Arguments); if (location != null && location.Count > 1) - result.AddChild (new CSharpTokenNode (Convert (location [1])), Roles.RPar); + result.AddChild(new CSharpTokenNode(Convert(location [1]), Roles.RPar), Roles.RPar); return result; } - - public override object Visit (MakeRefExpr makeRefExpr) + + public override object Visit(MakeRefExpr makeRefExpr) { - var result = new UndocumentedExpression () { UndocumentedExpressionType = UndocumentedExpressionType.MakeRef }; - result.AddChild (new CSharpTokenNode (Convert (makeRefExpr.Location)), UndocumentedExpression.MakerefKeywordRole); - var location = LocationsBag.GetLocations (makeRefExpr); + var result = new UndocumentedExpression { UndocumentedExpressionType = UndocumentedExpressionType.MakeRef }; + result.AddChild(new CSharpTokenNode(Convert(makeRefExpr.Location), UndocumentedExpression.MakerefKeywordRole), UndocumentedExpression.MakerefKeywordRole); + var location = LocationsBag.GetLocations(makeRefExpr); if (location != null) - result.AddChild (new CSharpTokenNode (Convert (location [0])), Roles.LPar); + result.AddChild(new CSharpTokenNode(Convert(location [0]), Roles.LPar), Roles.LPar); if (makeRefExpr.Expr != null) - result.AddChild ((Expression)makeRefExpr.Expr.Accept (this), Roles.Argument); + result.AddChild((Expression)makeRefExpr.Expr.Accept(this), Roles.Argument); if (location != null && location.Count > 1) - result.AddChild (new CSharpTokenNode (Convert (location [1])), Roles.RPar); + result.AddChild(new CSharpTokenNode(Convert(location [1]), Roles.RPar), Roles.RPar); return result; } - - public override object Visit (RefTypeExpr refTypeExpr) + + public override object Visit(RefTypeExpr refTypeExpr) { - var result = new UndocumentedExpression () { UndocumentedExpressionType = UndocumentedExpressionType.RefType }; - result.AddChild (new CSharpTokenNode (Convert (refTypeExpr.Location)), UndocumentedExpression.ReftypeKeywordRole); - var location = LocationsBag.GetLocations (refTypeExpr); + var result = new UndocumentedExpression { UndocumentedExpressionType = UndocumentedExpressionType.RefType }; + result.AddChild(new CSharpTokenNode(Convert(refTypeExpr.Location), UndocumentedExpression.ReftypeKeywordRole), UndocumentedExpression.ReftypeKeywordRole); + var location = LocationsBag.GetLocations(refTypeExpr); if (location != null) - result.AddChild (new CSharpTokenNode (Convert (location [0])), Roles.LPar); + result.AddChild(new CSharpTokenNode(Convert(location [0]), Roles.LPar), Roles.LPar); if (refTypeExpr.Expr != null) - result.AddChild ((Expression)refTypeExpr.Expr.Accept (this), Roles.Argument); + result.AddChild((Expression)refTypeExpr.Expr.Accept(this), Roles.Argument); if (location != null && location.Count > 1) - result.AddChild (new CSharpTokenNode (Convert (location [1])), Roles.RPar); + result.AddChild(new CSharpTokenNode(Convert(location [1]), Roles.RPar), Roles.RPar); return result; } - - public override object Visit (RefValueExpr refValueExpr) + + public override object Visit(RefValueExpr refValueExpr) { - var result = new UndocumentedExpression () { UndocumentedExpressionType = UndocumentedExpressionType.RefValue }; - result.AddChild (new CSharpTokenNode (Convert (refValueExpr.Location)), UndocumentedExpression.RefvalueKeywordRole); - var location = LocationsBag.GetLocations (refValueExpr); + var result = new UndocumentedExpression { UndocumentedExpressionType = UndocumentedExpressionType.RefValue }; + result.AddChild(new CSharpTokenNode(Convert(refValueExpr.Location), UndocumentedExpression.RefvalueKeywordRole), UndocumentedExpression.RefvalueKeywordRole); + var location = LocationsBag.GetLocations(refValueExpr); if (location != null) - result.AddChild (new CSharpTokenNode (Convert (location [0])), Roles.LPar); + result.AddChild(new CSharpTokenNode(Convert(location [0]), Roles.LPar), Roles.LPar); if (refValueExpr.Expr != null) - result.AddChild ((Expression)refValueExpr.Expr.Accept (this), Roles.Argument); + result.AddChild((Expression)refValueExpr.Expr.Accept(this), Roles.Argument); if (refValueExpr.FullNamedExpression != null) - result.AddChild ((Expression)refValueExpr.FullNamedExpression.Accept (this), Roles.Argument); + result.AddChild((Expression)refValueExpr.FullNamedExpression.Accept(this), Roles.Argument); if (location != null && location.Count > 1) - result.AddChild (new CSharpTokenNode (Convert (location [1])), Roles.RPar); + result.AddChild(new CSharpTokenNode(Convert(location [1]), Roles.RPar), Roles.RPar); return result; } + #endregion - - public override object Visit (TypeOf typeOfExpression) + + public override object Visit(TypeOf typeOfExpression) { - var result = new TypeOfExpression (); - var location = LocationsBag.GetLocations (typeOfExpression); - result.AddChild (new CSharpTokenNode (Convert (typeOfExpression.Location)), TypeOfExpression.TypeofKeywordRole); + var result = new TypeOfExpression(); + var location = LocationsBag.GetLocations(typeOfExpression); + result.AddChild(new CSharpTokenNode(Convert(typeOfExpression.Location), TypeOfExpression.TypeofKeywordRole), TypeOfExpression.TypeofKeywordRole); if (location != null) - result.AddChild (new CSharpTokenNode (Convert (location [0])), Roles.LPar); + result.AddChild(new CSharpTokenNode(Convert(location [0]), Roles.LPar), Roles.LPar); if (typeOfExpression.TypeExpression != null) - result.AddChild (ConvertToType (typeOfExpression.TypeExpression), Roles.Type); + result.AddChild(ConvertToType(typeOfExpression.TypeExpression), Roles.Type); if (location != null && location.Count > 1) - result.AddChild (new CSharpTokenNode (Convert (location [1])), Roles.RPar); + result.AddChild(new CSharpTokenNode(Convert(location [1]), Roles.RPar), Roles.RPar); return result; } - - public override object Visit (SizeOf sizeOfExpression) + + public override object Visit(SizeOf sizeOfExpression) { - var result = new SizeOfExpression (); - var location = LocationsBag.GetLocations (sizeOfExpression); - result.AddChild (new CSharpTokenNode (Convert (sizeOfExpression.Location)), SizeOfExpression.SizeofKeywordRole); + var result = new SizeOfExpression(); + var location = LocationsBag.GetLocations(sizeOfExpression); + result.AddChild(new CSharpTokenNode(Convert(sizeOfExpression.Location), SizeOfExpression.SizeofKeywordRole), SizeOfExpression.SizeofKeywordRole); if (location != null) - result.AddChild (new CSharpTokenNode (Convert (location [0])), Roles.LPar); + result.AddChild(new CSharpTokenNode(Convert(location [0]), Roles.LPar), Roles.LPar); if (sizeOfExpression.TypeExpression != null) - result.AddChild (ConvertToType (sizeOfExpression.TypeExpression), Roles.Type); + result.AddChild(ConvertToType(sizeOfExpression.TypeExpression), Roles.Type); if (location != null && location.Count > 1) - result.AddChild (new CSharpTokenNode (Convert (location [1])), Roles.RPar); + result.AddChild(new CSharpTokenNode(Convert(location [1]), Roles.RPar), Roles.RPar); return result; } - - public override object Visit (CheckedExpr checkedExpression) + + public override object Visit(CheckedExpr checkedExpression) { - var result = new CheckedExpression (); - var location = LocationsBag.GetLocations (checkedExpression); - result.AddChild (new CSharpTokenNode (Convert (checkedExpression.Location)), CheckedExpression.CheckedKeywordRole); + var result = new CheckedExpression(); + var location = LocationsBag.GetLocations(checkedExpression); + result.AddChild(new CSharpTokenNode(Convert(checkedExpression.Location), CheckedExpression.CheckedKeywordRole), CheckedExpression.CheckedKeywordRole); if (location != null) - result.AddChild (new CSharpTokenNode (Convert (location [0])), Roles.LPar); + result.AddChild(new CSharpTokenNode(Convert(location [0]), Roles.LPar), Roles.LPar); if (checkedExpression.Expr != null) - result.AddChild ((Expression)checkedExpression.Expr.Accept (this), Roles.Expression); + result.AddChild((Expression)checkedExpression.Expr.Accept(this), Roles.Expression); if (location != null && location.Count > 1) - result.AddChild (new CSharpTokenNode (Convert (location [1])), Roles.RPar); + result.AddChild(new CSharpTokenNode(Convert(location [1]), Roles.RPar), Roles.RPar); return result; } - - public override object Visit (UnCheckedExpr uncheckedExpression) + + public override object Visit(UnCheckedExpr uncheckedExpression) { - var result = new UncheckedExpression (); - var location = LocationsBag.GetLocations (uncheckedExpression); - result.AddChild (new CSharpTokenNode (Convert (uncheckedExpression.Location)), UncheckedExpression.UncheckedKeywordRole); + var result = new UncheckedExpression(); + var location = LocationsBag.GetLocations(uncheckedExpression); + result.AddChild(new CSharpTokenNode(Convert(uncheckedExpression.Location), UncheckedExpression.UncheckedKeywordRole), UncheckedExpression.UncheckedKeywordRole); if (location != null) - result.AddChild (new CSharpTokenNode (Convert (location [0])), Roles.LPar); + result.AddChild(new CSharpTokenNode(Convert(location [0]), Roles.LPar), Roles.LPar); if (uncheckedExpression.Expr != null) - result.AddChild ((Expression)uncheckedExpression.Expr.Accept (this), Roles.Expression); + result.AddChild((Expression)uncheckedExpression.Expr.Accept(this), Roles.Expression); if (location != null && location.Count > 1) - result.AddChild (new CSharpTokenNode (Convert (location [1])), Roles.RPar); + result.AddChild(new CSharpTokenNode(Convert(location [1]), Roles.RPar), Roles.RPar); return result; } - - public override object Visit (ElementAccess elementAccessExpression) + + public override object Visit(ElementAccess elementAccessExpression) { - IndexerExpression result = new IndexerExpression (); - var location = LocationsBag.GetLocations (elementAccessExpression); + var result = new IndexerExpression(); + var location = LocationsBag.GetLocations(elementAccessExpression); if (elementAccessExpression.Expr != null) - result.AddChild ((Expression)elementAccessExpression.Expr.Accept (this), Roles.TargetExpression); - result.AddChild (new CSharpTokenNode (Convert (elementAccessExpression.Location)), Roles.LBracket); - AddArguments (result, location, elementAccessExpression.Arguments); + result.AddChild((Expression)elementAccessExpression.Expr.Accept(this), Roles.TargetExpression); + result.AddChild(new CSharpTokenNode(Convert(elementAccessExpression.Location), Roles.LBracket), Roles.LBracket); + AddArguments(result, elementAccessExpression.Arguments); if (location != null) - result.AddChild (new CSharpTokenNode (Convert (location [0])), Roles.RBracket); + result.AddChild(new CSharpTokenNode(Convert(location [0]), Roles.RBracket), Roles.RBracket); return result; } - - public override object Visit (BaseThis baseAccessExpression) + + public override object Visit(BaseThis baseAccessExpression) { - var result = new BaseReferenceExpression (); - result.Location = Convert (baseAccessExpression.Location); + var result = new BaseReferenceExpression(); + result.Location = Convert(baseAccessExpression.Location); return result; } - - public override object Visit (StackAlloc stackAllocExpression) + + public override object Visit(StackAlloc stackAllocExpression) { - var result = new StackAllocExpression (); + var result = new StackAllocExpression(); - var location = LocationsBag.GetLocations (stackAllocExpression); + var location = LocationsBag.GetLocations(stackAllocExpression); if (location != null) - result.AddChild (new CSharpTokenNode (Convert (location [0])), StackAllocExpression.StackallocKeywordRole); + result.AddChild(new CSharpTokenNode(Convert(location [0]), StackAllocExpression.StackallocKeywordRole), StackAllocExpression.StackallocKeywordRole); if (stackAllocExpression.TypeExpression != null) - result.AddChild (ConvertToType (stackAllocExpression.TypeExpression), Roles.Type); + result.AddChild(ConvertToType(stackAllocExpression.TypeExpression), Roles.Type); if (location != null && location.Count > 1) - result.AddChild (new CSharpTokenNode (Convert (location [1])), Roles.LBracket); + result.AddChild(new CSharpTokenNode(Convert(location [1]), Roles.LBracket), Roles.LBracket); if (stackAllocExpression.CountExpression != null) - result.AddChild ((Expression)stackAllocExpression.CountExpression.Accept (this), Roles.Expression); + result.AddChild((Expression)stackAllocExpression.CountExpression.Accept(this), Roles.Expression); if (location != null && location.Count > 2) - result.AddChild (new CSharpTokenNode (Convert (location [2])), Roles.RBracket); + result.AddChild(new CSharpTokenNode(Convert(location [2]), Roles.RBracket), Roles.RBracket); return result; } - - public override object Visit (SimpleAssign simpleAssign) + + public override object Visit(SimpleAssign simpleAssign) { - var result = new AssignmentExpression (); + var result = new AssignmentExpression(); result.Operator = AssignmentOperatorType.Assign; if (simpleAssign.Target != null) - result.AddChild ((Expression)simpleAssign.Target.Accept (this), AssignmentExpression.LeftRole); - var location = LocationsBag.GetLocations (simpleAssign); + result.AddChild((Expression)simpleAssign.Target.Accept(this), AssignmentExpression.LeftRole); + var location = LocationsBag.GetLocations(simpleAssign); if (location != null) - result.AddChild (new CSharpTokenNode (Convert (location[0])), AssignmentExpression.AssignRole); + result.AddChild(new CSharpTokenNode(Convert(location [0]), AssignmentExpression.AssignRole), AssignmentExpression.AssignRole); if (simpleAssign.Source != null) { - result.AddChild ((Expression)simpleAssign.Source.Accept (this), AssignmentExpression.RightRole); + result.AddChild((Expression)simpleAssign.Source.Accept(this), AssignmentExpression.RightRole); } return result; } - - public override object Visit (CompoundAssign compoundAssign) + + public override object Visit(CompoundAssign compoundAssign) { - var result = new AssignmentExpression (); + var result = new AssignmentExpression(); switch (compoundAssign.Op) { case Binary.Operator.Multiply: result.Operator = AssignmentOperatorType.Multiply; @@ -3132,375 +3192,389 @@ namespace ICSharpCode.NRefactory.CSharp } if (compoundAssign.Target != null) - result.AddChild ((Expression)compoundAssign.Target.Accept (this), AssignmentExpression.LeftRole); - var location = LocationsBag.GetLocations (compoundAssign); - if (location != null) - result.AddChild (new CSharpTokenNode (Convert (location[0])), AssignmentExpression.GetOperatorRole (result.Operator)); + result.AddChild((Expression)compoundAssign.Target.Accept(this), AssignmentExpression.LeftRole); + var location = LocationsBag.GetLocations(compoundAssign); + if (location != null) { + var r = AssignmentExpression.GetOperatorRole(result.Operator); + result.AddChild(new CSharpTokenNode(Convert(location [0]), r), r); + } if (compoundAssign.Source != null) - result.AddChild ((Expression)compoundAssign.Source.Accept (this), AssignmentExpression.RightRole); + result.AddChild((Expression)compoundAssign.Source.Accept(this), AssignmentExpression.RightRole); return result; } - - public override object Visit (Mono.CSharp.AnonymousMethodExpression anonymousMethodExpression) + + public override object Visit(Mono.CSharp.AnonymousMethodExpression anonymousMethodExpression) { - var result = new AnonymousMethodExpression (); - var location = LocationsBag.GetLocations (anonymousMethodExpression); + var result = new AnonymousMethodExpression(); + var location = LocationsBag.GetLocations(anonymousMethodExpression); int l = 0; if (anonymousMethodExpression.IsAsync) { result.IsAsync = true; - result.AddChild (new CSharpTokenNode (Convert (location [l++])), AnonymousMethodExpression.AsyncModifierRole); + result.AddChild(new CSharpTokenNode(Convert(location [l++]), AnonymousMethodExpression.AsyncModifierRole), AnonymousMethodExpression.AsyncModifierRole); } if (location != null) { - result.AddChild (new CSharpTokenNode (Convert (location [l++])), AnonymousMethodExpression.DelegateKeywordRole); + result.AddChild(new CSharpTokenNode(Convert(location [l++]), AnonymousMethodExpression.DelegateKeywordRole), AnonymousMethodExpression.DelegateKeywordRole); if (location.Count > l) { result.HasParameterList = true; - result.AddChild (new CSharpTokenNode (Convert (location [l++])), Roles.LPar); - AddParameter (result, anonymousMethodExpression.Parameters); - result.AddChild (new CSharpTokenNode (Convert (location [l++])), Roles.RPar); + result.AddChild(new CSharpTokenNode(Convert(location [l++]), Roles.LPar), Roles.LPar); + AddParameter(result, anonymousMethodExpression.Parameters); + result.AddChild(new CSharpTokenNode(Convert(location [l++]), Roles.RPar), Roles.RPar); } } if (anonymousMethodExpression.Block != null) - result.AddChild ((BlockStatement)anonymousMethodExpression.Block.Accept (this), Roles.Body); + result.AddChild((BlockStatement)anonymousMethodExpression.Block.Accept(this), Roles.Body); return result; } - public override object Visit (Mono.CSharp.LambdaExpression lambdaExpression) + public override object Visit(Mono.CSharp.LambdaExpression lambdaExpression) { - var result = new LambdaExpression (); - var location = LocationsBag.GetLocations (lambdaExpression); + var result = new LambdaExpression(); + var location = LocationsBag.GetLocations(lambdaExpression); int l = 0; if (lambdaExpression.IsAsync) { result.IsAsync = true; - result.AddChild (new CSharpTokenNode (Convert (location [l++])), LambdaExpression.AsyncModifierRole); + result.AddChild(new CSharpTokenNode(Convert(location [l++]), LambdaExpression.AsyncModifierRole), LambdaExpression.AsyncModifierRole); } - if (location == null || location.Count == l + 1) { - AddParameter (result, lambdaExpression.Parameters); + if (lambdaExpression.Block != null) + AddParameter(result, lambdaExpression.Parameters); if (location != null) - result.AddChild (new CSharpTokenNode (Convert (location [l++])), LambdaExpression.ArrowRole); + result.AddChild(new CSharpTokenNode(Convert(location [l++]), LambdaExpression.ArrowRole), LambdaExpression.ArrowRole); } else { - result.AddChild (new CSharpTokenNode (Convert (location [l++])), Roles.LPar); - AddParameter (result, lambdaExpression.Parameters); + result.AddChild(new CSharpTokenNode(Convert(location [l++]), Roles.LPar), Roles.LPar); + if (lambdaExpression.Block != null) + AddParameter(result, lambdaExpression.Parameters); if (location != null) { - result.AddChild (new CSharpTokenNode (Convert (location [l++])), Roles.RPar); - result.AddChild (new CSharpTokenNode (Convert (location [l++])), LambdaExpression.ArrowRole); + result.AddChild(new CSharpTokenNode(Convert(location [l++]), Roles.RPar), Roles.RPar); + result.AddChild(new CSharpTokenNode(Convert(location [l++]), LambdaExpression.ArrowRole), LambdaExpression.ArrowRole); } } if (lambdaExpression.Block != null) { if (lambdaExpression.Block.IsCompilerGenerated) { - ContextualReturn generatedReturn = (ContextualReturn)lambdaExpression.Block.Statements [0]; - result.AddChild ((AstNode)generatedReturn.Expr.Accept (this), LambdaExpression.BodyRole); + var generatedReturn = (ContextualReturn)lambdaExpression.Block.Statements [0]; + result.AddChild((AstNode)generatedReturn.Expr.Accept(this), LambdaExpression.BodyRole); } else { - result.AddChild ((AstNode)lambdaExpression.Block.Accept (this), LambdaExpression.BodyRole); + result.AddChild((AstNode)lambdaExpression.Block.Accept(this), LambdaExpression.BodyRole); } } - return result; } - - public override object Visit (ConstInitializer constInitializer) + + public override object Visit(ConstInitializer constInitializer) { - return constInitializer.Expr.Accept (this); + return constInitializer.Expr.Accept(this); } - - public override object Visit (ArrayInitializer arrayInitializer) + + public override object Visit(ArrayInitializer arrayInitializer) { - var result = new ArrayInitializerExpression (); - var location = LocationsBag.GetLocations (arrayInitializer); - result.AddChild (new CSharpTokenNode (Convert (arrayInitializer.Location)), Roles.LBrace); - var commaLocations = LocationsBag.GetLocations (arrayInitializer.Elements); + var result = new ArrayInitializerExpression(); + var location = LocationsBag.GetLocations(arrayInitializer); + result.AddChild(new CSharpTokenNode(Convert(arrayInitializer.Location), Roles.LBrace), Roles.LBrace); + var commaLocations = LocationsBag.GetLocations(arrayInitializer.Elements); for (int i = 0; i < arrayInitializer.Count; i++) { var init = arrayInitializer [i]; if (init == null) continue; - result.AddChild ((Expression)init.Accept (this), Roles.Expression); + result.AddChild((Expression)init.Accept(this), Roles.Expression); if (commaLocations != null && i < commaLocations.Count) - result.AddChild (new CSharpTokenNode (Convert (commaLocations [i])), Roles.Comma); + result.AddChild(new CSharpTokenNode(Convert(commaLocations [i]), Roles.Comma), Roles.Comma); } if (location != null) { if (location.Count == 2) // optional comma - result.AddChild (new CSharpTokenNode (Convert (location [0])), Roles.Comma); - result.AddChild (new CSharpTokenNode (Convert (location [location.Count - 1])), Roles.RBrace); + result.AddChild(new CSharpTokenNode(Convert(location [0]), Roles.Comma), Roles.Comma); + result.AddChild(new CSharpTokenNode(Convert(location [location.Count - 1]), Roles.RBrace), Roles.RBrace); } return result; } - + #endregion - + #region LINQ expressions + QueryOrderClause currentQueryOrderClause; - public override object Visit (Mono.CSharp.Linq.QueryExpression queryExpression) + public override object Visit(Mono.CSharp.Linq.QueryExpression queryExpression) { var oldQueryOrderClause = currentQueryOrderClause; try { currentQueryOrderClause = null; - var result = new QueryExpression (); + var result = new QueryExpression(); var currentClause = queryExpression.next; while (currentClause != null) { - QueryClause clause = (QueryClause)currentClause.Accept (this); + var clause = (QueryClause)currentClause.Accept(this); if (clause is QueryContinuationClause) { // insert preceding query at beginning of QueryContinuationClause - clause.InsertChildAfter (null, result, QueryContinuationClause.PrecedingQueryRole); + clause.InsertChildAfter(null, result, QueryContinuationClause.PrecedingQueryRole); // create a new QueryExpression for the remaining query - result = new QueryExpression (); + result = new QueryExpression(); } if (clause != null) { - result.AddChild (clause, QueryExpression.ClauseRole); + result.AddChild(clause, QueryExpression.ClauseRole); } currentClause = currentClause.next; } return result; - } - finally { + } finally { currentQueryOrderClause = oldQueryOrderClause; } } - - public override object Visit (Mono.CSharp.Linq.QueryStartClause queryStart) + + public override object Visit(Mono.CSharp.Linq.QueryStartClause queryExpression) { - if (queryStart.Expr == null) { - var intoClause = new QueryContinuationClause (); - intoClause.AddChild (new CSharpTokenNode (Convert (queryStart.Location)), QueryContinuationClause.IntoKeywordRole); - intoClause.AddChild (Identifier.Create (queryStart.IntoVariable.Name, Convert (queryStart.IntoVariable.Location)), Roles.Identifier); + if (queryExpression.Expr == null) { + var intoClause = new QueryContinuationClause(); + intoClause.AddChild(new CSharpTokenNode(Convert(queryExpression.Location), QueryContinuationClause.IntoKeywordRole), QueryContinuationClause.IntoKeywordRole); + intoClause.AddChild(Identifier.Create(queryExpression.IntoVariable.Name, Convert(queryExpression.IntoVariable.Location)), Roles.Identifier); return intoClause; } - var fromClause = new QueryFromClause (); + var fromClause = new QueryFromClause(); - fromClause.AddChild (new CSharpTokenNode (Convert (queryStart.Location)), QueryFromClause.FromKeywordRole); + fromClause.AddChild(new CSharpTokenNode(Convert(queryExpression.Location), QueryFromClause.FromKeywordRole), QueryFromClause.FromKeywordRole); - if (queryStart.IdentifierType != null) - fromClause.AddChild (ConvertToType (queryStart.IdentifierType), Roles.Type); + if (queryExpression.IdentifierType != null) + fromClause.AddChild(ConvertToType(queryExpression.IdentifierType), Roles.Type); - fromClause.AddChild (Identifier.Create (queryStart.IntoVariable.Name, Convert (queryStart.IntoVariable.Location)), Roles.Identifier); + fromClause.AddChild(Identifier.Create(queryExpression.IntoVariable.Name, Convert(queryExpression.IntoVariable.Location)), Roles.Identifier); - var location = LocationsBag.GetLocations (queryStart); + var location = LocationsBag.GetLocations(queryExpression); if (location != null) - fromClause.AddChild (new CSharpTokenNode (Convert (location [0])), QueryFromClause.InKeywordRole); + fromClause.AddChild(new CSharpTokenNode(Convert(location [0]), QueryFromClause.InKeywordRole), QueryFromClause.InKeywordRole); - if (queryStart.Expr != null) - fromClause.AddChild ((Expression)queryStart.Expr.Accept (this), Roles.Expression); + if (queryExpression.Expr != null) + fromClause.AddChild((Expression)queryExpression.Expr.Accept(this), Roles.Expression); return fromClause; } - - public override object Visit (Mono.CSharp.Linq.SelectMany queryStart) + + public override object Visit(Mono.CSharp.Linq.SelectMany selectMany) { - var fromClause = new QueryFromClause (); + var fromClause = new QueryFromClause(); - fromClause.AddChild (new CSharpTokenNode (Convert (queryStart.Location)), QueryFromClause.FromKeywordRole); + fromClause.AddChild(new CSharpTokenNode(Convert(selectMany.Location), QueryFromClause.FromKeywordRole), QueryFromClause.FromKeywordRole); - if (queryStart.IdentifierType != null) - fromClause.AddChild (ConvertToType (queryStart.IdentifierType), Roles.Type); + if (selectMany.IdentifierType != null) + fromClause.AddChild(ConvertToType(selectMany.IdentifierType), Roles.Type); - fromClause.AddChild (Identifier.Create (queryStart.IntoVariable.Name, Convert (queryStart.IntoVariable.Location)), Roles.Identifier); + fromClause.AddChild(Identifier.Create(selectMany.IntoVariable.Name, Convert(selectMany.IntoVariable.Location)), Roles.Identifier); - var location = LocationsBag.GetLocations (queryStart); + var location = LocationsBag.GetLocations(selectMany); if (location != null) - fromClause.AddChild (new CSharpTokenNode (Convert (location [0])), QueryFromClause.InKeywordRole); + fromClause.AddChild(new CSharpTokenNode(Convert(location [0]), QueryFromClause.InKeywordRole), QueryFromClause.InKeywordRole); - if (queryStart.Expr != null) - fromClause.AddChild ((Expression)queryStart.Expr.Accept (this), Roles.Expression); + if (selectMany.Expr != null) + fromClause.AddChild((Expression)selectMany.Expr.Accept(this), Roles.Expression); return fromClause; } - - public override object Visit (Mono.CSharp.Linq.Select sel) + + public override object Visit(Mono.CSharp.Linq.Select select) { - var result = new QuerySelectClause (); - result.AddChild (new CSharpTokenNode (Convert (sel.Location)), QuerySelectClause.SelectKeywordRole); - if (sel.Expr != null) - result.AddChild ((Expression)sel.Expr.Accept (this), Roles.Expression); + var result = new QuerySelectClause(); + result.AddChild(new CSharpTokenNode(Convert(select.Location), QuerySelectClause.SelectKeywordRole), QuerySelectClause.SelectKeywordRole); + if (select.Expr != null) + result.AddChild((Expression)select.Expr.Accept(this), Roles.Expression); return result; } - - public override object Visit (Mono.CSharp.Linq.GroupBy groupBy) + + public override object Visit(Mono.CSharp.Linq.GroupBy groupBy) { - var result = new QueryGroupClause (); - var location = LocationsBag.GetLocations (groupBy); - result.AddChild (new CSharpTokenNode (Convert (groupBy.Location)), QueryGroupClause.GroupKeywordRole); + var result = new QueryGroupClause(); + var location = LocationsBag.GetLocations(groupBy); + result.AddChild(new CSharpTokenNode(Convert(groupBy.Location), QueryGroupClause.GroupKeywordRole), QueryGroupClause.GroupKeywordRole); if (groupBy.ElementSelector != null) - result.AddChild ((Expression)groupBy.ElementSelector.Accept (this), QueryGroupClause.ProjectionRole); - if (location != null) - result.AddChild (new CSharpTokenNode (Convert (location [0])), QueryGroupClause.ByKeywordRole); + result.AddChild((Expression)groupBy.ElementSelector.Accept(this), QueryGroupClause.ProjectionRole); + if (location != null) { + var byLoc = Convert(location[0]); + if (byLoc.Line > 1 || byLoc.Column > 1) + result.AddChild(new CSharpTokenNode(byLoc, QueryGroupClause.ByKeywordRole), QueryGroupClause.ByKeywordRole); + } if (groupBy.Expr != null) - result.AddChild ((Expression)groupBy.Expr.Accept (this), QueryGroupClause.KeyRole); + result.AddChild((Expression)groupBy.Expr.Accept(this), QueryGroupClause.KeyRole); return result; } - - public override object Visit (Mono.CSharp.Linq.Let l) + + public override object Visit(Mono.CSharp.Linq.Let let) { - var result = new QueryLetClause (); - var location = LocationsBag.GetLocations (l); + var result = new QueryLetClause(); + var location = LocationsBag.GetLocations(let); - result.AddChild (new CSharpTokenNode (Convert (l.Location)), QueryLetClause.LetKeywordRole); - result.AddChild (Identifier.Create (l.IntoVariable.Name, Convert (l.IntoVariable.Location)), Roles.Identifier); + result.AddChild(new CSharpTokenNode(Convert(let.Location), QueryLetClause.LetKeywordRole), QueryLetClause.LetKeywordRole); + result.AddChild(Identifier.Create(let.IntoVariable.Name, Convert(let.IntoVariable.Location)), Roles.Identifier); if (location != null) - result.AddChild (new CSharpTokenNode (Convert (location [0])), Roles.Assign); - if (l.Expr != null) - result.AddChild ((Expression)l.Expr.Accept (this), Roles.Expression); + result.AddChild(new CSharpTokenNode(Convert(location [0]), Roles.Assign), Roles.Assign); + if (let.Expr != null) + result.AddChild((Expression)let.Expr.Accept(this), Roles.Expression); return result; } - - public override object Visit (Mono.CSharp.Linq.Where w) + + public override object Visit(Mono.CSharp.Linq.Where where) { - var result = new QueryWhereClause (); - var location = LocationsBag.GetLocations (w); - if (location != null) - result.AddChild (new CSharpTokenNode (Convert (location [0])), QueryWhereClause.WhereKeywordRole); - if (w.Expr != null) - result.AddChild ((Expression)w.Expr.Accept (this), Roles.Condition); + var result = new QueryWhereClause(); + result.AddChild(new CSharpTokenNode(Convert(where.Location), QueryWhereClause.WhereKeywordRole), QueryWhereClause.WhereKeywordRole); + if (where.Expr != null) + result.AddChild((Expression)where.Expr.Accept(this), Roles.Condition); return result; } - - public override object Visit (Mono.CSharp.Linq.Join join) + + public override object Visit(Mono.CSharp.Linq.Join join) { - var result = new QueryJoinClause (); - var location = LocationsBag.GetLocations (join); - result.AddChild (new CSharpTokenNode (Convert (join.Location)), QueryJoinClause.JoinKeywordRole); - result.AddChild (Identifier.Create (join.JoinVariable.Name, Convert (join.JoinVariable.Location)), QueryJoinClause.JoinIdentifierRole); - + var result = new QueryJoinClause(); + var location = LocationsBag.GetLocations(join); + result.AddChild(new CSharpTokenNode(Convert(join.Location), QueryJoinClause.JoinKeywordRole), QueryJoinClause.JoinKeywordRole); + + if (join.IdentifierType != null) + result.AddChild(ConvertToType(join.IdentifierType), QueryJoinClause.TypeRole); + + result.AddChild(Identifier.Create(join.JoinVariable.Name, Convert(join.JoinVariable.Location)), QueryJoinClause.JoinIdentifierRole); + + if (join.IdentifierType != null) + result.AddChild(ConvertToType(join.IdentifierType), QueryJoinClause.TypeRole); + if (location != null) - result.AddChild (new CSharpTokenNode (Convert (location [0])), QueryJoinClause.InKeywordRole); + result.AddChild(new CSharpTokenNode(Convert(location [0]), QueryJoinClause.InKeywordRole), QueryJoinClause.InKeywordRole); if (join.Expr != null) - result.AddChild ((Expression)join.Expr.Accept (this), QueryJoinClause.InExpressionRole); + result.AddChild((Expression)join.Expr.Accept(this), QueryJoinClause.InExpressionRole); if (location != null && location.Count > 1) - result.AddChild (new CSharpTokenNode (Convert (location [1])), QueryJoinClause.OnKeywordRole); + result.AddChild(new CSharpTokenNode(Convert(location [1]), QueryJoinClause.OnKeywordRole), QueryJoinClause.OnKeywordRole); - var outer = join.OuterSelector.Statements.FirstOrDefault () as ContextualReturn; + var outer = join.OuterSelector.Statements.FirstOrDefault() as ContextualReturn; if (outer != null) - result.AddChild ((Expression)outer.Expr.Accept (this), QueryJoinClause.OnExpressionRole); + result.AddChild((Expression)outer.Expr.Accept(this), QueryJoinClause.OnExpressionRole); if (location != null && location.Count > 2) - result.AddChild (new CSharpTokenNode (Convert (location [2])), QueryJoinClause.EqualsKeywordRole); + result.AddChild(new CSharpTokenNode(Convert(location [2]), QueryJoinClause.EqualsKeywordRole), QueryJoinClause.EqualsKeywordRole); - var inner = join.InnerSelector.Statements.FirstOrDefault () as ContextualReturn; + var inner = join.InnerSelector.Statements.FirstOrDefault() as ContextualReturn; if (inner != null) - result.AddChild ((Expression)inner.Expr.Accept (this), QueryJoinClause.EqualsExpressionRole); + result.AddChild((Expression)inner.Expr.Accept(this), QueryJoinClause.EqualsExpressionRole); return result; } - - public override object Visit (Mono.CSharp.Linq.GroupJoin join) + + public override object Visit(Mono.CSharp.Linq.GroupJoin groupJoin) { - var result = new QueryJoinClause (); - var location = LocationsBag.GetLocations (join); - result.AddChild (new CSharpTokenNode (Convert (join.Location)), QueryJoinClause.JoinKeywordRole); + var result = new QueryJoinClause(); + var location = LocationsBag.GetLocations(groupJoin); + result.AddChild(new CSharpTokenNode(Convert(groupJoin.Location), QueryJoinClause.JoinKeywordRole), QueryJoinClause.JoinKeywordRole); // mcs seems to have swapped IntoVariable with JoinVariable, so we'll swap it back here - result.AddChild (Identifier.Create (join.IntoVariable.Name, Convert (join.IntoVariable.Location)), QueryJoinClause.JoinIdentifierRole); + result.AddChild(Identifier.Create(groupJoin.IntoVariable.Name, Convert(groupJoin.IntoVariable.Location)), QueryJoinClause.JoinIdentifierRole); if (location != null) - result.AddChild (new CSharpTokenNode (Convert (location [0])), QueryJoinClause.InKeywordRole); - - if (join.Expr != null) - result.AddChild ((Expression)join.Expr.Accept (this), QueryJoinClause.InExpressionRole); + result.AddChild(new CSharpTokenNode(Convert(location [0]), QueryJoinClause.InKeywordRole), QueryJoinClause.InKeywordRole); + + if (groupJoin.Expr != null) + result.AddChild((Expression)groupJoin.Expr.Accept(this), QueryJoinClause.InExpressionRole); if (location != null && location.Count > 1) - result.AddChild (new CSharpTokenNode (Convert (location [1])), QueryJoinClause.OnKeywordRole); + result.AddChild(new CSharpTokenNode(Convert(location [1]), QueryJoinClause.OnKeywordRole), QueryJoinClause.OnKeywordRole); - var outer = join.OuterSelector.Statements.FirstOrDefault () as ContextualReturn; + var outer = groupJoin.OuterSelector.Statements.FirstOrDefault() as ContextualReturn; if (outer != null) - result.AddChild ((Expression)outer.Expr.Accept (this), QueryJoinClause.OnExpressionRole); + result.AddChild((Expression)outer.Expr.Accept(this), QueryJoinClause.OnExpressionRole); if (location != null && location.Count > 2) - result.AddChild (new CSharpTokenNode (Convert (location [2])), QueryJoinClause.EqualsKeywordRole); - var inner = join.InnerSelector.Statements.FirstOrDefault () as ContextualReturn; + result.AddChild(new CSharpTokenNode(Convert(location [2]), QueryJoinClause.EqualsKeywordRole), QueryJoinClause.EqualsKeywordRole); + var inner = groupJoin.InnerSelector.Statements.FirstOrDefault() as ContextualReturn; if (inner != null) - result.AddChild ((Expression)inner.Expr.Accept (this), QueryJoinClause.EqualsExpressionRole); + result.AddChild((Expression)inner.Expr.Accept(this), QueryJoinClause.EqualsExpressionRole); if (location != null && location.Count > 3) - result.AddChild (new CSharpTokenNode (Convert (location [3])), QueryJoinClause.IntoKeywordRole); + result.AddChild(new CSharpTokenNode(Convert(location [3]), QueryJoinClause.IntoKeywordRole), QueryJoinClause.IntoKeywordRole); - result.AddChild (Identifier.Create (join.JoinVariable.Name, Convert (join.JoinVariable.Location)), QueryJoinClause.IntoIdentifierRole); + result.AddChild(Identifier.Create(groupJoin.JoinVariable.Name, Convert(groupJoin.JoinVariable.Location)), QueryJoinClause.IntoIdentifierRole); return result; } - - public override object Visit (Mono.CSharp.Linq.OrderByAscending orderByAscending) + + public override object Visit(Mono.CSharp.Linq.OrderByAscending orderByAscending) { currentQueryOrderClause = new QueryOrderClause(); - - var ordering = new QueryOrdering (); + var location2 = LocationsBag.GetLocations(orderByAscending.block); + if (location2 != null) + currentQueryOrderClause.AddChild(new CSharpTokenNode(Convert(location2 [0]), QueryOrderClause.OrderbyKeywordRole), QueryOrderClause.OrderbyKeywordRole); + var ordering = new QueryOrdering(); if (orderByAscending.Expr != null) - ordering.AddChild ((Expression)orderByAscending.Expr.Accept (this), Roles.Expression); - var location = LocationsBag.GetLocations (orderByAscending); + ordering.AddChild((Expression)orderByAscending.Expr.Accept(this), Roles.Expression); + var location = LocationsBag.GetLocations(orderByAscending); if (location != null) { ordering.Direction = QueryOrderingDirection.Ascending; - ordering.AddChild (new CSharpTokenNode (Convert (location [0])), QueryOrdering.AscendingKeywordRole); + ordering.AddChild(new CSharpTokenNode(Convert(location [0]), QueryOrdering.AscendingKeywordRole), QueryOrdering.AscendingKeywordRole); } - currentQueryOrderClause.AddChild (ordering, QueryOrderClause.OrderingRole); + currentQueryOrderClause.AddChild(ordering, QueryOrderClause.OrderingRole); return currentQueryOrderClause; } - - public override object Visit (Mono.CSharp.Linq.OrderByDescending orderByDescending) + + public override object Visit(Mono.CSharp.Linq.OrderByDescending orderByDescending) { - currentQueryOrderClause = new QueryOrderClause (); + currentQueryOrderClause = new QueryOrderClause(); - var ordering = new QueryOrdering (); + var ordering = new QueryOrdering(); if (orderByDescending.Expr != null) - ordering.AddChild ((Expression)orderByDescending.Expr.Accept (this), Roles.Expression); - var location = LocationsBag.GetLocations (orderByDescending); + ordering.AddChild((Expression)orderByDescending.Expr.Accept(this), Roles.Expression); + var location = LocationsBag.GetLocations(orderByDescending); if (location != null) { ordering.Direction = QueryOrderingDirection.Descending; - ordering.AddChild (new CSharpTokenNode (Convert (location [0])), QueryOrdering.DescendingKeywordRole); + ordering.AddChild(new CSharpTokenNode(Convert(location [0]), QueryOrdering.DescendingKeywordRole), QueryOrdering.DescendingKeywordRole); } - currentQueryOrderClause.AddChild (ordering, QueryOrderClause.OrderingRole); + currentQueryOrderClause.AddChild(ordering, QueryOrderClause.OrderingRole); return currentQueryOrderClause; } - - public override object Visit (Mono.CSharp.Linq.ThenByAscending thenByAscending) + + public override object Visit(Mono.CSharp.Linq.ThenByAscending thenByAscending) { - var ordering = new QueryOrdering (); + var ordering = new QueryOrdering(); if (thenByAscending.Expr != null) - ordering.AddChild ((Expression)thenByAscending.Expr.Accept (this), Roles.Expression); - var location = LocationsBag.GetLocations (thenByAscending); + ordering.AddChild((Expression)thenByAscending.Expr.Accept(this), Roles.Expression); + var location = LocationsBag.GetLocations(thenByAscending); if (location != null) { ordering.Direction = QueryOrderingDirection.Ascending; - ordering.AddChild (new CSharpTokenNode (Convert (location [0])), QueryOrdering.AscendingKeywordRole); + ordering.AddChild(new CSharpTokenNode(Convert(location [0]), QueryOrdering.AscendingKeywordRole), QueryOrdering.AscendingKeywordRole); } - currentQueryOrderClause.AddChild (ordering, QueryOrderClause.OrderingRole); + currentQueryOrderClause.AddChild(ordering, QueryOrderClause.OrderingRole); return null; } - - public override object Visit (Mono.CSharp.Linq.ThenByDescending thenByDescending) + + public override object Visit(Mono.CSharp.Linq.ThenByDescending thenByDescending) { - var ordering = new QueryOrdering (); + var ordering = new QueryOrdering(); if (thenByDescending.Expr != null) - ordering.AddChild ((Expression)thenByDescending.Expr.Accept (this), Roles.Expression); - var location = LocationsBag.GetLocations (thenByDescending); + ordering.AddChild((Expression)thenByDescending.Expr.Accept(this), Roles.Expression); + var location = LocationsBag.GetLocations(thenByDescending); if (location != null) { ordering.Direction = QueryOrderingDirection.Descending; - ordering.AddChild (new CSharpTokenNode (Convert (location [0])), QueryOrdering.DescendingKeywordRole); + ordering.AddChild(new CSharpTokenNode(Convert(location [0]), QueryOrdering.DescendingKeywordRole), QueryOrdering.DescendingKeywordRole); } - currentQueryOrderClause.AddChild (ordering, QueryOrderClause.OrderingRole); + currentQueryOrderClause.AddChild(ordering, QueryOrderClause.OrderingRole); return null; } - - public override object Visit (Await awaitExpr) + + public override object Visit(Await awaitExpr) { - var result = new UnaryOperatorExpression (); + var result = new UnaryOperatorExpression(); result.Operator = UnaryOperatorType.Await; - result.AddChild (new CSharpTokenNode (Convert (awaitExpr.Location)), UnaryOperatorExpression.AwaitRole); + result.AddChild(new CSharpTokenNode(Convert(awaitExpr.Location), UnaryOperatorExpression.AwaitRole), UnaryOperatorExpression.AwaitRole); if (awaitExpr.Expression != null) - result.AddChild ((Expression)awaitExpr.Expression.Accept (this), Roles.Expression); + result.AddChild((Expression)awaitExpr.Expression.Accept(this), Roles.Expression); return result; } + #endregion - + #region XmlDoc + public DocumentationReference ConvertXmlDoc(DocumentationBuilder doc) { - DocumentationReference result = new DocumentationReference(); + var result = new DocumentationReference(); if (doc.ParsedName != null) { if (doc.ParsedName.Name == "") { - result.EntityType = EntityType.Indexer; + result.SymbolKind = SymbolKind.Indexer; } else { result.MemberName = doc.ParsedName.Name; } @@ -3511,11 +3585,11 @@ namespace ICSharpCode.NRefactory.CSharp } if (doc.ParsedName.TypeParameters != null) { for (int i = 0; i < doc.ParsedName.TypeParameters.Count; i++) { - result.TypeArguments.Add(ConvertToType(doc.ParsedName.TypeParameters[i])); + result.TypeArguments.Add(ConvertToType(doc.ParsedName.TypeParameters [i])); } } } else if (doc.ParsedBuiltinType != null) { - result.EntityType = EntityType.TypeDefinition; + result.SymbolKind = SymbolKind.TypeDefinition; result.DeclaringType = ConvertToType(doc.ParsedBuiltinType); } if (doc.ParsedParameters != null) { @@ -3523,7 +3597,7 @@ namespace ICSharpCode.NRefactory.CSharp result.Parameters.AddRange(doc.ParsedParameters.Select(ConvertXmlDocParameter)); } if (doc.ParsedOperator != null) { - result.EntityType = EntityType.Operator; + result.SymbolKind = SymbolKind.Operator; result.OperatorType = (OperatorType)doc.ParsedOperator; if (result.OperatorType == OperatorType.Implicit || result.OperatorType == OperatorType.Explicit) { var returnTypeParam = result.Parameters.LastOrNullObject(); @@ -3539,10 +3613,10 @@ namespace ICSharpCode.NRefactory.CSharp } return result; } - + ParameterDeclaration ConvertXmlDocParameter(DocumentationParameter p) { - ParameterDeclaration result = new ParameterDeclaration(); + var result = new ParameterDeclaration(); switch (p.Modifier) { case Parameter.Modifier.OUT: result.ParameterModifier = ParameterModifier.Out; @@ -3559,172 +3633,176 @@ namespace ICSharpCode.NRefactory.CSharp } return result; } + #endregion + } - - public CSharpParser () + + public CSharpParser() { compilerSettings = new CompilerSettings(); } - - public CSharpParser (CompilerSettings args) + + public CSharpParser(CompilerSettings args) { compilerSettings = args ?? new CompilerSettings(); } - - static AstNode GetOuterLeft (AstNode node) - { - var outerLeft = node; - while (outerLeft.FirstChild != null) - outerLeft = outerLeft.FirstChild; - return outerLeft; - } - - static AstNode NextLeaf (AstNode node) - { - if (node == null) - return null; - var next = node.NextSibling; - if (next == null) - return node.Parent; - return GetOuterLeft (next); - } - - static void InsertComments (CompilerCompilationUnit top, ConversionVisitor conversionVisitor) + + void InsertComments(CompilerCompilationUnit top, ConversionVisitor conversionVisitor) { - var leaf = GetOuterLeft (conversionVisitor.Unit); - for (int i = 0; i < top.SpecialsBag.Specials.Count; i++) { - var special = top.SpecialsBag.Specials [i]; + AstNode insertionPoint = conversionVisitor.Unit.FirstChild; + foreach (var special in top.SpecialsBag.Specials) { AstNode newLeaf = null; + Role role = null; + bool isDocumentationComment = false; var comment = special as SpecialsBag.Comment; if (comment != null) { // HACK: multiline documentation comment detection; better move this logic into the mcs tokenizer - bool isMultilineDocumentationComment = ( - comment.CommentType == SpecialsBag.CommentType.Multi - && comment.Content.StartsWith("*", StringComparison.Ordinal) - && !comment.Content.StartsWith("**", StringComparison.Ordinal) - ); - if (conversionVisitor.convertTypeSystemMode && !(comment.CommentType == SpecialsBag.CommentType.Documentation || isMultilineDocumentationComment)) + bool isMultilineDocumentationComment = (comment.CommentType == SpecialsBag.CommentType.Multi && comment.Content.StartsWith("*", StringComparison.Ordinal) && !comment.Content.StartsWith("**", StringComparison.Ordinal)); + isDocumentationComment = comment.CommentType == SpecialsBag.CommentType.Documentation || isMultilineDocumentationComment; + if (conversionVisitor.convertTypeSystemMode && !isDocumentationComment) continue; var type = isMultilineDocumentationComment ? CommentType.MultiLineDocumentation : (CommentType)comment.CommentType; - var start = new TextLocation (comment.Line, comment.Col); - var end = new TextLocation (comment.EndLine, comment.EndCol); - newLeaf = new Comment (type, start, end) { + var start = new TextLocation(comment.Line, comment.Col); + var end = new TextLocation(comment.EndLine, comment.EndCol); + newLeaf = new Comment(type, start, end) { StartsLine = comment.StartsLine, Content = isMultilineDocumentationComment ? comment.Content.Substring(1) : comment.Content }; - } else { + role = Roles.Comment; + } else if (!GenerateTypeSystemMode) { + var pragmaDirective = special as SpecialsBag.PragmaPreProcessorDirective; + if (pragmaDirective != null) { + var pragma = new PragmaWarningPreprocessorDirective(new TextLocation(pragmaDirective.Line, pragmaDirective.Col), new TextLocation(pragmaDirective.EndLine, pragmaDirective.EndCol)); + pragma.AddChild(new CSharpTokenNode(new TextLocation(pragmaDirective.Line, pragmaDirective.Col), PragmaWarningPreprocessorDirective.PragmaKeywordRole), PragmaWarningPreprocessorDirective.PragmaKeywordRole); + pragma.AddChild(new CSharpTokenNode(new TextLocation(pragmaDirective.Line, pragmaDirective.WarningColumn), PragmaWarningPreprocessorDirective.WarningKeywordRole), PragmaWarningPreprocessorDirective.WarningKeywordRole); + var pragmaRole = pragmaDirective.Disalbe ? PragmaWarningPreprocessorDirective.DisableKeywordRole : PragmaWarningPreprocessorDirective.RestoreKeywordRole; + pragma.AddChild(new CSharpTokenNode(new TextLocation(pragmaDirective.Line, pragmaDirective.DisableRestoreColumn), pragmaRole), pragmaRole); + foreach (var code in pragmaDirective.Codes) { + pragma.AddChild((PrimitiveExpression)conversionVisitor.Visit(code), PragmaWarningPreprocessorDirective.WarningRole); + } + newLeaf = pragma; + role = Roles.PreProcessorDirective; + goto end; + } + var lineDirective = special as SpecialsBag.LineProcessorDirective; + if (lineDirective != null) { + var pragma = new LinePreprocessorDirective(new TextLocation(lineDirective.Line, lineDirective.Col), new TextLocation(lineDirective.EndLine, lineDirective.EndCol)); + pragma.LineNumber = lineDirective.LineNumber; + pragma.FileName = lineDirective.FileName; + newLeaf = pragma; + role = Roles.PreProcessorDirective; + goto end; + } var directive = special as SpecialsBag.PreProcessorDirective; if (directive != null) { - newLeaf = new PreProcessorDirective ((ICSharpCode.NRefactory.CSharp.PreProcessorDirectiveType)((int)directive.Cmd & 0xF), new TextLocation (directive.Line, directive.Col), new TextLocation (directive.EndLine, directive.EndCol)) { + newLeaf = new PreProcessorDirective((PreProcessorDirectiveType)((int)directive.Cmd & 0xF), new TextLocation(directive.Line, directive.Col), new TextLocation(directive.EndLine, directive.EndCol)) { Argument = directive.Arg, Take = directive.Take }; + role = Roles.PreProcessorDirective; } + end: + ; } - if (newLeaf == null) - continue; - - while (true) { - var nextLeaf = NextLeaf (leaf); - // insert comment at begin - if (newLeaf.StartLocation < leaf.StartLocation) { - var node = leaf.Parent ?? conversionVisitor.Unit; - while (node.Parent != null && node.FirstChild == leaf) { - leaf = node; - node = node.Parent; - } - if (newLeaf is Comment) { - node.InsertChildBefore (leaf, (Comment)newLeaf, Roles.Comment); - } else { - node.InsertChildBefore (leaf, (PreProcessorDirective)newLeaf, Roles.PreProcessorDirective); - } - leaf = newLeaf; - break; - } - - // insert comment at the end - if (nextLeaf == null) { - var node = leaf.Parent ?? conversionVisitor.Unit; - if (newLeaf is Comment) { - node.AddChild ((Comment)newLeaf, Roles.Comment); - } else { - node.AddChild ((PreProcessorDirective)newLeaf, Roles.PreProcessorDirective); - } - leaf = newLeaf; - break; - } - - // comment is between 2 nodes - if (leaf.EndLocation <= newLeaf.StartLocation && newLeaf.StartLocation <= nextLeaf.StartLocation) { - var node = leaf.Parent ?? conversionVisitor.Unit; - if (newLeaf is Comment) { - node.InsertChildAfter (leaf, (Comment)newLeaf, Roles.Comment); - } else { - node.InsertChildAfter (leaf, (PreProcessorDirective)newLeaf, Roles.PreProcessorDirective); - } - leaf = newLeaf; - break; + if (newLeaf != null) { + InsertComment(ref insertionPoint, newLeaf, role, isDocumentationComment, conversionVisitor.Unit); + } + } + if (!GenerateTypeSystemMode) { + // We cannot insert newlines in the same loop as comments/preprocessor directives + // because they are not correctly ordered in the specials bag + insertionPoint = conversionVisitor.Unit.FirstChild; + for (int i = 0; i < top.SpecialsBag.Specials.Count; i++) { + var newLine = top.SpecialsBag.Specials [i] as SpecialsBag.NewLineToken; + if (newLine != null) { + var newLeaf = new NewLineNode(new TextLocation(newLine.Line, newLine.Col + 1)); + newLeaf.NewLineType = newLine.NewLine == SpecialsBag.NewLine.Unix ? UnicodeNewline.LF : UnicodeNewline.CRLF; + InsertComment(ref insertionPoint, newLeaf, Roles.NewLine, false, conversionVisitor.Unit); } - leaf = nextLeaf; } } } - + + static void InsertComment(ref AstNode insertionPoint, AstNode newNode, Role role, bool isDocumentationComment, AstNode rootNode) + { + TextLocation insertAt = newNode.StartLocation; + // Advance insertionPoint to the first node that has a start location >= insertAt + while (insertionPoint != null && insertionPoint.StartLocation < insertAt) { + // Enter the current node if insertAt is within + while (insertAt < insertionPoint.EndLocation && insertionPoint.FirstChild != null) { + insertionPoint = insertionPoint.FirstChild; + } + // Go to next node (insertionPoint.NextSibling if it exists; otherwise the next sibling of the parent node etc.) + insertionPoint = insertionPoint.GetNextNode(); + } + // As a special case, XmlDoc gets inserted at the beginning of the entity declaration + if (isDocumentationComment && insertionPoint is EntityDeclaration && insertionPoint.FirstChild != null) { + insertionPoint = insertionPoint.FirstChild; + } + if (insertionPoint == null) { + // we're at the end of the compilation unit + rootNode.AddChildUnsafe(newNode, role); + } else { + insertionPoint.Parent.InsertChildBeforeUnsafe(insertionPoint, newNode, role); + } + } + public class ErrorReportPrinter : ReportPrinter { readonly string fileName; - public readonly List Errors = new List (); - - public ErrorReportPrinter (string fileName) + public readonly List Errors = new List(); + + public ErrorReportPrinter(string fileName) { this.fileName = fileName; } - - public override void Print (AbstractMessage msg, bool showFullPath) + + public override void Print(AbstractMessage msg, bool showFullPath) { - base.Print (msg, showFullPath); - var newError = new Error (msg.IsWarning ? ErrorType.Warning : ErrorType.Error, msg.Text, new DomRegion (fileName, msg.Location.Row, msg.Location.Column)); - Errors.Add (newError); + base.Print(msg, showFullPath); + var newError = new Error(msg.IsWarning ? ErrorType.Warning : ErrorType.Error, msg.Text, new DomRegion(fileName, msg.Location.Row, msg.Location.Column)); + Errors.Add(newError); } } - ErrorReportPrinter errorReportPrinter = new ErrorReportPrinter (null); - + + ErrorReportPrinter errorReportPrinter = new ErrorReportPrinter(null); + [Obsolete("Use the Errors/Warnings/ErrorsAndWarnings properties instead")] public ErrorReportPrinter ErrorPrinter { get { return errorReportPrinter; } } - + public bool HasErrors { get { return errorReportPrinter.ErrorsCount > 0; } } - + public bool HasWarnings { get { return errorReportPrinter.WarningsCount > 0; } } - + public IEnumerable Errors { get { return errorReportPrinter.Errors.Where(e => e.ErrorType == ErrorType.Error); } } - + public IEnumerable Warnings { get { return errorReportPrinter.Errors.Where(e => e.ErrorType == ErrorType.Warning); } } - + public IEnumerable ErrorsAndWarnings { get { return errorReportPrinter.Errors; } } - + /// /// Parses a C# code file. /// @@ -3732,11 +3810,11 @@ namespace ICSharpCode.NRefactory.CSharp /// The file name. Used to identify the file (e.g. when building a type system). /// This can be an arbitrary identifier, NRefactory never tries to access the file on disk. /// Returns the syntax tree. - public SyntaxTree Parse (string program, string fileName = "") + public SyntaxTree Parse(string program, string fileName = "") { - return Parse (new StringTextSource (program), fileName); + return Parse(new StringTextSource(program), fileName); } - + /// /// Parses a C# code file. /// @@ -3744,9 +3822,9 @@ namespace ICSharpCode.NRefactory.CSharp /// The file name. Used to identify the file (e.g. when building a type system). /// This can be an arbitrary identifier, NRefactory never tries to access the file on disk. /// Returns the syntax tree. - public SyntaxTree Parse (TextReader reader, string fileName = "") + public SyntaxTree Parse(TextReader reader, string fileName = "") { - return Parse(new StringTextSource (reader.ReadToEnd ()), fileName); + return Parse(new StringTextSource(reader.ReadToEnd()), fileName); } /// @@ -3757,21 +3835,32 @@ namespace ICSharpCode.NRefactory.CSharp if (top == null) { return null; } - CSharpParser.ConversionVisitor conversionVisitor = new ConversionVisitor (GenerateTypeSystemMode, top.LocationsBag); + CSharpParser.ConversionVisitor conversionVisitor = new ConversionVisitor(GenerateTypeSystemMode, top.LocationsBag); top.ModuleCompiled.Accept(conversionVisitor); InsertComments(top, conversionVisitor); if (CompilationUnitCallback != null) { CompilationUnitCallback(top); } - if (top.LastYYValue is Mono.CSharp.Expression) { - conversionVisitor.Unit.TopExpression = ((Mono.CSharp.Expression)top.LastYYValue).Accept(conversionVisitor) as AstNode; - } + var expr = top.LastYYValue as Mono.CSharp.Expression; + if (expr != null) + conversionVisitor.Unit.TopExpression = expr.Accept(conversionVisitor) as AstNode; conversionVisitor.Unit.FileName = fileName; - conversionVisitor.Unit.ConditionalSymbols = top.Conditionals.Concat (compilerSettings.ConditionalSymbols).ToArray (); + var conditionals = new List(); + foreach (var settings in compilerSettings.ConditionalSymbols) { + if (top.Conditionals.ContainsKey(settings) && !top.Conditionals [settings]) + continue; + conditionals.Add(settings); + } + foreach (var kv in top.Conditionals) { + if (!kv.Value || compilerSettings.ConditionalSymbols.Contains(kv.Key)) + continue; + conditionals.Add(kv.Key); + } + conversionVisitor.Unit.ConditionalSymbols = conditionals; return conversionVisitor.Unit; } - + public CompilerSettings CompilerSettings { get { return compilerSettings; } set { @@ -3780,7 +3869,7 @@ namespace ICSharpCode.NRefactory.CSharp compilerSettings = value; } } - + /// /// Callback that gets called with the Mono.CSharp syntax tree whenever some code is parsed. /// @@ -3788,7 +3877,7 @@ namespace ICSharpCode.NRefactory.CSharp get; set; } - + /// /// Specifies whether to run the parser in a special mode for generating the type system. /// If this property is true, the syntax tree will only contain nodes relevant for the @@ -3799,9 +3888,9 @@ namespace ICSharpCode.NRefactory.CSharp get; set; } - + TextLocation initialLocation = new TextLocation(1, 1); - + /// /// Specifies the text location where parsing starts. /// This property can be used when parsing a part of a file to make the locations of the AstNodes @@ -3812,9 +3901,9 @@ namespace ICSharpCode.NRefactory.CSharp get { return initialLocation; } set { initialLocation = value; } } - - internal static object parseLock = new object (); - + + internal static object parseLock = new object(); + /// /// Parses a C# code file. /// @@ -3822,62 +3911,61 @@ namespace ICSharpCode.NRefactory.CSharp /// The file name. Used to identify the file (e.g. when building a type system). /// This can be an arbitrary identifier, NRefactory never tries to access the file on disk. /// Returns the syntax tree. - public SyntaxTree Parse (Stream stream, string fileName = "") + public SyntaxTree Parse(Stream stream, string fileName = "") { - return Parse (new StreamReader (stream), fileName); + return Parse(new StreamReader(stream), fileName); } - + /// /// Parses a C# code file. /// /// The source code to parse. /// The file name. Used to identify the file (e.g. when building a type system). /// This can be an arbitrary identifier, NRefactory never tries to access the file on disk. - /// /// Returns the syntax tree. public SyntaxTree Parse(ITextSource program, string fileName = "") { return Parse(program, fileName, initialLocation.Line, initialLocation.Column); } - + SyntaxTree Parse(ITextSource program, string fileName, int initialLine, int initialColumn) { lock (parseLock) { - errorReportPrinter = new ErrorReportPrinter (""); - var ctx = new CompilerContext (compilerSettings.ToMono(), errorReportPrinter); + errorReportPrinter = new ErrorReportPrinter(""); + var ctx = new CompilerContext(compilerSettings.ToMono(), errorReportPrinter); ctx.Settings.TabSize = 1; - var reader = new SeekableStreamReader (program); - var file = new SourceFile (fileName, fileName, 0); - Location.Initialize (new List (new [] { file })); - var module = new ModuleContainer (ctx); - var session = new ParserSession (); - session.LocationsBag = new LocationsBag (); - var report = new Report (ctx, errorReportPrinter); - var parser = Driver.Parse (reader, file, module, session, report, initialLine - 1, initialColumn - 1); - var top = new CompilerCompilationUnit () { + var reader = new SeekableStreamReader(program); + var file = new SourceFile(fileName, fileName, 0); + Location.Initialize(new List(new [] { file })); + var module = new ModuleContainer(ctx); + var session = new ParserSession(); + session.LocationsBag = new LocationsBag(); + var report = new Report(ctx, errorReportPrinter); + var parser = Driver.Parse(reader, file, module, session, report, initialLine - 1, initialColumn - 1); + var top = new CompilerCompilationUnit { ModuleCompiled = module, LocationsBag = session.LocationsBag, SpecialsBag = parser.Lexer.sbag, Conditionals = parser.Lexer.SourceFile.Conditionals }; - var unit = Parse (top, fileName); - unit.Errors.AddRange (errorReportPrinter.Errors); - CompilerCallableEntryPoint.Reset (); + var unit = Parse(top, fileName); + unit.Errors.AddRange(errorReportPrinter.Errors); + CompilerCallableEntryPoint.Reset(); return unit; } } - public IEnumerable ParseTypeMembers (string code) + public IEnumerable ParseTypeMembers(string code) { return ParseTypeMembers(code, initialLocation.Line, initialLocation.Column); } - - IEnumerable ParseTypeMembers (string code, int initialLine, int initialColumn) + + IEnumerable ParseTypeMembers(string code, int initialLine, int initialColumn) { const string prefix = "unsafe partial class MyClass { "; - var syntaxTree = Parse (new StringTextSource (prefix + code + "}"), "parsed.cs", initialLine, initialColumn - prefix.Length); + var syntaxTree = Parse(new StringTextSource(prefix + code + "}"), "parsed.cs", initialLine, initialColumn - prefix.Length); if (syntaxTree == null) - return Enumerable.Empty (); + return Enumerable.Empty(); var td = syntaxTree.FirstChild as TypeDeclaration; if (td != null) { var members = td.Members.ToArray(); @@ -3886,20 +3974,20 @@ namespace ICSharpCode.NRefactory.CSharp m.Remove(); return members; } - return Enumerable.Empty (); + return Enumerable.Empty(); } - - public IEnumerable ParseStatements (string code) + + public IEnumerable ParseStatements(string code) { return ParseStatements(code, initialLocation.Line, initialLocation.Column); } - - IEnumerable ParseStatements (string code, int initialLine, int initialColumn) + + IEnumerable ParseStatements(string code, int initialLine, int initialColumn) { // the dummy method is async so that 'await' expressions are parsed as expected const string prefix = "async void M() { "; - var members = ParseTypeMembers (prefix + code + "}", initialLine, initialColumn - prefix.Length); - var method = members.FirstOrDefault () as MethodDeclaration; + var members = ParseTypeMembers(prefix + code + "}", initialLine, initialColumn - prefix.Length); + var method = members.FirstOrDefault() as MethodDeclaration; if (method != null && method.Body != null) { var statements = method.Body.Statements.ToArray(); // detach statements from parent @@ -3907,13 +3995,13 @@ namespace ICSharpCode.NRefactory.CSharp st.Remove(); return statements; } - return Enumerable.Empty (); + return Enumerable.Empty(); } - - public AstType ParseTypeReference (string code) + + public AstType ParseTypeReference(string code) { - var members = ParseTypeMembers (code + " a;"); - var field = members.FirstOrDefault () as FieldDeclaration; + var members = ParseTypeMembers(code + " a;"); + var field = members.FirstOrDefault() as FieldDeclaration; if (field != null) { AstType type = field.ReturnType; type.Remove(); @@ -3921,14 +4009,14 @@ namespace ICSharpCode.NRefactory.CSharp } return AstType.Null; } - - public Expression ParseExpression (string code) + + public Expression ParseExpression(string code) { const string prefix = "tmp = "; - var statements = ParseStatements (prefix + code + ";", initialLocation.Line, initialLocation.Column - prefix.Length); - var es = statements.FirstOrDefault () as ExpressionStatement; + var statements = ParseStatements(prefix + code + ";", initialLocation.Line, initialLocation.Column - prefix.Length); + var es = statements.FirstOrDefault() as ExpressionStatement; if (es != null) { - AssignmentExpression ae = es.Expression as AssignmentExpression; + var ae = es.Expression as AssignmentExpression; if (ae != null) { Expression expr = ae.Right; expr.Remove(); @@ -3937,7 +4025,6 @@ namespace ICSharpCode.NRefactory.CSharp } return Expression.Null; } - /* /// /// Parses a file snippet; guessing what the code snippet represents (whole file, type members, block, type reference, expression). @@ -3947,43 +4034,42 @@ namespace ICSharpCode.NRefactory.CSharp // TODO: add support for parsing a part of a file throw new NotImplementedException (); } - */ - - public DocumentationReference ParseDocumentationReference (string cref) + */ + public DocumentationReference ParseDocumentationReference(string cref) { // see Mono.CSharp.DocumentationBuilder.HandleXrefCommon if (cref == null) - throw new ArgumentNullException ("cref"); + throw new ArgumentNullException("cref"); // Additional symbols for < and > are allowed for easier XML typing - cref = cref.Replace ('{', '<').Replace ('}', '>'); + cref = cref.Replace('{', '<').Replace('}', '>'); lock (parseLock) { errorReportPrinter = new ErrorReportPrinter(""); var ctx = new CompilerContext(compilerSettings.ToMono(), errorReportPrinter); ctx.Settings.TabSize = 1; - var reader = new SeekableStreamReader(new StringTextSource (cref)); + var reader = new SeekableStreamReader(new StringTextSource(cref)); var file = new SourceFile("", "", 0); - Location.Initialize(new List (new [] { file })); + Location.Initialize(new List(new [] { file })); var module = new ModuleContainer(ctx); module.DocumentationBuilder = new DocumentationBuilder(module); - var source_file = new CompilationSourceFile (module); - var report = new Report (ctx, errorReportPrinter); - ParserSession session = new ParserSession (); - session.LocationsBag = new LocationsBag (); - var parser = new Mono.CSharp.CSharpParser (reader, source_file, report, session); + var source_file = new CompilationSourceFile(module); + var report = new Report(ctx, errorReportPrinter); + var session = new ParserSession(); + session.LocationsBag = new LocationsBag(); + var parser = new Mono.CSharp.CSharpParser(reader, source_file, report, session); parser.Lexer.Line += initialLocation.Line - 1; parser.Lexer.Column += initialLocation.Column - 1; parser.Lexer.putback_char = Tokenizer.DocumentationXref; parser.Lexer.parsing_generic_declaration_doc = true; - parser.parse (); + parser.parse(); if (report.Errors > 0) { // Report.Warning (1584, 1, mc.Location, "XML comment on `{0}' has syntactically incorrect cref attribute `{1}'", // mc.GetSignatureForError (), cref); } - ConversionVisitor conversionVisitor = new ConversionVisitor (false, session.LocationsBag); - DocumentationReference docRef = conversionVisitor.ConvertXmlDoc(module.DocumentationBuilder); + var conversionVisitor = new ConversionVisitor(false, session.LocationsBag); + var docRef = conversionVisitor.ConvertXmlDoc(module.DocumentationBuilder); CompilerCallableEntryPoint.Reset(); return docRef; } diff --git a/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/CompilerSettings.cs b/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/CompilerSettings.cs index e71331e92..1146ff85e 100644 --- a/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/CompilerSettings.cs +++ b/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/CompilerSettings.cs @@ -1,4 +1,4 @@ -// Copyright (c) AlphaSierraPapa for the SharpDevelop Team +// Copyright (c) 2010-2013 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 @@ -125,7 +125,7 @@ namespace ICSharpCode.NRefactory.CSharp IList disabledWarnings = new List(); /// - /// Allows treating specific warnings as errors without setting to true. + /// Disables the specified warnings. /// public IList DisabledWarnings { get { return disabledWarnings; } diff --git a/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/MonoSymbolFile.cs b/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/MonoSymbolFile.cs index 9b83bf3be..8431c70a4 100644 --- a/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/MonoSymbolFile.cs +++ b/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/MonoSymbolFile.cs @@ -130,24 +130,24 @@ namespace Mono.CompilerServices.SymbolWriter public int NumLineNumbers; - internal MonoSymbolFile () + public MonoSymbolFile () { ot = new OffsetTable (); } - internal int AddSource (SourceFileEntry source) + public int AddSource (SourceFileEntry source) { sources.Add (source); return sources.Count; } - internal int AddCompileUnit (CompileUnitEntry entry) + public int AddCompileUnit (CompileUnitEntry entry) { comp_units.Add (entry); return comp_units.Count; } - internal void AddMethod (MethodEntry entry) + public void AddMethod (MethodEntry entry) { methods.Add (entry); } diff --git a/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/MonoSymbolTable.cs b/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/MonoSymbolTable.cs index 88d604f2e..277f25a7f 100644 --- a/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/MonoSymbolTable.cs +++ b/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/MonoSymbolTable.cs @@ -184,6 +184,7 @@ namespace Mono.CompilerServices.SymbolWriter #region This is actually written to the symbol file public readonly int Row; public int Column; + public int EndRow, EndColumn; public readonly int File; public readonly int Offset; public readonly bool IsHidden; // Obsolete is never used @@ -214,17 +215,24 @@ namespace Mono.CompilerServices.SymbolWriter } public LineNumberEntry (int file, int row, int column, int offset, bool is_hidden) + : this (file, row, column, -1, -1, offset, is_hidden) + { + } + + public LineNumberEntry (int file, int row, int column, int end_row, int end_column, int offset, bool is_hidden) { this.File = file; this.Row = row; this.Column = column; + this.EndRow = end_row; + this.EndColumn = end_column; this.Offset = offset; this.IsHidden = is_hidden; } public override string ToString () { - return String.Format ("[Line {0}:{1,2}:{3}]", File, Row, Column, Offset); + return String.Format ("[Line {0}:{1,2}-{3,4}:{5}]", File, Row, Column, EndRow, EndColumn, Offset); } } @@ -601,6 +609,11 @@ namespace Mono.CompilerServices.SymbolWriter DataOffset = reader.ReadInt32 (); } + public void ReadAll () + { + ReadData (); + } + void ReadData () { if (creating) @@ -746,6 +759,7 @@ namespace Mono.CompilerServices.SymbolWriter public string FileName { get { return file_name; } + set { file_name = value; } } public bool AutoGenerated { @@ -830,7 +844,7 @@ namespace Mono.CompilerServices.SymbolWriter this._line_numbers = lines; } - internal void Write (MonoSymbolFile file, MyBinaryWriter bw, bool readColumnsInfo) + internal void Write (MonoSymbolFile file, MyBinaryWriter bw, bool hasColumnsInfo, bool hasEndInfo) { int start = (int) bw.BaseStream.Position; @@ -887,23 +901,37 @@ 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); + if (hasColumnsInfo) { + for (int i = 0; i < LineNumbers.Length; i++) { + var ln = LineNumbers [i]; + if (ln.Row >= 0) + bw.WriteLeb128 (ln.Column); + } + } + + if (hasEndInfo) { + for (int i = 0; i < LineNumbers.Length; i++) { + var ln = LineNumbers [i]; + if (ln.EndRow == -1 || ln.EndColumn == -1 || ln.Row > ln.EndRow) { + bw.WriteLeb128 (0xffffff); + } else { + bw.WriteLeb128 (ln.EndRow - ln.Row); + bw.WriteLeb128 (ln.EndColumn); + } + } } file.ExtendedLineNumberSize += (int) bw.BaseStream.Position - start; } - internal static LineNumberTable Read (MonoSymbolFile file, MyBinaryReader br, bool readColumnsInfo) + internal static LineNumberTable Read (MonoSymbolFile file, MyBinaryReader br, bool readColumnsInfo, bool readEndInfo) { LineNumberTable lnt = new LineNumberTable (file); - lnt.DoRead (file, br, readColumnsInfo); + lnt.DoRead (file, br, readColumnsInfo, readEndInfo); return lnt; } - void DoRead (MonoSymbolFile file, MyBinaryReader br, bool includesColumns) + void DoRead (MonoSymbolFile file, MyBinaryReader br, bool includesColumns, bool includesEnds) { var lines = new List (); @@ -982,6 +1010,20 @@ namespace Mono.CompilerServices.SymbolWriter ln.Column = br.ReadLeb128 (); } } + if (includesEnds) { + for (int i = 0; i < _line_numbers.Length; ++i) { + var ln = _line_numbers[i]; + + int row = br.ReadLeb128 (); + if (row == 0xffffff) { + ln.EndRow = -1; + ln.EndColumn = -1; + } else { + ln.EndRow = ln.Row + row; + ln.EndColumn = br.ReadLeb128 (); + } + } + } } public bool GetMethodBounds (out LineNumberEntry start, out LineNumberEntry end) @@ -1039,7 +1081,8 @@ namespace Mono.CompilerServices.SymbolWriter public enum Flags { LocalNamesAmbiguous = 1, - ColumnsInfoIncluded = 1 << 1 + ColumnsInfoIncluded = 1 << 1, + EndInfoIncluded = 1 << 2 } public const int Size = 12; @@ -1192,8 +1235,13 @@ namespace Mono.CompilerServices.SymbolWriter bw.Write (real_name); } + foreach (var lne in lnt.LineNumbers) { + if (lne.EndRow != -1 || lne.EndColumn != -1) + flags |= Flags.EndInfoIncluded; + } + LineNumberTableOffset = (int) bw.BaseStream.Position; - lnt.Write (file, bw, (flags & Flags.ColumnsInfoIncluded) != 0); + lnt.Write (file, bw, (flags & Flags.ColumnsInfoIncluded) != 0, (flags & Flags.EndInfoIncluded) != 0); DataOffset = (int) bw.BaseStream.Position; @@ -1208,6 +1256,15 @@ namespace Mono.CompilerServices.SymbolWriter bw.WriteLeb128 ((int) flags); } + public void ReadAll () + { + GetLineNumberTable (); + GetLocals (); + GetCodeBlocks (); + GetScopeVariables (); + GetRealName (); + } + public LineNumberTable GetLineNumberTable () { lock (SymbolFile) { @@ -1221,7 +1278,7 @@ namespace Mono.CompilerServices.SymbolWriter long old_pos = reader.BaseStream.Position; reader.BaseStream.Position = LineNumberTableOffset; - lnt = LineNumberTable.Read (SymbolFile, reader, (flags & Flags.ColumnsInfoIncluded) != 0); + lnt = LineNumberTable.Read (SymbolFile, reader, (flags & Flags.ColumnsInfoIncluded) != 0, (flags & Flags.EndInfoIncluded) != 0); reader.BaseStream.Position = old_pos; return lnt; diff --git a/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/MonoSymbolWriter.cs b/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/MonoSymbolWriter.cs index 199ef41d5..b2c2afdba 100644 --- a/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/MonoSymbolWriter.cs +++ b/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/MonoSymbolWriter.cs @@ -47,11 +47,7 @@ namespace Mono.CompilerServices.SymbolWriter string filename; private SourceMethodBuilder current_method; -#if NET_2_1 - System.Collections.Stack current_method_stack = new System.Collections.Stack (); -#else Stack current_method_stack = new Stack (); -#endif public MonoSymbolWriter (string filename) { diff --git a/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/SourceMethodBuilder.cs b/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/SourceMethodBuilder.cs index b45bf8a1f..bd801f657 100644 --- a/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/SourceMethodBuilder.cs +++ b/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/SourceMethodBuilder.cs @@ -37,11 +37,7 @@ namespace Mono.CompilerServices.SymbolWriter List _locals; List _blocks; List _scope_vars; -#if NET_2_1 - System.Collections.Stack _block_stack; -#else Stack _block_stack; -#endif readonly List method_lines; readonly ICompileUnit _comp_unit; @@ -62,9 +58,14 @@ namespace Mono.CompilerServices.SymbolWriter } public void MarkSequencePoint (int offset, SourceFileEntry file, int line, int column, bool is_hidden) + { + MarkSequencePoint (offset, file, line, column, -1, -1, is_hidden); + } + + public void MarkSequencePoint (int offset, SourceFileEntry file, int line, int column, int end_line, int end_column, bool is_hidden) { int file_idx = file != null ? file.Index : 0; - var lne = new LineNumberEntry (file_idx, line, column, offset, is_hidden); + var lne = new LineNumberEntry (file_idx, line, column, end_line, end_column, offset, is_hidden); if (method_lines.Count > 0) { var prev = method_lines[method_lines.Count - 1]; @@ -90,11 +91,7 @@ namespace Mono.CompilerServices.SymbolWriter public void StartBlock (CodeBlockEntry.Type type, int start_offset) { if (_block_stack == null) { -#if NET_2_1 - _block_stack = new System.Collections.Stack (); -#else _block_stack = new Stack (); -#endif } if (_blocks == null) diff --git a/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/anonymous.cs b/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/anonymous.cs index 9a2c4a334..64ea6fa4d 100644 --- a/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/anonymous.cs +++ b/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/anonymous.cs @@ -192,15 +192,32 @@ namespace Mono.CSharp { sealed class ThisInitializer : Statement { readonly HoistedThis hoisted_this; + readonly AnonymousMethodStorey parent; - public ThisInitializer (HoistedThis hoisted_this) + public ThisInitializer (HoistedThis hoisted_this, AnonymousMethodStorey parent) { this.hoisted_this = hoisted_this; + this.parent = parent; } protected override void DoEmit (EmitContext ec) { - hoisted_this.EmitAssign (ec, new CompilerGeneratedThis (ec.CurrentType, loc), false, false); + Expression source; + + if (parent == null) + source = new CompilerGeneratedThis (ec.CurrentType, loc); + else { + source = new FieldExpr (parent.HoistedThis.Field, Location.Null) { + InstanceExpression = new CompilerGeneratedThis (ec.CurrentType, Location.Null) + }; + } + + hoisted_this.EmitAssign (ec, source, false, false); + } + + protected override bool DoFlowAnalysis (FlowAnalysisContext fc) + { + return false; } protected override void CloneTo (CloneContext clonectx, Statement target) @@ -230,22 +247,24 @@ namespace Mono.CSharp { public Expression Instance; bool initialize_hoisted_this; + AnonymousMethodStorey hoisted_this_parent; public AnonymousMethodStorey (ExplicitBlock block, TypeDefinition parent, MemberBase host, TypeParameters tparams, string name, MemberKind kind) - : base (parent, MakeMemberName (host, name, parent.Module.CounterAnonymousContainers, tparams, block.StartLocation), + : base (parent, MakeMemberName (host, name, parent.PartialContainer.CounterAnonymousContainers, tparams, block.StartLocation), tparams, 0, kind) { OriginalSourceBlock = block; - ID = parent.Module.CounterAnonymousContainers++; + ID = parent.PartialContainer.CounterAnonymousContainers++; } - public void AddCapturedThisField (EmitContext ec) + public void AddCapturedThisField (EmitContext ec, AnonymousMethodStorey parent) { TypeExpr type_expr = new TypeExpression (ec.CurrentType, Location); Field f = AddCompilerGeneratedField ("$this", type_expr); hoisted_this = new HoistedThis (this, f); initialize_hoisted_this = true; + hoisted_this_parent = parent; } public Field AddCapturedVariable (string name, TypeSpec type) @@ -316,8 +335,11 @@ namespace Mono.CSharp { var hoisted = localVariable.HoistedVariant; if (hoisted != null && hoisted.Storey != this && hoisted.Storey is StateMachine) { - // TODO: It's too late the field is defined in HoistedLocalVariable ctor + // + // Variable is already hoisted but we need it in storey which can be shared + // hoisted.Storey.hoisted_locals.Remove (hoisted); + hoisted.Storey.Members.Remove (hoisted.Field); hoisted = null; } @@ -551,7 +573,7 @@ namespace Mono.CSharp { // referenced indirectly // if (initialize_hoisted_this) { - rc.CurrentBlock.AddScopeStatement (new ThisInitializer (hoisted_this)); + rc.CurrentBlock.AddScopeStatement (new ThisInitializer (hoisted_this, hoisted_this_parent)); } // @@ -570,6 +592,9 @@ namespace Mono.CSharp { protected virtual void EmitHoistedParameters (EmitContext ec, List hoisted) { foreach (HoistedParameter hp in hoisted) { + if (hp == null) + continue; + // // Parameters could be proxied via local fields for value type storey // @@ -726,6 +751,12 @@ namespace Mono.CSharp { this.field = field; } + public Field Field { + get { + return field; + } + } + public AnonymousMethodStorey Storey { get { return storey; @@ -846,11 +877,7 @@ namespace Mono.CSharp { #region Properties - public Field Field { - get { - return field; - } - } + public bool IsAssigned { get; set; } public ParameterReference Parameter { get { @@ -889,12 +916,6 @@ namespace Mono.CSharp { : base (storey, field) { } - - public Field Field { - get { - return field; - } - } } // @@ -955,6 +976,12 @@ namespace Mono.CSharp { } } + public override bool IsSideEffectFree { + get { + return true; + } + } + public ParametersCompiled Parameters { get { return Block.Parameters; @@ -1002,36 +1029,36 @@ namespace Mono.CSharp { return delegate_type; ec.Report.Error (835, loc, "Cannot convert `{0}' to an expression tree of non-delegate type `{1}'", - GetSignatureForError (), TypeManager.CSharpName (delegate_type)); + GetSignatureForError (), delegate_type.GetSignatureForError ()); return null; } ec.Report.Error (1660, loc, "Cannot convert `{0}' to non-delegate type `{1}'", - GetSignatureForError (), TypeManager.CSharpName (delegate_type)); + GetSignatureForError (), delegate_type.GetSignatureForError ()); return null; } - protected bool VerifyExplicitParameters (ResolveContext ec, TypeSpec delegate_type, AParametersCollection parameters) + protected bool VerifyExplicitParameters (ResolveContext ec, TypeInferenceContext tic, TypeSpec delegate_type, AParametersCollection parameters) { - if (VerifyParameterCompatibility (ec, delegate_type, parameters, ec.IsInProbingMode)) + if (VerifyParameterCompatibility (ec, tic, delegate_type, parameters, ec.IsInProbingMode)) return true; if (!ec.IsInProbingMode) ec.Report.Error (1661, loc, "Cannot convert `{0}' to delegate type `{1}' since there is a parameter mismatch", - GetSignatureForError (), TypeManager.CSharpName (delegate_type)); + GetSignatureForError (), delegate_type.GetSignatureForError ()); return false; } - protected bool VerifyParameterCompatibility (ResolveContext ec, TypeSpec delegate_type, AParametersCollection invoke_pd, bool ignore_errors) + protected bool VerifyParameterCompatibility (ResolveContext ec, TypeInferenceContext tic, TypeSpec delegate_type, AParametersCollection invoke_pd, bool ignore_errors) { if (Parameters.Count != invoke_pd.Count) { if (ignore_errors) return false; ec.Report.Error (1593, loc, "Delegate `{0}' does not take `{1}' arguments", - TypeManager.CSharpName (delegate_type), Parameters.Count.ToString ()); + delegate_type.GetSignatureForError (), Parameters.Count.ToString ()); return false; } @@ -1045,10 +1072,10 @@ namespace Mono.CSharp { return false; if (p_mod == Parameter.Modifier.NONE) - ec.Report.Error (1677, loc, "Parameter `{0}' should not be declared with the `{1}' keyword", - (i + 1).ToString (), Parameter.GetModifierSignature (Parameters.FixedParameters [i].ModFlags)); + ec.Report.Error (1677, Parameters[i].Location, "Parameter `{0}' should not be declared with the `{1}' keyword", + (i + 1).ToString (), Parameter.GetModifierSignature (Parameters [i].ModFlags)); else - ec.Report.Error (1676, loc, "Parameter `{0}' must be declared with the `{1}' keyword", + ec.Report.Error (1676, Parameters[i].Location, "Parameter `{0}' must be declared with the `{1}' keyword", (i+1).ToString (), Parameter.GetModifierSignature (p_mod)); error = true; } @@ -1057,22 +1084,18 @@ namespace Mono.CSharp { continue; TypeSpec type = invoke_pd.Types [i]; + + if (tic != null) + type = tic.InflateGenericArgument (ec, type); - // We assume that generic parameters are always inflated - if (TypeManager.IsGenericParameter (type)) - continue; - - if (TypeManager.HasElementType (type) && TypeManager.IsGenericParameter (TypeManager.GetElementType (type))) - continue; - - if (!TypeSpecComparer.IsEqual (invoke_pd.Types [i], Parameters.Types [i])) { + if (!TypeSpecComparer.IsEqual (type, Parameters.Types [i])) { if (ignore_errors) return false; - ec.Report.Error (1678, loc, "Parameter `{0}' is declared as type `{1}' but should be `{2}'", + ec.Report.Error (1678, Parameters [i].Location, "Parameter `{0}' is declared as type `{1}' but should be `{2}'", (i+1).ToString (), - TypeManager.CSharpName (Parameters.Types [i]), - TypeManager.CSharpName (invoke_pd.Types [i])); + Parameters.Types [i].GetSignatureForError (), + invoke_pd.Types [i].GetSignatureForError ()); error = true; } } @@ -1083,7 +1106,7 @@ namespace Mono.CSharp { // // Infers type arguments based on explicit arguments // - public bool ExplicitTypeInference (ResolveContext ec, TypeInferenceContext type_inference, TypeSpec delegate_type) + public bool ExplicitTypeInference (TypeInferenceContext type_inference, TypeSpec delegate_type) { if (!HasExplicitParameters) return false; @@ -1101,9 +1124,19 @@ namespace Mono.CSharp { if (d_params.Count != Parameters.Count) return false; + var ptypes = Parameters.Types; + var dtypes = d_params.Types; for (int i = 0; i < Parameters.Count; ++i) { - if (type_inference.ExactInference (Parameters.Types[i], d_params.Types[i]) == 0) + if (type_inference.ExactInference (ptypes[i], dtypes[i]) == 0) { + // + // Continue when 0 (quick path) does not mean inference failure. Checking for + // same type handles cases like int -> int + // + if (ptypes[i] == dtypes[i]) + continue; + return false; + } } return true; @@ -1220,6 +1253,17 @@ namespace Mono.CSharp { } } else { am = body.Compatible (ec); + + if (body.DirectMethodGroupConversion != null) { + var errors_printer = new SessionReportPrinter (); + var old = ec.Report.SetPrinter (errors_printer); + var expr = new ImplicitDelegateCreation (delegate_type, body.DirectMethodGroupConversion, loc) { + AllowSpecialMethodsInvocation = true + }.Resolve (ec); + ec.Report.SetPrinter (old); + if (expr != null && errors_printer.ErrorsCount == 0) + am = expr; + } } } catch (CompletionResult) { throw; @@ -1229,7 +1273,7 @@ namespace Mono.CSharp { throw new InternalErrorException (e, loc); } - if (!ec.IsInProbingMode) { + if (!ec.IsInProbingMode && !etree_conversion) { compatibles.Add (type, am ?? EmptyExpression.Null); } @@ -1276,7 +1320,7 @@ namespace Mono.CSharp { return ParametersCompiled.CreateFullyResolved (fixedpars, delegate_parameters.Types); } - if (!VerifyExplicitParameters (ec, delegate_type, delegate_parameters)) { + if (!VerifyExplicitParameters (ec, tic, delegate_type, delegate_parameters)) { return null; } @@ -1306,13 +1350,6 @@ namespace Mono.CSharp { if (!DoResolveParameters (ec)) return null; -#if !STATIC - // FIXME: The emitted code isn't very careful about reachability - // so, ensure we have a 'ret' at the end - BlockContext bc = ec as BlockContext; - if (bc != null && bc.CurrentBranching != null && bc.CurrentBranching.CurrentUsageVector.IsUnreachable) - bc.NeedReturnLabel (); -#endif return this; } @@ -1326,9 +1363,12 @@ namespace Mono.CSharp { // nothing, as we only exist to not do anything. } - public static void Error_AddressOfCapturedVar (ResolveContext ec, IVariableReference var, Location loc) + public static void Error_AddressOfCapturedVar (ResolveContext rc, IVariableReference var, Location loc) { - ec.Report.Error (1686, loc, + if (rc.CurrentAnonymousMethod is AsyncInitializer) + return; + + rc.Report.Error (1686, loc, "Local variable or parameter `{0}' cannot have their address taken and be used inside an anonymous method, lambda expression or query expression", var.Name); } @@ -1355,10 +1395,10 @@ namespace Mono.CSharp { return null; } - b = b.ConvertToAsyncTask (ec, ec.CurrentMemberDefinition.Parent.PartialContainer, p, return_type, loc); + b = b.ConvertToAsyncTask (ec, ec.CurrentMemberDefinition.Parent.PartialContainer, p, return_type, delegate_type, loc); } - return CompatibleMethodFactory (return_type ?? InternalType.Arglist, delegate_type, p, b); + return CompatibleMethodFactory (return_type ?? InternalType.ErrorType, delegate_type, p, b); } protected virtual AnonymousMethodBody CompatibleMethodFactory (TypeSpec return_type, TypeSpec delegate_type, ParametersCompiled p, ParametersBlock b) @@ -1443,7 +1483,7 @@ namespace Mono.CSharp { } } - protected ParametersBlock block; + protected readonly ParametersBlock block; public TypeSpec ReturnType; @@ -1481,35 +1521,35 @@ namespace Mono.CSharp { BlockContext aec = new BlockContext (ec, block, ReturnType); aec.CurrentAnonymousMethod = ae; - ResolveContext.Options flags = 0; - var am = this as AnonymousMethodBody; if (ec.HasSet (ResolveContext.Options.InferReturnType) && am != null) { am.ReturnTypeInference = new TypeInferenceContext (); } - if (ec.IsInProbingMode) - flags |= ResolveContext.Options.ProbingMode; - - if (ec.HasSet (ResolveContext.Options.FieldInitializerScope)) - flags |= ResolveContext.Options.FieldInitializerScope; + var bc = ec as BlockContext; - if (ec.HasSet (ResolveContext.Options.ExpressionTreeConversion)) - flags |= ResolveContext.Options.ExpressionTreeConversion; + if (bc != null) { + aec.AssignmentInfoOffset = bc.AssignmentInfoOffset; + aec.EnclosingLoop = bc.EnclosingLoop; + aec.EnclosingLoopOrSwitch = bc.EnclosingLoopOrSwitch; + aec.Switch = bc.Switch; + } - if (ec.HasSet (ResolveContext.Options.BaseInitializer)) - flags |= ResolveContext.Options.BaseInitializer; + var errors = ec.Report.Errors; - aec.Set (flags); + bool res = Block.Resolve (aec); - var bc = ec as BlockContext; - if (bc != null) - aec.FlowOffset = bc.FlowOffset; + if (res && errors == ec.Report.Errors) { + MarkReachable (new Reachability ()); - var errors = ec.Report.Errors; + if (!CheckReachableExit (ec.Report)) { + return null; + } - bool res = Block.Resolve (ec.CurrentBranching, aec, null); + if (bc != null) + bc.AssignmentInfoOffset = aec.AssignmentInfoOffset; + } if (am != null && am.ReturnTypeInference != null) { am.ReturnTypeInference.FixAllTypes (ec); @@ -1518,10 +1558,14 @@ namespace Mono.CSharp { // // If e is synchronous the inferred return type is T - // If e is asynchronous the inferred return type is Task + // If e is asynchronous and the body of F is either an expression classified as nothing + // or a statement block where no return statements have expressions, the inferred return type is Task + // If e is async and has an inferred result type T, the inferred return type is Task // if (block.IsAsync && ReturnType != null) { - ReturnType = ec.Module.PredefinedTypes.TaskGeneric.TypeSpec.MakeGenericType (ec, new [] { ReturnType }); + ReturnType = ReturnType.Kind == MemberKind.Void ? + ec.Module.PredefinedTypes.Task.TypeSpec : + ec.Module.PredefinedTypes.TaskGeneric.TypeSpec.MakeGenericType (ec, new [] { ReturnType }); } } @@ -1536,6 +1580,48 @@ namespace Mono.CSharp { return false; } + bool CheckReachableExit (Report report) + { + if (block.HasReachableClosingBrace && ReturnType.Kind != MemberKind.Void) { + // FIXME: Flow-analysis on MoveNext generated code + if (!IsIterator) { + report.Error (1643, StartLocation, + "Not all code paths return a value in anonymous method of type `{0}'", GetSignatureForError ()); + + return false; + } + } + + return true; + } + + public override void FlowAnalysis (FlowAnalysisContext fc) + { + // We are reachable, mark block body reachable too + MarkReachable (new Reachability ()); + + CheckReachableExit (fc.Report); + + var das = fc.BranchDefiniteAssignment (); + var prev_pb = fc.ParametersBlock; + fc.ParametersBlock = Block; + var da_ontrue = fc.DefiniteAssignmentOnTrue; + var da_onfalse = fc.DefiniteAssignmentOnFalse; + + fc.DefiniteAssignmentOnTrue = fc.DefiniteAssignmentOnFalse = null; + block.FlowAnalysis (fc); + + fc.ParametersBlock = prev_pb; + fc.DefiniteAssignment = das; + fc.DefiniteAssignmentOnTrue = da_ontrue; + fc.DefiniteAssignmentOnFalse = da_onfalse; + } + + public override void MarkReachable (Reachability rc) + { + block.MarkReachable (rc); + } + public void SetHasThisAccess () { ExplicitBlock b = block; @@ -1574,6 +1660,14 @@ namespace Mono.CSharp { get { return "anonymous method"; } } + // + // Method-group instance for lambdas which can be replaced with + // simple method group call + // + public MethodGroupExpr DirectMethodGroupConversion { + get; set; + } + public override bool IsIterator { get { return false; @@ -1596,7 +1690,9 @@ namespace Mono.CSharp { } public override AnonymousMethodStorey Storey { - get { return storey; } + get { + return storey; + } } #endregion @@ -1635,34 +1731,46 @@ namespace Mono.CSharp { Modifiers modifiers; TypeDefinition parent = null; + TypeParameters hoisted_tparams = null; var src_block = Block.Original.Explicit; if (src_block.HasCapturedVariable || src_block.HasCapturedThis) { parent = storey = FindBestMethodStorey (); if (storey == null) { - var sm = src_block.ParametersBlock.TopBlock.StateMachine; + var top_block = src_block.ParametersBlock.TopBlock; + var sm = top_block.StateMachine; - // - // Remove hoisted this demand when simple instance method is enough - // if (src_block.HasCapturedThis) { - src_block.ParametersBlock.TopBlock.RemoveThisReferenceFromChildrenBlock (src_block); - // - // Special case where parent class is used to emit instance method - // because currect storey is of value type (async host) and we don't - // want to create another childer storey to host this reference only + // Remove hoisted 'this' request when simple instance method is + // enough. No hoisted variables only 'this' and don't need to + // propagate this to value type state machine. // - if (sm != null && sm.Kind == MemberKind.Struct) - parent = sm.Parent.PartialContainer; + StateMachine sm_parent; + var pb = src_block.ParametersBlock; + do { + sm_parent = pb.StateMachine; + pb = pb.Parent == null ? null : pb.Parent.ParametersBlock; + } while (sm_parent == null && pb != null); + + if (sm_parent == null) { + top_block.RemoveThisReferenceFromChildrenBlock (src_block); + } else if (sm_parent.Kind == MemberKind.Struct) { + // + // Special case where parent class is used to emit instance method + // because currect storey is of value type (async host) and we cannot + // use ldftn on non-boxed instances either to share mutated state + // + parent = sm_parent.Parent.PartialContainer; + hoisted_tparams = sm_parent.OriginalTypeParameters; + } else if (sm is IteratorStorey) { + // + // For iterators we can host everything in one class + // + parent = storey = sm; + } } - - // - // For iterators we can host everything in one class - // - if (sm is IteratorStorey) - parent = storey = sm; } modifiers = storey != null ? Modifiers.INTERNAL : Modifiers.PRIVATE; @@ -1673,16 +1781,17 @@ namespace Mono.CSharp { modifiers = Modifiers.STATIC | Modifiers.PRIVATE; } + if (storey == null && hoisted_tparams == null) + hoisted_tparams = ec.CurrentTypeParameters; + if (parent == null) parent = ec.CurrentTypeDefinition.Parent.PartialContainer; string name = CompilerGeneratedContainer.MakeName (parent != storey ? block_name : null, - "m", null, ec.Module.CounterAnonymousMethods++); + "m", null, parent.PartialContainer.CounterAnonymousMethods++); MemberName member_name; - if (storey == null && ec.CurrentTypeParameters != null) { - - var hoisted_tparams = ec.CurrentTypeParameters; + if (hoisted_tparams != null) { var type_params = new TypeParameters (hoisted_tparams.Count); for (int i = 0; i < hoisted_tparams.Count; ++i) { type_params.Add (hoisted_tparams[i].CreateHoistedCopy (null)); @@ -1720,6 +1829,7 @@ namespace Mono.CSharp { // method = DoCreateMethodHost (ec); method.Define (); + method.PrepareEmit (); } bool is_static = (method.ModFlags & Modifiers.STATIC) != 0; @@ -1784,12 +1894,8 @@ namespace Mono.CSharp { // Special case for value type storey where this is not lifted but // droped off to parent class // - for (var b = Block.Parent; b != null; b = b.Parent) { - if (b.ParametersBlock.StateMachine != null) { - ec.Emit (OpCodes.Ldfld, b.ParametersBlock.StateMachine.HoistedThis.Field.Spec); - break; - } - } + if (ec.CurrentAnonymousMethod != null && ec.AsyncTaskStorey != null) + ec.Emit (OpCodes.Ldfld, ec.AsyncTaskStorey.HoistedThis.Field.Spec); } var delegate_method = method.Spec; @@ -1806,8 +1912,17 @@ namespace Mono.CSharp { ec.Emit (OpCodes.Ldftn, TypeBuilder.GetMethod (t.GetMetaInfo (), (MethodInfo) delegate_method.GetMetaInfo ())); } else { - if (delegate_method.IsGeneric) - delegate_method = delegate_method.MakeGenericMethod (ec.MemberContext, method.TypeParameters); + if (delegate_method.IsGeneric) { + TypeParameterSpec[] tparams; + var sm = ec.CurrentAnonymousMethod == null ? null : ec.CurrentAnonymousMethod.Storey as StateMachine; + if (sm != null && sm.OriginalTypeParameters != null) { + tparams = sm.CurrentTypeParameters.Types; + } else { + tparams = method.TypeParameters; + } + + delegate_method = delegate_method.MakeGenericMethod (ec.MemberContext, tparams); + } ec.Emit (OpCodes.Ldftn, delegate_method); } @@ -1846,7 +1961,7 @@ namespace Mono.CSharp { public override string GetSignatureForError () { - return TypeManager.CSharpName (type); + return type.GetSignatureForError (); } } @@ -1968,7 +2083,7 @@ namespace Mono.CSharp { Method tostring = new Method (this, new TypeExpression (Compiler.BuiltinTypes.String, loc), Modifiers.PUBLIC | Modifiers.OVERRIDE | Modifiers.DEBUGGER_HIDDEN, new MemberName ("ToString", loc), - Mono.CSharp.ParametersCompiled.EmptyReadOnlyParameters, null); + ParametersCompiled.EmptyReadOnlyParameters, null); ToplevelBlock equals_block = new ToplevelBlock (Compiler, equals.ParameterInfo, loc); @@ -1985,7 +2100,7 @@ namespace Mono.CSharp { } var li_other = LocalVariable.CreateCompilerGenerated (CurrentType, equals_block, loc); - equals_block.AddStatement (new BlockVariableDeclaration (new TypeExpression (li_other.Type, loc), li_other)); + equals_block.AddStatement (new BlockVariable (new TypeExpression (li_other.Type, loc), li_other)); var other_variable = new LocalVariableReference (li_other, loc); MemberAccess system_collections_generic = new MemberAccess (new MemberAccess ( @@ -2076,7 +2191,7 @@ namespace Mono.CSharp { Method hashcode = new Method (this, new TypeExpression (Compiler.BuiltinTypes.Int, loc), Modifiers.PUBLIC | Modifiers.OVERRIDE | Modifiers.DEBUGGER_HIDDEN, new MemberName ("GetHashCode", loc), - Mono.CSharp.ParametersCompiled.EmptyReadOnlyParameters, null); + ParametersCompiled.EmptyReadOnlyParameters, null); // // Modified FNV with good avalanche behavior and uniform @@ -2097,7 +2212,7 @@ namespace Mono.CSharp { hashcode_top.AddStatement (new Unchecked (hashcode_block, loc)); var li_hash = LocalVariable.CreateCompilerGenerated (Compiler.BuiltinTypes.Int, hashcode_top, loc); - hashcode_block.AddStatement (new BlockVariableDeclaration (new TypeExpression (li_hash.Type, loc), li_hash)); + hashcode_block.AddStatement (new BlockVariable (new TypeExpression (li_hash.Type, loc), li_hash)); LocalVariableReference hash_variable_assign = new LocalVariableReference (li_hash, loc); hashcode_block.AddStatement (new StatementExpression ( new SimpleAssign (hash_variable_assign, rs_hashcode))); diff --git a/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/argument.cs b/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/argument.cs index 22e28eaf7..13d0526cc 100644 --- a/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/argument.cs +++ b/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/argument.cs @@ -47,9 +47,6 @@ namespace Mono.CSharp public Argument (Expression expr) { - if (expr == null) - throw new ArgumentNullException (); - this.Expr = expr; } @@ -130,12 +127,35 @@ namespace Mono.CSharp return this; } + public void FlowAnalysis (FlowAnalysisContext fc) + { + if (ArgType == AType.Out) { + var vr = Expr as VariableReference; + if (vr != null) { + if (vr.VariableInfo != null) + fc.SetVariableAssigned (vr.VariableInfo); + + return; + } + + var fe = Expr as FieldExpr; + if (fe != null) { + fe.SetFieldAssigned (fc); + return; + } + + return; + } + + Expr.FlowAnalysis (fc); + } + public string GetSignatureForError () { if (Expr.eclass == ExprClass.MethodGroup) return Expr.ExprClassName; - return TypeManager.CSharpName (Expr.Type); + return Expr.Type.GetSignatureForError (); } public bool ResolveMethodGroup (ResolveContext ec) @@ -155,18 +175,16 @@ namespace Mono.CSharp public void Resolve (ResolveContext ec) { -// using (ec.With (ResolveContext.Options.DoFlowAnalysis, true)) { - // Verify that the argument is readable - if (ArgType != AType.Out) - Expr = Expr.Resolve (ec); + // Verify that the argument is readable + if (ArgType != AType.Out) + Expr = Expr.Resolve (ec); - // Verify that the argument is writeable - if (Expr != null && IsByRef) - Expr = Expr.ResolveLValue (ec, EmptyExpression.OutAccess); + // Verify that the argument is writeable + if (Expr != null && IsByRef) + Expr = Expr.ResolveLValue (ec, EmptyExpression.OutAccess); - if (Expr == null) - Expr = ErrorExpression.Instance; -// } + if (Expr == null) + Expr = ErrorExpression.Instance; } } @@ -350,7 +368,7 @@ namespace Mono.CSharp } else if (arg_type.Kind == MemberKind.Void || arg_type == InternalType.Arglist || arg_type.IsPointer) { rc.Report.Error (1978, a.Expr.Location, "An expression of type `{0}' cannot be used as an argument of dynamic operation", - TypeManager.CSharpName (arg_type)); + arg_type.GetSignatureForError ()); } info_flags = new Binary (Binary.Operator.BitwiseOr, info_flags, @@ -479,6 +497,29 @@ namespace Mono.CSharp return null; } + public void FlowAnalysis (FlowAnalysisContext fc) + { + bool has_out = false; + foreach (var arg in args) { + if (arg.ArgType == Argument.AType.Out) { + has_out = true; + continue; + } + + arg.FlowAnalysis (fc); + } + + if (!has_out) + return; + + foreach (var arg in args) { + if (arg.ArgType != Argument.AType.Out) + continue; + + arg.FlowAnalysis (fc); + } + } + public List.Enumerator GetEnumerator () { return args.GetEnumerator (); diff --git a/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/assembly.cs b/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/assembly.cs index f95a4d3cf..f93c03839 100644 --- a/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/assembly.cs +++ b/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/assembly.cs @@ -7,7 +7,7 @@ // // Copyright 2001, 2002, 2003 Ximian, Inc. // Copyright 2004-2011 Novell, Inc. -// Copyright 2011 Xamarin Inc +// Copyright 2011-2013 Xamarin Inc // @@ -36,7 +36,6 @@ namespace Mono.CSharp public interface IAssemblyDefinition { string FullName { get; } - bool HasExtensionMethod { get; } bool IsCLSCompliant { get; } bool IsMissing { get; } string Name { get; } @@ -55,6 +54,7 @@ namespace Mono.CSharp bool is_cls_compliant; bool wrap_non_exception_throws; bool wrap_non_exception_throws_custom; + bool has_user_debuggable; protected ModuleContainer module; readonly string name; @@ -75,6 +75,9 @@ namespace Mono.CSharp Dictionary emitted_forwarders; AssemblyAttributesPlaceholder module_target_attrs; + // Win32 version info values + string vi_product, vi_product_version, vi_company, vi_copyright, vi_trademark; + protected AssemblyDefinition (ModuleContainer module, string name) { this.module = module; @@ -132,12 +135,6 @@ namespace Mono.CSharp } } - public bool HasExtensionMethod { - get { - return module.HasExtensionMethod; - } - } - public bool HasCLSCompliantAttribute { get { return cls_attribute != null; @@ -161,6 +158,8 @@ namespace Mono.CSharp } } + public bool IsSatelliteAssembly { get; private set; } + public string Name { get { return name; @@ -208,7 +207,7 @@ namespace Mono.CSharp return; if (Compiler.Settings.Target == Target.Exe) { - a.Error_AttributeEmitError ("The executables cannot be satelite assemblies, remove the attribute or keep it empty"); + Report.Error (7059, a.Location, "Executables cannot be satellite assemblies. Remove the attribute or keep it empty"); return; } @@ -221,6 +220,7 @@ namespace Mono.CSharp builder_extra.SetCulture (value, a.Location); } + IsSatelliteAssembly = true; return; } @@ -231,7 +231,8 @@ namespace Mono.CSharp var vinfo = IsValidAssemblyVersion (value, true); if (vinfo == null) { - a.Error_AttributeEmitError (string.Format ("Specified version `{0}' is not valid", value)); + Report.Error (7034, a.Location, "The specified version string `{0}' does not conform to the required format - major[.minor[.build[.revision]]]", + value); return; } @@ -292,7 +293,7 @@ namespace Mono.CSharp } else if (emitted_forwarders.ContainsKey (t.MemberDefinition)) { Report.SymbolRelatedToPreviousError (emitted_forwarders[t.MemberDefinition].Location, null); Report.Error (739, a.Location, "A duplicate type forward of type `{0}'", - TypeManager.CSharpName (t)); + t.GetSignatureForError ()); return; } @@ -301,13 +302,13 @@ namespace Mono.CSharp if (t.MemberDefinition.DeclaringAssembly == this) { Report.SymbolRelatedToPreviousError (t); Report.Error (729, a.Location, "Cannot forward type `{0}' because it is defined in this assembly", - TypeManager.CSharpName (t)); + t.GetSignatureForError ()); return; } if (t.IsNested) { Report.Error (730, a.Location, "Cannot forward type `{0}' because it is a nested type", - TypeManager.CSharpName (t)); + t.GetSignatureForError ()); return; } @@ -322,13 +323,18 @@ namespace Mono.CSharp if (a.Type == pa.InternalsVisibleTo) { string assembly_name = a.GetString (); + if (assembly_name == null) { + Report.Error (7030, a.Location, "Friend assembly reference cannot have `null' value"); + return; + } + if (assembly_name.Length == 0) return; #if STATIC ParsedAssemblyName aname; ParseAssemblyResult r = Fusion.ParseAssemblyName (assembly_name, out aname); if (r != ParseAssemblyResult.OK) { - Report.Warning (1700, 3, a.Location, "Assembly reference `{0}' is invalid and cannot be resolved", + Report.Warning (1700, 3, a.Location, "Friend assembly reference `{0}' is invalid and cannot be resolved", assembly_name); return; } @@ -351,14 +357,30 @@ namespace Mono.CSharp } else if (a.Type == pa.RuntimeCompatibility) { wrap_non_exception_throws_custom = true; } else if (a.Type == pa.AssemblyFileVersion) { - string value = a.GetString (); - if (string.IsNullOrEmpty (value) || IsValidAssemblyVersion (value, false) == null) { - Report.Warning (1607, 1, a.Location, "The version number `{0}' specified for `{1}' is invalid", - value, a.Name); + vi_product_version = a.GetString (); + if (string.IsNullOrEmpty (vi_product_version) || IsValidAssemblyVersion (vi_product_version, false) == null) { + Report.Warning (7035, 1, a.Location, "The specified version string `{0}' does not conform to the recommended format major.minor.build.revision", + vi_product_version, a.Name); return; } - } + // File version info decoding from blob is not supported + var cab = new CustomAttributeBuilder ((ConstructorInfo) ctor.GetMetaInfo (), new object[] { vi_product_version }); + Builder.SetCustomAttribute (cab); + return; + } else if (a.Type == pa.AssemblyProduct) { + vi_product = a.GetString (); + } else if (a.Type == pa.AssemblyCompany) { + vi_company = a.GetString (); + } else if (a.Type == pa.AssemblyDescription) { + // TODO: Needs extra api + } else if (a.Type == pa.AssemblyCopyright) { + vi_copyright = a.GetString (); + } else if (a.Type == pa.AssemblyTrademark) { + vi_trademark = a.GetString (); + } else if (a.Type == pa.Debuggable) { + has_user_debuggable = true; + } SetCustomAttribute (ctor, cdata); } @@ -374,7 +396,7 @@ namespace Mono.CSharp // no working SRE API foreach (var entry in Importer.Assemblies) { var a = entry as ImportedAssemblyDefinition; - if (a == null) + if (a == null || a.IsMissing) continue; if (public_key != null && !a.HasStrongName) { @@ -383,8 +405,8 @@ namespace Mono.CSharp } var ci = a.Assembly.GetName ().CultureInfo; - if (!ci.Equals (System.Globalization.CultureInfo.InvariantCulture)) { - Report.Warning (1607, 1, "Referenced assembly `{0}' has different culture setting of `{1}'", + if (!ci.Equals (CultureInfo.InvariantCulture)) { + Report.Warning (8009, 1, "Referenced assembly `{0}' has different culture setting of `{1}'", a.Name, ci.Name); } @@ -464,26 +486,39 @@ namespace Mono.CSharp } } - if (!wrap_non_exception_throws_custom) { - PredefinedAttribute pa = module.PredefinedAttributes.RuntimeCompatibility; - if (pa.IsDefined && pa.ResolveBuilder ()) { - var prop = module.PredefinedMembers.RuntimeCompatibilityWrapNonExceptionThrows.Get (); - if (prop != null) { - AttributeEncoder encoder = new AttributeEncoder (); - encoder.EncodeNamedPropertyArgument (prop, new BoolLiteral (Compiler.BuiltinTypes, true, Location.Null)); - SetCustomAttribute (pa.Constructor, encoder.ToArray ()); + if (!IsSatelliteAssembly) { + if (!has_user_debuggable && Compiler.Settings.GenerateDebugInfo) { + var pa = module.PredefinedAttributes.Debuggable; + if (pa.IsDefined) { + var modes = System.Diagnostics.DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints; + if (!Compiler.Settings.Optimize) + modes |= System.Diagnostics.DebuggableAttribute.DebuggingModes.DisableOptimizations; + + pa.EmitAttribute (Builder, modes); } } - } - if (declarative_security != null) { -#if STATIC - foreach (var entry in declarative_security) { - Builder.__AddDeclarativeSecurity (entry); + if (!wrap_non_exception_throws_custom) { + PredefinedAttribute pa = module.PredefinedAttributes.RuntimeCompatibility; + if (pa.IsDefined && pa.ResolveBuilder ()) { + var prop = module.PredefinedMembers.RuntimeCompatibilityWrapNonExceptionThrows.Get (); + if (prop != null) { + AttributeEncoder encoder = new AttributeEncoder (); + encoder.EncodeNamedPropertyArgument (prop, new BoolLiteral (Compiler.BuiltinTypes, true, Location.Null)); + SetCustomAttribute (pa.Constructor, encoder.ToArray ()); + } + } } + + if (declarative_security != null) { +#if STATIC + foreach (var entry in declarative_security) { + Builder.__AddDeclarativeSecurity (entry); + } #else - throw new NotSupportedException ("Assembly-level security"); + throw new NotSupportedException ("Assembly-level security"); #endif + } } CheckReferencesPublicToken (); @@ -751,7 +786,7 @@ namespace Mono.CSharp if (Compiler.Settings.Win32ResourceFile != null) { Builder.DefineUnmanagedResource (Compiler.Settings.Win32ResourceFile); } else { - Builder.DefineVersionInfoResource (); + Builder.DefineVersionInfoResource (vi_product, vi_product_version, vi_company, vi_copyright, vi_trademark); } if (Compiler.Settings.Win32IconFile != null) { @@ -909,7 +944,7 @@ namespace Mono.CSharp return; } - var mtype = texpr.Type.MemberDefinition as ClassOrStruct; + var mtype = texpr.MemberDefinition as ClassOrStruct; if (mtype == null) { Report.Error (1556, "`{0}' specified for Main method must be a valid class or struct", main_class); return; @@ -1100,19 +1135,19 @@ namespace Mono.CSharp } } - abstract class AssemblyReferencesLoader + abstract class AssemblyReferencesLoader where T : class { protected readonly CompilerContext compiler; protected readonly List paths; - public AssemblyReferencesLoader (CompilerContext compiler) + protected AssemblyReferencesLoader (CompilerContext compiler) { this.compiler = compiler; paths = new List (); - paths.AddRange (compiler.Settings.ReferencesLookupPaths); paths.Add (Directory.GetCurrentDirectory ()); + paths.AddRange (compiler.Settings.ReferencesLookupPaths); } public abstract bool HasObjectType (T assembly); @@ -1169,15 +1204,27 @@ namespace Mono.CSharp if (loaded.Contains (key)) continue; - // A corlib assembly is the first assembly which contains System.Object - if (corlib_assembly == null && HasObjectType (a)) { - corlib_assembly = a; - continue; - } - loaded.Add (key); } + if (corlib_assembly == null) { + // + // Requires second pass because HasObjectType can trigger assembly load event + // + for (int i = 0; i < loaded.Count; ++i) { + var assembly = loaded [i]; + + // + // corlib assembly is the first referenced assembly which contains System.Object + // + if (HasObjectType (assembly.Item2)) { + corlib_assembly = assembly.Item2; + loaded.RemoveAt (i); + break; + } + } + } + foreach (var entry in module.Compiler.Settings.AssemblyReferencesAliases) { a = LoadAssemblyFile (entry.Item2, false); if (a == null) diff --git a/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/assign.cs b/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/assign.cs index ce8e25430..18c2d8ca7 100644 --- a/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/assign.cs +++ b/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/assign.cs @@ -310,6 +310,12 @@ namespace Mono.CSharp { } } + public override Location StartLocation { + get { + return target.StartLocation; + } + } + public override bool ContainsEmitWithAwait () { return target.ContainsEmitWithAwait () || source.ContainsEmitWithAwait (); @@ -328,7 +334,7 @@ namespace Mono.CSharp { if (source == null) { ok = false; - source = EmptyExpression.Null; + source = ErrorExpression.Instance; } target = target.ResolveLValue (ec, source); @@ -357,7 +363,7 @@ namespace Mono.CSharp { return this; } -#if NET_4_0 || MONODROID +#if NET_4_0 || MOBILE_DYNAMIC public override System.Linq.Expressions.Expression MakeExpression (BuilderContext ctx) { var tassign = target as IDynamicAssign; @@ -411,6 +417,14 @@ namespace Mono.CSharp { Emit (ec, true); } + public override void FlowAnalysis (FlowAnalysisContext fc) + { + source.FlowAnalysis (fc); + + if (target is ArrayAccess || target is IndexerExpr || target is PropertyExpr) + target.FlowAnalysis (fc); + } + protected override void CloneTo (CloneContext clonectx, Expression t) { Assign _target = (Assign) t; @@ -464,6 +478,32 @@ namespace Mono.CSharp { { return visitor.Visit (this); } + + public override void FlowAnalysis (FlowAnalysisContext fc) + { + base.FlowAnalysis (fc); + + var vr = target as VariableReference; + if (vr != null) { + if (vr.VariableInfo != null) + fc.SetVariableAssigned (vr.VariableInfo); + + return; + } + + var fe = target as FieldExpr; + if (fe != null) { + fe.SetFieldAssigned (fc); + return; + } + } + + public override void MarkReachable (Reachability rc) + { + var es = source as ExpressionStatement; + if (es != null) + es.MarkReachable (rc); + } } public class RuntimeExplicitAssign : Assign @@ -520,20 +560,24 @@ namespace Mono.CSharp { // share same constructor (block) for expression trees resolve but // they have they own resolve scope // - sealed class FieldInitializerContext : ResolveContext + sealed class FieldInitializerContext : BlockContext { - ExplicitBlock ctor_block; + readonly ExplicitBlock ctor_block; - public FieldInitializerContext (IMemberContext mc, ResolveContext constructorContext) - : base (mc, Options.FieldInitializerScope | Options.ConstructorScope) + public FieldInitializerContext (IMemberContext mc, BlockContext constructorContext) + : base (mc, null, constructorContext.ReturnType) { + flags |= Options.FieldInitializerScope | Options.ConstructorScope; this.ctor_block = constructorContext.CurrentBlock.Explicit; + + if (ctor_block.IsCompilerGenerated) + CurrentBlock = ctor_block; } public override ExplicitBlock ConstructorBlock { - get { - return ctor_block; - } + get { + return ctor_block; + } } } @@ -541,7 +585,7 @@ namespace Mono.CSharp { // Keep resolved value because field initializers have their own rules // ExpressionStatement resolved; - IMemberContext mc; + FieldBase mc; public FieldInitializer (FieldBase mc, Expression expression, Location loc) : base (new FieldExpr (mc.Spec, expression.Location), expression, loc) @@ -551,15 +595,31 @@ namespace Mono.CSharp { ((FieldExpr)target).InstanceExpression = new CompilerGeneratedThis (mc.CurrentType, expression.Location); } - protected override Expression DoResolve (ResolveContext ec) + public int AssignmentOffset { get; private set; } + + public FieldBase Field { + get { + return mc; + } + } + + public override Location StartLocation { + get { + return loc; + } + } + + protected override Expression DoResolve (ResolveContext rc) { // Field initializer can be resolved (fail) many times if (source == null) return null; if (resolved == null) { - var ctx = new FieldInitializerContext (mc, ec); + var bc = (BlockContext) rc; + var ctx = new FieldInitializerContext (mc, bc); resolved = base.DoResolve (ctx) as ExpressionStatement; + AssignmentOffset = ctx.AssignmentInfoOffset - bc.AssignmentInfoOffset; } return resolved; @@ -586,6 +646,11 @@ namespace Mono.CSharp { else base.EmitStatement (ec); } + + public override void FlowAnalysis (FlowAnalysisContext fc) + { + source.FlowAnalysis (fc); + } public bool IsDefaultInitializer { get { @@ -605,6 +670,33 @@ namespace Mono.CSharp { } } + class PrimaryConstructorAssign : SimpleAssign + { + readonly Field field; + readonly Parameter parameter; + + public PrimaryConstructorAssign (Field field, Parameter parameter) + : base (null, null, parameter.Location) + { + this.field = field; + this.parameter = parameter; + } + + protected override Expression DoResolve (ResolveContext rc) + { + target = new FieldExpr (field, loc); + source = rc.CurrentBlock.ParametersBlock.GetParameterInfo (parameter).CreateReferenceExpression (rc, loc); + return base.DoResolve (rc); + } + + public override void EmitStatement (EmitContext ec) + { + using (ec.With (BuilderContext.Options.OmitDebugInfo, true)) { + base.EmitStatement (ec); + } + } + } + // // This class is used for compound assignments. // @@ -779,6 +871,12 @@ namespace Mono.CSharp { return base.DoResolve (ec); } + public override void FlowAnalysis (FlowAnalysisContext fc) + { + target.FlowAnalysis (fc); + source.FlowAnalysis (fc); + } + protected override Expression ResolveConversions (ResolveContext ec) { // @@ -803,8 +901,19 @@ namespace Mono.CSharp { // Otherwise, if the selected operator is a predefined operator // Binary b = source as Binary; - if (b == null && source is ReducedExpression) - b = ((ReducedExpression) source).OriginalExpression as Binary; + if (b == null) { + if (source is ReducedExpression) + b = ((ReducedExpression) source).OriginalExpression as Binary; + else if (source is ReducedExpression.ReducedConstantExpression) { + b = ((ReducedExpression.ReducedConstantExpression) source).OriginalExpression as Binary; + } else if (source is Nullable.LiftedBinaryOperator) { + var po = ((Nullable.LiftedBinaryOperator) source); + if (po.UserOperator == null) + b = po.Binary; + } else if (source is TypeCast) { + b = ((TypeCast) source).Child as Binary; + } + } if (b != null) { // diff --git a/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/async.cs b/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/async.cs index e962e7d62..671e53a55 100644 --- a/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/async.cs +++ b/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/async.cs @@ -7,7 +7,7 @@ // Dual licensed under the terms of the MIT X11 or GNU GPL // // Copyright 2011 Novell, Inc. -// Copyright 2011 Xamarin Inc. +// Copyright 2011-2012 Xamarin Inc. // using System; @@ -16,8 +16,10 @@ using System.Linq; using System.Collections; #if STATIC +using IKVM.Reflection; using IKVM.Reflection.Emit; #else +using System.Reflection; using System.Reflection.Emit; #endif @@ -69,6 +71,13 @@ namespace Mono.CSharp return true; } + public override void FlowAnalysis (FlowAnalysisContext fc) + { + stmt.Expr.FlowAnalysis (fc); + + stmt.RegisterResumePoint (); + } + protected override Expression DoResolve (ResolveContext rc) { if (rc.HasSet (ResolveContext.Options.LockScope)) { @@ -119,6 +128,12 @@ namespace Mono.CSharp stmt.EmitStatement (ec); } + public override void MarkReachable (Reachability rc) + { + base.MarkReachable (rc); + stmt.MarkReachable (rc); + } + public override object Accept (StructuralVisitor visitor) { return visitor.Visit (this); @@ -127,13 +142,15 @@ namespace Mono.CSharp public class AwaitStatement : YieldStatement { - sealed class AwaitableMemberAccess : MemberAccess + public sealed class AwaitableMemberAccess : MemberAccess { public AwaitableMemberAccess (Expression expr) : base (expr, "GetAwaiter") { } + public bool ProbingMode { get; set; } + protected override void Error_TypeDoesNotContainDefinition (ResolveContext rc, TypeSpec type, string name) { Error_OperatorCannotBeApplied (rc, type); @@ -141,6 +158,9 @@ namespace Mono.CSharp protected override void Error_OperatorCannotBeApplied (ResolveContext rc, TypeSpec type) { + if (ProbingMode) + return; + var invocation = LeftExpression as Invocation; if (invocation != null && invocation.MethodGroup != null && (invocation.MethodGroup.BestCandidate.Modifiers & Modifiers.ASYNC) != 0) { rc.Report.Error (4008, loc, "Cannot await void method `{0}'. Consider changing method return type to `Task'", @@ -167,21 +187,21 @@ namespace Mono.CSharp } Field awaiter; - PropertySpec is_completed; - MethodSpec get_result; + AwaiterDefinition awaiter_definition; TypeSpec type; TypeSpec result_type; public AwaitStatement (Expression expr, Location loc) : base (expr, loc) { + unwind_protect = true; } #region Properties bool IsDynamic { get { - return is_completed == null; + return awaiter_definition == null; } } @@ -195,7 +215,9 @@ namespace Mono.CSharp protected override void DoEmit (EmitContext ec) { - GetResultExpression (ec).Emit (ec); + using (ec.With (BuilderContext.Options.OmitDebugInfo, true)) { + GetResultExpression (ec).Emit (ec); + } } public Expression GetResultExpression (EmitContext ec) @@ -209,49 +231,49 @@ namespace Mono.CSharp if (IsDynamic) { var rc = new ResolveContext (ec.MemberContext); return new Invocation (new MemberAccess (fe_awaiter, "GetResult"), new Arguments (0)).Resolve (rc); - } else { - var mg_result = MethodGroupExpr.CreatePredefined (get_result, fe_awaiter.Type, loc); - mg_result.InstanceExpression = fe_awaiter; - - return new GetResultInvocation (mg_result, new Arguments (0)); } + + var mg_result = MethodGroupExpr.CreatePredefined (awaiter_definition.GetResult, fe_awaiter.Type, loc); + mg_result.InstanceExpression = fe_awaiter; + + return new GetResultInvocation (mg_result, new Arguments (0)); } public void EmitPrologue (EmitContext ec) { - awaiter = ((AsyncTaskStorey) machine_initializer.Storey).AddAwaiter (expr.Type, loc); + awaiter = ((AsyncTaskStorey) machine_initializer.Storey).AddAwaiter (expr.Type); var fe_awaiter = new FieldExpr (awaiter, loc); fe_awaiter.InstanceExpression = new CompilerGeneratedThis (ec.CurrentType, loc); - // - // awaiter = expr.GetAwaiter (); - // + Label skip_continuation = ec.DefineLabel (); + using (ec.With (BuilderContext.Options.OmitDebugInfo, true)) { + // + // awaiter = expr.GetAwaiter (); + // fe_awaiter.EmitAssign (ec, expr, false, false); - } - Label skip_continuation = ec.DefineLabel (); + Expression completed_expr; + if (IsDynamic) { + var rc = new ResolveContext (ec.MemberContext); - Expression completed_expr; - if (IsDynamic) { - var rc = new ResolveContext (ec.MemberContext); + Arguments dargs = new Arguments (1); + dargs.Add (new Argument (fe_awaiter)); + completed_expr = new DynamicMemberBinder ("IsCompleted", dargs, loc).Resolve (rc); - Arguments dargs = new Arguments (1); - dargs.Add (new Argument (fe_awaiter)); - completed_expr = new DynamicMemberBinder ("IsCompleted", dargs, loc).Resolve (rc); + dargs = new Arguments (1); + dargs.Add (new Argument (completed_expr)); + completed_expr = new DynamicConversion (ec.Module.Compiler.BuiltinTypes.Bool, 0, dargs, loc).Resolve (rc); + } else { + var pe = PropertyExpr.CreatePredefined (awaiter_definition.IsCompleted, loc); + pe.InstanceExpression = fe_awaiter; + completed_expr = pe; + } - dargs = new Arguments (1); - dargs.Add (new Argument (completed_expr)); - completed_expr = new DynamicConversion (ec.Module.Compiler.BuiltinTypes.Bool, 0, dargs, loc).Resolve (rc); - } else { - var pe = PropertyExpr.CreatePredefined (is_completed, loc); - pe.InstanceExpression = fe_awaiter; - completed_expr = pe; + completed_expr.EmitBranchable (ec, skip_continuation, true); } - completed_expr.EmitBranchable (ec, skip_continuation, true); - base.DoEmit (ec); // @@ -307,9 +329,8 @@ namespace Mono.CSharp if (!base.Resolve (bc)) return false; - Arguments args = new Arguments (0); - type = expr.Type; + Arguments args = new Arguments (0); // // The await expression is of dynamic type @@ -341,49 +362,68 @@ namespace Mono.CSharp } var awaiter_type = ama.Type; - expr = ama; - - // - // Predefined: bool IsCompleted { get; } - // - is_completed = MemberCache.FindMember (awaiter_type, MemberFilter.Property ("IsCompleted", bc.Module.Compiler.BuiltinTypes.Bool), - BindingRestriction.InstanceOnly) as PropertySpec; - - if (is_completed == null || !is_completed.HasGet) { - Error_WrongAwaiterPattern (bc, awaiter_type); - return false; - } - // - // Predefined: GetResult () - // - // The method return type is also result type of await expression - // - get_result = MemberCache.FindMember (awaiter_type, MemberFilter.Method ("GetResult", 0, - ParametersCompiled.EmptyReadOnlyParameters, null), - BindingRestriction.InstanceOnly) as MethodSpec; + awaiter_definition = bc.Module.GetAwaiter (awaiter_type); - if (get_result == null) { + if (!awaiter_definition.IsValidPattern) { Error_WrongAwaiterPattern (bc, awaiter_type); return false; } - // - // Predefined: INotifyCompletion.OnCompleted (System.Action) - // - var nc = bc.Module.PredefinedTypes.INotifyCompletion; - if (nc.Define () && !awaiter_type.ImplementsInterface (nc.TypeSpec, false)) { + if (!awaiter_definition.INotifyCompletion) { bc.Report.Error (4027, loc, "The awaiter type `{0}' must implement interface `{1}'", - awaiter_type.GetSignatureForError (), nc.GetSignatureForError ()); + awaiter_type.GetSignatureForError (), bc.Module.PredefinedTypes.INotifyCompletion.GetSignatureForError ()); return false; } - result_type = get_result.ReturnType; + expr = ama; + result_type = awaiter_definition.GetResult.ReturnType; return true; } } + class AsyncInitializerStatement : StatementExpression + { + public AsyncInitializerStatement (AsyncInitializer expr) + : base (expr) + { + } + + protected override bool DoFlowAnalysis (FlowAnalysisContext fc) + { + base.DoFlowAnalysis (fc); + + var init = (AsyncInitializer) Expr; + var res = !init.Block.HasReachableClosingBrace; + var storey = (AsyncTaskStorey) init.Storey; + + if (storey.ReturnType.IsGenericTask) + return res; + + return true; + } + + public override Reachability MarkReachable (Reachability rc) + { + if (!rc.IsUnreachable) + reachable = true; + + var init = (AsyncInitializer) Expr; + rc = init.Block.MarkReachable (rc); + + var storey = (AsyncTaskStorey) init.Storey; + + // + // Explicit return is required for Task state machine + // + if (storey.ReturnType != null && storey.ReturnType.IsGenericTask) + return rc; + + return Reachability.CreateUnreachable (); + } + } + public class AsyncInitializer : StateMachineInitializer { TypeInferenceContext return_inference; @@ -401,6 +441,14 @@ namespace Mono.CSharp } } + public TypeSpec DelegateType { + get; set; + } + + public StackFieldExpr HoistedReturnState { + get; set; + } + public override bool IsIterator { get { return false; @@ -415,20 +463,16 @@ namespace Mono.CSharp #endregion - protected override BlockContext CreateBlockContext (ResolveContext rc) + protected override BlockContext CreateBlockContext (BlockContext bc) { - var ctx = base.CreateBlockContext (rc); - var lambda = rc.CurrentAnonymousMethod as LambdaMethod; - if (lambda != null) - return_inference = lambda.ReturnTypeInference; + var ctx = base.CreateBlockContext (bc); + var am = bc.CurrentAnonymousMethod as AnonymousMethodBody; + if (am != null) + return_inference = am.ReturnTypeInference; - ctx.StartFlowBranching (this, rc.CurrentBranching); - return ctx; - } + ctx.Set (ResolveContext.Options.TryScope); - public override Expression CreateExpressionTree (ResolveContext ec) - { - return base.CreateExpressionTree (ec); + return ctx; } public override void Emit (EmitContext ec) @@ -448,6 +492,13 @@ namespace Mono.CSharp storey.EmitInitializer (ec); ec.Emit (OpCodes.Ret); } + + public override void MarkReachable (Reachability rc) + { + // + // Reachability has been done in AsyncInitializerStatement + // + } } class AsyncTaskStorey : StateMachine @@ -460,7 +511,6 @@ namespace Mono.CSharp MethodSpec builder_factory; MethodSpec builder_start; PropertySpec task; - LocalVariable hoisted_return; int locals_captured; Dictionary> stack_fields; Dictionary> awaiter_fields; @@ -474,11 +524,7 @@ namespace Mono.CSharp #region Properties - public LocalVariable HoistedReturn { - get { - return hoisted_return; - } - } + public Expression HoistedReturnValue { get; set; } public TypeSpec ReturnType { get { @@ -492,14 +538,20 @@ namespace Mono.CSharp } } + protected override TypeAttributes TypeAttr { + get { + return base.TypeAttr & ~TypeAttributes.SequentialLayout; + } + } + #endregion - public Field AddAwaiter (TypeSpec type, Location loc) + public Field AddAwaiter (TypeSpec type) { if (mutator != null) type = mutator.Mutate (type); - List existing_fields = null; + List existing_fields; if (awaiter_fields.TryGetValue (type, out existing_fields)) { foreach (var f in existing_fields) { if (f.IsAvailableForReuse) { @@ -521,7 +573,7 @@ namespace Mono.CSharp return field; } - public Field AddCapturedLocalVariable (TypeSpec type) + public Field AddCapturedLocalVariable (TypeSpec type, bool requiresUninitialized = false) { if (mutator != null) type = mutator.Mutate (type); @@ -529,7 +581,7 @@ namespace Mono.CSharp List existing_fields = null; if (stack_fields == null) { stack_fields = new Dictionary> (); - } else if (stack_fields.TryGetValue (type, out existing_fields)) { + } else if (stack_fields.TryGetValue (type, out existing_fields) && !requiresUninitialized) { foreach (var f in existing_fields) { if (f.IsAvailableForReuse) { f.IsAvailableForReuse = false; @@ -662,7 +714,7 @@ namespace Mono.CSharp set_state_machine.Block.AddStatement (new StatementExpression (new Invocation (mg, args))); if (has_task_return_type) { - hoisted_return = LocalVariable.CreateCompilerGenerated (bt.TypeArguments[0], StateMachineMethod.Block, Location); + HoistedReturnValue = TemporaryVariableReference.Create (bt.TypeArguments [0], StateMachineMethod.Block, Location); } return true; @@ -754,7 +806,9 @@ namespace Mono.CSharp var args = new Arguments (2); args.Add (new Argument (awaiter, Argument.AType.Ref)); args.Add (new Argument (new CompilerGeneratedThis (CurrentType, Location), Argument.AType.Ref)); - mg.EmitCall (ec, args); + using (ec.With (BuilderContext.Options.OmitDebugInfo, true)) { + mg.EmitCall (ec, args); + } } public void EmitInitializer (EmitContext ec) @@ -830,7 +884,9 @@ namespace Mono.CSharp Arguments args = new Arguments (1); args.Add (new Argument (exceptionVariable)); - mg.EmitCall (ec, args); + using (ec.With (BuilderContext.Options.OmitDebugInfo, true)) { + mg.EmitCall (ec, args); + } } public void EmitSetResult (EmitContext ec) @@ -845,14 +901,16 @@ namespace Mono.CSharp }; Arguments args; - if (hoisted_return == null) { + if (HoistedReturnValue == null) { args = new Arguments (0); } else { args = new Arguments (1); - args.Add (new Argument (new LocalVariableReference (hoisted_return, Location))); + args.Add (new Argument (HoistedReturnValue)); } - mg.EmitCall (ec, args); + using (ec.With (BuilderContext.Options.OmitDebugInfo, true)) { + mg.EmitCall (ec, args); + } } protected override TypeSpec[] ResolveBaseTypes (out FullNamedExpression base_class) @@ -869,20 +927,30 @@ namespace Mono.CSharp } } - class StackFieldExpr : FieldExpr, IExpressionCleanup + public class StackFieldExpr : FieldExpr, IExpressionCleanup { public StackFieldExpr (Field field) : base (field, Location.Null) { } + public bool IsAvailableForReuse { + get { + var field = (Field) spec.MemberDefinition; + return field.IsAvailableForReuse; + } + set { + var field = (Field) spec.MemberDefinition; + field.IsAvailableForReuse = value; + } + } + public override void AddressOf (EmitContext ec, AddressOp mode) { base.AddressOf (ec, mode); if (mode == AddressOp.Load) { - var field = (Field) spec.MemberDefinition; - field.IsAvailableForReuse = true; + IsAvailableForReuse = true; } } @@ -890,8 +958,17 @@ namespace Mono.CSharp { base.Emit (ec); - var field = (Field) spec.MemberDefinition; - field.IsAvailableForReuse = true; + PrepareCleanup (ec); + } + + public void EmitLoad (EmitContext ec) + { + base.Emit (ec); + } + + public void PrepareCleanup (EmitContext ec) + { + IsAvailableForReuse = true; // // Release any captured reference type stack variables diff --git a/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/attribute.cs b/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/attribute.cs index eff7a5231..9e0437492 100644 --- a/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/attribute.cs +++ b/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/attribute.cs @@ -1,14 +1,14 @@ // -// attribute.cs: Attribute Handler +// attribute.cs: Attributes handling // // Author: Ravi Pratap (ravi@ximian.com) -// Marek Safar (marek.safar@seznam.cz) +// Marek Safar (marek.safar@gmail.com) // // Dual licensed under the terms of the MIT X11 or GNU GPL // // Copyright 2001-2003 Ximian, Inc (http://www.ximian.com) // Copyright 2003-2008 Novell, Inc. -// Copyright 2011 Xamarin Inc +// Copyright 2011-2013 Xamarin Inc // using System; @@ -143,6 +143,12 @@ namespace Mono.CSharp { } } + public bool ResolveError { + get { + return resolve_error; + } + } + public ATypeNameExpression TypeExpression { get { return expression; @@ -166,7 +172,7 @@ namespace Mono.CSharp { if (NamedArguments == null) named_args = new Arguments (1); - var value = Constant.CreateConstant (rc.Module.PredefinedTypes.CharSet.TypeSpec, rc.Module.DefaultCharSet, Location); + var value = Constant.CreateConstantFromValue (rc.Module.PredefinedTypes.CharSet.TypeSpec, rc.Module.DefaultCharSet, Location); NamedArguments.Add (new NamedArgument (dll_import_char_set, loc, value)); } @@ -251,19 +257,22 @@ namespace Mono.CSharp { Report.Error (1970, loc, "Do not use `{0}' directly. Use `dynamic' keyword instead", GetSignatureForError ()); } - /// - /// This is rather hack. We report many emit attribute error with same error to be compatible with - /// csc. But because csc has to report them this way because error came from ilasm we needn't. - /// - public void Error_AttributeEmitError (string inner) + void Error_AttributeEmitError (string inner) { Report.Error (647, Location, "Error during emitting `{0}' attribute. The reason is `{1}'", - TypeManager.CSharpName (Type), inner); + Type.GetSignatureForError (), inner); + } + + public void Error_InvalidArgumentValue (TypeSpec attributeType) + { + Report.Error (591, Location, "Invalid value for argument to `{0}' attribute", attributeType.GetSignatureForError ()); } public void Error_InvalidSecurityParent () { - Error_AttributeEmitError ("it is attached to invalid parent"); + Report.Error (7070, Location, + "Security attribute `{0}' is not valid on this declaration type. Security attributes are only valid on assembly, type and method declarations", + Type.GetSignatureForError ()); } Attributable Owner { @@ -275,9 +284,10 @@ namespace Mono.CSharp { /// /// Tries to resolve the type of the attribute. Flags an error if it can't, and complain is true. /// - void ResolveAttributeType () + void ResolveAttributeType (bool comparisonOnly) { - SessionReportPrinter resolve_printer = new SessionReportPrinter (); + var resolve_printer = new SessionReportPrinter (); + SessionReportPrinter secondary_printer = null; ReportPrinter prev_recorder = Report.SetPrinter (resolve_printer); bool t1_is_attr = false; @@ -290,29 +300,37 @@ namespace Mono.CSharp { try { t1 = expression.ResolveAsType (context); - if (t1 != null) - t1_is_attr = t1.IsAttribute; - resolve_printer.EndSession (); + if (t1 != null && resolve_printer.ErrorsCount == 0) + t1_is_attr = t1.IsAttribute; + if (nameEscaped) { t2 = null; } else { expanded = (ATypeNameExpression) expression.Clone (null); expanded.Name += "Attribute"; + secondary_printer = new SessionReportPrinter (); + Report.SetPrinter (secondary_printer); t2 = expanded.ResolveAsType (context); - if (t2 != null) + secondary_printer.EndSession (); + if (t2 != null && secondary_printer.ErrorsCount == 0) t2_is_attr = t2.IsAttribute; + + secondary_printer.EndSession (); } } finally { context.Module.Compiler.Report.SetPrinter (prev_recorder); } if (t1_is_attr && t2_is_attr && t1 != t2) { - Report.Error (1614, Location, "`{0}' is ambiguous between `{1}' and `{2}'. Use either `@{0}' or `{0}Attribute'", - GetSignatureForError (), expression.GetSignatureForError (), expanded.GetSignatureForError ()); - resolve_error = true; + if (!comparisonOnly) { + Report.Error (1614, Location, "`{0}' is ambiguous between `{1}' and `{2}'. Use either `@{0}' or `{0}Attribute'", + GetSignatureForError (), expression.GetSignatureForError (), expanded.GetSignatureForError ()); + resolve_error = true; + } + return; } @@ -326,36 +344,47 @@ namespace Mono.CSharp { return; } + if (comparisonOnly) + return; + resolve_error = true; - if (t1 != null) { - resolve_printer.Merge (prev_recorder); + if (t1 != null) { + if (resolve_printer.IsEmpty) { + Report.SymbolRelatedToPreviousError (t1); + Report.Error (616, Location, "`{0}': is not an attribute class", t1.GetSignatureForError ()); + } else { + resolve_printer.Merge (prev_recorder); + } - Report.SymbolRelatedToPreviousError (t1); - Report.Error (616, Location, "`{0}': is not an attribute class", t1.GetSignatureForError ()); return; } if (t2 != null) { - Report.SymbolRelatedToPreviousError (t2); - Report.Error (616, Location, "`{0}': is not an attribute class", t2.GetSignatureForError ()); + if (secondary_printer.IsEmpty) { + Report.SymbolRelatedToPreviousError (t2); + Report.Error (616, Location, "`{0}': is not an attribute class", t2.GetSignatureForError ()); + } else { + secondary_printer.Merge (prev_recorder); + } + return; } resolve_printer.Merge (prev_recorder); } - public TypeSpec ResolveType () + public TypeSpec ResolveTypeForComparison () { if (Type == null && !resolve_error) - ResolveAttributeType (); + ResolveAttributeType (true); return Type; } public string GetSignatureForError () { if (Type != null) - return TypeManager.CSharpName (Type); + return Type.GetSignatureForError (); return expression.GetSignatureForError (); } @@ -372,7 +401,20 @@ namespace Mono.CSharp { return HasSecurityAttribute && IsSecurityActionValid (); } - static bool IsValidArgumentType (TypeSpec t) + static bool IsValidMethodImplOption (int value) + { + // + // Allow to use AggressiveInlining on any runtime/corlib + // + MethodImplOptions all = (MethodImplOptions) 256; + foreach (MethodImplOptions v in System.Enum.GetValues (typeof (MethodImplOptions))) { + all |= v; + } + + return ((MethodImplOptions) value | all) == all; + } + + public static bool IsValidArgumentType (TypeSpec t) { if (t.IsArray) { var ac = (ArrayContainer) t; @@ -430,7 +472,7 @@ namespace Mono.CSharp { arg_resolved = true; if (Type == null) { - ResolveAttributeType (); + ResolveAttributeType (false); if (Type == null) return null; } @@ -442,7 +484,7 @@ namespace Mono.CSharp { ObsoleteAttribute obsolete_attr = Type.GetAttributeObsolete (); if (obsolete_attr != null) { - AttributeTester.Report_ObsoleteMessage (obsolete_attr, TypeManager.CSharpName (Type), Location, Report); + AttributeTester.Report_ObsoleteMessage (obsolete_attr, Type.GetSignatureForError (), Location, Report); } ResolveContext rc = null; @@ -797,6 +839,7 @@ namespace Mono.CSharp { { SecurityAction action = GetSecurityActionValue (); bool for_assembly = Target == AttributeTargets.Assembly || Target == AttributeTargets.Module; + var c = (Constant)pos_args [0].Expr; switch (action) { #pragma warning disable 618 @@ -819,11 +862,22 @@ namespace Mono.CSharp { #pragma warning restore 618 default: - Error_AttributeEmitError ("SecurityAction is out of range"); + Report.Error (7049, c.Location, "Security attribute `{0}' has an invalid SecurityAction value `{1}'", + Type.GetSignatureForError (), c.GetValueAsLiteral()); return false; } - Error_AttributeEmitError (String.Concat ("SecurityAction `", action, "' is not valid for this declaration")); + switch (Target) { + case AttributeTargets.Assembly: + Report.Error (7050, c.Location, "SecurityAction value `{0}' is invalid for security attributes applied to an assembly", + c.GetSignatureForError ()); + break; + default: + Report.Error (7051, c.Location, "SecurityAction value `{0}' is invalid for security attributes applied to a type or a method", + c.GetSignatureForError ()); + break; + } + return false; } @@ -992,40 +1046,42 @@ namespace Mono.CSharp { return; } } else if (Type == predefined.Guid) { + string v = ((StringConstant) arg_expr).Value; try { - string v = ((StringConstant) arg_expr).Value; new Guid (v); - } catch (Exception e) { - Error_AttributeEmitError (e.Message); + } catch { + Error_InvalidArgumentValue (Type); return; } } else if (Type == predefined.AttributeUsage) { int v = ((IntConstant) ((EnumConstant) arg_expr).Child).Value; - if (v == 0) { - context.Module.Compiler.Report.Error (591, Location, "Invalid value for argument to `{0}' attribute", - "System.AttributeUsage"); - } + if (v == 0) + Error_InvalidArgumentValue (Type); } else if (Type == predefined.MarshalAs) { if (pos_args.Count == 1) { var u_type = (UnmanagedType) System.Enum.Parse (typeof (UnmanagedType), ((Constant) pos_args[0].Expr).GetValue ().ToString ()); if (u_type == UnmanagedType.ByValArray && !(Owner is FieldBase)) { - Error_AttributeEmitError ("Specified unmanaged type is only valid on fields"); + Report.Error (7055, pos_args [0].Expr.Location, "Unmanaged type `ByValArray' is only valid for fields"); } } } else if (Type == predefined.DllImport) { 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 or null"); + Error_InvalidArgumentValue (Type); + } + } else if (Type == predefined.MethodImpl) { + if (pos_args.Count == 1) { + var value = (int) ((Constant) arg_expr).GetValueAsLong (); + + if (!IsValidMethodImplOption (value)) { + Error_InvalidArgumentValue (Type); + } } - } else if (Type == predefined.MethodImpl && pt.BuiltinType == BuiltinTypeSpec.Type.Short && - !System.Enum.IsDefined (typeof (MethodImplOptions), ((Constant) arg_expr).GetValue ().ToString ())) { - Error_AttributeEmitError ("Incorrect argument value."); - return; } } - arg_expr.EncodeAttributeValue (context, encoder, pt); + arg_expr.EncodeAttributeValue (context, encoder, pt, pt); } } @@ -1039,7 +1095,7 @@ namespace Mono.CSharp { encoder.Encode (na.Key.Type); encoder.Encode (na.Value.Name); - na.Value.Expr.EncodeAttributeValue (context, encoder, na.Key.Type); + na.Value.Expr.EncodeAttributeValue (context, encoder, na.Key.Type, na.Key.Type); } } else { encoder.EncodeEmptyNamedArguments (); @@ -1048,15 +1104,17 @@ namespace Mono.CSharp { cdata = encoder.ToArray (); } - try { - foreach (Attributable target in targets) - target.ApplyAttributeBuilder (this, ctor, cdata, predefined); - } catch (Exception e) { - if (e is BadImageFormat && Report.Errors > 0) - return; + if (!ctor.DeclaringType.IsConditionallyExcluded (context)) { + try { + foreach (Attributable target in targets) + target.ApplyAttributeBuilder (this, ctor, cdata, predefined); + } catch (Exception e) { + if (e is BadImageFormat && Report.Errors > 0) + return; - Error_AttributeEmitError (e.Message); - return; + Error_AttributeEmitError (e.Message); + return; + } } if (!usage_attr.AllowMultiple && allEmitted != null) { @@ -1139,7 +1197,7 @@ namespace Mono.CSharp { public Attributes (List attrs) { - Attrs = attrs; + Attrs = attrs ?? new List (); #if FULL_AST Sections.Add (attrs); #endif @@ -1212,6 +1270,16 @@ namespace Mono.CSharp { } } + public bool HasResolveError() + { + foreach (var a in Attrs) { + if (a.ResolveError) + return true; + } + + return false; + } + public Attribute Search (PredefinedAttribute t) { return Search (null, t); @@ -1223,7 +1291,7 @@ namespace Mono.CSharp { if (explicitTarget != null && a.ExplicitTarget != explicitTarget) continue; - if (a.ResolveType () == t) + if (a.ResolveTypeForComparison () == t) return a; } return null; @@ -1237,7 +1305,7 @@ namespace Mono.CSharp { List ar = null; foreach (Attribute a in Attrs) { - if (a.ResolveType () == t) { + if (a.ResolveTypeForComparison () == t) { if (ar == null) ar = new List (Attrs.Count); ar.Add (a); @@ -1491,7 +1559,7 @@ namespace Mono.CSharp { Encode ((byte) 0x54); // property Encode (property.MemberType); Encode (property.Name); - value.EncodeAttributeValue (null, this, property.MemberType); + value.EncodeAttributeValue (null, this, property.MemberType, property.MemberType); } // @@ -1503,7 +1571,7 @@ namespace Mono.CSharp { Encode ((byte) 0x53); // field Encode (field.MemberType); Encode (field.Name); - value.EncodeAttributeValue (null, this, field.MemberType); + value.EncodeAttributeValue (null, this, field.MemberType, field.MemberType); } public void EncodeNamedArguments (T[] members, Constant[] values) where T : MemberSpec, IInterfaceMemberSpec @@ -1523,7 +1591,7 @@ namespace Mono.CSharp { Encode (member.MemberType); Encode (member.Name); - values [i].EncodeAttributeValue (null, this, member.MemberType); + values [i].EncodeAttributeValue (null, this, member.MemberType, member.MemberType); } } @@ -1628,6 +1696,8 @@ namespace Mono.CSharp { public readonly PredefinedAttribute UnsafeValueType; public readonly PredefinedAttribute UnmanagedFunctionPointer; public readonly PredefinedDebuggerBrowsableAttribute DebuggerBrowsable; + public readonly PredefinedAttribute DebuggerStepThrough; + public readonly PredefinedDebuggableAttribute Debuggable; // New in .NET 3.5 public readonly PredefinedAttribute Extension; @@ -1637,7 +1707,6 @@ namespace Mono.CSharp { // New in .NET 4.5 public readonly PredefinedStateMachineAttribute AsyncStateMachine; - public readonly PredefinedStateMachineAttribute IteratorStateMachine; // // Optional types which are used as types and for member lookup @@ -1646,6 +1715,11 @@ namespace Mono.CSharp { public readonly PredefinedDecimalAttribute DecimalConstant; public readonly PredefinedAttribute StructLayout; public readonly PredefinedAttribute FieldOffset; + public readonly PredefinedAttribute AssemblyProduct; + public readonly PredefinedAttribute AssemblyCompany; + public readonly PredefinedAttribute AssemblyDescription; + public readonly PredefinedAttribute AssemblyCopyright; + public readonly PredefinedAttribute AssemblyTrademark; public readonly PredefinedAttribute CallerMemberNameAttribute; public readonly PredefinedAttribute CallerLineNumberAttribute; public readonly PredefinedAttribute CallerFilePathAttribute; @@ -1690,6 +1764,8 @@ namespace Mono.CSharp { UnsafeValueType = new PredefinedAttribute (module, "System.Runtime.CompilerServices", "UnsafeValueTypeAttribute"); UnmanagedFunctionPointer = new PredefinedAttribute (module, "System.Runtime.InteropServices", "UnmanagedFunctionPointerAttribute"); DebuggerBrowsable = new PredefinedDebuggerBrowsableAttribute (module, "System.Diagnostics", "DebuggerBrowsableAttribute"); + DebuggerStepThrough = new PredefinedAttribute (module, "System.Diagnostics", "DebuggerStepThroughAttribute"); + Debuggable = new PredefinedDebuggableAttribute (module, "System.Diagnostics", "DebuggableAttribute"); Extension = new PredefinedAttribute (module, "System.Runtime.CompilerServices", "ExtensionAttribute"); @@ -1699,11 +1775,13 @@ namespace Mono.CSharp { DecimalConstant = new PredefinedDecimalAttribute (module, "System.Runtime.CompilerServices", "DecimalConstantAttribute"); StructLayout = new PredefinedAttribute (module, "System.Runtime.InteropServices", "StructLayoutAttribute"); FieldOffset = new PredefinedAttribute (module, "System.Runtime.InteropServices", "FieldOffsetAttribute"); + AssemblyProduct = new PredefinedAttribute (module, "System.Reflection", "AssemblyProductAttribute"); + AssemblyCompany = new PredefinedAttribute (module, "System.Reflection", "AssemblyCompanyAttribute"); + AssemblyDescription = new PredefinedAttribute (module, "System.Reflection", "AssemblyDescriptionAttribute"); + AssemblyCopyright = new PredefinedAttribute (module, "System.Reflection", "AssemblyCopyrightAttribute"); + AssemblyTrademark = new PredefinedAttribute (module, "System.Reflection", "AssemblyTrademarkAttribute"); 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"); @@ -1819,7 +1897,7 @@ namespace Mono.CSharp { // // Handle all parameter-less attributes as optional // - if (!IsDefined) + if (!Define ()) return false; ctor = (MethodSpec) MemberCache.FindMember (type, MemberFilter.Constructor (ParametersCompiled.EmptyReadOnlyParameters), BindingRestriction.DeclaredOnly); @@ -1848,6 +1926,40 @@ namespace Mono.CSharp { } } + public class PredefinedDebuggableAttribute : PredefinedAttribute + { + public PredefinedDebuggableAttribute (ModuleContainer module, string ns, string name) + : base (module, ns, name) + { + } + + public void EmitAttribute (AssemblyBuilder builder, System.Diagnostics.DebuggableAttribute.DebuggingModes modes) + { + var atype = module.PredefinedAttributes.Debuggable; + if (!atype.Define ()) + return; + + MethodSpec ctor = null; + foreach (MethodSpec m in MemberCache.FindMembers (atype.TypeSpec, CSharp.Constructor.ConstructorName, true)) { + if (m.Parameters.Count != 1) + continue; + + if (m.Parameters.Types[0].Kind == MemberKind.Enum) { + ctor = m; + } + } + + if (ctor == null) + return; + + AttributeEncoder encoder = new AttributeEncoder (); + encoder.Encode ((int) modes); + encoder.EncodeEmptyNamedArguments (); + + builder.SetCustomAttribute ((ConstructorInfo) ctor.GetMetaInfo (), encoder.ToArray ()); + } + } + public class PredefinedDecimalAttribute : PredefinedAttribute { public PredefinedDecimalAttribute (ModuleContainer module, string ns, string name) @@ -1899,13 +2011,9 @@ namespace Mono.CSharp { { } - public bool IsIterator { get; set; } - public void EmitAttribute (MethodBuilder builder, StateMachine type) { - var predefined_ctor = IsIterator ? - module.PredefinedMembers.IteratorStateMachineAttributeCtor : - module.PredefinedMembers.AsyncStateMachineAttributeCtor; + var predefined_ctor = module.PredefinedMembers.AsyncStateMachineAttributeCtor; var ctor = predefined_ctor.Get (); @@ -1981,7 +2089,7 @@ namespace Mono.CSharp { if (ac != null) { element = GetTransformationFlags (ac.Element); if (element == null) - return null; + return new bool[] { false, false }; bool[] res = new bool[element.Length + 1]; res[0] = false; diff --git a/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/cfold.cs b/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/cfold.cs index 8724e48b5..72f3a9c36 100644 --- a/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/cfold.cs +++ b/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/cfold.cs @@ -149,7 +149,7 @@ namespace Mono.CSharp { case Binary.Operator.ExclusiveOr: result = BinaryFold (ec, oper, ((EnumConstant)left).Child, ((EnumConstant)right).Child, loc); if (result != null) - result = result.TryReduce (ec, lt); + result = result.Reduce (ec, lt); return result; /// @@ -158,7 +158,7 @@ namespace Mono.CSharp { case Binary.Operator.Subtraction: result = BinaryFold (ec, oper, ((EnumConstant)left).Child, ((EnumConstant)right).Child, loc); if (result != null) - result = result.TryReduce (ec, EnumSpec.GetUnderlyingType (lt)); + result = result.Reduce (ec, EnumSpec.GetUnderlyingType (lt)); return result; /// @@ -183,11 +183,11 @@ namespace Mono.CSharp { switch (oper){ case Binary.Operator.BitwiseOr: // - // bool? operator &(bool? x, bool? y); + // bool? operator |(bool? x, bool? y); // 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).Resolve (ec); + var b = new Binary (oper, left, right).ResolveOperator (ec); // false | null => null // null | false => null @@ -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).Resolve (ec); + var b = new Binary (oper, left, right).ResolveOperator (ec); // false & null => false // null & false => false @@ -299,25 +299,51 @@ namespace Mono.CSharp { break; case Binary.Operator.Addition: - if (lt == InternalType.NullLiteral) - return right; - - if (rt == InternalType.NullLiteral) - return left; - // - // If both sides are strings, then concatenate, if - // one is a string, and the other is not, then defer - // to runtime concatenation + // If both sides are strings, then concatenate + // + // string operator + (string x, string y) // if (lt.BuiltinType == BuiltinTypeSpec.Type.String || rt.BuiltinType == BuiltinTypeSpec.Type.String){ if (lt == rt) return new StringConstant (ec.BuiltinTypes, (string)left.GetValue () + (string)right.GetValue (), left.Location); - + + if (lt == InternalType.NullLiteral) + return new StringConstant (ec.BuiltinTypes, "" + right.GetValue (), left.Location); + + if (rt == InternalType.NullLiteral) + return new StringConstant (ec.BuiltinTypes, left.GetValue () + "", left.Location); + return null; } + // + // string operator + (string x, object y) + // + if (lt == InternalType.NullLiteral) { + if (rt.BuiltinType == BuiltinTypeSpec.Type.Object) + return new StringConstant (ec.BuiltinTypes, "" + right.GetValue (), left.Location); + + if (lt == rt) { + ec.Report.Error (34, loc, "Operator `{0}' is ambiguous on operands of type `{1}' and `{2}'", + "+", lt.GetSignatureForError (), rt.GetSignatureForError ()); + return null; + } + + return right; + } + + // + // string operator + (object x, string y) + // + if (rt == InternalType.NullLiteral) { + if (lt.BuiltinType == BuiltinTypeSpec.Type.Object) + return new StringConstant (ec.BuiltinTypes, right.GetValue () + "", left.Location); + + return left; + } + // // handle "E operator + (E x, U y)" // handle "E operator + (Y y, E x)" @@ -340,9 +366,9 @@ namespace Mono.CSharp { if (result == null) return null; - result = result.TryReduce (ec, lt); - if (result == null) - return null; + result = result.Reduce (ec, lt); + if (result == null || lt.IsEnum) + return result; return new EnumConstant (result, lt); } @@ -364,14 +390,14 @@ namespace Mono.CSharp { return new DoubleConstant (ec.BuiltinTypes, res, left.Location); } if (left is FloatConstant){ - float res; - + double a, b, res; + a = ((FloatConstant) left).DoubleValue; + b = ((FloatConstant) right).DoubleValue; + if (ec.ConstantCheckState) - res = checked (((FloatConstant) left).Value + - ((FloatConstant) right).Value); + res = checked (a + b); else - res = unchecked (((FloatConstant) left).Value + - ((FloatConstant) right).Value); + res = unchecked (a + b); result = new FloatConstant (ec.BuiltinTypes, res, left.Location); } else if (left is ULongConstant){ @@ -459,7 +485,7 @@ namespace Mono.CSharp { if (result == null) return null; - result = result.TryReduce (ec, lt); + result = result.Reduce (ec, lt); if (result == null) return null; @@ -469,7 +495,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).Resolve (ec); + return (Constant) new Binary (oper, lifted_int, right).ResolveOperator (ec); } if (!DoBinaryNumericPromotions (ec, ref left, ref right)) @@ -488,14 +514,14 @@ namespace Mono.CSharp { result = new DoubleConstant (ec.BuiltinTypes, res, left.Location); } else if (left is FloatConstant){ - float res; - + double a, b, res; + a = ((FloatConstant) left).DoubleValue; + b = ((FloatConstant) right).DoubleValue; + if (ec.ConstantCheckState) - res = checked (((FloatConstant) left).Value - - ((FloatConstant) right).Value); + res = checked (a - b); else - res = unchecked (((FloatConstant) left).Value - - ((FloatConstant) right).Value); + res = unchecked (a - b); result = new FloatConstant (ec.BuiltinTypes, res, left.Location); } else if (left is ULongConstant){ @@ -566,7 +592,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).Resolve (ec); + return (Constant) new Binary (oper, lifted_int, right).ResolveOperator (ec); } if (!DoBinaryNumericPromotions (ec, ref left, ref right)) @@ -585,14 +611,14 @@ namespace Mono.CSharp { return new DoubleConstant (ec.BuiltinTypes, res, left.Location); } else if (left is FloatConstant){ - float res; - + double a, b, res; + a = ((FloatConstant) left).DoubleValue; + b = ((FloatConstant) right).DoubleValue; + if (ec.ConstantCheckState) - res = checked (((FloatConstant) left).Value * - ((FloatConstant) right).Value); + res = checked (a * b); else - res = unchecked (((FloatConstant) left).Value * - ((FloatConstant) right).Value); + res = unchecked (a * b); return new FloatConstant (ec.BuiltinTypes, res, left.Location); } else if (left is ULongConstant){ @@ -662,7 +688,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).Resolve (ec); + return (Constant) new Binary (oper, lifted_int, right).ResolveOperator (ec); } if (!DoBinaryNumericPromotions (ec, ref left, ref right)) @@ -681,14 +707,14 @@ namespace Mono.CSharp { return new DoubleConstant (ec.BuiltinTypes, res, left.Location); } else if (left is FloatConstant){ - float res; - + double a, b, res; + a = ((FloatConstant) left).DoubleValue; + b = ((FloatConstant) right).DoubleValue; + if (ec.ConstantCheckState) - res = checked (((FloatConstant) left).Value / - ((FloatConstant) right).Value); + res = checked (a / b); else - res = unchecked (((FloatConstant) left).Value / - ((FloatConstant) right).Value); + res = unchecked (a / b); return new FloatConstant (ec.BuiltinTypes, res, left.Location); } else if (left is ULongConstant){ @@ -762,7 +788,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).Resolve (ec); + return (Constant) new Binary (oper, lifted_int, right).ResolveOperator (ec); } if (!DoBinaryNumericPromotions (ec, ref left, ref right)) @@ -781,14 +807,14 @@ namespace Mono.CSharp { return new DoubleConstant (ec.BuiltinTypes, res, left.Location); } else if (left is FloatConstant){ - float res; + double a, b, res; + a = ((FloatConstant) left).DoubleValue; + b = ((FloatConstant) right).DoubleValue; if (ec.ConstantCheckState) - res = checked (((FloatConstant) left).Value % - ((FloatConstant) right).Value); + res = checked (a % b); else - res = unchecked (((FloatConstant) left).Value % - ((FloatConstant) right).Value); + res = unchecked (a % b); return new FloatConstant (ec.BuiltinTypes, res, left.Location); } else if (left is ULongConstant){ @@ -852,12 +878,11 @@ 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).Resolve (ec); + return (Constant) new Binary (oper, lifted_int, right).ResolveOperator (ec); } IntConstant ic = right.ConvertImplicitly (ec.BuiltinTypes.Int) as IntConstant; if (ic == null){ - Binary.Error_OperatorCannotBeApplied (ec, left, right, oper, loc); return null; } @@ -873,14 +898,13 @@ namespace Mono.CSharp { // null << value => null if (left is NullLiteral) - return (Constant) new Nullable.LiftedBinaryOperator (oper, left, right).Resolve (ec); + return (Constant) new Binary (oper, left, right).ResolveOperator (ec); left = left.ConvertImplicitly (ec.BuiltinTypes.Int); if (left.Type.BuiltinType == BuiltinTypeSpec.Type.Int) return new IntConstant (ec.BuiltinTypes, ((IntConstant) left).Value << lshift_val, left.Location); - Binary.Error_OperatorCannotBeApplied (ec, left, right, oper, loc); - break; + return null; // // There is no overflow checking on right shift @@ -889,12 +913,11 @@ 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).Resolve (ec); + return (Constant) new Binary (oper, lifted_int, right).ResolveOperator (ec); } IntConstant sic = right.ConvertImplicitly (ec.BuiltinTypes.Int) as IntConstant; if (sic == null){ - Binary.Error_OperatorCannotBeApplied (ec, left, right, oper, loc); ; return null; } int rshift_val = sic.Value; @@ -909,14 +932,13 @@ namespace Mono.CSharp { // null >> value => null if (left is NullLiteral) - return (Constant) new Nullable.LiftedBinaryOperator (oper, left, right).Resolve (ec); + return (Constant) new Binary (oper, left, right).ResolveOperator (ec); left = left.ConvertImplicitly (ec.BuiltinTypes.Int); if (left.Type.BuiltinType == BuiltinTypeSpec.Type.Int) return new IntConstant (ec.BuiltinTypes, ((IntConstant) left).Value >> rshift_val, left.Location); - Binary.Error_OperatorCannotBeApplied (ec, left, right, oper, loc); - break; + return null; case Binary.Operator.Equality: if (TypeSpec.IsReferenceType (lt) && TypeSpec.IsReferenceType (rt) || @@ -943,8 +965,8 @@ namespace Mono.CSharp { bool_res = ((DoubleConstant) left).Value == ((DoubleConstant) right).Value; else if (left is FloatConstant) - bool_res = ((FloatConstant) left).Value == - ((FloatConstant) right).Value; + bool_res = ((FloatConstant) left).DoubleValue == + ((FloatConstant) right).DoubleValue; else if (left is ULongConstant) bool_res = ((ULongConstant) left).Value == ((ULongConstant) right).Value; @@ -987,8 +1009,8 @@ namespace Mono.CSharp { bool_res = ((DoubleConstant) left).Value != ((DoubleConstant) right).Value; else if (left is FloatConstant) - bool_res = ((FloatConstant) left).Value != - ((FloatConstant) right).Value; + bool_res = ((FloatConstant) left).DoubleValue != + ((FloatConstant) right).DoubleValue; else if (left is ULongConstant) bool_res = ((ULongConstant) left).Value != ((ULongConstant) right).Value; @@ -1011,11 +1033,7 @@ 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).Resolve (ec); - } - - if (left is Nullable.LiftedNull) { - return (Constant) new Nullable.LiftedBinaryOperator (oper, left, right).Resolve (ec); + return (Constant) new Binary (oper, lifted_int, right).ResolveOperator (ec); } } @@ -1027,8 +1045,8 @@ namespace Mono.CSharp { bool_res = ((DoubleConstant) left).Value < ((DoubleConstant) right).Value; else if (left is FloatConstant) - bool_res = ((FloatConstant) left).Value < - ((FloatConstant) right).Value; + bool_res = ((FloatConstant) left).DoubleValue < + ((FloatConstant) right).DoubleValue; else if (left is ULongConstant) bool_res = ((ULongConstant) left).Value < ((ULongConstant) right).Value; @@ -1051,11 +1069,7 @@ 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).Resolve (ec); - } - - if (left is Nullable.LiftedNull) { - return (Constant) new Nullable.LiftedBinaryOperator (oper, left, right).Resolve (ec); + return (Constant) new Binary (oper, lifted_int, right).ResolveOperator (ec); } } @@ -1067,8 +1081,8 @@ namespace Mono.CSharp { bool_res = ((DoubleConstant) left).Value > ((DoubleConstant) right).Value; else if (left is FloatConstant) - bool_res = ((FloatConstant) left).Value > - ((FloatConstant) right).Value; + bool_res = ((FloatConstant) left).DoubleValue > + ((FloatConstant) right).DoubleValue; else if (left is ULongConstant) bool_res = ((ULongConstant) left).Value > ((ULongConstant) right).Value; @@ -1091,11 +1105,7 @@ 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).Resolve (ec); - } - - if (left is Nullable.LiftedNull) { - return (Constant) new Nullable.LiftedBinaryOperator (oper, left, right).Resolve (ec); + return (Constant) new Binary (oper, lifted_int, right).ResolveOperator (ec); } } @@ -1107,8 +1117,8 @@ namespace Mono.CSharp { bool_res = ((DoubleConstant) left).Value >= ((DoubleConstant) right).Value; else if (left is FloatConstant) - bool_res = ((FloatConstant) left).Value >= - ((FloatConstant) right).Value; + bool_res = ((FloatConstant) left).DoubleValue >= + ((FloatConstant) right).DoubleValue; else if (left is ULongConstant) bool_res = ((ULongConstant) left).Value >= ((ULongConstant) right).Value; @@ -1131,11 +1141,7 @@ 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).Resolve (ec); - } - - if (left is Nullable.LiftedNull) { - return (Constant) new Nullable.LiftedBinaryOperator (oper, left, right).Resolve (ec); + return (Constant) new Binary (oper, lifted_int, right).ResolveOperator (ec); } } @@ -1147,8 +1153,8 @@ namespace Mono.CSharp { bool_res = ((DoubleConstant) left).Value <= ((DoubleConstant) right).Value; else if (left is FloatConstant) - bool_res = ((FloatConstant) left).Value <= - ((FloatConstant) right).Value; + bool_res = ((FloatConstant) left).DoubleValue <= + ((FloatConstant) right).DoubleValue; else if (left is ULongConstant) bool_res = ((ULongConstant) left).Value <= ((ULongConstant) right).Value; @@ -1166,7 +1172,7 @@ namespace Mono.CSharp { return new BoolConstant (ec.BuiltinTypes, bool_res, left.Location); } - + return null; } } diff --git a/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/class.cs b/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/class.cs index 645f53245..02f1b654c 100644 --- a/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/class.cs +++ b/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/class.cs @@ -13,11 +13,11 @@ // using System; +using System.Linq; using System.Collections.Generic; using System.Runtime.InteropServices; using System.Security; using System.Security.Permissions; -using System.Linq; using System.Text; using System.Diagnostics; using Mono.CompilerServices.SymbolWriter; @@ -54,7 +54,11 @@ namespace Mono.CSharp protected bool is_defined; - public TypeContainer (TypeContainer parent, MemberName name, Attributes attrs, MemberKind kind) + public int CounterAnonymousMethods { get; set; } + public int CounterAnonymousContainers { get; set; } + public int CounterSwitchTypes { get; set; } + + protected TypeContainer (TypeContainer parent, MemberName name, Attributes attrs, MemberKind kind) : base (parent, name, attrs) { this.Kind = kind; @@ -99,9 +103,9 @@ namespace Mono.CSharp get; set; } - public virtual void AddCompilerGeneratedClass (CompilerGeneratedContainer c) + public void AddCompilerGeneratedClass (CompilerGeneratedContainer c) { - containers.Add (c); + AddTypeContainerMember (c); } public virtual void AddPartial (TypeDefinition next_part) @@ -140,8 +144,8 @@ namespace Mono.CSharp } if ((existing.ModFlags & Modifiers.AccessibilityMask) != (next_part.ModFlags & Modifiers.AccessibilityMask) && - ((existing.ModFlags & Modifiers.DEFAULT_ACCESS_MODIFER) == 0 && - (next_part.ModFlags & Modifiers.DEFAULT_ACCESS_MODIFER) == 0)) { + ((existing.ModFlags & Modifiers.DEFAULT_ACCESS_MODIFIER) == 0 && + (next_part.ModFlags & Modifiers.DEFAULT_ACCESS_MODIFIER) == 0)) { Report.SymbolRelatedToPreviousError (existing); Report.Error (262, next_part.Location, "Partial declarations of `{0}' have conflicting accessibility modifiers", @@ -168,10 +172,10 @@ namespace Mono.CSharp } } - if ((next_part.ModFlags & Modifiers.DEFAULT_ACCESS_MODIFER) != 0) { - existing.ModFlags |= next_part.ModFlags & ~(Modifiers.DEFAULT_ACCESS_MODIFER | Modifiers.AccessibilityMask); - } else if ((existing.ModFlags & Modifiers.DEFAULT_ACCESS_MODIFER) != 0) { - existing.ModFlags &= ~(Modifiers.DEFAULT_ACCESS_MODIFER | Modifiers.AccessibilityMask); + if ((next_part.ModFlags & Modifiers.DEFAULT_ACCESS_MODIFIER) != 0) { + existing.ModFlags |= next_part.ModFlags & ~(Modifiers.DEFAULT_ACCESS_MODIFIER | Modifiers.AccessibilityMask); + } else if ((existing.ModFlags & Modifiers.DEFAULT_ACCESS_MODIFIER) != 0) { + existing.ModFlags &= ~(Modifiers.DEFAULT_ACCESS_MODIFIER | Modifiers.AccessibilityMask); existing.ModFlags |= next_part.ModFlags; } else { existing.ModFlags |= next_part.ModFlags; @@ -188,15 +192,14 @@ namespace Mono.CSharp next_part.PartialContainer = existing; - if (containers == null) - containers = new List (); + existing.AddPartialPart (next_part); - containers.Add (next_part); + AddTypeContainerMember (next_part); } public virtual void AddTypeContainer (TypeContainer tc) { - containers.Add (tc); + AddTypeContainerMember (tc); var tparams = tc.MemberName.TypeParameters; if (tparams != null && tc.PartialContainer != null) { @@ -211,6 +214,11 @@ namespace Mono.CSharp } } + protected virtual void AddTypeContainerMember (TypeContainer tc) + { + containers.Add (tc); + } + public virtual void CloseContainer () { if (containers != null) { @@ -298,6 +306,15 @@ namespace Mono.CSharp return true; } + public virtual void ExpandBaseInterfaces () + { + if (containers != null) { + foreach (TypeContainer tc in containers) { + tc.ExpandBaseInterfaces (); + } + } + } + protected virtual void DefineNamespace () { if (containers != null) { @@ -348,20 +365,13 @@ namespace Mono.CSharp public string GetSignatureForMetadata () { -#if STATIC - var name = TypeNameParser.Escape (MemberName.Basename); - if (Parent is TypeDefinition) { - return Parent.GetSignatureForMetadata () + "+" + name; + return Parent.GetSignatureForMetadata () + "+" + TypeNameParser.Escape (MemberName.Basename); } - if (Parent != null && Parent.MemberName != null) - return Parent.GetSignatureForMetadata () + "." + name; - - return name; -#else - throw new NotImplementedException (); -#endif + var sb = new StringBuilder (); + CreateMetadataName (sb); + return sb.ToString (); } public virtual void RemoveContainer (TypeContainer cont) @@ -414,7 +424,7 @@ namespace Mono.CSharp } public TypeSpec CurrentType { - get { return tc.Parent.CurrentType; } + get { return tc.PartialContainer.CurrentType; } } public TypeParameters CurrentTypeParameters { @@ -511,6 +521,9 @@ namespace Mono.CSharp protected List type_bases; + // Partial parts for classes only + List class_partial_parts; + TypeDefinition InTransit; public TypeBuilder TypeBuilder; @@ -538,6 +551,7 @@ namespace Mono.CSharp public int DynamicSitesCounter; public int AnonymousMethodsCounter; + public int MethodGroupsCounter; static readonly string[] attribute_targets = new string[] { "type" }; @@ -547,7 +561,7 @@ namespace Mono.CSharp /// PendingImplementation pending; - public TypeDefinition (TypeContainer parent, MemberName name, Attributes attrs, MemberKind kind) + protected TypeDefinition (TypeContainer parent, MemberName name, Attributes attrs, MemberKind kind) : base (parent, name, attrs, kind) { PartialContainer = this; @@ -679,6 +693,18 @@ namespace Mono.CSharp } } + bool ITypeDefinition.IsTypeForwarder { + get { + return false; + } + } + + bool ITypeDefinition.IsCyclicTypeForwarder { + get { + return false; + } + } + // // Returns true for secondary partial containers // @@ -710,6 +736,8 @@ namespace Mono.CSharp } } + public ParametersCompiled PrimaryConstructorParameters { get; set; } + public TypeParameters TypeParametersAll { get { return all_type_parameters; @@ -756,7 +784,7 @@ namespace Mono.CSharp } } - AddNameToContainer (symbol, symbol.MemberName.Basename); + AddNameToContainer (symbol, symbol.MemberName.Name); members.Add (symbol); } @@ -764,21 +792,17 @@ namespace Mono.CSharp { AddNameToContainer (tc, tc.Basename); - if (containers == null) - containers = new List (); - - members.Add (tc); base.AddTypeContainer (tc); } - public override void AddCompilerGeneratedClass (CompilerGeneratedContainer c) + protected override void AddTypeContainerMember (TypeContainer tc) { - members.Add (c); + members.Add (tc); if (containers == null) containers = new List (); - base.AddCompilerGeneratedClass (c); + base.AddTypeContainerMember (tc); } // @@ -811,6 +835,9 @@ namespace Mono.CSharp if (symbol is TypeParameter) { Report.Error (692, symbol.Location, "Duplicate type parameter `{0}'", symbol.GetSignatureForError ()); + } else if (symbol is PrimaryConstructorField && mc is TypeParameter) { + Report.Error (9003, symbol.Location, "Primary constructor of type `{0}' has parameter of same name as type parameter `{1}'", + symbol.Parent.GetSignatureForError (), symbol.GetSignatureForError ()); } else { Report.Error (102, symbol.Location, "The type `{0}' already contains a definition for `{1}'", @@ -876,6 +903,17 @@ namespace Mono.CSharp AddMember (op); } + public void AddPartialPart (TypeDefinition part) + { + if (Kind != MemberKind.Class) + return; + + if (class_partial_parts == null) + class_partial_parts = new List (); + + class_partial_parts.Add (part); + } + public override void ApplyAttributeBuilder (Attribute a, MethodSpec ctor, byte[] cdata, PredefinedAttributes pa) { if (has_normal_indexers && a.Type == pa.DefaultMember) { @@ -972,7 +1010,7 @@ namespace Mono.CSharp if (s == null) { s = EmptyExpressionStatement.Instance; } else if (!fi.IsSideEffectFree) { - has_complex_initializer |= true; + has_complex_initializer = true; } init [i] = s; @@ -988,6 +1026,7 @@ namespace Mono.CSharp if (!has_complex_initializer && fi.IsDefaultInitializer) continue; + ec.AssignmentInfoOffset += fi.AssignmentOffset; ec.CurrentBlock.AddScopeStatement (new StatementExpression (init [i])); } @@ -999,9 +1038,20 @@ namespace Mono.CSharp for (int i = 0; i < initialized_fields.Count; ++i) { FieldInitializer fi = initialized_fields [i]; + + // + // Clone before resolving otherwise when field initializer is needed + // in more than 1 constructor any resolve after the initial one would + // only took the resolved expression which is problem for expressions + // that generate extra expressions or code during Resolve phase + // + var cloned = fi.Clone (new CloneContext ()); + ExpressionStatement s = fi.ResolveStatement (ec); - if (s == null) + if (s == null) { + initialized_fields [i] = new FieldInitializer (fi.Field, ErrorExpression.Instance, Location.Null); continue; + } // // Field is re-initialized to its default value => removed @@ -1009,7 +1059,9 @@ namespace Mono.CSharp if (fi.IsDefaultInitializer && ec.Module.Compiler.Settings.Optimize) continue; + ec.AssignmentInfoOffset += fi.AssignmentOffset; ec.CurrentBlock.AddScopeStatement (new StatementExpression (s)); + initialized_fields [i] = (FieldInitializer) cloned; } } @@ -1031,6 +1083,9 @@ namespace Mono.CSharp internal override void GenerateDocComment (DocumentationBuilder builder) { + if (IsPartialPart) + return; + base.GenerateDocComment (builder); foreach (var member in members) @@ -1074,9 +1129,9 @@ namespace Mono.CSharp } } - public virtual void AddBasesForPart (List bases) + public virtual void SetBaseTypes (List baseTypes) { - type_bases = bases; + type_bases = baseTypes; } /// @@ -1186,7 +1241,7 @@ namespace Mono.CSharp } bool pair_found = false; - for (int ii = i + 1; ii < members.Count; ++ii) { + for (int ii = 0; ii < members.Count; ++ii) { var o_b = members[ii] as Operator; if (o_b == null || o_b.OperatorType != matching_type) continue; @@ -1238,7 +1293,7 @@ namespace Mono.CSharp // // Sets .size to 1 for structs with no instance fields // - int type_size = Kind == MemberKind.Struct && first_nonstatic_field == null ? 1 : 0; + int type_size = Kind == MemberKind.Struct && first_nonstatic_field == null && !(this is StateMachine) ? 1 : 0; var parent_def = Parent as TypeDefinition; if (parent_def == null) { @@ -1267,8 +1322,10 @@ namespace Mono.CSharp all_tp_builders = TypeBuilder.DefineGenericParameters (tparam_names); - if (CurrentTypeParameters != null) - CurrentTypeParameters.Define (all_tp_builders, spec, CurrentTypeParametersStartIndex, this); + if (CurrentTypeParameters != null) { + CurrentTypeParameters.Create (spec, CurrentTypeParametersStartIndex, this); + CurrentTypeParameters.Define (all_tp_builders); + } } return true; @@ -1351,22 +1408,12 @@ namespace Mono.CSharp if (proxy_method == null) { string name = CompilerGeneratedContainer.MakeName (method.Name, null, "BaseCallProxy", hoisted_base_call_proxies.Count); - var base_parameters = new Parameter[method.Parameters.Count]; - for (int i = 0; i < base_parameters.Length; ++i) { - var base_param = method.Parameters.FixedParameters[i]; - base_parameters[i] = new Parameter (new TypeExpression (method.Parameters.Types[i], Location), - base_param.Name, base_param.ModFlags, null, Location); - base_parameters[i].Resolve (this, i); - } - - var cloned_params = ParametersCompiled.CreateFullyResolved (base_parameters, method.Parameters.Types); - if (method.Parameters.HasArglist) { - cloned_params.FixedParameters[0] = new Parameter (null, "__arglist", Parameter.Modifier.NONE, null, Location); - cloned_params.Types[0] = Module.PredefinedTypes.RuntimeArgumentHandle.Resolve (); - } MemberName member_name; TypeArguments targs = null; + TypeSpec return_type = method.ReturnType; + var local_param_types = method.Parameters.Types; + if (method.IsGeneric) { // // Copy all base generic method type parameters info @@ -1378,19 +1425,42 @@ namespace Mono.CSharp targs.Arguments = new TypeSpec[hoisted_tparams.Length]; for (int i = 0; i < hoisted_tparams.Length; ++i) { var tp = hoisted_tparams[i]; - tparams.Add (new TypeParameter (tp, null, new MemberName (tp.Name, Location), null)); + var local_tp = new TypeParameter (tp, null, new MemberName (tp.Name, Location), null); + tparams.Add (local_tp); targs.Add (new SimpleName (tp.Name, Location)); - targs.Arguments[i] = tp; + targs.Arguments[i] = local_tp.Type; } member_name = new MemberName (name, tparams, Location); + + // + // Mutate any method type parameters from original + // to newly created hoisted version + // + var mutator = new TypeParameterMutator (hoisted_tparams, tparams); + return_type = mutator.Mutate (return_type); + local_param_types = mutator.Mutate (local_param_types); } else { member_name = new MemberName (name); } + var base_parameters = new Parameter[method.Parameters.Count]; + for (int i = 0; i < base_parameters.Length; ++i) { + var base_param = method.Parameters.FixedParameters[i]; + base_parameters[i] = new Parameter (new TypeExpression (local_param_types [i], Location), + base_param.Name, base_param.ModFlags, null, Location); + base_parameters[i].Resolve (this, i); + } + + var cloned_params = ParametersCompiled.CreateFullyResolved (base_parameters, method.Parameters.Types); + if (method.Parameters.HasArglist) { + cloned_params.FixedParameters[0] = new Parameter (null, "__arglist", Parameter.Modifier.NONE, null, Location); + cloned_params.Types[0] = Module.PredefinedTypes.RuntimeArgumentHandle.Resolve (); + } + // Compiler generated proxy - proxy_method = new Method (this, new TypeExpression (method.ReturnType, Location), + proxy_method = new Method (this, new TypeExpression (return_type, Location), Modifiers.PRIVATE | Modifiers.COMPILER_GENERATED | Modifiers.DEBUGGER_HIDDEN, member_name, cloned_params, null); @@ -1416,6 +1486,7 @@ namespace Mono.CSharp members.Add (proxy_method); proxy_method.Define (); + proxy_method.PrepareEmit (); hoisted_base_call_proxies.Add (method, proxy_method); } @@ -1424,6 +1495,14 @@ namespace Mono.CSharp } protected bool DefineBaseTypes () + { + if (IsPartialPart && Kind == MemberKind.Class) + return true; + + return DoDefineBaseType (); + } + + bool DoDefineBaseType () { iface_exprs = ResolveBaseTypes (out base_type_expr); bool set_base_type; @@ -1468,6 +1547,14 @@ namespace Mono.CSharp PartialContainer.containers.AddRange (containers); } + if (PrimaryConstructorParameters != null) { + if (PartialContainer.PrimaryConstructorParameters != null) { + Report.Error (9001, Location, "Only one part of a partial type can declare primary constructor parameters"); + } else { + PartialContainer.PrimaryConstructorParameters = PrimaryConstructorParameters; + } + } + members_defined = members_defined_ok = true; caching_flags |= Flags.CloseTypeCreated; } else { @@ -1483,12 +1570,14 @@ namespace Mono.CSharp GetSignatureForError (), cycle.GetSignatureForError ()); iface_exprs = null; + PartialContainer.iface_exprs = null; } else { Report.Error (146, Location, "Circular base class dependency involving `{0}' and `{1}'", GetSignatureForError (), cycle.GetSignatureForError ()); base_type = null; + PartialContainer.base_type = null; } } @@ -1502,26 +1591,6 @@ namespace Mono.CSharp continue; TypeBuilder.AddInterfaceImplementation (iface_type.GetMetaInfo ()); - - // Ensure the base is always setup - var compiled_iface = iface_type.MemberDefinition as Interface; - if (compiled_iface != null) { - // TODO: Need DefineBaseType only - compiled_iface.DefineContainer (); - } - - if (iface_type.Interfaces != null) { - var base_ifaces = new List (iface_type.Interfaces); - for (int i = 0; i < base_ifaces.Count; ++i) { - var ii_iface_type = base_ifaces[i]; - if (spec.AddInterfaceDefined (ii_iface_type)) { - TypeBuilder.AddInterfaceImplementation (ii_iface_type.GetMetaInfo ()); - - if (ii_iface_type.Interfaces != null) - base_ifaces.AddRange (ii_iface_type.Interfaces); - } - } - } } } @@ -1531,33 +1600,130 @@ namespace Mono.CSharp } if (set_base_type) { - if (base_type != null) { - spec.BaseType = base_type; + SetBaseType (); + } + + // + // Base type of partial container has to be resolved before we + // resolve any nested types of the container. We need to know + // partial parts because the base type can be specified in file + // defined after current container + // + if (class_partial_parts != null) { + foreach (var pp in class_partial_parts) + pp.DoDefineBaseType (); - // Set base type after type creation - TypeBuilder.SetParent (base_type.GetMetaInfo ()); - } else { - TypeBuilder.SetParent (null); - } } return true; } + void SetBaseType () + { + if (base_type == null) { + TypeBuilder.SetParent (null); + return; + } + + if (spec.BaseType == base_type) + return; + + spec.BaseType = base_type; + + if (IsPartialPart) + spec.UpdateInflatedInstancesBaseType (); + + // Set base type after type creation + TypeBuilder.SetParent (base_type.GetMetaInfo ()); + } + + public override void ExpandBaseInterfaces () + { + if (!IsPartialPart) + DoExpandBaseInterfaces (); + + base.ExpandBaseInterfaces (); + } + + public void DoExpandBaseInterfaces () + { + if ((caching_flags & Flags.InterfacesExpanded) != 0) + return; + + caching_flags |= Flags.InterfacesExpanded; + + // + // Expand base interfaces. It cannot be done earlier because all partial + // interface parts need to be defined before the type they are used from + // + if (iface_exprs != null) { + foreach (var iface in iface_exprs) { + if (iface == null) + continue; + + var td = iface.MemberDefinition as TypeDefinition; + if (td != null) + td.DoExpandBaseInterfaces (); + + if (iface.Interfaces == null) + continue; + + foreach (var biface in iface.Interfaces) { + if (spec.AddInterfaceDefined (biface)) { + TypeBuilder.AddInterfaceImplementation (biface.GetMetaInfo ()); + } + } + } + } + + // + // Include all base type interfaces too, see ImportTypeBase for details + // + if (base_type != null) { + var td = base_type.MemberDefinition as TypeDefinition; + if (td != null) + td.DoExpandBaseInterfaces (); + + // + // Simply use base interfaces only, they are all expanded which makes + // it easy to handle generic type argument propagation with single + // inflator only. + // + // interface IA : IB + // interface IB : IC + // interface IC + // + if (base_type.Interfaces != null) { + foreach (var iface in base_type.Interfaces) { + spec.AddInterfaceDefined (iface); + } + } + } + } + public override void PrepareEmit () { if ((caching_flags & Flags.CloseTypeCreated) != 0) return; foreach (var member in members) { + var pbm = member as PropertyBasedMember; + if (pbm != null) + pbm.PrepareEmit (); + var pm = member as IParametersMember; if (pm != null) { + var mc = member as MethodOrOperator; + if (mc != null) { + mc.PrepareEmit (); + } var p = pm.Parameters; if (p.IsEmpty) continue; ((ParametersCompiled) p).ResolveDefaultValues (member); + continue; } var c = member as Const; @@ -1623,19 +1789,6 @@ namespace Mono.CSharp current_type = null; } - void UpdateTypeParameterConstraints (TypeDefinition part) - { - for (int i = 0; i < CurrentTypeParameters.Count; i++) { - if (CurrentTypeParameters[i].AddPartialConstraints (part, part.MemberName.TypeParameters[i])) - continue; - - Report.SymbolRelatedToPreviousError (Location, ""); - Report.Error (265, part.Location, - "Partial declarations of `{0}' have inconsistent constraints for type parameter `{1}'", - GetSignatureForError (), CurrentTypeParameters[i].GetSignatureForError ()); - } - } - public override void RemoveContainer (TypeContainer cont) { base.RemoveContainer (cont); @@ -1660,7 +1813,7 @@ namespace Mono.CSharp } if (IsPartialPart) { - PartialContainer.UpdateTypeParameterConstraints (this); + PartialContainer.CurrentTypeParameters.UpdateConstraints (this); } return true; @@ -1727,16 +1880,13 @@ namespace Mono.CSharp if (compiled_iface != null) compiled_iface.Define (); - if (Kind == MemberKind.Interface) - MemberCache.AddInterface (iface_type); - ObsoleteAttribute oa = iface_type.GetAttributeObsolete (); if (oa != null && !IsObsolete) AttributeTester.Report_ObsoleteMessage (oa, iface_type.GetSignatureForError (), Location, Report); if (iface_type.Arity > 0) { // TODO: passing `this' is wrong, should be base type iface instead - TypeManager.CheckTypeVariance (iface_type, Variance.Covariant, this); + VarianceDecl.CheckTypeVariance (iface_type, Variance.Covariant, this); if (((InflatedTypeSpec) iface_type).HasDynamicArgument () && !IsCompilerGenerated) { Report.Error (1966, Location, @@ -1747,21 +1897,25 @@ namespace Mono.CSharp } if (iface_type.IsGenericOrParentIsGeneric) { - if (spec.Interfaces != null) { - foreach (var prev_iface in iface_exprs) { - if (prev_iface == iface_type) - break; + foreach (var prev_iface in iface_exprs) { + if (prev_iface == iface_type || prev_iface == null) + break; - if (!TypeSpecComparer.Unify.IsEqual (iface_type, prev_iface)) - continue; + if (!TypeSpecComparer.Unify.IsEqual (iface_type, prev_iface)) + continue; - Report.Error (695, Location, - "`{0}' cannot implement both `{1}' and `{2}' because they may unify for some type parameter substitutions", - GetSignatureForError (), prev_iface.GetSignatureForError (), iface_type.GetSignatureForError ()); - } + Report.Error (695, Location, + "`{0}' cannot implement both `{1}' and `{2}' because they may unify for some type parameter substitutions", + GetSignatureForError (), prev_iface.GetSignatureForError (), iface_type.GetSignatureForError ()); } } } + + if (Kind == MemberKind.Interface) { + foreach (var iface in spec.Interfaces) { + MemberCache.AddInterface (iface); + } + } } if (base_type != null) { @@ -1780,11 +1934,6 @@ namespace Mono.CSharp } } - if (base_type.Interfaces != null) { - foreach (var iface in base_type.Interfaces) - spec.AddInterface (iface); - } - var baseContainer = base_type.MemberDefinition as ClassOrStruct; if (baseContainer != null) { baseContainer.Define (); @@ -1914,10 +2063,10 @@ namespace Mono.CSharp foreach (var member in members) { if (member is Event) { // - // An event can be assigned from same class only, so we can report + // An event can be assigned from same class only, report // this warning for all accessibility modes // - if (!member.IsUsed) + if (!member.IsUsed && !PartialContainer.HasStructLayout) Report.Warning (67, 3, member.Location, "The event `{0}' is never used", member.GetSignatureForError ()); continue; @@ -1935,12 +2084,15 @@ namespace Mono.CSharp continue; if (!member.IsUsed) { - if ((member.caching_flags & Flags.IsAssigned) == 0) { - Report.Warning (169, 3, member.Location, "The private field `{0}' is never used", member.GetSignatureForError ()); - } else { - Report.Warning (414, 3, member.Location, "The private field `{0}' is assigned but its value is never used", - member.GetSignatureForError ()); + if (!PartialContainer.HasStructLayout) { + if ((member.caching_flags & Flags.IsAssigned) == 0) { + Report.Warning (169, 3, member.Location, "The private field `{0}' is never used", member.GetSignatureForError ()); + } else { + Report.Warning (414, 3, member.Location, "The private field `{0}' is assigned but its value is never used", + member.GetSignatureForError ()); + } } + continue; } @@ -2044,8 +2196,13 @@ namespace Mono.CSharp base.Emit (); - for (int i = 0; i < members.Count; i++) - members[i].Emit (); + for (int i = 0; i < members.Count; i++) { + var m = members[i]; + if ((m.caching_flags & Flags.CloseTypeCreated) != 0) + continue; + + m.Emit (); + } EmitIndexerName (); CheckAttributeClsCompliance (); @@ -2215,17 +2372,26 @@ namespace Mono.CSharp /// public bool VerifyImplements (InterfaceMemberBase mb) { - var ifaces = spec.Interfaces; + var ifaces = PartialContainer.Interfaces; if (ifaces != null) { foreach (TypeSpec t in ifaces){ if (t == mb.InterfaceType) return true; + + var expanded_base = t.Interfaces; + if (expanded_base == null) + continue; + + foreach (var bt in expanded_base) { + if (bt == mb.InterfaceType) + return true; + } } } Report.SymbolRelatedToPreviousError (mb.InterfaceType); Report.Error (540, mb.Location, "`{0}': containing type does not implement interface `{1}'", - mb.GetSignatureForError (), TypeManager.CSharpName (mb.InterfaceType)); + mb.GetSignatureForError (), mb.InterfaceType.GetSignatureForError ()); return false; } @@ -2276,8 +2442,6 @@ namespace Mono.CSharp // // Public function used to locate types. // - // Set 'ignore_cs0104' to true if you want to ignore cs0104 errors. - // // Returns: Type or null if they type can not be found. // public override FullNamedExpression LookupNamespaceOrType (string name, int arity, LookupMode mode, Location loc) @@ -2303,7 +2467,13 @@ namespace Mono.CSharp if (t != null && (t.IsAccessible (this) || mode == LookupMode.IgnoreAccessibility)) e = new TypeExpression (t, Location.Null); else { + var errors = Compiler.Report.Errors; e = Parent.LookupNamespaceOrType (name, arity, mode, loc); + + // TODO: LookupNamespaceOrType does more than just lookup. The result + // cannot be cached or the error reporting won't happen + if (errors != Compiler.Report.Errors) + return e; } } @@ -2385,12 +2555,15 @@ namespace Mono.CSharp public const TypeAttributes StaticClassAttribute = TypeAttributes.Abstract | TypeAttributes.Sealed; SecurityType declarative_security; + protected Constructor generated_primary_constructor; - public ClassOrStruct (TypeContainer parent, MemberName name, Attributes attrs, MemberKind kind) + protected ClassOrStruct (TypeContainer parent, MemberName name, Attributes attrs, MemberKind kind) : base (parent, name, attrs, kind) { } + public Arguments PrimaryConstructorBaseArguments { get; set; } + protected override TypeAttributes TypeAttr { get { TypeAttributes ta = base.TypeAttr; @@ -2418,6 +2591,12 @@ namespace Mono.CSharp symbol.GetSignatureForError ()); return; } + + if (symbol is PrimaryConstructorField) { + Report.Error (9004, symbol.Location, "Primary constructor of type `{0}' has parameter of same name as containing type", + symbol.Parent.GetSignatureForError ()); + return; + } InterfaceMemberBase imb = symbol as InterfaceMemberBase; if (imb == null || !imb.IsExplicitImpl) { @@ -2455,7 +2634,7 @@ namespace Mono.CSharp /// /// Defines the default constructors /// - protected Constructor DefineDefaultConstructor (bool is_static) + protected virtual Constructor DefineDefaultConstructor (bool is_static) { // The default instance constructor is public // If the class is abstract, the default constructor is protected @@ -2468,11 +2647,15 @@ namespace Mono.CSharp mods = ((ModFlags & Modifiers.ABSTRACT) != 0) ? Modifiers.PROTECTED : Modifiers.PUBLIC; } - var c = new Constructor (this, MemberName.Name, mods, null, ParametersCompiled.EmptyReadOnlyParameters, Location); - c.Initializer = new GeneratedBaseInitializer (Location); + var c = new Constructor (this, MemberName.Name, mods, null, PrimaryConstructorParameters ?? ParametersCompiled.EmptyReadOnlyParameters, Location); + if (Kind == MemberKind.Class) + c.Initializer = new GeneratedBaseInitializer (Location, PrimaryConstructorBaseArguments); + + if (PrimaryConstructorParameters != null) + c.IsPrimaryConstructor = true; AddConstructor (c, true); - c.Block = new ToplevelBlock (Compiler, ParametersCompiled.EmptyReadOnlyParameters, Location) { + c.Block = new ToplevelBlock (Compiler, c.ParameterInfo, Location) { IsCompilerGenerated = true }; @@ -2483,6 +2666,19 @@ namespace Mono.CSharp { CheckProtectedModifier (); + if (PrimaryConstructorParameters != null) { + foreach (Parameter p in PrimaryConstructorParameters.FixedParameters) { + if ((p.ModFlags & Parameter.Modifier.RefOutMask) != 0) + continue; + + var f = new PrimaryConstructorField (this, p); + AddField (f); + + generated_primary_constructor.Block.AddStatement ( + new StatementExpression (new PrimaryConstructorAssign (f, p), p.Location)); + } + } + base.DoDefineMembers (); return true; @@ -2522,7 +2718,7 @@ namespace Mono.CSharp Modifiers.SEALED | Modifiers.STATIC | Modifiers.UNSAFE; - + public Class (TypeContainer parent, MemberName name, Modifiers mod, Attributes attrs) : base (parent, name, attrs, MemberKind.Class) { @@ -2536,14 +2732,14 @@ namespace Mono.CSharp visitor.Visit (this); } - public override void AddBasesForPart (List bases) + public override void SetBaseTypes (List baseTypes) { var pmn = MemberName; if (pmn.Name == "Object" && !pmn.IsGeneric && Parent.MemberName.Name == "System" && Parent.MemberName.Left == null) Report.Error (537, Location, "The class System.Object cannot have a base class or implement an interface."); - base.AddBasesForPart (bases); + base.SetBaseTypes (baseTypes); } public override void ApplyAttributeBuilder (Attribute a, MethodSpec ctor, byte[] cdata, PredefinedAttributes pa) @@ -2569,7 +2765,7 @@ namespace Mono.CSharp return; } - if (a.Type.IsConditionallyExcluded (this, Location)) + if (a.Type.IsConditionallyExcluded (this)) return; base.ApplyAttributeBuilder (a, ctor, cdata, pa); @@ -2592,6 +2788,11 @@ namespace Mono.CSharp } if (IsStatic) { + if (PrimaryConstructorParameters != null) { + Report.Error (-800, Location, "`{0}': Static classes cannot have primary constructor", GetSignatureForError ()); + PrimaryConstructorParameters = null; + } + foreach (var m in Members) { if (m is Operator) { Report.Error (715, m.Location, "`{0}': Static classes cannot contain user-defined operators", m.GetSignatureForError ()); @@ -2619,8 +2820,8 @@ namespace Mono.CSharp Report.Error (708, m.Location, "`{0}': cannot declare instance members in a static class", m.GetSignatureForError ()); } } else { - if (!PartialContainer.HasInstanceConstructor) - DefineDefaultConstructor (false); + if (!PartialContainer.HasInstanceConstructor || PrimaryConstructorParameters != null) + generated_primary_constructor = DefineDefaultConstructor (false); } return base.DoDefineMembers (); @@ -2638,6 +2839,17 @@ namespace Mono.CSharp } } + public override void GetCompletionStartingWith (string prefix, List results) + { + base.GetCompletionStartingWith (prefix, results); + + var bt = base_type; + while (bt != null) { + results.AddRange (MemberCache.GetCompletitionMembers (this, bt, prefix).Where (l => l.IsStatic).Select (l => l.Name)); + bt = bt.BaseType; + } + } + protected override TypeSpec[] ResolveBaseTypes (out FullNamedExpression base_class) { var ifaces = base.ResolveBaseTypes (out base_class); @@ -2831,6 +3043,14 @@ namespace Mono.CSharp return fts.CheckStructCycles (); } + protected override bool DoDefineMembers () + { + if (PrimaryConstructorParameters != null) + generated_primary_constructor = DefineDefaultConstructor (false); + + return base.DoDefineMembers (); + } + public override void Emit () { CheckStructCycles (); @@ -2976,7 +3196,7 @@ namespace Mono.CSharp Report.SymbolRelatedToPreviousError (iface); Report.Warning (3027, 1, Location, "`{0}' is not CLS-compliant because base interface `{1}' is not CLS-compliant", - GetSignatureForError (), TypeManager.CSharpName (iface)); + GetSignatureForError (), iface.GetSignatureForError ()); } } @@ -3049,7 +3269,7 @@ namespace Mono.CSharp readonly Modifiers explicit_mod_flags; public MethodAttributes flags; - public InterfaceMemberBase (TypeDefinition parent, FullNamedExpression type, Modifiers mod, Modifiers allowed_mod, MemberName name, Attributes attrs) + protected InterfaceMemberBase (TypeDefinition parent, FullNamedExpression type, Modifiers mod, Modifiers allowed_mod, MemberName name, Attributes attrs) : base (parent, type, mod, allowed_mod, Modifiers.PRIVATE, name, attrs) { IsInterface = parent.Kind == MemberKind.Interface; @@ -3167,7 +3387,7 @@ namespace Mono.CSharp } } - if (!IsInterface && base_member.IsAbstract && !overrides) { + if (!IsInterface && base_member.IsAbstract && !overrides && !IsStatic) { Report.SymbolRelatedToPreviousError (base_member); Report.Error (533, Location, "`{0}' hides inherited abstract member `{1}'", GetSignatureForError (), base_member.GetSignatureForError ()); @@ -3211,10 +3431,10 @@ namespace Mono.CSharp Report.SymbolRelatedToPreviousError (base_member); if (this is PropertyBasedMember) { Report.Error (1715, Location, "`{0}': type must be `{1}' to match overridden member `{2}'", - GetSignatureForError (), TypeManager.CSharpName (base_member_type), TypeManager.CSharpSignature (base_member)); + GetSignatureForError (), base_member_type.GetSignatureForError (), base_member.GetSignatureForError ()); } else { Report.Error (508, Location, "`{0}': return type must be `{1}' to match overridden member `{2}'", - GetSignatureForError (), TypeManager.CSharpName (base_member_type), TypeManager.CSharpSignature (base_member)); + GetSignatureForError (), base_member_type.GetSignatureForError (), base_member.GetSignatureForError ()); } ok = false; } @@ -3288,12 +3508,16 @@ namespace Mono.CSharp if (!InterfaceType.IsInterface) { Report.SymbolRelatedToPreviousError (InterfaceType); Report.Error (538, Location, "The type `{0}' in explicit interface declaration is not an interface", - TypeManager.CSharpName (InterfaceType)); + InterfaceType.GetSignatureForError ()); } else { Parent.PartialContainer.VerifyImplements (this); } - ModifiersExtensions.Check (Modifiers.AllowedExplicitImplFlags, explicit_mod_flags, 0, Location, Report); + Modifiers allowed_explicit = Modifiers.AllowedExplicitImplFlags; + if (this is Method) + allowed_explicit |= Modifiers.ASYNC; + + ModifiersExtensions.Check (allowed_explicit, explicit_mod_flags, 0, Location, Report); } return base.Define (); @@ -3319,15 +3543,15 @@ namespace Mono.CSharp if (this is Indexer) Report.Error (55, Location, "Inconsistent accessibility: parameter type `{0}' is less accessible than indexer `{1}'", - TypeManager.CSharpName (t), GetSignatureForError ()); + t.GetSignatureForError (), GetSignatureForError ()); else if (this is Operator) Report.Error (57, Location, "Inconsistent accessibility: parameter type `{0}' is less accessible than operator `{1}'", - TypeManager.CSharpName (t), GetSignatureForError ()); + t.GetSignatureForError (), GetSignatureForError ()); else Report.Error (51, Location, "Inconsistent accessibility: parameter type `{0}' is less accessible than method `{1}'", - TypeManager.CSharpName (t), GetSignatureForError ()); + t.GetSignatureForError (), GetSignatureForError ()); error = true; } return !error; @@ -3337,14 +3561,14 @@ namespace Mono.CSharp { base.DoMemberTypeDependentChecks (); - TypeManager.CheckTypeVariance (MemberType, ExpectedMemberTypeVariance, this); + VarianceDecl.CheckTypeVariance (MemberType, ExpectedMemberTypeVariance, this); } public override void Emit() { // for extern static method must be specified either DllImport attribute or MethodImplAttribute. // We are more strict than csc and report this as an error because SRE does not allow emit that - if ((ModFlags & Modifiers.EXTERN) != 0 && !is_external_implementation) { + if ((ModFlags & Modifiers.EXTERN) != 0 && !is_external_implementation && (OptAttributes == null || !OptAttributes.HasResolveError ())) { if (this is Constructor) { Report.Warning (824, 1, Location, "Constructor `{0}' is marked `external' but has no external implementation specified", GetSignatureForError ()); @@ -3436,7 +3660,7 @@ namespace Mono.CSharp // replacing predefined names which saves some space and name // is still unique // - return TypeManager.CSharpName (InterfaceType) + "." + name; + return InterfaceType.GetSignatureForError () + "." + name; } public override string GetSignatureForDocumentation () @@ -3452,6 +3676,16 @@ namespace Mono.CSharp get { return IsExplicitImpl || base.IsUsed; } } + public override void SetConstraints (List constraints_list) + { + if (((ModFlags & Modifiers.OVERRIDE) != 0 || IsExplicitImpl)) { + Report.Error (460, Location, + "`{0}': Cannot specify constraints for overrides and explicit interface implementation methods", + GetSignatureForError ()); + } + + base.SetConstraints (constraints_list); + } } public abstract class MemberBase : MemberCore @@ -3465,7 +3699,9 @@ namespace Mono.CSharp { this.Parent = parent; this.type_expr = type; - ModFlags = ModifiersExtensions.Check (allowed_mod, mod, def_mod, Location, Report); + + if (name != MemberName.Null) + ModFlags = ModifiersExtensions.Check (allowed_mod, mod, def_mod, Location, Report); } #region Properties @@ -3523,29 +3759,33 @@ namespace Mono.CSharp Report.SymbolRelatedToPreviousError (MemberType); if (this is Property) Report.Error (53, Location, - "Inconsistent accessibility: property type `" + - TypeManager.CSharpName (MemberType) + "' is less " + - "accessible than property `" + GetSignatureForError () + "'"); + "Inconsistent accessibility: property type `" + + MemberType.GetSignatureForError () + "' is less " + + "accessible than property `" + GetSignatureForError () + "'"); else if (this is Indexer) Report.Error (54, Location, - "Inconsistent accessibility: indexer return type `" + - TypeManager.CSharpName (MemberType) + "' is less " + - "accessible than indexer `" + GetSignatureForError () + "'"); + "Inconsistent accessibility: indexer return type `" + + MemberType.GetSignatureForError () + "' is less " + + "accessible than indexer `" + GetSignatureForError () + "'"); else if (this is MethodCore) { if (this is Operator) Report.Error (56, Location, - "Inconsistent accessibility: return type `" + - TypeManager.CSharpName (MemberType) + "' is less " + - "accessible than operator `" + GetSignatureForError () + "'"); + "Inconsistent accessibility: return type `" + + MemberType.GetSignatureForError () + "' is less " + + "accessible than operator `" + GetSignatureForError () + "'"); else Report.Error (50, Location, - "Inconsistent accessibility: return type `" + - TypeManager.CSharpName (MemberType) + "' is less " + - "accessible than method `" + GetSignatureForError () + "'"); + "Inconsistent accessibility: return type `" + + MemberType.GetSignatureForError () + "' is less " + + "accessible than method `" + GetSignatureForError () + "'"); + } else if (this is Event) { + Report.Error (7025, Location, + "Inconsistent accessibility: event type `{0}' is less accessible than event `{1}'", + MemberType.GetSignatureForError (), GetSignatureForError ()); } else { Report.Error (52, Location, "Inconsistent accessibility: field type `" + - TypeManager.CSharpName (MemberType) + "' is less " + + MemberType.GetSignatureForError () + "' is less " + "accessible than field `" + GetSignatureForError () + "'"); } } diff --git a/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/codegen.cs b/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/codegen.cs index 9bb706675..7f7ccb332 100644 --- a/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/codegen.cs +++ b/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/codegen.cs @@ -175,6 +175,12 @@ namespace Mono.CSharp } } + public bool NotifyEvaluatorOnStore { + get { + return Module.Evaluator != null && Module.Evaluator.ModificationListener != null; + } + } + // Has to be used for specific emitter errors only any // possible resolver errors have to be reported during Resolve public Report Report { @@ -204,6 +210,10 @@ namespace Mono.CSharp } } + public LocalVariable AsyncThrowVariable { get; set; } + + public List TryFinallyUnwind { get; set; } + #endregion public void AddStatementEpilog (IExpressionCleanup cleanupExpression) @@ -248,6 +258,21 @@ namespace Mono.CSharp return true; } + public void MarkCallEntry (Location loc) + { + if (!EmitAccurateDebugInfo) + return; + + // + // TODO: This should emit different kind of sequence point to make + // step-over work for statement over multiple lines + // + // Debugging experience for Foo (A () + B ()) where A and B are + // on separate lines is not great + // + Mark (loc); + } + public void DefineLocalVariable (string name, LocalBuilder builder) { if ((flags & Options.OmitDebugInfo) != 0) @@ -258,14 +283,27 @@ namespace Mono.CSharp public void BeginCatchBlock (TypeSpec type) { + if (IsAnonymousStoreyMutateRequired) + type = CurrentAnonymousMethod.Storey.Mutator.Mutate (type); + ig.BeginCatchBlock (type.GetMetaInfo ()); } + public void BeginFilterHandler () + { + ig.BeginCatchBlock (null); + } + public void BeginExceptionBlock () { ig.BeginExceptionBlock (); } + public void BeginExceptionFilterBlock () + { + ig.BeginExceptFilterBlock (); + } + public void BeginFinallyBlock () { ig.BeginFinallyBlock (); @@ -281,6 +319,16 @@ namespace Mono.CSharp #endif } + public void BeginCompilerScope () + { + if ((flags & Options.OmitDebugInfo) != 0) + return; + +#if NET_4_0 + methodSymbols.StartBlock (CodeBlockEntry.Type.CompilerGenerated, ig.ILOffset); +#endif + } + public void EndExceptionBlock () { ig.EndExceptionBlock (); @@ -342,9 +390,9 @@ namespace Mono.CSharp // // Creates temporary field in current async storey // - public FieldExpr GetTemporaryField (TypeSpec type) + public StackFieldExpr GetTemporaryField (TypeSpec type, bool initializedFieldRequired = false) { - var f = AsyncTaskStorey.AddCapturedLocalVariable (type); + var f = AsyncTaskStorey.AddCapturedLocalVariable (type, initializedFieldRequired); var fexpr = new StackFieldExpr (f); fexpr.InstanceExpression = new CompilerGeneratedThis (CurrentType, Location.Null); return fexpr; @@ -480,8 +528,16 @@ namespace Mono.CSharp type = EnumSpec.GetUnderlyingType (type); switch (type.BuiltinType) { - case BuiltinTypeSpec.Type.Byte: case BuiltinTypeSpec.Type.Bool: + // + // Workaround MSIL limitation. Load bool element as single bit, + // bool array can actually store any byte value + // + ig.Emit (OpCodes.Ldelem_U1); + ig.Emit (OpCodes.Ldc_I4_1); + ig.Emit (OpCodes.And); + break; + case BuiltinTypeSpec.Type.Byte: ig.Emit (OpCodes.Ldelem_U1); break; case BuiltinTypeSpec.Type.SByte: @@ -696,8 +752,12 @@ namespace Mono.CSharp ig.Emit (OpCodes.Ldind_U1); break; case BuiltinTypeSpec.Type.SByte: + ig.Emit (OpCodes.Ldind_I1); + break; case BuiltinTypeSpec.Type.Bool: ig.Emit (OpCodes.Ldind_I1); + ig.Emit (OpCodes.Ldc_I4_1); + ig.Emit (OpCodes.And); break; case BuiltinTypeSpec.Type.ULong: case BuiltinTypeSpec.Type.Long: @@ -940,10 +1000,6 @@ namespace Mono.CSharp public void Emit (EmitContext ec, MethodSpec method, Arguments Arguments, Location loc) { - // Speed up the check by not doing it on not allowed targets - if (method.ReturnType.Kind == MemberKind.Void && method.IsConditionallyExcluded (ec.MemberContext, loc)) - return; - EmitPredefined (ec, method, Arguments, loc); } @@ -1002,7 +1058,7 @@ namespace Mono.CSharp } } - if (call_op == OpCodes.Callvirt && (InstanceExpression.Type.IsGenericParameter || InstanceExpression.Type.IsStruct)) { + if (call_op == OpCodes.Callvirt && (InstanceExpression.Type.IsGenericParameter || InstanceExpression.Type.IsStructOrEnum)) { ec.Emit (OpCodes.Constrained, InstanceExpression.Type); } @@ -1011,11 +1067,7 @@ namespace Mono.CSharp // 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); + ec.MarkCallEntry (loc.Value); } // @@ -1046,7 +1098,7 @@ namespace Mono.CSharp // // Push the instance expression // - if ((instance_type.IsStruct && (callOpcode == OpCodes.Callvirt || (callOpcode == OpCodes.Call && declaringType.IsStruct))) || + if ((instance_type.IsStructOrEnum && (callOpcode == OpCodes.Callvirt || (callOpcode == OpCodes.Call && declaringType.IsStruct))) || instance_type.IsGenericParameter || declaringType.IsNullableType) { // // If the expression implements IMemoryLocation, then @@ -1068,7 +1120,7 @@ namespace Mono.CSharp return ReferenceContainer.MakeType (ec.Module, instance_type); } - if (instance_type.IsEnum || instance_type.IsStruct) { + if (instance_type.IsStructOrEnum) { instance.Emit (ec); ec.Emit (OpCodes.Box, instance_type); return ec.BuiltinTypes.Object; diff --git a/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/complete.cs b/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/complete.cs index a1bb8ec00..3504302d5 100644 --- a/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/complete.cs +++ b/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/complete.cs @@ -109,40 +109,58 @@ namespace Mono.CSharp { this.targs = targs; } - protected override Expression DoResolve (ResolveContext ec) + protected override Expression DoResolve (ResolveContext rc) { - Expression expr_resolved = expr.Resolve (ec, - ResolveFlags.VariableOrValue | ResolveFlags.Type); + var sn = expr as SimpleName; + const ResolveFlags flags = ResolveFlags.VariableOrValue | ResolveFlags.Type; + + if (sn != null) { + expr = sn.LookupNameExpression (rc, MemberLookupRestrictions.ReadAccess | MemberLookupRestrictions.ExactArity); + + // + // Resolve expression which does have type set as we need expression type + // with disable flow analysis as we don't know whether left side expression + // is used as variable or type + // + if (expr is VariableReference || expr is ConstantExpr || expr is Linq.TransparentMemberAccess) { + expr = expr.Resolve (rc); + } else if (expr is TypeParameterExpr) { + expr.Error_UnexpectedKind (rc, flags, sn.Location); + expr = null; + } + } else { + expr = expr.Resolve (rc, flags); + } - if (expr_resolved == null) + if (expr == null) return null; - TypeSpec expr_type = expr_resolved.Type; + TypeSpec expr_type = expr.Type; if (expr_type.IsPointer || expr_type.Kind == MemberKind.Void || expr_type == InternalType.NullLiteral || expr_type == InternalType.AnonymousMethod) { - expr_resolved.Error_OperatorCannotBeApplied (ec, loc, ".", expr_type); + expr.Error_OperatorCannotBeApplied (rc, loc, ".", expr_type); return null; } if (targs != null) { - if (!targs.Resolve (ec)) + if (!targs.Resolve (rc)) return null; } var results = new List (); - if (expr_resolved is Namespace){ - Namespace nexpr = expr_resolved as Namespace; + var nexpr = expr as NamespaceExpression; + if (nexpr != null) { string namespaced_partial; if (partial_name == null) - namespaced_partial = nexpr.Name; + namespaced_partial = nexpr.Namespace.Name; else - namespaced_partial = nexpr.Name + "." + partial_name; + namespaced_partial = nexpr.Namespace.Name + "." + partial_name; - ec.CurrentMemberDefinition.GetCompletionStartingWith (namespaced_partial, results); + rc.CurrentMemberDefinition.GetCompletionStartingWith (namespaced_partial, results); if (partial_name != null) results = results.Select (l => l.Substring (partial_name.Length)).ToList (); } else { - var r = MemberCache.GetCompletitionMembers (ec, expr_type, partial_name).Select (l => l.Name); + var r = MemberCache.GetCompletitionMembers (rc, expr_type, partial_name).Select (l => l.Name); AppendResults (results, partial_name, r); } @@ -192,5 +210,17 @@ namespace Mono.CSharp { // Nothing } } + + public class EmptyCompletion : CompletingExpression + { + protected override void CloneTo (CloneContext clonectx, Expression target) + { + } + + protected override Expression DoResolve (ResolveContext rc) + { + throw new CompletionResult ("", new string [0]); + } + } } diff --git a/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/const.cs b/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/const.cs index 31cba91fe..eef90b346 100644 --- a/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/const.cs +++ b/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/const.cs @@ -100,10 +100,10 @@ namespace Mono.CSharp { { if (t.IsGenericParameter) { Report.Error (1959, loc, - "Type parameter `{0}' cannot be declared const", TypeManager.CSharpName (t)); + "Type parameter `{0}' cannot be declared const", t.GetSignatureForError ()); } else { Report.Error (283, loc, - "The type `{0}' cannot be declared const", TypeManager.CSharpName (t)); + "The type `{0}' cannot be declared const", t.GetSignatureForError ()); } } diff --git a/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/constant.cs b/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/constant.cs index 4297c521d..36f4a62a9 100644 --- a/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/constant.cs +++ b/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/constant.cs @@ -3,11 +3,11 @@ // // Author: // Miguel de Icaza (miguel@ximian.com) -// Marek Safar (marek.safar@seznam.cz) +// Marek Safar (marek.safar@gmail.com) // // Copyright 2001-2003 Ximian, Inc. // Copyright 2003-2008 Novell, Inc. -// Copyright 2011 Xamarin Inc +// Copyright 2011-2013 Xamarin Inc // using System; @@ -64,13 +64,13 @@ namespace Mono.CSharp { BuiltinTypeSpec.IsPrimitiveTypeOrDecimal (target) && BuiltinTypeSpec.IsPrimitiveTypeOrDecimal (type)) { ec.Report.Error (31, loc, "Constant value `{0}' cannot be converted to a `{1}'", - GetValueAsLiteral (), TypeManager.CSharpName (target)); + GetValueAsLiteral (), target.GetSignatureForError ()); } else { base.Error_ValueCannotBeConverted (ec, target, expl); } } - public Constant ImplicitConversionRequired (ResolveContext ec, TypeSpec type, Location loc) + public Constant ImplicitConversionRequired (ResolveContext ec, TypeSpec type) { Constant c = ConvertImplicitly (type); if (c == null) @@ -89,7 +89,7 @@ namespace Mono.CSharp { if (this.type == type) return this; - if (Convert.ImplicitNumericConversion (this, type) == null) + if (!Convert.ImplicitNumericConversionExists (this.type, type)) return null; bool fail; @@ -100,20 +100,15 @@ namespace Mono.CSharp { // reached, by calling Convert.ImplicitStandardConversionExists // throw new InternalErrorException ("Missing constant conversion between `{0}' and `{1}'", - TypeManager.CSharpName (Type), TypeManager.CSharpName (type)); + Type.GetSignatureForError (), type.GetSignatureForError ()); } - return CreateConstant (type, constant_value, loc); + return CreateConstantFromValue (type, constant_value, loc); } // // Returns a constant instance based on Type // - public static Constant CreateConstant (TypeSpec t, object v, Location loc) - { - return CreateConstantFromValue (t, v, loc); - } - public static Constant CreateConstantFromValue (TypeSpec t, object v, Location loc) { switch (t.BuiltinType) { @@ -167,6 +162,88 @@ namespace Mono.CSharp { #endif } + // + // Returns a constant instance based on value and type. This is probing version of + // CreateConstantFromValue + // + public static Constant ExtractConstantFromValue (TypeSpec t, object v, Location loc) + { + switch (t.BuiltinType) { + case BuiltinTypeSpec.Type.Int: + if (v is int) + return new IntConstant (t, (int) v, loc); + break; + case BuiltinTypeSpec.Type.String: + if (v is string) + return new StringConstant (t, (string) v, loc); + break; + case BuiltinTypeSpec.Type.UInt: + if (v is uint) + return new UIntConstant (t, (uint) v, loc); + break; + case BuiltinTypeSpec.Type.Long: + if (v is long) + return new LongConstant (t, (long) v, loc); + break; + case BuiltinTypeSpec.Type.ULong: + if (v is ulong) + return new ULongConstant (t, (ulong) v, loc); + break; + case BuiltinTypeSpec.Type.Float: + if (v is float) + return new FloatConstant (t, (float) v, loc); + break; + case BuiltinTypeSpec.Type.Double: + if (v is double) + return new DoubleConstant (t, (double) v, loc); + break; + case BuiltinTypeSpec.Type.Short: + if (v is short) + return new ShortConstant (t, (short) v, loc); + break; + case BuiltinTypeSpec.Type.UShort: + if (v is ushort) + return new UShortConstant (t, (ushort) v, loc); + break; + case BuiltinTypeSpec.Type.SByte: + if (v is sbyte) + return new SByteConstant (t, (sbyte) v, loc); + break; + case BuiltinTypeSpec.Type.Byte: + if (v is byte) + return new ByteConstant (t, (byte) v, loc); + break; + case BuiltinTypeSpec.Type.Char: + if (v is char) + return new CharConstant (t, (char) v, loc); + break; + case BuiltinTypeSpec.Type.Bool: + if (v is bool) + return new BoolConstant (t, (bool) v, loc); + break; + case BuiltinTypeSpec.Type.Decimal: + if (v is decimal) + return new DecimalConstant (t, (decimal) v, loc); + break; + } + + if (t.IsEnum) { + var real_type = EnumSpec.GetUnderlyingType (t); + return new EnumConstant (CreateConstantFromValue (real_type, v, loc), t); + } + + if (v == null) { + if (t.IsNullableType) + return Nullable.LiftedNull.Create (t, loc); + + if (TypeSpec.IsReferenceType (t)) + return new NullConstant (t, loc); + } + + return null; + } + + public override Expression CreateExpressionTree (ResolveContext ec) { Arguments args = new Arguments (2); @@ -251,10 +328,12 @@ namespace Mono.CSharp { return this; } - /// - /// Attempts to do a compile-time folding of a constant cast. - /// - public Constant TryReduce (ResolveContext ec, TypeSpec target_type) + // + // Attempts to do a compile-time folding of a constant cast and handles + // error reporting for constant overlows only, on normal conversion + // errors returns null + // + public Constant Reduce (ResolveContext ec, TypeSpec target_type) { try { return TryReduceConstant (ec, target_type); @@ -271,6 +350,15 @@ namespace Mono.CSharp { } } + public Constant TryReduce (ResolveContext rc, TypeSpec targetType) + { + try { + return TryReduceConstant (rc, targetType); + } catch (OverflowException) { + return null; + } + } + Constant TryReduceConstant (ResolveContext ec, TypeSpec target_type) { if (Type == target_type) { @@ -396,7 +484,7 @@ namespace Mono.CSharp { catch { ec.Report.Error (31, loc, "Constant value `{0}' cannot be converted to a `{1}'", - GetValue ().ToString (), TypeManager.CSharpName (target)); + GetValue ().ToString (), target.GetSignatureForError ()); } } @@ -440,7 +528,7 @@ namespace Mono.CSharp { return Value ? 1 : 0; } - public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType) + public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType, TypeSpec parameterType) { enc.Encode (Value); } @@ -491,7 +579,7 @@ namespace Mono.CSharp { Value = v; } - public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType) + public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType, TypeSpec parameterType) { enc.Encode (Value); } @@ -591,7 +679,7 @@ namespace Mono.CSharp { Value = v; } - public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType) + public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType, TypeSpec parameterType) { enc.Encode ((ushort) Value); } @@ -719,7 +807,7 @@ namespace Mono.CSharp { Value = v; } - public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType) + public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType, TypeSpec parameterType) { enc.Encode (Value); } @@ -822,7 +910,7 @@ namespace Mono.CSharp { Value = v; } - public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType) + public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType, TypeSpec parameterType) { enc.Encode (Value); } @@ -935,7 +1023,7 @@ namespace Mono.CSharp { Value = v; } - public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType) + public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType, TypeSpec parameterType) { enc.Encode (Value); } @@ -1044,7 +1132,7 @@ namespace Mono.CSharp { Value = v; } - public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType) + public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType, TypeSpec parameterType) { enc.Encode (Value); } @@ -1220,7 +1308,7 @@ namespace Mono.CSharp { Value = v; } - public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType) + public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType, TypeSpec parameterType) { enc.Encode (Value); } @@ -1337,7 +1425,7 @@ namespace Mono.CSharp { Value = v; } - public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType) + public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType, TypeSpec parameterType) { enc.Encode (Value); } @@ -1468,7 +1556,7 @@ namespace Mono.CSharp { Value = v; } - public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType) + public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType, TypeSpec parameterType) { enc.Encode (Value); } @@ -1564,23 +1652,35 @@ namespace Mono.CSharp { } public class FloatConstant : Constant { - public readonly float Value; + // + // Store constant value as double because float constant operations + // need to work on double value to match JIT + // + public readonly double DoubleValue; - public FloatConstant (BuiltinTypes types, float v, Location loc) + public FloatConstant (BuiltinTypes types, double v, Location loc) : this (types.Float, v, loc) { } - public FloatConstant (TypeSpec type, float v, Location loc) + public FloatConstant (TypeSpec type, double v, Location loc) : base (loc) { this.type = type; eclass = ExprClass.Value; - Value = v; + DoubleValue = v; + } + + public override Constant ConvertImplicitly (TypeSpec type) + { + if (type.BuiltinType == BuiltinTypeSpec.Type.Double) + return new DoubleConstant (type, DoubleValue, loc); + + return base.ConvertImplicitly (type); } - public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType) + public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType, TypeSpec parameterType) { enc.Encode (Value); } @@ -1590,6 +1690,12 @@ namespace Mono.CSharp { ec.Emit (OpCodes.Ldc_R4, Value); } + public float Value { + get { + return (float) DoubleValue; + } + } + public override object GetValue () { return Value; @@ -1625,59 +1731,59 @@ namespace Mono.CSharp { if (Value < byte.MinValue || Value > byte.MaxValue || float.IsNaN (Value)) throw new OverflowException (); } - return new ByteConstant (target_type, (byte) Value, Location); + return new ByteConstant (target_type, (byte) DoubleValue, Location); case BuiltinTypeSpec.Type.SByte: if (in_checked_context) { if (Value < sbyte.MinValue || Value > sbyte.MaxValue || float.IsNaN (Value)) throw new OverflowException (); } - return new SByteConstant (target_type, (sbyte) Value, Location); + return new SByteConstant (target_type, (sbyte) DoubleValue, Location); case BuiltinTypeSpec.Type.Short: if (in_checked_context) { if (Value < short.MinValue || Value > short.MaxValue || float.IsNaN (Value)) throw new OverflowException (); } - return new ShortConstant (target_type, (short) Value, Location); + return new ShortConstant (target_type, (short) DoubleValue, Location); case BuiltinTypeSpec.Type.UShort: if (in_checked_context) { if (Value < ushort.MinValue || Value > ushort.MaxValue || float.IsNaN (Value)) throw new OverflowException (); } - return new UShortConstant (target_type, (ushort) Value, Location); + return new UShortConstant (target_type, (ushort) DoubleValue, Location); case BuiltinTypeSpec.Type.Int: if (in_checked_context) { if (Value < int.MinValue || Value > int.MaxValue || float.IsNaN (Value)) throw new OverflowException (); } - return new IntConstant (target_type, (int) Value, Location); + return new IntConstant (target_type, (int) DoubleValue, Location); case BuiltinTypeSpec.Type.UInt: if (in_checked_context) { if (Value < uint.MinValue || Value > uint.MaxValue || float.IsNaN (Value)) throw new OverflowException (); } - return new UIntConstant (target_type, (uint) Value, Location); + return new UIntConstant (target_type, (uint) DoubleValue, Location); case BuiltinTypeSpec.Type.Long: if (in_checked_context) { if (Value < long.MinValue || Value > long.MaxValue || float.IsNaN (Value)) throw new OverflowException (); } - return new LongConstant (target_type, (long) Value, Location); + return new LongConstant (target_type, (long) DoubleValue, Location); case BuiltinTypeSpec.Type.ULong: if (in_checked_context) { if (Value < ulong.MinValue || Value > ulong.MaxValue || float.IsNaN (Value)) throw new OverflowException (); } - return new ULongConstant (target_type, (ulong) Value, Location); + return new ULongConstant (target_type, (ulong) DoubleValue, Location); case BuiltinTypeSpec.Type.Double: - return new DoubleConstant (target_type, (double) Value, Location); + return new DoubleConstant (target_type, DoubleValue, Location); case BuiltinTypeSpec.Type.Char: if (in_checked_context) { if (Value < (float) char.MinValue || Value > (float) char.MaxValue || float.IsNaN (Value)) throw new OverflowException (); } - return new CharConstant (target_type, (char) Value, Location); + return new CharConstant (target_type, (char) DoubleValue, Location); case BuiltinTypeSpec.Type.Decimal: - return new DecimalConstant (target_type, (decimal) Value, Location); + return new DecimalConstant (target_type, (decimal) DoubleValue, Location); } return null; @@ -1703,7 +1809,7 @@ namespace Mono.CSharp { Value = v; } - public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType) + public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType, TypeSpec parameterType) { enc.Encode (Value); } @@ -1988,7 +2094,7 @@ namespace Mono.CSharp { ec.Emit (OpCodes.Ldstr, Value); } - public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType) + public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType, TypeSpec parameterType) { // cast to object if (type != targetType) @@ -2019,6 +2125,14 @@ namespace Mono.CSharp { { return null; } + + public override Constant ConvertImplicitly (TypeSpec type) + { + if (IsDefaultValue && type.BuiltinType == BuiltinTypeSpec.Type.Object) + return new NullConstant (type, loc); + + return base.ConvertImplicitly (type); + } } // @@ -2045,7 +2159,7 @@ namespace Mono.CSharp { return base.CreateExpressionTree (ec); } - public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType) + public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType, TypeSpec parameterType) { switch (targetType.BuiltinType) { case BuiltinTypeSpec.Type.Object: @@ -2066,7 +2180,7 @@ namespace Mono.CSharp { break; } - base.EncodeAttributeValue (rc, enc, targetType); + base.EncodeAttributeValue (rc, enc, targetType, parameterType); } public override void Emit (EmitContext ec) @@ -2206,6 +2320,11 @@ namespace Mono.CSharp { } } + public override bool ContainsEmitWithAwait () + { + return side_effect.ContainsEmitWithAwait (); + } + public override object GetValue () { return value.GetValue (); @@ -2233,6 +2352,11 @@ namespace Mono.CSharp { value.EmitSideEffect (ec); } + public override void FlowAnalysis (FlowAnalysisContext fc) + { + side_effect.FlowAnalysis (fc); + } + public override bool IsDefaultValue { get { return value.IsDefaultValue; } } diff --git a/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/context.cs b/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/context.cs index 0e45bd5de..873c92d24 100644 --- a/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/context.cs +++ b/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/context.cs @@ -69,11 +69,12 @@ namespace Mono.CSharp // public class BlockContext : ResolveContext { - FlowBranching current_flow_branching; - readonly TypeSpec return_type; - public int FlowOffset; + // + // Tracks the last offset used by VariableInfo + // + public int AssignmentInfoOffset; public BlockContext (IMemberContext mc, ExplicitBlock block, TypeSpec returnType) : base (mc) @@ -95,108 +96,34 @@ namespace Mono.CSharp if (rc.HasSet (ResolveContext.Options.CheckedScope)) flags |= ResolveContext.Options.CheckedScope; - } - public override FlowBranching CurrentBranching { - get { return current_flow_branching; } - } + if (!rc.ConstantCheckState) + flags &= ~Options.ConstantCheckState; - public TypeSpec ReturnType { - get { return return_type; } - } - - // - // Starts a new code branching. This inherits the state of all local - // variables and parameters from the current branching. - // - public FlowBranching StartFlowBranching (FlowBranching.BranchingType type, Location loc) - { - current_flow_branching = FlowBranching.CreateBranching (CurrentBranching, type, null, loc); - return current_flow_branching; - } - - // - // Starts a new code branching for block `block'. - // - public FlowBranching StartFlowBranching (Block block) - { - Set (Options.DoFlowAnalysis); - - current_flow_branching = FlowBranching.CreateBranching ( - CurrentBranching, FlowBranching.BranchingType.Block, block, block.StartLocation); - return current_flow_branching; - } - - public FlowBranchingTryCatch StartFlowBranching (TryCatch stmt) - { - FlowBranchingTryCatch branching = new FlowBranchingTryCatch (CurrentBranching, stmt); - current_flow_branching = branching; - return branching; - } - - public FlowBranchingTryFinally StartFlowBranching (TryFinallyBlock stmt) - { - FlowBranchingTryFinally branching = new FlowBranchingTryFinally (CurrentBranching, stmt); - current_flow_branching = branching; - return branching; - } + if (rc.IsInProbingMode) + flags |= ResolveContext.Options.ProbingMode; - public FlowBranchingLabeled StartFlowBranching (LabeledStatement stmt) - { - FlowBranchingLabeled branching = new FlowBranchingLabeled (CurrentBranching, stmt); - current_flow_branching = branching; - return branching; - } + if (rc.HasSet (ResolveContext.Options.FieldInitializerScope)) + flags |= ResolveContext.Options.FieldInitializerScope; - public FlowBranchingIterator StartFlowBranching (Iterator iterator, FlowBranching parent) - { - FlowBranchingIterator branching = new FlowBranchingIterator (parent, iterator); - current_flow_branching = branching; - return branching; - } + if (rc.HasSet (ResolveContext.Options.ExpressionTreeConversion)) + flags |= ResolveContext.Options.ExpressionTreeConversion; - public FlowBranchingAsync StartFlowBranching (AsyncInitializer asyncBody, FlowBranching parent) - { - var branching = new FlowBranchingAsync (parent, asyncBody); - current_flow_branching = branching; - return branching; + if (rc.HasSet (ResolveContext.Options.BaseInitializer)) + flags |= ResolveContext.Options.BaseInitializer; } - public FlowBranchingToplevel StartFlowBranching (ParametersBlock stmt, FlowBranching parent) - { - FlowBranchingToplevel branching = new FlowBranchingToplevel (parent, stmt); - current_flow_branching = branching; - return branching; - } + public ExceptionStatement CurrentTryBlock { get; set; } - // - // Ends a code branching. Merges the state of locals and parameters - // from all the children of the ending branching. - // - public bool EndFlowBranching () - { - FlowBranching old = current_flow_branching; - current_flow_branching = current_flow_branching.Parent; + public LoopStatement EnclosingLoop { get; set; } - FlowBranching.UsageVector vector = current_flow_branching.MergeChild (old); - return vector.IsUnreachable; - } + public LoopStatement EnclosingLoopOrSwitch { get; set; } - // - // Kills the current code branching. This throws away any changed state - // information and should only be used in case of an error. - // - // FIXME: this is evil - public void KillFlowBranching () - { - current_flow_branching = current_flow_branching.Parent; - } + public Switch Switch { get; set; } -#if !STATIC - public void NeedReturnLabel () - { + public TypeSpec ReturnType { + get { return return_type; } } -#endif } // @@ -257,16 +184,9 @@ namespace Mono.CSharp LockScope = 1 << 13, - /// - /// Whether control flow analysis is enabled - /// - DoFlowAnalysis = 1 << 20, + TryScope = 1 << 14, - /// - /// Whether control flow analysis is disabled on structs - /// (only meaningful when DoFlowAnalysis is set) - /// - OmitStructFlowAnalysis = 1 << 21, + TryWithCatchScope = 1 << 15, /// /// Indicates the current context is in probing mode, no errors are reported. @@ -291,7 +211,7 @@ namespace Mono.CSharp // it's public so that we can use a struct at the callsite public struct FlagsHandle : IDisposable { - ResolveContext ec; + readonly ResolveContext ec; readonly Options invmask, oldval; public FlagsHandle (ResolveContext ec, Options flagsToSet) @@ -335,11 +255,6 @@ namespace Mono.CSharp public readonly IMemberContext MemberContext; - /// - /// If this is non-null, points to the current switch statement - /// - public Switch Switch; - public ResolveContext (IMemberContext mc) { if (mc == null) @@ -379,10 +294,6 @@ namespace Mono.CSharp } } - public virtual FlowBranching CurrentBranching { - get { return null; } - } - // // The current iterator // @@ -406,10 +317,6 @@ namespace Mono.CSharp get { return (flags & Options.ConstantCheckState) != 0; } } - public bool DoFlowAnalysis { - get { return (flags & Options.DoFlowAnalysis) != 0; } - } - public bool IsInProbingMode { get { return (flags & Options.ProbingMode) != 0; @@ -443,7 +350,7 @@ namespace Mono.CSharp public bool IsVariableCapturingRequired { get { - return !IsInProbingMode && (CurrentBranching == null || !CurrentBranching.CurrentUsageVector.IsUnreachable); + return !IsInProbingMode; } } @@ -453,10 +360,6 @@ namespace Mono.CSharp } } - public bool OmitStructFlowAnalysis { - get { return (flags & Options.OmitStructFlowAnalysis) != 0; } - } - public Report Report { get { return Module.Compiler.Report; @@ -475,14 +378,16 @@ namespace Mono.CSharp // or it's a parameter // if (CurrentAnonymousMethod.IsIterator) - return local.IsParameter || CurrentBlock.Explicit.HasYield; + return local.IsParameter || local.Block.Explicit.HasYield; // // Capture only if this or any of child blocks contain await - // or it's a parameter + // or it's a parameter or we need to access variable from + // different parameter block // if (CurrentAnonymousMethod is AsyncInitializer) - return local.IsParameter || CurrentBlock.Explicit.HasAwait; + return local.IsParameter || local.Block.Explicit.HasAwait || CurrentBlock.Explicit.HasAwait || + local.Block.ParametersBlock != CurrentBlock.ParametersBlock.Original; return local.Block.ParametersBlock != CurrentBlock.ParametersBlock.Original; } @@ -534,6 +439,72 @@ namespace Mono.CSharp #endregion } + public class FlowAnalysisContext + { + readonly CompilerContext ctx; + + public FlowAnalysisContext (CompilerContext ctx, ParametersBlock parametersBlock, int definiteAssignmentLength) + { + this.ctx = ctx; + this.ParametersBlock = parametersBlock; + + DefiniteAssignment = definiteAssignmentLength == 0 ? + DefiniteAssignmentBitSet.Empty : + new DefiniteAssignmentBitSet (definiteAssignmentLength); + } + + public DefiniteAssignmentBitSet DefiniteAssignment { get; set; } + + public DefiniteAssignmentBitSet DefiniteAssignmentOnTrue { get; set; } + + public DefiniteAssignmentBitSet DefiniteAssignmentOnFalse { get; set; } + + public List LabelStack { get; set; } + + public ParametersBlock ParametersBlock { get; set; } + + public Report Report { + get { + return ctx.Report; + } + } + + public DefiniteAssignmentBitSet SwitchInitialDefinitiveAssignment { get; set; } + + public TryFinally TryFinally { get; set; } + + public bool UnreachableReported { get; set; } + + public DefiniteAssignmentBitSet BranchDefiniteAssignment () + { + var dat = DefiniteAssignment; + if (dat != DefiniteAssignmentBitSet.Empty) + DefiniteAssignment = new DefiniteAssignmentBitSet (dat); + return dat; + } + + public bool IsDefinitelyAssigned (VariableInfo variable) + { + return variable.IsAssigned (DefiniteAssignment); + } + + public bool IsStructFieldDefinitelyAssigned (VariableInfo variable, string name) + { + return variable.IsStructFieldAssigned (DefiniteAssignment, name); + } + + public void SetVariableAssigned (VariableInfo variable, bool generatedAssignment = false) + { + variable.SetAssigned (DefiniteAssignment, generatedAssignment); + } + + public void SetStructFieldAssigned (VariableInfo variable, string name) + { + variable.SetStructFieldAssigned (DefiniteAssignment, name); + } + } + + // // This class is used during the Statement.Clone operation // to remap objects that have been cloned. @@ -647,8 +618,12 @@ namespace Mono.CSharp string path; if (!Path.IsPathRooted (name)) { - string root = Path.GetDirectoryName (comp_unit.SourceFile.FullPathName); - path = Path.Combine (root, name); + var loc = comp_unit.SourceFile; + string root = Path.GetDirectoryName (loc.FullPathName); + path = Path.GetFullPath (Path.Combine (root, name)); + var dir = Path.GetDirectoryName (loc.Name); + if (!string.IsNullOrEmpty (dir)) + name = Path.Combine (dir, name); } else path = name; @@ -689,14 +664,14 @@ namespace Mono.CSharp ConstructorScope = 1 << 3, - AsyncBody = 1 << 4 + AsyncBody = 1 << 4, } // utility helper for CheckExpr, UnCheckExpr, Checked and Unchecked statements // it's public so that we can use a struct at the callsite public struct FlagsHandle : IDisposable { - BuilderContext ec; + readonly BuilderContext ec; readonly Options invmask, oldval; public FlagsHandle (BuilderContext ec, Options flagsToSet) @@ -748,7 +723,7 @@ namespace Mono.CSharp public LocationsBag LocationsBag { get; set; } public bool UseJayGlobalArrays { get; set; } - public Tokenizer.LocatedToken[] LocatedTokens { get; set; } + public LocatedToken[] LocatedTokens { get; set; } public MD5 GetChecksumAlgorithm () { diff --git a/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/convert.cs b/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/convert.cs index 3020c8814..00be96b40 100644 --- a/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/convert.cs +++ b/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/convert.cs @@ -34,7 +34,7 @@ namespace Mono.CSharp { // static bool ArrayToIList (ArrayContainer array, TypeSpec list, bool isExplicit) { - if (array.Rank != 1 || !list.IsGenericIterateInterface) + if (array.Rank != 1 || !list.IsArrayGenericInterface) return false; var arg_type = list.TypeArguments[0]; @@ -55,7 +55,7 @@ namespace Mono.CSharp { static bool IList_To_Array(TypeSpec list, ArrayContainer array) { - if (array.Rank != 1 || !list.IsGenericIterateInterface) + if (array.Rank != 1 || !list.IsArrayGenericInterface) return false; var arg_type = list.TypeArguments[0]; @@ -71,19 +71,14 @@ namespace Mono.CSharp { // From T to a type parameter U, provided T depends on U // if (target_type.IsGenericParameter) { - if (expr_type.TypeArguments != null) { - foreach (var targ in expr_type.TypeArguments) { - if (!TypeSpecComparer.Override.IsEqual (target_type, targ)) - continue; - - if (expr == null) - return EmptyExpression.Null; + if (expr_type.TypeArguments != null && expr_type.HasDependencyOn (target_type)) { + if (expr == null) + return EmptyExpression.Null; - if (expr_type.IsReferenceType && !((TypeParameterSpec)target_type).IsReferenceType) - return new BoxedCast (expr, target_type); + if (expr_type.IsReferenceType && !((TypeParameterSpec) target_type).IsReferenceType) + return new BoxedCast (expr, target_type); - return new ClassCast (expr, target_type); - } + return new ClassCast (expr, target_type); } return null; @@ -131,38 +126,39 @@ namespace Mono.CSharp { return null; } - static Expression ExplicitTypeParameterConversion (Expression source, TypeSpec source_type, TypeSpec target_type) + static Expression ExplicitTypeParameterConversionFromT (Expression source, TypeSpec source_type, TypeSpec target_type) { var target_tp = target_type as TypeParameterSpec; if (target_tp != null) { - if (target_tp.TypeArguments != null) { - foreach (var targ in target_tp.TypeArguments) { - if (!TypeSpecComparer.Override.IsEqual (source_type, targ)) - continue; - - return source == null ? EmptyExpression.Null : new ClassCast (source, target_type); - } - } -/* - if (target_tp.Interfaces != null) { - foreach (TypeSpec iface in target_tp.Interfaces) { - if (!TypeManager.IsGenericParameter (iface)) - continue; - - if (TypeManager.IsSubclassOf (source_type, iface)) - return source == null ? EmptyExpression.Null : new ClassCast (source, target_type, true); - } + // + // From a type parameter U to T, provided T depends on U + // + if (target_tp.TypeArguments != null && target_tp.HasDependencyOn (source_type)) { + return source == null ? EmptyExpression.Null : new ClassCast (source, target_type); } -*/ - return null; } + // + // From T to any interface-type I provided there is not already an implicit conversion from T to I + // if (target_type.IsInterface) return source == null ? EmptyExpression.Null : new ClassCast (source, target_type, true); return null; } + static Expression ExplicitTypeParameterConversionToT (Expression source, TypeSpec source_type, TypeParameterSpec target_type) + { + // + // From the effective base class C of T to T and from any base class of C to T + // + var effective = target_type.GetEffectiveBase (); + if (TypeSpecComparer.IsEqual (effective, source_type) || TypeSpec.IsBaseClass (effective, source_type, false)) + return source == null ? EmptyExpression.Null : new ClassCast (source, target_type); + + return null; + } + public static Expression ImplicitReferenceConversion (Expression expr, TypeSpec target_type, bool explicit_cast) { TypeSpec expr_type = expr.Type; @@ -479,7 +475,7 @@ namespace Mono.CSharp { } if (expr_type != expr.Type) - return new Nullable.Lifted (conv, unwrap, target_type).Resolve (ec); + return new Nullable.LiftedConversion (conv, unwrap, target_type).Resolve (ec); return Nullable.Wrap.Create (conv, target_type); } @@ -704,7 +700,7 @@ namespace Mono.CSharp { if (expr.Type == InternalType.Arglist) return target_type == ec.Module.PredefinedTypes.ArgIterator.TypeSpec; - return ImplicitUserConversion (ec, expr, target_type, Location.Null) != null; + return UserDefinedConversion (ec, expr, target_type, true, true, Location.Null) != null; } // @@ -917,17 +913,20 @@ namespace Mono.CSharp { // static TypeSpec FindMostSpecificSource (List list, TypeSpec sourceType, Expression source, bool apply_explicit_conv_rules) { - var src_types_set = new TypeSpec [list.Count]; + TypeSpec[] src_types_set = null; // // Try exact match first, if any operator converts from S then Sx = S // - for (int i = 0; i < src_types_set.Length; ++i) { + for (int i = 0; i < list.Count; ++i) { TypeSpec param_type = list [i].Parameters.Types [0]; if (param_type == sourceType) return param_type; + if (src_types_set == null) + src_types_set = new TypeSpec [list.Count]; + src_types_set [i] = param_type; } @@ -961,7 +960,7 @@ namespace Mono.CSharp { static public TypeSpec FindMostSpecificTarget (IList list, TypeSpec target, bool apply_explicit_conv_rules) { - var tgt_types_set = new List (); + List tgt_types_set = null; // // If any operator converts to T then Tx = T @@ -971,6 +970,12 @@ namespace Mono.CSharp { if (ret_type == target) return ret_type; + if (tgt_types_set == null) { + tgt_types_set = new List (list.Count); + } else if (tgt_types_set.Contains (ret_type)) { + continue; + } + tgt_types_set.Add (ret_type); } @@ -1005,7 +1010,7 @@ namespace Mono.CSharp { /// static public Expression ImplicitUserConversion (ResolveContext ec, Expression source, TypeSpec target, Location loc) { - return UserDefinedConversion (ec, source, target, true, loc); + return UserDefinedConversion (ec, source, target, true, false, loc); } /// @@ -1013,7 +1018,7 @@ namespace Mono.CSharp { /// static Expression ExplicitUserConversion (ResolveContext ec, Expression source, TypeSpec target, Location loc) { - return UserDefinedConversion (ec, source, target, false, loc); + return UserDefinedConversion (ec, source, target, false, false, loc); } static void FindApplicableUserDefinedConversionOperators (IList operators, Expression source, TypeSpec target, bool implicitOnly, ref List candidates) @@ -1077,7 +1082,7 @@ namespace Mono.CSharp { // // User-defined conversions // - static Expression UserDefinedConversion (ResolveContext ec, Expression source, TypeSpec target, bool implicitOnly, Location loc) + static Expression UserDefinedConversion (ResolveContext ec, Expression source, TypeSpec target, bool implicitOnly, bool probingOnly, Location loc) { List candidates = null; @@ -1088,14 +1093,17 @@ namespace Mono.CSharp { TypeSpec source_type = source.Type; TypeSpec target_type = target; Expression source_type_expr; + bool nullable_source = false; if (source_type.IsNullableType) { - // No implicit conversion S? -> T for non-reference types - if (implicitOnly && !TypeSpec.IsReferenceType (target_type) && !target_type.IsNullableType) - return null; - - source_type_expr = Nullable.Unwrap.Create (source); - source_type = source_type_expr.Type; + // No unwrapping conversion S? -> T for non-reference types + if (implicitOnly && !TypeSpec.IsReferenceType (target_type) && !target_type.IsNullableType) { + source_type_expr = source; + } else { + source_type_expr = Nullable.Unwrap.CreateUnwrapped (source); + source_type = source_type_expr.Type; + nullable_source = true; + } } else { source_type_expr = source; } @@ -1172,19 +1180,24 @@ namespace Mono.CSharp { } if (most_specific_operator == null) { - MethodSpec ambig_arg = null; - foreach (var candidate in candidates) { - if (candidate.ReturnType == t_x) - most_specific_operator = candidate; - else if (candidate.Parameters.Types[0] == s_x) - ambig_arg = candidate; + // + // Unless running in probing more + // + if (!probingOnly) { + MethodSpec ambig_arg = null; + foreach (var candidate in candidates) { + if (candidate.ReturnType == t_x) + most_specific_operator = candidate; + else if (candidate.Parameters.Types[0] == s_x) + ambig_arg = candidate; + } + + ec.Report.Error (457, loc, + "Ambiguous user defined operators `{0}' and `{1}' when converting from `{2}' to `{3}'", + ambig_arg.GetSignatureForError (), most_specific_operator.GetSignatureForError (), + source.Type.GetSignatureForError (), target.GetSignatureForError ()); } - ec.Report.Error (457, loc, - "Ambiguous user defined operators `{0}' and `{1}' when converting from `{2}' to `{3}'", - ambig_arg.GetSignatureForError (), most_specific_operator.GetSignatureForError (), - source.Type.GetSignatureForError (), target.GetSignatureForError ()); - return ErrorExpression.Instance; } } @@ -1195,8 +1208,12 @@ namespace Mono.CSharp { if (s_x != source_type) { var c = source as Constant; if (c != null) { - source = c.TryReduce (ec, s_x); - } else { + source = c.Reduce (ec, s_x); + if (source == null) + c = null; + } + + if (c == null) { source = implicitOnly ? ImplicitConversionStandard (ec, source_type_expr, s_x, loc) : ExplicitConversionStandard (ec, source_type_expr, s_x, loc); @@ -1212,26 +1229,49 @@ namespace Mono.CSharp { // if (t_x != target_type) { // - // User operator is of T?, no need to lift it + // User operator is of T? // - if (t_x == target && t_x.IsNullableType) - return source; + if (t_x.IsNullableType && (target.IsNullableType || !implicitOnly)) { + // + // User operator return type does not match target type we need + // yet another conversion. This should happen for promoted numeric + // types only + // + if (t_x != target) { + var unwrap = Nullable.Unwrap.CreateUnwrapped (source); - source = implicitOnly ? - ImplicitConversionStandard (ec, source, target_type, loc) : - ExplicitConversionStandard (ec, source, target_type, loc); + source = implicitOnly ? + ImplicitConversionStandard (ec, unwrap, target_type, loc) : + ExplicitConversionStandard (ec, unwrap, target_type, loc); - if (source == null) - return null; + if (source == null) + return null; + + if (target.IsNullableType) + source = new Nullable.LiftedConversion (source, unwrap, target).Resolve (ec); + } + } else { + source = implicitOnly ? + ImplicitConversionStandard (ec, source, target_type, loc) : + ExplicitConversionStandard (ec, source, target_type, loc); + + if (source == null) + return null; + } } + + // + // Source expression is of nullable type and underlying conversion returns + // only non-nullable type we need to lift it manually + // + if (nullable_source && !s_x.IsNullableType) + return new Nullable.LiftedConversion (source, source_type_expr, target).Resolve (ec); + // - // Source expression is of nullable type, lift the result in the case it's null and - // not nullable/lifted user operator is used + // Target is of nullable type but source type is not, wrap the result expression // - if (source_type_expr is Nullable.Unwrap && !s_x.IsNullableType && (TypeSpec.IsReferenceType (target) || target_type != target)) - source = new Nullable.Lifted (source, source_type_expr, target).Resolve (ec); - else if (target_type != target) + if (target.IsNullableType && !t_x.IsNullableType) source = Nullable.Wrap.Create (source, target); return source; @@ -1291,8 +1331,7 @@ namespace Mono.CSharp { if (ec.Module.Compiler.Settings.Version != LanguageVersion.ISO_1){ MethodGroupExpr mg = expr as MethodGroupExpr; if (mg != null) - return ImplicitDelegateCreation.Create ( - ec, mg, target_type, loc); + return new ImplicitDelegateCreation (target_type, mg, loc).Resolve (ec); } } @@ -1370,25 +1409,23 @@ namespace Mono.CSharp { } } - if (ec.IsUnsafe) { - var target_pc = target_type as PointerContainer; - if (target_pc != null) { - if (expr_type.IsPointer) { - // - // Pointer types are same when they have same element types - // - if (expr_type == target_pc) - return expr; + var target_pc = target_type as PointerContainer; + if (target_pc != null) { + if (expr_type.IsPointer) { + // + // Pointer types are same when they have same element types + // + if (expr_type == target_pc) + return expr; - if (target_pc.Element.Kind == MemberKind.Void) - return EmptyCast.Create (expr, target_type); + if (target_pc.Element.Kind == MemberKind.Void) + return EmptyCast.Create (expr, target_type); //return null; - } - - if (expr_type == InternalType.NullLiteral) - return new NullPointer (target_type, loc); } + + if (expr_type == InternalType.NullLiteral) + return new NullPointer (target_type, loc); } if (expr_type == InternalType.AnonymousMethod){ @@ -1396,6 +1433,9 @@ namespace Mono.CSharp { Expression am = ame.Compatible (ec, target_type); if (am != null) return am.Resolve (ec); + + // Avoid CS1503 after CS1661 + return ErrorExpression.Instance; } if (expr_type == InternalType.Arglist && target_type == ec.Module.PredefinedTypes.ArgIterator.TypeSpec) @@ -1423,6 +1463,7 @@ namespace Mono.CSharp { return e; source.Error_ValueCannotBeConverted (ec, target_type, false); + return null; } @@ -1776,10 +1817,10 @@ namespace Mono.CSharp { return source == null ? EmptyExpression.Null : new UnboxCast (source, target_type); // - // Explicit type parameter conversion. + // Explicit type parameter conversion from T // if (source_type.Kind == MemberKind.TypeParameter) - return ExplicitTypeParameterConversion (source, source_type, target_type); + return ExplicitTypeParameterConversionFromT (source, source_type, target_type); bool target_is_value_type = target_type.Kind == MemberKind.Struct || target_type.Kind == MemberKind.Enum; @@ -1813,6 +1854,9 @@ namespace Mono.CSharp { // From any interface-type S to to any class type T, provided T is not // sealed, or provided T implements S. // + // This also covers Explicit conversions involving type parameters + // section From any interface type to T + // if (source_type.Kind == MemberKind.Interface) { if (!target_type.IsSealed || target_type.ImplementsInterface (source_type, true)) { if (source == null) @@ -1857,10 +1901,23 @@ namespace Mono.CSharp { if (source_array.Rank == target_array.Rank) { source_type = source_array.Element; - if (!TypeSpec.IsReferenceType (source_type)) - return null; - var target_element = target_array.Element; + + // + // LAMESPEC: Type parameters are special cased somehow but + // only when both source and target elements are type parameters + // + if ((source_type.Kind & target_element.Kind & MemberKind.TypeParameter) == MemberKind.TypeParameter) { + // + // Conversion is allowed unless source element type has struct constrain + // + if (TypeSpec.IsValueType (source_type)) + return null; + } else { + if (!TypeSpec.IsReferenceType (source_type)) + return null; + } + if (!TypeSpec.IsReferenceType (target_element)) return null; @@ -1935,6 +1992,10 @@ namespace Mono.CSharp { return source == null ? EmptyExpression.Null : new ClassCast (source, target_type); } + var tps = target_type as TypeParameterSpec; + if (tps != null) + return ExplicitTypeParameterConversionToT (source, source_type, tps); + return null; } @@ -1985,21 +2046,28 @@ namespace Mono.CSharp { if (expr_type == real_target) return EmptyCast.Create (expr, target_type); - ne = ImplicitNumericConversion (expr, real_target); - if (ne != null) - return EmptyCast.Create (ne, target_type); - - ne = ExplicitNumericConversion (ec, expr, real_target); - if (ne != null) - return EmptyCast.Create (ne, target_type); + Constant c = expr as Constant; + if (c != null) { + c = c.TryReduce (ec, real_target); + if (c != null) + return c; + } else { + ne = ImplicitNumericConversion (expr, real_target); + if (ne != null) + return EmptyCast.Create (ne, target_type); - // - // LAMESPEC: IntPtr and UIntPtr conversion to any Enum is allowed - // - if (expr_type.BuiltinType == BuiltinTypeSpec.Type.IntPtr || expr_type.BuiltinType == BuiltinTypeSpec.Type.UIntPtr) { - ne = ExplicitUserConversion (ec, expr, real_target, loc); + ne = ExplicitNumericConversion (ec, expr, real_target); if (ne != null) - return ExplicitConversionCore (ec, ne, target_type, loc); + return EmptyCast.Create (ne, target_type); + + // + // LAMESPEC: IntPtr and UIntPtr conversion to any Enum is allowed + // + if (expr_type.BuiltinType == BuiltinTypeSpec.Type.IntPtr || expr_type.BuiltinType == BuiltinTypeSpec.Type.UIntPtr) { + ne = ExplicitUserConversion (ec, expr, real_target, loc); + if (ne != null) + return ExplicitConversionCore (ec, ne, target_type, loc); + } } } else { ne = ExplicitNumericConversion (ec, expr, target_type); @@ -2140,7 +2208,7 @@ namespace Mono.CSharp { if (e == null) return null; - return new Nullable.Lifted (e, unwrap, target_type).Resolve (ec); + return new Nullable.LiftedConversion (e, unwrap, target_type).Resolve (ec); } if (expr_type.BuiltinType == BuiltinTypeSpec.Type.Object) { return new UnboxCast (expr, target_type); @@ -2149,7 +2217,7 @@ namespace Mono.CSharp { target = TypeManager.GetTypeArguments (target_type) [0]; e = ExplicitConversionCore (ec, expr, target, loc); if (e != null) - return Nullable.Wrap.Create (e, target_type); + return TypeSpec.IsReferenceType (expr.Type) ? new UnboxCast (expr, target_type) : Nullable.Wrap.Create (e, target_type); } else if (expr_type.IsNullableType) { e = ImplicitBoxingConversion (expr, Nullable.NullableInfo.GetUnderlyingType (expr_type), target_type); if (e != null) diff --git a/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/cs-parser.cs b/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/cs-parser.cs index b9491273a..64b8c1f09 100644 --- a/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/cs-parser.cs +++ b/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/cs-parser.cs @@ -37,7 +37,8 @@ namespace Mono.CSharp Arglist = 1 << 5, DefaultValue = 1 << 6, - All = Ref | Out | This | Params | Arglist | DefaultValue + All = Ref | Out | This | Params | Arglist | DefaultValue, + PrimaryConstructor = Ref | Out | Params | DefaultValue } static readonly object ModifierNone = 0; @@ -56,7 +57,7 @@ namespace Mono.CSharp /// Block current_block; - BlockVariableDeclaration current_variable; + BlockVariable current_variable; Delegate current_delegate; @@ -118,6 +119,8 @@ namespace Mono.CSharp // Keeps track of global data changes to undo on parser error // public Undo undo; + + bool? interactive_async; Stack linq_clause_blocks; @@ -139,24 +142,17 @@ namespace Mono.CSharp // // Full AST support members // - readonly LocationsBag lbag; - - public LocationsBag LocationsBag { - get { - return lbag; - } - } - + LocationsBag lbag; List> mod_locations; - Location parameterModifierLocation, savedLocation, savedOpenLocation, savedCloseLocation; + Location parameterModifierLocation, savedLocation, savedEventAssignLocation; Location savedAttrParenOpenLocation, savedAttrParenCloseLocation, savedOperatorLocation; Stack> locationListStack = new Stack> (); // used for type parameters Stack opt_intoStack = new Stack (); bool HadAttributeParens; - List attributeCommas = new List (); List attributeArgumentCommas = new List (); List parameterListCommas = new List (); + Stack location_stack; #line default /** error output stream. @@ -222,7 +218,11 @@ namespace Mono.CSharp //t "using_namespace : USING error", //t "$$2 :", //t "$$3 :", -//t "namespace_declaration : opt_attributes NAMESPACE namespace_name $$2 OPEN_BRACE $$3 opt_extern_alias_directives opt_using_directives opt_namespace_or_type_declarations CLOSE_BRACE opt_semicolon", +//t "namespace_declaration : opt_attributes NAMESPACE namespace_name $$2 OPEN_BRACE $$3 opt_extern_alias_directives opt_using_directives opt_namespace_or_type_declarations CLOSE_BRACE opt_semicolon_error", +//t "namespace_declaration : opt_attributes NAMESPACE namespace_name", +//t "opt_semicolon_error :", +//t "opt_semicolon_error : SEMICOLON", +//t "opt_semicolon_error : error", //t "namespace_name : IDENTIFIER", //t "namespace_name : namespace_name DOT IDENTIFIER", //t "namespace_name : error", @@ -255,10 +255,11 @@ namespace Mono.CSharp //t "$$5 :", //t "attribute_section_cont : attribute_target COLON $$5 attribute_list opt_comma CLOSE_BRACKET", //t "attribute_section_cont : attribute_list opt_comma CLOSE_BRACKET", +//t "attribute_section_cont : IDENTIFIER error", +//t "attribute_section_cont : error", //t "attribute_target : IDENTIFIER", //t "attribute_target : EVENT", //t "attribute_target : RETURN", -//t "attribute_target : error", //t "attribute_list : attribute", //t "attribute_list : attribute_list COMMA attribute", //t "$$6 :", @@ -273,9 +274,10 @@ namespace Mono.CSharp //t "attribute_arguments : attribute_arguments COMMA named_attribute_argument", //t "positional_or_named_argument : expression", //t "positional_or_named_argument : named_argument", +//t "positional_or_named_argument : error", //t "$$7 :", //t "named_attribute_argument : IDENTIFIER ASSIGN $$7 expression", -//t "named_argument : identifier_inside_body COLON opt_named_modifier expression", +//t "named_argument : identifier_inside_body COLON opt_named_modifier expression_or_error", //t "opt_named_modifier :", //t "opt_named_modifier : REF", //t "opt_named_modifier : OUT", @@ -294,16 +296,18 @@ namespace Mono.CSharp //t "class_member_declaration : destructor_declaration", //t "class_member_declaration : type_declaration", //t "class_member_declaration : attributes_without_members", +//t "class_member_declaration : incomplete_member", //t "class_member_declaration : error", //t "$$8 :", //t "$$9 :", //t "$$10 :", //t "$$11 :", //t "$$12 :", -//t "struct_declaration : opt_attributes opt_modifiers opt_partial STRUCT $$8 type_declaration_name $$9 opt_class_base opt_type_parameter_constraints_clauses $$10 OPEN_BRACE $$11 opt_class_member_declarations CLOSE_BRACE $$12 opt_semicolon", +//t "struct_declaration : opt_attributes opt_modifiers opt_partial STRUCT $$8 type_declaration_name $$9 opt_primary_parameters opt_class_base opt_type_parameter_constraints_clauses $$10 OPEN_BRACE $$11 opt_class_member_declarations CLOSE_BRACE $$12 opt_semicolon", //t "struct_declaration : opt_attributes opt_modifiers opt_partial STRUCT error", //t "$$13 :", //t "constant_declaration : opt_attributes opt_modifiers CONST type IDENTIFIER $$13 constant_initializer opt_constant_declarators SEMICOLON", +//t "constant_declaration : opt_attributes opt_modifiers CONST type error", //t "opt_constant_declarators :", //t "opt_constant_declarators : constant_declarators", //t "constant_declarators : constant_declarator", @@ -367,12 +371,12 @@ namespace Mono.CSharp //t "formal_parameter_list : error", //t "fixed_parameters : fixed_parameter", //t "fixed_parameters : fixed_parameters COMMA fixed_parameter", -//t "fixed_parameter : opt_attributes opt_parameter_modifier parameter_type IDENTIFIER", -//t "fixed_parameter : opt_attributes opt_parameter_modifier parameter_type IDENTIFIER OPEN_BRACKET CLOSE_BRACKET", +//t "fixed_parameter : opt_attributes opt_parameter_modifier parameter_type identifier_inside_body", +//t "fixed_parameter : opt_attributes opt_parameter_modifier parameter_type identifier_inside_body OPEN_BRACKET CLOSE_BRACKET", //t "fixed_parameter : attribute_sections error", //t "fixed_parameter : opt_attributes opt_parameter_modifier parameter_type error", //t "$$26 :", -//t "fixed_parameter : opt_attributes opt_parameter_modifier parameter_type IDENTIFIER ASSIGN $$26 constant_expression", +//t "fixed_parameter : opt_attributes opt_parameter_modifier parameter_type identifier_inside_body ASSIGN $$26 constant_expression", //t "opt_parameter_modifier :", //t "opt_parameter_modifier : parameter_modifiers", //t "parameter_modifiers : parameter_modifier", @@ -394,7 +398,7 @@ namespace Mono.CSharp //t "$$30 :", //t "$$31 :", //t "$$32 :", -//t "indexer_declaration : opt_attributes opt_modifiers member_type indexer_declaration_name OPEN_BRACKET $$30 opt_formal_parameter_list CLOSE_BRACKET OPEN_BRACE $$31 accessor_declarations $$32 CLOSE_BRACE", +//t "indexer_declaration : opt_attributes opt_modifiers member_type indexer_declaration_name OPEN_BRACKET $$30 opt_formal_parameter_list CLOSE_BRACKET $$31 OPEN_BRACE accessor_declarations $$32 CLOSE_BRACE", //t "accessor_declarations : get_accessor_declaration", //t "accessor_declarations : get_accessor_declaration accessor_declarations", //t "accessor_declarations : set_accessor_declaration", @@ -484,6 +488,7 @@ namespace Mono.CSharp //t "$$49 :", //t "$$50 :", //t "event_declaration : opt_attributes opt_modifiers EVENT type member_declaration_name OPEN_BRACE $$49 event_accessor_declarations $$50 CLOSE_BRACE", +//t "event_declaration : opt_attributes opt_modifiers EVENT type error", //t "opt_event_initializer :", //t "$$51 :", //t "opt_event_initializer : ASSIGN $$51 event_variable_initializer", @@ -508,6 +513,7 @@ namespace Mono.CSharp //t "event_accessor_block : opt_semicolon", //t "event_accessor_block : block", //t "attributes_without_members : attribute_sections CLOSE_BRACE", +//t "incomplete_member : opt_attributes opt_modifiers member_type CLOSE_BRACE", //t "$$56 :", //t "$$57 :", //t "$$58 :", @@ -626,16 +632,18 @@ namespace Mono.CSharp //t "close_parens : COMPLETE_COMPLETION", //t "parenthesized_expression : OPEN_PARENS expression CLOSE_PARENS", //t "parenthesized_expression : OPEN_PARENS expression COMPLETE_COMPLETION", -//t "member_access : primary_expression DOT IDENTIFIER opt_type_argument_list", -//t "member_access : builtin_types DOT IDENTIFIER opt_type_argument_list", -//t "member_access : BASE DOT IDENTIFIER opt_type_argument_list", -//t "member_access : qualified_alias_member IDENTIFIER opt_type_argument_list", +//t "member_access : primary_expression DOT identifier_inside_body opt_type_argument_list", +//t "member_access : builtin_types DOT identifier_inside_body opt_type_argument_list", +//t "member_access : BASE DOT identifier_inside_body opt_type_argument_list", +//t "member_access : AWAIT DOT identifier_inside_body opt_type_argument_list", +//t "member_access : qualified_alias_member identifier_inside_body opt_type_argument_list", //t "member_access : primary_expression DOT GENERATE_COMPLETION", //t "member_access : primary_expression DOT IDENTIFIER GENERATE_COMPLETION", //t "member_access : builtin_types DOT GENERATE_COMPLETION", //t "member_access : builtin_types DOT IDENTIFIER GENERATE_COMPLETION", //t "invocation_expression : primary_expression open_parens_any opt_argument_list close_parens", //t "invocation_expression : primary_expression open_parens_any argument_list error", +//t "invocation_expression : primary_expression open_parens_any error", //t "opt_object_or_collection_initializer :", //t "opt_object_or_collection_initializer : object_or_collection_initializer", //t "object_or_collection_initializer : OPEN_BRACE opt_member_initializer_list close_brace_or_complete_completion", @@ -646,6 +654,7 @@ namespace Mono.CSharp //t "member_initializer_list : member_initializer_list COMMA member_initializer", //t "member_initializer_list : member_initializer_list error", //t "member_initializer : IDENTIFIER ASSIGN initializer_value", +//t "member_initializer : AWAIT ASSIGN initializer_value", //t "member_initializer : GENERATE_COMPLETION", //t "member_initializer : non_assignment_expression opt_COMPLETE_COMPLETION", //t "member_initializer : OPEN_BRACE expression_list CLOSE_BRACE", @@ -671,9 +680,8 @@ namespace Mono.CSharp //t "element_access : primary_expression OPEN_BRACKET_EXPR expression_list_arguments CLOSE_BRACKET", //t "element_access : primary_expression OPEN_BRACKET_EXPR expression_list_arguments error", //t "element_access : primary_expression OPEN_BRACKET_EXPR error", -//t "expression_list : expression", -//t "expression_list : expression_list COMMA expression", -//t "expression_list : expression_list error", +//t "expression_list : expression_or_error", +//t "expression_list : expression_list COMMA expression_or_error", //t "expression_list_arguments : expression_list_argument", //t "expression_list_arguments : expression_list_arguments COMMA expression_list_argument", //t "expression_list_argument : expression", @@ -693,14 +701,17 @@ namespace Mono.CSharp //t "$$64 :", //t "new_expr_type : $$64 simple_type", //t "anonymous_type_expression : NEW OPEN_BRACE anonymous_type_parameters_opt_comma CLOSE_BRACE", +//t "anonymous_type_expression : NEW OPEN_BRACE GENERATE_COMPLETION", //t "anonymous_type_parameters_opt_comma : anonymous_type_parameters_opt", //t "anonymous_type_parameters_opt_comma : anonymous_type_parameters COMMA", //t "anonymous_type_parameters_opt :", //t "anonymous_type_parameters_opt : anonymous_type_parameters", //t "anonymous_type_parameters : anonymous_type_parameter", //t "anonymous_type_parameters : anonymous_type_parameters COMMA anonymous_type_parameter", -//t "anonymous_type_parameter : IDENTIFIER ASSIGN variable_initializer", -//t "anonymous_type_parameter : IDENTIFIER", +//t "anonymous_type_parameters : COMPLETE_COMPLETION", +//t "anonymous_type_parameters : anonymous_type_parameter COMPLETE_COMPLETION", +//t "anonymous_type_parameter : identifier_inside_body ASSIGN variable_initializer", +//t "anonymous_type_parameter : identifier_inside_body", //t "anonymous_type_parameter : member_access", //t "anonymous_type_parameter : error", //t "opt_rank_specifier :", @@ -730,8 +741,11 @@ namespace Mono.CSharp //t "generic_dimension : GENERIC_DIMENSION", //t "qualified_alias_member : IDENTIFIER DOUBLE_COLON", //t "sizeof_expression : SIZEOF open_parens_any type CLOSE_PARENS", +//t "sizeof_expression : SIZEOF open_parens_any type error", //t "checked_expression : CHECKED open_parens_any expression CLOSE_PARENS", +//t "checked_expression : CHECKED error", //t "unchecked_expression : UNCHECKED open_parens_any expression CLOSE_PARENS", +//t "unchecked_expression : UNCHECKED error", //t "pointer_member_access : primary_expression OP_PTR IDENTIFIER opt_type_argument_list", //t "$$66 :", //t "anonymous_method_expression : DELEGATE opt_anonymous_method_signature $$66 block", @@ -747,6 +761,10 @@ namespace Mono.CSharp //t "unary_expression : TILDE prefixed_unary_expression", //t "unary_expression : OPEN_PARENS_CAST type CLOSE_PARENS prefixed_unary_expression", //t "unary_expression : AWAIT prefixed_unary_expression", +//t "unary_expression : BANG error", +//t "unary_expression : TILDE error", +//t "unary_expression : OPEN_PARENS_CAST type CLOSE_PARENS error", +//t "unary_expression : AWAIT error", //t "prefixed_unary_expression : unary_expression", //t "prefixed_unary_expression : PLUS prefixed_unary_expression", //t "prefixed_unary_expression : MINUS prefixed_unary_expression", @@ -754,41 +772,71 @@ namespace Mono.CSharp //t "prefixed_unary_expression : OP_DEC prefixed_unary_expression", //t "prefixed_unary_expression : STAR prefixed_unary_expression", //t "prefixed_unary_expression : BITWISE_AND prefixed_unary_expression", +//t "prefixed_unary_expression : PLUS error", +//t "prefixed_unary_expression : MINUS error", +//t "prefixed_unary_expression : OP_INC error", +//t "prefixed_unary_expression : OP_DEC error", +//t "prefixed_unary_expression : STAR error", +//t "prefixed_unary_expression : BITWISE_AND error", //t "multiplicative_expression : prefixed_unary_expression", //t "multiplicative_expression : multiplicative_expression STAR prefixed_unary_expression", //t "multiplicative_expression : multiplicative_expression DIV prefixed_unary_expression", //t "multiplicative_expression : multiplicative_expression PERCENT prefixed_unary_expression", +//t "multiplicative_expression : multiplicative_expression STAR error", +//t "multiplicative_expression : multiplicative_expression DIV error", +//t "multiplicative_expression : multiplicative_expression PERCENT error", //t "additive_expression : multiplicative_expression", //t "additive_expression : additive_expression PLUS multiplicative_expression", //t "additive_expression : additive_expression MINUS multiplicative_expression", //t "additive_expression : additive_expression AS type", //t "additive_expression : additive_expression IS type", +//t "additive_expression : additive_expression PLUS error", +//t "additive_expression : additive_expression MINUS error", +//t "additive_expression : additive_expression AS error", +//t "additive_expression : additive_expression IS error", +//t "additive_expression : AWAIT IS type", +//t "additive_expression : AWAIT AS type", //t "shift_expression : additive_expression", //t "shift_expression : shift_expression OP_SHIFT_LEFT additive_expression", //t "shift_expression : shift_expression OP_SHIFT_RIGHT additive_expression", +//t "shift_expression : shift_expression OP_SHIFT_LEFT error", +//t "shift_expression : shift_expression OP_SHIFT_RIGHT error", //t "relational_expression : shift_expression", //t "relational_expression : relational_expression OP_LT shift_expression", //t "relational_expression : relational_expression OP_GT shift_expression", //t "relational_expression : relational_expression OP_LE shift_expression", //t "relational_expression : relational_expression OP_GE shift_expression", +//t "relational_expression : relational_expression OP_LT error", +//t "relational_expression : relational_expression OP_GT error", +//t "relational_expression : relational_expression OP_LE error", +//t "relational_expression : relational_expression OP_GE error", //t "equality_expression : relational_expression", //t "equality_expression : equality_expression OP_EQ relational_expression", //t "equality_expression : equality_expression OP_NE relational_expression", +//t "equality_expression : equality_expression OP_EQ error", +//t "equality_expression : equality_expression OP_NE error", //t "and_expression : equality_expression", //t "and_expression : and_expression BITWISE_AND equality_expression", +//t "and_expression : and_expression BITWISE_AND error", //t "exclusive_or_expression : and_expression", //t "exclusive_or_expression : exclusive_or_expression CARRET and_expression", +//t "exclusive_or_expression : exclusive_or_expression CARRET error", //t "inclusive_or_expression : exclusive_or_expression", //t "inclusive_or_expression : inclusive_or_expression BITWISE_OR exclusive_or_expression", +//t "inclusive_or_expression : inclusive_or_expression BITWISE_OR error", //t "conditional_and_expression : inclusive_or_expression", //t "conditional_and_expression : conditional_and_expression OP_AND inclusive_or_expression", +//t "conditional_and_expression : conditional_and_expression OP_AND error", //t "conditional_or_expression : conditional_and_expression", //t "conditional_or_expression : conditional_or_expression OP_OR conditional_and_expression", +//t "conditional_or_expression : conditional_or_expression OP_OR error", //t "null_coalescing_expression : conditional_or_expression", //t "null_coalescing_expression : conditional_or_expression OP_COALESCING null_coalescing_expression", //t "conditional_expression : null_coalescing_expression", -//t "conditional_expression : null_coalescing_expression INTERR expression COLON expression_or_error", +//t "conditional_expression : null_coalescing_expression INTERR expression COLON expression", //t "conditional_expression : null_coalescing_expression INTERR expression error", +//t "conditional_expression : null_coalescing_expression INTERR expression COLON error", +//t "conditional_expression : null_coalescing_expression INTERR expression COLON CLOSE_BRACE", //t "assignment_expression : prefixed_unary_expression ASSIGN expression", //t "assignment_expression : prefixed_unary_expression OP_MULT_ASSIGN expression", //t "assignment_expression : prefixed_unary_expression OP_DIV_ASSIGN expression", @@ -805,24 +853,27 @@ namespace Mono.CSharp //t "lambda_parameter : parameter_modifier parameter_type identifier_inside_body", //t "lambda_parameter : parameter_type identifier_inside_body", //t "lambda_parameter : IDENTIFIER", +//t "lambda_parameter : AWAIT", //t "opt_lambda_parameter_list :", //t "opt_lambda_parameter_list : lambda_parameter_list", -//t "lambda_expression_body : lambda_expression_body_simple", -//t "lambda_expression_body : block", //t "$$69 :", -//t "lambda_expression_body_simple : $$69 expression_or_error", +//t "lambda_expression_body : $$69 expression", +//t "lambda_expression_body : block", +//t "lambda_expression_body : error", //t "expression_or_error : expression", //t "expression_or_error : error", //t "$$70 :", //t "lambda_expression : IDENTIFIER ARROW $$70 lambda_expression_body", //t "$$71 :", -//t "lambda_expression : ASYNC identifier_inside_body ARROW $$71 lambda_expression_body", +//t "lambda_expression : AWAIT ARROW $$71 lambda_expression_body", //t "$$72 :", +//t "lambda_expression : ASYNC identifier_inside_body ARROW $$72 lambda_expression_body", //t "$$73 :", -//t "lambda_expression : OPEN_PARENS_LAMBDA $$72 opt_lambda_parameter_list CLOSE_PARENS ARROW $$73 lambda_expression_body", //t "$$74 :", +//t "lambda_expression : OPEN_PARENS_LAMBDA $$73 opt_lambda_parameter_list CLOSE_PARENS ARROW $$74 lambda_expression_body", //t "$$75 :", -//t "lambda_expression : ASYNC OPEN_PARENS_LAMBDA $$74 opt_lambda_parameter_list CLOSE_PARENS ARROW $$75 lambda_expression_body", +//t "$$76 :", +//t "lambda_expression : ASYNC OPEN_PARENS_LAMBDA $$75 opt_lambda_parameter_list CLOSE_PARENS ARROW $$76 lambda_expression_body", //t "expression : assignment_expression", //t "expression : non_assignment_expression", //t "non_assignment_expression : conditional_expression", @@ -834,11 +885,19 @@ namespace Mono.CSharp //t "undocumented_expressions : MAKEREF open_parens_any expression CLOSE_PARENS", //t "constant_expression : expression", //t "boolean_expression : expression", -//t "$$76 :", +//t "opt_primary_parameters :", +//t "opt_primary_parameters : primary_parameters", +//t "primary_parameters : OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS", +//t "opt_primary_parameters_with_class_base :", +//t "opt_primary_parameters_with_class_base : class_base", +//t "opt_primary_parameters_with_class_base : primary_parameters", //t "$$77 :", +//t "opt_primary_parameters_with_class_base : primary_parameters class_base OPEN_PARENS $$77 opt_argument_list CLOSE_PARENS", //t "$$78 :", //t "$$79 :", -//t "class_declaration : opt_attributes opt_modifiers opt_partial CLASS $$76 type_declaration_name $$77 opt_class_base opt_type_parameter_constraints_clauses $$78 OPEN_BRACE opt_class_member_declarations CLOSE_BRACE $$79 opt_semicolon", +//t "$$80 :", +//t "$$81 :", +//t "class_declaration : opt_attributes opt_modifiers opt_partial CLASS $$78 type_declaration_name $$79 opt_primary_parameters_with_class_base opt_type_parameter_constraints_clauses $$80 OPEN_BRACE opt_class_member_declarations CLOSE_BRACE $$81 opt_semicolon", //t "opt_partial :", //t "opt_partial : PARTIAL", //t "opt_modifiers :", @@ -861,8 +920,9 @@ namespace Mono.CSharp //t "modifier : UNSAFE", //t "modifier : ASYNC", //t "opt_class_base :", -//t "opt_class_base : COLON type_list", -//t "opt_class_base : COLON type_list error", +//t "opt_class_base : class_base", +//t "class_base : COLON type_list", +//t "class_base : COLON type_list error", //t "opt_type_parameter_constraints_clauses :", //t "opt_type_parameter_constraints_clauses : type_parameter_constraints_clauses", //t "type_parameter_constraints_clauses : type_parameter_constraints_clause", @@ -879,13 +939,15 @@ namespace Mono.CSharp //t "opt_type_parameter_variance : type_parameter_variance", //t "type_parameter_variance : OUT", //t "type_parameter_variance : IN", -//t "$$80 :", -//t "block : OPEN_BRACE $$80 opt_statement_list block_end", +//t "$$82 :", +//t "block : OPEN_BRACE $$82 opt_statement_list block_end", //t "block_end : CLOSE_BRACE", //t "block_end : COMPLETE_COMPLETION", -//t "$$81 :", -//t "block_prepared : OPEN_BRACE $$81 opt_statement_list CLOSE_BRACE", +//t "$$83 :", +//t "block_prepared : OPEN_BRACE $$83 opt_statement_list CLOSE_BRACE", //t "block_prepared : CLOSE_BRACE", +//t "$$84 :", +//t "block_prepared_strict : OPEN_BRACE $$84 opt_statement_list CLOSE_BRACE", //t "opt_statement_list :", //t "opt_statement_list : statement_list", //t "statement_list : statement", @@ -931,8 +993,8 @@ namespace Mono.CSharp //t "embedded_statement : labeled_statement", //t "embedded_statement : error", //t "empty_statement : SEMICOLON", -//t "$$82 :", -//t "labeled_statement : identifier_inside_body COLON $$82 statement", +//t "$$85 :", +//t "labeled_statement : identifier_inside_body COLON $$85 statement", //t "variable_type : variable_type_simple", //t "variable_type : variable_type_simple rank_specifiers", //t "variable_type_simple : primary_expression_or_type opt_nullable", @@ -946,15 +1008,14 @@ namespace Mono.CSharp //t "pointer_star : STAR", //t "identifier_inside_body : IDENTIFIER", //t "identifier_inside_body : AWAIT", -//t "$$83 :", -//t "block_variable_declaration : variable_type identifier_inside_body $$83 opt_local_variable_initializer opt_variable_declarators semicolon_or_handle_error_close_brace", -//t "$$84 :", -//t "block_variable_declaration : CONST variable_type identifier_inside_body $$84 const_variable_initializer opt_const_declarators SEMICOLON", +//t "$$86 :", +//t "block_variable_declaration : variable_type identifier_inside_body $$86 opt_local_variable_initializer opt_variable_declarators semicolon_or_handle_error_close_brace", +//t "$$87 :", +//t "block_variable_declaration : CONST variable_type identifier_inside_body $$87 const_variable_initializer opt_const_declarators SEMICOLON", //t "semicolon_or_handle_error_close_brace : SEMICOLON", //t "semicolon_or_handle_error_close_brace : CLOSE_BRACE", //t "opt_local_variable_initializer :", //t "opt_local_variable_initializer : ASSIGN block_variable_initializer", -//t "opt_local_variable_initializer : ASSIGN error", //t "opt_local_variable_initializer : error", //t "opt_variable_declarators :", //t "opt_variable_declarators : variable_declarators", @@ -987,16 +1048,15 @@ namespace Mono.CSharp //t "if_statement : IF open_parens_any boolean_expression CLOSE_PARENS embedded_statement", //t "if_statement : IF open_parens_any boolean_expression CLOSE_PARENS embedded_statement ELSE embedded_statement", //t "if_statement : IF open_parens_any boolean_expression error", -//t "$$85 :", -//t "switch_statement : SWITCH open_parens_any expression CLOSE_PARENS OPEN_BRACE $$85 opt_switch_sections CLOSE_BRACE", +//t "$$88 :", +//t "switch_statement : SWITCH open_parens_any expression CLOSE_PARENS OPEN_BRACE $$88 opt_switch_sections CLOSE_BRACE", //t "switch_statement : SWITCH open_parens_any expression error", //t "opt_switch_sections :", //t "opt_switch_sections : switch_sections", //t "switch_sections : switch_section", //t "switch_sections : switch_sections switch_section", //t "switch_sections : error", -//t "$$86 :", -//t "switch_section : switch_labels $$86 statement_list", +//t "switch_section : switch_labels statement_list", //t "switch_labels : switch_label", //t "switch_labels : switch_labels switch_label", //t "switch_label : CASE constant_expression COLON", @@ -1011,20 +1071,20 @@ namespace Mono.CSharp //t "do_statement : DO embedded_statement WHILE open_parens_any boolean_expression CLOSE_PARENS SEMICOLON", //t "do_statement : DO embedded_statement error", //t "do_statement : DO embedded_statement WHILE open_parens_any boolean_expression error", -//t "$$87 :", -//t "for_statement : FOR open_parens_any $$87 for_statement_cont", -//t "$$88 :", -//t "for_statement_cont : opt_for_initializer SEMICOLON $$88 for_statement_condition", -//t "for_statement_cont : opt_for_initializer CLOSE_PARENS", //t "$$89 :", -//t "for_statement_condition : opt_for_condition SEMICOLON $$89 for_statement_end", +//t "for_statement : FOR open_parens_any $$89 for_statement_cont", +//t "$$90 :", +//t "for_statement_cont : opt_for_initializer SEMICOLON $$90 for_statement_condition", +//t "for_statement_cont : opt_for_initializer CLOSE_PARENS", +//t "$$91 :", +//t "for_statement_condition : opt_for_condition SEMICOLON $$91 for_statement_end", //t "for_statement_condition : boolean_expression CLOSE_PARENS", //t "for_statement_end : opt_for_iterator CLOSE_PARENS embedded_statement", //t "for_statement_end : error", //t "opt_for_initializer :", //t "opt_for_initializer : for_initializer", -//t "$$90 :", -//t "for_initializer : variable_type identifier_inside_body $$90 opt_local_variable_initializer opt_variable_declarators", +//t "$$92 :", +//t "for_initializer : variable_type identifier_inside_body $$92 opt_local_variable_initializer opt_variable_declarators", //t "for_initializer : statement_expression_list", //t "opt_for_condition :", //t "opt_for_condition : boolean_expression", @@ -1035,8 +1095,8 @@ namespace Mono.CSharp //t "statement_expression_list : statement_expression_list COMMA statement_expression", //t "foreach_statement : FOREACH open_parens_any type error", //t "foreach_statement : FOREACH open_parens_any type identifier_inside_body error", -//t "$$91 :", -//t "foreach_statement : FOREACH open_parens_any type identifier_inside_body IN expression CLOSE_PARENS $$91 embedded_statement", +//t "$$93 :", +//t "foreach_statement : FOREACH open_parens_any type identifier_inside_body IN expression CLOSE_PARENS $$93 embedded_statement", //t "foreach_statement : FOREACH open_parens_any type identifier_inside_body error", //t "foreach_statement : FOREACH open_parens_any type error", //t "jump_statement : break_statement", @@ -1055,6 +1115,7 @@ namespace Mono.CSharp //t "return_statement : RETURN expression error", //t "return_statement : RETURN error", //t "throw_statement : THROW opt_expression SEMICOLON", +//t "throw_statement : THROW expression error", //t "throw_statement : THROW error", //t "yield_statement : identifier_inside_body RETURN opt_expression SEMICOLON", //t "yield_statement : identifier_inside_body RETURN expression error", @@ -1069,22 +1130,25 @@ namespace Mono.CSharp //t "catch_clauses : catch_clauses catch_clause", //t "opt_identifier :", //t "opt_identifier : identifier_inside_body", -//t "catch_clause : CATCH block", -//t "$$92 :", -//t "catch_clause : CATCH open_parens_any type opt_identifier CLOSE_PARENS $$92 block_prepared", +//t "catch_clause : CATCH opt_catch_filter block", +//t "$$94 :", +//t "catch_clause : CATCH open_parens_any type opt_identifier CLOSE_PARENS $$94 opt_catch_filter block_prepared", //t "catch_clause : CATCH open_parens_any error", +//t "catch_clause : CATCH open_parens_any type opt_identifier CLOSE_PARENS error", +//t "opt_catch_filter :", +//t "opt_catch_filter : IF open_parens_any expression CLOSE_PARENS", //t "checked_statement : CHECKED block", //t "unchecked_statement : UNCHECKED block", -//t "$$93 :", -//t "unsafe_statement : UNSAFE $$93 block", +//t "$$95 :", +//t "unsafe_statement : UNSAFE $$95 block", //t "lock_statement : LOCK open_parens_any expression CLOSE_PARENS embedded_statement", //t "lock_statement : LOCK open_parens_any expression error", -//t "$$94 :", -//t "$$95 :", -//t "fixed_statement : FIXED open_parens_any variable_type identifier_inside_body $$94 using_or_fixed_variable_initializer opt_using_or_fixed_variable_declarators CLOSE_PARENS $$95 embedded_statement", //t "$$96 :", //t "$$97 :", -//t "using_statement : USING open_parens_any variable_type identifier_inside_body $$96 using_initialization CLOSE_PARENS $$97 embedded_statement", +//t "fixed_statement : FIXED open_parens_any variable_type identifier_inside_body $$96 using_or_fixed_variable_initializer opt_using_or_fixed_variable_declarators CLOSE_PARENS $$97 embedded_statement", +//t "$$98 :", +//t "$$99 :", +//t "using_statement : USING open_parens_any variable_type identifier_inside_body $$98 using_initialization CLOSE_PARENS $$99 embedded_statement", //t "using_statement : USING open_parens_any expression CLOSE_PARENS embedded_statement", //t "using_statement : USING open_parens_any expression error", //t "using_initialization : using_or_fixed_variable_initializer opt_using_or_fixed_variable_declarators", @@ -1099,20 +1163,22 @@ namespace Mono.CSharp //t "first_from_clause : FROM_FIRST type identifier_inside_body IN expression", //t "nested_from_clause : FROM identifier_inside_body IN expression", //t "nested_from_clause : FROM type identifier_inside_body IN expression", -//t "$$98 :", -//t "from_clause : FROM identifier_inside_body IN $$98 expression_or_error", -//t "$$99 :", -//t "from_clause : FROM type identifier_inside_body IN $$99 expression_or_error", +//t "$$100 :", +//t "from_clause : FROM identifier_inside_body IN $$100 expression_or_error", +//t "$$101 :", +//t "from_clause : FROM type identifier_inside_body IN $$101 expression_or_error", //t "query_body : query_body_clauses select_or_group_clause opt_query_continuation", //t "query_body : select_or_group_clause opt_query_continuation", //t "query_body : query_body_clauses COMPLETE_COMPLETION", //t "query_body : query_body_clauses error", //t "query_body : error", -//t "$$100 :", -//t "select_or_group_clause : SELECT $$100 expression_or_error", -//t "$$101 :", //t "$$102 :", -//t "select_or_group_clause : GROUP $$101 expression_or_error $$102 BY expression_or_error", +//t "select_or_group_clause : SELECT $$102 expression_or_error", +//t "$$103 :", +//t "$$104 :", +//t "select_or_group_clause : GROUP $$103 expression_or_error $$104 by_expression", +//t "by_expression : BY expression_or_error", +//t "by_expression : error", //t "query_body_clauses : query_body_clause", //t "query_body_clauses : query_body_clauses query_body_clause", //t "query_body_clause : from_clause", @@ -1120,28 +1186,28 @@ namespace Mono.CSharp //t "query_body_clause : where_clause", //t "query_body_clause : join_clause", //t "query_body_clause : orderby_clause", -//t "$$103 :", -//t "let_clause : LET identifier_inside_body ASSIGN $$103 expression_or_error", -//t "$$104 :", -//t "where_clause : WHERE $$104 expression_or_error", //t "$$105 :", +//t "let_clause : LET identifier_inside_body ASSIGN $$105 expression_or_error", //t "$$106 :", +//t "where_clause : WHERE $$106 expression_or_error", //t "$$107 :", -//t "join_clause : JOIN identifier_inside_body IN $$105 expression_or_error ON $$106 expression_or_error EQUALS $$107 expression_or_error opt_join_into", //t "$$108 :", //t "$$109 :", +//t "join_clause : JOIN identifier_inside_body IN $$107 expression_or_error ON $$108 expression_or_error EQUALS $$109 expression_or_error opt_join_into", //t "$$110 :", -//t "join_clause : JOIN type identifier_inside_body IN $$108 expression_or_error ON $$109 expression_or_error EQUALS $$110 expression_or_error opt_join_into", +//t "$$111 :", +//t "$$112 :", +//t "join_clause : JOIN type identifier_inside_body IN $$110 expression_or_error ON $$111 expression_or_error EQUALS $$112 expression_or_error opt_join_into", //t "opt_join_into :", //t "opt_join_into : INTO identifier_inside_body", -//t "$$111 :", -//t "orderby_clause : ORDERBY $$111 orderings", +//t "$$113 :", +//t "orderby_clause : ORDERBY $$113 orderings", //t "orderings : order_by", -//t "$$112 :", -//t "orderings : order_by COMMA $$112 orderings_then_by", +//t "$$114 :", +//t "orderings : order_by COMMA $$114 orderings_then_by", //t "orderings_then_by : then_by", -//t "$$113 :", -//t "orderings_then_by : orderings_then_by COMMA $$113 then_by", +//t "$$115 :", +//t "orderings_then_by : orderings_then_by COMMA $$115 then_by", //t "order_by : expression", //t "order_by : expression ASCENDING", //t "order_by : expression DESCENDING", @@ -1149,12 +1215,12 @@ namespace Mono.CSharp //t "then_by : expression ASCENDING", //t "then_by : expression DESCENDING", //t "opt_query_continuation :", -//t "$$114 :", -//t "opt_query_continuation : INTO identifier_inside_body $$114 query_body", +//t "$$116 :", +//t "opt_query_continuation : INTO identifier_inside_body $$116 query_body", //t "interactive_parsing : EVAL_STATEMENT_PARSER EOF", //t "interactive_parsing : EVAL_USING_DECLARATIONS_UNIT_PARSER using_directives opt_COMPLETE_COMPLETION", -//t "$$115 :", -//t "interactive_parsing : EVAL_STATEMENT_PARSER $$115 interactive_statement_list opt_COMPLETE_COMPLETION", +//t "$$117 :", +//t "interactive_parsing : EVAL_STATEMENT_PARSER $$117 interactive_statement_list opt_COMPLETE_COMPLETION", //t "interactive_parsing : EVAL_COMPILATION_UNIT_PARSER interactive_compilation_unit", //t "interactive_compilation_unit : opt_extern_alias_directives opt_using_directives", //t "interactive_compilation_unit : opt_extern_alias_directives opt_using_directives namespace_or_type_declarations", @@ -1165,18 +1231,19 @@ namespace Mono.CSharp //t "documentation_parsing : DOC_SEE doc_cref", //t "doc_cref : doc_type_declaration_name opt_doc_method_sig", //t "doc_cref : builtin_types opt_doc_method_sig", +//t "doc_cref : VOID opt_doc_method_sig", //t "doc_cref : builtin_types DOT IDENTIFIER opt_doc_method_sig", //t "doc_cref : doc_type_declaration_name DOT THIS", -//t "$$116 :", -//t "doc_cref : doc_type_declaration_name DOT THIS OPEN_BRACKET $$116 opt_doc_parameters CLOSE_BRACKET", +//t "$$118 :", +//t "doc_cref : doc_type_declaration_name DOT THIS OPEN_BRACKET $$118 opt_doc_parameters CLOSE_BRACKET", //t "doc_cref : EXPLICIT OPERATOR type opt_doc_method_sig", //t "doc_cref : IMPLICIT OPERATOR type opt_doc_method_sig", //t "doc_cref : OPERATOR overloadable_operator opt_doc_method_sig", //t "doc_type_declaration_name : type_declaration_name", //t "doc_type_declaration_name : doc_type_declaration_name DOT type_declaration_name", //t "opt_doc_method_sig :", -//t "$$117 :", -//t "opt_doc_method_sig : OPEN_PARENS $$117 opt_doc_parameters CLOSE_PARENS", +//t "$$119 :", +//t "opt_doc_method_sig : OPEN_PARENS $$119 opt_doc_parameters CLOSE_PARENS", //t "opt_doc_parameters :", //t "opt_doc_parameters : doc_parameters", //t "doc_parameters : doc_parameter", @@ -1425,20 +1492,20 @@ namespace Mono.CSharp yyVal = yyV > yyTop ? null : yyVals[yyV]; // yyVal = yyDefault(yyV > yyTop ? null : yyVals[yyV]); switch (yyN) { case 1: -#line 385 "cs-parser.jay" +#line 388 "cs-parser.jay" { Lexer.check_incorrect_doc_comment (); } break; case 2: -#line 386 "cs-parser.jay" +#line 389 "cs-parser.jay" { Lexer.CompleteOnEOF = false; } break; case 6: case_6(); break; case 7: -#line 405 "cs-parser.jay" +#line 408 "cs-parser.jay" { module.AddAttributes ((Attributes) yyVals[0+yyTop], current_namespace); } @@ -1450,7 +1517,7 @@ case 13: case_13(); break; case 14: -#line 450 "cs-parser.jay" +#line 453 "cs-parser.jay" { Error_SyntaxError (yyToken); } @@ -1479,35 +1546,29 @@ case 23: case 24: case_24(); break; -case 25: - case_25(); +case 27: + case_27(); break; -case 26: - case_26(); +case 28: + case_28(); break; -case 39: - case_39(); +case 29: + case_29(); break; -case 40: -#line 616 "cs-parser.jay" +case 30: + case_30(); + break; +case 43: + case_43(); + break; +case 44: +#line 637 "cs-parser.jay" { current_namespace.DeclarationFound = true; } break; -case 41: - case_41(); - break; -case 49: - case_49(); - break; -case 50: - case_50(); - break; -case 51: - case_51(); - break; -case 52: - case_52(); +case 45: + case_45(); break; case 53: case_53(); @@ -1522,68 +1583,65 @@ case 56: case_56(); break; case 57: -#line 730 "cs-parser.jay" - { yyVal = "event"; savedCloseLocation = GetLocation (yyVals[0+yyTop]); } + case_57(); break; case 58: -#line 731 "cs-parser.jay" - { yyVal = "return"; savedCloseLocation = GetLocation (yyVals[0+yyTop]); } + case_58(); break; case 59: case_59(); break; case 60: -#line 748 "cs-parser.jay" - { - yyVal = new List (4) { (Attribute) yyVals[0+yyTop] }; - } + case_60(); break; case 61: case_61(); break; case 62: -#line 763 "cs-parser.jay" - { - ++lexer.parsing_block; - } + case_62(); break; case 63: - case_63(); +#line 762 "cs-parser.jay" + { yyVal = "event"; PushLocation (GetLocation (yyVals[0+yyTop])); } + break; +case 64: +#line 763 "cs-parser.jay" + { yyVal = "return"; PushLocation (GetLocation (yyVals[0+yyTop])); } break; case 65: -#line 791 "cs-parser.jay" - { yyVal = null; HadAttributeParens = false; } +#line 770 "cs-parser.jay" + { + yyVal = new List (4) { (Attribute) yyVals[0+yyTop] }; + } break; case 66: case_66(); break; case 67: -#line 803 "cs-parser.jay" - { yyVal = null; } +#line 787 "cs-parser.jay" + { + ++lexer.parsing_block; + } break; case 68: case_68(); break; -case 69: - case_69(); - break; case 70: - case_70(); +#line 815 "cs-parser.jay" + { yyVal = null; HadAttributeParens = false; } break; case 71: case_71(); break; case 72: -#line 847 "cs-parser.jay" - { - yyVal = new Argument ((Expression) yyVals[0+yyTop]); - } +#line 827 "cs-parser.jay" + { yyVal = null; } + break; +case 73: + case_73(); break; case 74: -#line 855 "cs-parser.jay" - { - ++lexer.parsing_block; - } + case_74(); break; case 75: case_75(); @@ -1592,90 +1650,80 @@ case 76: case_76(); break; case 77: -#line 881 "cs-parser.jay" - { yyVal = null; } - break; -case 78: -#line 885 "cs-parser.jay" - { - yyVal = Argument.AType.Ref; +#line 871 "cs-parser.jay" + { + yyVal = new Argument ((Expression) yyVals[0+yyTop]); } break; case 79: -#line 889 "cs-parser.jay" - { - yyVal = Argument.AType.Out; - } - break; -case 82: -#line 901 "cs-parser.jay" - { - lexer.parsing_modifiers = true; - } + case_79(); break; -case 83: -#line 905 "cs-parser.jay" +case 80: +#line 884 "cs-parser.jay" { - lexer.parsing_modifiers = true; + ++lexer.parsing_block; } break; -case 95: - case_95(); +case 81: + case_81(); break; -case 96: -#line 936 "cs-parser.jay" - { - lexer.ConstraintsParsing = true; - } +case 82: + case_82(); break; -case 97: - case_97(); +case 83: +#line 910 "cs-parser.jay" + { yyVal = null; } break; -case 98: - case_98(); +case 84: +#line 914 "cs-parser.jay" + { + yyVal = Argument.AType.Ref; + } break; -case 99: - case_99(); +case 85: +#line 918 "cs-parser.jay" + { + yyVal = Argument.AType.Out; + } break; -case 100: - case_100(); +case 88: + case_88(); break; -case 101: - case_101(); +case 89: + case_89(); break; case 102: -#line 979 "cs-parser.jay" - { - Error_SyntaxError (yyToken); - } + case_102(); break; case 103: - case_103(); +#line 967 "cs-parser.jay" + { + } break; case 104: case_104(); break; +case 105: + case_105(); + break; +case 106: + case_106(); + break; case 107: -#line 1020 "cs-parser.jay" - { - current_field.AddDeclarator ((FieldDeclarator) yyVals[0+yyTop]); - } + case_107(); break; case 108: -#line 1024 "cs-parser.jay" - { - current_field.AddDeclarator ((FieldDeclarator) yyVals[0+yyTop]); - } + case_108(); break; case 109: - case_109(); - break; -case 110: -#line 1040 "cs-parser.jay" +#line 1017 "cs-parser.jay" { - ++lexer.parsing_block; + Error_SyntaxError (yyToken); } break; +case 110: + case_110(); + break; case 111: case_111(); break; @@ -1683,118 +1731,109 @@ case 112: case_112(); break; case 115: - case_115(); +#line 1066 "cs-parser.jay" + { + current_field.AddDeclarator ((FieldDeclarator) yyVals[0+yyTop]); + } break; case 116: - case_116(); +#line 1070 "cs-parser.jay" + { + current_field.AddDeclarator ((FieldDeclarator) yyVals[0+yyTop]); + } break; case 117: case_117(); break; case 118: - case_118(); - break; -case 119: -#line 1119 "cs-parser.jay" +#line 1086 "cs-parser.jay" { - report.Error (1641, GetLocation (yyVals[-1+yyTop]), "A fixed size buffer field must have the array size specifier after the field name"); + ++lexer.parsing_block; } break; -case 121: - case_121(); +case 119: + case_119(); + break; +case 120: + case_120(); break; -case 122: - case_122(); +case 123: + case_123(); + break; +case 124: + case_124(); break; case 125: -#line 1149 "cs-parser.jay" - { - current_field.AddDeclarator ((FieldDeclarator) yyVals[0+yyTop]); - } + case_125(); break; case 126: -#line 1153 "cs-parser.jay" - { - current_field.AddDeclarator ((FieldDeclarator) yyVals[0+yyTop]); - } + case_126(); break; case 127: - case_127(); - break; -case 128: -#line 1166 "cs-parser.jay" +#line 1165 "cs-parser.jay" { - ++lexer.parsing_block; + report.Error (1641, GetLocation (yyVals[-1+yyTop]), "A fixed size buffer field must have the array size specifier after the field name"); } break; case 129: case_129(); break; -case 132: -#line 1185 "cs-parser.jay" - { - current_field.AddDeclarator ((FieldDeclarator) yyVals[0+yyTop]); - } +case 130: + case_130(); break; case 133: -#line 1189 "cs-parser.jay" +#line 1195 "cs-parser.jay" { current_field.AddDeclarator ((FieldDeclarator) yyVals[0+yyTop]); } break; case 134: - case_134(); +#line 1199 "cs-parser.jay" + { + current_field.AddDeclarator ((FieldDeclarator) yyVals[0+yyTop]); + } break; case 135: -#line 1205 "cs-parser.jay" + case_135(); + break; +case 136: +#line 1212 "cs-parser.jay" { ++lexer.parsing_block; } break; -case 136: - case_136(); - break; case 137: case_137(); break; case 140: - case_140(); +#line 1231 "cs-parser.jay" + { + current_field.AddDeclarator ((FieldDeclarator) yyVals[0+yyTop]); + } break; case 141: - case_141(); +#line 1235 "cs-parser.jay" + { + current_field.AddDeclarator ((FieldDeclarator) yyVals[0+yyTop]); + } break; case 142: case_142(); break; case 143: -#line 1276 "cs-parser.jay" +#line 1251 "cs-parser.jay" { - valid_param_mod = ParameterModifierType.All; + ++lexer.parsing_block; } break; case 144: -#line 1280 "cs-parser.jay" - { - lexer.ConstraintsParsing = true; - } + case_144(); break; case 145: case_145(); break; -case 146: -#line 1306 "cs-parser.jay" - { - lexer.parsing_generic_declaration = true; - } - break; -case 147: - case_147(); - break; case 148: -#line 1316 "cs-parser.jay" - { - lexer.ConstraintsParsing = true; - } + case_148(); break; case 149: case_149(); @@ -1803,18 +1842,31 @@ case 150: case_150(); break; case 151: - case_151(); +#line 1319 "cs-parser.jay" + { + valid_param_mod = ParameterModifierType.All; + } + break; +case 152: + case_152(); break; case 153: -#line 1381 "cs-parser.jay" - { savedLocation = GetLocation (yyVals[0+yyTop]); yyVal = null; } + case_153(); break; case 154: -#line 1385 "cs-parser.jay" - { yyVal = ParametersCompiled.EmptyReadOnlyParameters; } +#line 1358 "cs-parser.jay" + { + lexer.parsing_generic_declaration = true; + } + break; +case 155: + case_155(); break; case 156: - case_156(); +#line 1368 "cs-parser.jay" + { + lexer.ConstraintsParsing = true; + } break; case 157: case_157(); @@ -1825,26 +1877,16 @@ case 158: case 159: case_159(); break; -case 160: - case_160(); - break; case 161: - case_161(); +#line 1441 "cs-parser.jay" + { savedLocation = GetLocation (yyVals[0+yyTop]); yyVal = null; } break; case 162: - case_162(); - break; -case 163: -#line 1457 "cs-parser.jay" - { - yyVal = new ParametersCompiled (new Parameter[] { (Parameter) yyVals[0+yyTop] } ); - } +#line 1445 "cs-parser.jay" + { yyVal = ParametersCompiled.EmptyReadOnlyParameters; } break; case 164: -#line 1461 "cs-parser.jay" - { - yyVal = new ParametersCompiled (new Parameter [] { new ArglistParameter (GetLocation (yyVals[0+yyTop])) }, true); - } + case_164(); break; case 165: case_165(); @@ -1865,26 +1907,28 @@ case 170: case_170(); break; case 171: - case_171(); +#line 1517 "cs-parser.jay" + { + yyVal = new ParametersCompiled (new Parameter[] { (Parameter) yyVals[0+yyTop] } ); + } break; case 172: -#line 1542 "cs-parser.jay" +#line 1521 "cs-parser.jay" { - ++lexer.parsing_block; + yyVal = new ParametersCompiled (new Parameter [] { new ArglistParameter (GetLocation (yyVals[0+yyTop])) }, true); } break; case 173: case_173(); break; case 174: -#line 1583 "cs-parser.jay" - { yyVal = Parameter.Modifier.NONE; } + case_174(); + break; +case 175: + case_175(); break; case 176: -#line 1591 "cs-parser.jay" - { - yyVal = yyVals[0+yyTop]; - } + case_176(); break; case 177: case_177(); @@ -1896,28 +1940,29 @@ case 179: case_179(); break; case 180: - case_180(); +#line 1602 "cs-parser.jay" + { + ++lexer.parsing_block; + } break; case 181: case_181(); break; case 182: - case_182(); - break; -case 183: - case_183(); +#line 1643 "cs-parser.jay" + { yyVal = Parameter.Modifier.NONE; } break; case 184: - case_184(); +#line 1651 "cs-parser.jay" + { + yyVal = yyVals[0+yyTop]; + } break; case 185: case_185(); break; case 186: -#line 1684 "cs-parser.jay" - { - Error_DuplicateParameterModifier (GetLocation (yyVals[-1+yyTop]), Parameter.Modifier.PARAMS); - } + case_186(); break; case 187: case_187(); @@ -1935,50 +1980,53 @@ case 191: case_191(); break; case 192: -#line 1738 "cs-parser.jay" - { - valid_param_mod = ParameterModifierType.Params | ParameterModifierType.DefaultValue; - } + case_192(); break; case 193: case_193(); break; case 194: -#line 1767 "cs-parser.jay" +#line 1745 "cs-parser.jay" { - lexer.PropertyParsing = false; + Error_DuplicateParameterModifier (GetLocation (yyVals[-1+yyTop]), Parameter.Modifier.PARAMS); } break; case 195: case_195(); break; -case 200: - case_200(); +case 196: + case_196(); break; -case 201: - case_201(); +case 197: + case_197(); break; -case 202: - case_202(); +case 198: + case_198(); break; -case 203: - case_203(); +case 199: + case_199(); break; -case 204: - case_204(); - break; -case 206: - case_206(); +case 200: +#line 1799 "cs-parser.jay" + { + valid_param_mod = ParameterModifierType.Params | ParameterModifierType.DefaultValue; + } break; -case 207: - case_207(); +case 201: + case_201(); break; -case 208: -#line 1916 "cs-parser.jay" +case 202: +#line 1828 "cs-parser.jay" { - lexer.ConstraintsParsing = true; + lexer.PropertyParsing = false; } break; +case 203: + case_203(); + break; +case 208: + case_208(); + break; case 209: case_209(); break; @@ -1991,244 +2039,237 @@ case 211: case 212: case_212(); break; -case 213: -#line 1955 "cs-parser.jay" - { - Error_SyntaxError (yyToken); - } +case 214: + case_214(); + break; +case 215: + case_215(); break; case 216: -#line 1967 "cs-parser.jay" +#line 1976 "cs-parser.jay" { - lexer.parsing_modifiers = true; } break; case 217: -#line 1971 "cs-parser.jay" + case_217(); + break; +case 218: + case_218(); + break; +case 219: + case_219(); + break; +case 220: + case_220(); + break; +case 221: +#line 2016 "cs-parser.jay" { - lexer.parsing_modifiers = true; + Error_SyntaxError (yyToken); } break; -case 218: -#line 1978 "cs-parser.jay" +case 224: + case_224(); + break; +case 225: + case_225(); + break; +case 226: +#line 2041 "cs-parser.jay" { report.Error (525, GetLocation (yyVals[0+yyTop]), "Interfaces cannot contain fields or constants"); } break; -case 219: -#line 1982 "cs-parser.jay" +case 227: +#line 2045 "cs-parser.jay" { report.Error (525, GetLocation (yyVals[0+yyTop]), "Interfaces cannot contain fields or constants"); } break; -case 224: -#line 1990 "cs-parser.jay" +case 232: +#line 2053 "cs-parser.jay" { report.Error (567, GetLocation (yyVals[0+yyTop]), "Interfaces cannot contain operators"); } break; -case 225: -#line 1994 "cs-parser.jay" +case 233: +#line 2057 "cs-parser.jay" { report.Error (526, GetLocation (yyVals[0+yyTop]), "Interfaces cannot contain contructors"); } break; -case 226: -#line 1998 "cs-parser.jay" +case 234: +#line 2061 "cs-parser.jay" { report.Error (524, GetLocation (yyVals[0+yyTop]), "Interfaces cannot declare classes, structs, interfaces, delegates, or enumerations"); } break; -case 227: -#line 2004 "cs-parser.jay" +case 235: +#line 2067 "cs-parser.jay" { } break; -case 228: - case_228(); +case 236: + case_236(); break; -case 230: -#line 2037 "cs-parser.jay" +case 238: +#line 2100 "cs-parser.jay" { savedLocation = GetLocation (yyVals[0+yyTop]); yyVal = null; } break; -case 232: - case_232(); +case 240: + case_240(); break; -case 233: -#line 2053 "cs-parser.jay" +case 241: +#line 2116 "cs-parser.jay" { valid_param_mod = ParameterModifierType.DefaultValue; } break; -case 234: - case_234(); +case 242: + case_242(); break; -case 236: -#line 2099 "cs-parser.jay" +case 244: +#line 2162 "cs-parser.jay" { yyVal = Operator.OpType.LogicalNot; savedOperatorLocation = GetLocation (yyVals[0+yyTop]); } break; -case 237: -#line 2100 "cs-parser.jay" +case 245: +#line 2163 "cs-parser.jay" { yyVal = Operator.OpType.OnesComplement; savedOperatorLocation = GetLocation (yyVals[0+yyTop]); } break; -case 238: -#line 2101 "cs-parser.jay" +case 246: +#line 2164 "cs-parser.jay" { yyVal = Operator.OpType.Increment; savedOperatorLocation = GetLocation (yyVals[0+yyTop]); } break; -case 239: -#line 2102 "cs-parser.jay" +case 247: +#line 2165 "cs-parser.jay" { yyVal = Operator.OpType.Decrement; savedOperatorLocation = GetLocation (yyVals[0+yyTop]); } break; -case 240: -#line 2103 "cs-parser.jay" +case 248: +#line 2166 "cs-parser.jay" { yyVal = Operator.OpType.True; savedOperatorLocation = GetLocation (yyVals[0+yyTop]); } break; -case 241: -#line 2104 "cs-parser.jay" +case 249: +#line 2167 "cs-parser.jay" { yyVal = Operator.OpType.False; savedOperatorLocation = GetLocation (yyVals[0+yyTop]); } break; -case 242: -#line 2106 "cs-parser.jay" +case 250: +#line 2169 "cs-parser.jay" { yyVal = Operator.OpType.Addition; savedOperatorLocation = GetLocation (yyVals[0+yyTop]); } break; -case 243: -#line 2107 "cs-parser.jay" +case 251: +#line 2170 "cs-parser.jay" { yyVal = Operator.OpType.Subtraction; savedOperatorLocation = GetLocation (yyVals[0+yyTop]); } break; -case 244: -#line 2109 "cs-parser.jay" +case 252: +#line 2172 "cs-parser.jay" { yyVal = Operator.OpType.Multiply; savedOperatorLocation = GetLocation (yyVals[0+yyTop]); } break; -case 245: -#line 2110 "cs-parser.jay" +case 253: +#line 2173 "cs-parser.jay" { yyVal = Operator.OpType.Division; savedOperatorLocation = GetLocation (yyVals[0+yyTop]); } break; -case 246: -#line 2111 "cs-parser.jay" +case 254: +#line 2174 "cs-parser.jay" { yyVal = Operator.OpType.Modulus; savedOperatorLocation = GetLocation (yyVals[0+yyTop]); } break; -case 247: -#line 2112 "cs-parser.jay" +case 255: +#line 2175 "cs-parser.jay" { yyVal = Operator.OpType.BitwiseAnd; savedOperatorLocation = GetLocation (yyVals[0+yyTop]); } break; -case 248: -#line 2113 "cs-parser.jay" +case 256: +#line 2176 "cs-parser.jay" { yyVal = Operator.OpType.BitwiseOr; savedOperatorLocation = GetLocation (yyVals[0+yyTop]); } break; -case 249: -#line 2114 "cs-parser.jay" +case 257: +#line 2177 "cs-parser.jay" { yyVal = Operator.OpType.ExclusiveOr; savedOperatorLocation = GetLocation (yyVals[0+yyTop]); } break; -case 250: -#line 2115 "cs-parser.jay" +case 258: +#line 2178 "cs-parser.jay" { yyVal = Operator.OpType.LeftShift; savedOperatorLocation = GetLocation (yyVals[0+yyTop]); } break; -case 251: -#line 2116 "cs-parser.jay" +case 259: +#line 2179 "cs-parser.jay" { yyVal = Operator.OpType.RightShift; savedOperatorLocation = GetLocation (yyVals[0+yyTop]); } break; -case 252: -#line 2117 "cs-parser.jay" +case 260: +#line 2180 "cs-parser.jay" { yyVal = Operator.OpType.Equality; savedOperatorLocation = GetLocation (yyVals[0+yyTop]); } break; -case 253: -#line 2118 "cs-parser.jay" +case 261: +#line 2181 "cs-parser.jay" { yyVal = Operator.OpType.Inequality; savedOperatorLocation = GetLocation (yyVals[0+yyTop]); } break; -case 254: -#line 2119 "cs-parser.jay" +case 262: +#line 2182 "cs-parser.jay" { yyVal = Operator.OpType.GreaterThan; savedOperatorLocation = GetLocation (yyVals[0+yyTop]); } break; -case 255: -#line 2120 "cs-parser.jay" +case 263: +#line 2183 "cs-parser.jay" { yyVal = Operator.OpType.LessThan; savedOperatorLocation = GetLocation (yyVals[0+yyTop]); } break; -case 256: -#line 2121 "cs-parser.jay" +case 264: +#line 2184 "cs-parser.jay" { yyVal = Operator.OpType.GreaterThanOrEqual; savedOperatorLocation = GetLocation (yyVals[0+yyTop]); } break; -case 257: -#line 2122 "cs-parser.jay" +case 265: +#line 2185 "cs-parser.jay" { yyVal = Operator.OpType.LessThanOrEqual; savedOperatorLocation = GetLocation (yyVals[0+yyTop]); } break; -case 258: -#line 2129 "cs-parser.jay" +case 266: +#line 2192 "cs-parser.jay" { valid_param_mod = ParameterModifierType.DefaultValue; } break; -case 259: - case_259(); +case 267: + case_267(); break; -case 260: -#line 2148 "cs-parser.jay" +case 268: +#line 2215 "cs-parser.jay" { valid_param_mod = ParameterModifierType.DefaultValue; } break; -case 261: - case_261(); - break; -case 262: - case_262(); - break; -case 263: - case_263(); - break; -case 264: - case_264(); - break; -case 265: - case_265(); - break; -case 266: - case_266(); +case 269: + case_269(); break; -case 267: - case_267(); +case 270: + case_270(); break; -case 269: -#line 2254 "cs-parser.jay" - { current_block = null; yyVal = null; } +case 271: + case_271(); break; case 272: -#line 2266 "cs-parser.jay" - { - ++lexer.parsing_block; - } + case_272(); break; case 273: case_273(); break; case 274: -#line 2276 "cs-parser.jay" - { - ++lexer.parsing_block; - } + case_274(); break; case 275: case_275(); break; -case 276: - case_276(); - break; case 277: - case_277(); - break; -case 278: - case_278(); - break; -case 279: - case_279(); +#line 2325 "cs-parser.jay" + { current_block = null; yyVal = null; } break; case 280: - case_280(); +#line 2337 "cs-parser.jay" + { + ++lexer.parsing_block; + } break; case 281: case_281(); break; case 282: - case_282(); +#line 2347 "cs-parser.jay" + { + ++lexer.parsing_block; + } break; case 283: case_283(); @@ -2236,59 +2277,62 @@ case 283: case 284: case_284(); break; +case 285: + case_285(); + break; case 286: -#line 2392 "cs-parser.jay" - { - ++lexer.parsing_block; - } + case_286(); break; case 287: case_287(); break; +case 288: + case_288(); + break; +case 289: + case_289(); + break; case 290: -#line 2409 "cs-parser.jay" - { - current_event_field.AddDeclarator ((FieldDeclarator) yyVals[0+yyTop]); - } + case_290(); break; case 291: -#line 2413 "cs-parser.jay" - { - current_event_field.AddDeclarator ((FieldDeclarator) yyVals[0+yyTop]); - } + case_291(); break; case 292: case_292(); break; case 293: -#line 2426 "cs-parser.jay" - { - ++lexer.parsing_block; - } - break; -case 294: - case_294(); + case_293(); break; case 295: - case_295(); - break; -case 296: -#line 2451 "cs-parser.jay" +#line 2474 "cs-parser.jay" { - yyVal = yyVals[0+yyTop]; + ++lexer.parsing_block; } break; +case 296: + case_296(); + break; case 299: - case_299(); +#line 2492 "cs-parser.jay" + { + current_event_field.AddDeclarator ((FieldDeclarator) yyVals[0+yyTop]); + } break; case 300: - case_300(); +#line 2496 "cs-parser.jay" + { + current_event_field.AddDeclarator ((FieldDeclarator) yyVals[0+yyTop]); + } break; case 301: case_301(); break; case 302: - case_302(); +#line 2509 "cs-parser.jay" + { + ++lexer.parsing_block; + } break; case 303: case_303(); @@ -2297,10 +2341,10 @@ case 304: case_304(); break; case 305: - case_305(); - break; -case 306: - case_306(); +#line 2534 "cs-parser.jay" + { + yyVal = yyVals[0+yyTop]; + } break; case 308: case_308(); @@ -2317,17 +2361,23 @@ case 311: case 312: case_312(); break; +case 313: + case_313(); + break; case 314: case_314(); break; case 315: case_315(); break; +case 317: + case_317(); + break; case 318: -#line 2619 "cs-parser.jay" - { - lbag.AppendToMember (current_container, GetLocation (yyVals[0+yyTop])); - } + case_318(); + break; +case 319: + case_319(); break; case 320: case_320(); @@ -2338,72 +2388,63 @@ case 321: case 322: case_322(); break; -case 323: - case_323(); - break; case 324: case_324(); break; -case 326: -#line 2693 "cs-parser.jay" - { - valid_param_mod = ParameterModifierType.Ref | ParameterModifierType.Out | ParameterModifierType.Params | ParameterModifierType.DefaultValue; - } - break; -case 327: - case_327(); +case 325: + case_325(); break; case 328: -#line 2712 "cs-parser.jay" +#line 2722 "cs-parser.jay" { - lexer.ConstraintsParsing = false; + lbag.AppendToMember (current_container, GetLocation (yyVals[0+yyTop])); } break; -case 329: - case_329(); +case 330: + case_330(); break; case 331: case_331(); break; +case 332: + case_332(); + break; case 333: case_333(); break; -case 335: - case_335(); +case 334: + case_334(); break; case 336: - case_336(); +#line 2796 "cs-parser.jay" + { + valid_param_mod = ParameterModifierType.Ref | ParameterModifierType.Out | ParameterModifierType.Params | ParameterModifierType.DefaultValue; + } + break; +case 337: + case_337(); break; case 338: - case_338(); +#line 2815 "cs-parser.jay" + { + lexer.ConstraintsParsing = false; + } break; case 339: case_339(); break; -case 340: - case_340(); - break; case 341: case_341(); break; -case 342: -#line 2818 "cs-parser.jay" - { - lexer.parsing_generic_declaration = true; - } - break; case 343: case_343(); break; -case 344: - case_344(); +case 345: + case_345(); break; case 346: case_346(); break; -case 347: - case_347(); - break; case 348: case_348(); break; @@ -2416,207 +2457,203 @@ case 350: case 351: case_351(); break; +case 352: +#line 2921 "cs-parser.jay" + { + lexer.parsing_generic_declaration = true; + } + break; case 353: case_353(); break; case 354: case_354(); break; -case 355: - case_355(); - break; case 356: case_356(); break; case 357: case_357(); break; +case 358: + case_358(); + break; case 359: -#line 2940 "cs-parser.jay" - { - yyVal = new TypeExpression (compiler.BuiltinTypes.Void, GetLocation (yyVals[0+yyTop])); - } + case_359(); break; case 360: -#line 2947 "cs-parser.jay" - { - lexer.parsing_generic_declaration = true; - } + case_360(); break; -case 362: - case_362(); +case 361: + case_361(); + break; +case 363: + case_363(); break; case 364: case_364(); break; +case 365: + case_365(); + break; case 366: case_366(); break; -case 368: -#line 2985 "cs-parser.jay" - { - yyVal = new ComposedCast ((FullNamedExpression) yyVals[-1+yyTop], (ComposedTypeSpecifier) yyVals[0+yyTop]); - } +case 367: + case_367(); break; case 369: - case_369(); - break; -case 370: -#line 3004 "cs-parser.jay" +#line 3046 "cs-parser.jay" { - yyVal = new ComposedCast ((ATypeNameExpression) yyVals[-1+yyTop], (ComposedTypeSpecifier) yyVals[0+yyTop]); + yyVal = new TypeExpression (compiler.BuiltinTypes.Void, GetLocation (yyVals[0+yyTop])); } break; -case 371: - case_371(); - break; -case 372: -#line 3013 "cs-parser.jay" +case 370: +#line 3053 "cs-parser.jay" { - yyVal = new ComposedCast ((FullNamedExpression) yyVals[-1+yyTop], (ComposedTypeSpecifier) yyVals[0+yyTop]); + lexer.parsing_generic_declaration = true; } break; -case 373: -#line 3017 "cs-parser.jay" - { - yyVal = new ComposedCast (new TypeExpression (compiler.BuiltinTypes.Void, GetLocation (yyVals[-1+yyTop])), (ComposedTypeSpecifier) yyVals[0+yyTop]); - } +case 372: + case_372(); break; case 374: case_374(); break; -case 375: - case_375(); - break; case 376: case_376(); break; -case 377: -#line 3051 "cs-parser.jay" - { yyVal = new TypeExpression (compiler.BuiltinTypes.Object, GetLocation (yyVals[0+yyTop])); } - break; case 378: -#line 3052 "cs-parser.jay" - { yyVal = new TypeExpression (compiler.BuiltinTypes.String, GetLocation (yyVals[0+yyTop])); } +#line 3091 "cs-parser.jay" + { + yyVal = new ComposedCast ((FullNamedExpression) yyVals[-1+yyTop], (ComposedTypeSpecifier) yyVals[0+yyTop]); + } break; case 379: -#line 3053 "cs-parser.jay" - { yyVal = new TypeExpression (compiler.BuiltinTypes.Bool, GetLocation (yyVals[0+yyTop])); } + case_379(); break; case 380: -#line 3054 "cs-parser.jay" - { yyVal = new TypeExpression (compiler.BuiltinTypes.Decimal, GetLocation (yyVals[0+yyTop])); } +#line 3110 "cs-parser.jay" + { + yyVal = new ComposedCast ((ATypeNameExpression) yyVals[-1+yyTop], (ComposedTypeSpecifier) yyVals[0+yyTop]); + } break; case 381: -#line 3055 "cs-parser.jay" - { yyVal = new TypeExpression (compiler.BuiltinTypes.Float, GetLocation (yyVals[0+yyTop])); } + case_381(); break; case 382: -#line 3056 "cs-parser.jay" - { yyVal = new TypeExpression (compiler.BuiltinTypes.Double, GetLocation (yyVals[0+yyTop])); } - break; -case 384: -#line 3061 "cs-parser.jay" - { yyVal = new TypeExpression (compiler.BuiltinTypes.SByte, GetLocation (yyVals[0+yyTop])); } +#line 3119 "cs-parser.jay" + { + yyVal = new ComposedCast ((FullNamedExpression) yyVals[-1+yyTop], (ComposedTypeSpecifier) yyVals[0+yyTop]); + } + break; +case 383: +#line 3123 "cs-parser.jay" + { + yyVal = new ComposedCast (new TypeExpression (compiler.BuiltinTypes.Void, GetLocation (yyVals[-1+yyTop])), (ComposedTypeSpecifier) yyVals[0+yyTop]); + } + break; +case 384: + case_384(); break; case 385: -#line 3062 "cs-parser.jay" - { yyVal = new TypeExpression (compiler.BuiltinTypes.Byte, GetLocation (yyVals[0+yyTop])); } + case_385(); break; case 386: -#line 3063 "cs-parser.jay" - { yyVal = new TypeExpression (compiler.BuiltinTypes.Short, GetLocation (yyVals[0+yyTop])); } + case_386(); break; case 387: -#line 3064 "cs-parser.jay" - { yyVal = new TypeExpression (compiler.BuiltinTypes.UShort, GetLocation (yyVals[0+yyTop])); } +#line 3157 "cs-parser.jay" + { yyVal = new TypeExpression (compiler.BuiltinTypes.Object, GetLocation (yyVals[0+yyTop])); } break; case 388: -#line 3065 "cs-parser.jay" - { yyVal = new TypeExpression (compiler.BuiltinTypes.Int, GetLocation (yyVals[0+yyTop])); } +#line 3158 "cs-parser.jay" + { yyVal = new TypeExpression (compiler.BuiltinTypes.String, GetLocation (yyVals[0+yyTop])); } break; case 389: -#line 3066 "cs-parser.jay" - { yyVal = new TypeExpression (compiler.BuiltinTypes.UInt, GetLocation (yyVals[0+yyTop])); } +#line 3159 "cs-parser.jay" + { yyVal = new TypeExpression (compiler.BuiltinTypes.Bool, GetLocation (yyVals[0+yyTop])); } break; case 390: -#line 3067 "cs-parser.jay" - { yyVal = new TypeExpression (compiler.BuiltinTypes.Long, GetLocation (yyVals[0+yyTop])); } +#line 3160 "cs-parser.jay" + { yyVal = new TypeExpression (compiler.BuiltinTypes.Decimal, GetLocation (yyVals[0+yyTop])); } break; case 391: -#line 3068 "cs-parser.jay" - { yyVal = new TypeExpression (compiler.BuiltinTypes.ULong, GetLocation (yyVals[0+yyTop])); } +#line 3161 "cs-parser.jay" + { yyVal = new TypeExpression (compiler.BuiltinTypes.Float, GetLocation (yyVals[0+yyTop])); } break; case 392: -#line 3069 "cs-parser.jay" - { yyVal = new TypeExpression (compiler.BuiltinTypes.Char, GetLocation (yyVals[0+yyTop])); } - break; -case 413: - case_413(); +#line 3162 "cs-parser.jay" + { yyVal = new TypeExpression (compiler.BuiltinTypes.Double, GetLocation (yyVals[0+yyTop])); } break; -case 414: - case_414(); +case 394: +#line 3167 "cs-parser.jay" + { yyVal = new TypeExpression (compiler.BuiltinTypes.SByte, GetLocation (yyVals[0+yyTop])); } break; -case 418: -#line 3116 "cs-parser.jay" - { yyVal = new NullLiteral (GetLocation (yyVals[0+yyTop])); } +case 395: +#line 3168 "cs-parser.jay" + { yyVal = new TypeExpression (compiler.BuiltinTypes.Byte, GetLocation (yyVals[0+yyTop])); } break; -case 419: -#line 3120 "cs-parser.jay" - { yyVal = new BoolLiteral (compiler.BuiltinTypes, true, GetLocation (yyVals[0+yyTop])); } +case 396: +#line 3169 "cs-parser.jay" + { yyVal = new TypeExpression (compiler.BuiltinTypes.Short, GetLocation (yyVals[0+yyTop])); } break; -case 420: -#line 3121 "cs-parser.jay" - { yyVal = new BoolLiteral (compiler.BuiltinTypes, false, GetLocation (yyVals[0+yyTop])); } +case 397: +#line 3170 "cs-parser.jay" + { yyVal = new TypeExpression (compiler.BuiltinTypes.UShort, GetLocation (yyVals[0+yyTop])); } break; -case 425: - case_425(); +case 398: +#line 3171 "cs-parser.jay" + { yyVal = new TypeExpression (compiler.BuiltinTypes.Int, GetLocation (yyVals[0+yyTop])); } break; -case 426: -#line 3154 "cs-parser.jay" - { - yyVal = new ParenthesizedExpression ((Expression) yyVals[-1+yyTop]); - } +case 399: +#line 3172 "cs-parser.jay" + { yyVal = new TypeExpression (compiler.BuiltinTypes.UInt, GetLocation (yyVals[0+yyTop])); } break; -case 427: - case_427(); +case 400: +#line 3173 "cs-parser.jay" + { yyVal = new TypeExpression (compiler.BuiltinTypes.Long, GetLocation (yyVals[0+yyTop])); } break; -case 428: - case_428(); +case 401: +#line 3174 "cs-parser.jay" + { yyVal = new TypeExpression (compiler.BuiltinTypes.ULong, GetLocation (yyVals[0+yyTop])); } break; -case 429: - case_429(); +case 402: +#line 3175 "cs-parser.jay" + { yyVal = new TypeExpression (compiler.BuiltinTypes.Char, GetLocation (yyVals[0+yyTop])); } break; -case 430: - case_430(); +case 423: + case_423(); break; -case 431: -#line 3189 "cs-parser.jay" - { - yyVal = new CompletionMemberAccess ((Expression) yyVals[-2+yyTop], null,GetLocation (yyVals[0+yyTop])); - } +case 424: + case_424(); break; -case 432: - case_432(); +case 428: +#line 3222 "cs-parser.jay" + { yyVal = new NullLiteral (GetLocation (yyVals[0+yyTop])); } break; -case 433: -#line 3197 "cs-parser.jay" - { - yyVal = new CompletionMemberAccess ((Expression) yyVals[-2+yyTop], null, lexer.Location); - } +case 429: +#line 3226 "cs-parser.jay" + { yyVal = new BoolLiteral (compiler.BuiltinTypes, true, GetLocation (yyVals[0+yyTop])); } break; -case 434: - case_434(); +case 430: +#line 3227 "cs-parser.jay" + { yyVal = new BoolLiteral (compiler.BuiltinTypes, false, GetLocation (yyVals[0+yyTop])); } break; case 435: case_435(); break; case 436: - case_436(); +#line 3260 "cs-parser.jay" + { + yyVal = new ParenthesizedExpression ((Expression) yyVals[-1+yyTop], GetLocation (yyVals[-2+yyTop])); + } break; case 437: -#line 3221 "cs-parser.jay" - { yyVal = null; } + case_437(); + break; +case 438: + case_438(); break; case 439: case_439(); @@ -2625,20 +2662,22 @@ case 440: case_440(); break; case 441: -#line 3244 "cs-parser.jay" - { yyVal = null; } + case_441(); break; case 442: -#line 3248 "cs-parser.jay" +#line 3298 "cs-parser.jay" { - yyVal = yyVals[0+yyTop]; - } + yyVal = new CompletionMemberAccess ((Expression) yyVals[-2+yyTop], null,GetLocation (yyVals[0+yyTop])); + } break; case 443: case_443(); break; case 444: - case_444(); +#line 3306 "cs-parser.jay" + { + yyVal = new CompletionMemberAccess ((Expression) yyVals[-2+yyTop], null, lexer.Location); + } break; case 445: case_445(); @@ -2647,24 +2686,31 @@ case 446: case_446(); break; case 447: -#line 3281 "cs-parser.jay" - { - yyVal = new CompletionElementInitializer (null, GetLocation (yyVals[0+yyTop])); - } + case_447(); break; case 448: case_448(); break; case 449: - case_449(); +#line 3336 "cs-parser.jay" + { yyVal = null; } break; -case 450: - case_450(); +case 451: + case_451(); + break; +case 452: + case_452(); break; case 453: -#line 3312 "cs-parser.jay" +#line 3358 "cs-parser.jay" { yyVal = null; } break; +case 454: +#line 3362 "cs-parser.jay" + { + yyVal = yyVals[0+yyTop]; + } + break; case 455: case_455(); break; @@ -2681,22 +2727,26 @@ case 459: case_459(); break; case 460: -#line 3365 "cs-parser.jay" +#line 3401 "cs-parser.jay" { - yyVal = new Argument ((Expression) yyVals[0+yyTop]); + yyVal = new CompletionElementInitializer (null, GetLocation (yyVals[0+yyTop])); } break; -case 464: - case_464(); +case 461: + case_461(); + break; +case 462: + case_462(); break; -case 465: - case_465(); +case 463: + case_463(); break; case 466: - case_466(); +#line 3432 "cs-parser.jay" + { yyVal = null; } break; -case 467: - case_467(); +case 468: + case_468(); break; case 469: case_469(); @@ -2711,46 +2761,28 @@ case 472: case_472(); break; case 473: - case_473(); - break; -case 474: - case_474(); - break; -case 475: - case_475(); - break; -case 476: - case_476(); - break; -case 477: -#line 3462 "cs-parser.jay" +#line 3486 "cs-parser.jay" { - yyVal = new Argument ((Expression) yyVals[0+yyTop]); + yyVal = new Argument ((Expression) yyVals[0+yyTop]); } break; +case 477: + case_477(); + break; +case 478: + case_478(); + break; case 479: -#line 3470 "cs-parser.jay" - { - yyVal = new This (GetLocation (yyVals[0+yyTop])); - } + case_479(); break; case 480: case_480(); break; -case 481: - case_481(); - break; case 482: -#line 3490 "cs-parser.jay" - { - yyVal = new UnaryMutator (UnaryMutator.Mode.PostIncrement, (Expression) yyVals[-1+yyTop], GetLocation (yyVals[0+yyTop])); - } + case_482(); break; case 483: -#line 3497 "cs-parser.jay" - { - yyVal = new UnaryMutator (UnaryMutator.Mode.PostDecrement, (Expression) yyVals[-1+yyTop], GetLocation (yyVals[0+yyTop])); - } + case_483(); break; case 484: case_484(); @@ -2768,15 +2800,15 @@ case 488: case_488(); break; case 489: - case_489(); - break; -case 490: - case_490(); +#line 3579 "cs-parser.jay" + { + yyVal = new Argument ((Expression) yyVals[0+yyTop]); + } break; case 491: -#line 3564 "cs-parser.jay" +#line 3587 "cs-parser.jay" { - ++lexer.parsing_type; + yyVal = new This (GetLocation (yyVals[0+yyTop])); } break; case 492: @@ -2785,9 +2817,23 @@ case 492: case 493: case_493(); break; +case 494: +#line 3607 "cs-parser.jay" + { + yyVal = new UnaryMutator (UnaryMutator.Mode.PostIncrement, (Expression) yyVals[-1+yyTop], GetLocation (yyVals[0+yyTop])); + } + break; +case 495: +#line 3614 "cs-parser.jay" + { + yyVal = new UnaryMutator (UnaryMutator.Mode.PostDecrement, (Expression) yyVals[-1+yyTop], GetLocation (yyVals[0+yyTop])); + } + break; case 496: -#line 3591 "cs-parser.jay" - { yyVal = null; } + case_496(); + break; +case 497: + case_497(); break; case 498: case_498(); @@ -2805,43 +2851,44 @@ case 502: case_502(); break; case 503: - case_503(); - break; -case 507: - case_507(); +#line 3681 "cs-parser.jay" + { + ++lexer.parsing_type; + } break; -case 508: - case_508(); +case 504: + case_504(); break; -case 509: - case_509(); +case 505: + case_505(); break; -case 510: -#line 3669 "cs-parser.jay" +case 506: +#line 3703 "cs-parser.jay" { - yyVal = 2; + yyVal = new EmptyCompletion (); } break; +case 509: +#line 3712 "cs-parser.jay" + { yyVal = null; } + break; case 511: -#line 3673 "cs-parser.jay" - { - yyVal = ((int) yyVals[-1+yyTop]) + 1; - } + case_511(); break; case 512: -#line 3680 "cs-parser.jay" - { - yyVal = null; - } + case_512(); break; case 513: -#line 3684 "cs-parser.jay" +#line 3734 "cs-parser.jay" { - yyVal = yyVals[0+yyTop]; + yyVal = new EmptyCompletion (); } break; case 514: - case_514(); +#line 3738 "cs-parser.jay" + { + yyVal = yyVals[-1+yyTop]; + } break; case 515: case_515(); @@ -2853,13 +2900,7 @@ case 517: case_517(); break; case 518: -#line 3728 "cs-parser.jay" - { - lexer.TypeOfParsing = true; - } - break; -case 519: - case_519(); + case_518(); break; case 522: case_522(); @@ -2871,16 +2912,28 @@ case 524: case_524(); break; case 525: - case_525(); +#line 3798 "cs-parser.jay" + { + yyVal = 2; + } break; case 526: - case_526(); +#line 3802 "cs-parser.jay" + { + yyVal = ((int) yyVals[-1+yyTop]) + 1; + } break; case 527: - case_527(); +#line 3809 "cs-parser.jay" + { + yyVal = null; + } break; case 528: - case_528(); +#line 3813 "cs-parser.jay" + { + yyVal = yyVals[0+yyTop]; + } break; case 529: case_529(); @@ -2895,37 +2948,25 @@ case 532: case_532(); break; case 533: - case_533(); - break; -case 534: -#line 3848 "cs-parser.jay" +#line 3857 "cs-parser.jay" { - start_anonymous (false, (ParametersCompiled) yyVals[0+yyTop], false, GetLocation (yyVals[-1+yyTop])); + lexer.TypeOfParsing = true; } break; -case 535: - case_535(); - break; -case 536: -#line 3861 "cs-parser.jay" - { - start_anonymous (false, (ParametersCompiled) yyVals[0+yyTop], true, GetLocation (yyVals[-2+yyTop])); - } +case 534: + case_534(); break; case 537: case_537(); break; case 538: -#line 3878 "cs-parser.jay" - { - yyVal = ParametersCompiled.Undefined; - } + case_538(); + break; +case 539: + case_539(); break; case 540: -#line 3886 "cs-parser.jay" - { - valid_param_mod = ParameterModifierType.Ref | ParameterModifierType.Out; - } + case_540(); break; case 541: case_541(); @@ -2933,17 +2974,14 @@ case 541: case 542: case_542(); break; +case 543: + case_543(); + break; case 544: -#line 3912 "cs-parser.jay" - { - yyVal = new Unary (Unary.Operator.LogicalNot, (Expression) yyVals[0+yyTop], GetLocation (yyVals[-1+yyTop])); - } + case_544(); break; case 545: -#line 3916 "cs-parser.jay" - { - yyVal = new Unary (Unary.Operator.OnesComplement, (Expression) yyVals[0+yyTop], GetLocation (yyVals[-1+yyTop])); - } + case_545(); break; case 546: case_546(); @@ -2951,120 +2989,156 @@ case 546: case 547: case_547(); break; +case 548: + case_548(); + break; case 549: -#line 3952 "cs-parser.jay" - { - yyVal = new Unary (Unary.Operator.UnaryPlus, (Expression) yyVals[0+yyTop], GetLocation (yyVals[-1+yyTop])); - } + case_549(); break; case 550: -#line 3956 "cs-parser.jay" - { - yyVal = new Unary (Unary.Operator.UnaryNegation, (Expression) yyVals[0+yyTop], GetLocation (yyVals[-1+yyTop])); - } + case_550(); break; case 551: -#line 3960 "cs-parser.jay" - { - yyVal = new UnaryMutator (UnaryMutator.Mode.PreIncrement, (Expression) yyVals[0+yyTop], GetLocation (yyVals[-1+yyTop])); - } + case_551(); break; case 552: -#line 3964 "cs-parser.jay" +#line 4000 "cs-parser.jay" { - yyVal = new UnaryMutator (UnaryMutator.Mode.PreDecrement, (Expression) yyVals[0+yyTop], GetLocation (yyVals[-1+yyTop])); + start_anonymous (false, (ParametersCompiled) yyVals[0+yyTop], false, GetLocation (yyVals[-1+yyTop])); } break; case 553: -#line 3968 "cs-parser.jay" - { - yyVal = new Indirection ((Expression) yyVals[0+yyTop], GetLocation (yyVals[-1+yyTop])); - } + case_553(); break; case 554: -#line 3972 "cs-parser.jay" +#line 4013 "cs-parser.jay" { - yyVal = new Unary (Unary.Operator.AddressOf, (Expression) yyVals[0+yyTop], GetLocation (yyVals[-1+yyTop])); + start_anonymous (false, (ParametersCompiled) yyVals[0+yyTop], true, GetLocation (yyVals[-2+yyTop])); } break; -case 556: - case_556(); +case 555: + case_555(); break; -case 557: - case_557(); +case 556: +#line 4030 "cs-parser.jay" + { + yyVal = ParametersCompiled.Undefined; + } break; case 558: - case_558(); +#line 4038 "cs-parser.jay" + { + valid_param_mod = ParameterModifierType.Ref | ParameterModifierType.Out; + } + break; +case 559: + case_559(); break; case 560: case_560(); break; -case 561: - case_561(); - break; case 562: -#line 4009 "cs-parser.jay" +#line 4064 "cs-parser.jay" { - yyVal = new As ((Expression) yyVals[-2+yyTop], (Expression) yyVals[0+yyTop], GetLocation (yyVals[-1+yyTop])); + yyVal = new Unary (Unary.Operator.LogicalNot, (Expression) yyVals[0+yyTop], GetLocation (yyVals[-1+yyTop])); } break; case 563: -#line 4013 "cs-parser.jay" +#line 4068 "cs-parser.jay" { - yyVal = new Is ((Expression) yyVals[-2+yyTop], (Expression) yyVals[0+yyTop], GetLocation (yyVals[-1+yyTop])); + yyVal = new Unary (Unary.Operator.OnesComplement, (Expression) yyVals[0+yyTop], GetLocation (yyVals[-1+yyTop])); } break; +case 564: + case_564(); + break; case 565: case_565(); break; case 566: case_566(); break; +case 567: + case_567(); + break; case 568: case_568(); break; case 569: case_569(); break; -case 570: - case_570(); - break; case 571: - case_571(); +#line 4132 "cs-parser.jay" + { + yyVal = new Unary (Unary.Operator.UnaryPlus, (Expression) yyVals[0+yyTop], GetLocation (yyVals[-1+yyTop])); + } + break; +case 572: +#line 4136 "cs-parser.jay" + { + yyVal = new Unary (Unary.Operator.UnaryNegation, (Expression) yyVals[0+yyTop], GetLocation (yyVals[-1+yyTop])); + } break; case 573: - case_573(); +#line 4140 "cs-parser.jay" + { + yyVal = new UnaryMutator (UnaryMutator.Mode.PreIncrement, (Expression) yyVals[0+yyTop], GetLocation (yyVals[-1+yyTop])); + } break; case 574: - case_574(); +#line 4144 "cs-parser.jay" + { + yyVal = new UnaryMutator (UnaryMutator.Mode.PreDecrement, (Expression) yyVals[0+yyTop], GetLocation (yyVals[-1+yyTop])); + } + break; +case 575: +#line 4148 "cs-parser.jay" + { + yyVal = new Indirection ((Expression) yyVals[0+yyTop], GetLocation (yyVals[-1+yyTop])); + } break; case 576: - case_576(); +#line 4152 "cs-parser.jay" + { + yyVal = new Unary (Unary.Operator.AddressOf, (Expression) yyVals[0+yyTop], GetLocation (yyVals[-1+yyTop])); + } + break; +case 577: + case_577(); break; case 578: case_578(); break; +case 579: + case_579(); + break; case 580: case_580(); break; +case 581: + case_581(); + break; case 582: case_582(); break; case 584: case_584(); break; +case 585: + case_585(); + break; case 586: case_586(); break; +case 587: + case_587(); + break; case 588: case_588(); break; case 589: case_589(); break; -case 590: - case_590(); - break; case 591: case_591(); break; @@ -3072,10 +3146,16 @@ case 592: case_592(); break; case 593: - case_593(); +#line 4246 "cs-parser.jay" + { + yyVal = new As ((Expression) yyVals[-2+yyTop], (Expression) yyVals[0+yyTop], GetLocation (yyVals[-1+yyTop])); + } break; case 594: - case_594(); +#line 4250 "cs-parser.jay" + { + yyVal = new Is ((Expression) yyVals[-2+yyTop], (Expression) yyVals[0+yyTop], GetLocation (yyVals[-1+yyTop])); + } break; case 595: case_595(); @@ -3095,9 +3175,6 @@ case 599: case 600: case_600(); break; -case 601: - case_601(); - break; case 602: case_602(); break; @@ -3110,31 +3187,30 @@ case 604: case 605: case_605(); break; -case 606: -#line 4241 "cs-parser.jay" - { yyVal = ParametersCompiled.EmptyReadOnlyParameters; } - break; case 607: case_607(); break; +case 608: + case_608(); + break; +case 609: + case_609(); + break; case 610: -#line 4257 "cs-parser.jay" - { - start_block (Location.Null); - } + case_610(); break; case 611: case_611(); break; +case 612: + case_612(); + break; case 613: case_613(); break; case 614: case_614(); break; -case 615: - case_615(); - break; case 616: case_616(); break; @@ -3142,34 +3218,28 @@ case 617: case_617(); break; case 618: -#line 4302 "cs-parser.jay" - { - valid_param_mod = ParameterModifierType.Ref | ParameterModifierType.Out; - } + case_618(); break; case 619: case_619(); break; -case 620: - case_620(); - break; case 621: -#line 4316 "cs-parser.jay" - { - valid_param_mod = ParameterModifierType.Ref | ParameterModifierType.Out; - } + case_621(); break; case 622: case_622(); break; -case 623: - case_623(); +case 624: + case_624(); break; -case 629: -#line 4341 "cs-parser.jay" - { - yyVal = new ArglistAccess (GetLocation (yyVals[0+yyTop])); - } +case 625: + case_625(); + break; +case 627: + case_627(); + break; +case 628: + case_628(); break; case 630: case_630(); @@ -3177,27 +3247,15 @@ case 630: case 631: case_631(); break; -case 632: - case_632(); +case 633: + case_633(); break; case 634: -#line 4370 "cs-parser.jay" - { - yyVal = new BooleanExpression ((Expression) yyVals[0+yyTop]); - } - break; -case 635: -#line 4383 "cs-parser.jay" - { - lexer.ConstraintsParsing = true; - } + case_634(); break; case 636: case_636(); break; -case 637: - case_637(); - break; case 638: case_638(); break; @@ -3205,21 +3263,19 @@ case 639: case_639(); break; case 640: -#line 4428 "cs-parser.jay" - { yyVal = null; } + case_640(); break; case 641: -#line 4430 "cs-parser.jay" - { yyVal = yyVals[0+yyTop]; StoreModifierLocation (Modifiers.PARTIAL, GetLocation (yyVals[0+yyTop])); } + case_641(); break; case 642: case_642(); break; case 643: -#line 4443 "cs-parser.jay" - { - lexer.parsing_modifiers = false; - } + case_643(); + break; +case 644: + case_644(); break; case 645: case_645(); @@ -3264,22 +3320,23 @@ case 658: case_658(); break; case 659: - case_659(); +#line 4626 "cs-parser.jay" + { yyVal = ParametersCompiled.EmptyReadOnlyParameters; } break; case 660: case_660(); break; +case 661: +#line 4637 "cs-parser.jay" + { + start_block (Location.Null); + } + break; case 662: case_662(); break; -case 663: - case_663(); - break; -case 665: -#line 4569 "cs-parser.jay" - { - yyVal = yyVals[0+yyTop]; - } +case 664: + case_664(); break; case 666: case_666(); @@ -3303,24 +3360,21 @@ case 672: case_672(); break; case 673: - case_673(); - break; -case 674: -#line 4662 "cs-parser.jay" +#line 4704 "cs-parser.jay" { - yyVal = new SpecialContraintExpr (SpecialConstraint.Class, GetLocation (yyVals[0+yyTop])); + valid_param_mod = ParameterModifierType.Ref | ParameterModifierType.Out; } break; +case 674: + case_674(); + break; case 675: -#line 4666 "cs-parser.jay" - { - yyVal = new SpecialContraintExpr (SpecialConstraint.Struct, GetLocation (yyVals[0+yyTop])); - } + case_675(); break; case 676: -#line 4673 "cs-parser.jay" +#line 4718 "cs-parser.jay" { - yyVal = Variance.None; + valid_param_mod = ParameterModifierType.Ref | ParameterModifierType.Out; } break; case 677: @@ -3329,68 +3383,156 @@ case 677: case 678: case_678(); break; -case 679: - case_679(); - break; -case 680: - case_680(); - break; -case 681: -#line 4718 "cs-parser.jay" +case 684: +#line 4743 "cs-parser.jay" { - yyVal = yyVals[0+yyTop]; + yyVal = new ArglistAccess (GetLocation (yyVals[0+yyTop])); } break; -case 682: - case_682(); - break; -case 683: - case_683(); - break; -case 684: - case_684(); - break; case 685: case_685(); break; case 686: case_686(); break; -case 691: -#line 4767 "cs-parser.jay" +case 687: + case_687(); + break; +case 689: +#line 4772 "cs-parser.jay" { - current_block.AddStatement ((Statement) yyVals[0+yyTop]); + yyVal = new BooleanExpression ((Expression) yyVals[0+yyTop]); + } + break; +case 690: +#line 4779 "cs-parser.jay" + { + yyVal = null; } break; case 692: -#line 4771 "cs-parser.jay" + case_692(); + break; +case 693: +#line 4797 "cs-parser.jay" { - current_block.AddStatement ((Statement) yyVals[0+yyTop]); + yyVal = null; } break; case 694: - case_694(); +#line 4801 "cs-parser.jay" + { + yyVal = null; + } break; case 695: - case_695(); +#line 4805 "cs-parser.jay" + { + yyVal = yyVals[0+yyTop]; + } + break; +case 696: +#line 4809 "cs-parser.jay" + { + ++lexer.parsing_block; + } + break; +case 697: + case_697(); break; case 698: -#line 4805 "cs-parser.jay" +#line 4829 "cs-parser.jay" { - current_block.AddStatement ((Statement) yyVals[0+yyTop]); } break; case 699: -#line 4809 "cs-parser.jay" + case_699(); + break; +case 700: + case_700(); + break; +case 701: + case_701(); + break; +case 702: + case_702(); + break; +case 703: +#line 4881 "cs-parser.jay" + { yyVal = null; } + break; +case 704: +#line 4883 "cs-parser.jay" + { yyVal = yyVals[0+yyTop]; StoreModifierLocation (Modifiers.PARTIAL, GetLocation (yyVals[0+yyTop])); } + break; +case 705: + case_705(); + break; +case 706: +#line 4896 "cs-parser.jay" { - current_block.AddStatement ((Statement) yyVals[0+yyTop]); + lexer.parsing_modifiers = false; } break; -case 728: - case_728(); +case 708: + case_708(); + break; +case 709: + case_709(); + break; +case 710: + case_710(); + break; +case 711: + case_711(); + break; +case 712: + case_712(); + break; +case 713: + case_713(); + break; +case 714: + case_714(); + break; +case 715: + case_715(); + break; +case 716: + case_716(); + break; +case 717: + case_717(); + break; +case 718: + case_718(); + break; +case 719: + case_719(); + break; +case 720: + case_720(); + break; +case 721: + case_721(); + break; +case 722: + case_722(); + break; +case 723: + case_723(); + break; +case 726: + case_726(); + break; +case 727: + case_727(); break; case 729: - case_729(); +#line 5026 "cs-parser.jay" + { + yyVal = yyVals[0+yyTop]; + } break; case 730: case_730(); @@ -3401,6 +3543,12 @@ case 731: case 732: case_732(); break; +case 733: + case_733(); + break; +case 734: + case_734(); + break; case 735: case_735(); break; @@ -3411,30 +3559,39 @@ case 737: case_737(); break; case 738: - case_738(); +#line 5119 "cs-parser.jay" + { + yyVal = new SpecialContraintExpr (SpecialConstraint.Class, GetLocation (yyVals[0+yyTop])); + } break; case 739: -#line 4953 "cs-parser.jay" +#line 5123 "cs-parser.jay" { - yyVal = new ComposedCast ((FullNamedExpression) yyVals[-1+yyTop], (ComposedTypeSpecifier) yyVals[0+yyTop]); + yyVal = new SpecialContraintExpr (SpecialConstraint.Struct, GetLocation (yyVals[0+yyTop])); } break; case 740: -#line 4957 "cs-parser.jay" +#line 5130 "cs-parser.jay" { - yyVal = new ComposedCast (new TypeExpression (compiler.BuiltinTypes.Void, GetLocation (yyVals[-1+yyTop])), (ComposedTypeSpecifier) yyVals[0+yyTop]); + yyVal = null; } break; case 741: case_741(); break; +case 742: + case_742(); + break; case 743: case_743(); break; case 744: -#line 4978 "cs-parser.jay" + case_744(); + break; +case 745: +#line 5175 "cs-parser.jay" { - yyVal = ComposedTypeSpecifier.CreatePointer (GetLocation (yyVals[0+yyTop])); + yyVal = yyVals[0+yyTop]; } break; case 746: @@ -3452,99 +3609,42 @@ case 749: case 750: case_750(); break; +case 751: + case_751(); + break; case 752: case_752(); break; -case 754: - case_754(); - break; -case 755: - case_755(); +case 757: +#line 5237 "cs-parser.jay" + { + current_block.AddStatement ((Statement) yyVals[0+yyTop]); + } break; -case 756: - case_756(); +case 758: +#line 5241 "cs-parser.jay" + { + current_block.AddStatement ((Statement) yyVals[0+yyTop]); + } break; case 760: case_760(); break; -case 763: - case_763(); +case 761: + case_761(); break; case 764: - case_764(); - break; -case 765: -#line 5113 "cs-parser.jay" +#line 5275 "cs-parser.jay" { - report.Error (145, lexer.Location, "A const field requires a value to be provided"); + current_block.AddStatement ((Statement) yyVals[0+yyTop]); } break; -case 766: - case_766(); - break; -case 771: - case_771(); - break; -case 773: - case_773(); - break; -case 774: - case_774(); - break; -case 775: - case_775(); - break; -case 776: -#line 5163 "cs-parser.jay" - { yyVal = yyVals[-1+yyTop]; } - break; -case 777: - case_777(); - break; -case 778: -#line 5173 "cs-parser.jay" - { yyVal = yyVals[-1+yyTop]; } - break; -case 779: -#line 5174 "cs-parser.jay" - { yyVal = yyVals[-1+yyTop]; } - break; -case 780: - case_780(); - break; -case 781: - case_781(); - break; -case 782: - case_782(); - break; -case 785: - case_785(); - break; -case 786: - case_786(); - break; -case 787: - case_787(); - break; -case 788: -#line 5249 "cs-parser.jay" +case 765: +#line 5279 "cs-parser.jay" { - start_block (GetLocation (yyVals[0+yyTop])); + current_block.AddStatement ((Statement) yyVals[0+yyTop]); } break; -case 789: - case_789(); - break; -case 790: - case_790(); - break; -case 791: - case_791(); - break; -case 793: - case_793(); - break; case 794: case_794(); break; @@ -3552,82 +3652,70 @@ case 795: case_795(); break; case 796: -#line 5300 "cs-parser.jay" - { - current_block = current_block.CreateSwitchBlock (lexer.Location); - } + case_796(); break; case 797: -#line 5304 "cs-parser.jay" - { - yyVal = new SwitchSection ((List) yyVals[-2+yyTop], current_block); - } + case_797(); break; case 798: case_798(); break; -case 799: - case_799(); - break; -case 800: - case_800(); - break; case 801: case_801(); break; case 802: -#line 5338 "cs-parser.jay" + case_802(); + break; +case 803: + case_803(); + break; +case 804: + case_804(); + break; +case 805: +#line 5423 "cs-parser.jay" { - yyVal = new SwitchLabel (null, GetLocation (yyVals[0+yyTop])); + yyVal = new ComposedCast ((FullNamedExpression) yyVals[-1+yyTop], (ComposedTypeSpecifier) yyVals[0+yyTop]); + } + break; +case 806: +#line 5427 "cs-parser.jay" + { + yyVal = new ComposedCast (new TypeExpression (compiler.BuiltinTypes.Void, GetLocation (yyVals[-1+yyTop])), (ComposedTypeSpecifier) yyVals[0+yyTop]); } break; case 807: case_807(); break; -case 808: - case_808(); - break; case 809: case_809(); break; case 810: - case_810(); - break; -case 811: - case_811(); +#line 5448 "cs-parser.jay" + { + yyVal = ComposedTypeSpecifier.CreatePointer (GetLocation (yyVals[0+yyTop])); + } break; case 812: - case_812(); - break; -case 813: -#line 5399 "cs-parser.jay" +#line 5456 "cs-parser.jay" { - yyVal = yyVals[0+yyTop]; + yyVal = Error_AwaitAsIdentifier (yyVals[0+yyTop]); } break; +case 813: + case_813(); + break; case 814: case_814(); break; case 815: -#line 5414 "cs-parser.jay" - { - yyVal = yyVals[0+yyTop]; - } + case_815(); break; case 816: case_816(); break; -case 817: - case_817(); - break; case 818: -#line 5435 "cs-parser.jay" - { - yyVal = yyVals[0+yyTop]; - } - break; -case 819: - case_819(); + case_818(); break; case 820: case_820(); @@ -3635,57 +3723,60 @@ case 820: case 821: case_821(); break; -case 822: -#line 5469 "cs-parser.jay" - { yyVal = new EmptyStatement (lexer.Location); } - break; -case 824: - case_824(); - break; case 825: case_825(); break; -case 827: -#line 5490 "cs-parser.jay" - { yyVal = null; } +case 828: + case_828(); break; case 829: -#line 5495 "cs-parser.jay" - { yyVal = new EmptyStatement (lexer.Location); } - break; -case 833: - case_833(); + case_829(); break; -case 834: - case_834(); +case 830: +#line 5570 "cs-parser.jay" + { + report.Error (145, lexer.Location, "A const field requires a value to be provided"); + } break; -case 835: - case_835(); +case 831: + case_831(); break; case 836: case_836(); break; -case 837: - case_837(); - break; case 838: case_838(); break; case 839: case_839(); break; +case 840: + case_840(); + break; +case 841: +#line 5620 "cs-parser.jay" + { yyVal = yyVals[-1+yyTop]; } + break; +case 842: + case_842(); + break; +case 843: +#line 5630 "cs-parser.jay" + { yyVal = yyVals[-1+yyTop]; } + break; +case 844: +#line 5631 "cs-parser.jay" + { yyVal = yyVals[-1+yyTop]; } + break; +case 845: + case_845(); + break; case 846: case_846(); break; case 847: case_847(); break; -case 848: - case_848(); - break; -case 849: - case_849(); - break; case 850: case_850(); break; @@ -3696,7 +3787,10 @@ case 852: case_852(); break; case 853: - case_853(); +#line 5703 "cs-parser.jay" + { + start_block (GetLocation (yyVals[0+yyTop])); + } break; case 854: case_854(); @@ -3705,25 +3799,25 @@ case 855: case_855(); break; case 856: - case_856(); - break; -case 857: - case_857(); - break; -case 858: - case_858(); - break; -case 859: - case_859(); +#line 5723 "cs-parser.jay" + { + report.Warning (1522, 1, current_block.StartLocation, "Empty switch block"); + } break; -case 862: -#line 5735 "cs-parser.jay" +case 860: +#line 5733 "cs-parser.jay" { - yyVal = new TryCatch ((Block) yyVals[-1+yyTop], (List) yyVals[0+yyTop], GetLocation (yyVals[-2+yyTop]), false); + Error_SyntaxError (yyToken); } break; +case 862: + case_862(); + break; case 863: - case_863(); +#line 5750 "cs-parser.jay" + { + current_block.AddStatement ((Statement) yyVals[0+yyTop]); + } break; case 864: case_864(); @@ -3732,55 +3826,43 @@ case 865: case_865(); break; case 866: - case_866(); - break; -case 867: - case_867(); - break; -case 870: -#line 5785 "cs-parser.jay" +#line 5767 "cs-parser.jay" { - yyVal = new Catch ((Block) yyVals[0+yyTop], GetLocation (yyVals[-1+yyTop])); + yyVal = new SwitchLabel (null, GetLocation (yyVals[0+yyTop])); } break; case 871: case_871(); break; case 872: -#line 5804 "cs-parser.jay" - { - yyVal = yyVals[-1+yyTop]; - } + case_872(); break; case 873: case_873(); break; case 874: -#line 5822 "cs-parser.jay" - { - yyVal = new Checked ((Block) yyVals[0+yyTop], GetLocation (yyVals[-1+yyTop])); - } + case_874(); break; case 875: -#line 5829 "cs-parser.jay" - { - yyVal = new Unchecked ((Block) yyVals[0+yyTop], GetLocation (yyVals[-1+yyTop])); - } + case_875(); break; case 876: case_876(); break; case 877: -#line 5839 "cs-parser.jay" +#line 5828 "cs-parser.jay" { - yyVal = new Unsafe ((Block) yyVals[0+yyTop], GetLocation (yyVals[-2+yyTop])); + yyVal = yyVals[0+yyTop]; } break; case 878: case_878(); break; case 879: - case_879(); +#line 5843 "cs-parser.jay" + { + yyVal = yyVals[0+yyTop]; + } break; case 880: case_880(); @@ -3789,7 +3871,10 @@ case 881: case_881(); break; case 882: - case_882(); +#line 5864 "cs-parser.jay" + { + yyVal = yyVals[0+yyTop]; + } break; case 883: case_883(); @@ -3801,37 +3886,22 @@ case 885: case_885(); break; case 886: - case_886(); +#line 5898 "cs-parser.jay" + { yyVal = new EmptyStatement (lexer.Location); } break; -case 887: - case_887(); +case 888: + case_888(); break; case 889: case_889(); break; -case 890: -#line 5944 "cs-parser.jay" - { - Error_MissingInitializer (lexer.Location); - } - break; case 891: - case_891(); - break; -case 892: - case_892(); +#line 5922 "cs-parser.jay" + { yyVal = null; } break; case 893: - case_893(); - break; -case 894: - case_894(); - break; -case 895: - case_895(); - break; -case 896: - case_896(); +#line 5927 "cs-parser.jay" + { yyVal = new EmptyStatement (lexer.Location); } break; case 897: case_897(); @@ -3843,41 +3913,17 @@ case 899: case_899(); break; case 900: -#line 6049 "cs-parser.jay" - { - current_block = new Linq.QueryBlock (current_block, lexer.Location); - } + case_900(); break; case 901: case_901(); break; case 902: -#line 6065 "cs-parser.jay" - { - current_block = new Linq.QueryBlock (current_block, lexer.Location); - } + case_902(); break; case 903: case_903(); break; -case 904: - case_904(); - break; -case 905: - case_905(); - break; -case 907: - case_907(); - break; -case 908: - case_908(); - break; -case 909: -#line 6129 "cs-parser.jay" - { - current_block = new Linq.QueryBlock (current_block, lexer.Location); - } - break; case 910: case_910(); break; @@ -3890,35 +3936,44 @@ case 912: case 913: case_913(); break; +case 914: + case_914(); + break; case 915: case_915(); break; +case 916: + case_916(); + break; +case 917: + case_917(); + break; +case 918: + case_918(); + break; +case 919: + case_919(); + break; +case 920: + case_920(); + break; case 921: -#line 6183 "cs-parser.jay" - { - current_block = new Linq.QueryBlock (current_block, lexer.Location); - } + case_921(); break; case 922: case_922(); break; case 923: -#line 6202 "cs-parser.jay" - { - current_block = new Linq.QueryBlock (current_block, lexer.Location); - } + case_923(); break; case 924: case_924(); break; -case 925: - case_925(); - break; -case 926: - case_926(); - break; case 927: - case_927(); +#line 6173 "cs-parser.jay" + { + yyVal = new TryCatch ((Block) yyVals[-1+yyTop], (List) yyVals[0+yyTop], GetLocation (yyVals[-2+yyTop]), false); + } break; case 928: case_928(); @@ -3935,18 +3990,15 @@ case 931: case 932: case_932(); break; -case 934: - case_934(); - break; case 935: -#line 6356 "cs-parser.jay" - { - current_block = new Linq.QueryBlock (current_block, lexer.Location); - } + case_935(); break; case 936: case_936(); break; +case 937: + case_937(); + break; case 938: case_938(); break; @@ -3957,55 +4009,82 @@ case 941: case_941(); break; case 942: - case_942(); +#line 6298 "cs-parser.jay" + { + yyVal = new Checked ((Block) yyVals[0+yyTop], GetLocation (yyVals[-1+yyTop])); + } break; case 943: -#line 6402 "cs-parser.jay" +#line 6305 "cs-parser.jay" { - yyVal = new Linq.OrderByAscending ((Linq.QueryBlock) current_block, (Expression)yyVals[0+yyTop]); + yyVal = new Unchecked ((Block) yyVals[0+yyTop], GetLocation (yyVals[-1+yyTop])); } break; case 944: case_944(); break; case 945: - case_945(); - break; -case 946: -#line 6419 "cs-parser.jay" +#line 6315 "cs-parser.jay" { - yyVal = new Linq.ThenByAscending ((Linq.QueryBlock) current_block, (Expression)yyVals[0+yyTop]); + yyVal = new Unsafe ((Block) yyVals[0+yyTop], GetLocation (yyVals[-2+yyTop])); } break; +case 946: + case_946(); + break; case 947: case_947(); break; case 948: case_948(); break; +case 949: + case_949(); + break; case 950: case_950(); break; case 951: case_951(); break; +case 952: + case_952(); + break; +case 953: + case_953(); + break; case 954: case_954(); break; case 955: case_955(); break; -case 963: -#line 6541 "cs-parser.jay" +case 957: + case_957(); + break; +case 958: +#line 6420 "cs-parser.jay" { - module.DocumentationBuilder.ParsedName = (MemberName) yyVals[0+yyTop]; + Error_MissingInitializer (lexer.Location); } break; +case 959: + case_959(); + break; +case 960: + case_960(); + break; +case 961: + case_961(); + break; +case 962: + case_962(); + break; +case 963: + case_963(); + break; case 964: -#line 6548 "cs-parser.jay" - { - module.DocumentationBuilder.ParsedParameters = (List)yyVals[0+yyTop]; - } + case_964(); break; case 965: case_965(); @@ -4014,22 +4093,22 @@ case 966: case_966(); break; case 967: -#line 6565 "cs-parser.jay" - { - yyVal = new MemberName ((MemberName) yyVals[-2+yyTop], MemberCache.IndexerNameAlias, Location.Null); - } + case_967(); break; case 968: -#line 6569 "cs-parser.jay" +#line 6525 "cs-parser.jay" { - valid_param_mod = ParameterModifierType.Ref | ParameterModifierType.Out; + current_block = new Linq.QueryBlock (current_block, lexer.Location); } break; case 969: case_969(); break; case 970: - case_970(); +#line 6540 "cs-parser.jay" + { + current_block = new Linq.QueryBlock (current_block, lexer.Location); + } break; case 971: case_971(); @@ -4037,38 +4116,221 @@ case 971: case 972: case_972(); break; -case 974: -#line 6605 "cs-parser.jay" +case 973: + case_973(); + break; +case 975: + case_975(); + break; +case 976: + case_976(); + break; +case 977: +#line 6604 "cs-parser.jay" + { + current_block = new Linq.QueryBlock (current_block, lexer.Location); + } + break; +case 978: + case_978(); + break; +case 979: + case_979(); + break; +case 980: + case_980(); + break; +case 981: + case_981(); + break; +case 982: +#line 6643 "cs-parser.jay" + { + yyVal = new object[] { yyVals[0+yyTop], GetLocation (yyVals[-1+yyTop]) }; + } + break; +case 983: + case_983(); + break; +case 985: + case_985(); + break; +case 991: +#line 6672 "cs-parser.jay" + { + current_block = new Linq.QueryBlock (current_block, lexer.Location); + } + break; +case 992: + case_992(); + break; +case 993: +#line 6691 "cs-parser.jay" + { + current_block = new Linq.QueryBlock (current_block, lexer.Location); + } + break; +case 994: + case_994(); + break; +case 995: + case_995(); + break; +case 996: + case_996(); + break; +case 997: + case_997(); + break; +case 998: + case_998(); + break; +case 999: + case_999(); + break; +case 1000: + case_1000(); + break; +case 1001: + case_1001(); + break; +case 1002: + case_1002(); + break; +case 1004: + case_1004(); + break; +case 1005: + case_1005(); + break; +case 1006: + case_1006(); + break; +case 1008: + case_1008(); + break; +case 1009: + case_1009(); + break; +case 1011: + case_1011(); + break; +case 1012: + case_1012(); + break; +case 1013: +#line 6892 "cs-parser.jay" + { + yyVal = new Linq.OrderByAscending ((Linq.QueryBlock) current_block, (Expression)yyVals[0+yyTop]); + } + break; +case 1014: + case_1014(); + break; +case 1015: + case_1015(); + break; +case 1016: +#line 6909 "cs-parser.jay" + { + yyVal = new Linq.ThenByAscending ((Linq.QueryBlock) current_block, (Expression)yyVals[0+yyTop]); + } + break; +case 1017: + case_1017(); + break; +case 1018: + case_1018(); + break; +case 1020: + case_1020(); + break; +case 1021: + case_1021(); + break; +case 1024: + case_1024(); + break; +case 1025: + case_1025(); + break; +case 1033: +#line 7034 "cs-parser.jay" + { + module.DocumentationBuilder.ParsedName = (MemberName) yyVals[0+yyTop]; + } + break; +case 1034: +#line 7041 "cs-parser.jay" + { + module.DocumentationBuilder.ParsedParameters = (List)yyVals[0+yyTop]; + } + break; +case 1035: + case_1035(); + break; +case 1036: + case_1036(); + break; +case 1037: + case_1037(); + break; +case 1038: +#line 7064 "cs-parser.jay" + { + yyVal = new MemberName ((MemberName) yyVals[-2+yyTop], MemberCache.IndexerNameAlias, Location.Null); + } + break; +case 1039: +#line 7068 "cs-parser.jay" + { + valid_param_mod = ParameterModifierType.Ref | ParameterModifierType.Out; + } + break; +case 1040: + case_1040(); + break; +case 1041: + case_1041(); + break; +case 1042: + case_1042(); + break; +case 1043: + case_1043(); + break; +case 1045: +#line 7104 "cs-parser.jay" { yyVal = new MemberName (((MemberName) yyVals[-2+yyTop]), (MemberName) yyVals[0+yyTop]); } break; -case 976: -#line 6613 "cs-parser.jay" +case 1047: +#line 7112 "cs-parser.jay" { valid_param_mod = ParameterModifierType.Ref | ParameterModifierType.Out; } break; -case 977: -#line 6617 "cs-parser.jay" +case 1048: +#line 7116 "cs-parser.jay" { yyVal = yyVals[-1+yyTop]; } break; -case 978: -#line 6624 "cs-parser.jay" +case 1049: +#line 7123 "cs-parser.jay" { yyVal = new List (0); } break; -case 980: - case_980(); +case 1051: + case_1051(); break; -case 981: - case_981(); +case 1052: + case_1052(); break; -case 982: - case_982(); +case 1053: + case_1053(); break; #line default } @@ -4106,7 +4368,7 @@ case 982: All more than 3 lines long rules are wrapped into a method */ void case_6() -#line 393 "cs-parser.jay" +#line 396 "cs-parser.jay" { if (yyVals[0+yyTop] != null) { Attributes attrs = (Attributes) yyVals[0+yyTop]; @@ -4118,7 +4380,7 @@ void case_6() } void case_8() -#line 407 "cs-parser.jay" +#line 410 "cs-parser.jay" { if (yyToken == Token.EXTERN_ALIAS) report.Error (439, lexer.Location, "An extern alias declaration must precede all other elements"); @@ -4127,9 +4389,9 @@ void case_8() } void case_13() -#line 427 "cs-parser.jay" +#line 430 "cs-parser.jay" { - var lt = (Tokenizer.LocatedToken) yyVals[-2+yyTop]; + var lt = (LocatedToken) yyVals[-2+yyTop]; string s = lt.Value; if (s != "alias") { syntax_error (lt.Location, "`alias' expected"); @@ -4137,7 +4399,7 @@ void case_13() if (lang_version == LanguageVersion.ISO_1) FeatureIsNotAvailable (lt.Location, "external alias"); - lt = (Tokenizer.LocatedToken) yyVals[-1+yyTop]; + lt = (LocatedToken) yyVals[-1+yyTop]; if (lt.Value == QualifiedAliasMember.GlobalAlias) { RootNamespace.Error_GlobalNamespaceRedefined (report, lt.Location); } @@ -4150,14 +4412,14 @@ void case_13() } void case_17() -#line 460 "cs-parser.jay" +#line 463 "cs-parser.jay" { if (doc_support) Lexer.doc_state = XmlCommentState.Allowed; } void case_18() -#line 468 "cs-parser.jay" +#line 471 "cs-parser.jay" { var un = new UsingNamespace ((ATypeNameExpression) yyVals[-1+yyTop], GetLocation (yyVals[-2+yyTop])); current_namespace.AddUsing (un); @@ -4166,9 +4428,9 @@ void case_18() } void case_19() -#line 475 "cs-parser.jay" +#line 478 "cs-parser.jay" { - var lt = (Tokenizer.LocatedToken) yyVals[-3+yyTop]; + var lt = (LocatedToken) yyVals[-3+yyTop]; if (lang_version != LanguageVersion.ISO_1 && lt.Value == "global") { report.Warning (440, 2, lt.Location, "An alias named `global' will not be used when resolving `global::'. The global namespace will be used instead"); @@ -4180,14 +4442,14 @@ void case_19() } void case_20() -#line 487 "cs-parser.jay" +#line 490 "cs-parser.jay" { Error_SyntaxError (yyToken); yyVal = null; } void case_21() -#line 500 "cs-parser.jay" +#line 503 "cs-parser.jay" { Attributes attrs = (Attributes) yyVals[-2+yyTop]; var name = (MemberName) yyVals[0+yyTop]; @@ -4217,14 +4479,14 @@ void case_21() } void case_22() -#line 528 "cs-parser.jay" +#line 531 "cs-parser.jay" { if (doc_support) Lexer.doc_state = XmlCommentState.Allowed; } void case_23() -#line 533 "cs-parser.jay" +#line 536 "cs-parser.jay" { if (yyVals[0+yyTop] != null) lbag.AddLocation (current_container, GetLocation (yyVals[-9+yyTop]), GetLocation (yyVals[-6+yyTop]), GetLocation (yyVals[-1+yyTop]), GetLocation (yyVals[0+yyTop])); @@ -4237,28 +4499,45 @@ void case_23() void case_24() #line 545 "cs-parser.jay" { - var lt = (Tokenizer.LocatedToken) yyVals[0+yyTop]; + report.Error (1514, lexer.Location, "Unexpected symbol `{0}', expecting `.' or `{{'", GetSymbolName (yyToken)); + + var name = (MemberName) yyVals[0+yyTop]; + var ns = new NamespaceContainer (name, current_namespace); + lbag.AddLocation (ns, GetLocation (yyVals[-1+yyTop])); + current_namespace.AddTypeContainer (ns); + } + +void case_27() +#line 559 "cs-parser.jay" +{ + Error_SyntaxError (yyToken); + yyVal = null; + } + +void case_28() +#line 567 "cs-parser.jay" +{ + var lt = (LocatedToken) yyVals[0+yyTop]; yyVal = new MemberName (lt.Value, lt.Location); } -void case_25() -#line 550 "cs-parser.jay" +void case_29() +#line 572 "cs-parser.jay" { - var lt = (Tokenizer.LocatedToken) yyVals[0+yyTop]; - yyVal = new MemberName ((MemberName) yyVals[-2+yyTop], lt.Value, lt.Location) { - DotLocation = GetLocation (yyVals[-1+yyTop]) - }; + var lt = (LocatedToken) yyVals[0+yyTop]; + yyVal = new MemberName ((MemberName) yyVals[-2+yyTop], lt.Value, lt.Location); + lbag.AddLocation (yyVal, GetLocation (yyVals[-1+yyTop])); } -void case_26() -#line 557 "cs-parser.jay" +void case_30() +#line 578 "cs-parser.jay" { Error_SyntaxError (yyToken); yyVal = new MemberName ("", lexer.Location); } -void case_39() -#line 595 "cs-parser.jay" +void case_43() +#line 616 "cs-parser.jay" { if (yyVals[0+yyTop] != null) { TypeContainer ds = (TypeContainer)yyVals[0+yyTop]; @@ -4278,58 +4557,49 @@ void case_39() current_namespace.DeclarationFound = true; } -void case_41() -#line 617 "cs-parser.jay" +void case_45() +#line 638 "cs-parser.jay" { current_namespace.UnattachedAttributes = (Attributes) yyVals[-1+yyTop]; report.Error (1518, lexer.Location, "Attributes must be attached to class, delegate, enum, interface or struct"); lexer.putback ('}'); } -void case_49() -#line 650 "cs-parser.jay" +void case_53() +#line 671 "cs-parser.jay" { var sect = (List) yyVals[0+yyTop]; yyVal = new Attributes (sect); - if (locationListStack.Count > 0) - lbag.AddLocation (sect, locationListStack.Pop ()); - if (attributeCommas.Count > 0) { - lbag.AppendTo (sect, attributeCommas); - attributeCommas.Clear (); - } } -void case_50() -#line 661 "cs-parser.jay" +void case_54() +#line 676 "cs-parser.jay" { Attributes attrs = yyVals[-1+yyTop] as Attributes; var sect = (List) yyVals[0+yyTop]; - - if (locationListStack.Count > 0) - lbag.AddLocation (sect, locationListStack.Pop ()); if (attrs == null) attrs = new Attributes (sect); - else + else if (sect != null) attrs.AddAttributes (sect); yyVal = attrs; } -void case_51() -#line 677 "cs-parser.jay" +void case_55() +#line 689 "cs-parser.jay" { + PushLocation (GetLocation (yyVals[0+yyTop])); lexer.parsing_attribute_section = true; - savedOpenLocation = GetLocation (yyVals[0+yyTop]); } -void case_52() -#line 682 "cs-parser.jay" +void case_56() +#line 694 "cs-parser.jay" { lexer.parsing_attribute_section = false; yyVal = yyVals[0+yyTop]; } -void case_53() -#line 690 "cs-parser.jay" +void case_57() +#line 702 "cs-parser.jay" { current_attr_target = (string) yyVals[-1+yyTop]; if (current_attr_target == "assembly" || current_attr_target == "module") { @@ -4337,67 +4607,81 @@ void case_53() } } -void case_54() -#line 697 "cs-parser.jay" +void case_58() +#line 709 "cs-parser.jay" { /* when attribute target is invalid*/ if (current_attr_target == string.Empty) yyVal = new List (0); else yyVal = yyVals[-2+yyTop]; - - current_attr_target = null; - lexer.parsing_attribute_section = false; + lbag.InsertLocation (yyVal, 0, GetLocation (yyVals[-4+yyTop])); + lbag.InsertLocation (yyVal, 0, PopLocation ()); + lbag.InsertLocation (yyVal, 0, PopLocation ()); if (yyVals[-1+yyTop] != null) { - locationListStack.Push (new List(new [] { savedOpenLocation, savedCloseLocation, GetLocation (yyVals[-4+yyTop]), GetLocation (yyVals[-1+yyTop]), GetLocation (yyVals[0+yyTop]) })); + lbag.AddLocation (yyVal, GetLocation (yyVals[-1+yyTop]), GetLocation (yyVals[0+yyTop])); } else { - locationListStack.Push (new List(new [] { savedOpenLocation, savedCloseLocation, GetLocation (yyVals[-4+yyTop]), GetLocation (yyVals[0+yyTop]) })); + lbag.AddLocation (yyVal, GetLocation (yyVals[0+yyTop])); } + + current_attr_target = null; + lexer.parsing_attribute_section = false; } -void case_55() -#line 713 "cs-parser.jay" +void case_59() +#line 728 "cs-parser.jay" { yyVal = yyVals[-2+yyTop]; + lbag.InsertLocation (yyVal, 0, PopLocation ()); if (yyVals[-1+yyTop] != null) { - locationListStack.Push (new List(new [] { savedOpenLocation, GetLocation (yyVals[-1+yyTop]), GetLocation (yyVals[0+yyTop]) })); + lbag.AddLocation (yyVal, GetLocation(yyVals[-1+yyTop]), GetLocation (yyVals[0+yyTop])); } else { - locationListStack.Push (new List(new [] { savedOpenLocation, GetLocation (yyVals[0+yyTop]) })); + lbag.AddLocation (yyVal, GetLocation(yyVals[0+yyTop])); } } -void case_56() -#line 725 "cs-parser.jay" +void case_60() +#line 738 "cs-parser.jay" { - var lt = (Tokenizer.LocatedToken) yyVals[0+yyTop]; - yyVal = CheckAttributeTarget (lt.Value, lt.Location); - savedCloseLocation = GetLocation (yyVals[0+yyTop]); + Error_SyntaxError (yyToken); + + var lt = (LocatedToken) yyVals[-1+yyTop]; + var tne = new SimpleName (lt.Value, null, lt.Location); + + yyVal = new List () { + new Attribute (null, tne, null, GetLocation (yyVals[-1+yyTop]), false) + }; } -void case_59() -#line 733 "cs-parser.jay" +void case_61() +#line 749 "cs-parser.jay" { - if (yyToken == Token.IDENTIFIER) { - Error_SyntaxError (yyToken); - yyVal = null; - } else { - string name = GetTokenName (yyToken); - yyVal = CheckAttributeTarget (name, GetLocation (yyVals[0+yyTop])); - } + CheckAttributeTarget (yyToken, GetTokenName (yyToken), GetLocation (yyVals[0+yyTop])); + yyVal = null; } -void case_61() -#line 750 "cs-parser.jay" +void case_62() +#line 757 "cs-parser.jay" +{ + var lt = (LocatedToken) yyVals[0+yyTop]; + yyVal = CheckAttributeTarget (yyToken, lt.Value, lt.Location); + PushLocation (GetLocation (yyVals[0+yyTop])); + } + +void case_66() +#line 772 "cs-parser.jay" { var attrs = (List) yyVals[-2+yyTop]; - attrs.Add ((Attribute) yyVals[0+yyTop]); - attributeCommas.Add (GetLocation (yyVals[-1+yyTop])); + if (attrs != null) { + attrs.Add ((Attribute) yyVals[0+yyTop]); + lbag.AddLocation (attrs, GetLocation (yyVals[-1+yyTop])); + } yyVal = attrs; } -void case_63() -#line 765 "cs-parser.jay" +void case_68() +#line 789 "cs-parser.jay" { --lexer.parsing_block; @@ -4418,8 +4702,8 @@ void case_63() } } -void case_66() -#line 793 "cs-parser.jay" +void case_71() +#line 817 "cs-parser.jay" { savedAttrParenOpenLocation = GetLocation (yyVals[-2+yyTop]); savedAttrParenCloseLocation = GetLocation (yyVals[0+yyTop]); @@ -4427,24 +4711,24 @@ void case_66() HadAttributeParens = true; } -void case_68() -#line 805 "cs-parser.jay" +void case_73() +#line 829 "cs-parser.jay" { Arguments a = new Arguments (4); a.Add ((Argument) yyVals[0+yyTop]); yyVal = new Arguments [] { a, null }; } -void case_69() -#line 811 "cs-parser.jay" +void case_74() +#line 835 "cs-parser.jay" { Arguments a = new Arguments (4); a.Add ((Argument) yyVals[0+yyTop]); yyVal = new Arguments [] { null, a }; } -void case_70() -#line 817 "cs-parser.jay" +void case_75() +#line 841 "cs-parser.jay" { Arguments[] o = (Arguments[]) yyVals[-2+yyTop]; if (o [1] != null) { @@ -4460,8 +4744,8 @@ void case_70() attributeArgumentCommas.Add (GetLocation (yyVals[-1+yyTop])); } -void case_71() -#line 832 "cs-parser.jay" +void case_76() +#line 856 "cs-parser.jay" { Arguments[] o = (Arguments[]) yyVals[-2+yyTop]; if (o [1] == null) { @@ -4472,17 +4756,24 @@ void case_71() attributeArgumentCommas.Add (GetLocation (yyVals[-1+yyTop])); } -void case_75() -#line 857 "cs-parser.jay" +void case_79() +#line 874 "cs-parser.jay" +{ + Error_SyntaxError (yyToken); + yyVal = null; + } + +void case_81() +#line 886 "cs-parser.jay" { --lexer.parsing_block; - var lt = (Tokenizer.LocatedToken) yyVals[-3+yyTop]; + var lt = (LocatedToken) yyVals[-3+yyTop]; yyVal = new NamedArgument (lt.Value, lt.Location, (Expression) yyVals[0+yyTop]); lbag.AddLocation (yyVal, GetLocation(yyVals[-2+yyTop])); } -void case_76() -#line 867 "cs-parser.jay" +void case_82() +#line 896 "cs-parser.jay" { if (lang_version <= LanguageVersion.V_3) FeatureIsNotAvailable (GetLocation (yyVals[-3+yyTop]), "named argument"); @@ -4490,32 +4781,52 @@ void case_76() /* Avoid boxing in common case (no modifier)*/ var arg_mod = yyVals[-1+yyTop] == null ? Argument.AType.None : (Argument.AType) yyVals[-1+yyTop]; - var lt = (Tokenizer.LocatedToken) yyVals[-3+yyTop]; + var lt = (LocatedToken) yyVals[-3+yyTop]; yyVal = new NamedArgument (lt.Value, lt.Location, (Expression) yyVals[0+yyTop], arg_mod); lbag.AddLocation (yyVal, GetLocation(yyVals[-2+yyTop])); } -void case_95() -#line 921 "cs-parser.jay" +void case_88() +#line 928 "cs-parser.jay" { - report.Error (1519, lexer.Location, "Unexpected symbol `{0}' in class, struct, or interface member declaration", - GetSymbolName (yyToken)); - yyVal = null; - lexer.parsing_generic_declaration = false; + lexer.parsing_modifiers = true; + lexer.parsing_block = 0; + } + +void case_89() +#line 933 "cs-parser.jay" +{ + lexer.parsing_modifiers = true; + lexer.parsing_block = 0; + } + +void case_102() +#line 953 "cs-parser.jay" +{ + report.Error (1519, lexer.Location, "Unexpected symbol `{0}' in class, struct, or interface member declaration", + GetSymbolName (yyToken)); + yyVal = null; + lexer.parsing_generic_declaration = false; } -void case_97() -#line 938 "cs-parser.jay" +void case_104() +#line 969 "cs-parser.jay" { + lexer.ConstraintsParsing = true; + valid_param_mod = ParameterModifierType.PrimaryConstructor; push_current_container (new Struct (current_container, (MemberName) yyVals[0+yyTop], (Modifiers) yyVals[-4+yyTop], (Attributes) yyVals[-5+yyTop]), yyVals[-3+yyTop]); lbag.AddMember (current_container, GetModifierLocations (), GetLocation (yyVals[-2+yyTop])); } -void case_98() -#line 944 "cs-parser.jay" +void case_105() +#line 978 "cs-parser.jay" { + valid_param_mod = 0; lexer.ConstraintsParsing = false; + if (yyVals[-2+yyTop] != null) + current_type.PrimaryConstructorParameters = (ParametersCompiled) yyVals[-2+yyTop]; + if (yyVals[0+yyTop] != null) current_container.SetConstraints ((List) yyVals[0+yyTop]); @@ -4526,25 +4837,25 @@ void case_98() lexer.parsing_modifiers = true; } -void case_99() -#line 957 "cs-parser.jay" +void case_106() +#line 995 "cs-parser.jay" { if (doc_support) Lexer.doc_state = XmlCommentState.Allowed; } -void case_100() -#line 962 "cs-parser.jay" +void case_107() +#line 1000 "cs-parser.jay" { --lexer.parsing_declaration; if (doc_support) Lexer.doc_state = XmlCommentState.Allowed; } -void case_101() -#line 968 "cs-parser.jay" +void case_108() +#line 1006 "cs-parser.jay" { - if (yyVals[0+yyTop] == null) { + if (yyVals[-1+yyTop] == null) { lbag.AppendToMember (current_container, GetLocation (yyVals[-5+yyTop]), GetLocation (yyVals[-2+yyTop])); } else { lbag.AppendToMember (current_container, GetLocation (yyVals[-5+yyTop]), GetLocation (yyVals[-2+yyTop]), GetLocation (yyVals[0+yyTop])); @@ -4552,10 +4863,10 @@ void case_101() yyVal = pop_current_class (); } -void case_103() -#line 986 "cs-parser.jay" +void case_110() +#line 1024 "cs-parser.jay" { - var lt = (Tokenizer.LocatedToken) yyVals[0+yyTop]; + var lt = (LocatedToken) yyVals[0+yyTop]; var mod = (Modifiers) yyVals[-3+yyTop]; current_field = new Const (current_type, (FullNamedExpression) yyVals[-1+yyTop], mod, new MemberName (lt.Value, lt.Location), (Attributes) yyVals[-4+yyTop]); current_type.AddMember (current_field); @@ -4567,8 +4878,8 @@ void case_103() yyVal = current_field; } -void case_104() -#line 999 "cs-parser.jay" +void case_111() +#line 1037 "cs-parser.jay" { if (doc_support) { current_field.DocComment = Lexer.consume_doc_comment (); @@ -4580,31 +4891,39 @@ void case_104() current_field = null; } -void case_109() -#line 1029 "cs-parser.jay" +void case_112() +#line 1050 "cs-parser.jay" +{ + Error_SyntaxError (yyToken); + + current_type.AddMember (new Const (current_type, (FullNamedExpression) yyVals[-1+yyTop], (Modifiers) yyVals[-3+yyTop], MemberName.Null, (Attributes) yyVals[-4+yyTop])); + } + +void case_117() +#line 1075 "cs-parser.jay" { - var lt = (Tokenizer.LocatedToken) yyVals[-1+yyTop]; + var lt = (LocatedToken) yyVals[-1+yyTop]; yyVal = new FieldDeclarator (new SimpleMemberName (lt.Value, lt.Location), (ConstInitializer) yyVals[0+yyTop]); lbag.AddLocation (yyVal, GetLocation (yyVals[-2+yyTop])); } -void case_111() -#line 1042 "cs-parser.jay" +void case_119() +#line 1088 "cs-parser.jay" { --lexer.parsing_block; yyVal = new ConstInitializer (current_field, (Expression) yyVals[0+yyTop], GetLocation (yyVals[-2+yyTop])); lbag.AddLocation (yyVal, GetLocation (yyVals[-2+yyTop])); } -void case_112() -#line 1048 "cs-parser.jay" +void case_120() +#line 1094 "cs-parser.jay" { report.Error (145, lexer.Location, "A const field requires a value to be provided"); yyVal = null; } -void case_115() -#line 1063 "cs-parser.jay" +void case_123() +#line 1109 "cs-parser.jay" { lexer.parsing_generic_declaration = false; @@ -4612,14 +4931,14 @@ void case_115() if (type.Type != null && type.Type.Kind == MemberKind.Void) report.Error (670, GetLocation (yyVals[-1+yyTop]), "Fields cannot have void type"); - var lt = (Tokenizer.LocatedToken) yyVals[0+yyTop]; + var lt = (LocatedToken) yyVals[0+yyTop]; current_field = new Field (current_type, type, (Modifiers) yyVals[-2+yyTop], new MemberName (lt.Value, lt.Location), (Attributes) yyVals[-3+yyTop]); current_type.AddField (current_field); yyVal = current_field; } -void case_116() -#line 1078 "cs-parser.jay" +void case_124() +#line 1124 "cs-parser.jay" { if (doc_support) { current_field.DocComment = Lexer.consume_doc_comment (); @@ -4631,21 +4950,21 @@ void case_116() current_field = null; } -void case_117() -#line 1091 "cs-parser.jay" +void case_125() +#line 1137 "cs-parser.jay" { if (lang_version < LanguageVersion.ISO_2) FeatureIsNotAvailable (GetLocation (yyVals[-2+yyTop]), "fixed size buffers"); - var lt = (Tokenizer.LocatedToken) yyVals[0+yyTop]; + var lt = (LocatedToken) yyVals[0+yyTop]; current_field = new FixedField (current_type, (FullNamedExpression) yyVals[-1+yyTop], (Modifiers) yyVals[-3+yyTop], new MemberName (lt.Value, lt.Location), (Attributes) yyVals[-4+yyTop]); current_type.AddField (current_field); } -void case_118() -#line 1102 "cs-parser.jay" +void case_126() +#line 1148 "cs-parser.jay" { if (doc_support) { current_field.DocComment = Lexer.consume_doc_comment (); @@ -4658,16 +4977,16 @@ void case_118() current_field = null; } -void case_121() -#line 1125 "cs-parser.jay" +void case_129() +#line 1171 "cs-parser.jay" { ++lexer.parsing_block; current_local_parameters = ParametersCompiled.EmptyReadOnlyParameters; start_block (GetLocation (yyVals[0+yyTop])); } -void case_122() -#line 1131 "cs-parser.jay" +void case_130() +#line 1177 "cs-parser.jay" { --lexer.parsing_block; current_field.Initializer = (Expression) yyVals[0+yyTop]; @@ -4676,68 +4995,65 @@ void case_122() current_local_parameters = null; } -void case_127() -#line 1158 "cs-parser.jay" +void case_135() +#line 1204 "cs-parser.jay" { - var lt = (Tokenizer.LocatedToken) yyVals[0+yyTop]; + var lt = (LocatedToken) yyVals[0+yyTop]; yyVal = new FieldDeclarator (new SimpleMemberName (lt.Value, lt.Location), null); lbag.AddLocation (yyVal, GetLocation (yyVals[-1+yyTop])); } -void case_129() -#line 1168 "cs-parser.jay" +void case_137() +#line 1214 "cs-parser.jay" { --lexer.parsing_block; - var lt = (Tokenizer.LocatedToken) yyVals[-3+yyTop]; + var lt = (LocatedToken) yyVals[-3+yyTop]; yyVal = new FieldDeclarator (new SimpleMemberName (lt.Value, lt.Location), (Expression) yyVals[0+yyTop]); lbag.AddLocation (yyVal, GetLocation (yyVals[-4+yyTop]), GetLocation (yyVals[-2+yyTop])); } -void case_134() -#line 1194 "cs-parser.jay" +void case_142() +#line 1240 "cs-parser.jay" { - var lt = (Tokenizer.LocatedToken) yyVals[-1+yyTop]; + var lt = (LocatedToken) yyVals[-1+yyTop]; yyVal = new FieldDeclarator (new SimpleMemberName (lt.Value, lt.Location), (ConstInitializer) yyVals[0+yyTop]); lbag.AddLocation (yyVal, GetLocation (yyVals[-2+yyTop])); } -void case_136() -#line 1207 "cs-parser.jay" +void case_144() +#line 1253 "cs-parser.jay" { --lexer.parsing_block; yyVal = new ConstInitializer (current_field, (Expression) yyVals[-1+yyTop], GetLocation (yyVals[-3+yyTop])); lbag.AddLocation (yyVal, GetLocation (yyVals[0+yyTop])); } -void case_137() -#line 1213 "cs-parser.jay" +void case_145() +#line 1259 "cs-parser.jay" { report.Error (443, lexer.Location, "Value or constant expected"); yyVal = null; } -void case_140() -#line 1223 "cs-parser.jay" +void case_148() +#line 1269 "cs-parser.jay" { /* It has to be here for the parent to safely restore artificial block*/ Error_SyntaxError (yyToken); yyVal = null; } -void case_141() -#line 1232 "cs-parser.jay" +void case_149() +#line 1278 "cs-parser.jay" { if (doc_support) Lexer.doc_state = XmlCommentState.NotAllowed; - /* Add it early in the case of body being eof for full ast*/ - Method m = (Method) yyVals[0+yyTop]; - async_block = (m.ModFlags & Modifiers.ASYNC) != 0; - current_type.AddMember (m); + /* Was added earlier in the case of body being eof for full ast*/ } -void case_142() -#line 1242 "cs-parser.jay" +void case_150() +#line 1285 "cs-parser.jay" { Method method = (Method) yyVals[-2+yyTop]; method.Block = (ToplevelBlock) yyVals[0+yyTop]; @@ -4764,36 +5080,51 @@ void case_142() Lexer.doc_state = XmlCommentState.Allowed; } -void case_145() -#line 1282 "cs-parser.jay" +void case_152() +#line 1321 "cs-parser.jay" { - lexer.ConstraintsParsing = false; valid_param_mod = 0; - MemberName name = (MemberName) yyVals[-6+yyTop]; - current_local_parameters = (ParametersCompiled) yyVals[-3+yyTop]; + MemberName name = (MemberName) yyVals[-4+yyTop]; + current_local_parameters = (ParametersCompiled) yyVals[-1+yyTop]; - var method = Method.Create (current_type, (FullNamedExpression) yyVals[-7+yyTop], (Modifiers) yyVals[-8+yyTop], - name, current_local_parameters, (Attributes) yyVals[-9+yyTop], yyVals[0+yyTop] != null); + var method = Method.Create (current_type, (FullNamedExpression) yyVals[-5+yyTop], (Modifiers) yyVals[-6+yyTop], + name, current_local_parameters, (Attributes) yyVals[-7+yyTop]); + + current_type.AddMember (method); + + async_block = (method.ModFlags & Modifiers.ASYNC) != 0; - if (yyVals[0+yyTop] != null) - method.SetConstraints ((List) yyVals[0+yyTop]); - if (doc_support) method.DocComment = Lexer.consume_doc_comment (); - lbag.AddMember (method, GetModifierLocations (), GetLocation (yyVals[-5+yyTop]), GetLocation (yyVals[-2+yyTop])); + lbag.AddMember (method, GetModifierLocations (), GetLocation (yyVals[-3+yyTop]), GetLocation (yyVals[0+yyTop])); yyVal = method; + + lexer.ConstraintsParsing = true; + } + +void case_153() +#line 1342 "cs-parser.jay" +{ + lexer.ConstraintsParsing = false; + + if (yyVals[0+yyTop] != null) { + var method = (Method) yyVals[-1+yyTop]; + method.SetConstraints ((List) yyVals[0+yyTop]); + } + + yyVal = yyVals[-1+yyTop]; } -void case_147() -#line 1309 "cs-parser.jay" +void case_155() +#line 1361 "cs-parser.jay" { lexer.parsing_generic_declaration = false; valid_param_mod = ParameterModifierType.All; } -void case_149() -#line 1318 "cs-parser.jay" +void case_157() +#line 1370 "cs-parser.jay" { lexer.ConstraintsParsing = false; valid_param_mod = 0; @@ -4805,10 +5136,14 @@ void case_149() modifiers |= Modifiers.PARTIAL; var method = Method.Create (current_type, new TypeExpression (compiler.BuiltinTypes.Void, GetLocation (yyVals[-8+yyTop])), - modifiers, name, current_local_parameters, (Attributes) yyVals[-11+yyTop], yyVals[-1+yyTop] != null); + modifiers, name, current_local_parameters, (Attributes) yyVals[-11+yyTop]); - if (yyVals[-1+yyTop] != null) - method.SetConstraints ((List) yyVals[-1+yyTop]); + current_type.AddMember (method); + + async_block = (method.ModFlags & Modifiers.ASYNC) != 0; + + if (yyVals[0+yyTop] != null) + method.SetConstraints ((List) yyVals[0+yyTop]); if (doc_support) method.DocComment = Lexer.consume_doc_comment (); @@ -4818,15 +5153,17 @@ void case_149() yyVal = method; } -void case_150() -#line 1345 "cs-parser.jay" +void case_158() +#line 1401 "cs-parser.jay" { MemberName name = (MemberName) yyVals[-3+yyTop]; report.Error (1585, name.Location, "Member modifier `{0}' must precede the member type and name", ModifiersExtensions.Name ((Modifiers) yyVals[-4+yyTop])); var method = Method.Create (current_type, (FullNamedExpression) yyVals[-5+yyTop], - 0, name, (ParametersCompiled) yyVals[-1+yyTop], (Attributes) yyVals[-7+yyTop], false); + 0, name, (ParametersCompiled) yyVals[-1+yyTop], (Attributes) yyVals[-7+yyTop]); + + current_type.AddMember (method); current_local_parameters = (ParametersCompiled) yyVals[-1+yyTop]; @@ -4836,15 +5173,17 @@ void case_150() yyVal = method; } -void case_151() -#line 1364 "cs-parser.jay" +void case_159() +#line 1422 "cs-parser.jay" { Error_SyntaxError (yyToken); current_local_parameters = ParametersCompiled.Undefined; MemberName name = (MemberName) yyVals[-1+yyTop]; var method = Method.Create (current_type, (FullNamedExpression) yyVals[-2+yyTop], (Modifiers) yyVals[-3+yyTop], - name, current_local_parameters, (Attributes) yyVals[-4+yyTop], false); + name, current_local_parameters, (Attributes) yyVals[-4+yyTop]); + + current_type.AddMember (method); if (doc_support) method.DocComment = Lexer.consume_doc_comment (); @@ -4852,16 +5191,16 @@ void case_151() yyVal = method; } -void case_156() -#line 1391 "cs-parser.jay" +void case_164() +#line 1451 "cs-parser.jay" { var pars_list = (List) yyVals[0+yyTop]; yyVal = new ParametersCompiled (pars_list.ToArray ()); lbag.AddLocation (yyVal, parameterListCommas); } -void case_157() -#line 1397 "cs-parser.jay" +void case_165() +#line 1457 "cs-parser.jay" { var pars_list = (List) yyVals[-2+yyTop]; pars_list.Add ((Parameter) yyVals[0+yyTop]); @@ -4871,8 +5210,8 @@ void case_157() lbag.AddLocation (yyVal, parameterListCommas); } -void case_158() -#line 1406 "cs-parser.jay" +void case_166() +#line 1466 "cs-parser.jay" { var pars_list = (List) yyVals[-2+yyTop]; pars_list.Add (new ArglistParameter (GetLocation (yyVals[0+yyTop]))); @@ -4882,8 +5221,8 @@ void case_158() lbag.AddLocation (yyVal, parameterListCommas); } -void case_159() -#line 1415 "cs-parser.jay" +void case_167() +#line 1475 "cs-parser.jay" { if (yyVals[-2+yyTop] != null) report.Error (231, ((Parameter) yyVals[-2+yyTop]).Location, "A params parameter must be the last parameter in a formal parameter list"); @@ -4892,8 +5231,8 @@ void case_159() lbag.AddLocation (yyVal, parameterListCommas); } -void case_160() -#line 1423 "cs-parser.jay" +void case_168() +#line 1483 "cs-parser.jay" { if (yyVals[-2+yyTop] != null) report.Error (231, ((Parameter) yyVals[-2+yyTop]).Location, "A params parameter must be the last parameter in a formal parameter list"); @@ -4907,8 +5246,8 @@ void case_160() lbag.AddLocation (yyVal, parameterListCommas); } -void case_161() -#line 1436 "cs-parser.jay" +void case_169() +#line 1496 "cs-parser.jay" { report.Error (257, GetLocation (yyVals[-2+yyTop]), "An __arglist parameter must be the last parameter in a formal parameter list"); @@ -4916,8 +5255,8 @@ void case_161() lbag.AddLocation (yyVal, parameterListCommas); } -void case_162() -#line 1443 "cs-parser.jay" +void case_170() +#line 1503 "cs-parser.jay" { report.Error (257, GetLocation (yyVals[-2+yyTop]), "An __arglist parameter must be the last parameter in a formal parameter list"); @@ -4930,15 +5269,15 @@ void case_162() lbag.AddLocation (yyVal, parameterListCommas); } -void case_165() -#line 1463 "cs-parser.jay" +void case_173() +#line 1523 "cs-parser.jay" { Error_SyntaxError (yyToken); yyVal = ParametersCompiled.EmptyReadOnlyParameters; } -void case_166() -#line 1471 "cs-parser.jay" +void case_174() +#line 1531 "cs-parser.jay" { parameters_bucket.Clear (); Parameter p = (Parameter) yyVals[0+yyTop]; @@ -4948,8 +5287,8 @@ void case_166() yyVal = parameters_bucket; } -void case_167() -#line 1480 "cs-parser.jay" +void case_175() +#line 1540 "cs-parser.jay" { var pars = (List) yyVals[-2+yyTop]; Parameter p = (Parameter) yyVals[0+yyTop]; @@ -4968,33 +5307,33 @@ void case_167() yyVal = yyVals[-2+yyTop]; } -void case_168() -#line 1504 "cs-parser.jay" +void case_176() +#line 1564 "cs-parser.jay" { - var lt = (Tokenizer.LocatedToken) yyVals[0+yyTop]; + var lt = (LocatedToken) yyVals[0+yyTop]; yyVal = new Parameter ((FullNamedExpression) yyVals[-1+yyTop], lt.Value, (Parameter.Modifier) yyVals[-2+yyTop], (Attributes) yyVals[-3+yyTop], lt.Location); lbag.AddLocation (yyVal, parameterModifierLocation); } -void case_169() -#line 1513 "cs-parser.jay" +void case_177() +#line 1573 "cs-parser.jay" { - var lt = (Tokenizer.LocatedToken) yyVals[-2+yyTop]; + var lt = (LocatedToken) yyVals[-2+yyTop]; report.Error (1552, lt.Location, "Array type specifier, [], must appear before parameter name"); yyVal = new Parameter ((FullNamedExpression) yyVals[-3+yyTop], lt.Value, (Parameter.Modifier) yyVals[-4+yyTop], (Attributes) yyVals[-5+yyTop], lt.Location); lbag.AddLocation (yyVal, parameterModifierLocation); } -void case_170() -#line 1520 "cs-parser.jay" +void case_178() +#line 1580 "cs-parser.jay" { Error_SyntaxError (yyToken); Location l = GetLocation (yyVals[0+yyTop]); yyVal = new Parameter (null, null, Parameter.Modifier.NONE, (Attributes) yyVals[-1+yyTop], l); } -void case_171() -#line 1529 "cs-parser.jay" +void case_179() +#line 1589 "cs-parser.jay" { Error_SyntaxError (yyToken); Location l = GetLocation (yyVals[0+yyTop]); @@ -5002,8 +5341,8 @@ void case_171() lbag.AddLocation (yyVal, parameterModifierLocation); } -void case_173() -#line 1544 "cs-parser.jay" +void case_181() +#line 1604 "cs-parser.jay" { --lexer.parsing_block; if (lang_version <= LanguageVersion.V_3) { @@ -5033,7 +5372,7 @@ void case_173() if ((valid_param_mod & ParameterModifierType.DefaultValue) == 0) report.Error (1065, GetLocation (yyVals[-2+yyTop]), "Optional parameter is not valid in this context"); - var lt = (Tokenizer.LocatedToken) yyVals[-3+yyTop]; + var lt = (LocatedToken) yyVals[-3+yyTop]; yyVal = new Parameter ((FullNamedExpression) yyVals[-4+yyTop], lt.Value, mod, (Attributes) yyVals[-6+yyTop], lt.Location); lbag.AddLocation (yyVal, parameterModifierLocation, GetLocation (yyVals[-2+yyTop])); /* parameterModifierLocation should be ignored when mod == NONE*/ @@ -5041,8 +5380,8 @@ void case_173() ((Parameter) yyVal).DefaultValue = new DefaultParameterValueExpression ((Expression) yyVals[0+yyTop]); } -void case_177() -#line 1593 "cs-parser.jay" +void case_185() +#line 1653 "cs-parser.jay" { Parameter.Modifier p2 = (Parameter.Modifier)yyVals[0+yyTop]; Parameter.Modifier mod = (Parameter.Modifier)yyVals[-1+yyTop] | p2; @@ -5064,8 +5403,8 @@ void case_177() yyVal = mod; } -void case_178() -#line 1617 "cs-parser.jay" +void case_186() +#line 1677 "cs-parser.jay" { if ((valid_param_mod & ParameterModifierType.Ref) == 0) Error_ParameterModifierNotValid ("ref", GetLocation (yyVals[0+yyTop])); @@ -5073,8 +5412,8 @@ void case_178() yyVal = Parameter.Modifier.REF; } -void case_179() -#line 1624 "cs-parser.jay" +void case_187() +#line 1684 "cs-parser.jay" { if ((valid_param_mod & ParameterModifierType.Out) == 0) Error_ParameterModifierNotValid ("out", GetLocation (yyVals[0+yyTop])); @@ -5082,8 +5421,8 @@ void case_179() yyVal = Parameter.Modifier.OUT; } -void case_180() -#line 1631 "cs-parser.jay" +void case_188() +#line 1691 "cs-parser.jay" { if ((valid_param_mod & ParameterModifierType.This) == 0) Error_ParameterModifierNotValid ("this", GetLocation (yyVals[0+yyTop])); @@ -5094,41 +5433,42 @@ void case_180() yyVal = Parameter.Modifier.This; } -void case_181() -#line 1644 "cs-parser.jay" +void case_189() +#line 1704 "cs-parser.jay" { - var lt = (Tokenizer.LocatedToken) yyVals[0+yyTop]; + var lt = (LocatedToken) yyVals[0+yyTop]; yyVal = new ParamsParameter ((FullNamedExpression) yyVals[-1+yyTop], lt.Value, (Attributes) yyVals[-3+yyTop], lt.Location); lbag.AddLocation (yyVal, savedLocation); } -void case_182() -#line 1650 "cs-parser.jay" +void case_190() +#line 1710 "cs-parser.jay" { report.Error (1751, GetLocation (yyVals[-4+yyTop]), "Cannot specify a default value for a parameter array"); - var lt = (Tokenizer.LocatedToken) yyVals[-2+yyTop]; + var lt = (LocatedToken) yyVals[-2+yyTop]; yyVal = new ParamsParameter ((FullNamedExpression) yyVals[-3+yyTop], lt.Value, (Attributes) yyVals[-5+yyTop], lt.Location); lbag.AddLocation (yyVal, savedLocation); } -void case_183() -#line 1658 "cs-parser.jay" +void case_191() +#line 1718 "cs-parser.jay" { Error_SyntaxError (yyToken); - yyVal = null; + + yyVal = new ParamsParameter ((FullNamedExpression) yyVals[-1+yyTop], null, (Attributes) yyVals[-3+yyTop], Location.Null); } -void case_184() -#line 1666 "cs-parser.jay" +void case_192() +#line 1727 "cs-parser.jay" { if ((valid_param_mod & ParameterModifierType.Params) == 0) report.Error (1670, (GetLocation (yyVals[0+yyTop])), "The `params' modifier is not allowed in current context"); savedLocation = GetLocation (yyVals[0+yyTop]); } -void case_185() -#line 1672 "cs-parser.jay" +void case_193() +#line 1733 "cs-parser.jay" { Parameter.Modifier mod = (Parameter.Modifier)yyVals[0+yyTop]; if ((mod & Parameter.Modifier.This) != 0) { @@ -5139,22 +5479,22 @@ void case_185() savedLocation = GetLocation (yyVals[-1+yyTop]); } -void case_187() -#line 1689 "cs-parser.jay" +void case_195() +#line 1750 "cs-parser.jay" { if ((valid_param_mod & ParameterModifierType.Arglist) == 0) report.Error (1669, GetLocation (yyVals[0+yyTop]), "__arglist is not valid in this context"); } -void case_188() -#line 1700 "cs-parser.jay" +void case_196() +#line 1761 "cs-parser.jay" { if (doc_support) tmpComment = Lexer.consume_doc_comment (); } -void case_189() -#line 1705 "cs-parser.jay" +void case_197() +#line 1766 "cs-parser.jay" { var type = (FullNamedExpression) yyVals[-3+yyTop]; current_property = new Property (current_type, type, (Modifiers) yyVals[-4+yyTop], @@ -5169,8 +5509,8 @@ void case_189() lexer.PropertyParsing = true; } -void case_190() -#line 1719 "cs-parser.jay" +void case_198() +#line 1780 "cs-parser.jay" { lexer.PropertyParsing = false; @@ -5178,30 +5518,30 @@ void case_190() current_property.DocComment = ConsumeStoredComment (); } -void case_191() -#line 1726 "cs-parser.jay" +void case_199() +#line 1787 "cs-parser.jay" { lbag.AppendToMember (current_property, GetLocation (yyVals[0+yyTop])); current_property = null; } -void case_193() -#line 1740 "cs-parser.jay" +void case_201() +#line 1801 "cs-parser.jay" { valid_param_mod = 0; - var type = (FullNamedExpression) yyVals[-6+yyTop]; - Indexer indexer = new Indexer (current_type, type, (MemberName) yyVals[-5+yyTop], (Modifiers) yyVals[-7+yyTop], (ParametersCompiled) yyVals[-2+yyTop], (Attributes) yyVals[-8+yyTop]); + var type = (FullNamedExpression) yyVals[-5+yyTop]; + Indexer indexer = new Indexer (current_type, type, (MemberName) yyVals[-4+yyTop], (Modifiers) yyVals[-6+yyTop], (ParametersCompiled) yyVals[-1+yyTop], (Attributes) yyVals[-7+yyTop]); current_property = indexer; current_type.AddIndexer (indexer); - lbag.AddMember (current_property, GetModifierLocations (), GetLocation (yyVals[-4+yyTop]), GetLocation (yyVals[-1+yyTop]), GetLocation (yyVals[0+yyTop])); + lbag.AddMember (current_property, GetModifierLocations (), GetLocation (yyVals[-3+yyTop]), GetLocation (yyVals[0+yyTop])); if (type.Type != null && type.Type.Kind == MemberKind.Void) - report.Error (620, GetLocation (yyVals[-6+yyTop]), "`{0}': indexer return type cannot be `void'", indexer.GetSignatureForError ()); + report.Error (620, GetLocation (yyVals[-5+yyTop]), "`{0}': indexer return type cannot be `void'", indexer.GetSignatureForError ()); if (indexer.ParameterInfo.IsEmpty) { - report.Error (1551, GetLocation (yyVals[-4+yyTop]), "Indexers must have at least one parameter"); + report.Error (1551, GetLocation (yyVals[-3+yyTop]), "Indexers must have at least one parameter"); } if (doc_support) { @@ -5212,8 +5552,8 @@ void case_193() lexer.PropertyParsing = true; } -void case_195() -#line 1769 "cs-parser.jay" +void case_203() +#line 1830 "cs-parser.jay" { if (current_property.AccessorFirst != null && current_property.AccessorFirst.Block == null) ((Indexer) current_property).ParameterInfo.CheckParameters (current_property); @@ -5221,12 +5561,12 @@ void case_195() if (doc_support) current_property.DocComment = ConsumeStoredComment (); - lbag.AppendToMember (current_property, GetLocation (yyVals[-1+yyTop])); + lbag.AppendToMember (current_property, GetLocation (yyVals[-3+yyTop]), GetLocation (yyVals[0+yyTop])); current_property = null; } -void case_200() -#line 1788 "cs-parser.jay" +void case_208() +#line 1849 "cs-parser.jay" { if (yyToken == Token.CLOSE_BRACE) { report.Error (548, lexer.Location, "`{0}': property or indexer must have at least one accessor", current_property.GetSignatureForError ()); @@ -5238,8 +5578,8 @@ void case_200() } } -void case_201() -#line 1802 "cs-parser.jay" +void case_209() +#line 1863 "cs-parser.jay" { if (yyVals[-1+yyTop] != ModifierNone && lang_version == LanguageVersion.ISO_1) { FeatureIsNotAvailable (GetLocation (yyVals[-1+yyTop]), "access modifiers on properties"); @@ -5261,8 +5601,8 @@ void case_201() lexer.PropertyParsing = false; } -void case_202() -#line 1823 "cs-parser.jay" +void case_210() +#line 1884 "cs-parser.jay" { if (yyVals[0+yyTop] != null) { current_property.Get.Block = (ToplevelBlock) yyVals[0+yyTop]; @@ -5284,8 +5624,8 @@ void case_202() Lexer.doc_state = XmlCommentState.NotAllowed; } -void case_203() -#line 1847 "cs-parser.jay" +void case_211() +#line 1908 "cs-parser.jay" { if (yyVals[-1+yyTop] != ModifierNone && lang_version == LanguageVersion.ISO_1) { FeatureIsNotAvailable (GetLocation (yyVals[-1+yyTop]), "access modifiers on properties"); @@ -5312,8 +5652,8 @@ void case_203() lexer.PropertyParsing = false; } -void case_204() -#line 1873 "cs-parser.jay" +void case_212() +#line 1934 "cs-parser.jay" { if (yyVals[0+yyTop] != null) { current_property.Set.Block = (ToplevelBlock) yyVals[0+yyTop]; @@ -5335,29 +5675,30 @@ void case_204() Lexer.doc_state = XmlCommentState.NotAllowed; } -void case_206() -#line 1898 "cs-parser.jay" +void case_214() +#line 1959 "cs-parser.jay" { savedLocation = GetLocation (yyVals[0+yyTop]); yyVal = null; } -void case_207() -#line 1903 "cs-parser.jay" +void case_215() +#line 1964 "cs-parser.jay" { Error_SyntaxError (1043, yyToken, "Invalid accessor body"); yyVal = null; } -void case_209() -#line 1918 "cs-parser.jay" +void case_217() +#line 1978 "cs-parser.jay" { + lexer.ConstraintsParsing = true; push_current_container (new Interface (current_container, (MemberName) yyVals[0+yyTop], (Modifiers) yyVals[-4+yyTop], (Attributes) yyVals[-5+yyTop]), yyVals[-3+yyTop]); lbag.AddMember (current_container, GetModifierLocations (), GetLocation (yyVals[-2+yyTop])); } -void case_210() -#line 1924 "cs-parser.jay" +void case_218() +#line 1985 "cs-parser.jay" { lexer.ConstraintsParsing = false; @@ -5372,16 +5713,16 @@ void case_210() lexer.parsing_modifiers = true; } -void case_211() -#line 1938 "cs-parser.jay" +void case_219() +#line 1999 "cs-parser.jay" { --lexer.parsing_declaration; if (doc_support) Lexer.doc_state = XmlCommentState.Allowed; } -void case_212() -#line 1944 "cs-parser.jay" +void case_220() +#line 2005 "cs-parser.jay" { if (yyVals[0+yyTop] == null) { lbag.AppendToMember (current_container, GetLocation (yyVals[-4+yyTop]), GetLocation (yyVals[-2+yyTop])); @@ -5391,8 +5732,22 @@ void case_212() yyVal = pop_current_class (); } -void case_228() -#line 2006 "cs-parser.jay" +void case_224() +#line 2026 "cs-parser.jay" +{ + lexer.parsing_modifiers = true; + lexer.parsing_block = 0; + } + +void case_225() +#line 2031 "cs-parser.jay" +{ + lexer.parsing_modifiers = true; + lexer.parsing_block = 0; + } + +void case_236() +#line 2069 "cs-parser.jay" { OperatorDeclaration decl = (OperatorDeclaration) yyVals[-2+yyTop]; if (decl != null) { @@ -5414,22 +5769,22 @@ void case_228() lbag.AddMember (op, GetModifierLocations (), lbag.GetLocations (decl)); if (yyVals[0+yyTop] == null) { /* Semicolon*/ - lbag.AppendTo (op, savedLocation); + lbag.AddLocation (op, savedLocation); } } current_local_parameters = null; } -void case_232() -#line 2043 "cs-parser.jay" +void case_240() +#line 2106 "cs-parser.jay" { report.Error (590, GetLocation (yyVals[0+yyTop]), "User-defined operators cannot return void"); yyVal = new TypeExpression (compiler.BuiltinTypes.Void, GetLocation (yyVals[0+yyTop])); } -void case_234() -#line 2055 "cs-parser.jay" +void case_242() +#line 2118 "cs-parser.jay" { valid_param_mod = 0; @@ -5453,11 +5808,11 @@ void case_234() Operator.GetName (op)); } } else { - if (p_count > 2) { + if (p_count == 1) { + report.Error (1019, loc, "Overloadable unary operator expected"); + } else if (p_count != 2) { report.Error (1534, loc, "Overloaded binary operator `{0}' takes two parameters", Operator.GetName (op)); - } else if (p_count != 2) { - report.Error (1019, loc, "Overloadable unary operator expected"); } } @@ -5470,14 +5825,18 @@ void case_234() lbag.AddLocation (yyVal, GetLocation (yyVals[-5+yyTop]), savedOperatorLocation, GetLocation (yyVals[-3+yyTop]), GetLocation (yyVals[0+yyTop])); } -void case_259() -#line 2131 "cs-parser.jay" +void case_267() +#line 2194 "cs-parser.jay" { valid_param_mod = 0; Location loc = GetLocation (yyVals[-5+yyTop]); current_local_parameters = (ParametersCompiled)yyVals[-1+yyTop]; - + + if (current_local_parameters.Count != 1) { + report.Error (1535, loc, "Overloaded unary operator `implicit' takes one parameter"); + } + if (doc_support) { tmpComment = Lexer.consume_doc_comment (); Lexer.doc_state = XmlCommentState.NotAllowed; @@ -5487,14 +5846,18 @@ void case_259() lbag.AddLocation (yyVal, GetLocation (yyVals[-6+yyTop]), GetLocation (yyVals[-5+yyTop]), GetLocation (yyVals[-3+yyTop]), GetLocation (yyVals[0+yyTop])); } -void case_261() -#line 2150 "cs-parser.jay" +void case_269() +#line 2217 "cs-parser.jay" { valid_param_mod = 0; Location loc = GetLocation (yyVals[-5+yyTop]); current_local_parameters = (ParametersCompiled)yyVals[-1+yyTop]; - + + if (current_local_parameters.Count != 1) { + report.Error (1535, loc, "Overloaded unary operator `explicit' takes one parameter"); + } + if (doc_support) { tmpComment = Lexer.consume_doc_comment (); Lexer.doc_state = XmlCommentState.NotAllowed; @@ -5504,24 +5867,24 @@ void case_261() lbag.AddLocation (yyVal, GetLocation (yyVals[-6+yyTop]), GetLocation (yyVals[-5+yyTop]), GetLocation (yyVals[-3+yyTop]), GetLocation (yyVals[0+yyTop])); } -void case_262() -#line 2165 "cs-parser.jay" +void case_270() +#line 2236 "cs-parser.jay" { Error_SyntaxError (yyToken); current_local_parameters = ParametersCompiled.EmptyReadOnlyParameters; yyVal = new OperatorDeclaration (Operator.OpType.Implicit, null, GetLocation (yyVals[-1+yyTop])); } -void case_263() -#line 2171 "cs-parser.jay" +void case_271() +#line 2242 "cs-parser.jay" { Error_SyntaxError (yyToken); current_local_parameters = ParametersCompiled.EmptyReadOnlyParameters; yyVal = new OperatorDeclaration (Operator.OpType.Explicit, null, GetLocation (yyVals[-1+yyTop])); } -void case_264() -#line 2181 "cs-parser.jay" +void case_272() +#line 2252 "cs-parser.jay" { Constructor c = (Constructor) yyVals[-1+yyTop]; c.Block = (ToplevelBlock) yyVals[0+yyTop]; @@ -5534,8 +5897,8 @@ void case_264() Lexer.doc_state = XmlCommentState.Allowed; } -void case_265() -#line 2198 "cs-parser.jay" +void case_273() +#line 2269 "cs-parser.jay" { if (doc_support) { tmpComment = Lexer.consume_doc_comment (); @@ -5545,13 +5908,13 @@ void case_265() valid_param_mod = ParameterModifierType.All; } -void case_266() -#line 2207 "cs-parser.jay" +void case_274() +#line 2278 "cs-parser.jay" { valid_param_mod = 0; current_local_parameters = (ParametersCompiled) yyVals[-1+yyTop]; - var lt = (Tokenizer.LocatedToken) yyVals[-4+yyTop]; + var lt = (LocatedToken) yyVals[-4+yyTop]; var mods = (Modifiers) yyVals[-5+yyTop]; var c = new Constructor (current_type, lt.Value, mods, (Attributes) yyVals[-6+yyTop], current_local_parameters, lt.Location); @@ -5576,8 +5939,8 @@ void case_266() start_block (lexer.Location); } -void case_267() -#line 2236 "cs-parser.jay" +void case_275() +#line 2307 "cs-parser.jay" { if (yyVals[0+yyTop] != null) { var c = (Constructor) yyVals[-1+yyTop]; @@ -5593,39 +5956,39 @@ void case_267() yyVal = yyVals[-1+yyTop]; } -void case_273() -#line 2268 "cs-parser.jay" +void case_281() +#line 2339 "cs-parser.jay" { --lexer.parsing_block; yyVal = new ConstructorBaseInitializer ((Arguments) yyVals[-1+yyTop], GetLocation (yyVals[-4+yyTop])); lbag.AddLocation (yyVal, GetLocation (yyVals[-5+yyTop]), GetLocation (yyVals[-3+yyTop]), GetLocation (yyVals[0+yyTop])); } -void case_275() -#line 2278 "cs-parser.jay" +void case_283() +#line 2349 "cs-parser.jay" { --lexer.parsing_block; yyVal = new ConstructorThisInitializer ((Arguments) yyVals[-1+yyTop], GetLocation (yyVals[-4+yyTop])); lbag.AddLocation (yyVal, GetLocation (yyVals[-5+yyTop]), GetLocation (yyVals[-3+yyTop]), GetLocation (yyVals[0+yyTop])); } -void case_276() -#line 2284 "cs-parser.jay" +void case_284() +#line 2355 "cs-parser.jay" { Error_SyntaxError (yyToken); yyVal = new ConstructorThisInitializer (null, GetLocation (yyVals[0+yyTop])); lbag.AddLocation (yyVal, GetLocation (yyVals[-1+yyTop])); } -void case_277() -#line 2290 "cs-parser.jay" +void case_285() +#line 2361 "cs-parser.jay" { Error_SyntaxError (yyToken); yyVal = null; } -void case_278() -#line 2298 "cs-parser.jay" +void case_286() +#line 2369 "cs-parser.jay" { if (doc_support) { tmpComment = Lexer.consume_doc_comment (); @@ -5635,10 +5998,10 @@ void case_278() current_local_parameters = ParametersCompiled.EmptyReadOnlyParameters; } -void case_279() -#line 2307 "cs-parser.jay" +void case_287() +#line 2378 "cs-parser.jay" { - var lt = (Tokenizer.LocatedToken) yyVals[-3+yyTop]; + var lt = (LocatedToken) yyVals[-3+yyTop]; if (lt.Value != current_container.MemberName.Name){ report.Error (574, lt.Location, "Name of destructor must match name of class"); } else if (current_container.Kind != MemberKind.Class){ @@ -5658,8 +6021,8 @@ void case_279() current_local_parameters = null; } -void case_280() -#line 2333 "cs-parser.jay" +void case_288() +#line 2404 "cs-parser.jay" { current_event_field = new EventField (current_type, (FullNamedExpression) yyVals[-1+yyTop], (Modifiers) yyVals[-3+yyTop], (MemberName) yyVals[0+yyTop], (Attributes) yyVals[-4+yyTop]); current_type.AddMember (current_event_field); @@ -5672,20 +6035,23 @@ void case_280() yyVal = current_event_field; } -void case_281() -#line 2347 "cs-parser.jay" +void case_289() +#line 2418 "cs-parser.jay" { if (doc_support) { current_event_field.DocComment = Lexer.consume_doc_comment (); Lexer.doc_state = XmlCommentState.Allowed; } - - lbag.AddMember (current_event_field, GetModifierLocations (), GetLocation (yyVals[-6+yyTop]), GetLocation (yyVals[0+yyTop])); + if (current_event_field.Initializer != null) { + lbag.AddMember (current_event_field, GetModifierLocations (), GetLocation (yyVals[-6+yyTop]), savedEventAssignLocation, GetLocation (yyVals[0+yyTop])); + } else { + lbag.AddMember (current_event_field, GetModifierLocations (), GetLocation (yyVals[-6+yyTop]), GetLocation (yyVals[0+yyTop])); + } current_event_field = null; } -void case_282() -#line 2360 "cs-parser.jay" +void case_290() +#line 2434 "cs-parser.jay" { current_event = new EventProperty (current_type, (FullNamedExpression) yyVals[-2+yyTop], (Modifiers) yyVals[-4+yyTop], (MemberName) yyVals[-1+yyTop], (Attributes) yyVals[-5+yyTop]); current_type.AddMember (current_event); @@ -5694,8 +6060,8 @@ void case_282() lexer.EventParsing = true; } -void case_283() -#line 2368 "cs-parser.jay" +void case_291() +#line 2442 "cs-parser.jay" { if (current_container.Kind == MemberKind.Interface) report.Error (69, GetLocation (yyVals[-2+yyTop]), "Event in interface cannot have add or remove accessors"); @@ -5703,8 +6069,8 @@ void case_283() lexer.EventParsing = false; } -void case_284() -#line 2375 "cs-parser.jay" +void case_292() +#line 2449 "cs-parser.jay" { if (doc_support) { current_event.DocComment = Lexer.consume_doc_comment (); @@ -5716,32 +6082,41 @@ void case_284() current_local_parameters = null; } -void case_287() -#line 2394 "cs-parser.jay" +void case_293() +#line 2462 "cs-parser.jay" +{ + Error_SyntaxError (yyToken); + + current_type.AddMember (new EventField (current_type, (FullNamedExpression) yyVals[-1+yyTop], (Modifiers) yyVals[-3+yyTop], MemberName.Null, (Attributes) yyVals[-4+yyTop])); + } + +void case_296() +#line 2476 "cs-parser.jay" { --lexer.parsing_block; + savedEventAssignLocation = GetLocation (yyVals[-2+yyTop]); current_event_field.Initializer = (Expression) yyVals[0+yyTop]; } -void case_292() -#line 2418 "cs-parser.jay" +void case_301() +#line 2501 "cs-parser.jay" { - var lt = (Tokenizer.LocatedToken) yyVals[0+yyTop]; + var lt = (LocatedToken) yyVals[0+yyTop]; yyVal = new FieldDeclarator (new SimpleMemberName (lt.Value, lt.Location), null); lbag.AddLocation (yyVal, GetLocation (yyVals[-1+yyTop])); } -void case_294() -#line 2428 "cs-parser.jay" +void case_303() +#line 2511 "cs-parser.jay" { --lexer.parsing_block; - var lt = (Tokenizer.LocatedToken) yyVals[-3+yyTop]; + var lt = (LocatedToken) yyVals[-3+yyTop]; yyVal = new FieldDeclarator (new SimpleMemberName (lt.Value, lt.Location), (Expression) yyVals[0+yyTop]); lbag.AddLocation (yyVal, GetLocation (yyVals[-4+yyTop]), GetLocation (yyVals[-2+yyTop])); } -void case_295() -#line 2437 "cs-parser.jay" +void case_304() +#line 2520 "cs-parser.jay" { if (current_container.Kind == MemberKind.Interface) { report.Error (68, lexer.Location, "`{0}': event in interface cannot have an initializer", @@ -5754,29 +6129,29 @@ void case_295() } } -void case_299() -#line 2458 "cs-parser.jay" +void case_308() +#line 2541 "cs-parser.jay" { report.Error (65, lexer.Location, "`{0}': event property must have both add and remove accessors", current_event.GetSignatureForError ()); } -void case_300() -#line 2463 "cs-parser.jay" +void case_309() +#line 2546 "cs-parser.jay" { report.Error (65, lexer.Location, "`{0}': event property must have both add and remove accessors", current_event.GetSignatureForError ()); } -void case_301() -#line 2468 "cs-parser.jay" +void case_310() +#line 2551 "cs-parser.jay" { report.Error (1055, GetLocation (yyVals[0+yyTop]), "An add or remove accessor expected"); yyVal = null; } -void case_302() -#line 2476 "cs-parser.jay" +void case_311() +#line 2559 "cs-parser.jay" { if (yyVals[-1+yyTop] != ModifierNone) { report.Error (1609, GetLocation (yyVals[-1+yyTop]), "Modifiers cannot be placed on event accessor declarations"); @@ -5789,8 +6164,8 @@ void case_302() lexer.EventParsing = false; } -void case_303() -#line 2488 "cs-parser.jay" +void case_312() +#line 2571 "cs-parser.jay" { lexer.EventParsing = true; @@ -5804,8 +6179,8 @@ void case_303() current_local_parameters = null; } -void case_304() -#line 2504 "cs-parser.jay" +void case_313() +#line 2587 "cs-parser.jay" { if (yyVals[-1+yyTop] != ModifierNone) { report.Error (1609, GetLocation (yyVals[-1+yyTop]), "Modifiers cannot be placed on event accessor declarations"); @@ -5818,8 +6193,8 @@ void case_304() lexer.EventParsing = false; } -void case_305() -#line 2516 "cs-parser.jay" +void case_314() +#line 2599 "cs-parser.jay" { lexer.EventParsing = true; @@ -5833,30 +6208,45 @@ void case_305() current_local_parameters = null; } -void case_306() -#line 2532 "cs-parser.jay" +void case_315() +#line 2615 "cs-parser.jay" { report.Error (73, lexer.Location, "An add or remove accessor must have a body"); yyVal = null; } -void case_308() -#line 2541 "cs-parser.jay" +void case_317() +#line 2624 "cs-parser.jay" { current_type.UnattachedAttributes = (Attributes) yyVals[-1+yyTop]; report.Error (1519, GetLocation (yyVals[-1+yyTop]), "An attribute is missing member declaration"); lexer.putback ('}'); } -void case_309() -#line 2554 "cs-parser.jay" +void case_318() +#line 2635 "cs-parser.jay" +{ + report.Error (1519, lexer.Location, "Unexpected symbol `}' in class, struct, or interface member declaration"); + + lexer.putback ('}'); + + lexer.parsing_generic_declaration = false; + FullNamedExpression type = (FullNamedExpression) yyVals[-1+yyTop]; + current_field = new Field (current_type, type, (Modifiers) yyVals[-2+yyTop], MemberName.Null, (Attributes) yyVals[-3+yyTop]); + current_type.AddField (current_field); + lbag.AddMember (current_field, GetModifierLocations ()); + yyVal = current_field; + } + +void case_319() +#line 2655 "cs-parser.jay" { if (doc_support) enumTypeComment = Lexer.consume_doc_comment (); } -void case_310() -#line 2559 "cs-parser.jay" +void case_320() +#line 2660 "cs-parser.jay" { if (doc_support) Lexer.doc_state = XmlCommentState.Allowed; @@ -5874,16 +6264,18 @@ void case_310() } } -void case_311() -#line 2576 "cs-parser.jay" +void case_321() +#line 2677 "cs-parser.jay" { + lexer.parsing_modifiers = true; + /* here will be evaluated after CLOSE_BLACE is consumed.*/ if (doc_support) Lexer.doc_state = XmlCommentState.Allowed; } -void case_312() -#line 2582 "cs-parser.jay" +void case_322() +#line 2685 "cs-parser.jay" { lbag.AppendToMember (current_container, GetLocation (yyVals[-1+yyTop])); if (yyVals[0+yyTop] != null) { @@ -5900,31 +6292,31 @@ void case_312() yyVal = pop_current_class (); } -void case_314() -#line 2602 "cs-parser.jay" +void case_324() +#line 2705 "cs-parser.jay" { savedLocation = GetLocation (yyVals[-1+yyTop]); yyVal = yyVals[0+yyTop]; } -void case_315() -#line 2607 "cs-parser.jay" +void case_325() +#line 2710 "cs-parser.jay" { Error_TypeExpected (GetLocation (yyVals[-1+yyTop])); yyVal = null; } -void case_320() -#line 2625 "cs-parser.jay" +void case_330() +#line 2728 "cs-parser.jay" { lbag.AppendToMember (current_container, GetLocation (yyVals[-1+yyTop])); yyVal = yyVals[0+yyTop]; } -void case_321() -#line 2633 "cs-parser.jay" +void case_331() +#line 2736 "cs-parser.jay" { - var lt = (Tokenizer.LocatedToken) yyVals[0+yyTop]; + var lt = (LocatedToken) yyVals[0+yyTop]; var em = new EnumMember ((Enum) current_type, new MemberName (lt.Value, lt.Location), (Attributes) yyVals[-1+yyTop]); ((Enum) current_type).AddEnumMember (em); @@ -5936,8 +6328,8 @@ void case_321() yyVal = em; } -void case_322() -#line 2646 "cs-parser.jay" +void case_332() +#line 2749 "cs-parser.jay" { ++lexer.parsing_block; if (doc_support) { @@ -5946,12 +6338,12 @@ void case_322() } } -void case_323() -#line 2654 "cs-parser.jay" +void case_333() +#line 2757 "cs-parser.jay" { --lexer.parsing_block; - var lt = (Tokenizer.LocatedToken) yyVals[-3+yyTop]; + var lt = (LocatedToken) yyVals[-3+yyTop]; var em = new EnumMember ((Enum) current_type, new MemberName (lt.Value, lt.Location), (Attributes) yyVals[-4+yyTop]); em.Initializer = new ConstInitializer (em, (Expression) yyVals[0+yyTop], GetLocation (yyVals[-1+yyTop])); ((Enum) current_type).AddEnumMember (em); @@ -5962,12 +6354,12 @@ void case_323() yyVal = em; } -void case_324() -#line 2668 "cs-parser.jay" +void case_334() +#line 2771 "cs-parser.jay" { Error_SyntaxError (yyToken); - var lt = (Tokenizer.LocatedToken) yyVals[-1+yyTop]; + var lt = (LocatedToken) yyVals[-1+yyTop]; var em = new EnumMember ((Enum) current_type, new MemberName (lt.Value, lt.Location), (Attributes) yyVals[-2+yyTop]); ((Enum) current_type).AddEnumMember (em); @@ -5979,8 +6371,8 @@ void case_324() yyVal = em; } -void case_327() -#line 2695 "cs-parser.jay" +void case_337() +#line 2798 "cs-parser.jay" { valid_param_mod = 0; @@ -5996,8 +6388,8 @@ void case_327() lexer.ConstraintsParsing = true; } -void case_329() -#line 2714 "cs-parser.jay" +void case_339() +#line 2817 "cs-parser.jay" { if (doc_support) { current_delegate.DocComment = Lexer.consume_doc_comment (); @@ -6013,8 +6405,8 @@ void case_329() current_delegate = null; } -void case_331() -#line 2733 "cs-parser.jay" +void case_341() +#line 2836 "cs-parser.jay" { if (lang_version < LanguageVersion.ISO_2) FeatureIsNotAvailable (GetLocation (yyVals[0+yyTop]), "nullable types"); @@ -6022,33 +6414,33 @@ void case_331() yyVal = ComposedTypeSpecifier.CreateNullable (GetLocation (yyVals[0+yyTop])); } -void case_333() -#line 2744 "cs-parser.jay" +void case_343() +#line 2847 "cs-parser.jay" { - var lt1 = (Tokenizer.LocatedToken) yyVals[-2+yyTop]; - var lt2 = (Tokenizer.LocatedToken) yyVals[-1+yyTop]; + var lt1 = (LocatedToken) yyVals[-2+yyTop]; + var lt2 = (LocatedToken) yyVals[-1+yyTop]; yyVal = new QualifiedAliasMember (lt1.Value, lt2.Value, (TypeArguments) yyVals[0+yyTop], lt1.Location); - lbag.AddLocation (yyVal, GetLocation (yyVals[-1+yyTop])); + lbag.AddLocation (yyVal, savedLocation, GetLocation (yyVals[-1+yyTop])); } -void case_335() -#line 2756 "cs-parser.jay" +void case_345() +#line 2859 "cs-parser.jay" { - var lt = (Tokenizer.LocatedToken) yyVals[-1+yyTop]; + var lt = (LocatedToken) yyVals[-1+yyTop]; yyVal = new MemberAccess ((Expression) yyVals[-3+yyTop], lt.Value, (TypeArguments) yyVals[0+yyTop], lt.Location); lbag.AddLocation (yyVal, GetLocation (yyVals[-2+yyTop])); } -void case_336() -#line 2765 "cs-parser.jay" +void case_346() +#line 2868 "cs-parser.jay" { - var lt = (Tokenizer.LocatedToken) yyVals[-1+yyTop]; + var lt = (LocatedToken) yyVals[-1+yyTop]; yyVal = new SimpleName (lt.Value, (TypeArguments)yyVals[0+yyTop], lt.Location); } -void case_338() -#line 2777 "cs-parser.jay" +void case_348() +#line 2880 "cs-parser.jay" { if (lang_version < LanguageVersion.ISO_2) FeatureIsNotAvailable (GetLocation (yyVals[-2+yyTop]), "generics"); @@ -6060,15 +6452,15 @@ void case_338() yyVal = yyVals[-1+yyTop];; } -void case_339() -#line 2788 "cs-parser.jay" +void case_349() +#line 2891 "cs-parser.jay" { Error_TypeExpected (lexer.Location); yyVal = new TypeArguments (); } -void case_340() -#line 2796 "cs-parser.jay" +void case_350() +#line 2899 "cs-parser.jay" { TypeArguments type_args = new TypeArguments (); type_args.Add ((FullNamedExpression) yyVals[0+yyTop]); @@ -6076,8 +6468,8 @@ void case_340() locationListStack.Push (new List ()); } -void case_341() -#line 2803 "cs-parser.jay" +void case_351() +#line 2906 "cs-parser.jay" { TypeArguments type_args = (TypeArguments) yyVals[-2+yyTop]; type_args.Add ((FullNamedExpression) yyVals[0+yyTop]); @@ -6085,16 +6477,16 @@ void case_341() locationListStack.Peek ().Add (GetLocation (yyVals[-1+yyTop])); } -void case_343() -#line 2820 "cs-parser.jay" +void case_353() +#line 2923 "cs-parser.jay" { lexer.parsing_generic_declaration = false; - var lt = (Tokenizer.LocatedToken) yyVals[-2+yyTop]; + var lt = (LocatedToken) yyVals[-2+yyTop]; yyVal = new MemberName (lt.Value, (TypeParameters)yyVals[0+yyTop], lt.Location); } -void case_344() -#line 2829 "cs-parser.jay" +void case_354() +#line 2932 "cs-parser.jay" { MemberName mn = (MemberName)yyVals[0+yyTop]; if (mn.TypeParameters != null) @@ -6102,56 +6494,56 @@ void case_344() mn.GetSignatureForError ())); } -void case_346() -#line 2840 "cs-parser.jay" +void case_356() +#line 2943 "cs-parser.jay" { lexer.parsing_generic_declaration = false; - var lt = (Tokenizer.LocatedToken) yyVals[-1+yyTop]; + var lt = (LocatedToken) yyVals[-1+yyTop]; yyVal = new MemberName (lt.Value, (TypeParameters) yyVals[0+yyTop], (ATypeNameExpression) yyVals[-2+yyTop], lt.Location); } -void case_347() -#line 2849 "cs-parser.jay" +void case_357() +#line 2952 "cs-parser.jay" { lexer.parsing_generic_declaration = false; yyVal = new MemberName (TypeDefinition.DefaultIndexerName, GetLocation (yyVals[0+yyTop])); } -void case_348() -#line 2854 "cs-parser.jay" +void case_358() +#line 2957 "cs-parser.jay" { lexer.parsing_generic_declaration = false; yyVal = new MemberName (TypeDefinition.DefaultIndexerName, null, (ATypeNameExpression) yyVals[-1+yyTop], GetLocation (yyVals[0+yyTop])); } -void case_349() -#line 2862 "cs-parser.jay" +void case_359() +#line 2965 "cs-parser.jay" { - var lt = (Tokenizer.LocatedToken) yyVals[-2+yyTop]; + var lt = (LocatedToken) yyVals[-2+yyTop]; yyVal = new SimpleName (lt.Value, (TypeArguments) yyVals[-1+yyTop], lt.Location); lbag.AddLocation (yyVal, GetLocation (yyVals[0+yyTop])); } -void case_350() -#line 2868 "cs-parser.jay" +void case_360() +#line 2971 "cs-parser.jay" { - var lt1 = (Tokenizer.LocatedToken) yyVals[-3+yyTop]; - var lt2 = (Tokenizer.LocatedToken) yyVals[-2+yyTop]; + var lt1 = (LocatedToken) yyVals[-3+yyTop]; + var lt2 = (LocatedToken) yyVals[-2+yyTop]; yyVal = new QualifiedAliasMember (lt1.Value, lt2.Value, (TypeArguments) yyVals[-1+yyTop], lt1.Location); - lbag.AddLocation (yyVal, GetLocation (yyVals[0+yyTop])); + lbag.AddLocation (yyVal, savedLocation, GetLocation (yyVals[0+yyTop])); } -void case_351() -#line 2876 "cs-parser.jay" +void case_361() +#line 2979 "cs-parser.jay" { - var lt = (Tokenizer.LocatedToken) yyVals[-2+yyTop]; + var lt = (LocatedToken) yyVals[-2+yyTop]; yyVal = new MemberAccess ((ATypeNameExpression) yyVals[-3+yyTop], lt.Value, (TypeArguments) yyVals[-1+yyTop], lt.Location); lbag.AddLocation (yyVal, GetLocation (yyVals[0+yyTop])); } -void case_353() -#line 2886 "cs-parser.jay" +void case_363() +#line 2989 "cs-parser.jay" { if (lang_version < LanguageVersion.ISO_2) FeatureIsNotAvailable (GetLocation (yyVals[-2+yyTop]), "generics"); @@ -6163,8 +6555,8 @@ void case_353() lbag.AddLocation (yyVals[-1+yyTop], list); } -void case_354() -#line 2900 "cs-parser.jay" +void case_364() +#line 3003 "cs-parser.jay" { var tparams = new TypeParameters (); tparams.Add ((TypeParameter)yyVals[0+yyTop]); @@ -6172,8 +6564,8 @@ void case_354() locationListStack.Push (new List ()); } -void case_355() -#line 2907 "cs-parser.jay" +void case_365() +#line 3010 "cs-parser.jay" { var tparams = (TypeParameters) yyVals[-2+yyTop]; tparams.Add ((TypeParameter)yyVals[0+yyTop]); @@ -6181,47 +6573,50 @@ void case_355() locationListStack.Peek ().Add (GetLocation (yyVals[-1+yyTop])); } -void case_356() -#line 2917 "cs-parser.jay" +void case_366() +#line 3020 "cs-parser.jay" { - var lt = (Tokenizer.LocatedToken)yyVals[0+yyTop]; - yyVal = new TypeParameter (new MemberName (lt.Value, lt.Location), (Attributes)yyVals[-2+yyTop], (Variance) yyVals[-1+yyTop]); + var lt = (LocatedToken)yyVals[0+yyTop]; + var variance = (VarianceDecl) yyVals[-1+yyTop]; + yyVal = new TypeParameter (new MemberName (lt.Value, lt.Location), (Attributes)yyVals[-2+yyTop], variance); + if (variance != null) + lbag.AddLocation (yyVal, savedLocation); } -void case_357() -#line 2922 "cs-parser.jay" +void case_367() +#line 3028 "cs-parser.jay" { if (GetTokenName (yyToken) == "type") report.Error (81, GetLocation (yyVals[0+yyTop]), "Type parameter declaration must be an identifier not a type"); else Error_SyntaxError (yyToken); - yyVal = new TypeParameter (MemberName.Null, null, Variance.None); + yyVal = new TypeParameter (MemberName.Null, null, null); } -void case_362() -#line 2956 "cs-parser.jay" +void case_372() +#line 3062 "cs-parser.jay" { Expression.Error_VoidInvalidInTheContext (GetLocation (yyVals[0+yyTop]), report); yyVal = new TypeExpression (compiler.BuiltinTypes.Void, GetLocation (yyVals[0+yyTop])); } -void case_364() -#line 2965 "cs-parser.jay" +void case_374() +#line 3071 "cs-parser.jay" { Expression.Error_VoidInvalidInTheContext (GetLocation (yyVals[0+yyTop]), report); yyVal = new TypeExpression (compiler.BuiltinTypes.Void, GetLocation (yyVals[0+yyTop])); } -void case_366() -#line 2974 "cs-parser.jay" +void case_376() +#line 3080 "cs-parser.jay" { report.Error (1536, GetLocation (yyVals[0+yyTop]), "Invalid parameter type `void'"); yyVal = new TypeExpression (compiler.BuiltinTypes.Void, GetLocation (yyVals[0+yyTop])); } -void case_369() -#line 2990 "cs-parser.jay" +void case_379() +#line 3096 "cs-parser.jay" { if (yyVals[0+yyTop] != null) { yyVal = new ComposedCast ((ATypeNameExpression) yyVals[-1+yyTop], (ComposedTypeSpecifier) yyVals[0+yyTop]); @@ -6234,32 +6629,32 @@ void case_369() } } -void case_371() -#line 3006 "cs-parser.jay" +void case_381() +#line 3112 "cs-parser.jay" { if (yyVals[0+yyTop] != null) yyVal = new ComposedCast ((FullNamedExpression) yyVals[-1+yyTop], (ComposedTypeSpecifier) yyVals[0+yyTop]); } -void case_374() -#line 3022 "cs-parser.jay" +void case_384() +#line 3128 "cs-parser.jay" { var types = new List (2); types.Add ((FullNamedExpression) yyVals[0+yyTop]); yyVal = types; } -void case_375() -#line 3028 "cs-parser.jay" +void case_385() +#line 3134 "cs-parser.jay" { var types = (List) yyVals[-2+yyTop]; types.Add ((FullNamedExpression) yyVals[0+yyTop]); - lbag.AppendTo (types, GetLocation (yyVals[-1+yyTop])); + lbag.AddLocation (types, GetLocation (yyVals[-1+yyTop])); yyVal = types; } -void case_376() -#line 3038 "cs-parser.jay" +void case_386() +#line 3144 "cs-parser.jay" { if (yyVals[0+yyTop] is ComposedCast) { report.Error (1521, GetLocation (yyVals[0+yyTop]), "Invalid base type `{0}'", ((ComposedCast)yyVals[0+yyTop]).GetSignatureForError ()); @@ -6267,87 +6662,92 @@ void case_376() yyVal = yyVals[0+yyTop]; } -void case_413() -#line 3102 "cs-parser.jay" +void case_423() +#line 3208 "cs-parser.jay" { - var lt = (Tokenizer.LocatedToken) yyVals[-1+yyTop]; + var lt = (LocatedToken) yyVals[-1+yyTop]; yyVal = new SimpleName (lt.Value, (TypeArguments)yyVals[0+yyTop], lt.Location); } -void case_414() -#line 3106 "cs-parser.jay" +void case_424() +#line 3212 "cs-parser.jay" { - var lt = (Tokenizer.LocatedToken) yyVals[-1+yyTop]; + var lt = (LocatedToken) yyVals[-1+yyTop]; yyVal = new CompletionSimpleName (MemberName.MakeName (lt.Value, null), lt.Location); } -void case_425() -#line 3147 "cs-parser.jay" +void case_435() +#line 3253 "cs-parser.jay" { - yyVal = new ParenthesizedExpression ((Expression) yyVals[-1+yyTop]); + yyVal = new ParenthesizedExpression ((Expression) yyVals[-1+yyTop], GetLocation (yyVals[-2+yyTop])); lbag.AddLocation (yyVal, GetLocation (yyVals[-2+yyTop]), GetLocation (yyVals[0+yyTop])); } -void case_427() -#line 3159 "cs-parser.jay" +void case_437() +#line 3265 "cs-parser.jay" { - var lt = (Tokenizer.LocatedToken) yyVals[-1+yyTop]; - yyVal = new MemberAccess ((Expression) yyVals[-3+yyTop], lt.Value, (TypeArguments) yyVals[0+yyTop], lt.Location) { - DotLocation = GetLocation (yyVals[-2+yyTop]) - }; + var lt = (LocatedToken) yyVals[-1+yyTop]; + yyVal = new MemberAccess ((Expression) yyVals[-3+yyTop], lt.Value, (TypeArguments) yyVals[0+yyTop], lt.Location); + lbag.AddLocation (yyVal, GetLocation (yyVals[-2+yyTop])); } -void case_428() -#line 3166 "cs-parser.jay" +void case_438() +#line 3271 "cs-parser.jay" { - var lt = (Tokenizer.LocatedToken) yyVals[-1+yyTop]; - yyVal = new MemberAccess ((Expression) yyVals[-3+yyTop], lt.Value, (TypeArguments) yyVals[0+yyTop], lt.Location) { - DotLocation = GetLocation (yyVals[-2+yyTop]) - }; + var lt = (LocatedToken) yyVals[-1+yyTop]; + yyVal = new MemberAccess ((Expression) yyVals[-3+yyTop], lt.Value, (TypeArguments) yyVals[0+yyTop], lt.Location); + lbag.AddLocation (yyVal, GetLocation (yyVals[-2+yyTop])); } -void case_429() -#line 3173 "cs-parser.jay" +void case_439() +#line 3277 "cs-parser.jay" { - var lt = (Tokenizer.LocatedToken) yyVals[-1+yyTop]; - yyVal = new MemberAccess (new BaseThis (GetLocation (yyVals[-3+yyTop])), lt.Value, (TypeArguments) yyVals[0+yyTop], lt.Location) { - DotLocation = GetLocation (yyVals[-2+yyTop]) - }; + var lt = (LocatedToken) yyVals[-1+yyTop]; + yyVal = new MemberAccess (new BaseThis (GetLocation (yyVals[-3+yyTop])), lt.Value, (TypeArguments) yyVals[0+yyTop], lt.Location); + lbag.AddLocation (yyVal, GetLocation (yyVals[-2+yyTop])); + } + +void case_440() +#line 3283 "cs-parser.jay" +{ + var lt = (LocatedToken) yyVals[-1+yyTop]; + yyVal = new MemberAccess (new SimpleName ("await", ((LocatedToken) yyVals[-3+yyTop]).Location), lt.Value, (TypeArguments) yyVals[0+yyTop], lt.Location); + lbag.AddLocation (yyVal, GetLocation (yyVals[-2+yyTop])); } -void case_430() -#line 3180 "cs-parser.jay" +void case_441() +#line 3289 "cs-parser.jay" { - var lt1 = (Tokenizer.LocatedToken) yyVals[-2+yyTop]; - var lt2 = (Tokenizer.LocatedToken) yyVals[-1+yyTop]; + var lt1 = (LocatedToken) yyVals[-2+yyTop]; + var lt2 = (LocatedToken) yyVals[-1+yyTop]; yyVal = new QualifiedAliasMember (lt1.Value, lt2.Value, (TypeArguments) yyVals[0+yyTop], lt1.Location); - lbag.AddLocation (yyVal, GetLocation (yyVals[-1+yyTop])); + lbag.AddLocation (yyVal, savedLocation, GetLocation (yyVals[-1+yyTop])); } -void case_432() -#line 3190 "cs-parser.jay" +void case_443() +#line 3299 "cs-parser.jay" { - var lt = (Tokenizer.LocatedToken) yyVals[-1+yyTop]; + var lt = (LocatedToken) yyVals[-1+yyTop]; yyVal = new CompletionMemberAccess ((Expression) yyVals[-3+yyTop], lt.Value, lt.Location); } -void case_434() -#line 3198 "cs-parser.jay" +void case_445() +#line 3307 "cs-parser.jay" { - var lt = (Tokenizer.LocatedToken) yyVals[-1+yyTop]; + var lt = (LocatedToken) yyVals[-1+yyTop]; yyVal = new CompletionMemberAccess ((Expression) yyVals[-3+yyTop], lt.Value, lt.Location); } -void case_435() -#line 3206 "cs-parser.jay" +void case_446() +#line 3315 "cs-parser.jay" { yyVal = new Invocation ((Expression) yyVals[-3+yyTop], (Arguments) yyVals[-1+yyTop]); lbag.AddLocation (yyVal, GetLocation (yyVals[-2+yyTop]), GetLocation (yyVals[0+yyTop])); } -void case_436() -#line 3211 "cs-parser.jay" +void case_447() +#line 3320 "cs-parser.jay" { Error_SyntaxError (yyToken); @@ -6355,59 +6755,75 @@ void case_436() lbag.AddLocation (yyVal, GetLocation (yyVals[-2+yyTop])); } -void case_439() -#line 3227 "cs-parser.jay" +void case_448() +#line 3327 "cs-parser.jay" +{ + Error_SyntaxError (yyToken); + + yyVal = new Invocation ((Expression) yyVals[-2+yyTop], null); + lbag.AddLocation (yyVal, GetLocation (yyVals[-1+yyTop])); + } + +void case_451() +#line 3342 "cs-parser.jay" { if (yyVals[-1+yyTop] == null) { - yyVal = new CollectionOrObjectInitializers (new List (), GetLocation (yyVals[-2+yyTop])); - lbag.AddLocation (yyVal, GetLocation (yyVals[-2+yyTop]), GetLocation (yyVals[0+yyTop])); + yyVal = new CollectionOrObjectInitializers (GetLocation (yyVals[-2+yyTop])); } else { yyVal = new CollectionOrObjectInitializers ((List) yyVals[-1+yyTop], GetLocation (yyVals[-2+yyTop])); - lbag.AddLocation (yyVal, GetLocation (yyVals[-2+yyTop]), GetLocation (yyVals[0+yyTop])); } + lbag.AddLocation (yyVal, GetLocation (yyVals[0+yyTop])); } -void case_440() -#line 3237 "cs-parser.jay" +void case_452() +#line 3351 "cs-parser.jay" { yyVal = new CollectionOrObjectInitializers ((List) yyVals[-2+yyTop], GetLocation (yyVals[-3+yyTop])); - lbag.AddLocation (yyVal, GetLocation (yyVals[-3+yyTop]), GetLocation (yyVals[-1+yyTop]), GetLocation (yyVals[0+yyTop])); + lbag.AddLocation (yyVal, GetLocation (yyVals[-1+yyTop]), GetLocation (yyVals[0+yyTop])); } -void case_443() -#line 3253 "cs-parser.jay" +void case_455() +#line 3367 "cs-parser.jay" { var a = new List (); a.Add ((Expression) yyVals[0+yyTop]); yyVal = a; } -void case_444() -#line 3259 "cs-parser.jay" +void case_456() +#line 3373 "cs-parser.jay" { var a = (List)yyVals[-2+yyTop]; a.Add ((Expression) yyVals[0+yyTop]); - lbag.AppendTo (a, GetLocation (yyVals[-1+yyTop])); + lbag.AddLocation (a, GetLocation (yyVals[-1+yyTop])); yyVal = a; } -void case_445() -#line 3265 "cs-parser.jay" +void case_457() +#line 3379 "cs-parser.jay" { Error_SyntaxError (yyToken); yyVal = yyVals[-1+yyTop]; } -void case_446() -#line 3273 "cs-parser.jay" +void case_458() +#line 3387 "cs-parser.jay" { - var lt = (Tokenizer.LocatedToken) yyVals[-2+yyTop]; + var lt = (LocatedToken) yyVals[-2+yyTop]; yyVal = new ElementInitializer (lt.Value, (Expression)yyVals[0+yyTop], lt.Location); lbag.AddLocation (yyVal, GetLocation (yyVals[-1+yyTop])); } -void case_448() -#line 3282 "cs-parser.jay" +void case_459() +#line 3393 "cs-parser.jay" +{ + var lt = (LocatedToken) Error_AwaitAsIdentifier (yyVals[-2+yyTop]); + yyVal = new ElementInitializer (lt.Value, (Expression)yyVals[0+yyTop], lt.Location); + lbag.AddLocation (yyVal, GetLocation (yyVals[-1+yyTop])); + } + +void case_461() +#line 3402 "cs-parser.jay" { CompletionSimpleName csn = yyVals[-1+yyTop] as CompletionSimpleName; if (csn == null) @@ -6416,47 +6832,47 @@ void case_448() yyVal = new CompletionElementInitializer (csn.Prefix, csn.Location); } -void case_449() -#line 3290 "cs-parser.jay" +void case_462() +#line 3410 "cs-parser.jay" { if (yyVals[-1+yyTop] == null) - yyVal = null; + yyVal = new CollectionElementInitializer (GetLocation (yyVals[-2+yyTop])); else { yyVal = new CollectionElementInitializer ((List)yyVals[-1+yyTop], GetLocation (yyVals[-2+yyTop])); lbag.AddLocation (yyVal, GetLocation (yyVals[-1+yyTop])); - } + } } -void case_450() -#line 3299 "cs-parser.jay" +void case_463() +#line 3419 "cs-parser.jay" { report.Error (1920, GetLocation (yyVals[-1+yyTop]), "An element initializer cannot be empty"); - yyVal = new CollectionElementInitializer (new List (), GetLocation (yyVals[-1+yyTop])); + yyVal = new CollectionElementInitializer (GetLocation (yyVals[-1+yyTop])); lbag.AddLocation (yyVal, GetLocation (yyVals[0+yyTop])); } -void case_455() -#line 3318 "cs-parser.jay" +void case_468() +#line 3438 "cs-parser.jay" { Arguments list = new Arguments (4); list.Add ((Argument) yyVals[0+yyTop]); yyVal = list; } -void case_456() -#line 3324 "cs-parser.jay" +void case_469() +#line 3444 "cs-parser.jay" { Arguments list = (Arguments) yyVals[-2+yyTop]; if (list [list.Count - 1] is NamedArgument) Error_NamedArgumentExpected ((NamedArgument) list [list.Count - 1]); list.Add ((Argument) yyVals[0+yyTop]); - lbag.AppendTo (list, GetLocation (yyVals[-1+yyTop])); + lbag.AddLocation (list, GetLocation (yyVals[-1+yyTop])); yyVal = list; } -void case_457() -#line 3334 "cs-parser.jay" +void case_470() +#line 3454 "cs-parser.jay" { Arguments list = (Arguments) yyVals[-2+yyTop]; NamedArgument a = (NamedArgument) yyVals[0+yyTop]; @@ -6468,134 +6884,128 @@ void case_457() } list.Add (a); - lbag.AppendTo (list, GetLocation (yyVals[-1+yyTop])); + lbag.AddLocation (list, GetLocation (yyVals[-1+yyTop])); yyVal = list; } -void case_458() -#line 3349 "cs-parser.jay" +void case_471() +#line 3469 "cs-parser.jay" { - lexer.putback (')'); /* TODO: Wrong but what can I do*/ + if (lexer.putback_char == -1) + lexer.putback (')'); /* TODO: Wrong but what can I do*/ Error_SyntaxError (yyToken); yyVal = yyVals[-2+yyTop]; } -void case_459() -#line 3355 "cs-parser.jay" +void case_472() +#line 3476 "cs-parser.jay" { report.Error (839, GetLocation (yyVals[-1+yyTop]), "An argument is missing"); yyVal = null; } -void case_464() -#line 3376 "cs-parser.jay" +void case_477() +#line 3497 "cs-parser.jay" { yyVal = new Argument ((Expression) yyVals[0+yyTop], Argument.AType.Ref); lbag.AddLocation (yyVal, GetLocation (yyVals[-1+yyTop])); } -void case_465() -#line 3381 "cs-parser.jay" +void case_478() +#line 3502 "cs-parser.jay" { yyVal = new Argument ((Expression) yyVals[0+yyTop], Argument.AType.Out); lbag.AddLocation (yyVal, GetLocation (yyVals[-1+yyTop])); } -void case_466() -#line 3386 "cs-parser.jay" +void case_479() +#line 3507 "cs-parser.jay" { yyVal = new Argument (new Arglist ((Arguments) yyVals[-1+yyTop], GetLocation (yyVals[-3+yyTop]))); lbag.AddLocation (yyVal, GetLocation (yyVals[-2+yyTop]), GetLocation (yyVals[0+yyTop])); } -void case_467() -#line 3391 "cs-parser.jay" +void case_480() +#line 3512 "cs-parser.jay" { yyVal = new Argument (new Arglist (GetLocation (yyVals[-2+yyTop]))); lbag.AddLocation (yyVal, GetLocation (yyVals[-1+yyTop]), GetLocation (yyVals[0+yyTop])); } -void case_469() -#line 3403 "cs-parser.jay" +void case_482() +#line 3524 "cs-parser.jay" { yyVal = new ElementAccess ((Expression) yyVals[-3+yyTop], (Arguments) yyVals[-1+yyTop], GetLocation (yyVals[-2+yyTop])); lbag.AddLocation (yyVal, GetLocation (yyVals[0+yyTop])); } -void case_470() -#line 3408 "cs-parser.jay" +void case_483() +#line 3529 "cs-parser.jay" { Error_SyntaxError (yyToken); yyVal = new ElementAccess ((Expression) yyVals[-3+yyTop], (Arguments) yyVals[-1+yyTop], GetLocation (yyVals[-2+yyTop])); } -void case_471() -#line 3413 "cs-parser.jay" +void case_484() +#line 3534 "cs-parser.jay" { Error_SyntaxError (yyToken); yyVal = new ElementAccess ((Expression) yyVals[-2+yyTop], null, GetLocation (yyVals[-1+yyTop])); } -void case_472() -#line 3421 "cs-parser.jay" +void case_485() +#line 3542 "cs-parser.jay" { var list = new List (4); list.Add ((Expression) yyVals[0+yyTop]); yyVal = list; } -void case_473() -#line 3427 "cs-parser.jay" +void case_486() +#line 3548 "cs-parser.jay" { var list = (List) yyVals[-2+yyTop]; list.Add ((Expression) yyVals[0+yyTop]); - lbag.AppendTo (list, GetLocation (yyVals[-1+yyTop])); + lbag.AddLocation (list, GetLocation (yyVals[-1+yyTop])); yyVal = list; } -void case_474() -#line 3433 "cs-parser.jay" -{ - Error_SyntaxError (yyToken); - yyVal = yyVals[-1+yyTop]; - } - -void case_475() -#line 3441 "cs-parser.jay" +void case_487() +#line 3558 "cs-parser.jay" { Arguments args = new Arguments (4); args.Add ((Argument) yyVals[0+yyTop]); yyVal = args; } -void case_476() -#line 3447 "cs-parser.jay" +void case_488() +#line 3564 "cs-parser.jay" { Arguments args = (Arguments) yyVals[-2+yyTop]; if (args [args.Count - 1] is NamedArgument && !(yyVals[0+yyTop] is NamedArgument)) Error_NamedArgumentExpected ((NamedArgument) args [args.Count - 1]); args.Add ((Argument) yyVals[0+yyTop]); - lbag.AppendTo (args, GetLocation (yyVals[-1+yyTop])); + lbag.AddLocation (args, GetLocation (yyVals[-1+yyTop])); yyVal = args; } -void case_480() -#line 3475 "cs-parser.jay" +void case_492() +#line 3592 "cs-parser.jay" { yyVal = new ElementAccess (new BaseThis (GetLocation (yyVals[-3+yyTop])), (Arguments) yyVals[-1+yyTop], GetLocation (yyVals[-2+yyTop])); lbag.AddLocation (yyVal, GetLocation (yyVals[0+yyTop])); } -void case_481() -#line 3480 "cs-parser.jay" +void case_493() +#line 3597 "cs-parser.jay" { Error_SyntaxError (yyToken); yyVal = new ElementAccess (null, null, GetLocation (yyVals[-1+yyTop])); } -void case_484() -#line 3502 "cs-parser.jay" +void case_496() +#line 3619 "cs-parser.jay" { if (yyVals[0+yyTop] != null) { if (lang_version <= LanguageVersion.ISO_2) @@ -6609,8 +7019,8 @@ void case_484() lbag.AddLocation (yyVal, GetLocation (yyVals[-3+yyTop]), GetLocation (yyVals[-1+yyTop])); } -void case_485() -#line 3515 "cs-parser.jay" +void case_497() +#line 3632 "cs-parser.jay" { if (lang_version <= LanguageVersion.ISO_2) FeatureIsNotAvailable (GetLocation (yyVals[-2+yyTop]), "collection initializers"); @@ -6618,8 +7028,8 @@ void case_485() yyVal = new NewInitialize ((FullNamedExpression) yyVals[-1+yyTop], null, (CollectionOrObjectInitializers) yyVals[0+yyTop], GetLocation (yyVals[-2+yyTop])); } -void case_486() -#line 3527 "cs-parser.jay" +void case_498() +#line 3644 "cs-parser.jay" { yyVal = new ArrayCreation ((FullNamedExpression) yyVals[-5+yyTop], (List) yyVals[-3+yyTop], new ComposedTypeSpecifier (((List) yyVals[-3+yyTop]).Count, GetLocation (yyVals[-4+yyTop])) { @@ -6628,8 +7038,8 @@ void case_486() lbag.AddLocation (yyVal, GetLocation (yyVals[-4+yyTop]), GetLocation (yyVals[-2+yyTop])); } -void case_487() -#line 3535 "cs-parser.jay" +void case_499() +#line 3652 "cs-parser.jay" { if (yyVals[0+yyTop] == null) report.Error (1586, GetLocation (yyVals[-3+yyTop]), "Array creation must have array size or array initializer"); @@ -6637,8 +7047,8 @@ void case_487() yyVal = new ArrayCreation ((FullNamedExpression) yyVals[-2+yyTop], (ComposedTypeSpecifier) yyVals[-1+yyTop], (ArrayInitializer) yyVals[0+yyTop], GetLocation (yyVals[-3+yyTop])); } -void case_488() -#line 3542 "cs-parser.jay" +void case_500() +#line 3659 "cs-parser.jay" { if (lang_version <= LanguageVersion.ISO_2) FeatureIsNotAvailable (GetLocation (yyVals[-2+yyTop]), "implicitly typed arrays"); @@ -6646,30 +7056,30 @@ void case_488() yyVal = new ImplicitlyTypedArrayCreation ((ComposedTypeSpecifier) yyVals[-1+yyTop], (ArrayInitializer) yyVals[0+yyTop], GetLocation (yyVals[-2+yyTop])); } -void case_489() -#line 3549 "cs-parser.jay" +void case_501() +#line 3666 "cs-parser.jay" { report.Error (178, GetLocation (yyVals[-1+yyTop]), "Invalid rank specifier, expecting `,' or `]'"); yyVal = new ArrayCreation ((FullNamedExpression) yyVals[-5+yyTop], null, GetLocation (yyVals[-6+yyTop])); } -void case_490() -#line 3554 "cs-parser.jay" +void case_502() +#line 3671 "cs-parser.jay" { Error_SyntaxError (yyToken); /* It can be any of new expression, create the most common one*/ yyVal = new New ((FullNamedExpression) yyVals[-1+yyTop], null, GetLocation (yyVals[-2+yyTop])); } -void case_492() -#line 3566 "cs-parser.jay" +void case_504() +#line 3683 "cs-parser.jay" { --lexer.parsing_type; yyVal = yyVals[0+yyTop]; } -void case_493() -#line 3574 "cs-parser.jay" +void case_505() +#line 3691 "cs-parser.jay" { if (lang_version <= LanguageVersion.ISO_2) FeatureIsNotAvailable (GetLocation (yyVals[-3+yyTop]), "anonymous types"); @@ -6680,78 +7090,78 @@ void case_493() lbag.AddLocation (yyVal, GetLocation (yyVals[-2+yyTop]), GetLocation (yyVals[0+yyTop])); } -void case_498() -#line 3597 "cs-parser.jay" +void case_511() +#line 3718 "cs-parser.jay" { var a = new List (4); a.Add ((AnonymousTypeParameter) yyVals[0+yyTop]); yyVal = a; } -void case_499() -#line 3603 "cs-parser.jay" +void case_512() +#line 3724 "cs-parser.jay" { var a = (List) yyVals[-2+yyTop]; a.Add ((AnonymousTypeParameter) yyVals[0+yyTop]); - lbag.AppendTo (a, GetLocation (yyVals[-1+yyTop])); + lbag.AddLocation (a, GetLocation (yyVals[-1+yyTop])); yyVal = a; } -void case_500() -#line 3614 "cs-parser.jay" +void case_515() +#line 3743 "cs-parser.jay" { - var lt = (Tokenizer.LocatedToken)yyVals[-2+yyTop]; + var lt = (LocatedToken)yyVals[-2+yyTop]; yyVal = new AnonymousTypeParameter ((Expression)yyVals[0+yyTop], lt.Value, lt.Location); lbag.AddLocation (yyVal, GetLocation (yyVals[-1+yyTop])); } -void case_501() -#line 3620 "cs-parser.jay" +void case_516() +#line 3749 "cs-parser.jay" { - var lt = (Tokenizer.LocatedToken)yyVals[0+yyTop]; + var lt = (LocatedToken)yyVals[0+yyTop]; yyVal = new AnonymousTypeParameter (new SimpleName (lt.Value, lt.Location), lt.Value, lt.Location); } -void case_502() -#line 3626 "cs-parser.jay" +void case_517() +#line 3755 "cs-parser.jay" { MemberAccess ma = (MemberAccess) yyVals[0+yyTop]; yyVal = new AnonymousTypeParameter (ma, ma.Name, ma.Location); } -void case_503() -#line 3631 "cs-parser.jay" +void case_518() +#line 3760 "cs-parser.jay" { report.Error (746, lexer.Location, "Invalid anonymous type member declarator. Anonymous type members must be a member assignment, simple name or member access expression"); yyVal = null; } -void case_507() -#line 3646 "cs-parser.jay" +void case_522() +#line 3775 "cs-parser.jay" { ((ComposedTypeSpecifier) yyVals[-1+yyTop]).Next = (ComposedTypeSpecifier) yyVals[0+yyTop]; yyVal = yyVals[-1+yyTop]; } -void case_508() -#line 3654 "cs-parser.jay" +void case_523() +#line 3783 "cs-parser.jay" { yyVal = ComposedTypeSpecifier.CreateArrayDimension (1, GetLocation (yyVals[-1+yyTop])); lbag.AddLocation (yyVal, GetLocation (yyVals[0+yyTop])); } -void case_509() -#line 3659 "cs-parser.jay" +void case_524() +#line 3788 "cs-parser.jay" { yyVal = ComposedTypeSpecifier.CreateArrayDimension ((int)yyVals[-1+yyTop], GetLocation (yyVals[-2+yyTop])); lbag.AddLocation (yyVal, GetLocation (yyVals[0+yyTop])); } -void case_514() -#line 3689 "cs-parser.jay" +void case_529() +#line 3818 "cs-parser.jay" { var ai = new ArrayInitializer (0, GetLocation (yyVals[-1+yyTop])); ai.VariableDeclaration = current_variable; @@ -6759,8 +7169,8 @@ void case_514() yyVal = ai; } -void case_515() -#line 3696 "cs-parser.jay" +void case_530() +#line 3825 "cs-parser.jay" { var ai = new ArrayInitializer ((List) yyVals[-2+yyTop], GetLocation (yyVals[-3+yyTop])); ai.VariableDeclaration = current_variable; @@ -6772,91 +7182,95 @@ void case_515() yyVal = ai; } -void case_516() -#line 3710 "cs-parser.jay" +void case_531() +#line 3839 "cs-parser.jay" { var list = new List (4); list.Add ((Expression) yyVals[0+yyTop]); yyVal = list; } -void case_517() -#line 3716 "cs-parser.jay" +void case_532() +#line 3845 "cs-parser.jay" { var list = (List) yyVals[-2+yyTop]; list.Add ((Expression) yyVals[0+yyTop]); - lbag.AppendTo (list, GetLocation (yyVals[-1+yyTop])); + lbag.AddLocation (list, GetLocation (yyVals[-1+yyTop])); yyVal = list; } -void case_519() -#line 3730 "cs-parser.jay" +void case_534() +#line 3859 "cs-parser.jay" { lexer.TypeOfParsing = false; yyVal = new TypeOf ((FullNamedExpression) yyVals[-1+yyTop], GetLocation (yyVals[-4+yyTop])); lbag.AddLocation (yyVal, GetLocation (yyVals[-2+yyTop]), GetLocation (yyVals[0+yyTop])); } -void case_522() -#line 3741 "cs-parser.jay" +void case_537() +#line 3870 "cs-parser.jay" { Error_TypeExpected (lexer.Location); yyVal = null; } -void case_523() -#line 3749 "cs-parser.jay" +void case_538() +#line 3878 "cs-parser.jay" { - var lt = (Tokenizer.LocatedToken) yyVals[-1+yyTop]; + var lt = (LocatedToken) yyVals[-1+yyTop]; - yyVal = new SimpleName (lt.Value, (int) yyVals[0+yyTop], lt.Location); + var sn = new SimpleName (lt.Value, (int) yyVals[0+yyTop], lt.Location); + yyVal = sn; + lbag.AddLocation (sn.TypeArguments, Lexer.GetGenericDimensionLocations ()); } -void case_524() -#line 3755 "cs-parser.jay" +void case_539() +#line 3886 "cs-parser.jay" { - var lt1 = (Tokenizer.LocatedToken) yyVals[-2+yyTop]; - var lt2 = (Tokenizer.LocatedToken) yyVals[-1+yyTop]; + var lt1 = (LocatedToken) yyVals[-2+yyTop]; + var lt2 = (LocatedToken) yyVals[-1+yyTop]; - yyVal = new QualifiedAliasMember (lt1.Value, lt2.Value, (int) yyVals[0+yyTop], lt1.Location); - lbag.AddLocation (yyVal, GetLocation (yyVals[-1+yyTop])); + var qam = new QualifiedAliasMember (lt1.Value, lt2.Value, (int) yyVals[0+yyTop], lt1.Location); + yyVal = qam; + lbag.AddLocation (qam.TypeArguments, Lexer.GetGenericDimensionLocations ()); + lbag.AddLocation (yyVal, savedLocation, GetLocation (yyVals[-1+yyTop])); } -void case_525() -#line 3763 "cs-parser.jay" +void case_540() +#line 3896 "cs-parser.jay" { - var lt = (Tokenizer.LocatedToken) yyVals[0+yyTop]; + var lt = (LocatedToken) yyVals[0+yyTop]; - yyVal = new MemberAccess ((Expression) yyVals[-2+yyTop], lt.Value, lt.Location) { - DotLocation = GetLocation (yyVals[-1+yyTop]) - }; + yyVal = new MemberAccess ((Expression) yyVals[-2+yyTop], lt.Value, lt.Location); + lbag.AddLocation (yyVal, savedLocation, GetLocation (yyVals[-1+yyTop])); } -void case_526() -#line 3771 "cs-parser.jay" +void case_541() +#line 3903 "cs-parser.jay" { - var lt = (Tokenizer.LocatedToken) yyVals[-1+yyTop]; + var lt = (LocatedToken) yyVals[-1+yyTop]; - yyVal = new MemberAccess ((Expression) yyVals[-3+yyTop], lt.Value, (int) yyVals[0+yyTop], lt.Location) { - DotLocation = GetLocation (yyVals[-2+yyTop]) - }; + var ma = new MemberAccess ((Expression) yyVals[-3+yyTop], lt.Value, (int) yyVals[0+yyTop], lt.Location); + yyVal = ma; + lbag.AddLocation (yyVal, savedLocation, GetLocation (yyVals[-2+yyTop])); + lbag.AddLocation (ma.TypeArguments, Lexer.GetGenericDimensionLocations ()); } -void case_527() -#line 3779 "cs-parser.jay" +void case_542() +#line 3912 "cs-parser.jay" { var tne = (ATypeNameExpression) yyVals[-3+yyTop]; if (tne.HasTypeArguments) Error_TypeExpected (GetLocation (yyVals[0+yyTop])); - var lt = (Tokenizer.LocatedToken) yyVals[-1+yyTop]; - yyVal = new MemberAccess (tne, lt.Value, (int) yyVals[0+yyTop], lt.Location) { - DotLocation = GetLocation (yyVals[-2+yyTop]) - }; + var lt = (LocatedToken) yyVals[-1+yyTop]; + var ma = new MemberAccess (tne, lt.Value, (int) yyVals[0+yyTop], lt.Location); + yyVal = ma; + lbag.AddLocation (ma.TypeArguments, Lexer.GetGenericDimensionLocations ()); } -void case_528() -#line 3793 "cs-parser.jay" +void case_543() +#line 3926 "cs-parser.jay" { if (lang_version < LanguageVersion.ISO_2) FeatureIsNotAvailable (GetLocation (yyVals[0+yyTop]), "generics"); @@ -6864,78 +7278,103 @@ void case_528() yyVal = yyVals[0+yyTop]; } -void case_529() -#line 3803 "cs-parser.jay" +void case_544() +#line 3936 "cs-parser.jay" { - var lt = (Tokenizer.LocatedToken) yyVals[-1+yyTop]; + var lt = (LocatedToken) yyVals[-1+yyTop]; if (lang_version == LanguageVersion.ISO_1) FeatureIsNotAvailable (lt.Location, "namespace alias qualifier"); - + savedLocation = GetLocation (yyVals[0+yyTop]); yyVal = lt; } -void case_530() -#line 3814 "cs-parser.jay" +void case_545() +#line 3947 "cs-parser.jay" { yyVal = new SizeOf ((Expression) yyVals[-1+yyTop], GetLocation (yyVals[-3+yyTop])); lbag.AddLocation (yyVal, GetLocation (yyVals[-2+yyTop]), GetLocation (yyVals[0+yyTop])); } -void case_531() -#line 3822 "cs-parser.jay" +void case_546() +#line 3952 "cs-parser.jay" +{ + Error_SyntaxError (yyToken); + + yyVal = new SizeOf ((Expression) yyVals[-1+yyTop], GetLocation (yyVals[-3+yyTop])); + lbag.AddLocation (yyVal, GetLocation (yyVals[-2+yyTop])); + } + +void case_547() +#line 3962 "cs-parser.jay" { yyVal = new CheckedExpr ((Expression) yyVals[-1+yyTop], GetLocation (yyVals[-3+yyTop])); lbag.AddLocation (yyVal, GetLocation (yyVals[-2+yyTop]), GetLocation (yyVals[0+yyTop])); } -void case_532() -#line 3830 "cs-parser.jay" +void case_548() +#line 3967 "cs-parser.jay" +{ + Error_SyntaxError (yyToken); + + yyVal = new CheckedExpr (null, GetLocation (yyVals[-1+yyTop])); + } + +void case_549() +#line 3976 "cs-parser.jay" { yyVal = new UnCheckedExpr ((Expression) yyVals[-1+yyTop], GetLocation (yyVals[-3+yyTop])); lbag.AddLocation (yyVal, GetLocation (yyVals[-2+yyTop]), GetLocation (yyVals[0+yyTop])); } -void case_533() -#line 3838 "cs-parser.jay" +void case_550() +#line 3981 "cs-parser.jay" +{ + Error_SyntaxError (yyToken); + + yyVal = new UnCheckedExpr (null, GetLocation (yyVals[-1+yyTop])); + } + +void case_551() +#line 3990 "cs-parser.jay" { - var lt = (Tokenizer.LocatedToken) yyVals[-1+yyTop]; + var lt = (LocatedToken) yyVals[-1+yyTop]; yyVal = new MemberAccess (new Indirection ((Expression) yyVals[-3+yyTop], GetLocation (yyVals[-2+yyTop])), lt.Value, (TypeArguments) yyVals[0+yyTop], lt.Location); } -void case_535() -#line 3850 "cs-parser.jay" +void case_553() +#line 4002 "cs-parser.jay" { yyVal = end_anonymous ((ParametersBlock) yyVals[0+yyTop]); if ((ParametersCompiled) yyVals[-2+yyTop] != ParametersCompiled.Undefined) { - lbag.AddLocation (yyVal, GetLocation (yyVals[-3+yyTop]), savedOpenLocation, savedCloseLocation); + lbag.AddLocation (yyVal, GetLocation (yyVals[-3+yyTop]), PopLocation (), PopLocation ()); } else { lbag.AddLocation (yyVal, GetLocation (yyVals[-3+yyTop])); } } -void case_537() -#line 3863 "cs-parser.jay" +void case_555() +#line 4015 "cs-parser.jay" { yyVal = end_anonymous ((ParametersBlock) yyVals[0+yyTop]); if ((ParametersCompiled) yyVals[-2+yyTop] != ParametersCompiled.Undefined) { - lbag.AddLocation (yyVal, GetLocation (yyVals[-4+yyTop]), GetLocation (yyVals[-3+yyTop]), savedOpenLocation, savedCloseLocation); + lbag.AddLocation (yyVal, GetLocation (yyVals[-4+yyTop]), GetLocation (yyVals[-3+yyTop]), PopLocation (), PopLocation ()); } else { lbag.AddLocation (yyVal, GetLocation (yyVals[-4+yyTop]), GetLocation (yyVals[-3+yyTop])); } } -void case_541() -#line 3888 "cs-parser.jay" +void case_559() +#line 4040 "cs-parser.jay" { valid_param_mod = 0; yyVal = yyVals[-1+yyTop]; - savedOpenLocation = GetLocation (yyVals[-3+yyTop]); - savedCloseLocation = GetLocation (yyVals[-2+yyTop]); + PushLocation (GetLocation (yyVals[-1+yyTop])); + PushLocation (GetLocation (yyVals[-3+yyTop])); } -void case_542() -#line 3898 "cs-parser.jay" +void case_560() +#line 4050 "cs-parser.jay" { if (lang_version < LanguageVersion.ISO_2) FeatureIsNotAvailable (GetLocation (yyVals[-3+yyTop]), "default value expression"); @@ -6944,23 +7383,26 @@ void case_542() lbag.AddLocation (yyVal, GetLocation (yyVals[-2+yyTop]), GetLocation (yyVals[0+yyTop])); } -void case_546() -#line 3918 "cs-parser.jay" +void case_564() +#line 4070 "cs-parser.jay" { yyVal = new Cast ((FullNamedExpression) yyVals[-2+yyTop], (Expression) yyVals[0+yyTop], GetLocation (yyVals[-3+yyTop])); lbag.AddLocation (yyVal, GetLocation (yyVals[-1+yyTop])); } -void case_547() -#line 3923 "cs-parser.jay" +void case_565() +#line 4075 "cs-parser.jay" { if (!async_block) { if (current_anonymous_method is LambdaExpression) { report.Error (4034, GetLocation (yyVals[-1+yyTop]), "The `await' operator can only be used when its containing lambda expression is marked with the `async' modifier"); - } else if (current_anonymous_method is AnonymousMethodExpression) { + } else if (current_anonymous_method != null) { report.Error (4035, GetLocation (yyVals[-1+yyTop]), "The `await' operator can only be used when its containing anonymous method is marked with the `async' modifier"); + } else if (interactive_async != null) { + current_block.Explicit.RegisterAsyncAwait (); + interactive_async = true; } else { report.Error (4033, GetLocation (yyVals[-1+yyTop]), "The `await' operator can only be used when its containing method is marked with the `async' modifier"); @@ -6972,2341 +7414,2729 @@ void case_547() yyVal = new Await ((Expression) yyVals[0+yyTop], GetLocation (yyVals[-1+yyTop])); } -void case_556() -#line 3978 "cs-parser.jay" +void case_566() +#line 4097 "cs-parser.jay" { - yyVal = new Binary (Binary.Operator.Multiply, (Expression) yyVals[-2+yyTop], (Expression) yyVals[0+yyTop]); - lbag.AddLocation (yyVal, GetLocation (yyVals[-1+yyTop])); + Error_SyntaxError (yyToken); + + yyVal = new Unary (Unary.Operator.LogicalNot, null, GetLocation (yyVals[-1+yyTop])); } -void case_557() -#line 3983 "cs-parser.jay" +void case_567() +#line 4103 "cs-parser.jay" { - yyVal = new Binary (Binary.Operator.Division, (Expression) yyVals[-2+yyTop], (Expression) yyVals[0+yyTop]); - lbag.AddLocation (yyVal, GetLocation (yyVals[-1+yyTop])); + Error_SyntaxError (yyToken); + + yyVal = new Unary (Unary.Operator.OnesComplement, null, GetLocation (yyVals[-1+yyTop])); } -void case_558() -#line 3988 "cs-parser.jay" +void case_568() +#line 4109 "cs-parser.jay" { - yyVal = new Binary (Binary.Operator.Modulus, (Expression) yyVals[-2+yyTop], (Expression) yyVals[0+yyTop]); + Error_SyntaxError (yyToken); + + yyVal = new Cast ((FullNamedExpression) yyVals[-2+yyTop], null, GetLocation (yyVals[-3+yyTop])); lbag.AddLocation (yyVal, GetLocation (yyVals[-1+yyTop])); } -void case_560() -#line 3997 "cs-parser.jay" +void case_569() +#line 4116 "cs-parser.jay" { - yyVal = new Binary (Binary.Operator.Addition, (Expression) yyVals[-2+yyTop], (Expression) yyVals[0+yyTop]); - lbag.AddLocation (yyVal, GetLocation (yyVals[-1+yyTop])); + Error_SyntaxError (yyToken); + + yyVal = new Await (null, GetLocation (yyVals[-1+yyTop])); } -void case_561() -#line 4002 "cs-parser.jay" -{ - yyVal = new Binary (Binary.Operator.Subtraction, (Expression) yyVals[-2+yyTop], (Expression) yyVals[0+yyTop]); - lbag.AddLocation (yyVal, GetLocation (yyVals[-1+yyTop])); +void case_577() +#line 4154 "cs-parser.jay" +{ + Error_SyntaxError (yyToken); + + yyVal = new Unary (Unary.Operator.UnaryPlus, null, GetLocation (yyVals[-1+yyTop])); } -void case_565() -#line 4019 "cs-parser.jay" -{ - yyVal = new Binary (Binary.Operator.LeftShift, (Expression) yyVals[-2+yyTop], (Expression) yyVals[0+yyTop]); - lbag.AddLocation (yyVal, GetLocation (yyVals[-1+yyTop])); +void case_578() +#line 4160 "cs-parser.jay" +{ + Error_SyntaxError (yyToken); + + yyVal = new Unary (Unary.Operator.UnaryNegation, null, GetLocation (yyVals[-1+yyTop])); } -void case_566() -#line 4024 "cs-parser.jay" +void case_579() +#line 4166 "cs-parser.jay" { - yyVal = new Binary (Binary.Operator.RightShift, (Expression) yyVals[-2+yyTop], (Expression) yyVals[0+yyTop]); - lbag.AddLocation (yyVal, GetLocation (yyVals[-1+yyTop])); + Error_SyntaxError (yyToken); + + yyVal = new UnaryMutator (UnaryMutator.Mode.PreIncrement, null, GetLocation (yyVals[-1+yyTop])); } -void case_568() -#line 4033 "cs-parser.jay" +void case_580() +#line 4172 "cs-parser.jay" { - yyVal = new Binary (Binary.Operator.LessThan, (Expression) yyVals[-2+yyTop], (Expression) yyVals[0+yyTop]); - lbag.AddLocation (yyVal, GetLocation (yyVals[-1+yyTop])); + Error_SyntaxError (yyToken); + + yyVal = new UnaryMutator (UnaryMutator.Mode.PreDecrement, null, GetLocation (yyVals[-1+yyTop])); } -void case_569() -#line 4038 "cs-parser.jay" +void case_581() +#line 4178 "cs-parser.jay" { - yyVal = new Binary (Binary.Operator.GreaterThan, (Expression) yyVals[-2+yyTop], (Expression) yyVals[0+yyTop]); - lbag.AddLocation (yyVal, GetLocation (yyVals[-1+yyTop])); + Error_SyntaxError (yyToken); + + yyVal = new Indirection (null, GetLocation (yyVals[-1+yyTop])); } -void case_570() -#line 4043 "cs-parser.jay" +void case_582() +#line 4184 "cs-parser.jay" { - yyVal = new Binary (Binary.Operator.LessThanOrEqual, (Expression) yyVals[-2+yyTop], (Expression) yyVals[0+yyTop]); - lbag.AddLocation (yyVal, GetLocation (yyVals[-1+yyTop])); + Error_SyntaxError (yyToken); + + yyVal = new Unary (Unary.Operator.AddressOf, null, GetLocation (yyVals[-1+yyTop])); } -void case_571() -#line 4048 "cs-parser.jay" +void case_584() +#line 4194 "cs-parser.jay" { - yyVal = new Binary (Binary.Operator.GreaterThanOrEqual, (Expression) yyVals[-2+yyTop], (Expression) yyVals[0+yyTop]); + yyVal = new Binary (Binary.Operator.Multiply, (Expression) yyVals[-2+yyTop], (Expression) yyVals[0+yyTop]); lbag.AddLocation (yyVal, GetLocation (yyVals[-1+yyTop])); } -void case_573() -#line 4057 "cs-parser.jay" +void case_585() +#line 4199 "cs-parser.jay" { - yyVal = new Binary (Binary.Operator.Equality, (Expression) yyVals[-2+yyTop], (Expression) yyVals[0+yyTop]); + yyVal = new Binary (Binary.Operator.Division, (Expression) yyVals[-2+yyTop], (Expression) yyVals[0+yyTop]); lbag.AddLocation (yyVal, GetLocation (yyVals[-1+yyTop])); } -void case_574() -#line 4062 "cs-parser.jay" +void case_586() +#line 4204 "cs-parser.jay" { - yyVal = new Binary (Binary.Operator.Inequality, (Expression) yyVals[-2+yyTop], (Expression) yyVals[0+yyTop]); + yyVal = new Binary (Binary.Operator.Modulus, (Expression) yyVals[-2+yyTop], (Expression) yyVals[0+yyTop]); lbag.AddLocation (yyVal, GetLocation (yyVals[-1+yyTop])); } -void case_576() -#line 4071 "cs-parser.jay" +void case_587() +#line 4209 "cs-parser.jay" { - yyVal = new Binary (Binary.Operator.BitwiseAnd, (Expression) yyVals[-2+yyTop], (Expression) yyVals[0+yyTop]); + Error_SyntaxError (yyToken); + + yyVal = new Binary (Binary.Operator.Multiply, (Expression) yyVals[-2+yyTop], null); lbag.AddLocation (yyVal, GetLocation (yyVals[-1+yyTop])); } -void case_578() -#line 4080 "cs-parser.jay" +void case_588() +#line 4216 "cs-parser.jay" { - yyVal = new Binary (Binary.Operator.ExclusiveOr, (Expression) yyVals[-2+yyTop], (Expression) yyVals[0+yyTop]); + Error_SyntaxError (yyToken); + + yyVal = new Binary (Binary.Operator.Division, (Expression) yyVals[-2+yyTop], null); lbag.AddLocation (yyVal, GetLocation (yyVals[-1+yyTop])); } -void case_580() -#line 4089 "cs-parser.jay" +void case_589() +#line 4223 "cs-parser.jay" { - yyVal = new Binary (Binary.Operator.BitwiseOr, (Expression) yyVals[-2+yyTop], (Expression) yyVals[0+yyTop]); + Error_SyntaxError (yyToken); + + yyVal = new Binary (Binary.Operator.Modulus, (Expression) yyVals[-2+yyTop], null); lbag.AddLocation (yyVal, GetLocation (yyVals[-1+yyTop])); } -void case_582() -#line 4098 "cs-parser.jay" +void case_591() +#line 4234 "cs-parser.jay" { - yyVal = new Binary (Binary.Operator.LogicalAnd, (Expression) yyVals[-2+yyTop], (Expression) yyVals[0+yyTop]); + yyVal = new Binary (Binary.Operator.Addition, (Expression) yyVals[-2+yyTop], (Expression) yyVals[0+yyTop]); lbag.AddLocation (yyVal, GetLocation (yyVals[-1+yyTop])); } -void case_584() -#line 4107 "cs-parser.jay" +void case_592() +#line 4239 "cs-parser.jay" { - yyVal = new Binary (Binary.Operator.LogicalOr, (Expression) yyVals[-2+yyTop], (Expression) yyVals[0+yyTop]); + yyVal = new Binary (Binary.Operator.Subtraction, (Expression) yyVals[-2+yyTop], (Expression) yyVals[0+yyTop]); lbag.AddLocation (yyVal, GetLocation (yyVals[-1+yyTop])); } -void case_586() -#line 4116 "cs-parser.jay" +void case_595() +#line 4252 "cs-parser.jay" { - if (lang_version < LanguageVersion.ISO_2) - FeatureIsNotAvailable (GetLocation (yyVals[-1+yyTop]), "null coalescing operator"); - - yyVal = new Nullable.NullCoalescingOperator ((Expression) yyVals[-2+yyTop], (Expression) yyVals[0+yyTop]); + Error_SyntaxError (yyToken); + + yyVal = new Binary (Binary.Operator.Addition, (Expression) yyVals[-2+yyTop], null); lbag.AddLocation (yyVal, GetLocation (yyVals[-1+yyTop])); } -void case_588() -#line 4128 "cs-parser.jay" +void case_596() +#line 4259 "cs-parser.jay" { - yyVal = new Conditional (new BooleanExpression ((Expression) yyVals[-4+yyTop]), (Expression) yyVals[-2+yyTop], (Expression) yyVals[0+yyTop], GetLocation (yyVals[-3+yyTop])); + Error_SyntaxError (yyToken); + + yyVal = new Binary (Binary.Operator.Subtraction, (Expression) yyVals[-2+yyTop], null); lbag.AddLocation (yyVal, GetLocation (yyVals[-1+yyTop])); } -void case_589() -#line 4133 "cs-parser.jay" +void case_597() +#line 4266 "cs-parser.jay" { Error_SyntaxError (yyToken); - yyVal = new Conditional (new BooleanExpression ((Expression) yyVals[-3+yyTop]), (Expression) yyVals[-1+yyTop], null, GetLocation (yyVals[-2+yyTop])); - } -void case_590() -#line 4141 "cs-parser.jay" -{ - yyVal = new SimpleAssign ((Expression) yyVals[-2+yyTop], (Expression) yyVals[0+yyTop]); - lbag.AddLocation (yyVal, GetLocation (yyVals[-1+yyTop])); + yyVal = new As ((Expression) yyVals[-2+yyTop], null, GetLocation (yyVals[-1+yyTop])); } -void case_591() -#line 4146 "cs-parser.jay" +void case_598() +#line 4272 "cs-parser.jay" { - yyVal = new CompoundAssign (Binary.Operator.Multiply, (Expression) yyVals[-2+yyTop], (Expression) yyVals[0+yyTop]); - lbag.AddLocation (yyVal, GetLocation (yyVals[-1+yyTop])); + Error_SyntaxError (yyToken); + + yyVal = new Is ((Expression) yyVals[-2+yyTop], null, GetLocation (yyVals[-1+yyTop])); } -void case_592() -#line 4151 "cs-parser.jay" +void case_599() +#line 4278 "cs-parser.jay" { - yyVal = new CompoundAssign (Binary.Operator.Division, (Expression) yyVals[-2+yyTop], (Expression) yyVals[0+yyTop]); - lbag.AddLocation (yyVal, GetLocation (yyVals[-1+yyTop])); + var lt = (LocatedToken) yyVals[-2+yyTop]; + yyVal = new Is (new SimpleName (lt.Value, lt.Location), (Expression) yyVals[0+yyTop], GetLocation (yyVals[-1+yyTop])); } -void case_593() -#line 4156 "cs-parser.jay" +void case_600() +#line 4283 "cs-parser.jay" { - yyVal = new CompoundAssign (Binary.Operator.Modulus, (Expression) yyVals[-2+yyTop], (Expression) yyVals[0+yyTop]); - lbag.AddLocation (yyVal, GetLocation (yyVals[-1+yyTop])); + var lt = (LocatedToken) yyVals[-2+yyTop]; + yyVal = new As (new SimpleName (lt.Value, lt.Location), (Expression) yyVals[0+yyTop], GetLocation (yyVals[-1+yyTop])); } -void case_594() -#line 4161 "cs-parser.jay" +void case_602() +#line 4292 "cs-parser.jay" { - yyVal = new CompoundAssign (Binary.Operator.Addition, (Expression) yyVals[-2+yyTop], (Expression) yyVals[0+yyTop]); + yyVal = new Binary (Binary.Operator.LeftShift, (Expression) yyVals[-2+yyTop], (Expression) yyVals[0+yyTop]); lbag.AddLocation (yyVal, GetLocation (yyVals[-1+yyTop])); } -void case_595() -#line 4166 "cs-parser.jay" +void case_603() +#line 4297 "cs-parser.jay" { - yyVal = new CompoundAssign (Binary.Operator.Subtraction, (Expression) yyVals[-2+yyTop], (Expression) yyVals[0+yyTop]); + yyVal = new Binary (Binary.Operator.RightShift, (Expression) yyVals[-2+yyTop], (Expression) yyVals[0+yyTop]); lbag.AddLocation (yyVal, GetLocation (yyVals[-1+yyTop])); } -void case_596() -#line 4171 "cs-parser.jay" +void case_604() +#line 4302 "cs-parser.jay" { - yyVal = new CompoundAssign (Binary.Operator.LeftShift, (Expression) yyVals[-2+yyTop], (Expression) yyVals[0+yyTop]); + Error_SyntaxError (yyToken); + + yyVal = new Binary (Binary.Operator.LeftShift, (Expression) yyVals[-2+yyTop], null); lbag.AddLocation (yyVal, GetLocation (yyVals[-1+yyTop])); } -void case_597() -#line 4176 "cs-parser.jay" +void case_605() +#line 4309 "cs-parser.jay" { - yyVal = new CompoundAssign (Binary.Operator.RightShift, (Expression) yyVals[-2+yyTop], (Expression) yyVals[0+yyTop]); + Error_SyntaxError (yyToken); + + yyVal = new Binary (Binary.Operator.RightShift, (Expression) yyVals[-2+yyTop], null); lbag.AddLocation (yyVal, GetLocation (yyVals[-1+yyTop])); } -void case_598() -#line 4181 "cs-parser.jay" +void case_607() +#line 4320 "cs-parser.jay" { - yyVal = new CompoundAssign (Binary.Operator.BitwiseAnd, (Expression) yyVals[-2+yyTop], (Expression) yyVals[0+yyTop]); + yyVal = new Binary (Binary.Operator.LessThan, (Expression) yyVals[-2+yyTop], (Expression) yyVals[0+yyTop]); lbag.AddLocation (yyVal, GetLocation (yyVals[-1+yyTop])); } -void case_599() -#line 4186 "cs-parser.jay" +void case_608() +#line 4325 "cs-parser.jay" { - yyVal = new CompoundAssign (Binary.Operator.BitwiseOr, (Expression) yyVals[-2+yyTop], (Expression) yyVals[0+yyTop]); + yyVal = new Binary (Binary.Operator.GreaterThan, (Expression) yyVals[-2+yyTop], (Expression) yyVals[0+yyTop]); lbag.AddLocation (yyVal, GetLocation (yyVals[-1+yyTop])); } -void case_600() -#line 4191 "cs-parser.jay" +void case_609() +#line 4330 "cs-parser.jay" { - yyVal = new CompoundAssign (Binary.Operator.ExclusiveOr, (Expression) yyVals[-2+yyTop], (Expression) yyVals[0+yyTop]); + yyVal = new Binary (Binary.Operator.LessThanOrEqual, (Expression) yyVals[-2+yyTop], (Expression) yyVals[0+yyTop]); lbag.AddLocation (yyVal, GetLocation (yyVals[-1+yyTop])); } -void case_601() -#line 4199 "cs-parser.jay" +void case_610() +#line 4335 "cs-parser.jay" { - var pars = new List (4); - pars.Add ((Parameter) yyVals[0+yyTop]); - parameterListCommas.Clear (); - yyVal = pars; + yyVal = new Binary (Binary.Operator.GreaterThanOrEqual, (Expression) yyVals[-2+yyTop], (Expression) yyVals[0+yyTop]); + lbag.AddLocation (yyVal, GetLocation (yyVals[-1+yyTop])); } -void case_602() -#line 4206 "cs-parser.jay" +void case_611() +#line 4340 "cs-parser.jay" { - var pars = (List) yyVals[-2+yyTop]; - Parameter p = (Parameter)yyVals[0+yyTop]; - if (pars[0].GetType () != p.GetType ()) { - report.Error (748, p.Location, "All lambda parameters must be typed either explicitly or implicitly"); - } - - pars.Add (p); - parameterListCommas.Add (GetLocation (yyVals[-1+yyTop])); + Error_SyntaxError (yyToken); - yyVal = pars; + yyVal = new Binary (Binary.Operator.LessThan, (Expression) yyVals[-2+yyTop], null); + lbag.AddLocation (yyVal, GetLocation (yyVals[-1+yyTop])); } -void case_603() -#line 4222 "cs-parser.jay" +void case_612() +#line 4347 "cs-parser.jay" { - var lt = (Tokenizer.LocatedToken) yyVals[0+yyTop]; + Error_SyntaxError (yyToken); - yyVal = new Parameter ((FullNamedExpression) yyVals[-1+yyTop], lt.Value, (Parameter.Modifier) yyVals[-2+yyTop], null, lt.Location); + yyVal = new Binary (Binary.Operator.GreaterThan, (Expression) yyVals[-2+yyTop], null); + lbag.AddLocation (yyVal, GetLocation (yyVals[-1+yyTop])); } -void case_604() -#line 4228 "cs-parser.jay" +void case_613() +#line 4354 "cs-parser.jay" { - var lt = (Tokenizer.LocatedToken) yyVals[0+yyTop]; + Error_SyntaxError (yyToken); - yyVal = new Parameter ((FullNamedExpression) yyVals[-1+yyTop], lt.Value, Parameter.Modifier.NONE, null, lt.Location); + yyVal = new Binary (Binary.Operator.LessThanOrEqual, (Expression) yyVals[-2+yyTop], null); + lbag.AddLocation (yyVal, GetLocation (yyVals[-1+yyTop])); } -void case_605() -#line 4234 "cs-parser.jay" +void case_614() +#line 4361 "cs-parser.jay" { - var lt = (Tokenizer.LocatedToken) yyVals[0+yyTop]; - yyVal = new ImplicitLambdaParameter (lt.Value, lt.Location); - } + Error_SyntaxError (yyToken); -void case_607() -#line 4242 "cs-parser.jay" -{ - var pars_list = (List) yyVals[0+yyTop]; - yyVal = new ParametersCompiled (pars_list.ToArray ()); - lbag.AddLocation (yyVal, parameterListCommas); + yyVal = new Binary (Binary.Operator.GreaterThanOrEqual, (Expression) yyVals[-2+yyTop], null); + lbag.AddLocation (yyVal, GetLocation (yyVals[-1+yyTop])); } -void case_611() -#line 4259 "cs-parser.jay" +void case_616() +#line 4372 "cs-parser.jay" { - Block b = end_block (Location.Null); - b.IsCompilerGenerated = true; - b.AddStatement (new ContextualReturn ((Expression) yyVals[0+yyTop])); - yyVal = b; + yyVal = new Binary (Binary.Operator.Equality, (Expression) yyVals[-2+yyTop], (Expression) yyVals[0+yyTop]); + lbag.AddLocation (yyVal, GetLocation (yyVals[-1+yyTop])); } -void case_613() -#line 4270 "cs-parser.jay" +void case_617() +#line 4377 "cs-parser.jay" { - Error_SyntaxError (yyToken); - yyVal = EmptyExpression.Null; + yyVal = new Binary (Binary.Operator.Inequality, (Expression) yyVals[-2+yyTop], (Expression) yyVals[0+yyTop]); + lbag.AddLocation (yyVal, GetLocation (yyVals[-1+yyTop])); } -void case_614() -#line 4278 "cs-parser.jay" +void case_618() +#line 4382 "cs-parser.jay" { - var lt = (Tokenizer.LocatedToken) yyVals[-1+yyTop]; - Parameter p = new ImplicitLambdaParameter (lt.Value, lt.Location); - start_anonymous (true, new ParametersCompiled (p), false, lt.Location); + Error_SyntaxError (yyToken); + + yyVal = new Binary (Binary.Operator.Equality, (Expression) yyVals[-2+yyTop], null); + lbag.AddLocation (yyVal, GetLocation (yyVals[-1+yyTop])); } -void case_615() -#line 4284 "cs-parser.jay" +void case_619() +#line 4389 "cs-parser.jay" { - yyVal = end_anonymous ((ParametersBlock) yyVals[0+yyTop]); - lbag.AddLocation (yyVal, GetLocation (yyVals[-2+yyTop])); + Error_SyntaxError (yyToken); + + yyVal = new Binary (Binary.Operator.Inequality, (Expression) yyVals[-2+yyTop], null); + lbag.AddLocation (yyVal, GetLocation (yyVals[-1+yyTop])); } -void case_616() -#line 4289 "cs-parser.jay" +void case_621() +#line 4400 "cs-parser.jay" { - var lt = (Tokenizer.LocatedToken) yyVals[-1+yyTop]; - Parameter p = new ImplicitLambdaParameter (lt.Value, lt.Location); - start_anonymous (true, new ParametersCompiled (p), true, lt.Location); + yyVal = new Binary (Binary.Operator.BitwiseAnd, (Expression) yyVals[-2+yyTop], (Expression) yyVals[0+yyTop]); + lbag.AddLocation (yyVal, GetLocation (yyVals[-1+yyTop])); } -void case_617() -#line 4295 "cs-parser.jay" +void case_622() +#line 4405 "cs-parser.jay" { - yyVal = end_anonymous ((ParametersBlock) yyVals[0+yyTop]); - lbag.AddLocation (yyVal, GetLocation (yyVals[-4+yyTop]), GetLocation (yyVals[-2+yyTop])); + Error_SyntaxError (yyToken); + + yyVal = new Binary (Binary.Operator.BitwiseAnd, (Expression) yyVals[-2+yyTop], null); + lbag.AddLocation (yyVal, GetLocation (yyVals[-1+yyTop])); } -void case_619() -#line 4304 "cs-parser.jay" +void case_624() +#line 4416 "cs-parser.jay" { - valid_param_mod = 0; - start_anonymous (true, (ParametersCompiled) yyVals[-2+yyTop], false, GetLocation (yyVals[-4+yyTop])); + yyVal = new Binary (Binary.Operator.ExclusiveOr, (Expression) yyVals[-2+yyTop], (Expression) yyVals[0+yyTop]); + lbag.AddLocation (yyVal, GetLocation (yyVals[-1+yyTop])); } -void case_620() -#line 4309 "cs-parser.jay" +void case_625() +#line 4421 "cs-parser.jay" { - yyVal = end_anonymous ((ParametersBlock) yyVals[0+yyTop]); - lbag.AddLocation (yyVal, GetLocation (yyVals[-6+yyTop]), GetLocation (yyVals[-3+yyTop]), GetLocation (yyVals[-2+yyTop])); + Error_SyntaxError (yyToken); + + yyVal = new Binary (Binary.Operator.ExclusiveOr, (Expression) yyVals[-2+yyTop], null); + lbag.AddLocation (yyVal, GetLocation (yyVals[-1+yyTop])); } -void case_622() -#line 4318 "cs-parser.jay" +void case_627() +#line 4432 "cs-parser.jay" { - valid_param_mod = 0; - start_anonymous (true, (ParametersCompiled) yyVals[-2+yyTop], true, GetLocation (yyVals[-5+yyTop])); + yyVal = new Binary (Binary.Operator.BitwiseOr, (Expression) yyVals[-2+yyTop], (Expression) yyVals[0+yyTop]); + lbag.AddLocation (yyVal, GetLocation (yyVals[-1+yyTop])); } -void case_623() -#line 4323 "cs-parser.jay" +void case_628() +#line 4437 "cs-parser.jay" { - yyVal = end_anonymous ((ParametersBlock) yyVals[0+yyTop]); - lbag.AddLocation (yyVal, GetLocation (yyVals[-7+yyTop]), GetLocation (yyVals[-6+yyTop]), GetLocation (yyVals[-3+yyTop]), GetLocation (yyVals[-2+yyTop])); + Error_SyntaxError (yyToken); + + yyVal = new Binary (Binary.Operator.BitwiseOr, (Expression) yyVals[-2+yyTop], null); + lbag.AddLocation (yyVal, GetLocation (yyVals[-1+yyTop])); } void case_630() -#line 4346 "cs-parser.jay" +#line 4448 "cs-parser.jay" { - yyVal = new RefValueExpr ((Expression) yyVals[-3+yyTop], (FullNamedExpression) yyVals[-1+yyTop], GetLocation (yyVals[-5+yyTop])); - lbag.AddLocation (yyVal, GetLocation (yyVals[-4+yyTop]), GetLocation (yyVals[-2+yyTop]), GetLocation (yyVals[0+yyTop])); + yyVal = new Binary (Binary.Operator.LogicalAnd, (Expression) yyVals[-2+yyTop], (Expression) yyVals[0+yyTop]); + lbag.AddLocation (yyVal, GetLocation (yyVals[-1+yyTop])); } void case_631() -#line 4351 "cs-parser.jay" +#line 4453 "cs-parser.jay" { - yyVal = new RefTypeExpr ((Expression) yyVals[-1+yyTop], GetLocation (yyVals[-3+yyTop])); - lbag.AddLocation (yyVal, GetLocation (yyVals[-2+yyTop]), GetLocation (yyVals[0+yyTop])); - } + Error_SyntaxError (yyToken); -void case_632() -#line 4356 "cs-parser.jay" -{ - yyVal = new MakeRefExpr ((Expression) yyVals[-1+yyTop], GetLocation (yyVals[-3+yyTop])); - lbag.AddLocation (yyVal, GetLocation (yyVals[-2+yyTop]), GetLocation (yyVals[0+yyTop])); + yyVal = new Binary (Binary.Operator.LogicalAnd, (Expression) yyVals[-2+yyTop], null); + lbag.AddLocation (yyVal, GetLocation (yyVals[-1+yyTop])); } -void case_636() -#line 4385 "cs-parser.jay" +void case_633() +#line 4464 "cs-parser.jay" { - Class c = new Class (current_container, (MemberName) yyVals[0+yyTop], (Modifiers) yyVals[-4+yyTop], (Attributes) yyVals[-5+yyTop]); - if (((c.ModFlags & Modifiers.STATIC) != 0) && lang_version == LanguageVersion.ISO_1) { - FeatureIsNotAvailable (c.Location, "static classes"); - } - - push_current_container (c, yyVals[-3+yyTop]); - lbag.AddMember (current_container, GetModifierLocations (), GetLocation (yyVals[-2+yyTop])); + yyVal = new Binary (Binary.Operator.LogicalOr, (Expression) yyVals[-2+yyTop], (Expression) yyVals[0+yyTop]); + lbag.AddLocation (yyVal, GetLocation (yyVals[-1+yyTop])); } -void case_637() -#line 4396 "cs-parser.jay" +void case_634() +#line 4469 "cs-parser.jay" { - lexer.ConstraintsParsing = false; + Error_SyntaxError (yyToken); - if (yyVals[0+yyTop] != null) - current_container.SetConstraints ((List) yyVals[0+yyTop]); + yyVal = new Binary (Binary.Operator.LogicalOr, (Expression) yyVals[-2+yyTop], null); + lbag.AddLocation (yyVal, GetLocation (yyVals[-1+yyTop])); + } - if (doc_support) { - current_container.PartialContainer.DocComment = Lexer.consume_doc_comment (); - Lexer.doc_state = XmlCommentState.Allowed; - } - - lexer.parsing_modifiers = true; +void case_636() +#line 4480 "cs-parser.jay" +{ + if (lang_version < LanguageVersion.ISO_2) + FeatureIsNotAvailable (GetLocation (yyVals[-1+yyTop]), "null coalescing operator"); + + yyVal = new Nullable.NullCoalescingOperator ((Expression) yyVals[-2+yyTop], (Expression) yyVals[0+yyTop]); + lbag.AddLocation (yyVal, GetLocation (yyVals[-1+yyTop])); } void case_638() -#line 4410 "cs-parser.jay" +#line 4492 "cs-parser.jay" { - --lexer.parsing_declaration; - if (doc_support) - Lexer.doc_state = XmlCommentState.Allowed; + yyVal = new Conditional (new BooleanExpression ((Expression) yyVals[-4+yyTop]), (Expression) yyVals[-2+yyTop], (Expression) yyVals[0+yyTop], GetLocation (yyVals[-3+yyTop])); + lbag.AddLocation (yyVal, GetLocation (yyVals[-1+yyTop])); } void case_639() -#line 4416 "cs-parser.jay" +#line 4497 "cs-parser.jay" { - if (yyVals[0+yyTop] == null) { - lbag.AppendToMember (current_container, GetLocation (yyVals[-4+yyTop]), GetLocation (yyVals[-2+yyTop])); - } else { - lbag.AppendToMember (current_container, GetLocation (yyVals[-4+yyTop]), GetLocation (yyVals[-2+yyTop]), GetLocation (yyVals[0+yyTop])); - } - yyVal = pop_current_class (); + Error_SyntaxError (yyToken); + + yyVal = new Conditional (new BooleanExpression ((Expression) yyVals[-3+yyTop]), (Expression) yyVals[-1+yyTop], null, GetLocation (yyVals[-2+yyTop])); } -void case_642() -#line 4435 "cs-parser.jay" +void case_640() +#line 4503 "cs-parser.jay" { - mod_locations = null; - yyVal = ModifierNone; - lexer.parsing_modifiers = false; + Error_SyntaxError (yyToken); + + yyVal = new Conditional (new BooleanExpression ((Expression) yyVals[-4+yyTop]), (Expression) yyVals[-2+yyTop], null, GetLocation (yyVals[-3+yyTop])); + lbag.AddLocation (yyVal, GetLocation (yyVals[-1+yyTop])); } -void case_645() -#line 4449 "cs-parser.jay" -{ - var m1 = (Modifiers) yyVals[-1+yyTop]; - var m2 = (Modifiers) yyVals[0+yyTop]; +void case_641() +#line 4510 "cs-parser.jay" +{ + Error_SyntaxError (Token.CLOSE_BRACE); - if ((m1 & m2) != 0) { - report.Error (1004, lexer.Location - ModifiersExtensions.Name (m2).Length, - "Duplicate `{0}' modifier", ModifiersExtensions.Name (m2)); - } else if ((m2 & Modifiers.AccessibilityMask) != 0 && (m1 & Modifiers.AccessibilityMask) != 0 && - ((m2 | m1 & Modifiers.AccessibilityMask) != (Modifiers.PROTECTED | Modifiers.INTERNAL))) { - report.Error (107, lexer.Location - ModifiersExtensions.Name (m2).Length, - "More than one protection modifier specified"); - } - - yyVal = m1 | m2; + yyVal = new Conditional (new BooleanExpression ((Expression) yyVals[-4+yyTop]), (Expression) yyVals[-2+yyTop], null, GetLocation (yyVals[-3+yyTop])); + lbag.AddLocation (yyVal, GetLocation (yyVals[-1+yyTop])); + lexer.putback ('}'); + } + +void case_642() +#line 4521 "cs-parser.jay" +{ + yyVal = new SimpleAssign ((Expression) yyVals[-2+yyTop], (Expression) yyVals[0+yyTop]); + lbag.AddLocation (yyVal, GetLocation (yyVals[-1+yyTop])); + } + +void case_643() +#line 4526 "cs-parser.jay" +{ + yyVal = new CompoundAssign (Binary.Operator.Multiply, (Expression) yyVals[-2+yyTop], (Expression) yyVals[0+yyTop]); + lbag.AddLocation (yyVal, GetLocation (yyVals[-1+yyTop])); + } + +void case_644() +#line 4531 "cs-parser.jay" +{ + yyVal = new CompoundAssign (Binary.Operator.Division, (Expression) yyVals[-2+yyTop], (Expression) yyVals[0+yyTop]); + lbag.AddLocation (yyVal, GetLocation (yyVals[-1+yyTop])); + } + +void case_645() +#line 4536 "cs-parser.jay" +{ + yyVal = new CompoundAssign (Binary.Operator.Modulus, (Expression) yyVals[-2+yyTop], (Expression) yyVals[0+yyTop]); + lbag.AddLocation (yyVal, GetLocation (yyVals[-1+yyTop])); } void case_646() -#line 4468 "cs-parser.jay" +#line 4541 "cs-parser.jay" { - yyVal = Modifiers.NEW; - StoreModifierLocation (yyVal, GetLocation (yyVals[0+yyTop])); - - if (current_container.Kind == MemberKind.Namespace) - report.Error (1530, GetLocation (yyVals[0+yyTop]), "Keyword `new' is not allowed on namespace elements"); + yyVal = new CompoundAssign (Binary.Operator.Addition, (Expression) yyVals[-2+yyTop], (Expression) yyVals[0+yyTop]); + lbag.AddLocation (yyVal, GetLocation (yyVals[-1+yyTop])); } void case_647() -#line 4476 "cs-parser.jay" +#line 4546 "cs-parser.jay" { - yyVal = Modifiers.PUBLIC; - StoreModifierLocation (yyVal, GetLocation (yyVals[0+yyTop])); + yyVal = new CompoundAssign (Binary.Operator.Subtraction, (Expression) yyVals[-2+yyTop], (Expression) yyVals[0+yyTop]); + lbag.AddLocation (yyVal, GetLocation (yyVals[-1+yyTop])); } void case_648() -#line 4481 "cs-parser.jay" +#line 4551 "cs-parser.jay" { - yyVal = Modifiers.PROTECTED; - StoreModifierLocation (yyVal, GetLocation (yyVals[0+yyTop])); + yyVal = new CompoundAssign (Binary.Operator.LeftShift, (Expression) yyVals[-2+yyTop], (Expression) yyVals[0+yyTop]); + lbag.AddLocation (yyVal, GetLocation (yyVals[-1+yyTop])); } void case_649() -#line 4486 "cs-parser.jay" +#line 4556 "cs-parser.jay" { - yyVal = Modifiers.INTERNAL; - StoreModifierLocation (yyVal, GetLocation (yyVals[0+yyTop])); + yyVal = new CompoundAssign (Binary.Operator.RightShift, (Expression) yyVals[-2+yyTop], (Expression) yyVals[0+yyTop]); + lbag.AddLocation (yyVal, GetLocation (yyVals[-1+yyTop])); } void case_650() -#line 4491 "cs-parser.jay" +#line 4561 "cs-parser.jay" { - yyVal = Modifiers.PRIVATE; - StoreModifierLocation (yyVal, GetLocation (yyVals[0+yyTop])); + yyVal = new CompoundAssign (Binary.Operator.BitwiseAnd, (Expression) yyVals[-2+yyTop], (Expression) yyVals[0+yyTop]); + lbag.AddLocation (yyVal, GetLocation (yyVals[-1+yyTop])); } void case_651() -#line 4496 "cs-parser.jay" +#line 4566 "cs-parser.jay" { - yyVal = Modifiers.ABSTRACT; - StoreModifierLocation (yyVal, GetLocation (yyVals[0+yyTop])); + yyVal = new CompoundAssign (Binary.Operator.BitwiseOr, (Expression) yyVals[-2+yyTop], (Expression) yyVals[0+yyTop]); + lbag.AddLocation (yyVal, GetLocation (yyVals[-1+yyTop])); } void case_652() -#line 4501 "cs-parser.jay" +#line 4571 "cs-parser.jay" { - yyVal = Modifiers.SEALED; - StoreModifierLocation (yyVal, GetLocation (yyVals[0+yyTop])); + yyVal = new CompoundAssign (Binary.Operator.ExclusiveOr, (Expression) yyVals[-2+yyTop], (Expression) yyVals[0+yyTop]); + lbag.AddLocation (yyVal, GetLocation (yyVals[-1+yyTop])); } void case_653() -#line 4506 "cs-parser.jay" +#line 4579 "cs-parser.jay" { - yyVal = Modifiers.STATIC; - StoreModifierLocation (yyVal, GetLocation (yyVals[0+yyTop])); + var pars = new List (4); + pars.Add ((Parameter) yyVals[0+yyTop]); + parameterListCommas.Clear (); + yyVal = pars; } void case_654() -#line 4511 "cs-parser.jay" +#line 4586 "cs-parser.jay" { - yyVal = Modifiers.READONLY; - StoreModifierLocation (yyVal, GetLocation (yyVals[0+yyTop])); + var pars = (List) yyVals[-2+yyTop]; + Parameter p = (Parameter)yyVals[0+yyTop]; + if (pars[0].GetType () != p.GetType ()) { + report.Error (748, p.Location, "All lambda parameters must be typed either explicitly or implicitly"); + } + + pars.Add (p); + parameterListCommas.Add (GetLocation (yyVals[-1+yyTop])); + + yyVal = pars; } void case_655() -#line 4516 "cs-parser.jay" +#line 4602 "cs-parser.jay" { - yyVal = Modifiers.VIRTUAL; - StoreModifierLocation (yyVal, GetLocation (yyVals[0+yyTop])); + var lt = (LocatedToken) yyVals[0+yyTop]; + + yyVal = new Parameter ((FullNamedExpression) yyVals[-1+yyTop], lt.Value, (Parameter.Modifier) yyVals[-2+yyTop], null, lt.Location); } void case_656() -#line 4521 "cs-parser.jay" +#line 4608 "cs-parser.jay" { - yyVal = Modifiers.OVERRIDE; - StoreModifierLocation (yyVal, GetLocation (yyVals[0+yyTop])); + var lt = (LocatedToken) yyVals[0+yyTop]; + + yyVal = new Parameter ((FullNamedExpression) yyVals[-1+yyTop], lt.Value, Parameter.Modifier.NONE, null, lt.Location); } void case_657() -#line 4526 "cs-parser.jay" +#line 4614 "cs-parser.jay" { - yyVal = Modifiers.EXTERN; - StoreModifierLocation (yyVal, GetLocation (yyVals[0+yyTop])); + var lt = (LocatedToken) yyVals[0+yyTop]; + yyVal = new ImplicitLambdaParameter (lt.Value, lt.Location); } void case_658() -#line 4531 "cs-parser.jay" -{ - yyVal = Modifiers.VOLATILE; - StoreModifierLocation (yyVal, GetLocation (yyVals[0+yyTop])); - } - -void case_659() -#line 4536 "cs-parser.jay" +#line 4619 "cs-parser.jay" { - yyVal = Modifiers.UNSAFE; - StoreModifierLocation (yyVal, GetLocation (yyVals[0+yyTop])); - if (!settings.Unsafe) - Error_UnsafeCodeNotAllowed (GetLocation (yyVals[0+yyTop])); + var lt = (LocatedToken) Error_AwaitAsIdentifier (yyVals[0+yyTop]); + yyVal = new ImplicitLambdaParameter (lt.Value, lt.Location); } void case_660() -#line 4543 "cs-parser.jay" -{ - yyVal = Modifiers.ASYNC; - StoreModifierLocation (yyVal, GetLocation (yyVals[0+yyTop])); +#line 4627 "cs-parser.jay" +{ + var pars_list = (List) yyVals[0+yyTop]; + yyVal = new ParametersCompiled (pars_list.ToArray ()); + lbag.AddLocation (yyVal, parameterListCommas); } void case_662() -#line 4552 "cs-parser.jay" +#line 4639 "cs-parser.jay" { - current_type.AddBasesForPart ((List) yyVals[0+yyTop]); - lbag.AppendToMember (current_type, GetLocation (yyVals[-1+yyTop])); - } + Block b = end_block (Location.Null); + b.IsCompilerGenerated = true; + b.AddStatement (new ContextualReturn ((Expression) yyVals[0+yyTop])); + yyVal = b; + } -void case_663() -#line 4557 "cs-parser.jay" +void case_664() +#line 4647 "cs-parser.jay" { - Error_SyntaxError (yyToken); + /* Handles only cases like foo = x.FirstOrDefault (l => );*/ + /* where we must restore current_variable*/ + Block b = end_block (Location.Null); + b.IsCompilerGenerated = true; - current_type.AddBasesForPart ((List) yyVals[-1+yyTop]); + Error_SyntaxError (yyToken); + yyVal = null; } void case_666() -#line 4574 "cs-parser.jay" +#line 4661 "cs-parser.jay" { - var constraints = new List (1); - constraints.Add ((Constraints) yyVals[0+yyTop]); - yyVal = constraints; + Error_SyntaxError (yyToken); + yyVal = null; } void case_667() -#line 4580 "cs-parser.jay" +#line 4669 "cs-parser.jay" { - var constraints = (List) yyVals[-1+yyTop]; - Constraints new_constraint = (Constraints)yyVals[0+yyTop]; - - foreach (Constraints c in constraints) { - if (new_constraint.TypeParameter.Value == c.TypeParameter.Value) { - report.Error (409, new_constraint.Location, - "A constraint clause has already been specified for type parameter `{0}'", - new_constraint.TypeParameter.Value); - } - } - - constraints.Add (new_constraint); - yyVal = constraints; + var lt = (LocatedToken) yyVals[-1+yyTop]; + Parameter p = new ImplicitLambdaParameter (lt.Value, lt.Location); + start_anonymous (true, new ParametersCompiled (p), false, lt.Location); } void case_668() -#line 4599 "cs-parser.jay" +#line 4675 "cs-parser.jay" { - var lt = (Tokenizer.LocatedToken) yyVals[-2+yyTop]; - yyVal = new Constraints (new SimpleMemberName (lt.Value, lt.Location), (List) yyVals[0+yyTop], GetLocation (yyVals[-3+yyTop])); - lbag.AddLocation (yyVal, GetLocation (yyVals[-1+yyTop])); + yyVal = end_anonymous ((ParametersBlock) yyVals[0+yyTop]); + lbag.AddLocation (yyVal, GetLocation (yyVals[-2+yyTop])); } void case_669() -#line 4605 "cs-parser.jay" +#line 4680 "cs-parser.jay" { - Error_SyntaxError (yyToken); - - var lt = (Tokenizer.LocatedToken) yyVals[-1+yyTop]; - yyVal = new Constraints (new SimpleMemberName (lt.Value, lt.Location), null, GetLocation (yyVals[-2+yyTop])); + var lt = (LocatedToken) Error_AwaitAsIdentifier (yyVals[-1+yyTop]); + Parameter p = new ImplicitLambdaParameter (lt.Value, lt.Location); + start_anonymous (true, new ParametersCompiled (p), false, lt.Location); } void case_670() -#line 4615 "cs-parser.jay" +#line 4686 "cs-parser.jay" { - var constraints = new List (1); - constraints.Add ((FullNamedExpression) yyVals[0+yyTop]); - yyVal = constraints; + yyVal = end_anonymous ((ParametersBlock) yyVals[0+yyTop]); + lbag.AddLocation (yyVal, GetLocation (yyVals[-2+yyTop])); } void case_671() -#line 4621 "cs-parser.jay" +#line 4691 "cs-parser.jay" { - var constraints = (List) yyVals[-2+yyTop]; - var prev = constraints [constraints.Count - 1] as SpecialContraintExpr; - if (prev != null && (prev.Constraint & SpecialConstraint.Constructor) != 0) { - report.Error (401, GetLocation (yyVals[-1+yyTop]), "The `new()' constraint must be the last constraint specified"); - } - - prev = yyVals[0+yyTop] as SpecialContraintExpr; - if (prev != null) { - if ((prev.Constraint & (SpecialConstraint.Class | SpecialConstraint.Struct)) != 0) { - report.Error (449, prev.Location, "The `class' or `struct' constraint must be the first constraint specified"); - } else { - prev = constraints [0] as SpecialContraintExpr; - if (prev != null && (prev.Constraint & SpecialConstraint.Struct) != 0) { - report.Error (451, GetLocation (yyVals[0+yyTop]), "The `new()' constraint cannot be used with the `struct' constraint"); - } - } - } - - constraints.Add ((FullNamedExpression) yyVals[0+yyTop]); - lbag.AppendTo (constraints, GetLocation (yyVals[-1+yyTop])); - yyVal = constraints; + var lt = (LocatedToken) yyVals[-1+yyTop]; + Parameter p = new ImplicitLambdaParameter (lt.Value, lt.Location); + start_anonymous (true, new ParametersCompiled (p), true, lt.Location); } void case_672() -#line 4648 "cs-parser.jay" +#line 4697 "cs-parser.jay" { - if (yyVals[0+yyTop] is ComposedCast) - report.Error (706, GetLocation (yyVals[0+yyTop]), "Invalid constraint type `{0}'", ((ComposedCast)yyVals[0+yyTop]).GetSignatureForError ()); - - yyVal = yyVals[0+yyTop]; + yyVal = end_anonymous ((ParametersBlock) yyVals[0+yyTop]); + lbag.AddLocation (yyVal, GetLocation (yyVals[-4+yyTop]), GetLocation (yyVals[-2+yyTop])); } -void case_673() -#line 4655 "cs-parser.jay" +void case_674() +#line 4706 "cs-parser.jay" { - yyVal = new SpecialContraintExpr (SpecialConstraint.Constructor, GetLocation (yyVals[-2+yyTop])); - lbag.AddLocation (yyVal, GetLocation (yyVals[-1+yyTop]), GetLocation (yyVals[0+yyTop])); + valid_param_mod = 0; + start_anonymous (true, (ParametersCompiled) yyVals[-2+yyTop], false, GetLocation (yyVals[-4+yyTop])); } -void case_677() -#line 4675 "cs-parser.jay" +void case_675() +#line 4711 "cs-parser.jay" { - if (lang_version <= LanguageVersion.V_3) - FeatureIsNotAvailable (lexer.Location, "generic type variance"); - - yyVal = yyVals[0+yyTop]; + yyVal = end_anonymous ((ParametersBlock) yyVals[0+yyTop]); + lbag.AddLocation (yyVal, GetLocation (yyVals[-6+yyTop]), GetLocation (yyVals[-3+yyTop]), GetLocation (yyVals[-2+yyTop])); } -void case_678() -#line 4685 "cs-parser.jay" +void case_677() +#line 4720 "cs-parser.jay" { - yyVal = Variance.Covariant; - savedLocation = GetLocation (yyVals[0+yyTop]); + valid_param_mod = 0; + start_anonymous (true, (ParametersCompiled) yyVals[-2+yyTop], true, GetLocation (yyVals[-5+yyTop])); } -void case_679() -#line 4690 "cs-parser.jay" +void case_678() +#line 4725 "cs-parser.jay" { - yyVal = Variance.Contravariant; - savedLocation = GetLocation (yyVals[0+yyTop]); + yyVal = end_anonymous ((ParametersBlock) yyVals[0+yyTop]); + lbag.AddLocation (yyVal, GetLocation (yyVals[-7+yyTop]), GetLocation (yyVals[-6+yyTop]), GetLocation (yyVals[-3+yyTop]), GetLocation (yyVals[-2+yyTop])); } -void case_680() -#line 4711 "cs-parser.jay" +void case_685() +#line 4748 "cs-parser.jay" { - ++lexer.parsing_block; - start_block (GetLocation (yyVals[0+yyTop])); + yyVal = new RefValueExpr ((Expression) yyVals[-3+yyTop], (FullNamedExpression) yyVals[-1+yyTop], GetLocation (yyVals[-5+yyTop])); + lbag.AddLocation (yyVal, GetLocation (yyVals[-4+yyTop]), GetLocation (yyVals[-2+yyTop]), GetLocation (yyVals[0+yyTop])); } -void case_682() -#line 4723 "cs-parser.jay" +void case_686() +#line 4753 "cs-parser.jay" { - --lexer.parsing_block; - yyVal = end_block (GetLocation (yyVals[0+yyTop])); + yyVal = new RefTypeExpr ((Expression) yyVals[-1+yyTop], GetLocation (yyVals[-3+yyTop])); + lbag.AddLocation (yyVal, GetLocation (yyVals[-2+yyTop]), GetLocation (yyVals[0+yyTop])); } -void case_683() -#line 4728 "cs-parser.jay" +void case_687() +#line 4758 "cs-parser.jay" { - --lexer.parsing_block; - yyVal = end_block (lexer.Location); + yyVal = new MakeRefExpr ((Expression) yyVals[-1+yyTop], GetLocation (yyVals[-3+yyTop])); + lbag.AddLocation (yyVal, GetLocation (yyVals[-2+yyTop]), GetLocation (yyVals[0+yyTop])); } -void case_684() -#line 4737 "cs-parser.jay" +void case_692() +#line 4785 "cs-parser.jay" { - ++lexer.parsing_block; - current_block.StartLocation = GetLocation (yyVals[0+yyTop]); + yyVal = yyVals[-1+yyTop]; + + /* Cannot use opt_formal_parameter_list because it can be shared instance for empty parameters*/ + lbag.AppendToMember (current_container, GetLocation (yyVals[-2+yyTop]), GetLocation (yyVals[0+yyTop])); } -void case_685() -#line 4742 "cs-parser.jay" +void case_697() +#line 4811 "cs-parser.jay" { + lbag.AppendToMember (current_container, GetLocation (yyVals[-3+yyTop]), GetLocation (yyVals[0+yyTop])); + ((Class)current_type).PrimaryConstructorBaseArguments = (Arguments) yyVals[-1+yyTop]; --lexer.parsing_block; - yyVal = end_block (GetLocation (yyVals[0+yyTop])); - } -void case_686() -#line 4746 "cs-parser.jay" -{ - report.Error (1525, GetLocation (yyVals[0+yyTop]), "Unexpected symbol '}', expected '{'"); - lexer.putback ('}'); - yyVal = end_block (GetLocation (yyVals[0+yyTop])); + yyVal = yyVals[-5+yyTop]; } -void case_694() -#line 4775 "cs-parser.jay" +void case_699() +#line 4831 "cs-parser.jay" { - Error_SyntaxError (yyToken); - var lt =(Tokenizer.LocatedToken) yyVals[-1+yyTop]; - var sn = new SimpleName (lt.Value, lt.Location); - current_block.AddStatement(new StatementErrorExpression (sn)); - yyVal = null; - } + lexer.ConstraintsParsing = true; -void case_695() -#line 4784 "cs-parser.jay" -{ - Error_SyntaxError (yyToken); - yyVal = null; + Class c = new Class (current_container, (MemberName) yyVals[0+yyTop], (Modifiers) yyVals[-4+yyTop], (Attributes) yyVals[-5+yyTop]); + if (((c.ModFlags & Modifiers.STATIC) != 0) && lang_version == LanguageVersion.ISO_1) { + FeatureIsNotAvailable (c.Location, "static classes"); + } + + push_current_container (c, yyVals[-3+yyTop]); + lbag.AddMember (current_container, GetModifierLocations (), GetLocation (yyVals[-2+yyTop])); + valid_param_mod = ParameterModifierType.PrimaryConstructor; } -void case_728() -#line 4848 "cs-parser.jay" +void case_700() +#line 4845 "cs-parser.jay" { - report.Error (1023, GetLocation (yyVals[0+yyTop]), "An embedded statement may not be a declaration or labeled statement"); - yyVal = null; - } + valid_param_mod = 0; + lexer.ConstraintsParsing = false; -void case_729() -#line 4853 "cs-parser.jay" -{ - report.Error (1023, GetLocation (yyVals[0+yyTop]), "An embedded statement may not be a declaration or labeled statement"); - yyVal = null; - } + if (yyVals[-1+yyTop] != null) + current_type.PrimaryConstructorParameters = (ParametersCompiled) yyVals[-1+yyTop]; -void case_730() -#line 4858 "cs-parser.jay" -{ - Error_SyntaxError (yyToken); - yyVal = new EmptyStatement (GetLocation (yyVals[0+yyTop])); - } + if (yyVals[0+yyTop] != null) + current_container.SetConstraints ((List) yyVals[0+yyTop]); -void case_731() -#line 4866 "cs-parser.jay" -{ - /* Uses lexer.Location because semicolon location is not kept in quick mode*/ - yyVal = new EmptyStatement (lexer.Location); + if (doc_support) { + current_container.PartialContainer.DocComment = Lexer.consume_doc_comment (); + Lexer.doc_state = XmlCommentState.Allowed; + } + + lexer.parsing_modifiers = true; } -void case_732() -#line 4874 "cs-parser.jay" +void case_701() +#line 4863 "cs-parser.jay" { - var lt = (Tokenizer.LocatedToken) yyVals[-1+yyTop]; - LabeledStatement labeled = new LabeledStatement (lt.Value, current_block, lt.Location); - lbag.AddLocation (labeled, GetLocation (yyVals[0+yyTop])); - current_block.AddLabel (labeled); - current_block.AddStatement (labeled); + --lexer.parsing_declaration; + if (doc_support) + Lexer.doc_state = XmlCommentState.Allowed; } -void case_735() -#line 4887 "cs-parser.jay" +void case_702() +#line 4869 "cs-parser.jay" { - if (yyVals[-1+yyTop] is VarExpr) - yyVals[-1+yyTop] = new SimpleName ("var", ((VarExpr) yyVals[-1+yyTop]).Location); - - yyVal = new ComposedCast ((FullNamedExpression) yyVals[-1+yyTop], (ComposedTypeSpecifier) yyVals[0+yyTop]); - } - -void case_736() -#line 4903 "cs-parser.jay" -{ - /* Ok, the above "primary_expression" is there to get rid of*/ - /* both reduce/reduce and shift/reduces in the grammar, it should*/ - /* really just be "type_name". If you use type_name, a reduce/reduce*/ - /* creeps up. If you use namespace_or_type_name (which is all we need*/ - /* really) two shift/reduces appear.*/ - /* */ - - /* So the super-trick is that primary_expression*/ - /* can only be either a SimpleName or a MemberAccess. */ - /* The MemberAccess case arises when you have a fully qualified type-name like :*/ - /* Foo.Bar.Blah i;*/ - /* SimpleName is when you have*/ - /* Blah i;*/ - - Expression expr = (Expression) yyVals[-1+yyTop]; if (yyVals[0+yyTop] == null) { - SimpleName sn = expr as SimpleName; - if (sn != null && sn.Name == "var") - yyVal = new VarExpr (sn.Location); - else - yyVal = yyVals[-1+yyTop]; - } else if (expr is ATypeNameExpression) { - yyVal = new ComposedCast ((ATypeNameExpression)expr, (ComposedTypeSpecifier) yyVals[0+yyTop]); + lbag.AppendToMember (current_container, GetLocation (yyVals[-4+yyTop]), GetLocation (yyVals[-2+yyTop])); } else { - Error_ExpectingTypeName (expr); - yyVal = null; + lbag.AppendToMember (current_container, GetLocation (yyVals[-4+yyTop]), GetLocation (yyVals[-2+yyTop]), GetLocation (yyVals[0+yyTop])); } + yyVal = pop_current_class (); } -void case_737() -#line 4933 "cs-parser.jay" +void case_705() +#line 4888 "cs-parser.jay" { - ATypeNameExpression expr = yyVals[-1+yyTop] as ATypeNameExpression; + mod_locations = null; + yyVal = ModifierNone; + lexer.parsing_modifiers = false; + } - if (expr != null) { - yyVal = new ComposedCast (expr, (ComposedTypeSpecifier) yyVals[0+yyTop]); - } else { - Error_ExpectingTypeName ((Expression)yyVals[-1+yyTop]); - yyVal = expr; +void case_708() +#line 4902 "cs-parser.jay" +{ + var m1 = (Modifiers) yyVals[-1+yyTop]; + var m2 = (Modifiers) yyVals[0+yyTop]; + + if ((m1 & m2) != 0) { + report.Error (1004, lexer.Location - ModifiersExtensions.Name (m2).Length, + "Duplicate `{0}' modifier", ModifiersExtensions.Name (m2)); + } else if ((m2 & Modifiers.AccessibilityMask) != 0 && (m1 & Modifiers.AccessibilityMask) != 0 && + ((m2 | m1 & Modifiers.AccessibilityMask) != (Modifiers.PROTECTED | Modifiers.INTERNAL))) { + report.Error (107, lexer.Location - ModifiersExtensions.Name (m2).Length, + "More than one protection modifier specified"); } + + yyVal = m1 | m2; } -void case_738() -#line 4944 "cs-parser.jay" +void case_709() +#line 4921 "cs-parser.jay" { - if (yyVals[0+yyTop] == null) - yyVal = yyVals[-1+yyTop]; - else - yyVal = new ComposedCast ((FullNamedExpression) yyVals[-1+yyTop], (ComposedTypeSpecifier) yyVals[0+yyTop]); + yyVal = Modifiers.NEW; + StoreModifierLocation (yyVal, GetLocation (yyVals[0+yyTop])); + + if (current_container.Kind == MemberKind.Namespace) + report.Error (1530, GetLocation (yyVals[0+yyTop]), "Keyword `new' is not allowed on namespace elements"); } -void case_741() -#line 4959 "cs-parser.jay" +void case_710() +#line 4929 "cs-parser.jay" { - Expression.Error_VoidInvalidInTheContext (GetLocation (yyVals[0+yyTop]), report); - yyVal = new TypeExpression (compiler.BuiltinTypes.Void, GetLocation (yyVals[0+yyTop])); + yyVal = Modifiers.PUBLIC; + StoreModifierLocation (yyVal, GetLocation (yyVals[0+yyTop])); } -void case_743() -#line 4968 "cs-parser.jay" +void case_711() +#line 4934 "cs-parser.jay" { - ((ComposedTypeSpecifier) yyVals[-1+yyTop]).Next = (ComposedTypeSpecifier) yyVals[0+yyTop]; - yyVal = yyVals[-1+yyTop]; + yyVal = Modifiers.PROTECTED; + StoreModifierLocation (yyVal, GetLocation (yyVals[0+yyTop])); } -void case_746() -#line 4984 "cs-parser.jay" +void case_712() +#line 4939 "cs-parser.jay" { - if (async_block) { - report.Error (4003, GetLocation (yyVals[0+yyTop]), "`await' cannot be used as an identifier within an async method or lambda expression"); - yyVal = new Tokenizer.LocatedToken ("await", GetLocation (yyVals[0+yyTop])); - } + yyVal = Modifiers.INTERNAL; + StoreModifierLocation (yyVal, GetLocation (yyVals[0+yyTop])); } -void case_747() -#line 4994 "cs-parser.jay" +void case_713() +#line 4944 "cs-parser.jay" { - var lt = (Tokenizer.LocatedToken) yyVals[0+yyTop]; - var li = new LocalVariable (current_block, lt.Value, lt.Location); - current_block.AddLocalName (li); - current_variable = new BlockVariableDeclaration ((FullNamedExpression) yyVals[-1+yyTop], li); + yyVal = Modifiers.PRIVATE; + StoreModifierLocation (yyVal, GetLocation (yyVals[0+yyTop])); } -void case_748() -#line 5001 "cs-parser.jay" +void case_714() +#line 4949 "cs-parser.jay" { - yyVal = current_variable; - current_variable = null; - lbag.AppendTo (yyVal, GetLocation (yyVals[0+yyTop])); + yyVal = Modifiers.ABSTRACT; + StoreModifierLocation (yyVal, GetLocation (yyVals[0+yyTop])); } -void case_749() -#line 5007 "cs-parser.jay" +void case_715() +#line 4954 "cs-parser.jay" { - var lt = (Tokenizer.LocatedToken) yyVals[0+yyTop]; - var li = new LocalVariable (current_block, lt.Value, LocalVariable.Flags.Constant, lt.Location); - current_block.AddLocalName (li); - current_variable = new BlockConstantDeclaration ((FullNamedExpression) yyVals[-1+yyTop], li); + yyVal = Modifiers.SEALED; + StoreModifierLocation (yyVal, GetLocation (yyVals[0+yyTop])); } -void case_750() -#line 5014 "cs-parser.jay" +void case_716() +#line 4959 "cs-parser.jay" { - if (current_variable.Initializer != null) { - lbag.AddLocation (current_variable, GetLocation (yyVals[-6+yyTop]), savedLocation, GetLocation (yyVals[0+yyTop])); - } else { - lbag.AddLocation (current_variable, GetLocation (yyVals[-6+yyTop]), GetLocation (yyVals[0+yyTop])); - } - yyVal = current_variable;; - current_variable = null; + yyVal = Modifiers.STATIC; + StoreModifierLocation (yyVal, GetLocation (yyVals[0+yyTop])); } -void case_752() -#line 5027 "cs-parser.jay" +void case_717() +#line 4964 "cs-parser.jay" { - /* Redundant, but wont regress*/ - report.Error (1525, lexer.Location, "Unexpected symbol }"); - lexer.putback ('}'); - yyVal = yyVals[0+yyTop]; + yyVal = Modifiers.READONLY; + StoreModifierLocation (yyVal, GetLocation (yyVals[0+yyTop])); } -void case_754() -#line 5038 "cs-parser.jay" +void case_718() +#line 4969 "cs-parser.jay" { - current_variable.Initializer = (Expression) yyVals[0+yyTop]; - lbag.AppendTo (current_variable, GetLocation (yyVals[-1+yyTop])); + yyVal = Modifiers.VIRTUAL; + StoreModifierLocation (yyVal, GetLocation (yyVals[0+yyTop])); } -void case_755() -#line 5043 "cs-parser.jay" +void case_719() +#line 4974 "cs-parser.jay" { - if (yyToken == Token.OPEN_BRACKET_EXPR) { - report.Error (650, lexer.Location, - "Syntax error, bad array declarator. To declare a managed array the rank specifier precedes the variable's identifier. To declare a fixed size buffer field, use the fixed keyword before the field type"); - current_variable.Initializer = ErrorExpression.Create (650, lexer.Location, - "Syntax error, bad array declarator. To declare a managed array the rank specifier precedes the variable's identifier. To declare a fixed size buffer field, use the fixed keyword before the field type"); - } else { - Error_SyntaxError (yyToken); - current_variable.Initializer = ErrorExpression.Create (0, lexer.Location, - "Syntax error"); - } - lbag.AppendTo (current_variable, GetLocation (yyVals[-1+yyTop])); + yyVal = Modifiers.OVERRIDE; + StoreModifierLocation (yyVal, GetLocation (yyVals[0+yyTop])); } -void case_756() -#line 5057 "cs-parser.jay" +void case_720() +#line 4979 "cs-parser.jay" { - if (yyToken == Token.OPEN_BRACKET_EXPR) { - report.Error (650, lexer.Location, - "Syntax error, bad array declarator. To declare a managed array the rank specifier precedes the variable's identifier. To declare a fixed size buffer field, use the fixed keyword before the field type"); - } else { - Error_SyntaxError (yyToken); - } + yyVal = Modifiers.EXTERN; + StoreModifierLocation (yyVal, GetLocation (yyVals[0+yyTop])); } -void case_760() -#line 5075 "cs-parser.jay" +void case_721() +#line 4984 "cs-parser.jay" { - foreach (var d in current_variable.Declarators) { - if (d.Initializer == null) - Error_MissingInitializer (d.Variable.Location); - } + yyVal = Modifiers.VOLATILE; + StoreModifierLocation (yyVal, GetLocation (yyVals[0+yyTop])); } -void case_763() -#line 5090 "cs-parser.jay" +void case_722() +#line 4989 "cs-parser.jay" { - var lt = (Tokenizer.LocatedToken) yyVals[0+yyTop]; - var li = new LocalVariable (current_variable.Variable, lt.Value, lt.Location); - var d = new BlockVariableDeclaration.Declarator (li, null); - current_variable.AddDeclarator (d); - current_block.AddLocalName (li); - lbag.AddLocation (d, GetLocation (yyVals[-1+yyTop])); + yyVal = Modifiers.UNSAFE; + StoreModifierLocation (yyVal, GetLocation (yyVals[0+yyTop])); + if (!settings.Unsafe) + Error_UnsafeCodeNotAllowed (GetLocation (yyVals[0+yyTop])); } -void case_764() -#line 5099 "cs-parser.jay" +void case_723() +#line 4996 "cs-parser.jay" { - var lt = (Tokenizer.LocatedToken) yyVals[-2+yyTop]; - var li = new LocalVariable (current_variable.Variable, lt.Value, lt.Location); - var d = new BlockVariableDeclaration.Declarator (li, (Expression) yyVals[0+yyTop]); - current_variable.AddDeclarator (d); - current_block.AddLocalName (li); - lbag.AddLocation (d, GetLocation (yyVals[-3+yyTop]), GetLocation (yyVals[-1+yyTop])); + yyVal = Modifiers.ASYNC; + StoreModifierLocation (yyVal, GetLocation (yyVals[0+yyTop])); } -void case_766() -#line 5115 "cs-parser.jay" +void case_726() +#line 5009 "cs-parser.jay" { - savedLocation = GetLocation (yyVals[-1+yyTop]); - current_variable.Initializer = (Expression) yyVals[0+yyTop]; - } + current_type.SetBaseTypes ((List) yyVals[0+yyTop]); + lbag.AppendToMember (current_type, GetLocation (yyVals[-1+yyTop])); + } -void case_771() -#line 5133 "cs-parser.jay" +void case_727() +#line 5014 "cs-parser.jay" { - var lt = (Tokenizer.LocatedToken) yyVals[-2+yyTop]; - var li = new LocalVariable (current_block, lt.Value, LocalVariable.Flags.Constant, lt.Location); - var d = new BlockVariableDeclaration.Declarator (li, (Expression) yyVals[0+yyTop]); - current_variable.AddDeclarator (d); - current_block.AddLocalName (li); - lbag.AddLocation (d, GetLocation (yyVals[-3+yyTop]), GetLocation (yyVals[-1+yyTop])); + Error_SyntaxError (yyToken); + + current_type.SetBaseTypes ((List) yyVals[-1+yyTop]); } -void case_773() -#line 5146 "cs-parser.jay" +void case_730() +#line 5031 "cs-parser.jay" { - yyVal = new StackAlloc ((Expression) yyVals[-3+yyTop], (Expression) yyVals[-1+yyTop], GetLocation (yyVals[-4+yyTop])); - lbag.AddLocation (yyVal, GetLocation (yyVals[-2+yyTop]), GetLocation (yyVals[0+yyTop])); + var constraints = new List (1); + constraints.Add ((Constraints) yyVals[0+yyTop]); + yyVal = constraints; } -void case_774() -#line 5151 "cs-parser.jay" +void case_731() +#line 5037 "cs-parser.jay" { - report.Error (1575, GetLocation (yyVals[-1+yyTop]), "A stackalloc expression requires [] after type"); - yyVal = new StackAlloc ((Expression) yyVals[0+yyTop], null, GetLocation (yyVals[-1+yyTop])); + var constraints = (List) yyVals[-1+yyTop]; + Constraints new_constraint = (Constraints)yyVals[0+yyTop]; + + foreach (Constraints c in constraints) { + if (new_constraint.TypeParameter.Value == c.TypeParameter.Value) { + report.Error (409, new_constraint.Location, + "A constraint clause has already been specified for type parameter `{0}'", + new_constraint.TypeParameter.Value); + } + } + + constraints.Add (new_constraint); + yyVal = constraints; } -void case_775() -#line 5159 "cs-parser.jay" +void case_732() +#line 5056 "cs-parser.jay" { - yyVal = yyVals[-1+yyTop]; - lbag.AddStatement (yyVal, GetLocation (yyVals[0+yyTop])); + var lt = (LocatedToken) yyVals[-2+yyTop]; + yyVal = new Constraints (new SimpleMemberName (lt.Value, lt.Location), (List) yyVals[0+yyTop], GetLocation (yyVals[-3+yyTop])); + lbag.AddLocation (yyVal, GetLocation (yyVals[-1+yyTop])); } -void case_777() -#line 5165 "cs-parser.jay" +void case_733() +#line 5062 "cs-parser.jay" { - yyVal = yyVals[-1+yyTop]; - report.Error (1002, GetLocation (yyVals[0+yyTop]), "; expected"); - lexer.putback ('}'); + Error_SyntaxError (yyToken); + + var lt = (LocatedToken) yyVals[-1+yyTop]; + yyVal = new Constraints (new SimpleMemberName (lt.Value, lt.Location), null, GetLocation (yyVals[-2+yyTop])); } -void case_780() -#line 5183 "cs-parser.jay" +void case_734() +#line 5072 "cs-parser.jay" { - ExpressionStatement s = yyVals[0+yyTop] as ExpressionStatement; - if (s == null) { - Expression.Error_InvalidExpressionStatement (report, GetLocation (yyVals[0+yyTop])); - yyVal = new StatementErrorExpression (yyVals[0+yyTop] as Expression); - } else { - yyVal = new StatementExpression (s); - } + var constraints = new List (1); + constraints.Add ((FullNamedExpression) yyVals[0+yyTop]); + yyVal = constraints; } -void case_781() -#line 5196 "cs-parser.jay" +void case_735() +#line 5078 "cs-parser.jay" { - Expression expr = (Expression) yyVals[0+yyTop]; - ExpressionStatement s; + var constraints = (List) yyVals[-2+yyTop]; + var prev = constraints [constraints.Count - 1] as SpecialContraintExpr; + if (prev != null && (prev.Constraint & SpecialConstraint.Constructor) != 0) { + report.Error (401, GetLocation (yyVals[-1+yyTop]), "The `new()' constraint must be the last constraint specified"); + } + + prev = yyVals[0+yyTop] as SpecialContraintExpr; + if (prev != null) { + if ((prev.Constraint & (SpecialConstraint.Class | SpecialConstraint.Struct)) != 0) { + report.Error (449, prev.Location, "The `class' or `struct' constraint must be the first constraint specified"); + } else { + prev = constraints [0] as SpecialContraintExpr; + if (prev != null && (prev.Constraint & SpecialConstraint.Struct) != 0) { + report.Error (451, GetLocation (yyVals[0+yyTop]), "The `new()' constraint cannot be used with the `struct' constraint"); + } + } + } - s = new OptionalAssign (new SimpleName ("$retval", lexer.Location), expr, lexer.Location); - yyVal = new StatementExpression (s); + constraints.Add ((FullNamedExpression) yyVals[0+yyTop]); + lbag.AddLocation (constraints, GetLocation (yyVals[-1+yyTop])); + yyVal = constraints; } -void case_782() -#line 5204 "cs-parser.jay" +void case_736() +#line 5105 "cs-parser.jay" { - Error_SyntaxError (yyToken); - yyVal = new EmptyStatement (GetLocation (yyVals[0+yyTop])); + if (yyVals[0+yyTop] is ComposedCast) + report.Error (706, GetLocation (yyVals[0+yyTop]), "Invalid constraint type `{0}'", ((ComposedCast)yyVals[0+yyTop]).GetSignatureForError ()); + + yyVal = yyVals[0+yyTop]; } -void case_785() -#line 5218 "cs-parser.jay" -{ - if (yyVals[0+yyTop] is EmptyStatement) - Warning_EmptyStatement (GetLocation (yyVals[0+yyTop])); - - yyVal = new If ((BooleanExpression) yyVals[-2+yyTop], (Statement) yyVals[0+yyTop], GetLocation (yyVals[-4+yyTop])); - lbag.AddStatement (yyVal, GetLocation (yyVals[-3+yyTop]), GetLocation (yyVals[-1+yyTop])); +void case_737() +#line 5112 "cs-parser.jay" +{ + yyVal = new SpecialContraintExpr (SpecialConstraint.Constructor, GetLocation (yyVals[-2+yyTop])); + lbag.AddLocation (yyVal, GetLocation (yyVals[-1+yyTop]), GetLocation (yyVals[0+yyTop])); } -void case_786() -#line 5227 "cs-parser.jay" +void case_741() +#line 5132 "cs-parser.jay" { - yyVal = new If ((BooleanExpression) yyVals[-4+yyTop], (Statement) yyVals[-2+yyTop], (Statement) yyVals[0+yyTop], GetLocation (yyVals[-6+yyTop])); - lbag.AddStatement (yyVal, GetLocation (yyVals[-5+yyTop]), GetLocation (yyVals[-3+yyTop]), GetLocation (yyVals[-1+yyTop])); + if (lang_version <= LanguageVersion.V_3) + FeatureIsNotAvailable (lexer.Location, "generic type variance"); - if (yyVals[-2+yyTop] is EmptyStatement) - Warning_EmptyStatement (GetLocation (yyVals[-2+yyTop])); - if (yyVals[0+yyTop] is EmptyStatement) - Warning_EmptyStatement (GetLocation (yyVals[0+yyTop])); + yyVal = yyVals[0+yyTop]; } -void case_787() -#line 5237 "cs-parser.jay" +void case_742() +#line 5142 "cs-parser.jay" { - Error_SyntaxError (yyToken); - - yyVal = new If ((BooleanExpression) yyVals[-1+yyTop], null, GetLocation (yyVals[-3+yyTop])); - lbag.AddStatement (yyVal, GetLocation (yyVals[-2+yyTop])); + yyVal = new VarianceDecl (Variance.Covariant, GetLocation (yyVals[0+yyTop])); + savedLocation = GetLocation (yyVals[0+yyTop]); } -void case_789() -#line 5251 "cs-parser.jay" +void case_743() +#line 5147 "cs-parser.jay" { - yyVal = new Switch ((Expression) yyVals[-5+yyTop], (ExplicitBlock) current_block.Explicit, (List) yyVals[-1+yyTop], GetLocation (yyVals[-7+yyTop])); - end_block (GetLocation (yyVals[0+yyTop])); - lbag.AddStatement (yyVal, GetLocation (yyVals[-6+yyTop]), GetLocation (yyVals[-4+yyTop]), GetLocation (yyVals[-3+yyTop]), GetLocation (yyVals[0+yyTop])); + yyVal = new VarianceDecl (Variance.Contravariant, GetLocation (yyVals[0+yyTop])); + savedLocation = GetLocation (yyVals[0+yyTop]); } -void case_790() -#line 5257 "cs-parser.jay" +void case_744() +#line 5168 "cs-parser.jay" { - Error_SyntaxError (yyToken); - - yyVal = new Switch ((Expression) yyVals[-1+yyTop], null, null, GetLocation (yyVals[-3+yyTop])); - lbag.AddStatement (yyVal, GetLocation (yyVals[-2+yyTop])); + ++lexer.parsing_block; + start_block (GetLocation (yyVals[0+yyTop])); } -void case_791() -#line 5267 "cs-parser.jay" +void case_746() +#line 5180 "cs-parser.jay" { - report.Warning (1522, 1, current_block.StartLocation, "Empty switch block"); - yyVal = new List (); + --lexer.parsing_block; + yyVal = end_block (GetLocation (yyVals[0+yyTop])); } -void case_793() -#line 5276 "cs-parser.jay" +void case_747() +#line 5185 "cs-parser.jay" { - var sections = new List (4); - - sections.Add ((SwitchSection) yyVals[0+yyTop]); - yyVal = sections; + --lexer.parsing_block; + yyVal = end_block (lexer.Location); } -void case_794() -#line 5283 "cs-parser.jay" +void case_748() +#line 5194 "cs-parser.jay" { - var sections = (List) yyVals[-1+yyTop]; - - sections.Add ((SwitchSection) yyVals[0+yyTop]); - yyVal = sections; + ++lexer.parsing_block; + current_block.StartLocation = GetLocation (yyVals[0+yyTop]); } -void case_795() -#line 5290 "cs-parser.jay" +void case_749() +#line 5199 "cs-parser.jay" { - Error_SyntaxError (yyToken); - yyVal = new List (); + --lexer.parsing_block; + yyVal = end_block (GetLocation (yyVals[0+yyTop])); } -void case_798() -#line 5309 "cs-parser.jay" +void case_750() +#line 5203 "cs-parser.jay" { - var labels = new List (2); - - labels.Add ((SwitchLabel) yyVals[0+yyTop]); - yyVal = labels; + report.Error (1525, GetLocation (yyVals[0+yyTop]), "Unexpected symbol '}', expected '{'"); + lexer.putback ('}'); + yyVal = end_block (GetLocation (yyVals[0+yyTop])); } -void case_799() -#line 5316 "cs-parser.jay" +void case_751() +#line 5212 "cs-parser.jay" { - var labels = (List) (yyVals[-1+yyTop]); - labels.Add ((SwitchLabel) yyVals[0+yyTop]); - - yyVal = labels; + ++lexer.parsing_block; + current_block.StartLocation = GetLocation (yyVals[0+yyTop]); } -void case_800() -#line 5326 "cs-parser.jay" +void case_752() +#line 5217 "cs-parser.jay" { - yyVal = new SwitchLabel ((Expression) yyVals[-1+yyTop], GetLocation (yyVals[-2+yyTop])); - lbag.AddLocation (yyVal, GetLocation (yyVals[0+yyTop])); - } + --lexer.parsing_block; + yyVal = end_block (GetLocation (yyVals[0+yyTop])); + } -void case_801() -#line 5331 "cs-parser.jay" +void case_760() +#line 5245 "cs-parser.jay" { Error_SyntaxError (yyToken); - yyVal = new SwitchLabel ((Expression) yyVals[-1+yyTop], GetLocation (yyVals[-2+yyTop])); - } + var lt =(LocatedToken) yyVals[-1+yyTop]; + var sn = new SimpleName (lt.Value, lt.Location); + current_block.AddStatement(new StatementErrorExpression (sn)); + yyVal = null; + } -void case_807() -#line 5350 "cs-parser.jay" +void case_761() +#line 5254 "cs-parser.jay" { - if (yyVals[0+yyTop] is EmptyStatement && lexer.peek_token () == Token.OPEN_BRACE) - Warning_EmptyStatement (GetLocation (yyVals[0+yyTop])); - - yyVal = new While ((BooleanExpression) yyVals[-2+yyTop], (Statement) yyVals[0+yyTop], GetLocation (yyVals[-4+yyTop])); - lbag.AddStatement (yyVal, GetLocation (yyVals[-3+yyTop]), GetLocation (yyVals[-1+yyTop])); + Error_SyntaxError (yyToken); + yyVal = null; } -void case_808() -#line 5358 "cs-parser.jay" +void case_794() +#line 5318 "cs-parser.jay" { - Error_SyntaxError (yyToken); - - yyVal = new While ((BooleanExpression) yyVals[-1+yyTop], null, GetLocation (yyVals[-3+yyTop])); - lbag.AddStatement (yyVal, GetLocation (yyVals[-2+yyTop])); + report.Error (1023, GetLocation (yyVals[0+yyTop]), "An embedded statement may not be a declaration or labeled statement"); + yyVal = null; } -void case_809() -#line 5368 "cs-parser.jay" +void case_795() +#line 5323 "cs-parser.jay" { - yyVal = new Do ((Statement) yyVals[-5+yyTop], (BooleanExpression) yyVals[-2+yyTop], GetLocation (yyVals[-6+yyTop]), GetLocation (yyVals[-4+yyTop])); - lbag.AddStatement (yyVal, GetLocation (yyVals[-4+yyTop]), GetLocation (yyVals[-3+yyTop]), GetLocation (yyVals[-1+yyTop]), GetLocation (yyVals[0+yyTop])); + report.Error (1023, GetLocation (yyVals[0+yyTop]), "An embedded statement may not be a declaration or labeled statement"); + yyVal = null; } -void case_810() -#line 5373 "cs-parser.jay" +void case_796() +#line 5328 "cs-parser.jay" { Error_SyntaxError (yyToken); - yyVal = new Do ((Statement) yyVals[-1+yyTop], null, GetLocation (yyVals[-2+yyTop]), Location.Null); + yyVal = new EmptyStatement (GetLocation (yyVals[0+yyTop])); } -void case_811() -#line 5378 "cs-parser.jay" +void case_797() +#line 5336 "cs-parser.jay" { - Error_SyntaxError (yyToken); - - yyVal = new Do ((Statement) yyVals[-4+yyTop], (BooleanExpression) yyVals[-1+yyTop], GetLocation (yyVals[-5+yyTop]), GetLocation (yyVals[-3+yyTop])); - lbag.AddStatement (yyVal, GetLocation (yyVals[-3+yyTop]), GetLocation (yyVals[-2+yyTop])); + /* Uses lexer.Location because semicolon location is not kept in quick mode*/ + yyVal = new EmptyStatement (lexer.Location); } -void case_812() -#line 5388 "cs-parser.jay" +void case_798() +#line 5344 "cs-parser.jay" { - start_block (GetLocation (yyVals[0+yyTop])); - current_block.IsCompilerGenerated = true; - For f = new For (GetLocation (yyVals[-1+yyTop])); - current_block.AddStatement (f); - lbag.AddStatement (f, current_block.StartLocation); - yyVal = f; + var lt = (LocatedToken) yyVals[-1+yyTop]; + LabeledStatement labeled = new LabeledStatement (lt.Value, current_block, lt.Location); + lbag.AddLocation (labeled, GetLocation (yyVals[0+yyTop])); + current_block.AddLabel (labeled); + current_block.AddStatement (labeled); } -void case_814() -#line 5405 "cs-parser.jay" +void case_801() +#line 5357 "cs-parser.jay" { - For f = (For) yyVals[-2+yyTop]; - f.Initializer = (Statement) yyVals[-1+yyTop]; - lbag.AppendTo (f, GetLocation (yyVals[0+yyTop])); - yyVal = f; + if (yyVals[-1+yyTop] is VarExpr) + yyVals[-1+yyTop] = new SimpleName ("var", ((VarExpr) yyVals[-1+yyTop]).Location); + + yyVal = new ComposedCast ((FullNamedExpression) yyVals[-1+yyTop], (ComposedTypeSpecifier) yyVals[0+yyTop]); } -void case_816() -#line 5415 "cs-parser.jay" -{ - report.Error (1525, GetLocation (yyVals[0+yyTop]), "Unexpected symbol ')', expected ';'"); - For f = (For) yyVals[-2+yyTop]; - f.Initializer = (Statement) yyVals[-1+yyTop]; - lbag.AppendTo (f, GetLocation (yyVals[0+yyTop])); - yyVal = end_block (GetLocation (yyVals[0+yyTop])); - } +void case_802() +#line 5373 "cs-parser.jay" +{ + /* Ok, the above "primary_expression" is there to get rid of*/ + /* both reduce/reduce and shift/reduces in the grammar, it should*/ + /* really just be "type_name". If you use type_name, a reduce/reduce*/ + /* creeps up. If you use namespace_or_type_name (which is all we need*/ + /* really) two shift/reduces appear.*/ + /* */ -void case_817() -#line 5426 "cs-parser.jay" -{ - For f = (For) yyVals[-2+yyTop]; - f.Condition = (BooleanExpression) yyVals[-1+yyTop]; - lbag.AppendTo (f, GetLocation (yyVals[0+yyTop])); - yyVal = f; + /* So the super-trick is that primary_expression*/ + /* can only be either a SimpleName or a MemberAccess. */ + /* The MemberAccess case arises when you have a fully qualified type-name like :*/ + /* Foo.Bar.Blah i;*/ + /* SimpleName is when you have*/ + /* Blah i;*/ + + Expression expr = (Expression) yyVals[-1+yyTop]; + if (yyVals[0+yyTop] == null) { + SimpleName sn = expr as SimpleName; + if (sn != null && sn.Name == "var") + yyVal = new VarExpr (sn.Location); + else + yyVal = yyVals[-1+yyTop]; + } else if (expr is ATypeNameExpression) { + yyVal = new ComposedCast ((ATypeNameExpression)expr, (ComposedTypeSpecifier) yyVals[0+yyTop]); + } else { + Error_ExpectingTypeName (expr); + yyVal = null; + } } -void case_819() -#line 5437 "cs-parser.jay" +void case_803() +#line 5403 "cs-parser.jay" { - report.Error (1525, GetLocation (yyVals[0+yyTop]), "Unexpected symbol ')', expected ';'"); - For f = (For) yyVals[-2+yyTop]; - f.Condition = (BooleanExpression) yyVals[-1+yyTop]; - lbag.AppendTo (f, GetLocation (yyVals[0+yyTop])); - yyVal = end_block (GetLocation (yyVals[0+yyTop])); - } + ATypeNameExpression expr = yyVals[-1+yyTop] as ATypeNameExpression; -void case_820() -#line 5449 "cs-parser.jay" + if (expr != null) { + yyVal = new ComposedCast (expr, (ComposedTypeSpecifier) yyVals[0+yyTop]); + } else { + Error_ExpectingTypeName ((Expression)yyVals[-1+yyTop]); + yyVal = expr; + } + } + +void case_804() +#line 5414 "cs-parser.jay" { - For f = (For) yyVals[-3+yyTop]; - f.Iterator = (Statement) yyVals[-2+yyTop]; - - if (yyVals[0+yyTop] is EmptyStatement && lexer.peek_token () == Token.OPEN_BRACE) - Warning_EmptyStatement (GetLocation (yyVals[0+yyTop])); - - f.Statement = (Statement) yyVals[0+yyTop]; - lbag.AppendTo (f, GetLocation (yyVals[-1+yyTop])); + if (yyVals[0+yyTop] == null) + yyVal = yyVals[-1+yyTop]; + else + yyVal = new ComposedCast ((FullNamedExpression) yyVals[-1+yyTop], (ComposedTypeSpecifier) yyVals[0+yyTop]); + } - yyVal = end_block (GetLocation (yyVals[-1+yyTop])); +void case_807() +#line 5429 "cs-parser.jay" +{ + Expression.Error_VoidInvalidInTheContext (GetLocation (yyVals[0+yyTop]), report); + yyVal = new TypeExpression (compiler.BuiltinTypes.Void, GetLocation (yyVals[0+yyTop])); } -void case_821() -#line 5462 "cs-parser.jay" +void case_809() +#line 5438 "cs-parser.jay" { - Error_SyntaxError (yyToken); - yyVal = end_block (current_block.StartLocation); + ((ComposedTypeSpecifier) yyVals[-1+yyTop]).Next = (ComposedTypeSpecifier) yyVals[0+yyTop]; + yyVal = yyVals[-1+yyTop]; } -void case_824() -#line 5475 "cs-parser.jay" +void case_813() +#line 5461 "cs-parser.jay" { - var lt = (Tokenizer.LocatedToken) yyVals[0+yyTop]; + var lt = (LocatedToken) yyVals[0+yyTop]; var li = new LocalVariable (current_block, lt.Value, lt.Location); current_block.AddLocalName (li); - current_variable = new BlockVariableDeclaration ((FullNamedExpression) yyVals[-1+yyTop], li); + current_variable = new BlockVariable ((FullNamedExpression) yyVals[-1+yyTop], li); } -void case_825() -#line 5482 "cs-parser.jay" +void case_814() +#line 5468 "cs-parser.jay" { yyVal = current_variable; current_variable = null; + if (yyVals[-2+yyTop] != null) + lbag.AddLocation (yyVal, PopLocation (), GetLocation (yyVals[0+yyTop])); + else + lbag.AddLocation (yyVal, GetLocation (yyVals[0+yyTop])); } -void case_833() -#line 5506 "cs-parser.jay" +void case_815() +#line 5477 "cs-parser.jay" { - var sl = yyVals[-2+yyTop] as StatementList; - if (sl == null) { - sl = new StatementList ((Statement) yyVals[-2+yyTop], (Statement) yyVals[0+yyTop]); - lbag.AddStatement (sl, GetLocation (yyVals[-1+yyTop])); - } else { - sl.Add ((Statement) yyVals[0+yyTop]); - lbag.AppendTo (sl, GetLocation (yyVals[-1+yyTop])); - - } - - yyVal = sl; + var lt = (LocatedToken) yyVals[0+yyTop]; + var li = new LocalVariable (current_block, lt.Value, LocalVariable.Flags.Constant, lt.Location); + current_block.AddLocalName (li); + current_variable = new BlockConstant ((FullNamedExpression) yyVals[-1+yyTop], li); } -void case_834() -#line 5523 "cs-parser.jay" -{ - report.Error (230, GetLocation (yyVals[-3+yyTop]), "Type and identifier are both required in a foreach statement"); - - start_block (GetLocation (yyVals[-2+yyTop])); - current_block.IsCompilerGenerated = true; - - Foreach f = new Foreach ((Expression) yyVals[-1+yyTop], null, null, null, null, GetLocation (yyVals[-3+yyTop])); - current_block.AddStatement (f); - - lbag.AddStatement (f, GetLocation (yyVals[-2+yyTop])); - yyVal = end_block (GetLocation (yyVals[0+yyTop])); - } - -void case_835() -#line 5536 "cs-parser.jay" +void case_816() +#line 5484 "cs-parser.jay" { - Error_SyntaxError (yyToken); - - start_block (GetLocation (yyVals[-3+yyTop])); - current_block.IsCompilerGenerated = true; - - var lt = (Tokenizer.LocatedToken) yyVals[-1+yyTop]; - var li = new LocalVariable (current_block, lt.Value, LocalVariable.Flags.ForeachVariable | LocalVariable.Flags.Used, lt.Location); - current_block.AddLocalName (li); - - Foreach f = new Foreach ((Expression) yyVals[-2+yyTop], li, null, null, null, GetLocation (yyVals[-4+yyTop])); - current_block.AddStatement (f); - - lbag.AddStatement (f, GetLocation (yyVals[-3+yyTop])); - yyVal = end_block (GetLocation (yyVals[0+yyTop])); + if (current_variable.Initializer != null) { + lbag.AddLocation (current_variable, GetLocation (yyVals[-6+yyTop]), savedLocation, GetLocation (yyVals[0+yyTop])); + } else { + lbag.AddLocation (current_variable, GetLocation (yyVals[-6+yyTop]), GetLocation (yyVals[0+yyTop])); + } + yyVal = current_variable;; + current_variable = null; } -void case_836() -#line 5553 "cs-parser.jay" +void case_818() +#line 5497 "cs-parser.jay" { - start_block (GetLocation (yyVals[-5+yyTop])); - current_block.IsCompilerGenerated = true; - var lt = (Tokenizer.LocatedToken) yyVals[-3+yyTop]; - var li = new LocalVariable (current_block, lt.Value, LocalVariable.Flags.ForeachVariable | LocalVariable.Flags.Used, lt.Location); - current_block.AddLocalName (li); - yyVal = li; + /* Redundant, but wont regress*/ + report.Error (1525, lexer.Location, "Unexpected symbol }"); + lexer.putback ('}'); + yyVal = yyVals[0+yyTop]; } -void case_837() -#line 5562 "cs-parser.jay" +void case_820() +#line 5508 "cs-parser.jay" { - if (yyVals[0+yyTop] is EmptyStatement && lexer.peek_token () == Token.OPEN_BRACE) - Warning_EmptyStatement (GetLocation (yyVals[0+yyTop])); - - Foreach f = new Foreach ((Expression) yyVals[-6+yyTop], (LocalVariable) yyVals[-1+yyTop], (Expression) yyVals[-3+yyTop], (Statement) yyVals[0+yyTop], current_block, GetLocation (yyVals[-8+yyTop])); - lbag.AddStatement (f, GetLocation (yyVals[-7+yyTop]), GetLocation (yyVals[-4+yyTop]), GetLocation (yyVals[-2+yyTop])); - end_block (GetLocation (yyVals[-2+yyTop])); - - yyVal = f; + current_variable.Initializer = (Expression) yyVals[0+yyTop]; + PushLocation (GetLocation (yyVals[-1+yyTop])); + yyVal = current_variable; } -void case_838() -#line 5573 "cs-parser.jay" +void case_821() +#line 5514 "cs-parser.jay" { - start_block (GetLocation (yyVals[-3+yyTop])); - current_block.IsCompilerGenerated = true; - var lt = yyVals[-1+yyTop] as Tokenizer.LocatedToken; - var li = lt != null ? new LocalVariable (current_block, lt.Value, LocalVariable.Flags.ForeachVariable | LocalVariable.Flags.Used, lt.Location) : null; - - Foreach f = new Foreach ((Expression) yyVals[-2+yyTop], li, null, null, null, GetLocation (yyVals[-4+yyTop])); - current_block.AddStatement (f); - - lbag.AddStatement (f, GetLocation (yyVals[-3+yyTop])); - yyVal = end_block (GetLocation (yyVals[0+yyTop])); + if (yyToken == Token.OPEN_BRACKET_EXPR) { + report.Error (650, lexer.Location, + "Syntax error, bad array declarator. To declare a managed array the rank specifier precedes the variable's identifier. To declare a fixed size buffer field, use the fixed keyword before the field type"); + } else { + Error_SyntaxError (yyToken); + } } -void case_839() -#line 5586 "cs-parser.jay" +void case_825() +#line 5532 "cs-parser.jay" { - Foreach f = new Foreach ((Expression) yyVals[-1+yyTop], null, null, null, null, GetLocation (yyVals[-3+yyTop])); - current_block.AddStatement (f); - - lbag.AddStatement (f, GetLocation (yyVals[-2+yyTop])); - yyVal = f; + foreach (var d in current_variable.Declarators) { + if (d.Initializer == null) + Error_MissingInitializer (d.Variable.Location); + } } -void case_846() -#line 5606 "cs-parser.jay" +void case_828() +#line 5547 "cs-parser.jay" { - yyVal = new Break (GetLocation (yyVals[-1+yyTop])); - lbag.AddStatement (yyVal, GetLocation (yyVals[0+yyTop])); + var lt = (LocatedToken) yyVals[0+yyTop]; + var li = new LocalVariable (current_variable.Variable, lt.Value, lt.Location); + var d = new BlockVariableDeclarator (li, null); + current_variable.AddDeclarator (d); + current_block.AddLocalName (li); + lbag.AddLocation (d, GetLocation (yyVals[-1+yyTop])); } -void case_847() -#line 5614 "cs-parser.jay" +void case_829() +#line 5556 "cs-parser.jay" { - yyVal = new Continue (GetLocation (yyVals[-1+yyTop])); - lbag.AddStatement (yyVal, GetLocation (yyVals[0+yyTop])); + var lt = (LocatedToken) yyVals[-2+yyTop]; + var li = new LocalVariable (current_variable.Variable, lt.Value, lt.Location); + var d = new BlockVariableDeclarator (li, (Expression) yyVals[0+yyTop]); + current_variable.AddDeclarator (d); + current_block.AddLocalName (li); + lbag.AddLocation (d, GetLocation (yyVals[-3+yyTop]), GetLocation (yyVals[-1+yyTop])); } -void case_848() -#line 5619 "cs-parser.jay" +void case_831() +#line 5572 "cs-parser.jay" { - Error_SyntaxError (yyToken); - yyVal = new Continue (GetLocation (yyVals[-1+yyTop])); + savedLocation = GetLocation (yyVals[-1+yyTop]); + current_variable.Initializer = (Expression) yyVals[0+yyTop]; } -void case_849() -#line 5627 "cs-parser.jay" +void case_836() +#line 5590 "cs-parser.jay" { - var lt = (Tokenizer.LocatedToken) yyVals[-1+yyTop]; - yyVal = new Goto (lt.Value, GetLocation (yyVals[-2+yyTop])); - lbag.AddStatement (yyVal, GetLocation (yyVals[-1+yyTop]), GetLocation (yyVals[0+yyTop])); + var lt = (LocatedToken) yyVals[-2+yyTop]; + var li = new LocalVariable (current_block, lt.Value, LocalVariable.Flags.Constant, lt.Location); + var d = new BlockVariableDeclarator (li, (Expression) yyVals[0+yyTop]); + current_variable.AddDeclarator (d); + current_block.AddLocalName (li); + lbag.AddLocation (d, GetLocation (yyVals[-3+yyTop]), GetLocation (yyVals[-1+yyTop])); } -void case_850() -#line 5633 "cs-parser.jay" +void case_838() +#line 5603 "cs-parser.jay" { - yyVal = new GotoCase ((Expression) yyVals[-1+yyTop], GetLocation (yyVals[-3+yyTop])); - lbag.AddStatement (yyVal, GetLocation (yyVals[-2+yyTop]), GetLocation (yyVals[0+yyTop])); + yyVal = new StackAlloc ((Expression) yyVals[-3+yyTop], (Expression) yyVals[-1+yyTop], GetLocation (yyVals[-4+yyTop])); + lbag.AddLocation (yyVal, GetLocation (yyVals[-2+yyTop]), GetLocation (yyVals[0+yyTop])); } -void case_851() -#line 5638 "cs-parser.jay" +void case_839() +#line 5608 "cs-parser.jay" { - yyVal = new GotoDefault (GetLocation (yyVals[-2+yyTop])); - lbag.AddStatement (yyVal, GetLocation (yyVals[-1+yyTop]), GetLocation (yyVals[0+yyTop])); + report.Error (1575, GetLocation (yyVals[-1+yyTop]), "A stackalloc expression requires [] after type"); + yyVal = new StackAlloc ((Expression) yyVals[0+yyTop], null, GetLocation (yyVals[-1+yyTop])); } -void case_852() -#line 5646 "cs-parser.jay" +void case_840() +#line 5616 "cs-parser.jay" { - yyVal = new Return ((Expression) yyVals[-1+yyTop], GetLocation (yyVals[-2+yyTop])); + yyVal = yyVals[-1+yyTop]; lbag.AddStatement (yyVal, GetLocation (yyVals[0+yyTop])); } -void case_853() -#line 5651 "cs-parser.jay" +void case_842() +#line 5622 "cs-parser.jay" { - Error_SyntaxError (yyToken); - yyVal = new Return ((Expression) yyVals[-1+yyTop], GetLocation (yyVals[-2+yyTop])); + yyVal = yyVals[-1+yyTop]; + report.Error (1002, GetLocation (yyVals[0+yyTop]), "; expected"); + lexer.putback ('}'); } -void case_854() -#line 5656 "cs-parser.jay" +void case_845() +#line 5640 "cs-parser.jay" { - Error_SyntaxError (yyToken); - yyVal = new Return (null, GetLocation (yyVals[-1+yyTop])); + ExpressionStatement s = yyVals[0+yyTop] as ExpressionStatement; + if (s == null) { + var expr = yyVals[0+yyTop] as Expression; + yyVal = new StatementErrorExpression (expr); + } else { + yyVal = new StatementExpression (s); + } } -void case_855() -#line 5664 "cs-parser.jay" +void case_846() +#line 5653 "cs-parser.jay" { - yyVal = new Throw ((Expression) yyVals[-1+yyTop], GetLocation (yyVals[-2+yyTop])); - lbag.AddStatement (yyVal, GetLocation (yyVals[0+yyTop])); + Expression expr = (Expression) yyVals[0+yyTop]; + yyVal = new StatementExpression (new OptionalAssign (expr, lexer.Location)); } -void case_856() -#line 5669 "cs-parser.jay" +void case_847() +#line 5658 "cs-parser.jay" { Error_SyntaxError (yyToken); - yyVal = new Throw (null, GetLocation (yyVals[-1+yyTop])); + yyVal = new EmptyStatement (GetLocation (yyVals[0+yyTop])); } -void case_857() -#line 5677 "cs-parser.jay" +void case_850() +#line 5672 "cs-parser.jay" +{ + if (yyVals[0+yyTop] is EmptyStatement) + Warning_EmptyStatement (GetLocation (yyVals[0+yyTop])); + + yyVal = new If ((BooleanExpression) yyVals[-2+yyTop], (Statement) yyVals[0+yyTop], GetLocation (yyVals[-4+yyTop])); + lbag.AddStatement (yyVal, GetLocation (yyVals[-3+yyTop]), GetLocation (yyVals[-1+yyTop])); + } + +void case_851() +#line 5681 "cs-parser.jay" { - var lt = (Tokenizer.LocatedToken) yyVals[-3+yyTop]; - string s = lt.Value; - if (s != "yield"){ - report.Error (1003, lt.Location, "; expected"); - } else if (yyVals[-1+yyTop] == null) { - report.Error (1627, GetLocation (yyVals[0+yyTop]), "Expression expected after yield return"); - } else if (lang_version == LanguageVersion.ISO_1){ - FeatureIsNotAvailable (lt.Location, "iterators"); - } + yyVal = new If ((BooleanExpression) yyVals[-4+yyTop], (Statement) yyVals[-2+yyTop], (Statement) yyVals[0+yyTop], GetLocation (yyVals[-6+yyTop])); + lbag.AddStatement (yyVal, GetLocation (yyVals[-5+yyTop]), GetLocation (yyVals[-3+yyTop]), GetLocation (yyVals[-1+yyTop])); - current_block.Explicit.RegisterIteratorYield (); - yyVal = new Yield ((Expression) yyVals[-1+yyTop], lt.Location); - lbag.AddStatement (yyVal, GetLocation (yyVals[-2+yyTop]), GetLocation (yyVals[0+yyTop])); + if (yyVals[-2+yyTop] is EmptyStatement) + Warning_EmptyStatement (GetLocation (yyVals[-2+yyTop])); + if (yyVals[0+yyTop] is EmptyStatement) + Warning_EmptyStatement (GetLocation (yyVals[0+yyTop])); } -void case_858() -#line 5693 "cs-parser.jay" +void case_852() +#line 5691 "cs-parser.jay" { Error_SyntaxError (yyToken); - - var lt = (Tokenizer.LocatedToken) yyVals[-3+yyTop]; - string s = lt.Value; - if (s != "yield"){ - report.Error (1003, lt.Location, "; expected"); - } else if (yyVals[-1+yyTop] == null) { - report.Error (1627, GetLocation (yyVals[0+yyTop]), "Expression expected after yield return"); - } else if (lang_version == LanguageVersion.ISO_1){ - FeatureIsNotAvailable (lt.Location, "iterators"); - } - current_block.Explicit.RegisterIteratorYield (); - yyVal = new Yield ((Expression) yyVals[-1+yyTop], lt.Location); + yyVal = new If ((BooleanExpression) yyVals[-1+yyTop], null, GetLocation (yyVals[-3+yyTop])); lbag.AddStatement (yyVal, GetLocation (yyVals[-2+yyTop])); } -void case_859() -#line 5711 "cs-parser.jay" +void case_854() +#line 5705 "cs-parser.jay" { - var lt = (Tokenizer.LocatedToken) yyVals[-2+yyTop]; - string s = lt.Value; - if (s != "yield"){ - report.Error (1003, lt.Location, "; expected"); - } else if (lang_version == LanguageVersion.ISO_1){ - FeatureIsNotAvailable (lt.Location, "iterators"); - } - - current_block.Explicit.RegisterIteratorYield (); - yyVal = new YieldBreak (lt.Location); - lbag.AddStatement (yyVal, GetLocation (yyVals[-1+yyTop]), GetLocation (yyVals[0+yyTop])); + yyVal = new Switch ((Expression) yyVals[-5+yyTop], (ExplicitBlock) current_block.Explicit, GetLocation (yyVals[-7+yyTop])); + end_block (GetLocation (yyVals[0+yyTop])); + lbag.AddStatement (yyVal, GetLocation (yyVals[-6+yyTop]), GetLocation (yyVals[-4+yyTop]), GetLocation (yyVals[-3+yyTop]), GetLocation (yyVals[0+yyTop])); } -void case_863() -#line 5737 "cs-parser.jay" +void case_855() +#line 5711 "cs-parser.jay" { - yyVal = new TryFinally ((Statement) yyVals[-2+yyTop], (Block) yyVals[0+yyTop], GetLocation (yyVals[-3+yyTop])); - lbag.AddStatement (yyVal, GetLocation (yyVals[-1+yyTop])); + Error_SyntaxError (yyToken); + + yyVal = new Switch ((Expression) yyVals[-1+yyTop], null, GetLocation (yyVals[-3+yyTop])); + lbag.AddStatement (yyVal, GetLocation (yyVals[-2+yyTop])); } -void case_864() +void case_862() #line 5742 "cs-parser.jay" { - var loc = GetLocation (yyVals[-4+yyTop]); - yyVal = new TryFinally (new TryCatch ((Block) yyVals[-3+yyTop], (List) yyVals[-2+yyTop], loc, true), (Block) yyVals[0+yyTop], loc); - lbag.AddStatement (yyVal, GetLocation (yyVals[-1+yyTop])); + var label = (SwitchLabel) yyVals[0+yyTop]; + label.SectionStart = true; + current_block.AddStatement (label); } +void case_864() +#line 5755 "cs-parser.jay" +{ + yyVal = new SwitchLabel ((Expression) yyVals[-1+yyTop], GetLocation (yyVals[-2+yyTop])); + lbag.AddLocation (yyVal, GetLocation (yyVals[0+yyTop])); + } + void case_865() -#line 5748 "cs-parser.jay" +#line 5760 "cs-parser.jay" { - Error_SyntaxError (1524, yyToken); - yyVal = new TryCatch ((Block) yyVals[-1+yyTop], null, GetLocation (yyVals[-2+yyTop]), false); + Error_SyntaxError (yyToken); + yyVal = new SwitchLabel ((Expression) yyVals[-1+yyTop], GetLocation (yyVals[-2+yyTop])); } -void case_866() -#line 5756 "cs-parser.jay" +void case_871() +#line 5779 "cs-parser.jay" { - var l = new List (2); - - l.Add ((Catch) yyVals[0+yyTop]); - yyVal = l; + if (yyVals[0+yyTop] is EmptyStatement && lexer.peek_token () == Token.OPEN_BRACE) + Warning_EmptyStatement (GetLocation (yyVals[0+yyTop])); + + yyVal = new While ((BooleanExpression) yyVals[-2+yyTop], (Statement) yyVals[0+yyTop], GetLocation (yyVals[-4+yyTop])); + lbag.AddStatement (yyVal, GetLocation (yyVals[-3+yyTop]), GetLocation (yyVals[-1+yyTop])); } -void case_867() -#line 5763 "cs-parser.jay" +void case_872() +#line 5787 "cs-parser.jay" { - var l = (List) yyVals[-1+yyTop]; - - Catch c = (Catch) yyVals[0+yyTop]; - if (l [l.Count - 1].IsGeneral) { - report.Error (1017, c.loc, "Try statement already has an empty catch block"); - } + Error_SyntaxError (yyToken); - l.Add (c); - yyVal = l; + yyVal = new While ((BooleanExpression) yyVals[-1+yyTop], null, GetLocation (yyVals[-3+yyTop])); + lbag.AddStatement (yyVal, GetLocation (yyVals[-2+yyTop])); } -void case_871() -#line 5787 "cs-parser.jay" +void case_873() +#line 5797 "cs-parser.jay" { - start_block (GetLocation (yyVals[-3+yyTop])); - var c = new Catch (current_block, GetLocation (yyVals[-4+yyTop])); - c.TypeExpression = (FullNamedExpression) yyVals[-2+yyTop]; - - if (yyVals[-1+yyTop] != null) { - var lt = (Tokenizer.LocatedToken) yyVals[-1+yyTop]; - c.Variable = new LocalVariable (current_block, lt.Value, lt.Location); - current_block.AddLocalName (c.Variable); - } + yyVal = new Do ((Statement) yyVals[-5+yyTop], (BooleanExpression) yyVals[-2+yyTop], GetLocation (yyVals[-6+yyTop]), GetLocation (yyVals[-4+yyTop])); + lbag.AddStatement (yyVal, GetLocation (yyVals[-4+yyTop]), GetLocation (yyVals[-3+yyTop]), GetLocation (yyVals[-1+yyTop]), GetLocation (yyVals[0+yyTop])); + } - lbag.AddLocation (c, GetLocation (yyVals[-3+yyTop]), GetLocation (yyVals[0+yyTop])); - yyVal = c; +void case_874() +#line 5802 "cs-parser.jay" +{ + Error_SyntaxError (yyToken); + yyVal = new Do ((Statement) yyVals[-1+yyTop], null, GetLocation (yyVals[-2+yyTop]), Location.Null); } -void case_873() -#line 5806 "cs-parser.jay" +void case_875() +#line 5807 "cs-parser.jay" { - if (yyToken == Token.CLOSE_PARENS) { - report.Error (1015, lexer.Location, - "A type that derives from `System.Exception', `object', or `string' expected"); - } else { - Error_SyntaxError (yyToken); - } - - yyVal = new Catch (null, GetLocation (yyVals[-2+yyTop])); + Error_SyntaxError (yyToken); + + yyVal = new Do ((Statement) yyVals[-4+yyTop], (BooleanExpression) yyVals[-1+yyTop], GetLocation (yyVals[-5+yyTop]), GetLocation (yyVals[-3+yyTop])); + lbag.AddStatement (yyVal, GetLocation (yyVals[-3+yyTop]), GetLocation (yyVals[-2+yyTop])); } void case_876() -#line 5834 "cs-parser.jay" +#line 5817 "cs-parser.jay" { - if (!settings.Unsafe) - Error_UnsafeCodeNotAllowed (GetLocation (yyVals[0+yyTop])); + start_block (GetLocation (yyVals[0+yyTop])); + current_block.IsCompilerGenerated = true; + For f = new For (GetLocation (yyVals[-1+yyTop])); + current_block.AddStatement (f); + lbag.AddStatement (f, current_block.StartLocation); + yyVal = f; } void case_878() +#line 5834 "cs-parser.jay" +{ + For f = (For) yyVals[-2+yyTop]; + f.Initializer = (Statement) yyVals[-1+yyTop]; + lbag.AddLocation (f, GetLocation (yyVals[0+yyTop])); + yyVal = f; + } + +void case_880() #line 5844 "cs-parser.jay" { + report.Error (1525, GetLocation (yyVals[0+yyTop]), "Unexpected symbol ')', expected ';'"); + For f = (For) yyVals[-2+yyTop]; + f.Initializer = (Statement) yyVals[-1+yyTop]; + lbag.AddLocation (f, GetLocation (yyVals[0+yyTop])); + yyVal = end_block (GetLocation (yyVals[0+yyTop])); + } + +void case_881() +#line 5855 "cs-parser.jay" +{ + For f = (For) yyVals[-2+yyTop]; + f.Condition = (BooleanExpression) yyVals[-1+yyTop]; + lbag.AddLocation (f, GetLocation (yyVals[0+yyTop])); + yyVal = f; + } + +void case_883() +#line 5866 "cs-parser.jay" +{ + report.Error (1525, GetLocation (yyVals[0+yyTop]), "Unexpected symbol ')', expected ';'"); + For f = (For) yyVals[-2+yyTop]; + f.Condition = (BooleanExpression) yyVals[-1+yyTop]; + lbag.AddLocation (f, GetLocation (yyVals[0+yyTop])); + yyVal = end_block (GetLocation (yyVals[0+yyTop])); + } + +void case_884() +#line 5878 "cs-parser.jay" +{ + For f = (For) yyVals[-3+yyTop]; + f.Iterator = (Statement) yyVals[-2+yyTop]; + if (yyVals[0+yyTop] is EmptyStatement && lexer.peek_token () == Token.OPEN_BRACE) Warning_EmptyStatement (GetLocation (yyVals[0+yyTop])); - yyVal = new Lock ((Expression) yyVals[-2+yyTop], (Statement) yyVals[0+yyTop], GetLocation (yyVals[-4+yyTop])); - lbag.AddStatement (yyVal, GetLocation (yyVals[-3+yyTop]), GetLocation (yyVals[-1+yyTop])); + f.Statement = (Statement) yyVals[0+yyTop]; + lbag.AddLocation (f, GetLocation (yyVals[-1+yyTop])); + + yyVal = end_block (GetLocation (yyVals[-1+yyTop])); } -void case_879() -#line 5852 "cs-parser.jay" +void case_885() +#line 5891 "cs-parser.jay" { Error_SyntaxError (yyToken); - - yyVal = new Lock ((Expression) yyVals[-1+yyTop], null, GetLocation (yyVals[-3+yyTop])); - lbag.AddStatement (yyVal, GetLocation (yyVals[-2+yyTop])); + yyVal = end_block (current_block.StartLocation); } -void case_880() -#line 5862 "cs-parser.jay" +void case_888() +#line 5904 "cs-parser.jay" { - start_block (GetLocation (yyVals[-2+yyTop])); - - current_block.IsCompilerGenerated = true; - var lt = (Tokenizer.LocatedToken) yyVals[0+yyTop]; - var li = new LocalVariable (current_block, lt.Value, LocalVariable.Flags.FixedVariable | LocalVariable.Flags.Used, lt.Location); + var lt = (LocatedToken) yyVals[0+yyTop]; + var li = new LocalVariable (current_block, lt.Value, lt.Location); current_block.AddLocalName (li); - current_variable = new Fixed.VariableDeclaration ((FullNamedExpression) yyVals[-1+yyTop], li); + current_variable = new BlockVariable ((FullNamedExpression) yyVals[-1+yyTop], li); } -void case_881() -#line 5872 "cs-parser.jay" +void case_889() +#line 5911 "cs-parser.jay" { yyVal = current_variable; + if (yyVals[-1+yyTop] != null) + lbag.AddLocation (current_variable, PopLocation ()); + current_variable = null; } -void case_882() -#line 5877 "cs-parser.jay" +void case_897() +#line 5938 "cs-parser.jay" { - if (yyVals[0+yyTop] is EmptyStatement && lexer.peek_token () == Token.OPEN_BRACE) - Warning_EmptyStatement (GetLocation (yyVals[0+yyTop])); - - Fixed f = new Fixed ((Fixed.VariableDeclaration) yyVals[-1+yyTop], (Statement) yyVals[0+yyTop], GetLocation (yyVals[-9+yyTop])); + var sl = yyVals[-2+yyTop] as StatementList; + if (sl == null) { + sl = new StatementList ((Statement) yyVals[-2+yyTop], (Statement) yyVals[0+yyTop]); + lbag.AddStatement (sl, GetLocation (yyVals[-1+yyTop])); + } else { + sl.Add ((Statement) yyVals[0+yyTop]); + lbag.AddLocation (sl, GetLocation (yyVals[-1+yyTop])); + + } + + yyVal = sl; + } + +void case_898() +#line 5955 "cs-parser.jay" +{ + report.Error (230, GetLocation (yyVals[-3+yyTop]), "Type and identifier are both required in a foreach statement"); + + start_block (GetLocation (yyVals[-2+yyTop])); + current_block.IsCompilerGenerated = true; + + Foreach f = new Foreach ((Expression) yyVals[-1+yyTop], null, null, null, null, GetLocation (yyVals[-3+yyTop])); current_block.AddStatement (f); - lbag.AddStatement (f, GetLocation (yyVals[-8+yyTop]), GetLocation (yyVals[-2+yyTop])); - yyVal = end_block (GetLocation (yyVals[-2+yyTop])); + + lbag.AddStatement (f, GetLocation (yyVals[-2+yyTop])); + yyVal = end_block (GetLocation (yyVals[0+yyTop])); } -void case_883() -#line 5890 "cs-parser.jay" +void case_899() +#line 5968 "cs-parser.jay" { - start_block (GetLocation (yyVals[-2+yyTop])); - + Error_SyntaxError (yyToken); + + start_block (GetLocation (yyVals[-3+yyTop])); current_block.IsCompilerGenerated = true; - var lt = (Tokenizer.LocatedToken) yyVals[0+yyTop]; - var li = new LocalVariable (current_block, lt.Value, LocalVariable.Flags.UsingVariable | LocalVariable.Flags.Used, lt.Location); + + var lt = (LocatedToken) yyVals[-1+yyTop]; + var li = new LocalVariable (current_block, lt.Value, LocalVariable.Flags.ForeachVariable | LocalVariable.Flags.Used, lt.Location); current_block.AddLocalName (li); - current_variable = new Using.VariableDeclaration ((FullNamedExpression) yyVals[-1+yyTop], li); + + Foreach f = new Foreach ((Expression) yyVals[-2+yyTop], li, null, null, null, GetLocation (yyVals[-4+yyTop])); + current_block.AddStatement (f); + + lbag.AddStatement (f, GetLocation (yyVals[-3+yyTop])); + yyVal = end_block (GetLocation (yyVals[0+yyTop])); } -void case_884() -#line 5900 "cs-parser.jay" +void case_900() +#line 5985 "cs-parser.jay" { - yyVal = current_variable; - current_variable = null; + start_block (GetLocation (yyVals[-5+yyTop])); + current_block.IsCompilerGenerated = true; + + var lt = (LocatedToken) yyVals[-3+yyTop]; + var li = new LocalVariable (current_block, lt.Value, LocalVariable.Flags.ForeachVariable | LocalVariable.Flags.Used, lt.Location); + current_block.AddLocalName (li); + yyVal = li; } -void case_885() -#line 5905 "cs-parser.jay" +void case_901() +#line 5995 "cs-parser.jay" { if (yyVals[0+yyTop] is EmptyStatement && lexer.peek_token () == Token.OPEN_BRACE) Warning_EmptyStatement (GetLocation (yyVals[0+yyTop])); - - Using u = new Using ((Using.VariableDeclaration) yyVals[-1+yyTop], (Statement) yyVals[0+yyTop], GetLocation (yyVals[-8+yyTop])); - lbag.AddStatement (u, GetLocation (yyVals[-7+yyTop]), GetLocation (yyVals[-2+yyTop])); - current_block.AddStatement (u); - yyVal = end_block (GetLocation (yyVals[-2+yyTop])); + + Foreach f = new Foreach ((Expression) yyVals[-6+yyTop], (LocalVariable) yyVals[-1+yyTop], (Expression) yyVals[-3+yyTop], (Statement) yyVals[0+yyTop], current_block, GetLocation (yyVals[-8+yyTop])); + lbag.AddStatement (f, GetLocation (yyVals[-7+yyTop]), GetLocation (yyVals[-4+yyTop]), GetLocation (yyVals[-2+yyTop])); + end_block (GetLocation (yyVals[-2+yyTop])); + + yyVal = f; } -void case_886() -#line 5915 "cs-parser.jay" +void case_902() +#line 6006 "cs-parser.jay" { - if (yyVals[0+yyTop] is EmptyStatement && lexer.peek_token () == Token.OPEN_BRACE) - Warning_EmptyStatement (GetLocation (yyVals[0+yyTop])); - - yyVal = new Using ((Expression) yyVals[-2+yyTop], (Statement) yyVals[0+yyTop], GetLocation (yyVals[-4+yyTop])); - lbag.AddStatement (yyVal, GetLocation (yyVals[-3+yyTop]), GetLocation (yyVals[-1+yyTop])); + start_block (GetLocation (yyVals[-3+yyTop])); + current_block.IsCompilerGenerated = true; + var lt = yyVals[-1+yyTop] as LocatedToken; + var li = lt != null ? new LocalVariable (current_block, lt.Value, LocalVariable.Flags.ForeachVariable | LocalVariable.Flags.Used, lt.Location) : null; + + Foreach f = new Foreach ((Expression) yyVals[-2+yyTop], li, null, null, null, GetLocation (yyVals[-4+yyTop])); + current_block.AddStatement (f); + + lbag.AddStatement (f, GetLocation (yyVals[-3+yyTop])); + yyVal = end_block (GetLocation (yyVals[0+yyTop])); } -void case_887() -#line 5923 "cs-parser.jay" +void case_903() +#line 6019 "cs-parser.jay" { - Error_SyntaxError (yyToken); + Foreach f = new Foreach ((Expression) yyVals[-1+yyTop], null, null, null, null, GetLocation (yyVals[-3+yyTop])); + current_block.AddStatement (f); - yyVal = new Using ((Expression) yyVals[-1+yyTop], null, GetLocation (yyVals[-3+yyTop])); - lbag.AddStatement (yyVal, GetLocation (yyVals[-2+yyTop])); + lbag.AddStatement (f, GetLocation (yyVals[-2+yyTop])); + yyVal = f; } -void case_889() -#line 5934 "cs-parser.jay" +void case_910() +#line 6039 "cs-parser.jay" { - /* It has to be here for the parent to safely restore artificial block*/ - Error_SyntaxError (yyToken); + yyVal = new Break (GetLocation (yyVals[-1+yyTop])); + lbag.AddStatement (yyVal, GetLocation (yyVals[0+yyTop])); } -void case_891() -#line 5946 "cs-parser.jay" +void case_911() +#line 6047 "cs-parser.jay" { - current_variable.Initializer = (Expression) yyVals[0+yyTop]; - lbag.AppendTo (current_variable, GetLocation (yyVals[-1+yyTop])); - yyVal = current_variable; + yyVal = new Continue (GetLocation (yyVals[-1+yyTop])); + lbag.AddStatement (yyVal, GetLocation (yyVals[0+yyTop])); } -void case_892() -#line 5958 "cs-parser.jay" +void case_912() +#line 6052 "cs-parser.jay" { - lexer.query_parsing = false; - - Linq.AQueryClause from = yyVals[-1+yyTop] as Linq.AQueryClause; - - from.Tail.Next = (Linq.AQueryClause)yyVals[0+yyTop]; - yyVal = from; - - current_block.SetEndLocation (lexer.Location); - current_block = current_block.Parent; + Error_SyntaxError (yyToken); + yyVal = new Continue (GetLocation (yyVals[-1+yyTop])); } -void case_893() -#line 5970 "cs-parser.jay" +void case_913() +#line 6060 "cs-parser.jay" { - Linq.AQueryClause from = yyVals[-1+yyTop] as Linq.AQueryClause; - - from.Tail.Next = (Linq.AQueryClause)yyVals[0+yyTop]; - yyVal = from; - - current_block.SetEndLocation (lexer.Location); - current_block = current_block.Parent; + var lt = (LocatedToken) yyVals[-1+yyTop]; + yyVal = new Goto (lt.Value, GetLocation (yyVals[-2+yyTop])); + lbag.AddStatement (yyVal, GetLocation (yyVals[-1+yyTop]), GetLocation (yyVals[0+yyTop])); } -void case_894() -#line 5981 "cs-parser.jay" +void case_914() +#line 6066 "cs-parser.jay" { - lexer.query_parsing = false; - yyVal = yyVals[-1+yyTop]; - - current_block.SetEndLocation (lexer.Location); - current_block = current_block.Parent; + yyVal = new GotoCase ((Expression) yyVals[-1+yyTop], GetLocation (yyVals[-3+yyTop])); + lbag.AddStatement (yyVal, GetLocation (yyVals[-2+yyTop]), GetLocation (yyVals[0+yyTop])); } -void case_895() -#line 5988 "cs-parser.jay" +void case_915() +#line 6071 "cs-parser.jay" { - yyVal = yyVals[-1+yyTop]; - current_block.SetEndLocation (lexer.Location); - current_block = current_block.Parent; + yyVal = new GotoDefault (GetLocation (yyVals[-2+yyTop])); + lbag.AddStatement (yyVal, GetLocation (yyVals[-1+yyTop]), GetLocation (yyVals[0+yyTop])); } -void case_896() -#line 5997 "cs-parser.jay" +void case_916() +#line 6079 "cs-parser.jay" { - current_block = new Linq.QueryBlock (current_block, lexer.Location); - - var lt = (Tokenizer.LocatedToken) yyVals[-2+yyTop]; - var rv = new Linq.RangeVariable (lt.Value, lt.Location); - var start = new Linq.QueryStartClause ((Linq.QueryBlock)current_block, (Expression)yyVals[0+yyTop], rv, GetLocation (yyVals[-3+yyTop])); - lbag.AddLocation (start, GetLocation (yyVals[-1+yyTop])); - yyVal = new Linq.QueryExpression (start); + yyVal = new Return ((Expression) yyVals[-1+yyTop], GetLocation (yyVals[-2+yyTop])); + lbag.AddStatement (yyVal, GetLocation (yyVals[0+yyTop])); } -void case_897() -#line 6007 "cs-parser.jay" +void case_917() +#line 6084 "cs-parser.jay" { - current_block = new Linq.QueryBlock (current_block, lexer.Location); - - var lt = (Tokenizer.LocatedToken) yyVals[-2+yyTop]; - var rv = new Linq.RangeVariable (lt.Value, lt.Location); - var start = new Linq.QueryStartClause ((Linq.QueryBlock)current_block, (Expression)yyVals[0+yyTop], rv, GetLocation (yyVals[-4+yyTop])) { - IdentifierType = (FullNamedExpression)yyVals[-3+yyTop] - }; - lbag.AddLocation (start, GetLocation (yyVals[-1+yyTop])); - yyVal = new Linq.QueryExpression (start); + Error_SyntaxError (yyToken); + yyVal = new Return ((Expression) yyVals[-1+yyTop], GetLocation (yyVals[-2+yyTop])); } -void case_898() -#line 6022 "cs-parser.jay" +void case_918() +#line 6089 "cs-parser.jay" { - current_block = new Linq.QueryBlock (current_block, lexer.Location); - - var lt = (Tokenizer.LocatedToken) yyVals[-2+yyTop]; - var rv = new Linq.RangeVariable (lt.Value, lt.Location); - var start = new Linq.QueryStartClause ((Linq.QueryBlock)current_block, (Expression)yyVals[0+yyTop], rv, GetLocation (yyVals[-3+yyTop])); - lbag.AddLocation (start, GetLocation (yyVals[-1+yyTop])); - yyVal = new Linq.QueryExpression (start); + Error_SyntaxError (yyToken); + yyVal = new Return (null, GetLocation (yyVals[-1+yyTop])); } -void case_899() -#line 6032 "cs-parser.jay" +void case_919() +#line 6097 "cs-parser.jay" { - current_block = new Linq.QueryBlock (current_block, lexer.Location); - - var lt = (Tokenizer.LocatedToken) yyVals[-2+yyTop]; - var rv = new Linq.RangeVariable (lt.Value, lt.Location); - var start = new Linq.QueryStartClause ((Linq.QueryBlock)current_block, (Expression)yyVals[0+yyTop], rv, GetLocation (yyVals[-4+yyTop])) { - IdentifierType = (FullNamedExpression)yyVals[-3+yyTop] - }; - lbag.AddLocation (start, GetLocation (yyVals[-1+yyTop])); - yyVal = new Linq.QueryExpression (start); + yyVal = new Throw ((Expression) yyVals[-1+yyTop], GetLocation (yyVals[-2+yyTop])); + lbag.AddStatement (yyVal, GetLocation (yyVals[0+yyTop])); } -void case_901() -#line 6051 "cs-parser.jay" +void case_920() +#line 6102 "cs-parser.jay" { - var lt = (Tokenizer.LocatedToken) yyVals[-3+yyTop]; - var sn = new Linq.RangeVariable (lt.Value, lt.Location); - yyVal = new Linq.SelectMany ((Linq.QueryBlock)current_block, sn, (Expression)yyVals[0+yyTop], GetLocation (yyVals[-4+yyTop])); - - current_block.SetEndLocation (lexer.Location); - current_block = current_block.Parent; - ((Linq.QueryBlock)current_block).AddRangeVariable (sn); - - lbag.AddLocation (yyVal, GetLocation (yyVals[-2+yyTop])); + Error_SyntaxError (yyToken); + yyVal = new Throw ((Expression) yyVals[-1+yyTop], GetLocation (yyVals[-2+yyTop])); } -void case_903() -#line 6067 "cs-parser.jay" +void case_921() +#line 6107 "cs-parser.jay" { - var lt = (Tokenizer.LocatedToken) yyVals[-3+yyTop]; - var sn = new Linq.RangeVariable (lt.Value, lt.Location); + Error_SyntaxError (yyToken); + yyVal = new Throw (null, GetLocation (yyVals[-1+yyTop])); + } - yyVal = new Linq.SelectMany ((Linq.QueryBlock)current_block, sn, (Expression)yyVals[0+yyTop], GetLocation (yyVals[-5+yyTop])) { - IdentifierType = (FullNamedExpression)yyVals[-4+yyTop] - }; - - current_block.SetEndLocation (lexer.Location); - current_block = current_block.Parent; - - ((Linq.QueryBlock)current_block).AddRangeVariable (sn); +void case_922() +#line 6115 "cs-parser.jay" +{ + var lt = (LocatedToken) yyVals[-3+yyTop]; + string s = lt.Value; + if (s != "yield"){ + report.Error (1003, lt.Location, "; expected"); + } else if (yyVals[-1+yyTop] == null) { + report.Error (1627, GetLocation (yyVals[0+yyTop]), "Expression expected after yield return"); + } else if (lang_version == LanguageVersion.ISO_1){ + FeatureIsNotAvailable (lt.Location, "iterators"); + } - lbag.AddLocation (yyVal, GetLocation (yyVals[-2+yyTop])); + current_block.Explicit.RegisterIteratorYield (); + yyVal = new Yield ((Expression) yyVals[-1+yyTop], lt.Location); + lbag.AddStatement (yyVal, GetLocation (yyVals[-2+yyTop]), GetLocation (yyVals[0+yyTop])); } -void case_904() -#line 6086 "cs-parser.jay" +void case_923() +#line 6131 "cs-parser.jay" { - Linq.AQueryClause head = (Linq.AQueryClause)yyVals[-1+yyTop]; - - if (yyVals[0+yyTop] != null) - head.Next = (Linq.AQueryClause)yyVals[0+yyTop]; - - if (yyVals[-2+yyTop] != null) { - Linq.AQueryClause clause = (Linq.AQueryClause)yyVals[-2+yyTop]; - clause.Tail.Next = head; - head = clause; + Error_SyntaxError (yyToken); + + var lt = (LocatedToken) yyVals[-3+yyTop]; + string s = lt.Value; + if (s != "yield"){ + report.Error (1003, lt.Location, "; expected"); + } else if (yyVals[-1+yyTop] == null) { + report.Error (1627, GetLocation (yyVals[0+yyTop]), "Expression expected after yield return"); + } else if (lang_version == LanguageVersion.ISO_1){ + FeatureIsNotAvailable (lt.Location, "iterators"); } - yyVal = head; + current_block.Explicit.RegisterIteratorYield (); + yyVal = new Yield ((Expression) yyVals[-1+yyTop], lt.Location); + lbag.AddStatement (yyVal, GetLocation (yyVals[-2+yyTop])); } -void case_905() -#line 6101 "cs-parser.jay" +void case_924() +#line 6149 "cs-parser.jay" { - Linq.AQueryClause head = (Linq.AQueryClause)yyVals[0+yyTop]; - - if (yyVals[-1+yyTop] != null) { - Linq.AQueryClause clause = (Linq.AQueryClause)yyVals[-1+yyTop]; - clause.Tail.Next = head; - head = clause; + var lt = (LocatedToken) yyVals[-2+yyTop]; + string s = lt.Value; + if (s != "yield"){ + report.Error (1003, lt.Location, "; expected"); + } else if (lang_version == LanguageVersion.ISO_1){ + FeatureIsNotAvailable (lt.Location, "iterators"); } - yyVal = head; + current_block.ParametersBlock.TopBlock.IsIterator = true; + yyVal = new YieldBreak (lt.Location); + lbag.AddStatement (yyVal, GetLocation (yyVals[-1+yyTop]), GetLocation (yyVals[0+yyTop])); } -void case_907() -#line 6114 "cs-parser.jay" +void case_928() +#line 6175 "cs-parser.jay" { - report.Error (742, GetLocation (yyVals[0+yyTop]), "Unexpected symbol `{0}'. A query body must end with select or group clause", GetSymbolName (yyToken)); - yyVal = yyVals[-1+yyTop]; + yyVal = new TryFinally ((Statement) yyVals[-2+yyTop], (ExplicitBlock) yyVals[0+yyTop], GetLocation (yyVals[-3+yyTop])); + lbag.AddStatement (yyVal, GetLocation (yyVals[-1+yyTop])); } -void case_908() -#line 6119 "cs-parser.jay" +void case_929() +#line 6180 "cs-parser.jay" { - Error_SyntaxError (yyToken); - yyVal = null; + yyVal = new TryFinally (new TryCatch ((Block) yyVals[-3+yyTop], (List) yyVals[-2+yyTop], GetLocation (yyVals[-4+yyTop]), true), (ExplicitBlock) yyVals[0+yyTop], GetLocation (yyVals[-4+yyTop])); + lbag.AddStatement (yyVal, GetLocation (yyVals[-1+yyTop])); } -void case_910() -#line 6131 "cs-parser.jay" +void case_930() +#line 6185 "cs-parser.jay" { - yyVal = new Linq.Select ((Linq.QueryBlock)current_block, (Expression)yyVals[0+yyTop], GetLocation (yyVals[-2+yyTop])); + Error_SyntaxError (1524, yyToken); + yyVal = new TryCatch ((Block) yyVals[-1+yyTop], null, GetLocation (yyVals[-2+yyTop]), false); + } - current_block.SetEndLocation (lexer.Location); - current_block = current_block.Parent; +void case_931() +#line 6193 "cs-parser.jay" +{ + var l = new List (2); + + l.Add ((Catch) yyVals[0+yyTop]); + yyVal = l; } -void case_911() -#line 6138 "cs-parser.jay" +void case_932() +#line 6200 "cs-parser.jay" { - if (linq_clause_blocks == null) - linq_clause_blocks = new Stack (); - - current_block = new Linq.QueryBlock (current_block, lexer.Location); - linq_clause_blocks.Push ((Linq.QueryBlock)current_block); + var l = (List) yyVals[-1+yyTop]; + + Catch c = (Catch) yyVals[0+yyTop]; + var prev_catch = l [l.Count - 1]; + if (prev_catch.IsGeneral && prev_catch.Filter == null) { + report.Error (1017, c.loc, "Try statement already has an empty catch block"); + } + + l.Add (c); + yyVal = l; } -void case_912() -#line 6146 "cs-parser.jay" +void case_935() +#line 6221 "cs-parser.jay" { - current_block.SetEndLocation (lexer.Location); - current_block = current_block.Parent; - - current_block = new Linq.QueryBlock (current_block, lexer.Location); + var c = new Catch ((ExplicitBlock) yyVals[0+yyTop], GetLocation (yyVals[-2+yyTop])); + c.Filter = (CatchFilterExpression) yyVals[-1+yyTop]; + yyVal = c; } -void case_913() -#line 6153 "cs-parser.jay" +void case_936() +#line 6227 "cs-parser.jay" { - yyVal = new Linq.GroupBy ((Linq.QueryBlock)current_block, (Expression)yyVals[-3+yyTop], linq_clause_blocks.Pop (), (Expression)yyVals[0+yyTop], GetLocation (yyVals[-5+yyTop])); - lbag.AddLocation (yyVal, GetLocation (yyVals[-1+yyTop])); - - current_block.SetEndLocation (lexer.Location); - current_block = current_block.Parent; + start_block (GetLocation (yyVals[-3+yyTop])); + var c = new Catch ((ExplicitBlock) current_block, GetLocation (yyVals[-4+yyTop])); + c.TypeExpression = (FullNamedExpression) yyVals[-2+yyTop]; + + if (yyVals[-1+yyTop] != null) { + var lt = (LocatedToken) yyVals[-1+yyTop]; + c.Variable = new LocalVariable (current_block, lt.Value, lt.Location); + current_block.AddLocalName (c.Variable); + } + + lbag.AddLocation (c, GetLocation (yyVals[-3+yyTop]), GetLocation (yyVals[0+yyTop])); + yyVal = c; } -void case_915() -#line 6165 "cs-parser.jay" +void case_937() +#line 6242 "cs-parser.jay" { - ((Linq.AQueryClause)yyVals[-1+yyTop]).Tail.Next = (Linq.AQueryClause)yyVals[0+yyTop]; - yyVal = yyVals[-1+yyTop]; + ((Catch) yyVals[-2+yyTop]).Filter = (CatchFilterExpression) yyVals[-1+yyTop]; + yyVal = yyVals[-2+yyTop]; } -void case_922() -#line 6185 "cs-parser.jay" +void case_938() +#line 6247 "cs-parser.jay" { - var lt = (Tokenizer.LocatedToken) yyVals[-3+yyTop]; - var sn = new Linq.RangeVariable (lt.Value, lt.Location); - yyVal = new Linq.Let ((Linq.QueryBlock) current_block, sn, (Expression)yyVals[0+yyTop], GetLocation (yyVals[-4+yyTop])); - lbag.AddLocation (yyVal, GetLocation (yyVals[-2+yyTop])); - - current_block.SetEndLocation (lexer.Location); - current_block = current_block.Parent; + if (yyToken == Token.CLOSE_PARENS) { + report.Error (1015, lexer.Location, + "A type that derives from `System.Exception', `object', or `string' expected"); + } else { + Error_SyntaxError (yyToken); + } - ((Linq.QueryBlock)current_block).AddRangeVariable (sn); + yyVal = new Catch (null, GetLocation (yyVals[-2+yyTop])); } -void case_924() -#line 6204 "cs-parser.jay" +void case_939() +#line 6258 "cs-parser.jay" { - yyVal = new Linq.Where ((Linq.QueryBlock)current_block, (Expression)yyVals[0+yyTop], GetLocation (yyVals[-2+yyTop])); + Error_SyntaxError (yyToken); - current_block.SetEndLocation (lexer.Location); - current_block = current_block.Parent; - } + /* Required otherwise missing block could not be detected because*/ + /* start_block is run early*/ + var c = new Catch (null, GetLocation (yyVals[-5+yyTop])); + c.TypeExpression = (FullNamedExpression) yyVals[-3+yyTop]; + + if (yyVals[-2+yyTop] != null) { + var lt = (LocatedToken) yyVals[-2+yyTop]; + c.Variable = new LocalVariable (current_block, lt.Value, lt.Location); + } -void case_925() -#line 6214 "cs-parser.jay" -{ - if (linq_clause_blocks == null) - linq_clause_blocks = new Stack (); - - current_block = new Linq.QueryBlock (current_block, lexer.Location); - linq_clause_blocks.Push ((Linq.QueryBlock) current_block); + if (yyVals[-2+yyTop] != null) { + var lt = (LocatedToken) yyVals[-2+yyTop]; + c.Variable = new LocalVariable (current_block, lt.Value, lt.Location); + } + + lbag.AddLocation (c, GetLocation (yyVals[-4+yyTop]), GetLocation (yyVals[-1+yyTop])); + + yyVal = c; } -void case_926() -#line 6222 "cs-parser.jay" +void case_941() +#line 6285 "cs-parser.jay" { - current_block.SetEndLocation (lexer.Location); - current_block = current_block.Parent; + if (lang_version <= LanguageVersion.V_5) + FeatureIsNotAvailable (GetLocation (yyVals[-3+yyTop]), "exception filter"); - current_block = new Linq.QueryBlock (current_block, lexer.Location); - linq_clause_blocks.Push ((Linq.QueryBlock) current_block); + yyVal = new CatchFilterExpression ((Expression) yyVals[-1+yyTop], GetLocation (yyVals[-3+yyTop])); + lbag.AddLocation (yyVal, GetLocation (yyVals[-2+yyTop]), GetLocation (yyVals[0+yyTop])); } -void case_927() -#line 6230 "cs-parser.jay" +void case_944() +#line 6310 "cs-parser.jay" { - current_block.AddStatement (new ContextualReturn ((Expression) yyVals[-1+yyTop])); - current_block.SetEndLocation (lexer.Location); - current_block = current_block.Parent; - - current_block = new Linq.QueryBlock (current_block, lexer.Location); + if (!settings.Unsafe) + Error_UnsafeCodeNotAllowed (GetLocation (yyVals[0+yyTop])); } -void case_928() -#line 6238 "cs-parser.jay" +void case_946() +#line 6320 "cs-parser.jay" { - current_block.AddStatement (new ContextualReturn ((Expression) yyVals[-1+yyTop])); - current_block.SetEndLocation (lexer.Location); + if (yyVals[0+yyTop] is EmptyStatement && lexer.peek_token () == Token.OPEN_BRACE) + Warning_EmptyStatement (GetLocation (yyVals[0+yyTop])); - var outer_selector = linq_clause_blocks.Pop (); - var block = linq_clause_blocks.Pop (); - - var lt = (Tokenizer.LocatedToken) yyVals[-10+yyTop]; - var sn = new Linq.RangeVariable (lt.Value, lt.Location); - Linq.RangeVariable into; - - if (yyVals[0+yyTop] == null) { - into = sn; - yyVal = new Linq.Join (block, sn, (Expression)yyVals[-7+yyTop], outer_selector, (Linq.QueryBlock) current_block, GetLocation (yyVals[-11+yyTop])); - lbag.AddLocation (yyVal, GetLocation (yyVals[-9+yyTop]), GetLocation (yyVals[-6+yyTop]), GetLocation (yyVals[-3+yyTop])); - } else { - /**/ - /* Set equals right side parent to beginning of linq query, it is not accessible therefore cannot cause name collisions*/ - /**/ - var parent = block.Parent; - while (parent is Linq.QueryBlock) { - parent = parent.Parent; - } - current_block.Parent = parent; - - ((Linq.QueryBlock)current_block).AddRangeVariable (sn); - - lt = (Tokenizer.LocatedToken) yyVals[0+yyTop]; - into = new Linq.RangeVariable (lt.Value, lt.Location); + yyVal = new Lock ((Expression) yyVals[-2+yyTop], (Statement) yyVals[0+yyTop], GetLocation (yyVals[-4+yyTop])); + lbag.AddStatement (yyVal, GetLocation (yyVals[-3+yyTop]), GetLocation (yyVals[-1+yyTop])); + } - yyVal = new Linq.GroupJoin (block, sn, (Expression)yyVals[-7+yyTop], outer_selector, (Linq.QueryBlock) current_block, into, GetLocation (yyVals[-11+yyTop])); - lbag.AddLocation (yyVal, GetLocation (yyVals[-9+yyTop]), GetLocation (yyVals[-6+yyTop]), GetLocation (yyVals[-3+yyTop]), opt_intoStack.Pop ()); - } +void case_947() +#line 6328 "cs-parser.jay" +{ + Error_SyntaxError (yyToken); - current_block = block.Parent; - ((Linq.QueryBlock)current_block).AddRangeVariable (into); + yyVal = new Lock ((Expression) yyVals[-1+yyTop], null, GetLocation (yyVals[-3+yyTop])); + lbag.AddStatement (yyVal, GetLocation (yyVals[-2+yyTop])); } -void case_929() -#line 6276 "cs-parser.jay" +void case_948() +#line 6338 "cs-parser.jay" { - if (linq_clause_blocks == null) - linq_clause_blocks = new Stack (); - - current_block = new Linq.QueryBlock (current_block, lexer.Location); - linq_clause_blocks.Push ((Linq.QueryBlock) current_block); + start_block (GetLocation (yyVals[-2+yyTop])); + + current_block.IsCompilerGenerated = true; + var lt = (LocatedToken) yyVals[0+yyTop]; + var li = new LocalVariable (current_block, lt.Value, LocalVariable.Flags.FixedVariable | LocalVariable.Flags.Used, lt.Location); + current_block.AddLocalName (li); + current_variable = new Fixed.VariableDeclaration ((FullNamedExpression) yyVals[-1+yyTop], li); } -void case_930() -#line 6284 "cs-parser.jay" +void case_949() +#line 6348 "cs-parser.jay" { - current_block.SetEndLocation (lexer.Location); - current_block = current_block.Parent; - - current_block = new Linq.QueryBlock (current_block, lexer.Location); - linq_clause_blocks.Push ((Linq.QueryBlock) current_block); + yyVal = current_variable; + current_variable = null; } -void case_931() -#line 6292 "cs-parser.jay" +void case_950() +#line 6353 "cs-parser.jay" { - current_block.AddStatement (new ContextualReturn ((Expression) yyVals[-1+yyTop])); - current_block.SetEndLocation (lexer.Location); - current_block = current_block.Parent; - - current_block = new Linq.QueryBlock (current_block, lexer.Location); + if (yyVals[0+yyTop] is EmptyStatement && lexer.peek_token () == Token.OPEN_BRACE) + Warning_EmptyStatement (GetLocation (yyVals[0+yyTop])); + + Fixed f = new Fixed ((Fixed.VariableDeclaration) yyVals[-1+yyTop], (Statement) yyVals[0+yyTop], GetLocation (yyVals[-9+yyTop])); + current_block.AddStatement (f); + lbag.AddStatement (f, GetLocation (yyVals[-8+yyTop]), GetLocation (yyVals[-2+yyTop])); + yyVal = end_block (GetLocation (yyVals[-2+yyTop])); } -void case_932() -#line 6300 "cs-parser.jay" +void case_951() +#line 6366 "cs-parser.jay" { - current_block.AddStatement (new ContextualReturn ((Expression) yyVals[-1+yyTop])); - current_block.SetEndLocation (lexer.Location); - - var outer_selector = linq_clause_blocks.Pop (); - var block = linq_clause_blocks.Pop (); - - var lt = (Tokenizer.LocatedToken) yyVals[-10+yyTop]; - var sn = new Linq.RangeVariable (lt.Value, lt.Location); - Linq.RangeVariable into; - - if (yyVals[0+yyTop] == null) { - into = sn; - yyVal = new Linq.Join (block, sn, (Expression)yyVals[-7+yyTop], outer_selector, (Linq.QueryBlock) current_block, GetLocation (yyVals[-12+yyTop])) { - IdentifierType = (FullNamedExpression)yyVals[-11+yyTop] - }; - lbag.AddLocation (yyVal, GetLocation (yyVals[-10+yyTop]), GetLocation (yyVals[-7+yyTop]), GetLocation (yyVals[-4+yyTop])); - } else { - /**/ - /* Set equals right side parent to beginning of linq query, it is not accessible therefore cannot cause name collisions*/ - /**/ - var parent = block.Parent; - while (parent is Linq.QueryBlock) { - parent = parent.Parent; - } - current_block.Parent = parent; - - ((Linq.QueryBlock)current_block).AddRangeVariable (sn); - - lt = (Tokenizer.LocatedToken) yyVals[0+yyTop]; - into = new Linq.RangeVariable (lt.Value, lt.Location); /* TODO:*/ - - yyVal = new Linq.GroupJoin (block, sn, (Expression)yyVals[-7+yyTop], outer_selector, (Linq.QueryBlock) current_block, into, GetLocation (yyVals[-12+yyTop])) { - IdentifierType = (FullNamedExpression)yyVals[-11+yyTop] - }; - lbag.AddLocation (yyVal, GetLocation (yyVals[-10+yyTop]), GetLocation (yyVals[-7+yyTop]), GetLocation (yyVals[-4+yyTop]), opt_intoStack.Pop ()); - } - - current_block = block.Parent; - ((Linq.QueryBlock)current_block).AddRangeVariable (into); + start_block (GetLocation (yyVals[-2+yyTop])); + + current_block.IsCompilerGenerated = true; + var lt = (LocatedToken) yyVals[0+yyTop]; + var li = new LocalVariable (current_block, lt.Value, LocalVariable.Flags.UsingVariable | LocalVariable.Flags.Used, lt.Location); + current_block.AddLocalName (li); + current_variable = new Using.VariableDeclaration ((FullNamedExpression) yyVals[-1+yyTop], li); } -void case_934() -#line 6346 "cs-parser.jay" +void case_952() +#line 6376 "cs-parser.jay" { - opt_intoStack.Push (GetLocation (yyVals[-1+yyTop])); - yyVal = yyVals[0+yyTop]; + yyVal = current_variable; + current_variable = null; } -void case_936() -#line 6358 "cs-parser.jay" +void case_953() +#line 6381 "cs-parser.jay" { - current_block.SetEndLocation (lexer.Location); - current_block = current_block.Parent; + if (yyVals[0+yyTop] is EmptyStatement && lexer.peek_token () == Token.OPEN_BRACE) + Warning_EmptyStatement (GetLocation (yyVals[0+yyTop])); - yyVal = yyVals[0+yyTop]; + Using u = new Using ((Using.VariableDeclaration) yyVals[-1+yyTop], (Statement) yyVals[0+yyTop], GetLocation (yyVals[-8+yyTop])); + lbag.AddStatement (u, GetLocation (yyVals[-7+yyTop]), GetLocation (yyVals[-2+yyTop])); + current_block.AddStatement (u); + yyVal = end_block (GetLocation (yyVals[-2+yyTop])); } -void case_938() -#line 6369 "cs-parser.jay" +void case_954() +#line 6391 "cs-parser.jay" { - current_block.SetEndLocation (lexer.Location); - current_block = current_block.Parent; + if (yyVals[0+yyTop] is EmptyStatement && lexer.peek_token () == Token.OPEN_BRACE) + Warning_EmptyStatement (GetLocation (yyVals[0+yyTop])); - current_block = new Linq.QueryBlock (current_block, lexer.Location); + yyVal = new Using ((Expression) yyVals[-2+yyTop], (Statement) yyVals[0+yyTop], GetLocation (yyVals[-4+yyTop])); + lbag.AddStatement (yyVal, GetLocation (yyVals[-3+yyTop]), GetLocation (yyVals[-1+yyTop])); } -void case_939() -#line 6376 "cs-parser.jay" +void case_955() +#line 6399 "cs-parser.jay" { - ((Linq.AQueryClause)yyVals[-3+yyTop]).Next = (Linq.AQueryClause)yyVals[0+yyTop]; - yyVal = yyVals[-3+yyTop]; + Error_SyntaxError (yyToken); + + yyVal = new Using ((Expression) yyVals[-1+yyTop], null, GetLocation (yyVals[-3+yyTop])); + lbag.AddStatement (yyVal, GetLocation (yyVals[-2+yyTop])); } -void case_941() -#line 6385 "cs-parser.jay" -{ - current_block.SetEndLocation (lexer.Location); - current_block = current_block.Parent; - - current_block = new Linq.QueryBlock ((Linq.QueryBlock) current_block, lexer.Location); - } - -void case_942() -#line 6392 "cs-parser.jay" -{ - ((Linq.AQueryClause)yyVals[-3+yyTop]).Tail.Next = (Linq.AQueryClause)yyVals[0+yyTop]; - yyVal = yyVals[-3+yyTop]; - } - -void case_944() -#line 6404 "cs-parser.jay" +void case_957() +#line 6410 "cs-parser.jay" { - yyVal = new Linq.OrderByAscending ((Linq.QueryBlock) current_block, (Expression)yyVals[-1+yyTop]); - lbag.AddLocation (yyVal, GetLocation (yyVals[0+yyTop])); + /* It has to be here for the parent to safely restore artificial block*/ + Error_SyntaxError (yyToken); } -void case_945() -#line 6409 "cs-parser.jay" +void case_959() +#line 6422 "cs-parser.jay" { - yyVal = new Linq.OrderByDescending ((Linq.QueryBlock) current_block, (Expression)yyVals[-1+yyTop]); - lbag.AddLocation (yyVal, GetLocation (yyVals[0+yyTop])); + current_variable.Initializer = (Expression) yyVals[0+yyTop]; + lbag.AddLocation (current_variable, GetLocation (yyVals[-1+yyTop])); + yyVal = current_variable; } -void case_947() -#line 6421 "cs-parser.jay" +void case_960() +#line 6434 "cs-parser.jay" { - yyVal = new Linq.ThenByAscending ((Linq.QueryBlock) current_block, (Expression)yyVals[-1+yyTop]); - lbag.AddLocation (yyVal, GetLocation (yyVals[0+yyTop])); + lexer.query_parsing = false; + + Linq.AQueryClause from = yyVals[-1+yyTop] as Linq.AQueryClause; + + from.Tail.Next = (Linq.AQueryClause)yyVals[0+yyTop]; + yyVal = from; + + current_block.SetEndLocation (lexer.Location); + current_block = current_block.Parent; } -void case_948() -#line 6426 "cs-parser.jay" +void case_961() +#line 6446 "cs-parser.jay" { - yyVal = new Linq.ThenByDescending ((Linq.QueryBlock) current_block, (Expression)yyVals[-1+yyTop]); - lbag.AddLocation (yyVal, GetLocation (yyVals[0+yyTop])); + Linq.AQueryClause from = yyVals[-1+yyTop] as Linq.AQueryClause; + + from.Tail.Next = (Linq.AQueryClause)yyVals[0+yyTop]; + yyVal = from; + + current_block.SetEndLocation (lexer.Location); + current_block = current_block.Parent; } -void case_950() -#line 6436 "cs-parser.jay" +void case_962() +#line 6457 "cs-parser.jay" { - /* query continuation block is not linked with query block but with block*/ - /* before. This means each query can use same range variable names for*/ - /* different identifiers.*/ + lexer.query_parsing = false; + yyVal = yyVals[-1+yyTop]; - current_block.SetEndLocation (GetLocation (yyVals[-1+yyTop])); + current_block.SetEndLocation (lexer.Location); current_block = current_block.Parent; - - current_block = new Linq.QueryBlock (current_block, lexer.Location); - - if (linq_clause_blocks == null) - linq_clause_blocks = new Stack (); - - linq_clause_blocks.Push ((Linq.QueryBlock) current_block); } -void case_951() -#line 6452 "cs-parser.jay" +void case_963() +#line 6464 "cs-parser.jay" { - var current_block = linq_clause_blocks.Pop (); - var lt = (Tokenizer.LocatedToken) yyVals[-2+yyTop]; - var rv = new Linq.RangeVariable (lt.Value, lt.Location); - yyVal = new Linq.QueryStartClause ((Linq.QueryBlock)current_block, null, rv, GetLocation (yyVals[-3+yyTop])) { - next = (Linq.AQueryClause)yyVals[0+yyTop] - }; - } - -void case_954() -#line 6479 "cs-parser.jay" -{ - current_container = current_type = new Class (current_container, new MemberName (""), Modifiers.PUBLIC, null); - - /* (ref object retval)*/ - Parameter [] mpar = new Parameter [1]; - mpar [0] = new Parameter (new TypeExpression (compiler.BuiltinTypes.Object, Location.Null), "$retval", Parameter.Modifier.REF, null, Location.Null); - - ParametersCompiled pars = new ParametersCompiled (mpar); - var mods = Modifiers.PUBLIC | Modifiers.STATIC; - if (settings.Unsafe) - mods |= Modifiers.UNSAFE; - - current_local_parameters = pars; - Method method = new Method ( - current_type, - new TypeExpression (compiler.BuiltinTypes.Void, Location.Null), - mods, - new MemberName ("Host"), - pars, - null /* attributes */); - - current_type.AddMember (method); - - oob_stack.Push (method); - ++lexer.parsing_block; - start_block (lexer.Location); + yyVal = yyVals[-1+yyTop]; + current_block.SetEndLocation (lexer.Location); + current_block = current_block.Parent; } -void case_955() -#line 6507 "cs-parser.jay" +void case_964() +#line 6473 "cs-parser.jay" { - --lexer.parsing_block; - Method method = (Method) oob_stack.Pop (); - - method.Block = (ToplevelBlock) end_block(lexer.Location); - - InteractiveResult = (Class) pop_current_class (); - current_local_parameters = null; + current_block = new Linq.QueryBlock (current_block, lexer.Location); + + var lt = (LocatedToken) yyVals[-2+yyTop]; + var rv = new Linq.RangeVariable (lt.Value, lt.Location); + var clause = new Linq.QueryStartClause ((Linq.QueryBlock)current_block, (Expression)yyVals[0+yyTop], rv, GetLocation (yyVals[-3+yyTop])); + lbag.AddLocation (clause, GetLocation (yyVals[-1+yyTop])); + yyVal = new Linq.QueryExpression (clause); } void case_965() -#line 6550 "cs-parser.jay" +#line 6483 "cs-parser.jay" { - module.DocumentationBuilder.ParsedBuiltinType = (TypeExpression)yyVals[-1+yyTop]; - module.DocumentationBuilder.ParsedParameters = (List)yyVals[0+yyTop]; - yyVal = null; + current_block = new Linq.QueryBlock (current_block, lexer.Location); + + var lt = (LocatedToken) yyVals[-2+yyTop]; + var rv = new Linq.RangeVariable (lt.Value, lt.Location); + var clause = new Linq.QueryStartClause ((Linq.QueryBlock)current_block, (Expression)yyVals[0+yyTop], rv, GetLocation (yyVals[-4+yyTop])) { + IdentifierType = (FullNamedExpression)yyVals[-3+yyTop] + }; + lbag.AddLocation (clause, GetLocation (yyVals[-1+yyTop])); + yyVal = new Linq.QueryExpression (clause); } void case_966() -#line 6556 "cs-parser.jay" +#line 6498 "cs-parser.jay" { - module.DocumentationBuilder.ParsedBuiltinType = (TypeExpression)yyVals[-3+yyTop]; - module.DocumentationBuilder.ParsedParameters = (List)yyVals[0+yyTop]; - var lt = (Tokenizer.LocatedToken) yyVals[-1+yyTop]; - yyVal = new MemberName (lt.Value); + current_block = new Linq.QueryBlock (current_block, lexer.Location); + + var lt = (LocatedToken) yyVals[-2+yyTop]; + var rv = new Linq.RangeVariable (lt.Value, lt.Location); + var clause = new Linq.QueryStartClause ((Linq.QueryBlock)current_block, (Expression)yyVals[0+yyTop], rv, GetLocation (yyVals[-3+yyTop])); + lbag.AddLocation (clause, GetLocation (yyVals[-1+yyTop])); + yyVal = new Linq.QueryExpression (clause); } -void case_969() -#line 6571 "cs-parser.jay" +void case_967() +#line 6508 "cs-parser.jay" { - module.DocumentationBuilder.ParsedParameters = (List)yyVals[-1+yyTop]; - yyVal = new MemberName ((MemberName) yyVals[-6+yyTop], MemberCache.IndexerNameAlias, Location.Null); + current_block = new Linq.QueryBlock (current_block, lexer.Location); + + var lt = (LocatedToken) yyVals[-2+yyTop]; + var rv = new Linq.RangeVariable (lt.Value, lt.Location); + var clause = new Linq.QueryStartClause ((Linq.QueryBlock)current_block, (Expression)yyVals[0+yyTop], rv, GetLocation (yyVals[-4+yyTop])) { + IdentifierType = (FullNamedExpression)yyVals[-3+yyTop] + }; + lbag.AddLocation (clause, GetLocation (yyVals[-1+yyTop])); + yyVal = new Linq.QueryExpression (clause); } -void case_970() -#line 6576 "cs-parser.jay" +void case_969() +#line 6527 "cs-parser.jay" { - var p = (List)yyVals[0+yyTop] ?? new List (1); - p.Add (new DocumentationParameter ((FullNamedExpression) yyVals[-1+yyTop])); - module.DocumentationBuilder.ParsedParameters = p; - module.DocumentationBuilder.ParsedOperator = Operator.OpType.Explicit; - yyVal = null; + var lt = (LocatedToken) yyVals[-3+yyTop]; + var sn = new Linq.RangeVariable (lt.Value, lt.Location); + yyVal = new Linq.SelectMany ((Linq.QueryBlock)current_block, sn, (Expression)yyVals[0+yyTop], GetLocation (yyVals[-4+yyTop])); + + current_block.SetEndLocation (lexer.Location); + current_block = current_block.Parent; + ((Linq.QueryBlock)current_block).AddRangeVariable (sn); + lbag.AddLocation (yyVal, GetLocation (yyVals[-2+yyTop])); } void case_971() -#line 6584 "cs-parser.jay" +#line 6542 "cs-parser.jay" { - var p = (List)yyVals[0+yyTop] ?? new List (1); - p.Add (new DocumentationParameter ((FullNamedExpression) yyVals[-1+yyTop])); - module.DocumentationBuilder.ParsedParameters = p; - module.DocumentationBuilder.ParsedOperator = Operator.OpType.Implicit; - yyVal = null; + var lt = (LocatedToken) yyVals[-3+yyTop]; + var sn = new Linq.RangeVariable (lt.Value, lt.Location); + + yyVal = new Linq.SelectMany ((Linq.QueryBlock)current_block, sn, (Expression)yyVals[0+yyTop], GetLocation (yyVals[-5+yyTop])) { + IdentifierType = (FullNamedExpression)yyVals[-4+yyTop] + }; + + current_block.SetEndLocation (lexer.Location); + current_block = current_block.Parent; + + ((Linq.QueryBlock)current_block).AddRangeVariable (sn); + + lbag.AddLocation (yyVal, GetLocation (yyVals[-2+yyTop])); } void case_972() -#line 6592 "cs-parser.jay" +#line 6561 "cs-parser.jay" { - var p = (List)yyVals[0+yyTop] ?? new List (1); - module.DocumentationBuilder.ParsedParameters = p; - module.DocumentationBuilder.ParsedOperator = (Operator.OpType) yyVals[-1+yyTop]; - yyVal = null; + Linq.AQueryClause head = (Linq.AQueryClause)yyVals[-1+yyTop]; + + if (yyVals[0+yyTop] != null) + head.Next = (Linq.AQueryClause)yyVals[0+yyTop]; + + if (yyVals[-2+yyTop] != null) { + Linq.AQueryClause clause = (Linq.AQueryClause)yyVals[-2+yyTop]; + clause.Tail.Next = head; + head = clause; + } + + yyVal = head; } -void case_980() -#line 6630 "cs-parser.jay" +void case_973() +#line 6576 "cs-parser.jay" { - var parameters = new List (); - parameters.Add ((DocumentationParameter) yyVals[0+yyTop]); - yyVal = parameters; - } + Linq.AQueryClause head = (Linq.AQueryClause)yyVals[0+yyTop]; -void case_981() -#line 6636 "cs-parser.jay" -{ - var parameters = yyVals[-2+yyTop] as List; - parameters.Add ((DocumentationParameter) yyVals[0+yyTop]); - yyVal = parameters; - } + if (yyVals[-1+yyTop] != null) { + Linq.AQueryClause clause = (Linq.AQueryClause)yyVals[-1+yyTop]; + clause.Tail.Next = head; + head = clause; + } + + yyVal = head; + } + +void case_975() +#line 6589 "cs-parser.jay" +{ + report.Error (742, GetLocation (yyVals[0+yyTop]), "Unexpected symbol `{0}'. A query body must end with select or group clause", GetSymbolName (yyToken)); + yyVal = yyVals[-1+yyTop]; + } + +void case_976() +#line 6594 "cs-parser.jay" +{ + Error_SyntaxError (yyToken); + yyVal = null; + } + +void case_978() +#line 6606 "cs-parser.jay" +{ + yyVal = new Linq.Select ((Linq.QueryBlock)current_block, (Expression)yyVals[0+yyTop], GetLocation (yyVals[-2+yyTop])); -void case_982() + current_block.SetEndLocation (lexer.Location); + current_block = current_block.Parent; + } + +void case_979() +#line 6613 "cs-parser.jay" +{ + if (linq_clause_blocks == null) + linq_clause_blocks = new Stack (); + + current_block = new Linq.QueryBlock (current_block, lexer.Location); + linq_clause_blocks.Push ((Linq.QueryBlock)current_block); + } + +void case_980() +#line 6621 "cs-parser.jay" +{ + current_block.SetEndLocation (lexer.Location); + current_block = current_block.Parent; + + current_block = new Linq.QueryBlock (current_block, lexer.Location); + } + +void case_981() +#line 6628 "cs-parser.jay" +{ + var obj = (object[]) yyVals[0+yyTop]; + + yyVal = new Linq.GroupBy ((Linq.QueryBlock)current_block, (Expression)yyVals[-2+yyTop], linq_clause_blocks.Pop (), (Expression)obj[0], GetLocation (yyVals[-4+yyTop])); + lbag.AddLocation (yyVal, (Location) obj[1]); + + current_block.SetEndLocation (lexer.Location); + current_block = current_block.Parent; + } + +void case_983() #line 6645 "cs-parser.jay" +{ + Error_SyntaxError (yyToken); + yyVal = new object[2] { null, Location.Null }; + } + +void case_985() +#line 6654 "cs-parser.jay" +{ + ((Linq.AQueryClause)yyVals[-1+yyTop]).Tail.Next = (Linq.AQueryClause)yyVals[0+yyTop]; + yyVal = yyVals[-1+yyTop]; + } + +void case_992() +#line 6674 "cs-parser.jay" +{ + var lt = (LocatedToken) yyVals[-3+yyTop]; + var sn = new Linq.RangeVariable (lt.Value, lt.Location); + yyVal = new Linq.Let ((Linq.QueryBlock) current_block, sn, (Expression)yyVals[0+yyTop], GetLocation (yyVals[-4+yyTop])); + lbag.AddLocation (yyVal, GetLocation (yyVals[-2+yyTop])); + + current_block.SetEndLocation (lexer.Location); + current_block = current_block.Parent; + + ((Linq.QueryBlock)current_block).AddRangeVariable (sn); + } + +void case_994() +#line 6693 "cs-parser.jay" +{ + yyVal = new Linq.Where ((Linq.QueryBlock)current_block, (Expression)yyVals[0+yyTop], GetLocation (yyVals[-2+yyTop])); + + current_block.SetEndLocation (lexer.Location); + current_block = current_block.Parent; + } + +void case_995() +#line 6703 "cs-parser.jay" +{ + if (linq_clause_blocks == null) + linq_clause_blocks = new Stack (); + + current_block = new Linq.QueryBlock (current_block, lexer.Location); + linq_clause_blocks.Push ((Linq.QueryBlock) current_block); + } + +void case_996() +#line 6711 "cs-parser.jay" +{ + current_block.SetEndLocation (lexer.Location); + current_block = current_block.Parent; + + current_block = new Linq.QueryBlock (current_block, lexer.Location); + linq_clause_blocks.Push ((Linq.QueryBlock) current_block); + } + +void case_997() +#line 6719 "cs-parser.jay" +{ + current_block.AddStatement (new ContextualReturn ((Expression) yyVals[-1+yyTop])); + current_block.SetEndLocation (lexer.Location); + current_block = current_block.Parent; + + current_block = new Linq.QueryBlock (current_block, lexer.Location); + } + +void case_998() +#line 6727 "cs-parser.jay" +{ + current_block.AddStatement (new ContextualReturn ((Expression) yyVals[-1+yyTop])); + current_block.SetEndLocation (lexer.Location); + + var outer_selector = linq_clause_blocks.Pop (); + var block = linq_clause_blocks.Pop (); + + var lt = (LocatedToken) yyVals[-10+yyTop]; + var sn = new Linq.RangeVariable (lt.Value, lt.Location); + Linq.RangeVariable into; + + if (yyVals[0+yyTop] == null) { + into = sn; + yyVal = new Linq.Join (block, sn, (Expression)yyVals[-7+yyTop], outer_selector, (Linq.QueryBlock) current_block, GetLocation (yyVals[-11+yyTop])); + lbag.AddLocation (yyVal, GetLocation (yyVals[-9+yyTop]), GetLocation (yyVals[-6+yyTop]), GetLocation (yyVals[-3+yyTop])); + } else { + /**/ + /* Set equals right side parent to beginning of linq query, it is not accessible therefore cannot cause name collisions*/ + /**/ + var parent = block.Parent; + while (parent is Linq.QueryBlock) { + parent = parent.Parent; + } + current_block.Parent = parent; + + ((Linq.QueryBlock)current_block).AddRangeVariable (sn); + + lt = (LocatedToken) yyVals[0+yyTop]; + into = new Linq.RangeVariable (lt.Value, lt.Location); + + yyVal = new Linq.GroupJoin (block, sn, (Expression)yyVals[-7+yyTop], outer_selector, (Linq.QueryBlock) current_block, into, GetLocation (yyVals[-11+yyTop])); + lbag.AddLocation (yyVal, GetLocation (yyVals[-9+yyTop]), GetLocation (yyVals[-6+yyTop]), GetLocation (yyVals[-3+yyTop]), opt_intoStack.Pop ()); + } + + current_block = block.Parent; + ((Linq.QueryBlock)current_block).AddRangeVariable (into); + } + +void case_999() +#line 6765 "cs-parser.jay" +{ + if (linq_clause_blocks == null) + linq_clause_blocks = new Stack (); + + current_block = new Linq.QueryBlock (current_block, lexer.Location); + linq_clause_blocks.Push ((Linq.QueryBlock) current_block); + } + +void case_1000() +#line 6773 "cs-parser.jay" +{ + current_block.SetEndLocation (lexer.Location); + current_block = current_block.Parent; + + current_block = new Linq.QueryBlock (current_block, lexer.Location); + linq_clause_blocks.Push ((Linq.QueryBlock) current_block); + } + +void case_1001() +#line 6781 "cs-parser.jay" +{ + current_block.AddStatement (new ContextualReturn ((Expression) yyVals[-1+yyTop])); + current_block.SetEndLocation (lexer.Location); + current_block = current_block.Parent; + + current_block = new Linq.QueryBlock (current_block, lexer.Location); + } + +void case_1002() +#line 6789 "cs-parser.jay" +{ + current_block.AddStatement (new ContextualReturn ((Expression) yyVals[-1+yyTop])); + current_block.SetEndLocation (lexer.Location); + + var outer_selector = linq_clause_blocks.Pop (); + var block = linq_clause_blocks.Pop (); + + var lt = (LocatedToken) yyVals[-10+yyTop]; + var sn = new Linq.RangeVariable (lt.Value, lt.Location); + Linq.RangeVariable into; + + if (yyVals[0+yyTop] == null) { + into = sn; + yyVal = new Linq.Join (block, sn, (Expression)yyVals[-7+yyTop], outer_selector, (Linq.QueryBlock) current_block, GetLocation (yyVals[-12+yyTop])) { + IdentifierType = (FullNamedExpression)yyVals[-11+yyTop] + }; + lbag.AddLocation (yyVal, GetLocation (yyVals[-10+yyTop]), GetLocation (yyVals[-7+yyTop]), GetLocation (yyVals[-4+yyTop])); + } else { + /**/ + /* Set equals right side parent to beginning of linq query, it is not accessible therefore cannot cause name collisions*/ + /**/ + var parent = block.Parent; + while (parent is Linq.QueryBlock) { + parent = parent.Parent; + } + current_block.Parent = parent; + + ((Linq.QueryBlock)current_block).AddRangeVariable (sn); + + lt = (LocatedToken) yyVals[0+yyTop]; + into = new Linq.RangeVariable (lt.Value, lt.Location); /* TODO:*/ + + yyVal = new Linq.GroupJoin (block, sn, (Expression)yyVals[-7+yyTop], outer_selector, (Linq.QueryBlock) current_block, into, GetLocation (yyVals[-12+yyTop])) { + IdentifierType = (FullNamedExpression)yyVals[-11+yyTop] + }; + lbag.AddLocation (yyVal, GetLocation (yyVals[-10+yyTop]), GetLocation (yyVals[-7+yyTop]), GetLocation (yyVals[-4+yyTop]), opt_intoStack.Pop ()); + } + + current_block = block.Parent; + ((Linq.QueryBlock)current_block).AddRangeVariable (into); + } + +void case_1004() +#line 6835 "cs-parser.jay" +{ + opt_intoStack.Push (GetLocation (yyVals[-1+yyTop])); + yyVal = yyVals[0+yyTop]; + } + +void case_1005() +#line 6843 "cs-parser.jay" +{ + current_block = new Linq.QueryBlock (current_block, lexer.Location); + lbag.AddLocation (current_block, GetLocation (yyVals[0+yyTop])); + } + +void case_1006() +#line 6848 "cs-parser.jay" +{ + current_block.SetEndLocation (lexer.Location); + current_block = current_block.Parent; + + yyVal = yyVals[0+yyTop]; + } + +void case_1008() +#line 6859 "cs-parser.jay" +{ + current_block.SetEndLocation (lexer.Location); + current_block = current_block.Parent; + + current_block = new Linq.QueryBlock (current_block, lexer.Location); + } + +void case_1009() +#line 6866 "cs-parser.jay" +{ + ((Linq.AQueryClause)yyVals[-3+yyTop]).Next = (Linq.AQueryClause)yyVals[0+yyTop]; + yyVal = yyVals[-3+yyTop]; + } + +void case_1011() +#line 6875 "cs-parser.jay" +{ + current_block.SetEndLocation (lexer.Location); + current_block = current_block.Parent; + + current_block = new Linq.QueryBlock ((Linq.QueryBlock) current_block, lexer.Location); + } + +void case_1012() +#line 6882 "cs-parser.jay" +{ + ((Linq.AQueryClause)yyVals[-3+yyTop]).Tail.Next = (Linq.AQueryClause)yyVals[0+yyTop]; + yyVal = yyVals[-3+yyTop]; + } + +void case_1014() +#line 6894 "cs-parser.jay" +{ + yyVal = new Linq.OrderByAscending ((Linq.QueryBlock) current_block, (Expression)yyVals[-1+yyTop]); + lbag.AddLocation (yyVal, GetLocation (yyVals[0+yyTop])); + } + +void case_1015() +#line 6899 "cs-parser.jay" +{ + yyVal = new Linq.OrderByDescending ((Linq.QueryBlock) current_block, (Expression)yyVals[-1+yyTop]); + lbag.AddLocation (yyVal, GetLocation (yyVals[0+yyTop])); + } + +void case_1017() +#line 6911 "cs-parser.jay" +{ + yyVal = new Linq.ThenByAscending ((Linq.QueryBlock) current_block, (Expression)yyVals[-1+yyTop]); + lbag.AddLocation (yyVal, GetLocation (yyVals[0+yyTop])); + } + +void case_1018() +#line 6916 "cs-parser.jay" +{ + yyVal = new Linq.ThenByDescending ((Linq.QueryBlock) current_block, (Expression)yyVals[-1+yyTop]); + lbag.AddLocation (yyVal, GetLocation (yyVals[0+yyTop])); + } + +void case_1020() +#line 6926 "cs-parser.jay" +{ + /* query continuation block is not linked with query block but with block*/ + /* before. This means each query can use same range variable names for*/ + /* different identifiers.*/ + + current_block.SetEndLocation (GetLocation (yyVals[-1+yyTop])); + current_block = current_block.Parent; + + current_block = new Linq.QueryBlock (current_block, lexer.Location); + + if (linq_clause_blocks == null) + linq_clause_blocks = new Stack (); + + linq_clause_blocks.Push ((Linq.QueryBlock) current_block); + } + +void case_1021() +#line 6942 "cs-parser.jay" +{ + var current_block = linq_clause_blocks.Pop (); + var lt = (LocatedToken) yyVals[-2+yyTop]; + var rv = new Linq.RangeVariable (lt.Value, lt.Location); + yyVal = new Linq.QueryStartClause ((Linq.QueryBlock)current_block, null, rv, GetLocation (yyVals[-3+yyTop])) { + next = (Linq.AQueryClause)yyVals[0+yyTop] + }; + } + +void case_1024() +#line 6969 "cs-parser.jay" +{ + current_container = current_type = new Class (current_container, new MemberName (""), Modifiers.PUBLIC, null); + + /* (ref object retval)*/ + Parameter [] mpar = new Parameter [1]; + mpar [0] = new Parameter (new TypeExpression (compiler.BuiltinTypes.Object, Location.Null), "$retval", Parameter.Modifier.REF, null, Location.Null); + + ParametersCompiled pars = new ParametersCompiled (mpar); + var mods = Modifiers.PUBLIC | Modifiers.STATIC; + if (settings.Unsafe) + mods |= Modifiers.UNSAFE; + + current_local_parameters = pars; + var method = new InteractiveMethod ( + current_type, + new TypeExpression (compiler.BuiltinTypes.Void, Location.Null), + mods, + pars); + + current_type.AddMember (method); + oob_stack.Push (method); + + interactive_async = false; + + ++lexer.parsing_block; + start_block (lexer.Location); + } + +void case_1025() +#line 6997 "cs-parser.jay" +{ + --lexer.parsing_block; + var method = (InteractiveMethod) oob_stack.Pop (); + method.Block = (ToplevelBlock) end_block(lexer.Location); + + if (interactive_async == true) { + method.ChangeToAsync (); + } + + InteractiveResult = (Class) pop_current_class (); + current_local_parameters = null; + } + +void case_1035() +#line 7043 "cs-parser.jay" +{ + module.DocumentationBuilder.ParsedBuiltinType = (TypeExpression)yyVals[-1+yyTop]; + module.DocumentationBuilder.ParsedParameters = (List)yyVals[0+yyTop]; + yyVal = null; + } + +void case_1036() +#line 7049 "cs-parser.jay" +{ + module.DocumentationBuilder.ParsedBuiltinType = new TypeExpression (compiler.BuiltinTypes.Void, GetLocation (yyVals[-1+yyTop])); + module.DocumentationBuilder.ParsedParameters = (List)yyVals[0+yyTop]; + yyVal = null; + } + +void case_1037() +#line 7055 "cs-parser.jay" +{ + module.DocumentationBuilder.ParsedBuiltinType = (TypeExpression)yyVals[-3+yyTop]; + module.DocumentationBuilder.ParsedParameters = (List)yyVals[0+yyTop]; + var lt = (LocatedToken) yyVals[-1+yyTop]; + yyVal = new MemberName (lt.Value); + } + +void case_1040() +#line 7070 "cs-parser.jay" +{ + module.DocumentationBuilder.ParsedParameters = (List)yyVals[-1+yyTop]; + yyVal = new MemberName ((MemberName) yyVals[-6+yyTop], MemberCache.IndexerNameAlias, Location.Null); + } + +void case_1041() +#line 7075 "cs-parser.jay" +{ + var p = (List)yyVals[0+yyTop] ?? new List (1); + p.Add (new DocumentationParameter ((FullNamedExpression) yyVals[-1+yyTop])); + module.DocumentationBuilder.ParsedParameters = p; + module.DocumentationBuilder.ParsedOperator = Operator.OpType.Explicit; + yyVal = null; + } + +void case_1042() +#line 7083 "cs-parser.jay" +{ + var p = (List)yyVals[0+yyTop] ?? new List (1); + p.Add (new DocumentationParameter ((FullNamedExpression) yyVals[-1+yyTop])); + module.DocumentationBuilder.ParsedParameters = p; + module.DocumentationBuilder.ParsedOperator = Operator.OpType.Implicit; + yyVal = null; + } + +void case_1043() +#line 7091 "cs-parser.jay" +{ + var p = (List)yyVals[0+yyTop]; + module.DocumentationBuilder.ParsedParameters = p; + module.DocumentationBuilder.ParsedOperator = (Operator.OpType) yyVals[-1+yyTop]; + yyVal = null; + } + +void case_1051() +#line 7129 "cs-parser.jay" +{ + var parameters = new List (); + parameters.Add ((DocumentationParameter) yyVals[0+yyTop]); + yyVal = parameters; + } + +void case_1052() +#line 7135 "cs-parser.jay" +{ + var parameters = yyVals[-2+yyTop] as List; + parameters.Add ((DocumentationParameter) yyVals[0+yyTop]); + yyVal = parameters; + } + +void case_1053() +#line 7144 "cs-parser.jay" { if (yyVals[-1+yyTop] != null) yyVal = new DocumentationParameter ((Parameter.Modifier) yyVals[-1+yyTop], (FullNamedExpression) yyVals[0+yyTop]); @@ -9318,136 +10148,144 @@ void case_982() static readonly short [] yyLhs = { -1, 0, 4, 0, 0, 1, 1, 1, 1, 2, 2, 11, 11, 12, 12, 13, 13, 14, 15, 15, 15, - 19, 20, 17, 18, 18, 18, 22, 22, 23, 23, - 7, 7, 6, 6, 21, 21, 8, 8, 24, 24, - 24, 25, 25, 25, 25, 25, 9, 9, 10, 10, - 33, 31, 36, 32, 32, 34, 34, 34, 34, 35, - 35, 40, 37, 38, 39, 39, 41, 41, 41, 41, - 41, 42, 42, 46, 43, 45, 48, 48, 48, 49, - 49, 50, 50, 51, 51, 51, 51, 51, 51, 51, - 51, 51, 51, 51, 51, 65, 67, 69, 70, 71, - 27, 27, 74, 52, 75, 75, 76, 76, 77, 79, - 73, 73, 78, 78, 84, 53, 88, 53, 53, 83, - 91, 83, 85, 85, 92, 92, 93, 94, 93, 89, - 89, 95, 95, 96, 97, 87, 87, 90, 90, 90, - 100, 54, 103, 104, 98, 105, 106, 107, 98, 98, - 98, 99, 99, 102, 102, 110, 110, 110, 110, 110, - 110, 110, 110, 110, 110, 111, 111, 114, 114, 114, - 114, 117, 114, 115, 115, 118, 118, 119, 119, 119, - 112, 112, 112, 120, 120, 120, 113, 122, 124, 125, - 55, 127, 128, 129, 57, 123, 123, 123, 123, 123, - 133, 130, 134, 131, 132, 132, 132, 135, 136, 137, - 139, 28, 28, 138, 138, 140, 140, 141, 141, 141, - 141, 141, 141, 141, 141, 141, 144, 58, 143, 143, - 145, 145, 148, 142, 142, 147, 147, 147, 147, 147, - 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, - 147, 147, 147, 147, 147, 147, 147, 150, 149, 151, - 149, 149, 149, 59, 154, 156, 152, 153, 153, 155, - 155, 160, 158, 161, 158, 158, 158, 162, 60, 164, - 56, 167, 168, 56, 163, 170, 163, 165, 165, 171, - 171, 172, 173, 172, 174, 169, 166, 166, 166, 166, - 166, 178, 175, 179, 176, 177, 177, 61, 181, 183, - 184, 29, 180, 180, 180, 182, 182, 182, 185, 185, - 186, 187, 186, 186, 186, 188, 189, 190, 30, 191, - 191, 16, 16, 192, 192, 195, 194, 194, 194, 196, - 196, 198, 64, 121, 101, 101, 126, 126, 199, 199, - 199, 197, 197, 200, 200, 201, 201, 203, 203, 82, - 72, 72, 86, 86, 116, 116, 146, 146, 204, 204, - 204, 204, 204, 208, 208, 209, 207, 207, 207, 207, - 207, 207, 207, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 211, 211, 211, 211, 211, 211, 211, 211, - 211, 211, 211, 211, 211, 211, 211, 211, 211, 211, - 211, 211, 212, 212, 212, 213, 213, 213, 233, 233, - 234, 234, 235, 235, 215, 215, 232, 232, 232, 232, - 232, 232, 232, 232, 217, 217, 237, 237, 238, 238, - 239, 239, 241, 241, 241, 242, 242, 242, 242, 242, - 243, 243, 159, 159, 236, 236, 236, 236, 236, 248, - 248, 247, 247, 249, 249, 249, 249, 250, 218, 218, - 218, 246, 246, 246, 251, 251, 252, 252, 219, 220, - 220, 221, 222, 223, 223, 214, 214, 214, 214, 214, - 257, 253, 224, 258, 258, 259, 259, 260, 260, 261, - 261, 261, 261, 254, 254, 205, 205, 256, 256, 262, - 262, 255, 255, 81, 81, 263, 263, 264, 225, 265, - 265, 265, 266, 266, 266, 266, 266, 267, 193, 226, - 227, 228, 229, 269, 230, 270, 230, 268, 268, 272, - 271, 216, 273, 273, 273, 273, 273, 274, 274, 274, - 274, 274, 274, 274, 275, 275, 275, 275, 276, 276, - 276, 276, 276, 277, 277, 277, 278, 278, 278, 278, - 278, 279, 279, 279, 280, 280, 281, 281, 282, 282, - 283, 283, 284, 284, 285, 285, 286, 286, 286, 288, - 288, 288, 288, 288, 288, 288, 288, 288, 288, 288, - 289, 289, 290, 290, 290, 291, 291, 292, 292, 294, - 293, 287, 287, 296, 295, 297, 295, 298, 299, 295, - 300, 301, 295, 44, 44, 244, 244, 244, 244, 231, - 231, 231, 80, 303, 304, 305, 306, 307, 26, 63, - 63, 62, 62, 108, 108, 308, 308, 308, 308, 308, - 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, - 66, 66, 66, 68, 68, 309, 309, 310, 310, 311, - 311, 312, 312, 312, 312, 202, 202, 313, 313, 315, - 109, 316, 316, 317, 157, 157, 314, 314, 318, 318, - 319, 319, 319, 319, 319, 323, 323, 324, 324, 324, - 321, 321, 321, 321, 321, 321, 321, 321, 321, 321, - 321, 321, 321, 325, 325, 325, 325, 325, 325, 325, - 325, 325, 325, 325, 325, 325, 339, 339, 339, 339, - 326, 340, 322, 341, 341, 342, 342, 342, 342, 342, - 342, 206, 206, 343, 47, 47, 345, 320, 349, 320, - 347, 347, 344, 344, 344, 344, 346, 346, 353, 353, - 352, 352, 354, 354, 348, 348, 350, 350, 355, 355, - 356, 351, 351, 351, 327, 327, 327, 338, 338, 357, - 358, 358, 328, 328, 359, 359, 359, 362, 360, 360, - 361, 361, 363, 363, 363, 366, 364, 365, 365, 367, - 367, 367, 329, 329, 329, 329, 368, 368, 369, 369, - 369, 373, 370, 376, 372, 372, 379, 375, 375, 378, - 378, 374, 374, 382, 381, 381, 377, 377, 380, 380, - 384, 383, 383, 371, 371, 385, 371, 371, 371, 330, - 330, 330, 330, 330, 330, 386, 387, 387, 388, 388, - 388, 389, 389, 389, 390, 390, 391, 391, 391, 392, - 392, 331, 331, 331, 331, 393, 393, 395, 395, 394, - 396, 394, 394, 332, 333, 397, 336, 334, 334, 399, - 400, 337, 402, 403, 335, 335, 335, 401, 401, 398, - 398, 302, 302, 302, 302, 404, 404, 406, 406, 408, - 407, 409, 407, 405, 405, 405, 405, 405, 413, 411, - 414, 415, 411, 410, 410, 416, 416, 416, 416, 416, - 421, 417, 422, 418, 423, 424, 425, 419, 427, 428, - 429, 419, 426, 426, 431, 420, 430, 434, 430, 433, - 436, 433, 432, 432, 432, 435, 435, 435, 412, 437, - 412, 3, 3, 438, 3, 3, 439, 439, 245, 245, - 240, 240, 5, 440, 440, 440, 440, 444, 440, 440, - 440, 440, 441, 441, 442, 445, 442, 443, 443, 446, - 446, 447, + 19, 20, 17, 17, 22, 22, 22, 18, 18, 18, + 23, 23, 24, 24, 7, 7, 6, 6, 21, 21, + 8, 8, 25, 25, 25, 26, 26, 26, 26, 26, + 9, 9, 10, 10, 34, 32, 37, 33, 33, 33, + 33, 35, 35, 35, 36, 36, 41, 38, 39, 40, + 40, 42, 42, 42, 42, 42, 43, 43, 43, 47, + 44, 46, 49, 49, 49, 51, 51, 52, 52, 53, + 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, + 53, 53, 68, 70, 73, 74, 75, 28, 28, 78, + 54, 54, 79, 79, 80, 80, 81, 83, 77, 77, + 82, 82, 88, 55, 92, 55, 55, 87, 95, 87, + 89, 89, 96, 96, 97, 98, 97, 93, 93, 99, + 99, 100, 101, 91, 91, 94, 94, 94, 104, 56, + 107, 108, 102, 109, 110, 111, 102, 102, 102, 103, + 103, 106, 106, 114, 114, 114, 114, 114, 114, 114, + 114, 114, 114, 115, 115, 118, 118, 118, 118, 121, + 118, 119, 119, 122, 122, 123, 123, 123, 116, 116, + 116, 124, 124, 124, 117, 126, 128, 129, 57, 131, + 132, 133, 59, 127, 127, 127, 127, 127, 137, 134, + 138, 135, 136, 136, 136, 139, 140, 141, 143, 29, + 29, 142, 142, 144, 144, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 148, 60, 147, 147, 149, 149, + 152, 146, 146, 151, 151, 151, 151, 151, 151, 151, + 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, + 151, 151, 151, 151, 151, 154, 153, 155, 153, 153, + 153, 61, 158, 160, 156, 157, 157, 159, 159, 164, + 162, 165, 162, 162, 162, 166, 62, 168, 58, 171, + 172, 58, 58, 167, 174, 167, 169, 169, 175, 175, + 176, 177, 176, 178, 173, 170, 170, 170, 170, 170, + 182, 179, 183, 180, 181, 181, 63, 64, 185, 187, + 188, 30, 184, 184, 184, 186, 186, 186, 189, 189, + 190, 191, 190, 190, 190, 192, 193, 194, 31, 195, + 195, 16, 16, 196, 196, 199, 198, 198, 198, 200, + 200, 202, 67, 125, 105, 105, 130, 130, 203, 203, + 203, 201, 201, 204, 204, 205, 205, 207, 207, 86, + 76, 76, 90, 90, 120, 120, 150, 150, 208, 208, + 208, 208, 208, 212, 212, 213, 211, 211, 211, 211, + 211, 211, 211, 214, 214, 214, 214, 214, 214, 214, + 214, 214, 215, 215, 215, 215, 215, 215, 215, 215, + 215, 215, 215, 215, 215, 215, 215, 215, 215, 215, + 215, 215, 216, 216, 216, 217, 217, 217, 237, 237, + 238, 238, 239, 239, 219, 219, 236, 236, 236, 236, + 236, 236, 236, 236, 236, 221, 221, 221, 241, 241, + 242, 242, 243, 243, 245, 245, 245, 246, 246, 246, + 246, 246, 246, 247, 247, 163, 163, 240, 240, 240, + 240, 240, 252, 252, 251, 251, 253, 253, 253, 253, + 254, 222, 222, 222, 250, 250, 255, 255, 256, 256, + 223, 224, 224, 225, 226, 227, 227, 218, 218, 218, + 218, 218, 261, 257, 228, 228, 262, 262, 263, 263, + 264, 264, 264, 264, 265, 265, 265, 265, 258, 258, + 209, 209, 260, 260, 266, 266, 259, 259, 85, 85, + 267, 267, 268, 229, 269, 269, 269, 270, 270, 270, + 270, 270, 271, 197, 230, 230, 231, 231, 232, 232, + 233, 273, 234, 274, 234, 272, 272, 276, 275, 220, + 277, 277, 277, 277, 277, 277, 277, 277, 277, 278, + 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, + 278, 278, 279, 279, 279, 279, 279, 279, 279, 280, + 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, + 281, 281, 281, 281, 281, 282, 282, 282, 282, 282, + 282, 282, 282, 282, 283, 283, 283, 283, 283, 284, + 284, 284, 285, 285, 285, 286, 286, 286, 287, 287, + 287, 288, 288, 288, 289, 289, 290, 290, 290, 290, + 290, 291, 291, 291, 291, 291, 291, 291, 291, 291, + 291, 291, 292, 292, 293, 293, 293, 293, 294, 294, + 296, 295, 295, 295, 50, 50, 298, 297, 299, 297, + 300, 297, 301, 302, 297, 303, 304, 297, 45, 45, + 248, 248, 248, 248, 235, 235, 235, 84, 306, 69, + 69, 307, 308, 308, 308, 310, 308, 311, 312, 313, + 314, 27, 66, 66, 65, 65, 112, 112, 315, 315, + 315, 315, 315, 315, 315, 315, 315, 315, 315, 315, + 315, 315, 315, 71, 71, 309, 309, 72, 72, 316, + 316, 317, 317, 318, 318, 319, 319, 319, 319, 206, + 206, 320, 320, 322, 113, 323, 323, 324, 161, 161, + 326, 325, 321, 321, 327, 327, 328, 328, 328, 328, + 328, 332, 332, 333, 333, 333, 330, 330, 330, 330, + 330, 330, 330, 330, 330, 330, 330, 330, 330, 334, + 334, 334, 334, 334, 334, 334, 334, 334, 334, 334, + 334, 334, 348, 348, 348, 348, 335, 349, 331, 350, + 350, 351, 351, 351, 351, 351, 351, 210, 210, 352, + 48, 48, 354, 329, 358, 329, 356, 356, 353, 353, + 353, 355, 355, 362, 362, 361, 361, 363, 363, 357, + 357, 359, 359, 364, 364, 365, 360, 360, 360, 336, + 336, 336, 347, 347, 366, 367, 367, 337, 337, 368, + 368, 368, 371, 369, 369, 370, 370, 372, 372, 372, + 373, 374, 374, 375, 375, 375, 338, 338, 338, 338, + 376, 376, 377, 377, 377, 381, 378, 384, 380, 380, + 387, 383, 383, 386, 386, 382, 382, 390, 389, 389, + 385, 385, 388, 388, 392, 391, 391, 379, 379, 393, + 379, 379, 379, 339, 339, 339, 339, 339, 339, 394, + 395, 395, 396, 396, 396, 397, 397, 397, 398, 398, + 398, 399, 399, 399, 400, 400, 340, 340, 340, 340, + 401, 401, 403, 403, 402, 405, 402, 402, 402, 404, + 404, 341, 342, 406, 345, 343, 343, 408, 409, 346, + 411, 412, 344, 344, 344, 410, 410, 407, 407, 305, + 305, 305, 305, 413, 413, 415, 415, 417, 416, 418, + 416, 414, 414, 414, 414, 414, 422, 420, 423, 425, + 420, 424, 424, 419, 419, 426, 426, 426, 426, 426, + 431, 427, 432, 428, 433, 434, 435, 429, 437, 438, + 439, 429, 436, 436, 441, 430, 440, 444, 440, 443, + 446, 443, 442, 442, 442, 445, 445, 445, 421, 447, + 421, 3, 3, 448, 3, 3, 449, 449, 249, 249, + 244, 244, 5, 450, 450, 450, 450, 450, 454, 450, + 450, 450, 450, 451, 451, 452, 455, 452, 453, 453, + 456, 456, 457, }; static readonly short [] yyLen = { 2, 2, 0, 3, 1, 2, 4, 3, 1, 0, 1, 1, 2, 4, 2, 1, 2, 1, 3, 5, 2, - 0, 0, 11, 1, 3, 1, 0, 1, 0, 1, - 0, 1, 0, 1, 0, 1, 1, 2, 1, 1, - 2, 1, 1, 1, 1, 1, 0, 1, 1, 2, - 0, 3, 0, 6, 3, 1, 1, 1, 1, 1, - 3, 0, 3, 1, 0, 3, 0, 1, 1, 3, - 3, 1, 1, 0, 4, 4, 0, 1, 1, 0, - 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, - 16, 5, 0, 9, 0, 1, 1, 2, 3, 0, - 3, 1, 1, 1, 0, 8, 0, 9, 6, 0, - 0, 3, 0, 1, 1, 2, 2, 0, 5, 0, - 1, 1, 2, 3, 0, 4, 2, 1, 1, 1, - 0, 3, 0, 0, 10, 0, 0, 0, 12, 8, - 5, 1, 1, 0, 1, 1, 3, 3, 3, 5, - 3, 5, 1, 1, 1, 1, 3, 4, 6, 2, - 4, 0, 7, 0, 1, 1, 2, 1, 1, 1, - 4, 6, 4, 1, 2, 2, 1, 0, 0, 0, - 10, 0, 0, 0, 13, 1, 2, 1, 2, 1, - 0, 5, 0, 5, 1, 1, 1, 0, 0, 0, - 0, 15, 5, 0, 1, 1, 2, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 0, 5, 1, 1, - 1, 1, 0, 7, 1, 1, 1, 1, 1, 1, + 0, 0, 11, 3, 0, 1, 1, 1, 3, 1, + 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, + 1, 2, 1, 1, 2, 1, 1, 1, 1, 1, + 0, 1, 1, 2, 0, 3, 0, 6, 3, 2, + 1, 1, 1, 1, 1, 3, 0, 3, 1, 0, + 3, 0, 1, 1, 3, 3, 1, 1, 1, 0, + 4, 4, 0, 1, 1, 0, 1, 1, 2, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 0, 0, 0, 0, 0, 17, 5, 0, + 9, 5, 0, 1, 1, 2, 3, 0, 3, 1, + 1, 1, 0, 8, 0, 9, 6, 0, 0, 3, + 0, 1, 1, 2, 2, 0, 5, 0, 1, 1, + 2, 3, 0, 4, 2, 1, 1, 1, 0, 3, + 0, 0, 10, 0, 0, 0, 12, 8, 5, 1, + 1, 0, 1, 1, 3, 3, 3, 5, 3, 5, + 1, 1, 1, 1, 3, 4, 6, 2, 4, 0, + 7, 0, 1, 1, 2, 1, 1, 1, 4, 6, + 4, 1, 2, 2, 1, 0, 0, 0, 10, 0, + 0, 0, 13, 1, 2, 1, 2, 1, 0, 5, + 0, 5, 1, 1, 1, 0, 0, 0, 0, 15, + 5, 0, 1, 1, 2, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 0, 5, 1, 1, 1, 1, + 0, 7, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 0, 7, 0, - 7, 2, 2, 2, 0, 0, 9, 1, 1, 0, - 1, 0, 6, 0, 6, 2, 1, 0, 8, 0, - 9, 0, 0, 10, 0, 0, 3, 0, 1, 1, - 2, 2, 0, 5, 0, 2, 2, 2, 1, 1, - 1, 0, 5, 0, 5, 1, 1, 2, 0, 0, + 1, 1, 1, 1, 1, 0, 7, 0, 7, 2, + 2, 2, 0, 0, 9, 1, 1, 0, 1, 0, + 6, 0, 6, 2, 1, 0, 8, 0, 9, 0, + 0, 10, 5, 0, 0, 3, 0, 1, 1, 2, + 2, 0, 5, 0, 2, 2, 2, 1, 1, 1, + 0, 5, 0, 5, 1, 1, 2, 4, 0, 0, 0, 12, 0, 2, 2, 0, 1, 2, 1, 3, 2, 0, 5, 3, 1, 0, 0, 0, 13, 0, 1, 1, 3, 1, 4, 2, 0, 3, 2, 1, @@ -9459,2200 +10297,2716 @@ void case_982() 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 3, 3, 4, 4, 4, 3, - 3, 4, 3, 4, 4, 4, 0, 1, 3, 4, - 0, 1, 1, 3, 2, 3, 1, 2, 3, 2, - 1, 1, 0, 1, 1, 3, 3, 3, 2, 1, - 1, 1, 1, 2, 2, 4, 3, 1, 4, 4, - 3, 1, 3, 2, 1, 3, 1, 1, 1, 4, - 3, 2, 2, 6, 3, 7, 4, 3, 7, 3, - 0, 2, 4, 1, 2, 0, 1, 1, 3, 3, - 1, 1, 1, 0, 1, 1, 2, 2, 3, 1, - 2, 0, 1, 2, 4, 1, 3, 0, 5, 1, - 1, 1, 2, 3, 3, 4, 4, 1, 2, 4, - 4, 4, 4, 0, 4, 0, 5, 0, 1, 0, - 4, 4, 1, 2, 2, 4, 2, 1, 2, 2, - 2, 2, 2, 2, 1, 3, 3, 3, 1, 3, - 3, 3, 3, 1, 3, 3, 1, 3, 3, 3, - 3, 1, 3, 3, 1, 3, 1, 3, 1, 3, - 1, 3, 1, 3, 1, 3, 1, 5, 4, 3, + 1, 1, 1, 1, 3, 3, 4, 4, 4, 4, + 3, 3, 4, 3, 4, 4, 4, 3, 0, 1, + 3, 4, 0, 1, 1, 3, 2, 3, 3, 1, + 2, 3, 2, 1, 1, 0, 1, 1, 3, 3, + 3, 2, 1, 1, 1, 1, 2, 2, 4, 3, + 1, 4, 4, 3, 1, 3, 1, 3, 1, 1, + 1, 4, 3, 2, 2, 6, 3, 7, 4, 3, + 7, 3, 0, 2, 4, 3, 1, 2, 0, 1, + 1, 3, 1, 2, 3, 1, 1, 1, 0, 1, + 1, 2, 2, 3, 1, 2, 0, 1, 2, 4, + 1, 3, 0, 5, 1, 1, 1, 2, 3, 3, + 4, 4, 1, 2, 4, 4, 4, 2, 4, 2, + 4, 0, 4, 0, 5, 0, 1, 0, 4, 4, + 1, 2, 2, 4, 2, 2, 2, 4, 2, 1, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 1, 3, 3, 3, 3, 3, 3, 1, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 1, 3, 3, 2, 1, 0, 1, 1, 1, 0, - 2, 1, 1, 0, 4, 0, 5, 0, 0, 7, - 0, 0, 8, 1, 1, 1, 1, 1, 1, 6, - 4, 4, 1, 1, 0, 0, 0, 0, 15, 0, - 1, 0, 1, 1, 2, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 0, 2, 3, 0, 1, 1, 2, 4, 3, 1, - 3, 1, 3, 1, 1, 0, 1, 1, 1, 0, - 4, 1, 1, 0, 4, 1, 0, 1, 1, 2, - 1, 1, 1, 2, 1, 1, 2, 1, 1, 1, + 1, 3, 3, 3, 3, 1, 3, 3, 3, 3, + 3, 3, 3, 3, 1, 3, 3, 3, 3, 1, + 3, 3, 1, 3, 3, 1, 3, 3, 1, 3, + 3, 1, 3, 3, 1, 3, 1, 5, 4, 5, + 5, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 1, 3, 3, 2, 1, 1, 0, 1, + 0, 2, 1, 1, 1, 1, 0, 4, 0, 4, + 0, 5, 0, 0, 7, 0, 0, 8, 1, 1, + 1, 1, 1, 1, 6, 4, 4, 1, 1, 0, + 1, 3, 0, 1, 1, 0, 6, 0, 0, 0, + 0, 15, 0, 1, 0, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 0, 1, 2, 3, 0, 1, 1, + 2, 4, 3, 1, 3, 1, 3, 1, 1, 0, + 1, 1, 1, 0, 4, 1, 1, 0, 4, 1, + 0, 4, 0, 1, 1, 2, 1, 1, 1, 2, + 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 0, 4, 1, 2, 2, 2, 2, 2, 2, - 1, 1, 2, 1, 1, 1, 0, 6, 0, 7, - 1, 1, 0, 2, 2, 1, 0, 1, 0, 1, - 1, 2, 2, 4, 0, 2, 0, 1, 1, 2, - 4, 1, 5, 2, 2, 2, 2, 2, 2, 1, - 1, 1, 1, 1, 5, 7, 4, 0, 8, 4, - 0, 1, 1, 2, 1, 0, 3, 1, 2, 3, - 3, 1, 1, 1, 1, 1, 5, 4, 7, 3, - 6, 0, 4, 0, 4, 2, 0, 4, 2, 3, - 1, 0, 1, 0, 5, 1, 0, 1, 0, 1, - 1, 1, 3, 4, 5, 0, 9, 5, 4, 1, - 1, 1, 1, 1, 1, 2, 2, 2, 3, 4, - 3, 3, 3, 2, 3, 2, 4, 4, 3, 0, - 1, 3, 4, 5, 3, 1, 2, 0, 1, 2, - 0, 7, 3, 2, 2, 0, 3, 5, 4, 0, - 0, 10, 0, 0, 9, 5, 4, 2, 1, 0, - 2, 2, 2, 2, 2, 4, 5, 4, 5, 0, - 5, 0, 6, 3, 2, 2, 2, 1, 0, 3, - 0, 0, 6, 1, 2, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 0, 4, 1, + 2, 2, 2, 2, 2, 2, 1, 1, 2, 1, + 1, 1, 0, 6, 0, 7, 1, 1, 0, 2, + 1, 0, 1, 0, 1, 1, 2, 2, 4, 0, + 2, 0, 1, 1, 2, 4, 1, 5, 2, 2, + 2, 2, 2, 2, 1, 1, 1, 1, 1, 5, + 7, 4, 0, 8, 4, 0, 1, 1, 2, 1, + 2, 1, 2, 3, 3, 1, 1, 1, 1, 1, + 5, 4, 7, 3, 6, 0, 4, 0, 4, 2, + 0, 4, 2, 3, 1, 0, 1, 0, 5, 1, + 0, 1, 0, 1, 1, 1, 3, 4, 5, 0, + 9, 5, 4, 1, 1, 1, 1, 1, 1, 2, + 2, 2, 3, 4, 3, 3, 3, 2, 3, 3, + 2, 4, 4, 3, 0, 1, 3, 4, 5, 3, + 1, 2, 0, 1, 3, 0, 8, 3, 6, 0, + 4, 2, 2, 0, 3, 5, 4, 0, 0, 10, + 0, 0, 9, 5, 4, 2, 1, 0, 2, 2, + 2, 2, 2, 4, 5, 4, 5, 0, 5, 0, + 6, 3, 2, 2, 2, 1, 0, 3, 0, 0, + 5, 2, 1, 1, 2, 1, 1, 1, 1, 1, 0, 5, 0, 3, 0, 0, 0, 12, 0, 0, 0, 13, 0, 2, 0, 3, 1, 0, 4, 1, 0, 4, 1, 2, 2, 1, 2, 2, 0, 0, 4, 2, 3, 0, 4, 2, 2, 3, 0, 1, - 1, 1, 2, 2, 2, 4, 3, 0, 7, 4, - 4, 3, 1, 3, 0, 0, 4, 0, 1, 1, - 3, 2, + 1, 1, 2, 2, 2, 2, 4, 3, 0, 7, + 4, 4, 3, 1, 3, 0, 0, 4, 0, 1, + 1, 3, 2, }; static readonly short [] yyDefRed = { 0, 8, 0, 0, 0, 0, 0, 0, 0, 2, 4, - 0, 0, 11, 14, 0, 952, 0, 0, 956, 0, - 0, 15, 17, 379, 385, 392, 380, 382, 0, 381, - 0, 388, 390, 377, 0, 384, 386, 378, 389, 391, - 387, 342, 973, 0, 383, 963, 0, 10, 1, 0, - 0, 0, 12, 0, 782, 0, 0, 0, 0, 0, - 0, 0, 0, 420, 0, 0, 0, 0, 0, 0, - 0, 418, 0, 0, 0, 479, 0, 419, 0, 518, - 0, 876, 0, 0, 0, 629, 0, 0, 0, 0, - 0, 0, 0, 680, 0, 731, 0, 0, 0, 0, - 0, 0, 0, 0, 417, 0, 618, 0, 781, 0, - 714, 0, 0, 0, 0, 394, 395, 396, 397, 398, - 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, - 409, 410, 411, 412, 415, 416, 625, 548, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 626, 624, 627, 628, 698, 700, 0, 696, 699, 715, - 717, 718, 719, 720, 721, 722, 723, 724, 725, 726, - 716, 0, 0, 0, 783, 784, 803, 804, 805, 806, - 840, 841, 842, 843, 844, 845, 0, 0, 0, 20, - 0, 0, 332, 0, 334, 960, 16, 953, 0, 0, - 241, 240, 237, 242, 243, 236, 255, 254, 247, 248, - 244, 246, 245, 249, 238, 239, 250, 251, 257, 256, - 252, 253, 0, 0, 976, 0, 965, 0, 964, 3, - 51, 0, 0, 0, 40, 37, 39, 42, 43, 44, - 45, 46, 49, 13, 0, 0, 0, 846, 421, 422, - 874, 0, 0, 0, 0, 0, 0, 0, 848, 847, - 0, 540, 534, 539, 730, 780, 701, 728, 727, 729, - 702, 703, 704, 705, 706, 707, 708, 709, 710, 711, - 712, 713, 0, 0, 0, 812, 0, 0, 0, 746, - 745, 0, 0, 0, 0, 0, 0, 0, 0, 854, - 0, 0, 0, 0, 393, 0, 0, 0, 856, 861, - 0, 0, 0, 875, 0, 0, 0, 744, 740, 0, - 0, 0, 0, 0, 0, 0, 361, 0, 0, 0, - 0, 0, 0, 0, 0, 621, 0, 547, 0, 0, - 545, 549, 550, 544, 554, 553, 551, 552, 614, 529, - 0, 414, 413, 0, 0, 0, 0, 0, 732, 0, - 331, 0, 738, 739, 0, 482, 483, 0, 0, 0, - 736, 737, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 955, 697, 747, 735, 0, - 778, 779, 908, 923, 0, 0, 909, 911, 0, 935, - 894, 892, 916, 0, 0, 914, 917, 918, 919, 920, - 895, 893, 0, 0, 0, 336, 0, 18, 0, 0, - 0, 972, 0, 343, 0, 0, 0, 974, 0, 0, - 38, 651, 657, 649, 0, 646, 656, 650, 648, 647, - 654, 652, 653, 659, 655, 658, 660, 0, 0, 644, - 41, 50, 481, 0, 477, 478, 0, 0, 475, 0, - 749, 0, 0, 0, 810, 0, 777, 775, 776, 0, - 0, 0, 633, 0, 851, 849, 634, 0, 0, 503, - 0, 0, 0, 494, 0, 498, 508, 510, 0, 490, - 0, 0, 0, 0, 0, 485, 0, 488, 0, 492, - 363, 853, 852, 0, 0, 855, 865, 0, 0, 0, - 866, 0, 0, 877, 0, 0, 743, 0, 373, 369, - 370, 0, 0, 368, 371, 372, 0, 0, 0, 555, - 0, 0, 536, 0, 616, 695, 0, 0, 0, 689, - 691, 692, 693, 425, 426, 0, 339, 340, 0, 179, - 178, 180, 0, 0, 0, 0, 365, 0, 601, 0, - 0, 859, 0, 0, 0, 430, 0, 433, 0, 431, - 0, 471, 0, 0, 0, 0, 0, 460, 463, 0, - 0, 455, 462, 461, 590, 591, 592, 593, 594, 595, - 596, 597, 598, 600, 599, 556, 558, 557, 562, 563, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 586, 0, 0, 507, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 907, 906, - 0, 915, 0, 905, 0, 0, 333, 970, 971, 357, - 0, 0, 0, 354, 0, 0, 176, 0, 0, 980, - 966, 968, 59, 57, 58, 0, 0, 52, 0, 0, - 60, 62, 26, 24, 0, 0, 0, 641, 0, 645, - 429, 0, 480, 0, 531, 0, 542, 165, 187, 0, - 0, 0, 155, 0, 0, 0, 166, 535, 0, 880, - 0, 832, 813, 0, 823, 0, 834, 0, 850, 787, - 0, 879, 0, 0, 493, 0, 509, 511, 0, 0, - 447, 0, 0, 443, 0, 0, 472, 0, 513, 487, - 0, 0, 140, 514, 138, 139, 516, 0, 530, 790, - 0, 870, 0, 863, 0, 867, 522, 0, 0, 0, - 358, 0, 520, 0, 0, 532, 887, 0, 883, 808, - 0, 898, 0, 896, 0, 0, 631, 632, 0, 0, - 0, 694, 682, 683, 681, 690, 609, 615, 608, 0, - 0, 338, 604, 0, 0, 0, 546, 858, 857, 733, - 434, 428, 432, 427, 533, 470, 469, 468, 465, 464, - 0, 459, 423, 424, 435, 436, 0, 589, 0, 756, - 0, 0, 613, 612, 924, 900, 0, 925, 0, 910, - 912, 921, 0, 936, 0, 904, 950, 19, 335, 679, - 678, 0, 677, 0, 353, 982, 177, 977, 0, 0, - 53, 0, 0, 0, 0, 0, 0, 360, 0, 635, - 0, 0, 79, 78, 0, 476, 0, 0, 0, 0, - 0, 170, 541, 0, 0, 0, 0, 0, 824, 816, - 814, 0, 835, 0, 0, 878, 500, 499, 450, 0, - 0, 961, 962, 439, 445, 0, 448, 0, 474, 0, - 0, 0, 0, 0, 788, 873, 0, 864, 0, 528, - 523, 0, 0, 519, 0, 886, 0, 807, 899, 897, - 0, 537, 0, 617, 611, 341, 603, 602, 619, 467, - 0, 458, 457, 456, 588, 140, 0, 772, 754, 0, - 0, 0, 761, 0, 902, 0, 929, 0, 0, 944, - 945, 938, 0, 356, 355, 981, 0, 0, 61, 55, - 0, 63, 25, 22, 0, 0, 309, 0, 213, 0, - 102, 0, 76, 766, 113, 114, 0, 0, 0, 769, - 185, 186, 0, 0, 0, 0, 158, 167, 159, 161, - 811, 0, 0, 0, 0, 0, 833, 0, 0, 449, - 451, 452, 446, 440, 444, 0, 505, 0, 473, 484, - 438, 517, 515, 0, 869, 0, 0, 0, 524, 0, - 889, 0, 0, 630, 622, 0, 466, 0, 0, 752, - 751, 748, 762, 901, 0, 0, 0, 0, 922, 0, - 951, 969, 0, 0, 0, 68, 69, 72, 73, 0, - 326, 315, 314, 0, 636, 209, 97, 0, 750, 770, - 171, 0, 183, 0, 0, 0, 809, 891, 0, 0, - 0, 0, 815, 0, 836, 786, 489, 486, 795, 0, - 802, 0, 0, 793, 0, 798, 871, 527, 526, 888, - 884, 0, 620, 0, 0, 903, 926, 0, 913, 0, - 0, 940, 0, 74, 66, 0, 0, 0, 310, 0, - 0, 0, 0, 0, 172, 0, 162, 160, 881, 825, - 819, 817, 0, 0, 789, 794, 0, 799, 0, 0, - 623, 0, 764, 0, 930, 947, 948, 941, 54, 0, - 70, 71, 0, 0, 0, 0, 0, 0, 0, 771, - 169, 0, 182, 0, 0, 837, 801, 800, 0, 684, - 686, 872, 885, 773, 0, 0, 0, 75, 0, 0, - 327, 0, 0, 325, 311, 0, 319, 376, 0, 374, - 0, 637, 0, 666, 210, 98, 173, 882, 821, 818, - 0, 0, 830, 0, 927, 0, 942, 0, 0, 0, - 308, 0, 0, 663, 0, 0, 0, 667, 0, 0, - 0, 0, 0, 931, 28, 23, 328, 324, 0, 0, - 320, 375, 669, 0, 0, 0, 99, 820, 685, 0, - 0, 0, 0, 312, 674, 0, 675, 672, 0, 670, - 95, 0, 93, 0, 0, 82, 84, 85, 86, 87, - 88, 89, 90, 91, 92, 94, 141, 0, 0, 226, - 218, 219, 220, 221, 222, 223, 224, 225, 0, 0, - 216, 0, 0, 928, 0, 329, 323, 0, 0, 0, - 638, 83, 0, 269, 264, 268, 0, 211, 217, 0, - 934, 932, 673, 671, 0, 0, 0, 0, 0, 0, - 0, 278, 0, 0, 227, 0, 0, 235, 0, 153, - 142, 152, 0, 100, 0, 0, 263, 0, 0, 262, - 0, 146, 0, 0, 347, 0, 345, 0, 0, 188, - 0, 0, 0, 0, 0, 639, 212, 0, 103, 0, - 344, 0, 0, 0, 0, 117, 0, 0, 0, 0, - 0, 0, 151, 143, 0, 0, 192, 0, 348, 0, - 230, 229, 228, 0, 101, 0, 282, 0, 260, 119, - 0, 258, 0, 0, 0, 121, 0, 349, 0, 0, - 189, 0, 0, 0, 346, 233, 112, 110, 0, 0, - 286, 0, 0, 0, 0, 0, 147, 0, 266, 0, - 0, 0, 0, 125, 0, 0, 0, 0, 350, 351, - 0, 0, 0, 0, 0, 107, 301, 0, 283, 0, - 0, 295, 0, 0, 0, 290, 0, 137, 0, 0, - 0, 0, 132, 0, 0, 279, 0, 122, 0, 116, - 126, 144, 150, 200, 0, 190, 0, 0, 0, 0, - 111, 0, 104, 108, 0, 0, 0, 297, 0, 298, - 287, 0, 0, 281, 291, 261, 0, 0, 118, 133, - 259, 0, 277, 0, 267, 271, 128, 0, 0, 0, - 197, 199, 193, 234, 109, 302, 304, 284, 0, 0, - 296, 293, 136, 134, 148, 276, 0, 0, 0, 145, - 201, 203, 191, 0, 0, 0, 295, 0, 272, 274, - 129, 0, 0, 194, 306, 307, 303, 305, 294, 149, - 0, 0, 207, 206, 205, 202, 204, 0, 0, 0, - 195, 273, 275, + 0, 0, 11, 14, 0, 1022, 0, 0, 1026, 0, + 0, 15, 17, 389, 395, 402, 390, 392, 0, 391, + 0, 398, 400, 387, 0, 394, 396, 388, 399, 401, + 397, 0, 352, 1044, 0, 393, 1033, 0, 10, 1, + 0, 0, 0, 12, 0, 847, 0, 0, 0, 0, + 0, 0, 0, 0, 430, 0, 0, 0, 0, 0, + 0, 0, 428, 0, 0, 0, 491, 0, 429, 0, + 533, 0, 944, 0, 0, 0, 684, 0, 0, 0, + 0, 0, 0, 0, 744, 0, 797, 0, 0, 0, + 0, 0, 0, 0, 0, 427, 0, 673, 0, 846, + 0, 780, 0, 0, 0, 0, 404, 405, 406, 407, + 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, + 418, 419, 420, 421, 422, 425, 426, 680, 570, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 681, 679, 682, 683, 764, 766, 0, 762, 765, + 781, 783, 784, 785, 786, 787, 788, 789, 790, 791, + 792, 782, 0, 0, 0, 848, 849, 867, 868, 869, + 870, 904, 905, 906, 907, 908, 909, 0, 0, 0, + 20, 0, 0, 342, 0, 344, 1030, 16, 1023, 0, + 0, 249, 248, 245, 250, 251, 244, 263, 262, 255, + 256, 252, 254, 253, 257, 246, 247, 258, 259, 265, + 264, 260, 261, 0, 1047, 1036, 0, 0, 1035, 0, + 1034, 3, 55, 0, 0, 0, 44, 41, 43, 46, + 47, 48, 49, 50, 53, 13, 0, 0, 0, 910, + 548, 431, 432, 942, 0, 0, 0, 0, 0, 0, + 0, 0, 912, 911, 0, 558, 552, 557, 796, 845, + 767, 794, 793, 795, 768, 769, 770, 771, 772, 773, + 774, 775, 776, 777, 778, 779, 0, 0, 0, 876, + 0, 0, 0, 812, 811, 0, 0, 0, 0, 0, + 0, 0, 0, 918, 0, 0, 0, 0, 403, 0, + 0, 0, 921, 0, 0, 0, 0, 550, 943, 0, + 0, 0, 810, 806, 0, 0, 0, 0, 0, 0, + 0, 371, 0, 0, 0, 0, 0, 0, 0, 0, + 676, 0, 569, 0, 0, 669, 0, 0, 565, 0, + 0, 567, 563, 577, 571, 578, 572, 566, 562, 582, + 576, 581, 575, 579, 573, 580, 574, 667, 544, 0, + 424, 423, 0, 0, 0, 0, 0, 798, 0, 341, + 0, 804, 805, 0, 494, 495, 0, 0, 0, 802, + 803, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1025, 763, 813, 801, 0, 843, + 844, 976, 993, 0, 0, 977, 979, 0, 1005, 962, + 960, 986, 0, 0, 984, 987, 988, 989, 990, 963, + 961, 0, 0, 0, 346, 0, 18, 0, 0, 0, + 1043, 0, 0, 353, 0, 0, 1045, 0, 0, 42, + 714, 720, 712, 0, 709, 719, 713, 711, 710, 717, + 715, 716, 722, 718, 721, 723, 0, 0, 707, 45, + 54, 493, 0, 489, 490, 0, 0, 487, 0, 815, + 0, 0, 0, 874, 0, 842, 840, 841, 0, 0, + 0, 688, 0, 915, 913, 689, 0, 0, 518, 0, + 0, 506, 513, 0, 0, 0, 507, 0, 0, 523, + 525, 0, 502, 0, 0, 0, 0, 0, 497, 0, + 500, 0, 504, 373, 917, 916, 0, 0, 920, 919, + 930, 0, 0, 0, 931, 0, 0, 945, 0, 0, + 809, 0, 383, 379, 380, 0, 0, 378, 381, 382, + 0, 0, 0, 583, 0, 0, 554, 0, 671, 600, + 599, 0, 0, 761, 0, 0, 0, 755, 757, 758, + 759, 435, 436, 0, 349, 350, 0, 187, 186, 188, + 0, 658, 0, 0, 0, 375, 0, 653, 0, 0, + 924, 0, 0, 0, 441, 0, 444, 0, 0, 442, + 0, 0, 484, 0, 448, 0, 0, 0, 0, 473, + 476, 0, 0, 468, 475, 474, 642, 643, 644, 645, + 646, 647, 648, 649, 650, 652, 651, 587, 584, 589, + 586, 588, 585, 597, 593, 598, 594, 595, 0, 596, + 0, 604, 0, 0, 605, 0, 611, 0, 612, 0, + 613, 0, 614, 0, 618, 0, 619, 0, 622, 0, + 625, 0, 628, 0, 631, 0, 634, 0, 636, 0, + 0, 522, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 975, 974, 0, 985, 0, 973, 0, 0, 343, + 1041, 1042, 0, 0, 184, 0, 0, 1051, 367, 0, + 0, 0, 364, 1037, 1039, 61, 63, 64, 0, 0, + 56, 0, 0, 65, 67, 30, 28, 0, 0, 0, + 704, 0, 708, 439, 0, 492, 0, 547, 0, 560, + 173, 195, 0, 0, 0, 163, 0, 0, 0, 174, + 553, 0, 948, 0, 896, 877, 0, 887, 0, 898, + 0, 914, 852, 0, 947, 0, 0, 505, 0, 514, + 524, 526, 0, 0, 0, 460, 0, 0, 455, 0, + 0, 666, 665, 485, 0, 528, 499, 0, 0, 148, + 529, 146, 147, 531, 0, 546, 545, 855, 0, 0, + 0, 0, 928, 0, 932, 537, 0, 0, 0, 368, + 0, 535, 0, 0, 549, 955, 0, 951, 872, 0, + 966, 0, 964, 0, 0, 686, 687, 0, 0, 0, + 664, 663, 670, 0, 440, 760, 746, 747, 745, 756, + 668, 0, 348, 656, 0, 0, 0, 568, 564, 923, + 922, 799, 445, 438, 443, 437, 551, 483, 482, 481, + 478, 477, 0, 472, 433, 434, 446, 447, 0, 639, + 0, 821, 0, 0, 994, 968, 0, 995, 0, 978, + 980, 991, 0, 1006, 0, 972, 1020, 19, 345, 1053, + 185, 1048, 0, 743, 742, 0, 741, 0, 363, 0, + 60, 57, 0, 0, 0, 0, 0, 0, 370, 0, + 698, 0, 0, 85, 84, 0, 488, 0, 0, 0, + 0, 0, 178, 559, 0, 0, 0, 0, 0, 888, + 880, 878, 0, 899, 0, 0, 946, 515, 512, 0, + 463, 0, 0, 1031, 1032, 451, 457, 0, 461, 0, + 0, 0, 0, 0, 0, 853, 0, 938, 0, 935, + 929, 0, 543, 538, 0, 0, 534, 0, 954, 0, + 871, 967, 965, 0, 555, 0, 672, 662, 351, 655, + 654, 674, 480, 0, 471, 470, 469, 640, 641, 638, + 0, 837, 820, 0, 0, 0, 826, 0, 970, 0, + 999, 0, 0, 1014, 1015, 1008, 0, 1052, 366, 365, + 0, 0, 66, 59, 0, 68, 29, 22, 0, 0, + 319, 0, 221, 0, 109, 0, 82, 831, 121, 122, + 0, 0, 0, 834, 193, 194, 0, 0, 0, 0, + 166, 175, 167, 169, 875, 0, 0, 0, 0, 0, + 897, 0, 0, 464, 465, 459, 462, 458, 452, 456, + 0, 520, 0, 486, 496, 450, 532, 530, 0, 0, + 934, 0, 0, 0, 539, 0, 957, 0, 0, 685, + 677, 0, 479, 0, 0, 818, 817, 814, 827, 969, + 0, 0, 0, 983, 0, 981, 992, 0, 1021, 1040, + 0, 79, 0, 0, 73, 74, 77, 78, 0, 336, + 325, 324, 0, 699, 217, 104, 0, 816, 835, 179, + 0, 191, 0, 0, 0, 873, 959, 0, 0, 0, + 0, 879, 0, 900, 851, 501, 498, 860, 0, 866, + 0, 0, 858, 0, 862, 941, 0, 542, 541, 956, + 952, 0, 675, 0, 0, 971, 996, 0, 982, 0, + 0, 1010, 0, 80, 71, 0, 0, 0, 320, 0, + 0, 0, 0, 0, 180, 0, 170, 168, 949, 889, + 883, 881, 0, 0, 854, 859, 0, 863, 939, 0, + 0, 678, 0, 829, 0, 1000, 1017, 1018, 1011, 58, + 0, 75, 76, 0, 0, 0, 0, 0, 0, 0, + 694, 0, 725, 0, 691, 836, 177, 0, 190, 0, + 0, 901, 865, 864, 0, 953, 838, 0, 0, 0, + 81, 0, 0, 337, 0, 0, 335, 321, 0, 329, + 0, 386, 0, 384, 0, 0, 700, 0, 730, 218, + 0, 181, 950, 885, 882, 0, 0, 894, 748, 750, + 937, 997, 0, 1012, 0, 0, 0, 317, 0, 0, + 692, 727, 0, 696, 0, 0, 731, 0, 105, 0, + 0, 0, 1001, 27, 26, 23, 338, 334, 0, 0, + 330, 385, 0, 733, 0, 0, 0, 0, 884, 0, + 0, 0, 0, 0, 32, 322, 0, 738, 0, 739, + 736, 0, 734, 102, 0, 99, 0, 0, 88, 90, + 91, 92, 93, 94, 95, 96, 97, 98, 100, 101, + 149, 0, 0, 234, 226, 227, 228, 229, 230, 231, + 232, 233, 0, 0, 224, 106, 749, 0, 998, 0, + 339, 333, 697, 0, 0, 0, 701, 89, 0, 277, + 272, 276, 0, 219, 225, 0, 1004, 1002, 737, 735, + 0, 0, 0, 0, 0, 0, 0, 286, 0, 0, + 235, 0, 0, 243, 0, 161, 150, 160, 0, 0, + 0, 0, 0, 271, 0, 0, 270, 0, 154, 0, + 0, 357, 318, 0, 355, 0, 0, 196, 0, 0, + 0, 0, 0, 702, 220, 107, 112, 110, 293, 0, + 354, 0, 0, 0, 0, 125, 0, 0, 0, 0, + 0, 0, 159, 151, 0, 0, 200, 0, 358, 0, + 238, 237, 236, 0, 0, 0, 290, 0, 268, 127, + 0, 266, 0, 0, 0, 129, 0, 359, 0, 0, + 197, 0, 0, 0, 356, 241, 108, 120, 118, 0, + 0, 295, 0, 0, 0, 0, 0, 155, 0, 274, + 0, 0, 0, 0, 133, 0, 0, 0, 0, 360, + 361, 0, 0, 0, 0, 0, 115, 310, 0, 291, + 0, 0, 304, 0, 0, 0, 299, 0, 145, 0, + 0, 0, 0, 140, 0, 0, 287, 0, 130, 0, + 124, 134, 152, 158, 208, 0, 198, 0, 0, 201, + 0, 119, 0, 111, 116, 0, 0, 0, 306, 0, + 307, 296, 0, 0, 289, 300, 269, 0, 0, 126, + 141, 267, 0, 285, 0, 275, 279, 136, 0, 0, + 0, 205, 207, 0, 242, 117, 311, 313, 292, 0, + 0, 305, 302, 144, 142, 156, 284, 0, 0, 0, + 153, 209, 211, 199, 0, 0, 0, 304, 0, 280, + 282, 137, 0, 0, 202, 315, 316, 312, 314, 303, + 157, 0, 0, 215, 214, 213, 210, 212, 0, 0, + 0, 203, 281, 283, }; protected static readonly short [] yyDgoto = { 7, - 8, 49, 9, 50, 10, 11, 51, 232, 700, 662, - 12, 13, 52, 22, 23, 324, 235, 685, 856, 1050, - 1170, 1515, 853, 236, 237, 238, 239, 240, 241, 242, - 243, 678, 449, 679, 680, 958, 681, 682, 962, 854, - 1045, 1046, 1047, 266, 599, 1140, 110, 865, 1244, 1245, - 1246, 1247, 1248, 1249, 1250, 1251, 1252, 1253, 1254, 1255, - 1256, 468, 689, 1327, 972, 1147, 1112, 1182, 1210, 1272, - 1338, 1178, 1389, 1366, 1414, 1415, 1416, 974, 1412, 975, - 746, 1304, 1377, 1351, 1402, 520, 1395, 1371, 1431, 938, - 1400, 1403, 1404, 1499, 1432, 1433, 1429, 1257, 1311, 1283, - 1328, 702, 1379, 1478, 1348, 1435, 1508, 469, 267, 703, - 704, 705, 706, 707, 665, 575, 1152, 666, 667, 871, - 1330, 1356, 1446, 1407, 1480, 1331, 1382, 1504, 1528, 1447, - 1448, 1526, 1512, 1513, 970, 1111, 1209, 1269, 1313, 1270, - 1271, 1305, 1363, 1334, 1306, 327, 223, 1411, 1308, 1396, - 1393, 1258, 1285, 1324, 1475, 1437, 1162, 1476, 600, 1521, - 1522, 1323, 1392, 1368, 1424, 1419, 1390, 1456, 1461, 1422, - 1425, 1426, 1507, 1462, 1420, 1421, 1517, 1505, 1506, 967, - 1054, 1175, 1145, 1202, 1176, 1177, 1219, 1108, 1199, 1232, - 540, 193, 112, 353, 195, 569, 444, 224, 1343, 663, - 664, 842, 858, 328, 409, 539, 304, 1179, 1180, 45, - 114, 305, 116, 117, 118, 119, 120, 121, 122, 123, - 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, - 134, 135, 136, 252, 815, 742, 1010, 516, 732, 894, - 733, 734, 1003, 137, 198, 738, 602, 603, 604, 809, - 478, 479, 297, 1008, 740, 410, 299, 503, 504, 505, - 506, 509, 748, 313, 764, 765, 911, 263, 484, 779, - 264, 483, 138, 139, 140, 141, 142, 143, 144, 145, - 146, 147, 148, 149, 150, 151, 825, 152, 578, 579, - 580, 788, 789, 790, 153, 566, 781, 354, 1026, 554, - 1092, 154, 498, 968, 1110, 1207, 1309, 470, 1183, 1184, - 1239, 1240, 843, 558, 339, 785, 1194, 559, 560, 268, - 269, 270, 157, 158, 159, 271, 272, 273, 274, 275, - 276, 277, 278, 279, 280, 281, 282, 171, 283, 585, - 172, 173, 320, 822, 638, 941, 1032, 868, 696, 978, - 939, 942, 1070, 943, 979, 980, 284, 174, 175, 176, - 1082, 1014, 1083, 1084, 1085, 1127, 1086, 177, 178, 179, - 180, 713, 491, 714, 1073, 996, 1074, 1190, 1155, 1191, - 715, 995, 716, 1193, 1123, 181, 182, 183, 184, 185, - 186, 306, 530, 531, 1016, 1129, 316, 994, 878, 1154, - 1023, 917, 1130, 187, 422, 188, 423, 944, 1035, 424, - 425, 654, 645, 646, 948, 426, 427, 428, 429, 430, - 949, 640, 946, 1134, 1213, 1274, 1037, 1166, 1231, 834, - 648, 835, 1101, 1040, 1102, 1167, 953, 17, 19, 46, - 47, 227, 668, 850, 445, 669, 670, + 8, 50, 9, 51, 10, 11, 52, 234, 753, 754, + 12, 13, 53, 22, 23, 329, 237, 738, 917, 1119, + 1243, 1296, 1606, 914, 238, 239, 240, 241, 242, 243, + 244, 245, 731, 468, 732, 733, 1022, 734, 735, 1026, + 915, 1114, 1115, 1116, 270, 631, 1211, 111, 926, 794, + 1327, 1328, 1329, 1330, 1331, 1332, 1333, 1334, 1335, 1336, + 1337, 1338, 1339, 1340, 487, 742, 1415, 1036, 1224, 1182, + 1222, 1257, 1308, 1376, 1455, 1252, 1480, 1456, 1505, 1506, + 1507, 1038, 1503, 1039, 803, 918, 1467, 1441, 1493, 543, + 1486, 1461, 1522, 1002, 1491, 1494, 1495, 1590, 1523, 1524, + 1520, 1341, 1397, 1369, 1416, 755, 1469, 1569, 1438, 1526, + 1599, 488, 271, 756, 757, 758, 759, 760, 713, 604, + 1228, 714, 715, 932, 1418, 1446, 1537, 1498, 1571, 1419, + 1472, 1574, 1619, 1538, 1539, 1617, 1603, 1604, 1034, 1181, + 1288, 1353, 1400, 1354, 1355, 1391, 1453, 1422, 1392, 332, + 224, 1502, 1394, 1487, 1484, 1342, 1371, 1411, 1566, 1528, + 1271, 1567, 632, 1612, 1613, 1410, 1483, 1458, 1515, 1510, + 1481, 1547, 1552, 1513, 1516, 1517, 1598, 1553, 1511, 1512, + 1608, 1596, 1597, 1031, 1123, 1248, 1216, 1279, 1249, 1250, + 1299, 1178, 1276, 1313, 564, 194, 113, 372, 196, 597, + 464, 227, 1433, 722, 723, 906, 919, 333, 428, 563, + 308, 1253, 1254, 46, 115, 309, 117, 118, 119, 120, + 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, + 131, 132, 133, 134, 135, 136, 137, 255, 877, 799, + 1075, 1065, 787, 956, 788, 789, 1066, 138, 199, 795, + 634, 635, 636, 871, 497, 498, 301, 1073, 797, 429, + 303, 526, 527, 528, 529, 532, 805, 317, 823, 824, + 974, 267, 503, 838, 268, 502, 139, 140, 141, 142, + 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, + 153, 607, 608, 609, 843, 844, 154, 594, 582, 840, + 373, 1092, 578, 1162, 155, 517, 1219, 1220, 1223, 1303, + 1032, 1180, 1286, 1395, 489, 1258, 1259, 1322, 1323, 907, + 586, 350, 849, 1291, 0, 0, 587, 588, 272, 273, + 274, 158, 159, 160, 275, 276, 277, 278, 279, 280, + 281, 282, 283, 284, 285, 286, 172, 287, 614, 173, + 174, 325, 884, 691, 1005, 1098, 929, 749, 1042, 1003, + 1006, 1139, 1007, 1043, 1044, 288, 175, 176, 177, 1151, + 1079, 1152, 1153, 1154, 1155, 178, 179, 180, 181, 766, + 510, 767, 1142, 1060, 1143, 1265, 1231, 1266, 768, 1059, + 769, 1268, 1193, 182, 183, 184, 185, 186, 187, 310, + 554, 555, 1082, 812, 1200, 321, 1058, 939, 1230, 1089, + 980, 1201, 188, 441, 189, 442, 1008, 1101, 443, 444, + 707, 698, 699, 1106, 1012, 445, 446, 447, 448, 449, + 1013, 693, 1010, 1205, 1292, 1359, 1103, 1239, 1312, 894, + 701, 895, 1171, 1108, 1172, 1240, 1017, 17, 19, 47, + 48, 226, 716, 910, 462, 717, 718, + }; + protected static readonly short [] yySindex = { -98, + 0, -176, 55, -199, 34,17217, 0, 149, 0, 0, + 34, -199, 0, 0, 28, 0, 7035, 34, 0, -170, + -239, 0, 0, 0, 0, 0, 0, 0, 200, 0, + 297, 0, 0, 0, 1389, 0, 0, 0, 0, 0, + 0, 320, 0, 0, 678, 0, 0, 732, 0, 0, + 149, 366, 34, 0, 443, 0, 30, 529, -141,16646, + -77, 298, 548, 7192, 0, 298, 298, 298, 38, 298, + 298, 788, 0, 9169, 298, 298, 0, 9326, 0, 512, + 0, -118, 0, 298, 554, 298, 0, 777, 777, 587, + 298, 298, -73, 9485, 0,15885, 0,10665,10796,10927, +11058,11189,11320,11451,11582, 0, 226, 0, 9029, 0, + 230, 0, 212, 551, 744, -223, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1744, + 805, 96, 465, 640, 714, 617, 576, 654, 661, 164, + 679, 0, 0, 0, 0, 0, 0, 3587, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 212, 711, 319, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 158, 387, 366, + 0, 472, 626, 0, 700, 0, 0, 0, 0, 9029, + 9029, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 320, 0, 0, 681, 713, 0, 18, + 0, 0, 0, 366,17762, 802, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 818, 212,16021, 0, + 0, 0, 0, 0,15885, -180, -174, 857, 771, 409, + 744, 212, 0, 0, 9029, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 108, -279,16646, 0, + 9029,15885, 808, 0, 0, 811,15885,15885, 5423, 218, + -110, 793, 9186, 0, 9485, 226, 946, 837, 0, 842, + 9029,15885, 0, 957, 851, 549, 298, 0, 0,15885, + 512,15477, 0, 0, 554,15885, 554, 176, 557, 940, + 212, 0, 711, -223, 943, 212,15885,15885,15885, 548, + 0, 898, 0, 9029, 9029, 0,10534, 212, 0, 7349, + -240, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 4470, + 0, 0,17043, 176, 872, 888,15885, 0, 854, 0, + 173, 0, 0, 217, 0, 0, 853, 9616, 7663, 0, + 0,15885,15885,15885,15885,15885,15885,15885,15885,15885, +15885,15885,11713,11844,11975, 4629, 4794,12106,12237,12368, +12499,12630,12761,12892,13023,13154,13285,13416,13547,13678, +13809,13940,16429,15885, 0, 0, 0, 0, 711, 0, + 0, 0, 0, 777, 777, 0, 0, 212, 0, 0, + 0, 0, 442, 932, 0, 0, 0, 0, 0, 0, + 0, 366, 802, 867, 0, 896, 0, 854, 320, 320, + 0, 643, 171, 0, 320, 935, 0, -131,17762, 0, + 0, 0, 0, -162, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 93,17794, 0, 0, + 0, 0, 854, 0, 0, 970, 503, 0, 950, 0, + 977, 157, 512, 0, 298, 0, 0, 0, 212,15477, + -185, 0, 974, 0, 0, 0, 110, 111, 0, 771, + 409, 0, 0, 975, 0, 985, 0, 981, 941, 0, + 0, 645, 0, 8406, 705, 9773, 793,15341, 0, 7820, + 0, 554, 0, 0, 0, 0, 117, 134, 0, 0, + 0, 70, 512, -151, 0, 4152, 991, 0, 152, 212, + 0, 161, 0, 0, 0,15885, 1070, 0, 0, 0, +15885, 1075, 997, 0, 1002, 1003, 0,17043, 0, 0, + 0, 170, 854, 0, -206, 133, 7349, 0, 0, 0, + 0, 0, 0, 170, 0, 0, -254, 0, 0, 0, + 554, 0, 176, 212, 9790, 0, 1004, 0, 1020,14071, + 0, 1137, 1021, 7349, 0, 968, 0, 854, 971, 0, + 854, 854, 0, 77, 0,15885,15885, 1027, 1144, 0, + 0, 189, -154, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 805, 0, + 805, 0,10403, 96, 0, 96, 0, 465, 0, 465, + 0, 465, 0, 465, 0, 640, 0, 640, 0, 714, + 0, 617, 0, 576, 0, 654, 0, 661, 0, -58, + -172, 0, 9773, 1108, 212, 1110, 212, 9773, 9773, 1029, +15885, 0, 0, 932, 0, 212, 0, 665, 854, 0, + 0, 0, 9790, 643, 0, 1039, 1040, 0, 0, 377, + 366, 390, 0, 0, 0, 0, 0, 0, -203, 1047, + 0, 1038, 1051, 0, 0, 0, 0, 1048, 9947, 1017, + 0, 424, 0, 0, 530, 0,16021, 0, 1055, 0, + 0, 0, 591, 177, 1065, 0, 1064, 1067, 1068, 0, + 0,15885, 0, 212, 0, 0, 754, 0, 1069, 0, + 327, 0, 0, 7192, 0, 7192, 8565, 0,14202, 0, + 0, 0, 8724, 8855, 242, 0, 166, -81, 0, 1010, + 1022, 0, 0, 0, 751, 0, 0, 1072, 1074, 0, + 0, 0, 0, 0, 1076, 0, 0, 0, 1082, 298, + 7680, 512, 0, 512, 0, 0, 554, 581, 1030, 0, + 274, 0, 1080, 1081, 0, 0, 7192, 0, 0, 7192, + 0,15885, 0,15885, 9029, 0, 0, 512, 1086, 170, + 0, 0, 0,15885, 0, 0, 0, 0, 0, 0, + 0, 9029, 0, 0, 212,17043, 1116, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0,15205, 0, 0, 0, 0, 0, 7977, 0, + 9012, 0, 8134, 1079, 0, 0, 1166, 0, 1167, 0, + 0, 0, 923, 0, 1089, 0, 0, 0, 0, 0, + 0, 0, 643, 0, 0, 1049, 0, 171, 0, 643, + 0, 0, 867, 1096, 1097, 1054, 1102, 1017, 0, 1098, + 0, 1219, 1220, 0, 0, 9773, 0,15613, 1106, 591, + 9790, 9029, 0, 0, 386, 1225, 1226, 163, 1104, 0, + 0, 0,15885, 0,15885, 1203, 0, 0, 0,15749, + 0, 555,15749, 0, 0, 0, 0, 8270, 0, 1244, + 711, 9773, 1134, 8565, 1138, 0,15885, 0, 212, 0, + 0, 301, 0, 0, 854, 1030, 0, 212, 0, -168, + 0, 0, 0, 1130, 0, 1164, 0, 0, 0, 0, + 0, 0, 0, 804, 0, 0, 0, 0, 0, 0, + 9186, 0, 0, 212, 595, 1079, 0, 9773, 0, 9773, + 0, 141, 9773, 0, 0, 0, 789, 0, 0, 0, + 1139, 867, 0, 0, 9930, 0, 0, 0, 1140, 7837, + 0, 1017, 0, 1017, 0, 1017, 0, 0, 0, 0, + 212, 1132, 1106, 0, 0, 0, -171, -150, 1136, 1141, + 0, 0, 0, 0, 0, 1143, 8565, 1079, -172,15885, + 0, 1145, 7192, 0, 0, 0, 0, 0, 0, 0, + 1142, 0, 793, 0, 0, 0, 0, 0, -212, 1148, + 0, 1149, 854, 1030, 0, 1030, 0, 1079, 1153, 0, + 0, 170, 0, 1090, 1135, 0, 0, 0, 0, 0, + 9773, 1179, 9773, 0, 9773, 0, 0,15885, 0, 0, + 1051, 0, 368, 825, 0, 0, 0, 0, -199, 0, + 0, 0, 1160, 0, 0, 0, 1147, 0, 0, 0, + 509, 0, 1150, 1273, 1274, 0, 0, 1079, 1161, 1079, + 1165, 0, 1156, 0, 0, 0, 0, 0,15885, 0, + 1170, -167, 0, 6876, 0, 0, 1283, 0, 0, 0, + 0, 170, 0,15885, 8134, 0, 0, 1194, 0, 938, + 1168, 0, 1173, 0, 0, 9930, 34, 157, 0, 302, + 1169, 1175,15613, 1181, 0,15885, 0, 0, 0, 0, + 0, 0, 7192, 40, 0, 0, 7349, 0, 0, 1260, + 7192, 0, 1183, 0, 9773, 0, 0, 0, 0, 0, +15885, 0, 0, 366, 1184, 366, 157, 9029, 1169, 1218, + 0, 1218, 0, 1169, 0, 0, 0,15885, 0, 7192, +10087, 0, 0, 0, 884, 0, 0, 1210, 9773,15885, + 0, 366, 1195, 0, 1146, 931, 0, 0, 1188, 0, + 1196, 0, 97, 0, 1198, 1152, 0, 1218, 0, 0, + 1218, 0, 0, 0, 0, 1200, 1069, 0, 0, 0, + 0, 0, 1227, 0, 52, 1218, 1311, 0, 1209, 366, + 0, 0, 9029, 0, 63, 1211, 0, 1212, 0, 7192, + 7349, 9773, 0, 0, 0, 0, 0, 0, 1199, 1206, + 0, 0,15341, 0,16725, 183, 366, 1216, 0, 1217, + 1228, 9773, 1213,15885, 0, 0, 1232, 0, 1221, 0, + 0, 1214, 0, 0,17794, 0, 1222, 183, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 534,17794, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1223, 366, 0, 0, 0, 212, 0, 1228, + 0, 0, 0, 1233,16725,16891, 0, 0, -222, 0, + 0, 0,16923, 0, 0, 183, 0, 0, 0, 0, + 9029, 9029, -165, 9186, 460, 554, 1261, 0, 176,15059, + 0, 1292, 0, 0, 1206, 0, 0, 0,15097, 1206, + 1239, -147, -132, 0, 9029, -126, 0, 9029, 0, 1201, + 1249, 0, 0, 176, 0, 168,15135, 0, 1254, 1208, + 175, 453, 1389, 0, 0, 0, 0, 0, 0, 176, + 0, 1257, 1224, 1256, 1252, 0, 1264, 1231, 1268, 157, + 1250, 1270, 0, 0, 1279, 1286, 0, 854, 0, 911, + 0, 0, 0, 1284, 1206, -49, 0, 1285, 0, 0, + 1295, 0, 1294, 1282, 1296, 0, 1293, 0, 157, 157, + 0, 157, 1297, 1298, 0, 0, 0, 0, 0, 1299, + 184, 0, 1302, 157, 1413, 1303, 157, 0, -222, 0, + 8565, 1266, 1310, 1293, 0, 1300, 1307, 187, 1317, 0, + 0, 157,15613, 1272, 1312, 1299, 0, 0,17794, 0, + 366, 366, 0, 1275, 1316, 1302, 0, 1322, 0,15885, + 1278, 1323, 1303, 0, 1329, 157, 0, 95, 0, 1321, + 0, 0, 0, 0, 0,17794, 0, 187, 187, 0, + 1331, 0, -49, 0, 0, -146, 1336,17794, 0,17794, + 0, 0, 8565, 1324, 0, 0, 0, 1337, 1295, 0, + 0, 0, 1338, 0, -120, 0, 0, 0, 1218, 965, + 1340, 0, 0, 1342, 0, 0, 0, 0, 0, 1396, + 1449, 0, 0, 0, 0, 0, 0, 1343, 1346, 8565, + 0, 0, 0, 0, 187, 508, 508, 0, 1218, 0, + 0, 0, -60, -60, 0, 0, 0, 0, 0, 0, + 0,15341,15341, 0, 0, 0, 0, 0, 1345, 1350, + 1351, 0, 0, 0, + }; + protected static readonly short [] yyRindex = { 3016, + 0, 0, 7506, 3016, 0, 0, 0, 1718, 0, 0, + 3202, 1926, 0, 0, 0, 0, 0, 3202, 0, 0, + 43, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1725, 0, 0, 1725, 0, 0, 1725, 0, 0, + 1718, 3245, 3085, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1359, 0, 0, 0, 0, 0, 0, 0, + 0,10104, 0, 1352, 0, 0, 0, 1352, 0, 0, + 0, 0, 0, 0, 311, 0, 0, 0, 0, 0, + 0, 0, 0, 292, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 4787, 0, 0, 0, + 0, 0, 0, 345, 4880, 4222, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 5036, + 5104, 1033, 5577, 5917, 6121, 6257, 1476, 6461, 6597, 4967, + 3954, 0, 0, 0, 0, 0, 0, 43, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 303, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 3308, + 0, 687, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1725, 0, 0, 92, 0, 0, 0, + 0, 0, 0, 3355, 604, 3422, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 3833, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1361, 0, + 0, 0, 0, 0, 0, 3833, 1354, 0, 0, 0, + 0, 0, 0, 1354, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 2334, 0, 1262, 955, 2464, 0, + 0, 0, 2594, 2464, 0, 0, 0, 0, 0, 1359, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 205, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1362, 2698, 0, 0, 1352, 0, 3833, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 243, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1581, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 635, 0, 0, 0, 0, 0, 0, + 0, 3465, 3508, 0, 0, 0, 0, 2188, 1725, 1725, + 0, 7994, -184, 0, 1725, 1731, 0, 0, 180, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 511,16578, 0, 0, + 0, 0, 3833, 0, 0, 0, 0, 0, 0, 0, + 0,16967, 0, 0, 0, 0, 0, 0, 0, 773, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 268, + 1489, 0, 0, -235, 1792, 0, 0, 1367, 602, 0, + 0, 0, 0, 210, 0, 0, 4310, 1366, 0, 0, + 0, 934, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1373, 0, 1752, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 1362, 0, 0, + 0,16157, 3833, 0, 6716, 0, 228, 0, 0, 0, + 0, 0, 0,16157, 0, 0, 0, 0, 0, 0, + 26, 0, 852, 0, 0, 0, 1369, 0, 0, 0, + 0, 1354, 0, 0, 0, 3674, 0, 3833, 3674, 0, + 3833, 4469, 0, 0, 0, 0, 0, -208, 0, 0, + 0, 0, 286, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 5208, 0, + 5276, 0, 0, 5425, 0, 5509, 0, 5645, 0, 5713, + 0, 5781, 0, 5849, 0, 5985, 0, 6053, 0, 6189, + 0, 6325, 0, 6393, 0, 6529, 0, 6653, 0, 0, + 638, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 635, 0, 0, 0, 0, 2188, 0, + 0, 0, 0,17241, 0, 0, 844, 0, 0, 1325, +14364, 0, 0, 0, 0, 0, 0, 0, 749, 683, + 0, 0, 1372, 0, 0, 0, 0, 2953, 0, 0, + 0, 0, 0, 0,10244, 0, 0, 0, 843, 0, + 0, 0,17291,17114, 0, 0, 860, 863, 885, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 774, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1377, 0, + 0, 0, 0, 0, 3740, 0, 0, 236, 0, 112, + 3992, 0, 0, 0, 0, 0, 0, 0, 1374, 0, + 0, 0, 0, 0, 1379, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 369, 608, 0, 0, + 0, 0, 0, 1376, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0,16157, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 649, 0, 0, 0, 0, 0, 0, + 0, 0, -179, 0, 505, 0, 0, 0, 0, 0, + 0, 0,17291, 0, 0, 0, 0, -184, 0, 8151, + 0, 0, 1380, 0, 784, 0, 0, 0, 0, 1382, + 0, 1333, 1335, 0, 0, 0, 0, 0, 1381,17315, + 0, 0, 0, 0,17146, 0, 0, 0, 886, 0, + 0, 0, 0, 0, 0, 2062, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 4151, 0, 4628, 1387, 0, 0, 0, 0, 1384, 0, + 0, 0, 0, 0, 321, 0, 0, 0, 0, 886, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 659, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 889, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1383, 0, 0, 0, 0, 0, 897, 904, + 0, 0, 0, 0, 0, 0, 0, 1386, 730, 1388, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 4310, 0, 0, 0, 0, 0, 1392, 0, + 0, 0, 321, 0, 0, 959, 0, 1386, 0, 0, + 0,16157, 0, 656, 694, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1372, 0,14203, 0, 0, 0, 0, 0,17366, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 791, 0, 809, 0, 0, 0, 0, 991, 0, 813, + 1394, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1395, 0, 0, 0, 0, 196, 0, 0, 0, + 0,16157, 0, 0, 0, 0, 0, 0, 0, 360, + 543, 0, 0, 0, 0, 0,17409,16967, 0, 232, + 473, 513, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, -152, 0, 0, 966, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0,17495, 0, -215,16967, 0, 531, 1412, + 0, 1412, 0, 473, 0, 0, 0, 0, 0, 0, + 1408, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0,17538, 0, 0, 0,14667, 0, 0, 1421, 0, + 0, 0, 494, 0, 0, 0, 0, 536, 0, 0, + 1412, 0, 0, 0, 0, 0, 1418, 0, 0, 0, + 0, 0, 0, 0, 3159, 1415, 539, 0, 0, -16, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1424, 0, 0, 0, 0, 0, 0, 0, 0, 2867, + 0, 0, 1366, 0, 0,14469,14753, 0, 0, 0, + 748, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 446, 0, 0,16749, 0, 0,14568, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0,16817, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0,14847, 0, 0, 0, 0, 0, 748, + 0, 0, 0, 0, 0, 511, 0, 0, 0, 0, + 0, 0, 511, 0, 0,14469, 0, 0, 0, 0, + 0, 0, 0, 0, 0,14959, 518, 0,14889, 0, + 0, 0,15021, 0, 2867, 0, 0, 0, 0, 2867, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 395, 0, 1429, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 869, + 0, 697, 0, 0, 0, 0, 0, 0, 0,16967, + 907, 0, 0, 0, 0, 0, 0, 1441, 0, 174, + 0, 0, 0, 0, 2867, 0, 0, 922, 0, 0, + 0, 0, 0, 0, 0, 0, 1440, 0,16967,16967, + 0,16999, 0, 0, 0, 0, 0, 0, 0, 1442, +17732, 0, 1443,16967,16293, 1445,16967, 0, 0, 0, + 0, 0, 0, 1457, 0, 0, 0, 1238, 0, 0, + 0,16967, 0, 0, 0, 1458, 0, 0, 179, 0, +17656,17694, 0, 0, 0, 1459, 0, 0, 0, 0, + 0, 0, 1460, 0, 0,16967, 0, 585, 0, 933, + 0, 0, 0, 0, 0, 972, 0,17580,17618, 0, + 0, 0, 0, 0, 0, 0, 0, 1447, 0, 1534, + 0, 0, 0, 947, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 568, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1238,16465,17452, 0, 568, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1366, 1366, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, }; - protected static readonly short [] yySindex = { -167, - 0, -194, 51, 72, 108,12563, 0, 231, 0, 0, - 108, 72, 0, 0, -63, 0, 6715, 108, 0, -179, - -254, 0, 0, 0, 0, 0, 0, 0, 244, 0, - 327, 0, 0, 0, 3845, 0, 0, 0, 0, 0, - 0, 0, 0, 439, 0, 0, 575, 0, 0, 231, - 215, 108, 0, 319, 0, 264, 358, 279,12045, -163, - 9, 399, 6872, 0, 9, 9, 9, -137, 9, 9, - 706, 0, 8561, 9, 9, 0, 8718, 0, 482, 0, - 279, 0, 9, 419, 9, 0, 1465, 1465, 501, 9, - 9, -216,11828, 0,11148, 0,11828,11828,11828,11828, -11828,11828,11828,11828, 0, 133, 0, 7831, 0, 131, - 0, 437, 505, 318, 429, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 1044, 775, - 84, 280, 559, 260, 523, 568, 580, 593, -288, 609, - 0, 0, 0, 0, 0, 0, 3546, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 168, 614, 250, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 317, 332, 215, 0, - 451, 191, 0, 587, 0, 0, 0, 0, 7831, 7831, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 665, 599, 0, 629, 0, 69, 0, 0, - 0, 215,13031, 713, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 794, 641,11284, 0, 0, 0, - 0,11148, 9, 9, 785, 331, 318, 168, 0, 0, - 7831, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, -176, -267,12045, 0, 7831,11148, 716, 0, - 0, 734,11148,11148, 9503, -251, -118, 772, 8126, 0, -11828, 133, 889, 800, 0, 818, 7831,11148, 0, 0, - 830, 591, 9, 0,11148, 482,10604, 0, 0, 419, -11148, 419, -279, 539, 854, 168, 0, 614, 429, 919, - 168,11148,11148,11148, 399, 0, 840, 0, 7029, 82, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 4270, 0, 0,12518, -279, 843, 857,11148, 0, 809, - 0, -294, 0, 0, 356, 0, 0, 810, 8875,10468, - 0, 0,11148,11148,11148,11148,11148,11148,11148,11148, -11148,11148,11148,11828,11828,11828, 7831, 7831,11828,11828, -11828,11828,11828,11828,11828,11828,11828,11828,11828,11828, -11828,11828,11828,11828,11148, 0, 0, 0, 0, 614, - 0, 0, 0, 0, 1465, 1465, 0, 0, 168, 0, - 0, 0, 0, 374, 875, 0, 0, 0, 0, 0, - 0, 0, 215, 713, 821, 0, 841, 0, 809, 665, - 665, 0, -86, 0, 551, 665, 873, 0, -184,13031, - 0, 0, 0, 0, -174, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 198,13061, 0, - 0, 0, 0, 809, 0, 0, 872, 534, 0, 888, - 0, 890, 144, 482, 0, 9, 0, 0, 0, 168, -10604, -156, 0, 885, 0, 0, 0, -40, 53, 0, - 438, 0, 897, 0, 892, 0, 0, 0, 596, 0, - 8245, 615,11148, 772,10468, 0, 7500, 0, 419, 0, - 0, 0, 0, 896, 92, 0, 0, 279, 482, -159, - 0, 4111, 900, 0, 135, 168, 0, 136, 0, 0, - 0,11148, 975, 0, 0, 0,11148, 979, 901, 0, - 904, 906, 0,12518, 0, 0, -186, 44, 7029, 0, - 0, 0, 0, 0, 0, 482, 0, 0, -268, 0, - 0, 0, 419, -279, 168, 8421, 0, 907, 0, 908, -11828, 0, 1029, 920, 7029, 0, -300, 0, 240, 0, - 809, 0, 81,11148,11148, 924, 1041, 0, 0, 123, - -80, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 775, 775, 84, 84, 280, 280, 280, 280, 559, 559, - 260, 523, 568, 580, 593, 0, -161, -149, 0, 9032, - 1005, 168, 1006, 168, 9032, 9032, 921,11148, 0, 0, - 875, 0, 168, 0, 422, 809, 0, 0, 0, 0, - 481, 215, 31, 0, 8421, 551, 0, 931, 930, 0, - 0, 0, 0, 0, 0, -279, 933, 0, 934, 936, - 0, 0, 0, 0, 938, 8578, 894, 0, 267, 0, - 0, 321, 0,11284, 0, 932, 0, 0, 0, 454, - -47, 942, 0, 941, 943, 944, 0, 0,11148, 0, - 168, 0, 0, 704, 0, 945, 0, 427, 0, 0, - 6872, 0, 6872, 8404, 0, 9503, 0, 0,10740, 151, - 0, 114, -34, 0, 887, 899, 0, 91, 0, 0, - 948, 949, 0, 0, 0, 0, 0, 950, 0, 0, - 958, 0, 4429, 0, 482, 0, 0, 419, 617, 905, - 0, 175, 0, 955, 956, 0, 0, 6872, 0, 0, - 6872, 0,11148, 0,11148, 7831, 0, 0, 482, 959, - 482, 0, 0, 0, 0, 0, 0, 0, 0, 9032, - 7831, 0, 0, 168,12518, 987, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -10332, 0, 0, 0, 0, 0, 7657, 0, 9032, 0, - 7814, 964, 0, 0, 0, 0, 1038, 0, 1039, 0, - 0, 0, 566, 0, 966, 0, 0, 0, 0, 0, - 0, 926, 0, -86, 0, 0, 0, 0, 551, 551, - 0, 821, 976, 974, 937, 981, 894, 0, 977, 0, - 1093, 1095, 0, 0,11148, 0,10876, 980, 454, 8421, - 7831, 0, 0, -233, 1100, 1102, 137, 984, 0, 0, - 0,11148, 0,11148, 1080, 0, 0, 0, 0, 41, -11012, 0, 0, 0, 0, 7950, 0, 1105, 0, 614, -11148, 999, 8404, 1001, 0, 0, 168, 0, 196, 0, - 0, 809, 905, 0, 168, 0, -62, 0, 0, 0, - 995, 0, 1027, 0, 0, 0, 0, 0, 0, 0, - 729, 0, 0, 0, 0, 0, 8126, 0, 0, 168, - 13, 964, 0, 9032, 0, 9032, 0, 1020, 9032, 0, - 0, 0, 584, 0, 0, 0, 1004, 821, 0, 0, -11420, 0, 0, 0, 1007, 4594, 0, 894, 0, 894, - 0, 894, 0, 0, 0, 0, 168, 1000, 980, 0, - 0, 0, -166, -164, 1003, 1008, 0, 0, 0, 0, - 0, 1010, 8404, 964, -149,11148, 0, 1009, 6872, 0, - 0, 0, 0, 0, 0, 1014, 0, 772, 0, 0, - 0, 0, 0, -172, 0, 1015, 809, 905, 0, 905, - 0, 964, 1016, 0, 0, 482, 0, 952, 998, 0, - 0, 0, 0, 0, 9032, 1042, 9032, 9032, 0,11148, - 0, 0, 936, 208, 746, 0, 0, 0, 0, 72, - 0, 0, 0, 1023, 0, 0, 0, 1013, 0, 0, - 0, 428, 0, 1021, 1135, 1140, 0, 0, 964, 1025, - 964, 1037, 0, 1035, 0, 0, 0, 0, 0,11148, - 0, 1046, -153, 0, -153, 0, 0, 0, 0, 0, - 0, 482, 0,11148, 8109, 0, 0, 1068, 0, 760, - 1045, 0, 1048, 0, 0,11420, 108, 144, 0, 1049, - 1049, 1049,10876, 1050, 0,11148, 0, 0, 0, 0, - 0, 0, 6872, -139, 0, 0, 7029, 0, 784, 6872, - 0, 1056, 0, 9032, 0, 0, 0, 0, 0,11148, - 0, 0, 215, 1055, 215, 7831, 1077, 1077, 1077, 0, - 0,11148, 0, 6872, 9189, 0, 0, 0, 7029, 0, - 0, 0, 0, 0, 1082, 9032,11148, 0, 215, 1060, - 0, 1017, 789, 0, 0, 1057, 0, 0, 36, 0, - 1018, 0, 1077, 0, 0, 0, 0, 0, 0, 0, - 1061, 945, 0, 7029, 0, 1089, 0, 1063, 1077, 1184, - 0, 1073, 215, 0, 7831, -105, 1075, 0, 1090, 1092, - 6872, 1076, 9032, 0, 0, 0, 0, 0, 1079, 1063, - 0, 0, 0,12124, 120, 215, 0, 0, 0, 1106, - 9032, 1085,11148, 0, 0, 1094, 0, 0, 1097, 0, - 0,13061, 0, 1098, 120, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 583,13061, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 1099, 215, - 0, 120, 168, 0, 1106, 0, 0, 1091,12124,12290, - 0, 0, 20, 0, 0, 0,12322, 0, 0, 1101, - 0, 0, 0, 0, 7831, 7831, 265, 8126, 278, 419, - 1127, 0, -279, 946, 0, 1163, 0, 0, 1063, 0, - 0, 0, 1063, 0, 1052, 1054, 0, 7831, -151, 0, - 7831, 0, 1059, 1103, 0, -279, 0, -45,10251, 0, - 1104, 1062, 73, 506, 3845, 0, 0, 1063, 0, -279, - 0, 1111, 1065, 1110, 1108, 0, 1114, 1054, 1115, 144, - 1107, 1117, 0, 0, 1116, 1128, 0, 809, 0, 795, - 0, 0, 0, 1123, 0, -52, 0, 1121, 0, 0, - 1129, 0, 1125, 1131, 1136, 0, 1133, 0, 144, 144, - 0, 144, 1124, 1138, 0, 0, 0, 0, 1141, 128, - 0, 1142, 144, 1253, 1143, 144, 0, 20, 0, 8404, - 1109, 1144, 1133, 0, 1147, 1149, 130, 1154, 0, 0, - 144,10876, 1112, 1152, 1141, 0, 0,13061, 0, 215, - 215, 0, 1126, 1153, 1142, 0, 1173, 0,11148, 1130, - 1170, 1143, 0, 1175, 144, 0, -96, 0, 1168, 0, - 0, 0, 0, 0,13061, 0, 130, 130, 1145, 1178, - 0, -52, 0, 0, 256, 1157,13061, 0,13061, 0, - 0, 8404, 1171, 0, 0, 0, 1181, 1129, 0, 0, - 0, 1182, 0, 294, 0, 0, 0, 1077, 847, 1185, - 0, 0, 0, 0, 0, 0, 0, 0, 1241, 1295, - 0, 0, 0, 0, 0, 0, 1189, 1193, 8404, 0, - 0, 0, 0, 130, 526, 526, 0, 1077, 0, 0, - 0, 55, 55, 0, 0, 0, 0, 0, 0, 0, -10468,10468, 0, 0, 0, 0, 0, 1197, 1194, 1195, - 0, 0, 0, + protected static readonly short [] yyGindex = { 0, + 0, 1766, 0, 0, 0, -3, -15, -181, -41, -34, + 0, 1826, 1834, 342, 0, 4, 0, 0, 0, 0, + 0, 0,-1219, -767, -229, -675, 0, 0, 0, 0, + 0, -226, 0, 0, 0, 823, 0, 936, 0, 0, + 0, 0, 671, 677, -17, -216, 0, -47, 0, -481, + 478, 0, 527, -699, -582, -579, -561, -530, -509, -506, + -504, 0,-1153, 0,-1274, 0, 14, 0, 0, 0, + 632,-1183, 0, 0, 0, -14, 315, 0, 0, 0, + 353,-1146, 0, -280, -300, -527, 0, 0, 0, -972, + 305, 0, 0, -532, 0, 0, 373, 0, 0, 346, + 0, 0, 379, 0, -660, -858, 0, 0, 0, 0, + 0, -435, -10, 0, 0, 937, 945, 949, 1118, -570, + 0, 0, -305, 964, 470, 0, -892, 0, 0, 0, + 0, 0, 0, 0, 0, 270, 0, 0, 0, 0, + 0, 0, 0, 0, 521, 0, 0, 0, 0, -290, + 462, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 545, 0, -523, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 299, 0, 0, 380, 0, 0, 383, 388, + 306, 0, 0, 0, 0, 0, 0, 0, 0, 620, + 0, 0, 0, 0, -69, 0, 316, -24, 0, 0, + 454, 0, -424, 0, 999, 0, 1355, -299, -274, -62, + 909, 0, 625, 0, -35, 165, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, -259, 0, 37, 0, -355, + 0, -275, 0, 0, 0, 958, 960, -306, -128, 1131, + 0, 1042, 0, 1313, 1535, 1191, 0, 0, 849, 1869, + 0, 0, 0, 0, 1163, 0, 0, 0, 0, 0, + -516, 1605, 0, 0, 0, 0, 0, 1390, 939, 929, + 792, 944, 1528, 1531, 1527, 1537, 1539, 0, 1572, 0, + 0, 0, 1151, 1420, -562, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, -307, 814, 0, -681, 0, + 0, 0, 0, 0, -475, 0, 745, 0, 637, 0, + 715, 0, 0, 0, 0, 0, 858, -559, -11, -329, + -1, 0, 1847, 0, 48, 0, 56, 73, 81, 83, + 125, 160, 167, 182, 207, 252, 0, -716, 0, 2, + 0, 0, 952, 0, 873, 0, 0, 0, 0, 850, + -927, 926, -919, 0, 978, -493, 0, 0, 0, 0, + 0, 0, 881, 0, 870, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 803, 0, 0, 0, 0, 0, 0, 0, 0, -42, + 0, 1481, 0, 836, 0, 0, 1058, 0, 0, 0, + 0, 0, 0, -175, 0, 0, 0, 0, 0, 1602, + 1344, 0, 0, 0, 0, 1603, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 689, 0, 0, 0, 0, + 0, 0, 0, 0, 810, 0, 0, 0, 0, 0, + 0, 19, 1154, 0, 0, 0, 1155, }; - protected static readonly short [] yyRindex = { 1410, - 0, 0, 7186, 1410, 0, 0, 0, 1568, 0, 0, - 1513, 1341, 0, 0, 0, 0, 0, 1513, 0, 0, - 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, + protected static readonly short [] yyTable = { 110, + 18, 541, 190, 544, 470, 156, 112, 804, 452, 491, + 235, 513, 743, 451, 798, 157, 765, 236, 562, 44, + 590, 296, 324, 193, 261, 539, 537, 850, 1094, 425, + 573, 851, 495, 633, 855, 315, 1226, 965, 1260, 525, + 330, 335, 1029, 1148, 382, 342, 390, 684, 254, 846, + 1366, 383, 911, 391, 862, 1149, 307, 946, 568, 947, + 314, 262, 1247, 229, 161, 379, 231, 605, 1373, 316, + 770, 319, 162, 331, 336, 251, 1013, 1289, 351, 14, + 1316, 318, 606, 882, 1130, 191, 1099, 1087, 506, 163, + 1404, 362, 1297, 736, 375, 20, 507, 164, 265, 165, + 1149, 878, 289, 290, 291, 1132, 297, 298, 1427, 51, + 979, 311, 312, 981, 251, 861, 1577, 552, 320, 852, + 322, 51, 326, 1429, 726, 427, 1247, 338, 339, 1435, + 1138, 592, 516, 380, 814, 1587, 368, 318, 516, 1405, + 110, 166, 900, 1588, 95, 533, 156, 112, 235, 508, + 727, 389, 326, 1396, 692, 453, 157, 1, 2, 1013, + 1138, 853, 323, 684, 1013, 684, 1013, 455, 1578, 1013, + 1013, 495, 1013, 1013, 957, 1424, 167, 294, 263, 6, + 1425, 116, 728, 168, 369, 459, 460, 369, 593, 197, + 252, 294, 469, 516, 1013, 1614, 252, 880, 169, 453, + 493, 496, 51, 340, 1589, 161, 1478, 370, 883, 1150, + 370, 885, 1057, 162, 500, 861, 890, 891, 1099, 879, + 684, 371, 470, 170, 116, 95, 491, 790, 116, 252, + 163, 494, 295, 51, 1546, 1477, 796, 499, 164, 253, + 165, 15, 461, 467, 948, 253, 295, 192, 95, 1013, + 501, 524, 252, 261, 1150, 737, 534, 590, 535, 2, + 252, 1570, 561, 261, 569, 820, 565, 1133, 171, 861, + 1428, 570, 605, 1580, 512, 1581, 511, 987, 253, 516, + 518, 376, 166, 567, 590, 1430, 729, 606, 572, 294, + 509, 1436, 958, 320, 548, 1233, 547, 389, 264, 1029, + 583, 253, 557, 455, 559, 292, 95, 1294, 516, 253, + 558, 16, 536, 293, 606, 1615, 881, 167, 1304, 1215, + 575, 576, 116, 560, 168, 3, 4, 5, 6, 580, + 581, 1479, 868, 618, 613, 195, 621, 538, 589, 169, + 496, 496, 466, 1173, 295, 341, 1145, 362, 591, 455, + 1564, 328, 1282, 556, 615, 596, 1542, 406, 1251, 612, + 1047, 810, 198, 504, 170, 773, 775, 1029, 20, 739, + 494, 630, 806, 740, 637, 638, 639, 640, 641, 642, + 643, 644, 645, 646, 647, 1591, 694, 696, 376, 808, + 700, 655, 657, 407, 198, 376, 1104, 376, 247, 376, + 294, 51, 248, 195, 195, 49, 690, 826, 901, 171, + 235, 1406, 751, 432, 1234, 1611, 829, 453, 1055, 695, + 697, 720, 606, 1443, 195, 841, 719, 1295, 721, 362, + 362, 1077, 933, 710, 741, 43, 6, 1305, 1324, 1508, + 252, 705, 1535, 376, 1037, 55, 869, 505, 820, 1061, + 747, 705, 249, 116, 938, 295, 705, 708, 362, 1085, + 705, 763, 362, 771, 362, 362, 362, 362, 744, 1565, + 1283, 730, 362, 408, 409, 705, 1232, 711, 712, 1029, + 1074, 774, 776, 724, 1236, 1029, 116, 936, 807, 253, + 496, 1105, 761, 705, 491, 376, 433, 752, 1221, 1449, + 847, 434, 705, 435, 200, 809, 436, 437, 819, 438, + 439, 764, 828, 1263, 116, 195, 195, 994, 793, 525, + 630, 705, 802, 827, 1137, 233, 1100, 491, 1102, 1163, + 495, 1107, 830, 954, 1056, 294, 95, 1255, 1444, 233, + 362, 762, 813, 377, 362, 233, 347, 362, 831, 362, + 605, 233, 233, 833, 362, 233, 854, 812, 845, 818, + 875, 848, 936, 936, 422, 606, 369, 1158, 368, 1159, + 693, 842, 753, 1309, 294, 589, 423, 453, 455, 294, + 195, 1465, 944, 842, 368, 591, 440, 530, 811, 370, + 616, 531, 1450, 864, 955, 754, 866, 867, 693, 1202, + 617, 201, 589, 454, 378, 812, 195, 1345, 870, 870, + 1496, 1497, 591, 1499, 466, 1016, 369, 876, 195, 1166, + 945, 1168, 953, 1169, 1045, 1518, 195, 1040, 1525, 295, + 1326, 1344, 369, 753, 619, 812, 294, 850, 453, 370, + 606, 812, 432, 1541, 620, 1572, 1573, 887, 812, 889, + 352, 790, 1326, 371, 1345, 370, 754, 467, 897, 195, + 195, 959, 996, 294, 454, 800, 812, 1563, 252, 371, + 904, 466, 1217, 807, 116, 793, 1218, 347, 1344, 807, + 793, 793, 905, 893, 899, 195, 1072, 1076, 195, 347, + 225, 975, 347, 347, 430, 921, 812, 702, 1016, 496, + 1326, 544, 1605, 1016, 455, 1016, 347, 340, 1016, 1016, + 368, 1016, 1016, 340, 467, 1407, 940, 253, 1083, 922, + 800, 195, 195, 1238, 1346, 433, 1049, 1347, 807, 494, + 434, 524, 435, 1016, 233, 436, 437, 765, 438, 439, + 369, 811, 1431, 261, 516, 1348, 923, 431, 1174, 195, + 195, 116, 1141, 920, 233, 565, 1445, 1273, 369, 802, + 1007, 352, 340, 908, 1408, 352, 793, 347, 123, 195, + 123, 1346, 796, 976, 1347, 123, 1349, 1463, 116, 1317, + 433, 370, 703, 195, 732, 434, 369, 435, 1016, 704, + 436, 437, 1348, 438, 439, 371, 969, 1350, 1009, 369, + 1351, 970, 1352, 971, 551, 909, 703, 990, 1118, 352, + 1311, 724, 732, 704, 982, 450, 983, 552, 246, 95, + 984, 732, 370, 1349, 590, 496, 988, 985, 1451, 842, + 1360, 496, 726, 703, 553, 924, 371, 989, 1390, 724, + 704, 1109, 925, 1007, 1350, 1399, 967, 1351, 1007, 1352, + 1007, 690, 454, 1007, 1007, 630, 1007, 1007, 410, 411, + 726, 630, 369, 1000, 726, 802, 720, 590, 1194, 695, + 703, 821, 746, 721, 95, 705, 747, 1184, 95, 690, + 705, 1009, 1040, 1315, 705, 370, 1009, 690, 1009, 1185, + 1019, 1009, 1009, 195, 1009, 1009, 598, 695, 930, 705, + 1269, 1270, 729, 599, 250, 1229, 331, 380, 793, 1370, + 512, 729, 331, 380, 45, 600, 730, 1048, 266, 332, + 195, 1081, 1067, 381, 1084, 114, 705, 1062, 962, 456, + 1086, 1029, 1064, 1007, 728, 1064, 323, 380, 116, 323, + 116, 743, 323, 728, 793, 705, 802, 1262, 598, 1080, + 710, 278, 278, 972, 1417, 599, 1095, 337, 1529, 1118, + 278, 590, 1096, 1417, 419, 1421, 323, 600, 114, 511, + 1097, 1009, 114, 1019, 1421, 511, 340, 496, 1019, 340, + 1019, 1019, 1019, 1019, 1019, 1019, 1019, 1019, 1019, 1019, + 793, 116, 793, 1127, 116, 793, 334, 334, 456, 1131, + 418, 457, 1019, 1003, 1019, 819, 1019, 1117, 1019, 1019, + 1019, 819, 470, 819, 781, 1122, 822, 334, 782, 491, + 1582, 412, 413, 839, 822, 730, 823, 839, 195, 839, + 823, 839, 1242, 1362, 823, 414, 415, 456, 420, 802, + 898, 24, 516, 25, 432, 1124, 26, 1125, 225, 1126, + 228, 27, 69, 69, 195, 28, 69, 1602, 899, 347, + 421, 828, 347, 1019, 30, 828, 114, 828, 424, 828, + 288, 32, 288, 492, 791, 1393, 33, 288, 531, 300, + 34, 842, 1393, 793, 544, 793, 1003, 793, 1620, 1621, + 1170, 1003, 36, 1003, 37, 463, 1003, 1003, 38, 1003, + 1003, 819, 225, 819, 230, 819, 39, 40, 334, 334, + 41, 416, 417, 327, 252, 1177, 384, 458, 347, 347, + 961, 347, 347, 62, 962, 941, 195, 433, 496, 942, + 465, 512, 434, 340, 435, 385, 386, 436, 437, 294, + 438, 439, 589, 348, 886, 890, 1203, 802, 886, 890, + 195, 842, 591, 70, 299, 387, 300, 70, 1117, 540, + 176, 1214, 176, 253, 176, 512, 388, 195, 512, 490, + 233, 195, 235, 334, 1245, 1093, 1003, 879, 189, 453, + 189, 1246, 189, 514, 822, 589, 515, 793, 822, 374, + 403, 404, 405, 1241, 328, 591, 1175, 114, 1176, 334, + 235, 545, 1040, 668, 670, 672, 674, 453, 347, 381, + 512, 334, 549, 1050, 347, 1050, 830, 546, 830, 334, + 347, 793, 1170, 657, 347, 657, 550, 116, 195, 164, + 114, 164, 171, 566, 171, 352, 571, 347, 1245, 352, + 579, 347, 352, 610, 352, 1246, 195, 195, 811, 352, + 1269, 1270, 334, 334, 172, 496, 172, 958, 114, 958, + 72, 372, 72, 611, 1325, 1343, 195, 370, 195, 347, + 622, 1246, 721, 165, 793, 165, 1014, 1015, 334, 589, + 128, 334, 128, 352, 374, 630, 1325, 706, 601, 591, + 1321, 1207, 1208, 1246, 793, 294, 512, 294, 1278, 233, + 374, 374, 374, 725, 374, 374, 135, 374, 135, 374, + 1377, 347, 1343, 709, 334, 334, 195, 347, 116, 721, + 301, 748, 301, 347, 370, 463, 347, 347, 1592, 1593, + 540, 540, 940, 940, 1325, 705, 705, 195, 664, 666, + 347, 1246, 334, 334, 745, 195, 659, 661, 750, 772, + 1321, 374, 778, 374, 779, 777, 374, 116, 1398, 676, + 678, 116, 825, 832, 455, 116, 1402, 1403, 834, 780, + 835, 601, 347, 836, 837, 811, 601, 856, 601, 601, + 601, 601, 601, 601, 601, 601, 601, 601, 601, 1442, + 1434, 857, 860, 1437, 116, 863, 861, 873, 865, 874, + 601, 886, 601, 888, 601, 1442, 601, 601, 601, 892, + 902, 1452, 912, 903, 601, 601, 601, 601, 114, 456, + 916, 601, 601, 1473, 913, 1474, 601, 601, 601, 601, + 601, 601, 601, 601, 43, 928, 934, 935, 197, 1509, + 936, 937, 943, 963, 960, 601, 721, 879, 966, 964, + 973, 977, 1004, 978, 116, 116, 1536, 986, 992, 1009, + 1011, 601, 1016, 721, 334, 1024, 1019, 1025, 1028, 1548, + 1550, 1027, 1030, 802, 1033, 1035, 721, 721, 1398, 1041, + 1053, 1054, 1063, 349, 1057, 512, 334, 353, 355, 357, + 359, 361, 363, 365, 367, 114, 1536, 1536, 51, 1071, + 534, 1090, 1558, 721, 721, 1078, 1091, 1128, 1110, 1134, + 1120, 1146, 1164, 334, 1135, 1165, 1144, 372, 1136, 1156, + 1157, 51, 114, 372, 1161, 1167, 1179, 1183, 1187, 1188, + 1186, 1192, 1189, 195, 51, 802, 1191, 1195, 1199, 51, + 1206, 1209, 1210, 1218, 51, 1217, 51, 51, 51, 51, + 1227, 810, 1237, 1536, 51, 1244, 1256, 1272, 51, 372, + 721, 1280, 1275, 1277, 496, 496, 1298, 1281, 1284, 1285, + 51, 1290, 802, 51, 1293, 51, 1300, 1306, 1307, 1314, + 521, 1315, 1356, 1358, 1357, 1607, 1607, 1365, 1361, 1367, + 1374, 1364, 1616, 1616, 630, 630, 1423, 1409, 195, 51, + 372, 51, 51, 1363, 1379, 372, 1426, 372, 372, 372, + 372, 372, 372, 372, 372, 372, 372, 372, 1439, 1440, + 195, 334, 1447, 1457, 372, 1448, 1459, 1460, 372, 372, + 1466, 372, 372, 372, 1462, 372, 372, 372, 1464, 372, + 372, 1450, 1468, 372, 372, 372, 372, 334, 1430, 1470, + 372, 372, 1471, 1489, 1476, 372, 372, 372, 372, 372, + 372, 372, 372, 1485, 1488, 1482, 1492, 1490, 1519, 1500, + 1501, 1533, 1504, 202, 372, 1514, 1521, 372, 1534, 372, + 195, 195, 114, 1530, 114, 1531, 1540, 1544, 195, 1543, + 372, 1555, 1554, 1557, 349, 1559, 195, 195, 1560, 195, + 1562, 1568, 1575, 1579, 1583, 1420, 1584, 1594, 1595, 1586, + 1578, 1577, 1622, 1600, 1420, 203, 1601, 9, 1420, 334, + 195, 1623, 1624, 195, 1046, 556, 574, 925, 509, 926, + 1038, 626, 1420, 659, 510, 114, 349, 466, 114, 940, + 660, 33, 740, 334, 508, 467, 33, 536, 323, 34, + 216, 927, 103, 1420, 34, 933, 832, 824, 833, 856, + 334, 705, 857, 891, 334, 204, 205, 206, 207, 892, + 208, 209, 210, 211, 212, 213, 214, 215, 728, 893, + 216, 217, 218, 219, 220, 221, 222, 223, 327, 895, + 728, 753, 649, 651, 653, 354, 705, 574, 574, 574, + 574, 574, 574, 574, 574, 574, 574, 574, 574, 574, + 574, 574, 574, 347, 626, 131, 232, 113, 297, 626, + 138, 626, 626, 626, 626, 626, 626, 626, 626, 626, + 626, 626, 132, 114, 298, 139, 521, 54, 21, 334, + 334, 521, 521, 626, 1111, 626, 1212, 626, 1023, 626, + 626, 626, 1213, 1401, 1368, 1261, 811, 1576, 1545, 347, + 626, 347, 811, 1585, 521, 626, 1532, 1527, 1561, 811, + 931, 1050, 1432, 1618, 1375, 626, 626, 521, 521, 1051, + 347, 347, 521, 1052, 1454, 521, 1372, 521, 626, 521, + 521, 521, 521, 1046, 1551, 1556, 1610, 521, 1549, 1301, + 347, 521, 1609, 1475, 626, 521, 1020, 1302, 347, 334, + 822, 347, 1068, 521, 952, 1070, 521, 811, 521, 521, + 997, 1147, 624, 574, 521, 38, 521, 521, 521, 521, + 521, 521, 521, 521, 521, 521, 521, 927, 334, 872, + 302, 949, 521, 521, 577, 680, 684, 521, 521, 682, + 521, 521, 521, 521, 521, 521, 521, 686, 521, 521, + 688, 521, 521, 521, 521, 521, 521, 521, 521, 521, + 521, 114, 521, 521, 521, 521, 521, 521, 521, 521, + 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, + 521, 521, 521, 521, 689, 1225, 521, 839, 521, 859, + 521, 1380, 1287, 521, 426, 1310, 991, 927, 927, 521, + 1140, 1197, 1190, 1160, 1204, 927, 927, 927, 927, 927, + 1129, 927, 927, 1198, 927, 927, 927, 927, 927, 927, + 927, 927, 1196, 1267, 815, 1235, 927, 1088, 927, 927, + 927, 927, 927, 927, 704, 705, 927, 896, 1378, 1274, + 927, 927, 349, 927, 927, 927, 0, 1018, 0, 0, + 0, 850, 114, 1021, 0, 927, 0, 927, 0, 927, + 927, 0, 0, 927, 0, 927, 927, 927, 927, 927, + 927, 927, 927, 927, 927, 927, 927, 0, 927, 0, + 0, 927, 927, 0, 0, 927, 927, 0, 0, 0, + 0, 114, 0, 0, 0, 114, 0, 0, 0, 114, + 927, 927, 927, 927, 927, 0, 0, 0, 927, 927, + 0, 0, 927, 0, 392, 0, 334, 927, 927, 927, + 927, 927, 0, 0, 0, 927, 0, 927, 114, 0, + 0, 0, 0, 927, 927, 393, 394, 395, 396, 397, + 398, 399, 400, 401, 402, 0, 0, 0, 0, 517, + 0, 0, 425, 0, 425, 517, 0, 0, 927, 927, + 927, 927, 349, 927, 0, 0, 0, 0, 0, 0, + 927, 0, 38, 425, 425, 0, 38, 347, 0, 0, + 0, 334, 0, 0, 0, 0, 0, 38, 114, 114, + 0, 0, 38, 425, 0, 0, 38, 0, 0, 38, + 0, 425, 0, 334, 425, 0, 0, 0, 0, 0, + 517, 38, 38, 0, 0, 0, 38, 38, 0, 0, + 0, 0, 38, 0, 38, 38, 38, 38, 0, 0, + 0, 0, 38, 0, 0, 0, 38, 0, 38, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 38, 0, + 38, 38, 0, 38, 0, 0, 0, 38, 0, 0, + 0, 0, 0, 334, 334, 0, 0, 0, 0, 0, + 0, 334, 0, 0, 0, 0, 0, 38, 0, 334, + 334, 0, 334, 38, 38, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1569, 0, 0, 1569, 0, 0, 1568, - 3215, 1788, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1203, 0, 0, 0, 0, 0, 0, 0, 0, - 8735, 0, 1196, 0, 0, 0, 1196, 0, 0, 0, - 0, 0, 0, 197, 0, 0, 0, 0, 0, 0, - 0, 0, 153, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 4587, 0, 0, 0, 0, - 0, 0, 286, 4680, 1796, 0, 0, 0, 0, 0, + 0, 0, 0, 334, 0, 0, 334, 850, 850, 0, + 0, 0, 0, 0, 0, 850, 850, 850, 850, 850, + 0, 850, 850, 808, 850, 850, 850, 850, 850, 850, + 850, 0, 0, 0, 0, 0, 850, 574, 850, 850, + 850, 850, 850, 850, 0, 0, 850, 0, 0, 0, + 850, 850, 0, 850, 850, 850, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 850, 0, 850, 0, 850, + 850, 0, 0, 850, 0, 850, 850, 850, 850, 850, + 850, 850, 850, 850, 850, 850, 850, 0, 850, 0, + 0, 850, 850, 0, 0, 850, 850, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 4836, 4904, - 5144, 5348, 5688, 5892, 6028, 6164, 6300, 6436, 1187, 2889, - 0, 0, 0, 0, 0, 0, 58, 0, 0, 0, + 850, 850, 850, 850, 850, 0, 0, 0, 850, 850, + 0, 0, 850, 0, 0, 0, 0, 850, 850, 850, + 850, 850, 0, 347, 0, 850, 0, 850, 347, 347, + 0, 0, 0, 850, 850, 0, 0, 0, 0, 0, + 0, 0, 0, 340, 0, 0, 0, 0, 0, 0, + 0, 347, 0, 0, 0, 0, 0, 0, 850, 850, + 850, 850, 0, 850, 347, 347, 0, 0, 0, 347, + 850, 0, 347, 0, 347, 0, 347, 347, 347, 347, + 0, 0, 0, 0, 347, 0, 0, 0, 347, 0, + 0, 0, 347, 0, 0, 0, 0, 0, 0, 0, + 347, 0, 0, 347, 0, 347, 347, 0, 0, 0, + 0, 347, 0, 347, 347, 347, 347, 347, 347, 347, + 347, 347, 347, 347, 347, 0, 0, 0, 0, 347, + 347, 0, 0, 0, 347, 347, 347, 347, 347, 347, + 347, 347, 347, 347, 0, 347, 347, 0, 0, 347, + 347, 347, 347, 347, 0, 0, 347, 347, 0, 0, + 0, 347, 347, 347, 347, 347, 347, 347, 347, 808, + 0, 0, 0, 377, 808, 808, 0, 0, 0, 0, + 347, 0, 0, 347, 0, 347, 0, 347, 0, 0, + 347, 0, 0, 0, 0, 0, 347, 808, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 199, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 3258, 0, - 512, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 808, 808, 0, 0, 0, 808, 0, 0, 808, 0, + 808, 0, 808, 808, 808, 808, 0, 0, 0, 0, + 808, 0, 0, 0, 808, 0, 0, 0, 808, 0, + 0, 0, 0, 0, 0, 0, 808, 0, 0, 808, + 0, 808, 808, 0, 0, 0, 0, 808, 0, 808, + 808, 808, 808, 808, 808, 808, 808, 808, 808, 808, + 0, 0, 0, 0, 0, 808, 808, 347, 0, 0, + 808, 808, 808, 808, 808, 808, 0, 808, 808, 808, + 0, 808, 808, 0, 0, 808, 808, 808, 808, 340, + 0, 0, 808, 808, 340, 340, 0, 808, 808, 808, + 808, 808, 808, 808, 808, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 808, 340, 0, 808, + 0, 808, 0, 808, 0, 0, 808, 0, 0, 0, + 340, 340, 808, 0, 0, 340, 0, 0, 340, 0, + 340, 0, 340, 340, 340, 340, 0, 0, 0, 0, + 340, 0, 0, 0, 340, 0, 0, 0, 340, 0, + 0, 0, 0, 0, 0, 0, 340, 0, 0, 340, + 0, 340, 340, 0, 0, 0, 0, 340, 0, 340, + 340, 340, 340, 340, 340, 340, 340, 340, 340, 340, + 0, 0, 0, 0, 0, 340, 340, 0, 0, 0, + 340, 340, 340, 340, 340, 340, 0, 340, 340, 340, + 0, 340, 340, 0, 0, 340, 340, 340, 340, 377, + 0, 0, 340, 340, 377, 377, 0, 340, 340, 340, + 340, 340, 340, 340, 340, 0, 31, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 340, 377, 0, 340, + 0, 340, 0, 340, 0, 0, 340, 0, 0, 0, + 377, 377, 340, 0, 0, 377, 0, 0, 377, 0, + 377, 0, 377, 377, 377, 377, 0, 0, 0, 0, + 377, 0, 0, 0, 377, 0, 0, 0, 377, 0, + 0, 0, 0, 0, 0, 0, 377, 0, 0, 377, + 0, 377, 377, 0, 0, 0, 0, 377, 0, 377, + 377, 377, 377, 377, 377, 377, 377, 377, 377, 377, + 0, 0, 24, 347, 0, 377, 377, 0, 0, 347, + 377, 377, 0, 377, 377, 377, 0, 377, 377, 377, + 0, 377, 377, 0, 0, 377, 377, 377, 377, 0, + 0, 0, 377, 377, 0, 0, 0, 377, 377, 377, + 377, 377, 377, 377, 377, 347, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 377, 0, 0, 377, + 0, 377, 0, 0, 0, 37, 0, 0, 0, 0, + 0, 0, 377, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 347, 0, 0, 0, + 0, 347, 0, 347, 347, 347, 347, 347, 347, 347, + 347, 347, 347, 347, 347, 0, 0, 0, 0, 0, + 347, 0, 0, 0, 347, 347, 347, 347, 347, 347, + 347, 347, 347, 347, 0, 347, 347, 0, 0, 347, + 347, 347, 347, 347, 36, 0, 347, 347, 0, 0, + 0, 347, 347, 347, 347, 347, 347, 347, 347, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 347, 0, 0, 347, 0, 347, 0, 347, 0, 0, + 347, 0, 31, 31, 0, 0, 347, 31, 0, 0, + 0, 31, 0, 31, 0, 0, 31, 0, 31, 31, + 0, 31, 0, 31, 0, 31, 0, 31, 31, 31, + 31, 0, 0, 31, 31, 0, 0, 0, 25, 31, + 0, 31, 31, 31, 0, 0, 31, 31, 31, 0, + 31, 0, 0, 31, 0, 31, 31, 31, 31, 0, + 0, 0, 31, 31, 31, 0, 0, 31, 31, 31, + 0, 0, 0, 0, 0, 0, 31, 31, 0, 31, + 31, 35, 31, 31, 31, 0, 0, 0, 31, 24, + 0, 0, 0, 24, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 24, 0, 0, 0, 31, 24, + 0, 0, 0, 24, 31, 31, 24, 0, 0, 0, + 0, 0, 0, 31, 5, 0, 0, 0, 24, 24, + 0, 0, 0, 24, 24, 0, 0, 0, 0, 24, + 0, 24, 24, 24, 24, 0, 0, 0, 0, 24, + 0, 0, 37, 24, 0, 24, 37, 0, 0, 0, + 0, 0, 0, 0, 31, 24, 0, 37, 24, 0, + 24, 0, 37, 0, 24, 0, 37, 0, 0, 37, + 0, 0, 0, 0, 0, 0, 0, 1027, 0, 0, + 0, 37, 37, 0, 24, 0, 37, 37, 0, 21, + 24, 24, 37, 0, 37, 37, 37, 37, 0, 0, + 0, 0, 37, 0, 0, 0, 37, 0, 37, 0, + 0, 36, 0, 0, 0, 36, 0, 0, 37, 0, + 37, 37, 0, 37, 51, 0, 36, 37, 0, 0, + 0, 36, 0, 0, 0, 36, 0, 0, 36, 0, + 0, 0, 0, 0, 0, 0, 0, 37, 0, 0, + 36, 36, 0, 0, 37, 36, 36, 0, 0, 0, + 0, 36, 0, 36, 36, 36, 36, 0, 0, 0, + 0, 36, 0, 0, 0, 36, 0, 36, 0, 0, + 0, 0, 0, 0, 0, 25, 0, 36, 0, 25, + 36, 7, 36, 0, 0, 0, 36, 0, 0, 0, + 25, 0, 0, 0, 0, 25, 0, 0, 0, 25, + 0, 0, 25, 0, 0, 0, 36, 0, 0, 0, + 0, 0, 36, 36, 25, 25, 0, 0, 35, 25, + 25, 0, 35, 0, 1028, 25, 0, 25, 25, 25, + 25, 0, 0, 35, 0, 25, 0, 0, 35, 25, + 0, 25, 35, 0, 0, 35, 0, 0, 0, 0, + 0, 25, 0, 0, 25, 0, 25, 35, 35, 0, + 25, 5, 35, 35, 0, 51, 0, 52, 35, 0, + 35, 35, 35, 35, 0, 0, 51, 0, 35, 0, + 25, 51, 35, 0, 35, 51, 25, 25, 51, 0, + 0, 0, 0, 0, 35, 0, 0, 35, 0, 35, + 51, 51, 0, 35, 0, 51, 51, 0, 0, 0, + 0, 51, 0, 51, 51, 51, 51, 0, 0, 0, + 0, 51, 0, 35, 1027, 51, 0, 51, 51, 0, + 35, 0, 0, 0, 0, 0, 0, 51, 0, 51, + 51, 0, 51, 0, 51, 0, 51, 0, 51, 0, + 0, 51, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 51, 51, 0, 51, 0, 51, 51, + 0, 51, 0, 0, 51, 51, 51, 51, 51, 51, + 0, 0, 0, 0, 51, 0, 51, 0, 51, 0, + 51, 51, 0, 0, 0, 51, 0, 0, 51, 0, + 51, 0, 0, 51, 0, 51, 0, 0, 0, 51, + 51, 51, 0, 0, 0, 51, 51, 0, 0, 0, + 0, 51, 0, 51, 51, 51, 51, 0, 0, 51, + 0, 51, 0, 0, 0, 51, 0, 51, 7, 0, + 0, 0, 52, 0, 0, 0, 0, 51, 0, 0, + 51, 0, 51, 52, 0, 0, 51, 0, 52, 0, + 0, 0, 52, 0, 0, 52, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 51, 52, 52, 0, + 0, 1028, 52, 52, 0, 51, 0, 0, 52, 0, + 52, 52, 52, 52, 0, 0, 51, 0, 52, 0, + 0, 51, 52, 0, 52, 51, 0, 0, 51, 0, + 0, 0, 0, 0, 52, 0, 0, 52, 0, 52, + 51, 51, 0, 52, 52, 51, 51, 0, 52, 0, + 0, 51, 0, 51, 51, 51, 51, 0, 0, 52, + 0, 51, 0, 52, 52, 51, 0, 51, 52, 0, + 0, 52, 0, 0, 0, 0, 0, 51, 0, 0, + 51, 0, 51, 52, 52, 0, 51, 0, 52, 52, + 0, 0, 0, 0, 52, 0, 52, 52, 52, 52, + 0, 0, 0, 0, 52, 0, 51, 0, 52, 0, + 52, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 52, 0, 56, 52, 0, 52, 0, 0, 0, 52, + 57, 24, 58, 25, 0, 0, 26, 59, 0, 60, + 61, 27, 62, 63, 64, 28, 0, 0, 0, 52, + 0, 65, 0, 66, 30, 67, 68, 69, 70, 0, + 0, 32, 0, 0, 0, 71, 33, 0, 72, 73, + 34, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 74, 0, 36, 0, 37, 75, 0, 0, 38, 0, + 76, 77, 78, 79, 80, 81, 39, 40, 82, 83, + 41, 84, 0, 85, 0, 0, 86, 87, 0, 811, + 88, 89, 0, 0, 0, 811, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 90, 91, 92, 93, 94, + 0, 0, 0, 95, 0, 0, 0, 96, 0, 0, + 0, 0, 97, 98, 99, 100, 101, 0, 0, 0, + 102, 811, 103, 0, 0, 0, 0, 0, 104, 105, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1569, 237, 0, 0, 0, 0, 0, 0, - 0, 3338, 320, 3381, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 3633, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 1205, 0, 0, 0, 0, 0, - 0, 3633, 1202, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 2421, - 0, 2931, 420, 2551, 0, 0, 0, 2681, 2551, 0, - 0, 0, 0, 0, 1203, 0, 0, 0, 152, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1199, 2785, 0, 0, 1196, 0, 3633, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 146, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 1605, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 3913, 0, 0, 0, 0, 0, - 0, 0, 3424, 3467, 0, 0, 0, 0, 2275, 1569, - 1569, 0, -10, 0, 7517, 1569, 1595, 0, 0, 245, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 453,11977, 0, - 0, 0, 0, 3633, 0, 0, 0, 0, 0, 0, - 0, 0,12366, 0, 0, 0, 0, 0, 0, 0, - 711, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 604, 693, 0, 0, 1228, 0, 0, 0, 0, 0, - 165, 0, 0, 4110, 1225, 0, 0, 0, 670, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 1982, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1199, 0, 0, 6555, 0, 176, 0, - 0, 0, 0, 0, 0, 9346, 0, 0, 0, 0, - 0, 0, 5, 802, 0, 0, 0, 1227, 0, 0, - 0, 0, 1202, 0, 0, 0, 3633, 0, 3633, 0, - 4269, 0, 0, 0, 0, -191, 0, 0, 0, 0, - 174, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 5008, 5076, 5212, 5280, 5416, 5484, 5552, 5620, 5756, 5824, - 5960, 6096, 6232, 6368, 6492, 0, 0, 675, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 3913, 0, 0, 0, 0, 2275, 0, 0, 0, 0, - 1183, 9694, 0, 0, 0, 8892, 0, 0, 755, 0, - 0, 0, 0, 0, 0, 683, 698, 0, 0, 1230, - 0, 0, 0, 0, 1236, 0, 0, 0, 0, 0, - 0,11556, 0, 0, 0, 758, 0, 0, 0, 9049, -12442, 0, 0, 759, 766, 796, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 722, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 1238, 0, 0, 0, 3699, - 0, 0, 177, 0, 98, 3792, 0, 0, 0, 0, - 0, 1232, 0, 0, 0, 0, 0, 1239, 0, 0, - 0, 0, 0, 0, 0, 0, 0, -51, 676, 0, - 0, 0, 0, 0, 1237, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 9346, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 567, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, -181, 0, 472, 0, 0, 0, 0, 0, - 0, 0, 0, -10, 0, 0, 0, 0, 9049, 7674, - 0, 1240, 0, 700, 0, 0, 0, 0, 1244, 0, - 1201, 1206, 0, 0, 0, 0, 0, 1245, 9206, 0, - 0, 0, 0,12474, 0, 0, 0, 798, 0, 0, - 0, 0, 0, 0, 2149, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 3951, - 0, 4428, 1246, 0, 0, 0, 1243, 0, 0, 0, - 0, 333, 0, 0, 0, 0, 798, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 657, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 807, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 1247, 0, - 0, 0, 0, 0, 814, 820, 0, 0, 0, 0, - 0, 0, 0, 1248, 608, 1250, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 4110, 0, 0, - 0, 0, 0, 1249, 0, 0, 333, 0, 0, 846, - 0, 1248, 0, 0, 0, 9346, 0, 643, 654, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1230, 9540, 0, 0, 0, 0, 0,12605, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 630, 0, 737, 0, 0, 0, 0, 1255, 0, - 736, 1252, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1261, 0, 7343, 0, 0, 0, 0, 0, - 0, 9346, 0, 0, 0, 0, 0, 0, 0, -154, - 484, 0, 0, 0, 0, 0,12681,12366, 0, 218, - 218, 218, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0,12724, 0, -285, 0, 1263, 1263, 1263, 0, - 0, 0, 0, 0, 1259, 0, 0, 0, -182, 0, - 0, 0, 0, 0, 0, 0, 0, 0,12767, 0, - 0, 0, 9997, 0, 0, 1264, 0, 0, 369, 0, - 0, 0, 533, 0, 0, 0, 0, 0, 0, 0, - 0, 1262, 0, 1267, 0, 0, 0, 3172, 1260, 537, - 0, 0, -269, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 3089, - 0, 0, 0, 0, 9799,10083, 0, 0, 0, 642, - 0, 0, 0, 0, 0, 0, 0, 0, 478, 0, - 0,12148, 0, 0, 9898, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0,12216, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0,10177, - 0, 9799, 0, 0, 642, 0, 0, 0, 0, 453, - 0, 0, 0, 0, 0, 0, 453, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 1096, - 457, 0,10219, 0, 0, 0, 4810, 0, 3089, 0, - 0, 0, 3089, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 271, 0, 1272, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 3089, 0, 543, - 0, 494, 0, 0, 0, 0, 0, 0, 0,12366, - 819, 0, 0, 0, 0, 0, 0, 1235, 0, 516, - 0, 0, 0, 0, 0, 0, 0, 824, 0, 0, - 0, 0, 0, 0, 0, 0, 1265, 0,12366,12366, - 0,12398, 0, 0, 0, 0, 0, 0, 1268,12991, - 0, 1269,12366,11692, 1270,12366, 0, 0, 0, 0, - 0, 0, 1271, 0, 0, 0,12961, 0, 0, 0, -12366, 0, 0, 0, 1273, 0, 0, 378, 0,12885, -12923, 0, 0, 0, 1278, 0, 0, 0, 0, 0, - 0, 1279, 0, 0,12366, 0, 664, 0, 825, 0, - 0, 0, 0, 0, 861, 0,12809,12847, 0, 0, - 0, 0, 0, 0, 0, 0, 1325, 0, 1393, 0, - 0, 0, 829, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 571, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0,12961, 9534,11864, 0, 571, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1225, 1225, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, - }; - protected static readonly short [] yyGindex = { 0, - 0, 1607, 0, 0, 0, 2, -16, -180, -48, -43, - 0, 1647, 1655, 101, 0, 4, 0, 0, 0, 0, - 0,-1020, -693, -215, -482, 0, 0, 0, 0, 0, - -224, 0, 0, 0, 703, 0, 811, 0, 0, 0, - 0, 560, 563, -17, -226, 0, -46, 0, 393, 0, - 430, -573, -569, -553, -471, -469, -462, -444, -435, 0, --1042,-1171, 0, 1, 0, 129, 0,-1095, 0, 0, - 0, -44, 220, 0, 0, 0, 258,-1073, 0, -273, - -293, 992, 0, 0, 0, -899, 212, 0, 0, -501, - 0, 0, 281, 0, 0, 249, 0, 0, 287, 0, - -579, -976, 0, 0, 0, 0, 0, 382, -13, 0, - 0, 815, 816, 822, 988, -528, 0, 0, -321, 823, - 377, 0,-1327, 0, 0, 0, 0, 0, 0, 0, - 0, 182, 0, 0, 0, 0, 0, 0, 0, 0, - 432, 0, 0, 0, 0, -335, 362, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 441, 0, -514, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 201, 0, - 0, 288, 0, 0, 283, 285, 210, 0, 0, 0, - 0, 0, 0, 0, 0, 511, 0, 0, 0, 0, - -39, 0, 552, -173, 0, 0, 364, 0, 421, 0, - 882, 0, 1204, -286, -265, -56, 947, 0, 524, 0, - -30, 10, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, -256, 0, 367, 0, -333, 0, -773, 0, 0, - 0, 832, 0, -296, -126, 1012, 0, 917, 0, 1155, - 1368, 1053, 0, 0, 731, 1678, 0, 0, 0, 0, - 1028, 0, 0, 0, 0, 0, -506, 1416, 0, 0, - 0, 0, 0, 1190, 855, 845, 748, 852, 1356, 1358, - 1355, 1357, 1359, 0, 1360, 0, -611, 0, 0, 968, - 1207, -714, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, -298, 0, 0, 0, 0, -458, 0, 585, - 0, 487, 0, 573, 0, 0, 0, 646, -534, -5, - -313, -3, 0, 1618, 0, 68, 0, 70, 74, 99, - 125, 142, 149, 156, 157, 163, 171, 0, -674, 0, - -7, 0, 0, 782, 0, 707, 0, 0, 0, 0, - 685, -322, 762, -863, 0, 803, -461, 0, 0, 0, - 0, 0, 0, 708, 0, 0, 701, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 634, 0, 0, 0, 0, 0, 0, 0, - 0, -27, 0, 1274, 0, 0, 0, 876, 0, 0, - 0, 0, 0, 0, -168, 0, 0, 0, 0, 0, - 1374, 1150, 0, 0, 0, 1376, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 517, 0, 0, 0, 0, - 0, 0, 0, 0, 636, 0, 0, 0, 0, 0, - 0, 64, 957, 0, 0, 0, 962, - }; - protected static readonly short [] yyTable = { 109, - 741, 189, 233, 111, 518, 18, 43, 234, 433, 472, - 690, 155, 521, 156, 494, 747, 451, 436, 577, 432, - 476, 292, 538, 192, 786, 562, 115, 319, 257, 712, - 406, 514, 576, 830, 831, 549, 601, 1028, 502, 1150, - 325, 330, 326, 331, 251, 337, 885, 794, 886, 311, - 800, 258, 1185, 1186, 904, 303, 364, 959, 372, 310, - 335, 14, 544, 356, 629, 312, 924, 314, 115, 782, - 1280, 673, 115, 363, 943, 371, 190, 340, 1033, 485, - 20, 683, 316, 1079, 160, 797, 161, 1287, 1, 1061, - 162, 1063, 259, 916, 818, 1080, 918, 674, 318, 717, - 487, 946, 1174, 1217, 1345, 791, 820, 985, 488, 528, - 229, 350, 403, 351, 1080, 163, 1157, 1002, 507, 1481, - 1482, 197, 508, 587, 404, 408, 755, 801, 1011, 675, - 288, 1144, 47, 588, 351, 231, 846, 510, 289, 109, - 233, 164, 476, 111, 639, 434, 290, 792, 47, 436, - 1223, 155, 197, 156, 440, 441, 349, 943, 165, 1473, - 1174, 489, 943, 486, 943, 166, 115, 943, 943, 660, - 943, 943, 167, 168, 196, 816, 1514, 1216, 925, 169, - 629, 436, 629, 450, 946, 797, 586, 170, 434, 946, - 2, 946, 943, 1021, 946, 946, 761, 946, 946, 1234, - 477, 291, 336, 1387, 350, 1033, 290, 935, 872, 472, - 1353, 481, 260, 819, 735, 720, 482, 451, 577, 946, - 739, 895, 887, 15, 160, 290, 161, 351, 448, 475, - 162, 821, 576, 676, 480, 1158, 352, 629, 191, 797, - 577, 352, 492, 684, 6, 562, 1455, 943, 511, 1081, - 512, 1062, 249, 1064, 257, 163, 3, 4, 5, 6, - 366, 291, 524, 537, 257, 657, 1346, 541, 1081, 1224, - 493, 562, 546, 1479, 946, 497, 499, 490, 1474, 543, - 291, 164, 231, 47, 548, 1489, 442, 1490, 1336, 545, - 525, 1204, 1337, 817, 115, 47, 899, 533, 165, 535, - 691, 250, 534, 497, 513, 166, 568, 16, 722, 536, - 1523, 1093, 167, 168, 959, 551, 552, 1365, 993, 169, - 359, 231, 477, 477, 1076, 1354, 115, 170, 1388, 577, - 584, 721, 1034, 561, 1036, 563, 806, 1039, 1451, 896, - 583, 983, 619, 620, 847, 387, 899, 750, 115, 1103, - 761, 475, 598, 959, 54, 605, 606, 607, 608, 609, - 610, 611, 612, 613, 614, 615, 359, 366, 641, 643, - 642, 644, 647, 1375, 366, 1241, 366, 1131, 366, 249, - 1030, 388, 1500, 1417, 233, 1444, 94, 637, 1031, 434, - 767, 770, 991, 447, 661, 1310, 357, 1359, 1319, 698, - 436, 1012, 1405, 1406, 844, 1408, 1019, 47, 1000, 1205, - 877, 783, 1520, 802, 901, 804, 1427, 805, 746, 1434, - 997, 94, 366, 1096, 723, 1098, 1099, 261, 250, 2, - 1524, 285, 286, 287, 1450, 293, 294, 472, 655, 701, - 307, 308, 20, 710, 358, 718, 845, 315, 1156, 317, - 807, 321, 677, 564, 694, 1163, 333, 334, 1472, 577, - 900, 389, 390, 751, 901, 959, 746, 476, 477, 502, - 708, 959, 784, 576, 686, 349, 472, 931, 687, 1188, - 370, 892, 839, 711, 699, 760, 42, 48, 231, 769, - 1360, 1068, 352, 349, 813, 737, 231, 598, 231, 745, - 115, 6, 436, 658, 659, 359, 768, 771, 992, 671, - 565, 1088, 231, 1089, 752, 754, 642, 453, 1486, 687, - 1317, 642, 1165, 350, 772, 642, 342, 746, 793, 774, - 290, 891, 441, 1320, 577, 759, 1228, 290, 860, 688, - 642, 350, 893, 688, 442, 454, 351, 981, 199, 1496, - 349, 814, 787, 561, 1196, 563, 661, 1497, 290, 741, - 352, 734, 861, 437, 351, 741, 438, 642, 115, 1318, - 1487, 194, 413, 976, 453, 352, 808, 808, 352, 561, - 687, 563, 1321, 231, 661, 291, 642, 413, 1104, 862, - 933, 642, 912, 441, 115, 827, 642, 829, 350, 735, - 642, 1230, 454, 352, 688, 442, 837, 352, 897, 352, - 352, 352, 352, 1017, 741, 642, 734, 352, 1498, 1275, - 315, 351, 824, 370, 786, 411, 863, 824, 824, 649, - 833, 200, 245, 864, 1007, 352, 246, 342, 194, 194, - 642, 342, 642, 337, 115, 94, 115, 477, 330, 249, - 521, 115, 1261, 351, 330, 414, 1262, 397, 398, 194, - 415, 642, 416, 515, 879, 417, 418, 803, 419, 420, - 414, 1069, 1263, 391, 392, 415, 475, 416, 412, 532, - 417, 418, 883, 419, 420, 342, 247, 859, 249, 337, - 365, 497, 642, 712, 244, 257, 1261, 1072, 250, 1069, - 1262, 337, 541, 330, 337, 337, 745, 662, 907, 366, - 367, 737, 414, 745, 739, 913, 1263, 415, 337, 416, - 884, 350, 417, 418, 640, 419, 420, 937, 641, 368, - 115, 921, 115, 248, 1049, 662, 1341, 250, 657, 939, - 369, 908, 1243, 1260, 351, 421, 926, 927, 640, 1355, - 194, 194, 641, 745, 1264, 919, 1265, 920, 352, 570, - 431, 869, 1243, 1266, 477, 922, 571, 787, 1373, 262, - 477, 352, 824, 589, 840, 640, 337, 115, 572, 641, - 115, 1267, 337, 590, 1041, 361, 841, 1260, 337, 1243, - 1268, 337, 337, 598, 437, 661, 1114, 838, 1264, 598, - 1265, 824, 650, 745, 318, 337, 1124, 1266, 1115, 225, - 937, 226, 194, 562, 318, 937, 668, 937, 724, 976, - 937, 937, 939, 937, 937, 1267, 984, 939, 350, 939, - 701, 435, 939, 939, 1268, 939, 939, 337, 194, 413, - 745, 350, 1153, 839, 668, 562, 527, 973, 94, 493, - 194, 351, 709, 668, 360, 677, 570, 965, 194, 528, - 1015, 361, 1018, 571, 351, 352, 998, 280, 1020, 280, - 690, 332, 94, 1001, 280, 572, 529, 362, 1187, 1049, - 562, 1361, 352, 1009, 337, 745, 352, 337, 337, 352, - 318, 352, 94, 1029, 753, 361, 352, 933, 1438, 665, - 937, 1215, 194, 693, 321, 194, 399, 694, 665, 342, - 321, 437, 939, 342, 477, 337, 342, 322, 342, 950, - 951, 1053, 414, 342, 318, 364, 824, 415, 824, 416, - 1058, 824, 417, 418, 757, 419, 420, 664, 194, 194, - 393, 394, 757, 1048, 1307, 225, 664, 228, 472, 1160, - 1161, 1307, 44, 451, 395, 396, 400, 342, 1284, 1277, - 1491, 677, 1169, 113, 401, 727, 194, 194, 1055, 728, - 1056, 501, 1057, 361, 337, 745, 337, 501, 497, 753, - 933, 753, 296, 753, 736, 933, 194, 933, 508, 909, - 933, 933, 402, 933, 933, 337, 337, 1511, 405, 168, - 194, 168, 318, 168, 439, 113, 1529, 1530, 115, 113, - 774, 521, 787, 443, 774, 337, 774, 824, 774, 824, - 824, 763, 1100, 337, 758, 763, 337, 763, 758, 763, - 270, 270, 758, 329, 329, 225, 364, 364, 364, 270, - 364, 364, 753, 364, 330, 364, 446, 330, 753, 473, - 753, 1107, 337, 337, 329, 337, 337, 56, 474, 477, - 502, 335, 493, 415, 701, 415, 502, 64, 64, 65, - 933, 64, 295, 65, 296, 880, 1132, 745, 787, 881, - 471, 231, 822, 762, 415, 415, 822, 364, 1048, 364, - 1143, 495, 364, 826, 233, 493, 1172, 826, 493, 434, - 1027, 1173, 817, 113, 415, 194, 181, 757, 181, 496, - 181, 757, 415, 1136, 1137, 415, 824, 1105, 976, 1106, - 233, 561, 1168, 563, 979, 434, 979, 194, 156, 436, - 156, 765, 115, 765, 493, 163, 115, 163, 517, 115, - 625, 626, 627, 628, 522, 329, 329, 542, 824, 1100, - 1160, 1161, 1352, 561, 1172, 563, 1201, 231, 337, 1173, - 384, 385, 386, 115, 337, 164, 1352, 164, 115, 890, - 337, 890, 362, 605, 337, 605, 1242, 1259, 67, 1238, - 67, 1173, 555, 187, 1383, 187, 1384, 337, 561, 157, - 563, 157, 120, 523, 120, 824, 1242, 285, 127, 285, - 127, 1173, 292, 115, 292, 526, 452, 329, 351, 443, - 1501, 1502, 547, 824, 581, 493, 194, 525, 525, 337, - 115, 1259, 351, 1242, 642, 642, 1291, 591, 1173, 453, - 653, 113, 582, 329, 1238, 623, 624, 194, 355, 1148, - 1149, 672, 454, 621, 622, 329, 692, 456, 629, 630, - 1315, 1316, 457, 329, 458, 459, 460, 461, 656, 695, - 719, 697, 462, 113, 725, 726, 463, 749, 773, 1312, - 1325, 766, 775, 1344, 776, 777, 1347, 778, 464, 796, - 795, 465, 338, 466, 798, 113, 341, 342, 343, 344, - 345, 346, 347, 348, 811, 799, 812, 329, 826, 828, - 329, 832, 848, 849, 194, 437, 701, 467, 851, 852, - 855, 42, 867, 873, 874, 196, 875, 876, 882, 902, - 1362, 898, 817, 903, 905, 910, 914, 194, 915, 929, - 923, 945, 947, 329, 329, 701, 701, 940, 701, 952, - 34, 1418, 194, 954, 961, 960, 194, 964, 969, 701, - 971, 966, 701, 977, 963, 989, 359, 990, 1445, 999, - 1006, 329, 329, 1326, 993, 511, 1024, 701, 1013, 1025, - 1038, 1457, 1459, 1042, 1094, 1059, 1065, 1051, 1095, 359, - 1075, 1066, 745, 1077, 1312, 1067, 1087, 1091, 1097, 1109, - 1117, 701, 359, 1113, 493, 1118, 1119, 359, 1445, 1445, - 232, 1116, 359, 194, 359, 359, 359, 359, 1121, 33, - 1122, 1467, 359, 1125, 1135, 1181, 359, 1139, 1138, 1151, - 359, 194, 194, 1146, 373, 1164, 1171, 1198, 359, 1195, - 1203, 359, 1211, 359, 1200, 1206, 1214, 113, 1215, 1218, - 1220, 1225, 585, 1229, 745, 374, 375, 376, 377, 378, - 379, 380, 381, 382, 383, 1445, 1226, 359, 1227, 1233, - 1276, 1273, 1293, 1322, 1278, 1281, 1288, 1335, 1314, 1339, - 1279, 1340, 1357, 1350, 477, 477, 1349, 1367, 329, 1358, - 1369, 745, 1360, 1370, 1372, 1374, 1380, 1376, 194, 1378, - 338, 1516, 1516, 1386, 1381, 1397, 1409, 1394, 1525, 1525, - 329, 1391, 1398, 598, 598, 113, 1401, 1399, 1428, 194, - 1410, 1483, 31, 359, 1413, 1423, 1430, 194, 1442, 1440, - 1443, 550, 329, 1449, 1488, 585, 1439, 1453, 1464, 1452, - 585, 113, 585, 585, 585, 585, 585, 585, 585, 585, - 585, 585, 585, 1463, 1466, 1469, 1471, 1468, 1477, 1484, - 1493, 1492, 1503, 1495, 585, 1487, 585, 1486, 585, 1509, - 585, 585, 585, 1510, 1531, 1532, 1533, 9, 975, 538, - 606, 860, 496, 616, 617, 618, 585, 861, 550, 550, - 550, 550, 550, 550, 550, 550, 550, 550, 550, 550, - 550, 550, 550, 550, 967, 497, 453, 34, 607, 29, - 676, 34, 21, 454, 506, 495, 29, 337, 521, 30, - 313, 329, 34, 30, 868, 585, 791, 34, 208, 759, - 767, 34, 768, 96, 34, 827, 760, 828, 792, 664, - 829, 317, 329, 831, 687, 664, 34, 34, 344, 642, - 123, 34, 34, 105, 288, 130, 124, 34, 106, 34, - 34, 34, 34, 289, 131, 642, 230, 34, 53, 21, - 1043, 34, 959, 34, 1290, 1141, 33, 113, 1142, 113, - 33, 1485, 1454, 34, 1282, 34, 34, 857, 34, 1494, - 1470, 33, 34, 1441, 1436, 1329, 33, 870, 986, 987, - 33, 982, 1342, 33, 1527, 988, 1364, 194, 1286, 329, - 550, 1289, 34, 1460, 1458, 33, 33, 1519, 34, 34, - 33, 33, 1465, 1221, 113, 1518, 33, 113, 33, 33, - 33, 33, 329, 1385, 1333, 955, 33, 1005, 1222, 24, - 33, 25, 33, 934, 26, 763, 593, 329, 1078, 27, - 890, 329, 33, 28, 33, 33, 866, 33, 298, 810, - 553, 33, 30, 888, 631, 633, 194, 632, 634, 32, - 780, 635, 928, 636, 33, 1294, 1212, 1208, 34, 31, - 797, 33, 1159, 31, 407, 194, 1071, 1120, 33, 1133, - 36, 1060, 37, 1090, 31, 1128, 38, 32, 1192, 31, - 1126, 1292, 1022, 31, 39, 40, 31, 651, 41, 652, - 836, 322, 1197, 756, 0, 0, 957, 0, 31, 31, - 956, 0, 0, 31, 31, 0, 329, 329, 0, 31, - 0, 31, 31, 31, 31, 0, 0, 290, 0, 31, - 194, 194, 0, 31, 0, 31, 0, 0, 194, 0, - 0, 0, 0, 0, 0, 31, 194, 194, 31, 194, - 31, 0, 0, 0, 31, 1332, 0, 0, 0, 0, - 506, 0, 0, 0, 0, 506, 506, 1332, 0, 194, - 0, 0, 194, 0, 31, 0, 0, 0, 0, 0, - 1332, 31, 323, 329, 0, 0, 0, 0, 506, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 1332, - 0, 506, 506, 0, 0, 0, 506, 0, 0, 506, - 0, 506, 329, 506, 506, 506, 506, 0, 0, 0, - 0, 506, 0, 0, 0, 506, 0, 0, 0, 506, - 0, 0, 0, 0, 0, 0, 0, 506, 0, 0, - 506, 0, 506, 506, 0, 113, 0, 0, 506, 0, - 506, 506, 506, 506, 506, 506, 506, 506, 506, 506, - 506, 0, 0, 0, 0, 0, 506, 506, 0, 0, - 0, 506, 506, 0, 506, 506, 506, 506, 506, 506, - 506, 862, 506, 506, 0, 506, 506, 506, 506, 506, - 506, 506, 506, 506, 506, 0, 506, 506, 506, 506, - 506, 506, 506, 506, 506, 506, 506, 506, 506, 506, - 506, 506, 506, 506, 506, 506, 506, 506, 0, 0, - 506, 0, 506, 0, 506, 0, 0, 506, 0, 0, - 0, 0, 0, 506, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 32, 0, 0, 0, 32, 0, - 0, 393, 0, 0, 0, 0, 0, 393, 0, 32, - 0, 0, 0, 0, 32, 0, 0, 0, 32, 113, - 0, 32, 0, 113, 0, 0, 113, 0, 0, 0, - 0, 0, 0, 32, 32, 550, 0, 0, 32, 32, - 0, 0, 329, 393, 32, 0, 32, 32, 32, 32, - 113, 0, 0, 0, 32, 113, 0, 0, 32, 0, - 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 32, 0, 0, 32, 0, 32, 0, 0, 0, 32, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 113, 0, 0, 0, 0, 0, 0, 0, 785, 32, - 0, 329, 0, 0, 0, 32, 32, 113, 330, 0, - 0, 0, 0, 393, 330, 0, 393, 393, 393, 393, - 329, 393, 0, 393, 393, 0, 393, 393, 393, 393, - 393, 0, 393, 393, 393, 393, 0, 393, 393, 393, - 393, 393, 393, 393, 393, 393, 393, 393, 393, 393, - 393, 393, 393, 393, 393, 393, 393, 393, 393, 0, - 0, 0, 0, 330, 0, 393, 0, 0, 393, 0, - 0, 0, 0, 0, 393, 329, 329, 0, 0, 0, - 0, 0, 0, 329, 0, 0, 0, 862, 862, 0, - 0, 329, 329, 0, 329, 862, 862, 862, 862, 862, - 0, 862, 862, 0, 862, 862, 862, 862, 862, 862, - 862, 862, 0, 0, 329, 0, 862, 329, 862, 862, - 862, 862, 862, 862, 337, 0, 862, 0, 0, 0, - 862, 862, 0, 862, 862, 862, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 862, 0, 862, 0, 862, - 862, 0, 0, 862, 0, 862, 862, 862, 862, 862, - 862, 862, 862, 862, 862, 862, 862, 0, 862, 0, - 0, 862, 862, 0, 0, 862, 862, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 862, 862, 862, 862, 862, 0, 0, 0, 862, 862, - 0, 0, 862, 0, 0, 0, 0, 862, 862, 862, - 862, 862, 0, 0, 0, 862, 0, 862, 0, 0, - 0, 0, 0, 862, 862, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 862, 862, - 862, 862, 0, 862, 785, 785, 0, 0, 0, 0, - 862, 0, 785, 785, 785, 785, 785, 0, 785, 785, - 742, 785, 785, 785, 785, 785, 785, 785, 0, 0, - 0, 0, 0, 785, 0, 785, 785, 785, 785, 785, - 785, 0, 0, 785, 0, 0, 0, 785, 785, 0, - 785, 785, 785, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 785, 0, 785, 0, 785, 785, 0, 0, - 785, 0, 785, 785, 785, 785, 785, 785, 785, 785, - 785, 785, 785, 785, 0, 785, 0, 0, 785, 785, - 0, 0, 785, 785, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 785, 785, 785, - 785, 785, 0, 0, 0, 785, 785, 0, 0, 785, - 0, 0, 0, 0, 785, 785, 785, 785, 785, 0, - 337, 0, 785, 0, 785, 337, 337, 0, 0, 0, - 785, 785, 0, 0, 0, 0, 0, 0, 0, 0, - 330, 0, 0, 0, 0, 0, 0, 0, 337, 0, - 0, 0, 0, 0, 0, 785, 785, 785, 785, 0, - 785, 337, 337, 0, 0, 0, 337, 785, 0, 337, - 0, 337, 0, 337, 337, 337, 337, 0, 0, 0, - 0, 337, 0, 0, 0, 337, 0, 0, 0, 337, - 0, 0, 0, 0, 0, 0, 0, 337, 0, 0, - 337, 0, 337, 337, 0, 0, 0, 0, 337, 0, - 337, 337, 337, 337, 337, 337, 337, 337, 337, 337, - 337, 337, 0, 0, 0, 0, 337, 337, 0, 0, - 0, 337, 337, 337, 337, 337, 337, 337, 337, 337, - 337, 0, 337, 337, 0, 0, 337, 337, 337, 337, - 337, 0, 0, 337, 337, 0, 0, 0, 337, 337, - 337, 337, 337, 337, 337, 337, 742, 0, 0, 0, - 367, 742, 742, 0, 0, 0, 0, 337, 0, 0, - 337, 0, 337, 0, 337, 0, 0, 337, 0, 0, - 0, 0, 0, 337, 742, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 742, 742, 0, - 0, 0, 742, 0, 0, 742, 0, 742, 0, 742, - 742, 742, 742, 0, 0, 0, 0, 742, 0, 0, - 0, 742, 0, 0, 0, 742, 0, 0, 0, 0, - 0, 0, 0, 742, 0, 0, 742, 0, 742, 742, - 0, 0, 0, 0, 742, 0, 742, 742, 742, 742, - 742, 742, 742, 742, 742, 742, 742, 0, 0, 0, - 0, 0, 742, 742, 337, 0, 0, 742, 742, 742, - 742, 742, 742, 0, 742, 742, 742, 0, 742, 742, - 0, 0, 742, 742, 742, 742, 330, 0, 0, 742, - 742, 330, 330, 0, 742, 742, 742, 742, 742, 742, - 742, 742, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 742, 330, 0, 742, 0, 742, 0, - 742, 0, 0, 742, 0, 0, 0, 330, 330, 742, - 0, 0, 330, 0, 0, 330, 0, 330, 0, 330, - 330, 330, 330, 0, 0, 0, 0, 330, 0, 0, - 0, 330, 0, 0, 0, 330, 0, 0, 0, 0, - 0, 0, 0, 330, 0, 0, 330, 0, 330, 330, - 0, 0, 0, 0, 330, 0, 330, 330, 330, 330, - 330, 330, 330, 330, 330, 330, 330, 0, 0, 0, - 0, 0, 330, 330, 0, 0, 0, 330, 330, 330, - 330, 330, 330, 0, 330, 330, 330, 0, 330, 330, - 362, 0, 330, 330, 330, 330, 367, 0, 0, 330, - 330, 367, 367, 0, 330, 330, 330, 330, 330, 330, - 330, 330, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 330, 367, 0, 330, 0, 330, 0, - 330, 0, 0, 330, 0, 0, 0, 367, 367, 330, - 0, 0, 367, 0, 0, 367, 0, 367, 0, 367, - 367, 367, 367, 0, 0, 0, 0, 367, 0, 0, - 0, 367, 0, 0, 0, 367, 0, 0, 0, 0, - 0, 0, 0, 367, 0, 0, 367, 0, 367, 367, - 0, 0, 0, 0, 367, 0, 367, 367, 367, 367, - 367, 367, 367, 367, 367, 367, 367, 0, 0, 0, - 337, 0, 367, 367, 0, 0, 337, 367, 367, 0, - 367, 367, 367, 0, 367, 367, 367, 0, 367, 367, - 0, 0, 367, 367, 367, 367, 0, 0, 0, 367, - 367, 0, 0, 0, 367, 367, 367, 367, 367, 367, - 367, 367, 337, 0, 0, 0, 0, 0, 27, 0, - 0, 0, 0, 367, 0, 0, 367, 0, 367, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 367, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 337, 0, 0, 0, 0, 337, 0, - 337, 337, 337, 337, 337, 337, 337, 337, 337, 337, - 337, 337, 0, 0, 587, 0, 0, 337, 0, 0, - 0, 337, 337, 337, 337, 337, 337, 337, 337, 337, - 337, 0, 337, 337, 0, 0, 337, 337, 337, 337, - 337, 27, 0, 337, 337, 0, 0, 0, 337, 337, - 337, 337, 337, 337, 337, 337, 362, 0, 0, 0, - 0, 0, 362, 0, 0, 0, 0, 337, 0, 0, - 337, 0, 337, 0, 337, 0, 0, 337, 0, 0, - 0, 0, 0, 337, 5, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 587, 362, 0, - 0, 0, 587, 0, 587, 587, 587, 587, 587, 587, - 587, 587, 587, 587, 587, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 587, 957, 587, 0, - 587, 0, 587, 587, 587, 0, 0, 0, 0, 362, - 0, 0, 0, 0, 362, 0, 362, 362, 362, 362, - 362, 362, 362, 362, 362, 362, 362, 0, 0, 0, - 0, 0, 0, 362, 0, 0, 0, 362, 362, 0, - 362, 362, 362, 0, 362, 362, 362, 0, 362, 362, - 0, 0, 362, 362, 362, 362, 0, 587, 0, 362, - 362, 0, 0, 0, 362, 362, 362, 362, 362, 362, - 362, 362, 0, 0, 0, 0, 0, 47, 0, 0, - 0, 0, 0, 362, 27, 27, 362, 0, 362, 27, - 0, 0, 0, 27, 0, 27, 0, 0, 27, 362, - 27, 27, 0, 27, 0, 27, 0, 27, 0, 27, - 27, 27, 27, 0, 0, 27, 27, 0, 0, 0, - 7, 27, 0, 27, 27, 27, 0, 0, 27, 27, - 27, 0, 27, 0, 0, 27, 0, 27, 27, 27, - 27, 0, 0, 0, 27, 27, 27, 0, 0, 27, - 27, 27, 0, 0, 0, 0, 0, 0, 27, 27, - 0, 27, 27, 958, 27, 27, 27, 0, 27, 0, - 27, 0, 27, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 27, 0, 0, 0, 0, 27, 0, - 27, 0, 27, 0, 0, 27, 27, 27, 0, 0, - 0, 0, 0, 0, 0, 27, 48, 27, 27, 0, - 0, 5, 27, 27, 0, 47, 0, 0, 27, 0, - 27, 27, 27, 27, 0, 0, 47, 0, 27, 0, - 0, 47, 27, 0, 27, 47, 0, 0, 47, 0, - 0, 0, 0, 0, 27, 0, 27, 27, 0, 27, - 47, 47, 0, 27, 957, 47, 47, 0, 47, 0, - 0, 47, 0, 47, 47, 47, 47, 0, 0, 47, - 0, 47, 0, 27, 47, 47, 0, 47, 47, 27, - 27, 47, 0, 0, 0, 0, 0, 47, 0, 0, - 47, 0, 47, 47, 47, 0, 47, 0, 47, 47, - 0, 0, 0, 0, 47, 0, 47, 47, 47, 47, - 0, 0, 0, 0, 47, 0, 47, 0, 47, 0, - 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 47, 0, 0, 47, 47, 47, 0, 0, 47, 47, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 47, - 0, 0, 0, 0, 47, 0, 0, 0, 47, 47, - 0, 47, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 47, 47, 0, 0, 7, 47, 47, - 0, 48, 0, 0, 47, 0, 47, 47, 47, 47, - 0, 0, 48, 0, 47, 0, 0, 48, 47, 0, - 47, 48, 0, 0, 48, 0, 0, 0, 0, 0, - 47, 0, 0, 47, 0, 47, 48, 48, 0, 47, - 958, 48, 48, 0, 47, 0, 0, 48, 0, 48, - 48, 48, 48, 0, 0, 47, 0, 48, 0, 47, - 47, 48, 0, 48, 47, 0, 0, 47, 0, 0, - 0, 0, 0, 48, 0, 0, 48, 0, 48, 47, - 47, 0, 48, 48, 47, 47, 0, 48, 0, 0, - 47, 0, 47, 47, 47, 47, 0, 0, 48, 0, - 47, 0, 48, 48, 47, 0, 47, 48, 0, 0, - 48, 0, 0, 0, 0, 0, 47, 0, 0, 47, - 0, 47, 48, 48, 0, 47, 0, 48, 48, 0, - 0, 0, 0, 48, 0, 48, 48, 48, 48, 0, - 0, 0, 0, 48, 0, 47, 0, 48, 0, 48, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, - 0, 55, 48, 0, 48, 0, 0, 0, 48, 56, - 24, 57, 25, 0, 0, 26, 58, 0, 59, 60, - 27, 61, 62, 63, 28, 0, 0, 0, 48, 0, - 64, 0, 65, 30, 66, 67, 68, 69, 0, 0, - 32, 0, 0, 0, 70, 33, 0, 71, 72, 34, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 73, - 0, 36, 0, 37, 74, 0, 0, 38, 0, 75, - 76, 77, 78, 79, 80, 39, 40, 81, 82, 41, - 83, 0, 84, 0, 0, 85, 86, 0, 337, 87, - 88, 0, 0, 0, 337, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 89, 90, 91, 92, 93, 0, - 0, 0, 94, 0, 0, 0, 95, 0, 0, 0, - 0, 96, 97, 98, 99, 100, 0, 0, 0, 101, - 337, 102, 0, 0, 0, 0, 0, 103, 104, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 337, 0, 0, 0, 0, 0, - 337, 0, 105, 106, 107, 108, 0, 0, 0, 0, - 0, 337, 0, 0, 196, 0, 337, 0, 337, 337, - 337, 337, 337, 337, 337, 337, 337, 337, 337, 337, - 0, 0, 0, 0, 0, 337, 337, 0, 0, 0, - 337, 337, 337, 337, 337, 337, 337, 337, 337, 0, - 337, 337, 0, 337, 337, 337, 337, 337, 337, 337, - 337, 337, 337, 0, 337, 337, 337, 337, 337, 337, - 337, 337, 337, 337, 337, 337, 337, 337, 337, 337, - 337, 337, 337, 337, 337, 337, 0, 508, 0, 0, - 337, 0, 337, 508, 0, 337, 0, 0, 0, 0, - 0, 337, 0, 0, 0, 0, 337, 0, 0, 337, - 0, 337, 337, 0, 0, 0, 337, 337, 0, 0, - 337, 337, 337, 337, 337, 337, 337, 337, 337, 508, - 337, 337, 337, 337, 337, 337, 337, 337, 337, 337, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 337, 337, 0, 0, 0, 0, 0, 0, 337, 0, - 0, 337, 0, 0, 0, 0, 0, 337, 0, 201, - 508, 0, 0, 0, 0, 508, 0, 508, 508, 508, - 508, 508, 508, 508, 508, 508, 508, 508, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 508, 508, - 508, 508, 508, 508, 508, 508, 508, 508, 949, 508, - 508, 202, 508, 508, 508, 508, 508, 508, 508, 508, - 508, 508, 0, 508, 508, 508, 508, 508, 508, 508, - 508, 508, 508, 508, 508, 508, 508, 508, 508, 508, - 508, 508, 508, 508, 508, 0, 504, 0, 0, 0, - 0, 508, 504, 0, 0, 0, 0, 0, 0, 0, - 508, 203, 204, 205, 206, 0, 207, 208, 209, 210, - 211, 212, 213, 214, 0, 0, 215, 216, 217, 218, - 219, 220, 221, 222, 0, 0, 0, 0, 504, 0, - 0, 949, 0, 0, 0, 0, 949, 0, 949, 949, - 949, 949, 949, 949, 949, 949, 949, 949, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 949, 0, 949, 0, 949, 0, 949, 949, 949, 504, - 0, 0, 0, 0, 504, 0, 504, 504, 504, 504, - 504, 504, 504, 504, 504, 504, 504, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 504, 504, 0, - 504, 504, 504, 504, 504, 504, 504, 0, 504, 504, - 0, 504, 504, 504, 504, 504, 504, 504, 504, 504, - 504, 949, 504, 504, 504, 504, 504, 504, 504, 504, - 504, 504, 504, 504, 504, 504, 504, 504, 504, 504, - 504, 504, 504, 504, 0, 512, 757, 0, 0, 0, - 504, 512, 0, 504, 0, 24, 0, 25, 0, 504, - 26, 0, 0, 0, 0, 27, 0, 0, 0, 28, - 0, 0, 0, 0, 0, 0, 0, 0, 30, 0, - 0, 0, 0, 0, 0, 32, 0, 512, 0, 0, - 33, 0, 0, 0, 34, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 36, 0, 37, 0, - 0, 0, 38, 0, 0, 0, 0, 0, 0, 0, - 39, 40, 0, 0, 41, 0, 0, 758, 512, 0, - 0, 0, 0, 512, 0, 512, 512, 512, 512, 512, - 512, 512, 512, 512, 512, 512, 0, 0, 0, 0, - 0, 0, 0, 290, 0, 0, 0, 512, 0, 512, - 512, 512, 512, 512, 512, 512, 0, 512, 512, 0, - 512, 512, 512, 512, 512, 512, 512, 512, 512, 512, - 0, 512, 512, 512, 512, 512, 512, 512, 512, 512, - 512, 512, 512, 512, 512, 512, 512, 512, 512, 512, - 512, 512, 512, 0, 337, 567, 0, 0, 323, 512, - 337, 0, 512, 0, 24, 0, 25, 0, 512, 26, + 0, 0, 0, 0, 0, 347, 0, 0, 0, 0, + 0, 347, 0, 106, 107, 108, 109, 0, 0, 0, + 0, 0, 811, 0, 0, 197, 0, 811, 0, 811, + 811, 811, 811, 811, 811, 811, 811, 811, 811, 811, + 811, 0, 0, 0, 0, 0, 811, 347, 0, 0, + 0, 811, 811, 811, 811, 811, 811, 811, 811, 811, + 0, 811, 811, 0, 811, 811, 811, 811, 811, 811, + 811, 811, 811, 811, 0, 811, 811, 811, 811, 811, + 811, 811, 811, 811, 811, 811, 811, 811, 811, 811, + 811, 811, 811, 811, 811, 811, 811, 811, 347, 0, + 0, 811, 0, 811, 347, 0, 811, 0, 0, 0, + 0, 0, 811, 0, 0, 0, 0, 347, 0, 0, + 347, 0, 347, 347, 0, 0, 0, 347, 347, 0, + 0, 347, 347, 347, 347, 347, 347, 347, 347, 347, + 347, 347, 347, 347, 347, 347, 347, 347, 347, 347, + 347, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 347, 347, 0, 0, 0, 0, 0, 0, 347, + 0, 0, 347, 0, 0, 0, 0, 0, 347, 0, + 0, 347, 0, 0, 0, 0, 347, 0, 347, 347, + 347, 347, 347, 347, 347, 347, 347, 347, 347, 347, + 0, 0, 0, 0, 0, 347, 0, 0, 0, 0, + 347, 347, 347, 347, 347, 347, 347, 347, 347, 637, + 347, 347, 0, 347, 347, 347, 347, 347, 347, 347, + 347, 347, 347, 0, 347, 347, 347, 347, 347, 347, + 347, 347, 347, 347, 347, 347, 347, 347, 347, 347, + 347, 347, 347, 347, 347, 347, 0, 523, 0, 0, + 347, 0, 347, 523, 0, 347, 0, 0, 0, 0, + 0, 347, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 523, + 0, 0, 637, 0, 0, 0, 0, 637, 0, 637, + 637, 637, 637, 637, 637, 637, 637, 637, 637, 637, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 637, 0, 637, 0, 637, 0, 637, 637, 637, + 523, 0, 0, 0, 0, 523, 0, 523, 523, 523, + 523, 523, 523, 523, 523, 523, 523, 523, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 523, 523, + 523, 523, 523, 523, 523, 523, 523, 523, 0, 523, + 523, 0, 523, 523, 523, 523, 523, 523, 523, 523, + 523, 523, 637, 523, 523, 523, 523, 523, 523, 523, + 523, 523, 523, 523, 523, 523, 523, 523, 523, 523, + 523, 523, 523, 523, 523, 0, 519, 816, 0, 0, + 0, 523, 519, 0, 0, 0, 24, 0, 25, 0, + 523, 26, 0, 0, 0, 0, 27, 0, 0, 0, + 28, 0, 0, 0, 0, 0, 0, 0, 0, 30, + 0, 0, 0, 0, 0, 0, 32, 0, 519, 0, + 0, 33, 0, 0, 0, 34, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 36, 0, 37, + 0, 0, 0, 38, 0, 0, 0, 403, 0, 0, + 0, 39, 40, 403, 0, 41, 0, 0, 817, 519, + 0, 0, 0, 0, 519, 0, 519, 519, 519, 519, + 519, 519, 519, 519, 519, 519, 519, 0, 0, 0, + 0, 0, 0, 0, 294, 0, 0, 519, 519, 403, + 519, 519, 519, 519, 519, 519, 519, 0, 519, 519, + 0, 519, 519, 519, 519, 519, 519, 519, 519, 519, + 519, 0, 519, 519, 519, 519, 519, 519, 519, 519, + 519, 519, 519, 519, 519, 519, 519, 519, 519, 519, + 519, 519, 519, 519, 0, 527, 0, 0, 0, 328, + 519, 527, 0, 519, 0, 0, 0, 0, 0, 519, + 0, 0, 0, 0, 340, 0, 0, 0, 0, 403, + 340, 0, 403, 403, 403, 403, 0, 403, 0, 403, + 403, 0, 403, 403, 403, 403, 403, 527, 403, 403, + 403, 403, 0, 403, 403, 403, 403, 403, 403, 403, + 403, 403, 403, 403, 403, 403, 403, 403, 403, 403, + 403, 403, 403, 403, 403, 0, 0, 0, 0, 340, + 0, 403, 0, 0, 403, 0, 0, 0, 527, 0, + 403, 0, 0, 527, 0, 527, 527, 527, 527, 527, + 527, 527, 527, 527, 527, 527, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 527, 0, 527, + 527, 527, 527, 527, 527, 527, 0, 527, 527, 0, + 527, 527, 527, 527, 527, 527, 527, 527, 527, 527, + 0, 527, 527, 527, 527, 527, 527, 527, 527, 527, + 527, 527, 527, 527, 527, 527, 527, 527, 527, 527, + 527, 527, 527, 0, 347, 595, 0, 0, 0, 527, + 347, 0, 527, 0, 24, 0, 25, 0, 527, 26, 0, 0, 0, 0, 27, 0, 0, 0, 28, 0, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, - 0, 0, 0, 0, 32, 0, 337, 0, 0, 33, + 0, 0, 0, 0, 32, 0, 347, 0, 0, 33, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 36, 0, 37, 0, 0, 0, 38, 0, 0, 0, 0, 0, 0, 0, 39, - 40, 0, 0, 41, 0, 0, 322, 337, 0, 0, - 0, 0, 337, 0, 337, 337, 337, 337, 337, 337, - 337, 337, 337, 337, 337, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 337, 0, 337, 337, - 337, 337, 337, 337, 337, 0, 337, 337, 0, 337, - 337, 337, 337, 337, 337, 337, 337, 337, 337, 0, - 337, 337, 337, 337, 337, 337, 337, 337, 337, 337, - 337, 337, 337, 337, 337, 337, 337, 337, 337, 337, - 337, 337, 0, 437, 906, 0, 0, 355, 337, 437, - 0, 337, 0, 24, 0, 25, 0, 337, 26, 0, + 40, 0, 0, 41, 0, 0, 327, 347, 0, 0, + 0, 0, 347, 0, 347, 347, 347, 347, 347, 347, + 347, 347, 347, 347, 347, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 347, 0, 347, 347, + 347, 347, 347, 347, 347, 0, 347, 347, 0, 347, + 347, 347, 347, 347, 347, 347, 347, 347, 347, 0, + 347, 347, 347, 347, 347, 347, 347, 347, 347, 347, + 347, 347, 347, 347, 347, 347, 347, 347, 347, 347, + 347, 347, 0, 449, 654, 0, 0, 374, 347, 449, + 0, 347, 0, 24, 0, 25, 0, 347, 26, 0, 0, 0, 0, 27, 0, 0, 0, 28, 0, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 0, - 0, 0, 0, 32, 0, 437, 0, 0, 33, 0, + 0, 0, 0, 32, 0, 449, 0, 0, 33, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 36, 0, 37, 0, 0, 0, 38, 0, 0, 0, 0, 0, 0, 0, 39, 40, - 0, 0, 41, 0, 0, 322, 437, 0, 0, 0, - 0, 437, 0, 437, 437, 437, 437, 437, 437, 437, - 437, 437, 437, 437, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 437, 0, 437, 437, 437, - 437, 437, 437, 437, 0, 437, 437, 0, 437, 437, - 437, 437, 437, 437, 437, 437, 437, 437, 0, 437, - 437, 437, 437, 437, 437, 437, 437, 437, 437, 437, - 437, 437, 437, 437, 437, 437, 437, 437, 437, 437, - 437, 0, 337, 0, 0, 0, 355, 437, 337, 1052, - 437, 0, 745, 0, 0, 0, 437, 0, 24, 0, + 0, 0, 41, 0, 0, 327, 449, 0, 0, 0, + 0, 449, 0, 449, 449, 449, 449, 449, 449, 449, + 449, 449, 449, 449, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 449, 0, 449, 449, 449, + 449, 449, 449, 449, 0, 449, 449, 0, 449, 449, + 449, 449, 449, 449, 449, 449, 449, 449, 0, 449, + 449, 449, 449, 449, 449, 449, 449, 449, 449, 449, + 449, 449, 449, 449, 449, 449, 449, 449, 449, 449, + 449, 0, 347, 0, 0, 0, 374, 449, 347, 656, + 449, 0, 811, 0, 0, 0, 449, 0, 24, 0, 25, 0, 0, 26, 0, 0, 0, 0, 27, 0, 0, 0, 28, 0, 0, 0, 0, 0, 0, 0, - 0, 30, 0, 0, 337, 0, 0, 0, 32, 0, + 0, 30, 0, 0, 347, 0, 0, 0, 32, 0, 0, 0, 0, 33, 0, 0, 0, 34, 0, 0, - 745, 0, 0, 0, 0, 0, 0, 0, 0, 36, + 811, 0, 0, 0, 0, 0, 0, 0, 0, 36, 0, 37, 0, 0, 0, 38, 0, 0, 0, 0, 0, 0, 0, 39, 40, 0, 0, 41, 0, 0, - 322, 0, 0, 0, 0, 543, 0, 0, 0, 0, - 0, 543, 0, 337, 0, 0, 0, 0, 0, 337, - 0, 0, 0, 0, 337, 337, 337, 337, 337, 337, - 337, 745, 337, 0, 337, 337, 0, 337, 337, 337, - 337, 337, 337, 337, 337, 337, 337, 543, 337, 337, - 337, 337, 337, 337, 337, 337, 337, 337, 337, 337, - 337, 337, 337, 337, 337, 337, 337, 337, 337, 337, - 0, 0, 0, 0, 337, 0, 337, 0, 0, 337, - 0, 355, 0, 0, 0, 337, 0, 0, 543, 0, - 0, 0, 0, 543, 0, 543, 543, 543, 543, 543, - 543, 543, 543, 543, 543, 543, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 543, 0, 543, - 0, 543, 0, 543, 543, 543, 0, 543, 543, 0, - 543, 543, 543, 543, 543, 543, 543, 543, 543, 543, - 358, 0, 0, 543, 543, 543, 543, 543, 543, 543, - 543, 543, 543, 543, 543, 543, 543, 543, 543, 543, - 543, 555, 543, 358, 0, 0, 0, 555, 0, 0, - 0, 0, 0, 0, 0, 0, 358, 0, 543, 0, - 0, 358, 0, 0, 231, 0, 358, 0, 358, 358, - 358, 358, 0, 0, 0, 0, 358, 0, 0, 0, - 358, 0, 0, 555, 358, 0, 0, 0, 0, 0, - 0, 0, 358, 0, 0, 358, 0, 358, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 559, - 0, 0, 0, 0, 0, 559, 0, 0, 0, 0, - 0, 358, 0, 0, 555, 0, 0, 0, 0, 555, - 0, 555, 555, 555, 555, 555, 555, 555, 555, 555, - 555, 555, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 559, 0, 555, 0, 555, 0, 555, 0, 555, - 555, 555, 0, 555, 555, 0, 0, 555, 555, 555, - 555, 555, 555, 555, 555, 555, 0, 358, 0, 555, - 555, 555, 555, 555, 555, 555, 555, 0, 0, 0, - 0, 0, 559, 0, 0, 0, 0, 559, 555, 559, - 559, 559, 559, 559, 559, 559, 559, 559, 559, 559, - 0, 0, 0, 560, 555, 0, 0, 0, 0, 560, - 0, 559, 0, 559, 0, 559, 0, 559, 559, 559, - 0, 559, 559, 0, 0, 559, 559, 559, 559, 0, - 0, 0, 559, 559, 0, 0, 0, 559, 559, 559, - 559, 559, 559, 559, 559, 560, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 559, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 561, 559, 0, 0, 0, 0, 561, 0, 0, - 0, 0, 0, 0, 0, 0, 560, 0, 0, 0, - 0, 560, 0, 560, 560, 560, 560, 560, 560, 560, - 560, 560, 560, 560, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 561, 0, 560, 0, 560, 0, 560, - 0, 560, 560, 560, 0, 560, 560, 0, 0, 560, - 560, 560, 560, 0, 0, 0, 560, 560, 0, 564, - 0, 560, 560, 560, 560, 560, 560, 560, 560, 0, - 0, 0, 0, 0, 561, 0, 0, 0, 0, 561, - 560, 561, 561, 561, 561, 561, 561, 561, 561, 561, - 561, 561, 0, 0, 0, 0, 560, 0, 0, 0, - 0, 0, 0, 561, 0, 561, 0, 561, 0, 561, - 561, 561, 0, 561, 561, 0, 0, 561, 561, 561, - 561, 0, 0, 0, 561, 561, 0, 565, 0, 561, - 561, 561, 561, 561, 561, 561, 561, 0, 0, 0, - 0, 0, 564, 0, 0, 0, 0, 564, 561, 564, - 564, 564, 564, 564, 564, 564, 564, 564, 564, 564, - 0, 0, 0, 0, 561, 0, 0, 0, 0, 0, - 0, 564, 0, 564, 0, 564, 0, 564, 564, 564, - 0, 0, 0, 0, 0, 564, 564, 564, 564, 0, - 0, 0, 564, 564, 0, 566, 0, 564, 564, 564, - 564, 564, 564, 564, 564, 0, 0, 0, 0, 0, - 565, 0, 0, 0, 0, 565, 564, 565, 565, 565, - 565, 565, 565, 565, 565, 565, 565, 565, 0, 0, - 0, 0, 564, 0, 0, 0, 0, 0, 0, 565, - 0, 565, 0, 565, 0, 565, 565, 565, 0, 0, - 0, 0, 0, 565, 565, 565, 565, 0, 0, 0, - 565, 565, 0, 567, 0, 565, 565, 565, 565, 565, - 565, 565, 565, 0, 0, 0, 0, 0, 566, 0, - 0, 0, 0, 566, 565, 566, 566, 566, 566, 566, - 566, 566, 566, 566, 566, 566, 0, 0, 0, 0, - 565, 0, 0, 0, 0, 0, 0, 566, 0, 566, - 0, 566, 0, 566, 566, 566, 0, 0, 0, 0, - 0, 566, 566, 566, 566, 0, 0, 0, 566, 566, - 0, 568, 0, 566, 566, 566, 566, 566, 566, 566, - 566, 0, 0, 0, 0, 0, 567, 0, 0, 0, - 0, 567, 566, 567, 567, 567, 567, 567, 567, 567, - 567, 567, 567, 567, 0, 0, 0, 0, 566, 0, - 0, 0, 0, 0, 0, 567, 0, 567, 0, 567, - 0, 567, 567, 567, 0, 0, 0, 0, 0, 567, - 567, 567, 567, 0, 0, 0, 567, 567, 0, 569, - 0, 0, 0, 567, 567, 567, 567, 567, 567, 0, - 0, 0, 0, 0, 568, 0, 0, 0, 0, 568, - 567, 568, 568, 568, 568, 568, 568, 568, 568, 568, - 568, 568, 0, 0, 0, 0, 567, 0, 0, 0, - 0, 0, 0, 568, 0, 568, 0, 568, 0, 568, - 568, 568, 0, 0, 0, 0, 0, 568, 568, 568, - 568, 0, 0, 0, 568, 568, 0, 570, 0, 0, - 0, 568, 568, 568, 568, 568, 568, 0, 0, 0, - 0, 0, 569, 0, 0, 0, 0, 569, 568, 569, - 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, - 0, 0, 0, 0, 568, 0, 0, 0, 0, 0, - 0, 569, 0, 569, 0, 569, 0, 569, 569, 569, - 0, 0, 0, 0, 0, 569, 569, 569, 569, 0, - 0, 0, 569, 569, 0, 571, 0, 0, 0, 569, - 569, 569, 569, 569, 569, 0, 0, 0, 0, 0, - 570, 0, 0, 0, 0, 570, 569, 570, 570, 570, - 570, 570, 570, 570, 570, 570, 570, 570, 0, 0, - 0, 0, 569, 0, 0, 0, 0, 0, 0, 570, - 0, 570, 0, 570, 0, 570, 570, 570, 0, 0, - 0, 0, 0, 570, 570, 570, 570, 0, 0, 0, - 570, 570, 0, 572, 0, 0, 0, 570, 570, 570, - 570, 570, 570, 0, 0, 0, 0, 0, 571, 0, - 0, 0, 0, 571, 570, 571, 571, 571, 571, 571, - 571, 571, 571, 571, 571, 571, 0, 0, 0, 0, - 570, 0, 0, 0, 0, 0, 0, 571, 0, 571, - 0, 571, 0, 571, 571, 571, 0, 0, 0, 0, - 0, 571, 571, 571, 571, 0, 0, 0, 571, 571, - 0, 573, 0, 0, 0, 571, 571, 571, 571, 571, - 571, 0, 0, 0, 0, 0, 572, 0, 0, 0, - 0, 572, 571, 572, 572, 572, 572, 572, 572, 572, - 572, 572, 572, 572, 0, 0, 0, 0, 571, 0, - 0, 0, 0, 0, 0, 572, 0, 572, 0, 572, - 0, 572, 572, 572, 0, 0, 0, 0, 0, 0, - 0, 572, 572, 0, 0, 0, 572, 572, 0, 574, - 0, 0, 0, 0, 0, 572, 572, 572, 572, 0, - 0, 0, 0, 0, 573, 0, 0, 0, 0, 573, - 572, 573, 573, 573, 573, 573, 573, 573, 573, 573, - 573, 573, 0, 0, 0, 0, 572, 0, 0, 0, - 0, 0, 0, 573, 0, 573, 0, 573, 0, 573, - 573, 573, 0, 0, 0, 0, 0, 0, 0, 573, - 573, 0, 0, 0, 573, 573, 0, 575, 0, 0, - 0, 0, 0, 573, 573, 573, 573, 0, 0, 0, - 0, 0, 574, 0, 0, 0, 0, 574, 573, 574, - 574, 574, 574, 574, 574, 574, 574, 574, 574, 574, - 0, 0, 0, 0, 573, 0, 0, 0, 0, 0, - 0, 574, 0, 574, 0, 574, 0, 574, 574, 574, - 0, 0, 0, 0, 0, 0, 0, 574, 574, 0, - 0, 0, 574, 574, 0, 576, 0, 0, 0, 0, - 0, 574, 574, 574, 574, 0, 0, 0, 0, 0, - 575, 0, 0, 0, 0, 575, 574, 575, 575, 575, - 575, 575, 575, 575, 575, 575, 575, 575, 0, 0, - 0, 0, 574, 0, 0, 0, 0, 0, 0, 575, - 0, 575, 0, 575, 0, 575, 575, 575, 0, 0, - 0, 0, 0, 0, 0, 575, 575, 0, 0, 0, - 575, 575, 0, 577, 0, 0, 0, 0, 0, 0, - 0, 575, 575, 0, 0, 0, 0, 0, 576, 0, - 0, 0, 0, 576, 575, 576, 576, 576, 576, 576, - 576, 576, 576, 576, 576, 576, 0, 0, 0, 0, - 575, 0, 0, 0, 0, 0, 0, 576, 0, 576, - 0, 576, 0, 576, 576, 576, 0, 0, 0, 0, - 0, 0, 0, 576, 576, 0, 0, 0, 576, 576, - 0, 578, 0, 0, 0, 0, 0, 0, 0, 576, - 576, 0, 0, 0, 0, 0, 577, 0, 0, 0, - 0, 577, 576, 577, 577, 577, 577, 577, 577, 577, - 577, 577, 577, 577, 0, 0, 0, 0, 576, 0, - 0, 0, 0, 0, 0, 577, 0, 577, 0, 577, - 0, 577, 577, 577, 0, 0, 0, 0, 0, 0, - 0, 0, 577, 0, 0, 0, 577, 577, 0, 579, - 0, 0, 0, 0, 0, 0, 0, 577, 577, 0, - 0, 0, 0, 0, 578, 0, 0, 0, 0, 578, - 577, 578, 578, 578, 578, 578, 578, 578, 578, 578, - 578, 578, 0, 0, 0, 0, 577, 0, 0, 0, - 0, 0, 0, 578, 0, 578, 0, 578, 0, 578, - 578, 578, 0, 0, 0, 0, 0, 0, 0, 0, - 578, 0, 0, 0, 578, 578, 0, 580, 0, 0, - 0, 0, 0, 0, 0, 578, 578, 0, 0, 0, - 0, 0, 579, 0, 0, 0, 0, 579, 578, 579, - 579, 579, 579, 579, 579, 579, 579, 579, 579, 579, - 0, 0, 0, 0, 578, 0, 0, 0, 0, 0, - 0, 579, 0, 579, 0, 579, 0, 579, 579, 579, - 0, 0, 0, 0, 0, 0, 0, 0, 579, 0, - 0, 0, 0, 579, 0, 581, 0, 0, 0, 0, - 0, 0, 0, 579, 579, 0, 0, 0, 0, 0, - 580, 0, 0, 0, 0, 580, 579, 580, 580, 580, - 580, 580, 580, 580, 580, 580, 580, 580, 0, 0, - 0, 0, 579, 0, 0, 0, 0, 0, 0, 580, - 0, 580, 0, 580, 0, 580, 580, 580, 0, 0, - 0, 0, 0, 0, 0, 0, 580, 0, 0, 0, - 0, 580, 0, 582, 0, 0, 0, 0, 0, 0, - 0, 580, 580, 0, 0, 0, 0, 0, 581, 0, - 0, 0, 0, 581, 580, 581, 581, 581, 581, 581, - 581, 581, 581, 581, 581, 581, 0, 0, 0, 0, - 580, 0, 0, 0, 0, 0, 0, 581, 0, 581, - 0, 581, 0, 581, 581, 581, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 581, - 0, 583, 0, 0, 0, 0, 0, 0, 0, 581, - 581, 0, 0, 0, 0, 0, 582, 0, 0, 0, - 0, 582, 581, 582, 582, 582, 582, 582, 582, 582, - 582, 582, 582, 582, 0, 0, 0, 0, 581, 0, - 0, 0, 0, 0, 0, 582, 0, 582, 0, 582, - 0, 582, 582, 582, 0, 0, 0, 584, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 582, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 582, 582, 0, + 327, 0, 0, 0, 0, 561, 0, 0, 0, 0, + 0, 561, 0, 347, 0, 0, 0, 0, 0, 347, + 0, 0, 0, 0, 347, 347, 347, 347, 347, 347, + 347, 811, 347, 0, 347, 347, 0, 347, 347, 347, + 347, 347, 347, 347, 347, 347, 347, 561, 347, 347, + 347, 347, 347, 347, 347, 347, 347, 347, 347, 347, + 347, 347, 347, 347, 347, 347, 347, 347, 347, 347, + 0, 0, 0, 0, 347, 0, 347, 0, 0, 347, + 0, 374, 0, 0, 0, 347, 0, 0, 561, 0, + 0, 0, 635, 561, 0, 561, 561, 561, 561, 561, + 561, 561, 561, 561, 561, 561, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 561, 0, 561, + 0, 561, 0, 561, 561, 561, 0, 561, 561, 0, + 561, 561, 561, 561, 561, 561, 561, 561, 561, 561, + 0, 0, 0, 561, 561, 561, 561, 561, 561, 561, + 561, 561, 561, 561, 561, 561, 561, 561, 561, 561, + 561, 583, 561, 0, 0, 0, 0, 583, 0, 0, + 0, 0, 0, 0, 0, 635, 0, 0, 561, 0, + 635, 0, 635, 635, 635, 635, 635, 635, 635, 635, + 635, 635, 635, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 583, 635, 0, 635, 0, 635, 0, + 635, 635, 635, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 635, 0, 0, 590, + 0, 0, 0, 0, 0, 590, 0, 0, 0, 0, 0, 0, 0, 0, 583, 0, 0, 0, 0, 583, - 582, 583, 583, 583, 583, 583, 583, 583, 583, 583, - 583, 583, 0, 0, 0, 0, 582, 0, 0, 0, - 0, 0, 0, 583, 0, 583, 0, 583, 0, 583, - 583, 583, 0, 0, 0, 0, 337, 0, 0, 0, - 745, 0, 0, 0, 0, 583, 0, 0, 0, 0, - 584, 0, 0, 0, 0, 584, 583, 584, 584, 584, - 584, 584, 584, 584, 584, 584, 584, 584, 583, 0, - 0, 0, 337, 0, 0, 0, 0, 0, 0, 584, - 0, 584, 0, 584, 583, 584, 584, 584, 745, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 584, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 584, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 584, 0, 0, 0, 0, 0, - 0, 337, 0, 0, 0, 0, 0, 337, 0, 0, - 584, 0, 337, 337, 0, 337, 0, 337, 0, 745, - 337, 0, 337, 337, 0, 337, 337, 337, 337, 337, - 337, 337, 337, 337, 337, 0, 337, 337, 337, 337, - 337, 337, 337, 337, 337, 337, 337, 337, 337, 337, - 337, 337, 337, 337, 337, 337, 337, 337, 0, 0, - 55, 0, 337, 0, 337, 0, 0, 337, 56, 24, - 57, 25, 0, 337, 26, 58, 0, 59, 60, 27, - 61, 62, 63, 28, 0, 0, 0, 0, 0, 64, - 0, 65, 30, 66, 67, 68, 69, 0, 0, 32, - 0, 0, 0, 70, 33, 0, 71, 72, 34, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 73, 0, - 36, 0, 37, 74, 0, 0, 38, 0, 75, 76, - 77, 78, 79, 80, 39, 40, 81, 82, 41, 83, - 0, 84, 0, 0, 85, 86, 0, 0, 87, 88, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 89, 90, 91, 92, 93, 0, 0, - 0, 94, 0, 0, 0, 95, 0, 0, 0, 0, - 96, 97, 98, 99, 100, 0, 0, 0, 101, 0, - 102, 0, 0, 0, 0, 0, 103, 104, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 265, 0, 0, - 0, 105, 106, 107, 108, 56, 24, 57, 25, 0, - 0, 26, 58, 0, 59, 60, 27, 61, 62, 63, - 28, 0, 0, 0, 0, 0, 64, 0, 65, 30, - 66, 67, 68, 69, 0, 0, 32, 0, 0, 0, - 70, 33, 0, 71, 72, 34, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 73, 0, 36, 0, 37, - 74, 0, 0, 38, 0, 75, 76, 77, 78, 79, - 80, 39, 40, 81, 82, 41, 83, 0, 84, 0, - 0, 85, 86, 0, 0, 87, 88, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 89, 90, 91, 92, 93, 0, 0, 0, 94, 0, - 0, 0, 95, 0, 0, 0, 0, 96, 97, 98, - 99, 100, 0, 0, 0, 101, 0, 102, 0, 0, - 0, 0, 0, 103, 104, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 556, 0, 0, 0, 105, 106, - 107, 108, 56, 24, 57, 25, 0, 0, 26, 58, - 0, 59, 60, 27, 61, 62, 63, 28, 0, 0, - 0, 0, 0, 64, 0, 65, 30, 66, 67, 68, - 69, 0, 0, 32, 0, 0, 0, 70, 33, 0, - 71, 72, 34, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 73, 0, 36, 0, 37, 74, 0, 0, - 38, 0, 75, 76, 77, 78, 79, 80, 39, 40, - 81, 82, 41, 83, 0, 84, 0, 0, 85, 86, - 0, 0, 87, 88, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 89, 90, 91, - 92, 93, 0, 0, 0, 94, 0, 0, 0, 95, - 0, 0, 0, 0, 96, 97, 98, 99, 100, 0, - 0, 0, 101, 0, 102, 0, 0, 0, 0, 0, - 103, 104, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 954, 0, 0, 0, 105, 557, 107, 108, 954, - 954, 954, 954, 0, 0, 954, 954, 0, 954, 954, - 954, 954, 954, 954, 954, 0, 0, 0, 0, 0, - 954, 0, 954, 954, 954, 954, 954, 954, 0, 0, - 954, 0, 0, 0, 954, 954, 0, 954, 954, 954, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 954, - 0, 954, 0, 954, 954, 0, 0, 954, 0, 954, - 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, - 954, 0, 954, 0, 0, 954, 954, 0, 0, 954, - 954, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 954, 954, 954, 954, 954, 0, - 0, 0, 954, 0, 0, 0, 954, 0, 0, 0, - 0, 954, 954, 954, 954, 954, 0, 0, 0, 954, - 0, 954, 0, 0, 0, 0, 0, 954, 954, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 796, 0, - 0, 0, 954, 954, 954, 954, 796, 796, 796, 796, - 0, 0, 796, 796, 0, 796, 796, 796, 796, 796, - 796, 796, 0, 0, 0, 0, 0, 796, 0, 796, - 796, 796, 796, 796, 796, 0, 0, 796, 0, 0, - 0, 796, 796, 0, 796, 796, 796, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 796, 0, 796, 0, - 796, 796, 0, 0, 796, 0, 796, 796, 796, 796, - 796, 796, 796, 796, 796, 796, 796, 796, 0, 796, - 0, 0, 796, 796, 0, 0, 796, 796, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 796, 796, 796, 796, 796, 0, 0, 0, 796, - 0, 0, 0, 796, 0, 0, 0, 0, 796, 796, - 796, 796, 796, 0, 0, 0, 796, 0, 796, 0, - 0, 0, 0, 0, 796, 796, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 743, 0, 0, 0, 796, - 796, 796, 796, 56, 24, 0, 25, 0, 0, 26, - 253, 0, 0, 0, 27, 61, 62, 0, 28, 0, - 0, 174, 0, 174, 64, 0, 174, 30, 0, 0, - 0, 174, 0, 0, 32, 174, 0, 0, 0, 33, - 0, 71, 72, 34, 174, 0, 0, 0, 0, 0, - 0, 174, 0, 0, 0, 36, 174, 37, 74, 0, - 174, 38, 0, 0, 76, 0, 78, 0, 80, 39, - 40, 254, 174, 41, 174, 0, 0, 0, 174, 0, - 86, 0, 0, 87, 88, 0, 174, 174, 0, 0, - 174, 0, 0, 174, 0, 0, 0, 0, 89, 90, - 91, 92, 301, 0, 0, 0, 517, 744, 0, 0, - 95, 0, 0, 0, 0, 0, 97, 98, 99, 100, - 0, 0, 0, 101, 0, 102, 0, 0, 978, 0, - 0, 103, 104, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 932, 0, 0, 0, 105, 302, 107, 108, - 56, 24, 0, 25, 0, 0, 26, 253, 0, 0, - 0, 27, 61, 62, 174, 28, 0, 0, 174, 0, - 174, 64, 0, 174, 30, 0, 0, 0, 174, 0, - 0, 32, 174, 0, 0, 0, 33, 0, 71, 72, - 34, 174, 594, 0, 0, 0, 0, 0, 174, 595, - 0, 0, 36, 174, 37, 74, 0, 174, 38, 0, - 0, 76, 0, 78, 0, 80, 39, 40, 254, 174, - 41, 174, 0, 0, 0, 174, 0, 596, 0, 0, - 87, 88, 0, 174, 174, 0, 0, 174, 0, 0, - 174, 0, 0, 0, 0, 89, 90, 91, 92, 93, - 0, 0, 0, 0, 0, 0, 0, 95, 0, 0, - 0, 0, 0, 97, 98, 99, 100, 0, 0, 0, - 101, 0, 102, 978, 0, 0, 0, 0, 103, 104, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 936, - 0, 0, 0, 105, 106, 107, 108, 56, 24, 0, - 25, 0, 0, 26, 253, 0, 0, 0, 27, 61, - 62, 174, 28, 0, 0, 24, 0, 25, 64, 0, - 26, 30, 0, 0, 0, 27, 0, 0, 32, 28, - 0, 0, 0, 33, 0, 71, 72, 34, 30, 0, - 0, 0, 0, 0, 0, 32, 0, 0, 0, 36, - 33, 37, 74, 937, 34, 38, 0, 0, 76, 0, - 78, 0, 80, 39, 40, 254, 36, 41, 37, 0, - 0, 0, 38, 0, 86, 0, 0, 87, 88, 0, - 39, 40, 0, 0, 41, 0, 0, 322, 0, 0, - 0, 0, 89, 90, 91, 92, 301, 0, 0, 0, - 517, 0, 0, 0, 95, 0, 0, 0, 0, 0, - 97, 98, 99, 100, 0, 0, 0, 101, 0, 102, - 0, 0, 0, 0, 0, 103, 104, 0, 0, 0, - 0, 0, 0, 56, 24, 0, 25, 0, 0, 26, - 253, 0, 0, 0, 27, 61, 62, 0, 28, 0, - 105, 302, 107, 108, 64, 0, 0, 30, 0, 0, - 0, 0, 0, 0, 32, 0, 0, 0, 355, 33, - 0, 71, 72, 34, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 36, 0, 37, 74, 0, - 0, 38, 0, 0, 76, 0, 78, 0, 80, 39, - 40, 254, 0, 41, 0, 0, 0, 0, 0, 0, - 86, 0, 0, 87, 88, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 89, 90, - 91, 92, 301, 0, 0, 0, 729, 1004, 0, 0, - 95, 0, 0, 0, 0, 0, 97, 98, 99, 100, - 0, 0, 0, 101, 0, 102, 0, 0, 0, 0, - 0, 103, 104, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 743, 0, 105, 730, 107, 108, - 0, 0, 56, 24, 0, 25, 0, 731, 26, 253, - 0, 0, 0, 27, 61, 62, 0, 28, 0, 0, - 24, 0, 25, 64, 0, 26, 30, 0, 0, 0, - 27, 0, 0, 32, 28, 0, 0, 0, 33, 0, - 71, 72, 34, 30, 0, 0, 0, 0, 0, 0, - 32, 0, 0, 0, 36, 33, 37, 74, 937, 34, - 38, 0, 0, 76, 0, 78, 0, 80, 39, 40, - 254, 36, 41, 37, 0, 0, 0, 38, 0, 86, - 0, 0, 87, 88, 0, 39, 40, 0, 0, 41, - 0, 0, 519, 0, 0, 0, 0, 89, 90, 91, - 92, 301, 0, 0, 0, 517, 0, 0, 0, 95, - 0, 0, 0, 0, 0, 97, 98, 99, 100, 0, - 0, 0, 101, 0, 102, 0, 0, 0, 0, 0, - 103, 104, 0, 0, 0, 0, 0, 0, 56, 24, - 0, 25, 0, 0, 26, 253, 0, 0, 0, 27, - 61, 62, 0, 28, 0, 105, 302, 107, 108, 64, + 0, 583, 583, 583, 583, 583, 583, 583, 583, 583, + 583, 583, 0, 0, 0, 635, 0, 0, 0, 0, + 0, 590, 0, 583, 0, 583, 0, 583, 0, 583, + 583, 583, 0, 583, 583, 0, 0, 583, 583, 583, + 583, 583, 583, 583, 583, 583, 0, 0, 0, 583, + 583, 583, 583, 583, 583, 583, 583, 0, 0, 0, + 0, 0, 590, 0, 0, 0, 0, 590, 583, 590, + 590, 590, 590, 590, 590, 590, 590, 590, 590, 590, + 0, 0, 0, 591, 583, 0, 0, 0, 0, 591, + 0, 590, 0, 590, 0, 590, 0, 590, 590, 590, + 0, 590, 590, 0, 0, 590, 590, 590, 590, 0, + 0, 0, 590, 590, 0, 0, 0, 590, 590, 590, + 590, 590, 590, 590, 590, 591, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 590, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 592, 590, 0, 0, 0, 0, 592, 0, 0, + 0, 0, 0, 0, 0, 0, 591, 0, 0, 0, + 0, 591, 0, 591, 591, 591, 591, 591, 591, 591, + 591, 591, 591, 591, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 592, 0, 591, 0, 591, 0, 591, + 0, 591, 591, 591, 0, 591, 591, 0, 0, 591, + 591, 591, 591, 0, 0, 0, 591, 591, 0, 0, + 0, 591, 591, 591, 591, 591, 591, 591, 591, 0, + 0, 0, 0, 0, 592, 0, 0, 0, 0, 592, + 591, 592, 592, 592, 592, 592, 592, 592, 592, 592, + 592, 592, 0, 0, 0, 0, 591, 0, 0, 0, + 0, 0, 0, 592, 0, 592, 0, 592, 0, 592, + 592, 592, 0, 592, 592, 0, 0, 592, 592, 592, + 592, 0, 0, 0, 592, 592, 0, 0, 0, 592, + 592, 592, 592, 592, 592, 592, 592, 0, 519, 0, + 602, 0, 0, 0, 0, 0, 57, 24, 592, 25, + 0, 0, 26, 256, 0, 0, 0, 27, 62, 63, + 0, 28, 0, 0, 592, 0, 0, 65, 0, 0, + 30, 0, 0, 0, 0, 0, 0, 32, 0, 0, + 0, 0, 33, 0, 72, 73, 34, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 36, 0, + 37, 75, 0, 0, 38, 0, 0, 77, 0, 79, + 0, 81, 39, 40, 257, 0, 41, 0, 0, 0, + 0, 0, 0, 602, 603, 0, 0, 0, 602, 0, + 602, 602, 602, 602, 602, 602, 602, 602, 602, 602, + 602, 90, 91, 92, 258, 520, 0, 0, 0, 0, + 0, 0, 602, 96, 602, 0, 602, 0, 602, 602, + 602, 0, 0, 0, 0, 0, 602, 602, 602, 602, + 0, 0, 0, 602, 602, 0, 0, 0, 602, 602, + 602, 602, 602, 602, 602, 602, 0, 0, 0, 0, + 0, 0, 606, 0, 0, 0, 0, 602, 0, 106, + 521, 0, 0, 0, 0, 0, 0, 603, 0, 0, + 522, 523, 603, 602, 603, 603, 603, 603, 603, 603, + 603, 603, 603, 603, 603, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 603, 0, 603, 0, + 603, 0, 603, 603, 603, 0, 0, 0, 0, 0, + 603, 603, 603, 603, 0, 0, 0, 603, 603, 0, + 607, 0, 603, 603, 603, 603, 603, 603, 603, 603, + 0, 0, 0, 0, 0, 606, 0, 0, 0, 0, + 606, 603, 606, 606, 606, 606, 606, 606, 606, 606, + 606, 606, 606, 0, 0, 0, 0, 603, 0, 0, + 0, 0, 0, 0, 606, 0, 606, 0, 606, 0, + 606, 606, 606, 0, 0, 0, 0, 0, 606, 606, + 606, 606, 0, 0, 0, 606, 606, 0, 608, 0, + 0, 0, 606, 606, 606, 606, 606, 606, 0, 0, + 0, 0, 0, 607, 0, 0, 0, 0, 607, 606, + 607, 607, 607, 607, 607, 607, 607, 607, 607, 607, + 607, 0, 0, 0, 0, 606, 0, 0, 0, 0, + 0, 0, 607, 0, 607, 0, 607, 0, 607, 607, + 607, 0, 0, 0, 0, 0, 607, 607, 607, 607, + 0, 0, 0, 607, 607, 0, 609, 0, 0, 0, + 607, 607, 607, 607, 607, 607, 0, 0, 0, 0, + 0, 608, 0, 0, 0, 0, 608, 607, 608, 608, + 608, 608, 608, 608, 608, 608, 608, 608, 608, 0, + 0, 0, 0, 607, 0, 0, 0, 0, 0, 0, + 608, 0, 608, 0, 608, 0, 608, 608, 608, 0, + 0, 0, 0, 0, 608, 608, 608, 608, 0, 0, + 0, 608, 608, 0, 610, 0, 0, 0, 608, 608, + 608, 608, 608, 608, 0, 0, 0, 0, 0, 609, + 0, 0, 0, 0, 609, 608, 609, 609, 609, 609, + 609, 609, 609, 609, 609, 609, 609, 0, 0, 0, + 0, 608, 0, 0, 0, 0, 0, 0, 609, 0, + 609, 0, 609, 0, 609, 609, 609, 0, 0, 0, + 0, 0, 609, 609, 609, 609, 0, 0, 0, 609, + 609, 0, 615, 0, 0, 0, 609, 609, 609, 609, + 609, 609, 0, 0, 0, 0, 0, 610, 0, 0, + 0, 0, 610, 609, 610, 610, 610, 610, 610, 610, + 610, 610, 610, 610, 610, 0, 0, 0, 0, 609, + 0, 0, 0, 0, 0, 0, 610, 0, 610, 0, + 610, 0, 610, 610, 610, 0, 0, 0, 0, 0, + 610, 610, 610, 610, 0, 0, 0, 610, 610, 0, + 616, 0, 0, 0, 610, 610, 610, 610, 610, 610, + 0, 0, 0, 0, 0, 615, 0, 0, 0, 0, + 615, 610, 615, 615, 615, 615, 615, 615, 615, 615, + 615, 615, 615, 0, 0, 0, 0, 610, 0, 0, + 0, 0, 0, 0, 615, 0, 615, 0, 615, 0, + 615, 615, 615, 0, 0, 0, 0, 0, 0, 0, + 615, 615, 0, 0, 0, 615, 615, 0, 617, 0, + 0, 0, 0, 0, 615, 615, 615, 615, 0, 0, + 0, 0, 0, 616, 0, 0, 0, 0, 616, 615, + 616, 616, 616, 616, 616, 616, 616, 616, 616, 616, + 616, 0, 0, 0, 0, 615, 0, 0, 0, 0, + 0, 0, 616, 0, 616, 0, 616, 0, 616, 616, + 616, 0, 0, 0, 0, 0, 0, 0, 616, 616, + 0, 0, 0, 616, 616, 0, 620, 0, 0, 0, + 0, 0, 616, 616, 616, 616, 0, 0, 0, 0, + 0, 617, 0, 0, 0, 0, 617, 616, 617, 617, + 617, 617, 617, 617, 617, 617, 617, 617, 617, 0, + 0, 0, 0, 616, 0, 0, 0, 0, 0, 0, + 617, 0, 617, 0, 617, 0, 617, 617, 617, 0, + 0, 0, 0, 0, 0, 0, 617, 617, 0, 0, + 0, 617, 617, 0, 621, 0, 0, 0, 0, 0, + 617, 617, 617, 617, 0, 0, 0, 0, 0, 620, + 0, 0, 0, 0, 620, 617, 620, 620, 620, 620, + 620, 620, 620, 620, 620, 620, 620, 0, 0, 0, + 0, 617, 0, 0, 0, 0, 0, 0, 620, 0, + 620, 0, 620, 0, 620, 620, 620, 0, 0, 0, + 0, 0, 0, 0, 620, 620, 0, 0, 0, 620, + 620, 0, 623, 0, 0, 0, 0, 0, 0, 0, + 620, 620, 0, 0, 0, 0, 0, 621, 0, 0, + 0, 0, 621, 620, 621, 621, 621, 621, 621, 621, + 621, 621, 621, 621, 621, 0, 0, 0, 0, 620, + 0, 0, 0, 0, 0, 0, 621, 0, 621, 0, + 621, 0, 621, 621, 621, 0, 0, 0, 0, 0, + 0, 0, 621, 621, 0, 0, 0, 621, 621, 0, + 624, 0, 0, 0, 0, 0, 0, 0, 621, 621, + 0, 0, 0, 0, 0, 623, 0, 0, 0, 0, + 623, 621, 623, 623, 623, 623, 623, 623, 623, 623, + 623, 623, 623, 0, 0, 0, 0, 621, 0, 0, + 0, 0, 0, 0, 623, 0, 623, 0, 623, 0, + 623, 623, 623, 0, 0, 0, 0, 0, 0, 0, + 0, 623, 0, 0, 0, 623, 623, 0, 627, 0, + 0, 0, 0, 0, 0, 0, 623, 623, 0, 0, + 0, 0, 0, 624, 0, 0, 0, 0, 624, 623, + 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, + 624, 0, 0, 0, 0, 623, 0, 0, 0, 0, + 0, 0, 624, 0, 624, 0, 624, 0, 624, 624, + 624, 0, 0, 0, 0, 0, 0, 0, 0, 624, + 0, 0, 0, 624, 624, 0, 629, 0, 0, 0, + 0, 0, 0, 0, 624, 624, 0, 0, 0, 0, + 0, 627, 0, 0, 0, 0, 627, 624, 627, 627, + 627, 627, 627, 627, 627, 627, 627, 627, 627, 0, + 0, 0, 0, 624, 0, 0, 0, 0, 0, 0, + 627, 0, 627, 0, 627, 0, 627, 627, 627, 0, + 0, 0, 0, 0, 0, 0, 0, 627, 0, 0, + 0, 0, 627, 0, 630, 0, 0, 0, 0, 0, + 0, 0, 627, 627, 0, 0, 0, 0, 0, 629, + 0, 0, 0, 0, 629, 627, 629, 629, 629, 629, + 629, 629, 629, 629, 629, 629, 629, 0, 0, 0, + 0, 627, 0, 0, 0, 0, 0, 0, 629, 0, + 629, 0, 629, 0, 629, 629, 629, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 629, 0, 632, 0, 0, 0, 0, 0, 0, 0, + 629, 629, 0, 0, 0, 0, 0, 630, 0, 0, + 0, 0, 630, 629, 630, 630, 630, 630, 630, 630, + 630, 630, 630, 630, 630, 0, 0, 0, 0, 629, + 0, 0, 0, 0, 0, 0, 630, 0, 630, 0, + 630, 0, 630, 630, 630, 0, 0, 0, 633, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 630, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 630, 630, + 0, 0, 0, 0, 0, 632, 0, 0, 0, 0, + 632, 630, 632, 632, 632, 632, 632, 632, 632, 632, + 632, 632, 632, 0, 0, 0, 0, 630, 0, 0, + 0, 0, 0, 0, 632, 0, 632, 0, 632, 0, + 632, 632, 632, 0, 0, 0, 0, 347, 0, 0, + 0, 811, 0, 0, 0, 0, 632, 0, 0, 0, + 0, 633, 0, 0, 0, 0, 633, 632, 633, 633, + 633, 633, 633, 633, 633, 633, 633, 633, 633, 632, + 0, 0, 0, 347, 0, 0, 0, 0, 0, 0, + 633, 0, 633, 0, 633, 632, 633, 633, 633, 811, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 633, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 633, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 633, 0, 0, 0, 0, + 0, 0, 347, 0, 0, 0, 0, 0, 347, 0, + 0, 633, 0, 347, 347, 0, 347, 0, 347, 0, + 811, 347, 0, 347, 347, 0, 347, 347, 347, 347, + 347, 347, 347, 347, 347, 347, 0, 347, 347, 347, + 347, 347, 347, 347, 347, 347, 347, 347, 347, 347, + 347, 347, 347, 347, 347, 347, 347, 347, 347, 0, + 0, 584, 0, 347, 0, 347, 0, 0, 347, 57, + 24, 58, 25, 1149, 347, 26, 59, 0, 60, 61, + 27, 62, 63, 64, 28, 0, 0, 0, 0, 0, + 65, 0, 66, 30, 67, 68, 69, 70, 0, 0, + 32, 0, 0, 0, 71, 33, 0, 72, 73, 34, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 74, + 0, 36, 0, 37, 75, 0, 0, 38, 0, 76, + 77, 78, 79, 80, 81, 39, 40, 82, 83, 41, + 84, 0, 85, 0, 0, 86, 87, 0, 0, 88, + 89, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 90, 91, 92, 93, 94, 0, + 0, 0, 95, 0, 0, 0, 96, 0, 0, 0, + 0, 97, 98, 99, 100, 101, 0, 0, 0, 102, + 0, 103, 0, 0, 0, 0, 0, 104, 105, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 56, 0, 106, 585, 108, 109, 0, 1150, 57, 24, + 58, 25, 0, 0, 26, 59, 0, 60, 61, 27, + 62, 63, 64, 28, 0, 0, 0, 0, 0, 65, + 0, 66, 30, 67, 68, 69, 70, 0, 0, 32, + 0, 0, 0, 71, 33, 0, 72, 73, 34, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 74, 0, + 36, 0, 37, 75, 0, 0, 38, 0, 76, 77, + 78, 79, 80, 81, 39, 40, 82, 83, 41, 84, + 0, 85, 0, 0, 86, 87, 0, 0, 88, 89, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 90, 91, 92, 93, 94, 0, 0, + 0, 95, 0, 0, 0, 96, 0, 0, 0, 0, + 97, 98, 99, 100, 101, 0, 0, 0, 102, 0, + 103, 0, 0, 0, 0, 0, 104, 105, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 269, 0, 0, + 0, 106, 107, 108, 109, 57, 24, 58, 25, 0, + 0, 26, 59, 0, 60, 61, 27, 62, 63, 64, + 28, 0, 0, 0, 0, 0, 65, 0, 66, 30, + 67, 68, 69, 70, 0, 0, 32, 0, 0, 0, + 71, 33, 0, 72, 73, 34, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 74, 0, 36, 0, 37, + 75, 0, 0, 38, 0, 76, 77, 78, 79, 80, + 81, 39, 40, 82, 83, 41, 84, 0, 85, 0, + 0, 86, 87, 0, 0, 88, 89, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 90, 91, 92, 93, 94, 0, 0, 0, 95, 0, + 0, 0, 96, 0, 0, 0, 0, 97, 98, 99, + 100, 101, 0, 0, 0, 102, 0, 103, 0, 0, + 0, 0, 0, 104, 105, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 584, 0, 0, 0, 106, 107, + 108, 109, 57, 24, 58, 25, 0, 0, 26, 59, + 0, 60, 61, 27, 62, 63, 64, 28, 0, 0, + 0, 0, 0, 65, 0, 66, 30, 67, 68, 69, + 70, 0, 0, 32, 0, 0, 0, 71, 33, 0, + 72, 73, 34, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 74, 0, 36, 0, 37, 75, 0, 0, + 38, 0, 76, 77, 78, 79, 80, 81, 39, 40, + 82, 83, 41, 84, 0, 85, 0, 0, 86, 87, + 0, 0, 88, 89, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 90, 91, 92, + 93, 94, 0, 0, 0, 95, 0, 0, 0, 96, + 0, 0, 0, 0, 97, 98, 99, 100, 101, 0, + 0, 0, 102, 0, 103, 0, 0, 0, 0, 0, + 104, 105, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1024, 0, 0, 0, 106, 585, 108, 109, 1024, + 1024, 1024, 1024, 0, 0, 1024, 1024, 0, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 0, 0, 0, 0, 0, + 1024, 0, 1024, 1024, 1024, 1024, 1024, 1024, 0, 0, + 1024, 0, 0, 0, 1024, 1024, 0, 1024, 1024, 1024, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1024, + 0, 1024, 0, 1024, 1024, 0, 0, 1024, 0, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 0, 1024, 0, 0, 1024, 1024, 0, 0, 1024, + 1024, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1024, 1024, 1024, 1024, 1024, 0, + 0, 0, 1024, 0, 0, 0, 1024, 0, 0, 0, + 0, 1024, 1024, 1024, 1024, 1024, 0, 0, 0, 1024, + 0, 1024, 0, 0, 0, 0, 0, 1024, 1024, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 625, 0, + 0, 0, 1024, 1024, 1024, 1024, 57, 24, 0, 25, + 0, 0, 26, 256, 0, 968, 0, 27, 62, 63, + 0, 28, 0, 0, 24, 0, 25, 65, 0, 26, + 30, 0, 0, 0, 27, 0, 0, 32, 28, 0, + 0, 0, 33, 0, 72, 73, 34, 30, 626, 0, + 0, 0, 0, 0, 32, 627, 0, 0, 36, 33, + 37, 75, 0, 34, 38, 0, 0, 77, 0, 79, + 0, 81, 39, 40, 257, 36, 41, 37, 0, 0, + 0, 38, 0, 628, 0, 0, 88, 89, 0, 39, + 40, 0, 0, 41, 0, 0, 327, 0, 0, 0, + 0, 90, 91, 92, 93, 94, 0, 0, 0, 0, + 0, 0, 0, 96, 0, 0, 629, 0, 0, 98, + 99, 100, 101, 0, 0, 0, 102, 0, 103, 0, + 0, 0, 0, 0, 104, 105, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 800, 0, 0, 0, 106, + 107, 108, 109, 57, 24, 0, 25, 0, 0, 26, + 256, 0, 1121, 0, 27, 62, 63, 374, 28, 0, + 0, 24, 0, 25, 65, 0, 26, 30, 0, 0, + 0, 27, 0, 0, 32, 28, 0, 0, 0, 33, + 0, 72, 73, 34, 30, 0, 0, 0, 0, 0, + 0, 32, 0, 0, 0, 36, 33, 37, 75, 0, + 34, 38, 0, 0, 77, 0, 79, 0, 81, 39, + 40, 257, 36, 41, 37, 0, 0, 0, 38, 0, + 87, 0, 0, 88, 89, 0, 39, 40, 0, 0, + 41, 0, 0, 327, 0, 0, 0, 0, 90, 91, + 92, 93, 305, 0, 0, 0, 540, 801, 0, 0, + 96, 0, 0, 0, 0, 0, 98, 99, 100, 101, + 0, 0, 0, 102, 0, 103, 0, 0, 0, 0, + 0, 104, 105, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 995, 0, 0, 0, 106, 306, 108, 109, + 57, 24, 0, 25, 0, 0, 26, 256, 0, 0, + 0, 27, 62, 63, 374, 28, 0, 0, 182, 0, + 182, 65, 0, 182, 30, 0, 0, 0, 182, 0, + 0, 32, 182, 0, 0, 0, 33, 0, 72, 73, + 34, 182, 626, 0, 0, 0, 0, 0, 182, 627, + 0, 0, 36, 182, 37, 75, 0, 182, 38, 0, + 0, 77, 0, 79, 0, 81, 39, 40, 257, 182, + 41, 182, 0, 0, 0, 182, 0, 628, 0, 0, + 88, 89, 0, 182, 182, 0, 0, 182, 0, 0, + 182, 0, 0, 0, 0, 90, 91, 92, 93, 94, + 0, 0, 0, 0, 0, 0, 0, 96, 0, 0, + 0, 0, 0, 98, 99, 100, 101, 0, 0, 0, + 102, 0, 103, 0, 0, 1049, 0, 0, 104, 105, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 800, + 0, 0, 0, 106, 107, 108, 109, 57, 24, 0, + 25, 0, 0, 26, 256, 0, 0, 0, 27, 62, + 63, 182, 28, 0, 0, 182, 0, 182, 65, 0, + 182, 30, 0, 0, 0, 182, 0, 0, 32, 182, + 0, 0, 0, 33, 0, 72, 73, 34, 182, 0, + 0, 0, 0, 0, 0, 182, 0, 0, 0, 36, + 182, 37, 75, 1001, 182, 38, 0, 0, 77, 0, + 79, 0, 81, 39, 40, 257, 182, 41, 182, 0, + 0, 0, 182, 0, 87, 0, 0, 88, 89, 0, + 182, 182, 0, 0, 182, 0, 0, 182, 0, 0, + 0, 0, 90, 91, 92, 93, 305, 0, 0, 0, + 540, 0, 0, 0, 96, 0, 0, 0, 0, 0, + 98, 99, 100, 101, 0, 0, 0, 102, 0, 103, + 1049, 0, 0, 0, 0, 104, 105, 0, 0, 0, + 0, 0, 0, 57, 24, 0, 25, 0, 0, 26, + 256, 0, 0, 0, 27, 62, 63, 0, 28, 0, + 106, 306, 108, 109, 65, 0, 0, 30, 0, 0, + 0, 0, 0, 0, 32, 0, 0, 0, 182, 33, + 0, 72, 73, 34, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 36, 0, 37, 75, 0, + 0, 38, 0, 0, 77, 0, 79, 0, 81, 39, + 40, 257, 0, 41, 0, 0, 0, 0, 0, 0, + 87, 0, 0, 88, 89, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 90, 91, + 92, 93, 783, 0, 0, 0, 784, 1069, 0, 0, + 96, 0, 0, 0, 0, 0, 98, 99, 100, 101, + 0, 0, 0, 102, 0, 103, 0, 0, 0, 0, + 0, 104, 105, 0, 0, 0, 0, 0, 0, 57, + 24, 0, 25, 0, 0, 26, 256, 0, 0, 0, + 27, 62, 63, 0, 28, 0, 106, 785, 108, 109, + 65, 0, 0, 30, 0, 0, 0, 786, 0, 0, + 32, 0, 0, 0, 0, 33, 0, 72, 73, 34, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 36, 0, 37, 75, 0, 0, 38, 0, 0, + 77, 0, 79, 0, 81, 39, 40, 257, 0, 41, + 0, 0, 0, 0, 0, 0, 87, 0, 0, 88, + 89, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 90, 91, 92, 93, 783, 0, + 0, 0, 784, 0, 0, 0, 96, 0, 0, 0, + 0, 0, 98, 99, 100, 101, 0, 0, 0, 102, + 0, 103, 0, 0, 0, 0, 0, 104, 105, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 800, 0, 106, 785, 108, 109, 0, 0, 57, 24, + 0, 25, 0, 786, 26, 256, 0, 0, 0, 27, + 62, 63, 0, 28, 0, 0, 0, 0, 0, 65, 0, 0, 30, 0, 0, 0, 0, 0, 0, 32, - 0, 0, 0, 355, 33, 0, 71, 72, 34, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 36, 0, 37, 74, 0, 0, 38, 0, 0, 76, - 0, 78, 0, 80, 39, 40, 254, 0, 41, 0, - 0, 0, 0, 0, 0, 86, 0, 0, 87, 88, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 89, 90, 91, 92, 301, 0, 0, - 0, 729, 0, 0, 0, 95, 0, 0, 0, 0, - 0, 97, 98, 99, 100, 0, 0, 0, 101, 0, - 102, 0, 0, 0, 0, 0, 103, 104, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 743, - 0, 105, 730, 107, 108, 0, 0, 56, 24, 0, - 25, 0, 731, 26, 253, 0, 0, 0, 27, 61, - 62, 0, 28, 0, 0, 24, 0, 25, 64, 0, - 26, 30, 0, 0, 0, 27, 0, 0, 32, 28, - 0, 0, 0, 33, 0, 71, 72, 34, 30, 0, - 0, 0, 0, 0, 0, 32, 0, 0, 0, 36, - 33, 37, 74, 0, 34, 38, 0, 0, 76, 0, - 78, 0, 80, 39, 40, 254, 36, 41, 37, 0, - 0, 0, 38, 0, 86, 0, 0, 87, 88, 0, - 39, 40, 0, 0, 41, 0, 0, 573, 0, 0, - 0, 0, 89, 90, 91, 92, 301, 0, 0, 0, - 517, 0, 0, 0, 95, 0, 0, 0, 0, 0, - 97, 98, 99, 100, 0, 0, 0, 101, 0, 102, - 0, 0, 0, 0, 0, 103, 104, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 300, 0, 0, 0, - 105, 302, 107, 108, 56, 24, 0, 25, 0, 0, - 26, 253, 0, 0, 0, 27, 61, 62, 355, 28, - 0, 0, 24, 0, 25, 64, 0, 26, 30, 0, - 0, 0, 27, 0, 0, 32, 28, 0, 0, 0, - 33, 0, 71, 72, 34, 30, 0, 0, 0, 0, - 0, 0, 32, 0, 0, 0, 36, 33, 37, 74, - 0, 34, 38, 0, 0, 76, 0, 78, 0, 80, - 39, 40, 254, 36, 41, 37, 0, 0, 0, 38, - 0, 86, 0, 0, 87, 88, 0, 39, 40, 0, - 0, 41, 0, 0, 758, 0, 0, 0, 0, 89, - 90, 91, 92, 301, 0, 0, 0, 0, 0, 0, - 0, 95, 0, 0, 0, 0, 0, 97, 98, 99, - 100, 0, 0, 0, 101, 0, 102, 0, 0, 0, - 0, 0, 103, 104, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 309, 0, 0, 0, 105, 302, 107, - 108, 56, 24, 0, 25, 0, 0, 26, 253, 0, - 0, 0, 27, 61, 62, 355, 28, 0, 0, 491, - 0, 491, 64, 0, 491, 30, 0, 0, 0, 491, - 0, 0, 32, 491, 0, 0, 0, 33, 0, 71, - 72, 34, 491, 0, 0, 0, 0, 0, 0, 491, - 0, 0, 0, 36, 491, 37, 74, 0, 491, 38, - 0, 0, 76, 0, 78, 0, 80, 39, 40, 254, - 491, 41, 491, 0, 0, 0, 491, 0, 86, 0, - 0, 87, 88, 0, 491, 491, 0, 0, 491, 0, - 0, 491, 0, 0, 0, 0, 89, 90, 91, 92, - 301, 0, 0, 0, 0, 0, 0, 0, 95, 0, - 0, 0, 0, 0, 97, 98, 99, 100, 0, 0, - 0, 101, 0, 102, 0, 0, 0, 0, 0, 103, - 104, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 592, 0, 0, 0, 105, 302, 107, 108, 56, 24, - 0, 25, 0, 0, 26, 253, 0, 0, 0, 27, - 61, 62, 491, 28, 0, 0, 175, 0, 175, 64, - 0, 175, 30, 0, 0, 0, 175, 0, 0, 32, - 175, 0, 0, 0, 33, 0, 71, 72, 34, 175, - 0, 0, 0, 0, 0, 0, 175, 0, 0, 0, - 36, 175, 37, 74, 0, 175, 38, 0, 0, 76, - 0, 78, 0, 80, 39, 40, 254, 175, 41, 175, - 0, 0, 0, 175, 0, 86, 0, 0, 87, 88, - 0, 175, 175, 0, 0, 175, 0, 0, 175, 0, - 0, 0, 0, 89, 90, 91, 92, 93, 0, 0, - 0, 0, 0, 0, 0, 95, 0, 0, 0, 0, - 0, 97, 98, 99, 100, 0, 0, 0, 101, 0, - 102, 0, 0, 0, 0, 0, 103, 104, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 823, 0, 0, - 0, 105, 106, 107, 108, 56, 24, 0, 25, 0, - 0, 26, 253, 0, 0, 0, 27, 61, 62, 175, - 28, 0, 0, 174, 0, 174, 64, 0, 174, 30, - 0, 0, 0, 174, 0, 0, 32, 174, 0, 0, - 0, 33, 0, 71, 72, 34, 174, 0, 0, 0, - 0, 0, 0, 174, 0, 0, 0, 36, 174, 37, - 74, 0, 174, 38, 0, 0, 76, 0, 78, 0, - 80, 39, 40, 254, 174, 41, 174, 0, 0, 0, - 174, 0, 86, 0, 0, 87, 88, 0, 174, 174, - 0, 0, 174, 0, 0, 174, 0, 0, 0, 0, - 89, 90, 91, 92, 301, 0, 0, 0, 0, 0, - 0, 0, 95, 0, 0, 0, 0, 0, 97, 98, - 99, 100, 0, 0, 0, 101, 0, 102, 0, 0, - 0, 0, 0, 103, 104, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 1189, 0, 0, 0, 105, 302, - 107, 108, 56, 24, 0, 25, 0, 0, 26, 253, - 0, 0, 0, 27, 61, 62, 174, 28, 0, 0, - 184, 0, 184, 64, 0, 184, 30, 0, 0, 0, - 184, 0, 0, 32, 184, 0, 0, 0, 33, 0, - 71, 72, 34, 184, 0, 0, 0, 0, 0, 0, - 184, 0, 0, 0, 36, 184, 37, 74, 0, 184, - 38, 0, 0, 76, 0, 78, 0, 80, 39, 40, - 254, 184, 41, 184, 0, 0, 0, 184, 0, 86, - 0, 0, 87, 88, 0, 184, 184, 0, 0, 184, - 0, 0, 184, 0, 0, 0, 0, 89, 90, 91, - 92, 301, 0, 0, 0, 0, 0, 0, 0, 95, - 0, 0, 0, 0, 0, 97, 98, 99, 100, 0, - 0, 0, 101, 0, 102, 0, 0, 0, 0, 0, - 103, 104, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 610, 0, 0, 0, 105, 302, 107, 108, 610, - 610, 0, 610, 0, 0, 610, 610, 0, 0, 0, - 610, 610, 610, 184, 610, 0, 0, 0, 0, 0, - 610, 0, 0, 610, 0, 0, 0, 0, 0, 0, - 610, 0, 0, 0, 0, 610, 0, 610, 610, 610, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 610, 0, 610, 610, 0, 0, 610, 0, 0, - 610, 0, 610, 0, 610, 610, 610, 610, 0, 610, - 0, 0, 0, 0, 0, 0, 610, 0, 0, 610, - 610, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 610, 610, 610, 610, 610, 0, - 0, 0, 0, 0, 0, 0, 610, 0, 0, 0, - 0, 0, 610, 610, 610, 610, 0, 0, 0, 610, - 0, 610, 0, 0, 0, 0, 0, 610, 610, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 500, 0, - 0, 0, 610, 610, 610, 610, 56, 24, 0, 25, - 0, 0, 26, 253, 0, 0, 0, 27, 61, 62, - 0, 28, 0, 0, 0, 0, 0, 64, 0, 0, - 30, 0, 0, 0, 27, 0, 0, 32, 0, 0, - 0, 337, 33, 0, 71, 72, 34, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 27, 36, 0, - 37, 74, 0, 0, 38, 0, 0, 76, 0, 78, - 27, 80, 39, 40, 254, 27, 41, 337, 0, 0, - 27, 0, 27, 27, 27, 27, 0, 0, 27, 0, - 27, 0, 0, 0, 27, 0, 0, 0, 0, 0, - 0, 89, 90, 91, 255, 0, 27, 0, 0, 27, - 0, 27, 0, 95, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 27, 0, 0, 0, 0, - 0, 27, 27, 0, 0, 0, 0, 0, 0, 0, - 337, 337, 337, 337, 745, 0, 0, 337, 337, 105, - 501, 337, 337, 337, 337, 337, 337, 337, 337, 337, - 0, 337, 337, 337, 337, 337, 337, 337, 337, 337, - 337, 337, 337, 337, 337, 337, 337, 337, 337, 337, - 337, 337, 337, 0, 48, 0, 48, 0, 48, 337, - 48, 0, 337, 48, 0, 48, 48, 0, 48, 0, - 48, 0, 48, 0, 48, 48, 48, 48, 0, 0, - 48, 48, 0, 0, 0, 0, 48, 48, 48, 48, - 48, 0, 0, 48, 0, 48, 0, 48, 0, 48, - 48, 0, 48, 48, 48, 48, 0, 0, 48, 48, - 48, 48, 0, 0, 48, 48, 48, 0, 0, 0, - 0, 0, 0, 48, 48, 0, 48, 48, 0, 48, - 48, 48, 0, 0, 0, 48, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 48, 0, 48, 48, 47, - 0, 0, 0, 47, 0, 47, 0, 0, 47, 0, - 47, 47, 0, 47, 0, 47, 0, 47, 0, 47, - 47, 47, 47, 0, 0, 47, 47, 0, 0, 0, - 0, 47, 0, 47, 47, 47, 0, 0, 47, 0, - 47, 0, 47, 0, 0, 47, 0, 47, 47, 47, - 47, 48, 0, 0, 47, 47, 47, 0, 0, 47, - 47, 47, 0, 0, 0, 0, 0, 0, 47, 47, - 0, 47, 47, 0, 47, 47, 47, 0, 0, 0, - 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 47, 0, - 47, 0, 47, 0, 47, 0, 80, 47, 0, 47, - 47, 0, 47, 0, 47, 47, 47, 0, 47, 47, - 47, 47, 0, 0, 47, 47, 0, 0, 0, 0, - 47, 0, 47, 47, 47, 0, 0, 47, 0, 47, - 0, 47, 0, 0, 47, 0, 47, 47, 47, 47, - 0, 0, 0, 47, 47, 47, 47, 0, 47, 47, - 47, 0, 0, 0, 0, 0, 0, 47, 47, 0, - 47, 47, 0, 47, 47, 47, 0, 0, 0, 47, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 48, 0, 47, - 0, 48, 0, 48, 0, 81, 48, 0, 48, 48, - 0, 48, 0, 48, 47, 48, 0, 48, 48, 48, - 48, 0, 0, 48, 48, 0, 0, 0, 0, 48, - 0, 48, 48, 48, 0, 0, 48, 0, 48, 0, - 48, 0, 0, 48, 0, 48, 48, 48, 48, 0, - 0, 0, 48, 48, 48, 47, 0, 48, 48, 48, - 0, 0, 0, 0, 0, 0, 48, 48, 0, 48, - 48, 0, 48, 48, 48, 0, 0, 0, 48, 0, - 0, 0, 0, 47, 0, 0, 0, 47, 0, 47, - 0, 0, 47, 0, 47, 47, 0, 47, 48, 47, - 0, 47, 0, 47, 47, 47, 47, 0, 0, 47, - 47, 0, 0, 48, 0, 47, 0, 47, 47, 47, - 0, 0, 47, 0, 47, 0, 47, 0, 0, 47, - 0, 47, 47, 47, 47, 0, 0, 0, 47, 47, - 47, 0, 0, 47, 47, 47, 0, 0, 0, 0, - 0, 0, 47, 47, 48, 47, 47, 0, 47, 47, - 47, 0, 0, 0, 47, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 47, 0, 0, - 0, 47, 0, 47, 47, 0, 47, 0, 47, 47, - 214, 47, 0, 47, 0, 47, 0, 47, 47, 47, - 47, 0, 0, 47, 47, 0, 0, 0, 0, 47, - 0, 47, 47, 47, 0, 0, 47, 0, 47, 337, - 47, 0, 0, 47, 0, 47, 47, 47, 47, 0, - 0, 0, 47, 47, 47, 0, 0, 47, 47, 47, - 47, 0, 337, 0, 0, 0, 47, 47, 0, 47, - 47, 452, 47, 47, 47, 337, 0, 0, 47, 0, - 337, 0, 0, 337, 0, 337, 0, 337, 337, 337, - 337, 0, 0, 0, 453, 337, 0, 0, 47, 337, - 0, 0, 0, 337, 215, 0, 0, 454, 0, 0, - 0, 337, 456, 0, 337, 0, 337, 457, 0, 458, - 459, 460, 461, 0, 0, 0, 0, 462, 0, 0, - 0, 463, 0, 0, 0, 337, 0, 0, 0, 0, - 337, 0, 0, 464, 0, 0, 465, 337, 466, 265, - 0, 337, 0, 0, 47, 56, 24, 0, 25, 0, - 0, 26, 253, 0, 337, 0, 27, 61, 62, 0, - 28, 0, 467, 0, 0, 0, 64, 0, 0, 30, - 0, 0, 0, 0, 0, 0, 32, 0, 0, 0, - 0, 33, 0, 71, 72, 34, 337, 594, 0, 0, - 0, 0, 0, 0, 595, 0, 0, 36, 0, 37, - 74, 0, 0, 38, 0, 0, 76, 0, 78, 0, - 80, 39, 40, 254, 0, 41, 0, 0, 1340, 0, - 0, 0, 596, 0, 0, 87, 88, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 89, 90, 91, 92, 93, 0, 0, 0, 0, 0, - 0, 0, 95, 930, 0, 597, 0, 0, 97, 98, - 99, 100, 0, 0, 0, 101, 0, 102, 0, 0, - 0, 0, 0, 103, 104, 0, 0, 0, 0, 0, - 0, 56, 24, 0, 25, 0, 0, 26, 253, 0, - 0, 0, 27, 61, 62, 0, 28, 0, 105, 106, - 107, 108, 64, 0, 0, 30, 0, 0, 0, 0, - 0, 0, 32, 0, 0, 0, 0, 33, 0, 71, - 72, 34, 0, 594, 0, 0, 0, 0, 0, 0, - 595, 0, 0, 36, 0, 37, 74, 0, 0, 38, - 0, 0, 76, 0, 78, 0, 80, 39, 40, 254, - 0, 41, 0, 0, 0, 0, 0, 0, 596, 0, - 0, 87, 88, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 89, 90, 91, 92, - 93, 0, 0, 0, 0, 0, 0, 0, 95, 0, - 0, 597, 0, 0, 97, 98, 99, 100, 0, 0, - 0, 101, 0, 102, 0, 0, 0, 0, 0, 103, - 104, 0, 0, 0, 0, 0, 0, 56, 24, 0, - 25, 0, 0, 26, 253, 0, 0, 0, 27, 61, - 62, 0, 28, 0, 105, 106, 107, 108, 64, 0, + 0, 0, 0, 0, 33, 0, 72, 73, 34, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 36, 0, 37, 75, 0, 0, 38, 0, 0, 77, + 0, 79, 0, 81, 39, 40, 257, 0, 41, 0, + 0, 0, 0, 0, 0, 87, 0, 0, 88, 89, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 90, 91, 92, 93, 305, 0, 0, + 0, 540, 0, 0, 0, 96, 0, 0, 0, 0, + 0, 98, 99, 100, 101, 0, 0, 0, 102, 0, + 103, 0, 0, 0, 0, 0, 104, 105, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 343, + 0, 106, 306, 108, 109, 344, 0, 57, 24, 0, + 25, 0, 0, 26, 256, 0, 0, 0, 27, 62, + 63, 0, 28, 0, 0, 0, 0, 0, 65, 0, 0, 30, 0, 0, 0, 0, 0, 0, 32, 0, - 0, 0, 0, 33, 0, 71, 72, 34, 0, 0, + 0, 345, 0, 33, 0, 72, 73, 34, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 36, + 0, 37, 75, 0, 0, 38, 0, 0, 77, 0, + 79, 0, 81, 39, 40, 257, 0, 41, 0, 0, + 0, 0, 0, 0, 0, 0, 346, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 90, 91, 92, 258, 347, 0, 0, 0, + 0, 0, 0, 0, 96, 0, 348, 0, 0, 0, + 98, 99, 100, 101, 950, 0, 0, 102, 0, 103, + 792, 0, 0, 0, 0, 104, 105, 0, 57, 24, + 0, 25, 0, 0, 26, 256, 0, 0, 0, 27, + 62, 63, 0, 28, 0, 0, 0, 0, 0, 65, + 106, 260, 30, 109, 0, 0, 0, 0, 0, 32, + 0, 0, 0, 0, 33, 0, 72, 73, 34, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 36, 0, 37, 75, 0, 0, 38, 0, 0, 77, + 0, 79, 0, 81, 39, 40, 257, 0, 41, 0, + 0, 0, 0, 0, 0, 87, 0, 0, 88, 89, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 90, 91, 92, 93, 305, 0, 0, + 0, 0, 951, 0, 0, 96, 0, 0, 0, 0, + 0, 98, 99, 100, 101, 0, 0, 0, 102, 0, + 103, 0, 0, 0, 0, 0, 104, 105, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 998, 0, 0, + 0, 106, 306, 108, 109, 57, 24, 0, 25, 0, + 0, 26, 256, 0, 0, 0, 27, 62, 63, 0, + 28, 0, 0, 24, 0, 25, 65, 0, 26, 30, + 0, 0, 0, 27, 0, 0, 32, 28, 0, 0, + 0, 33, 0, 72, 73, 34, 30, 0, 0, 0, + 0, 0, 0, 32, 0, 0, 0, 36, 33, 37, + 75, 0, 34, 38, 0, 0, 77, 0, 79, 0, + 81, 39, 40, 257, 36, 41, 37, 0, 0, 0, + 38, 0, 87, 0, 0, 88, 89, 0, 39, 40, + 0, 0, 41, 0, 0, 327, 0, 0, 0, 0, + 90, 91, 92, 93, 305, 0, 0, 0, 0, 999, + 0, 0, 96, 0, 0, 0, 0, 0, 98, 99, + 100, 101, 0, 0, 0, 102, 0, 103, 0, 0, + 0, 0, 0, 104, 105, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 304, 0, 0, 0, 106, 306, + 108, 109, 57, 24, 0, 25, 0, 0, 26, 256, + 0, 0, 0, 27, 62, 63, 374, 28, 0, 0, + 24, 0, 25, 65, 0, 26, 30, 0, 0, 0, + 27, 0, 0, 32, 28, 0, 0, 0, 33, 0, + 72, 73, 34, 30, 0, 0, 0, 0, 0, 0, + 32, 0, 0, 0, 36, 33, 37, 75, 0, 34, + 38, 0, 0, 77, 0, 79, 0, 81, 39, 40, + 257, 36, 41, 37, 0, 0, 0, 38, 0, 87, + 0, 0, 88, 89, 0, 39, 40, 0, 0, 41, + 0, 0, 542, 0, 0, 0, 0, 90, 91, 92, + 93, 305, 0, 0, 0, 0, 0, 0, 0, 96, + 0, 0, 0, 0, 0, 98, 99, 100, 101, 0, + 0, 0, 102, 0, 103, 0, 0, 0, 0, 0, + 104, 105, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 313, 0, 0, 0, 106, 306, 108, 109, 57, + 24, 0, 25, 0, 0, 26, 256, 0, 0, 0, + 27, 62, 63, 374, 28, 0, 0, 0, 0, 0, + 65, 0, 0, 30, 0, 0, 0, 0, 0, 0, + 32, 0, 0, 0, 0, 33, 0, 72, 73, 34, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 36, 0, 37, 75, 0, 0, 38, 0, 0, + 77, 0, 79, 0, 81, 39, 40, 257, 0, 41, + 0, 0, 0, 0, 0, 0, 87, 0, 0, 88, + 89, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 90, 91, 92, 93, 305, 0, + 0, 0, 0, 0, 0, 0, 96, 0, 0, 0, + 0, 0, 98, 99, 100, 101, 0, 0, 0, 102, + 0, 103, 0, 0, 0, 0, 0, 104, 105, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 343, 0, 106, 306, 108, 109, 344, 0, 57, 24, + 0, 25, 0, 0, 26, 256, 0, 0, 0, 27, + 62, 63, 0, 28, 0, 0, 0, 0, 0, 65, + 0, 0, 30, 0, 0, 0, 0, 0, 0, 32, + 0, 0, 345, 0, 33, 0, 72, 73, 34, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 36, 0, 37, 75, 0, 0, 38, 0, 0, 77, + 0, 79, 0, 81, 39, 40, 257, 0, 41, 0, + 0, 0, 0, 0, 0, 0, 0, 346, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 90, 91, 92, 258, 347, 0, 0, + 0, 0, 0, 0, 0, 96, 0, 348, 0, 0, + 0, 98, 99, 100, 101, 0, 0, 0, 102, 0, + 103, 623, 0, 0, 0, 0, 104, 105, 0, 57, + 24, 0, 25, 0, 0, 26, 256, 0, 0, 0, + 27, 62, 63, 0, 28, 0, 0, 0, 0, 0, + 65, 106, 260, 30, 109, 0, 0, 0, 0, 0, + 32, 0, 0, 0, 0, 33, 0, 72, 73, 34, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 36, 0, 37, 75, 0, 0, 38, 0, 0, + 77, 0, 79, 0, 81, 39, 40, 257, 0, 41, + 0, 0, 0, 0, 0, 0, 87, 0, 0, 88, + 89, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 90, 91, 92, 93, 94, 0, + 0, 0, 0, 0, 0, 0, 96, 0, 0, 0, + 0, 0, 98, 99, 100, 101, 0, 0, 0, 102, + 0, 103, 0, 0, 0, 0, 0, 104, 105, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 792, 0, + 0, 0, 106, 107, 108, 109, 57, 24, 0, 25, + 0, 0, 26, 256, 0, 0, 0, 27, 62, 63, + 0, 28, 0, 0, 24, 0, 25, 65, 0, 26, + 30, 0, 0, 0, 27, 0, 0, 32, 28, 0, + 0, 0, 33, 0, 72, 73, 34, 30, 0, 0, + 0, 0, 0, 0, 32, 0, 0, 0, 36, 33, + 37, 75, 0, 34, 38, 0, 0, 77, 0, 79, + 0, 81, 39, 40, 257, 36, 41, 37, 0, 0, + 0, 38, 0, 87, 0, 0, 88, 89, 0, 39, + 40, 0, 0, 41, 0, 0, 601, 0, 0, 0, + 0, 90, 91, 92, 93, 305, 0, 0, 0, 0, + 0, 0, 0, 96, 0, 0, 0, 0, 0, 98, + 99, 100, 101, 0, 0, 0, 102, 0, 103, 0, + 0, 0, 0, 0, 104, 105, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1112, 0, 0, 0, 106, + 306, 108, 109, 57, 24, 0, 25, 0, 0, 26, + 256, 0, 0, 0, 27, 62, 63, 374, 28, 0, + 0, 24, 0, 25, 65, 0, 26, 30, 0, 0, + 0, 27, 0, 0, 32, 28, 0, 0, 0, 33, + 0, 72, 73, 34, 30, 0, 0, 0, 0, 0, + 0, 32, 0, 0, 0, 36, 33, 37, 75, 0, + 34, 38, 0, 0, 77, 0, 79, 0, 81, 39, + 40, 257, 36, 41, 37, 0, 0, 0, 38, 0, + 87, 0, 0, 88, 89, 0, 39, 40, 0, 0, + 41, 0, 0, 817, 0, 0, 0, 0, 90, 91, + 92, 93, 94, 0, 0, 0, 0, 0, 0, 0, + 96, 0, 0, 0, 0, 0, 98, 99, 100, 101, + 0, 0, 0, 102, 0, 103, 0, 0, 0, 0, + 0, 104, 105, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1264, 0, 0, 0, 106, 1113, 108, 109, + 57, 24, 0, 25, 0, 0, 26, 256, 0, 0, + 0, 27, 62, 63, 374, 28, 0, 0, 503, 0, + 503, 65, 0, 503, 30, 0, 0, 0, 503, 0, + 0, 32, 503, 0, 0, 0, 33, 0, 72, 73, + 34, 503, 0, 0, 0, 0, 0, 0, 503, 0, + 0, 0, 36, 503, 37, 75, 0, 503, 38, 0, + 0, 77, 0, 79, 0, 81, 39, 40, 257, 503, + 41, 503, 0, 0, 0, 503, 0, 87, 0, 0, + 88, 89, 0, 503, 503, 0, 0, 503, 0, 0, + 503, 0, 0, 0, 0, 90, 91, 92, 93, 305, + 0, 0, 0, 0, 0, 0, 0, 96, 0, 0, + 0, 0, 0, 98, 99, 100, 101, 0, 0, 0, + 102, 0, 103, 0, 0, 0, 0, 0, 104, 105, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 83, + 0, 0, 0, 106, 306, 108, 109, 83, 83, 0, + 83, 0, 0, 83, 83, 0, 0, 0, 83, 83, + 83, 503, 83, 0, 0, 0, 0, 0, 83, 0, + 0, 83, 0, 0, 0, 0, 0, 0, 83, 0, + 0, 0, 0, 83, 0, 83, 83, 83, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 83, + 0, 83, 83, 0, 0, 83, 0, 0, 83, 0, + 83, 0, 83, 83, 83, 83, 0, 83, 0, 0, + 0, 0, 0, 0, 83, 0, 0, 83, 83, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 83, 83, 83, 83, 83, 0, 0, 0, + 0, 0, 0, 0, 83, 0, 0, 0, 0, 0, + 83, 83, 83, 83, 0, 0, 0, 83, 0, 83, + 0, 0, 0, 0, 0, 83, 83, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 343, 0, + 83, 83, 83, 83, 344, 0, 57, 24, 0, 25, + 0, 0, 26, 256, 0, 0, 0, 27, 62, 63, + 0, 28, 0, 0, 0, 0, 0, 65, 0, 0, + 30, 0, 0, 0, 0, 0, 0, 32, 0, 0, + 345, 0, 33, 0, 72, 73, 34, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 36, 0, + 37, 75, 0, 0, 38, 0, 0, 77, 0, 79, + 0, 81, 39, 40, 257, 0, 41, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 90, 91, 92, 258, 347, 0, 0, 0, 0, + 0, 0, 0, 96, 0, 348, 0, 0, 0, 98, + 99, 100, 101, 0, 0, 0, 102, 0, 103, 343, + 0, 0, 0, 0, 104, 105, 0, 57, 24, 0, + 25, 0, 0, 26, 256, 0, 0, 0, 27, 62, + 63, 0, 28, 0, 0, 0, 0, 0, 65, 106, + 260, 30, 109, 0, 0, 0, 0, 0, 32, 0, + 0, 0, 0, 33, 0, 72, 73, 34, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 36, + 0, 37, 75, 0, 0, 38, 0, 0, 77, 0, + 79, 0, 81, 39, 40, 257, 0, 41, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 90, 91, 92, 258, 347, 0, 0, 0, + 0, 0, 0, 0, 96, 0, 348, 0, 0, 0, + 98, 99, 100, 101, 0, 0, 0, 102, 0, 103, + 352, 0, 0, 0, 0, 104, 105, 0, 57, 24, + 0, 25, 0, 0, 26, 256, 0, 0, 0, 27, + 62, 63, 0, 28, 0, 0, 0, 0, 0, 65, + 106, 260, 30, 109, 0, 0, 0, 0, 0, 32, + 0, 0, 0, 0, 33, 0, 72, 73, 34, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 36, 0, 37, 75, 0, 0, 38, 0, 0, 77, + 0, 79, 0, 81, 39, 40, 257, 0, 41, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 90, 91, 92, 258, 347, 0, 0, + 0, 0, 0, 0, 0, 96, 0, 0, 0, 0, + 0, 98, 99, 100, 101, 0, 0, 0, 102, 0, + 103, 354, 0, 0, 0, 0, 104, 105, 0, 57, + 24, 0, 25, 0, 0, 26, 256, 0, 0, 0, + 27, 62, 63, 0, 28, 0, 0, 0, 0, 0, + 65, 106, 260, 30, 109, 0, 0, 0, 0, 0, + 32, 0, 0, 0, 0, 33, 0, 72, 73, 34, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 36, 0, 37, 75, 0, 0, 38, 0, 0, + 77, 0, 79, 0, 81, 39, 40, 257, 0, 41, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 90, 91, 92, 258, 347, 0, + 0, 0, 0, 0, 0, 0, 96, 0, 0, 0, + 0, 0, 98, 99, 100, 101, 0, 0, 0, 102, + 0, 103, 356, 0, 0, 0, 0, 104, 105, 0, + 57, 24, 0, 25, 0, 0, 26, 256, 0, 0, + 0, 27, 62, 63, 0, 28, 0, 0, 0, 0, + 0, 65, 106, 260, 30, 109, 0, 0, 0, 0, + 0, 32, 0, 0, 0, 0, 33, 0, 72, 73, + 34, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 36, 0, 37, 75, 0, 0, 38, 0, + 0, 77, 0, 79, 0, 81, 39, 40, 257, 0, + 41, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 90, 91, 92, 258, 347, + 0, 0, 0, 0, 0, 0, 0, 96, 0, 0, + 0, 0, 0, 98, 99, 100, 101, 0, 0, 0, + 102, 0, 103, 358, 0, 0, 0, 0, 104, 105, + 0, 57, 24, 0, 25, 0, 0, 26, 256, 0, + 0, 0, 27, 62, 63, 0, 28, 0, 0, 0, + 0, 0, 65, 106, 260, 30, 109, 0, 0, 0, + 0, 0, 32, 0, 0, 0, 0, 33, 0, 72, + 73, 34, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 36, 0, 37, 75, 0, 0, 38, + 0, 0, 77, 0, 79, 0, 81, 39, 40, 257, + 0, 41, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 90, 91, 92, 258, + 347, 0, 0, 0, 0, 0, 0, 0, 96, 0, + 0, 0, 0, 0, 98, 99, 100, 101, 0, 0, + 0, 102, 0, 103, 360, 0, 0, 0, 0, 104, + 105, 0, 57, 24, 0, 25, 0, 0, 26, 256, + 0, 0, 0, 27, 62, 63, 0, 28, 0, 0, + 0, 0, 0, 65, 106, 260, 30, 109, 0, 0, + 0, 0, 0, 32, 0, 0, 0, 0, 33, 0, + 72, 73, 34, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 36, 0, 37, 75, 0, 0, + 38, 0, 0, 77, 0, 79, 0, 81, 39, 40, + 257, 0, 41, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 90, 91, 92, + 258, 347, 0, 0, 0, 0, 0, 0, 0, 96, + 0, 0, 0, 0, 0, 98, 99, 100, 101, 0, + 0, 0, 102, 0, 103, 362, 0, 0, 0, 0, + 104, 105, 0, 57, 24, 0, 25, 0, 0, 26, + 256, 0, 0, 0, 27, 62, 63, 0, 28, 0, + 0, 0, 0, 0, 65, 106, 260, 30, 109, 0, + 0, 0, 0, 0, 32, 0, 0, 0, 0, 33, + 0, 72, 73, 34, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 36, 0, 37, 75, 0, + 0, 38, 0, 0, 77, 0, 79, 0, 81, 39, + 40, 257, 0, 41, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 90, 91, + 92, 258, 347, 0, 0, 0, 0, 0, 0, 0, + 96, 0, 0, 0, 0, 0, 98, 99, 100, 101, + 0, 0, 0, 102, 0, 103, 364, 0, 0, 0, + 0, 104, 105, 0, 57, 24, 0, 25, 0, 0, + 26, 256, 0, 0, 0, 27, 62, 63, 0, 28, + 0, 0, 0, 0, 0, 65, 106, 260, 30, 109, + 0, 0, 0, 0, 0, 32, 0, 0, 0, 0, + 33, 0, 72, 73, 34, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 36, 0, 37, 75, + 0, 0, 38, 0, 0, 77, 0, 79, 0, 81, + 39, 40, 257, 0, 41, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 90, + 91, 92, 258, 347, 0, 0, 0, 0, 0, 0, + 0, 96, 0, 0, 0, 0, 0, 98, 99, 100, + 101, 0, 0, 0, 102, 0, 103, 366, 0, 0, + 0, 0, 104, 105, 0, 57, 24, 0, 25, 0, + 0, 26, 256, 0, 0, 0, 27, 62, 63, 0, + 28, 0, 0, 0, 0, 0, 65, 106, 260, 30, + 109, 0, 0, 0, 0, 0, 32, 0, 0, 0, + 0, 33, 0, 72, 73, 34, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 36, 0, 37, + 75, 0, 0, 38, 0, 0, 77, 0, 79, 0, + 81, 39, 40, 257, 0, 41, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 90, 91, 92, 258, 347, 0, 0, 0, 0, 0, + 0, 0, 96, 0, 0, 0, 0, 0, 98, 99, + 100, 101, 0, 0, 0, 102, 0, 103, 648, 0, + 0, 0, 0, 104, 105, 0, 57, 24, 0, 25, + 0, 0, 26, 256, 0, 0, 0, 27, 62, 63, + 0, 28, 0, 0, 0, 0, 0, 65, 106, 260, + 30, 109, 0, 0, 0, 0, 0, 32, 0, 0, + 0, 0, 33, 0, 72, 73, 34, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 36, 0, + 37, 75, 0, 0, 38, 0, 0, 77, 0, 79, + 0, 81, 39, 40, 257, 0, 41, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 90, 91, 92, 258, 347, 0, 0, 0, 0, + 0, 0, 0, 96, 0, 0, 0, 0, 0, 98, + 99, 100, 101, 0, 0, 0, 102, 0, 103, 650, + 0, 0, 0, 0, 104, 105, 0, 57, 24, 0, + 25, 0, 0, 26, 256, 0, 0, 0, 27, 62, + 63, 0, 28, 0, 0, 0, 0, 0, 65, 106, + 260, 30, 109, 0, 0, 0, 0, 0, 32, 0, + 0, 0, 0, 33, 0, 72, 73, 34, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 36, - 0, 37, 74, 0, 0, 38, 0, 0, 76, 0, - 78, 0, 80, 39, 40, 254, 0, 41, 0, 0, - 84, 0, 0, 0, 86, 0, 0, 87, 88, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 89, 90, 91, 92, 301, 0, 0, 0, - 0, 0, 0, 0, 95, 0, 0, 0, 0, 0, - 97, 98, 99, 100, 0, 0, 0, 101, 0, 102, - 0, 0, 0, 0, 0, 103, 104, 0, 0, 0, - 0, 0, 0, 56, 24, 0, 25, 0, 0, 26, - 253, 0, 0, 0, 27, 61, 62, 0, 28, 0, - 105, 302, 107, 108, 64, 0, 0, 30, 0, 0, + 0, 37, 75, 0, 0, 38, 0, 0, 77, 0, + 79, 0, 81, 39, 40, 257, 0, 41, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 90, 91, 92, 258, 347, 0, 0, 0, + 0, 0, 0, 0, 96, 0, 0, 0, 0, 0, + 98, 99, 100, 101, 0, 0, 0, 102, 0, 103, + 652, 0, 0, 0, 0, 104, 105, 0, 57, 24, + 0, 25, 0, 0, 26, 256, 0, 0, 0, 27, + 62, 63, 0, 28, 0, 0, 0, 0, 0, 65, + 106, 260, 30, 109, 0, 0, 0, 0, 0, 32, + 0, 0, 0, 0, 33, 0, 72, 73, 34, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 36, 0, 37, 75, 0, 0, 38, 0, 0, 77, + 0, 79, 0, 81, 39, 40, 257, 0, 41, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 90, 91, 92, 258, 347, 0, 0, + 0, 0, 0, 0, 0, 96, 0, 0, 0, 0, + 0, 98, 99, 100, 101, 0, 0, 0, 102, 0, + 103, 658, 0, 0, 0, 0, 104, 105, 0, 57, + 24, 0, 25, 0, 0, 26, 256, 0, 0, 0, + 27, 62, 63, 0, 28, 0, 0, 0, 0, 0, + 65, 106, 260, 30, 109, 0, 0, 0, 0, 0, + 32, 0, 0, 0, 0, 33, 0, 72, 73, 34, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 36, 0, 37, 75, 0, 0, 38, 0, 0, + 77, 0, 79, 0, 81, 39, 40, 257, 0, 41, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 90, 91, 92, 258, 347, 0, + 0, 0, 0, 0, 0, 0, 96, 0, 0, 0, + 0, 0, 98, 99, 100, 101, 0, 0, 0, 102, + 0, 103, 660, 0, 0, 0, 0, 104, 105, 0, + 57, 24, 0, 25, 0, 0, 26, 256, 0, 0, + 0, 27, 62, 63, 0, 28, 0, 0, 0, 0, + 0, 65, 106, 260, 30, 109, 0, 0, 0, 0, + 0, 32, 0, 0, 0, 0, 33, 0, 72, 73, + 34, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 36, 0, 37, 75, 0, 0, 38, 0, + 0, 77, 0, 79, 0, 81, 39, 40, 257, 0, + 41, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 90, 91, 92, 258, 347, + 0, 0, 0, 0, 0, 0, 0, 96, 0, 0, + 0, 0, 0, 98, 99, 100, 101, 0, 0, 0, + 102, 0, 103, 662, 0, 0, 0, 0, 104, 105, + 0, 57, 24, 0, 25, 0, 0, 26, 256, 0, + 0, 0, 27, 62, 63, 0, 28, 0, 0, 0, + 0, 0, 65, 106, 260, 30, 109, 0, 0, 0, + 0, 0, 32, 0, 0, 0, 0, 33, 0, 72, + 73, 34, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 36, 0, 37, 75, 0, 0, 38, + 0, 0, 77, 0, 79, 0, 81, 39, 40, 257, + 0, 41, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 90, 91, 92, 258, + 663, 0, 0, 0, 0, 0, 0, 0, 96, 0, + 0, 0, 0, 0, 98, 99, 100, 101, 0, 0, + 0, 102, 0, 103, 665, 0, 0, 0, 0, 104, + 105, 0, 57, 24, 0, 25, 0, 0, 26, 256, + 0, 0, 0, 27, 62, 63, 0, 28, 0, 0, + 0, 0, 0, 65, 106, 260, 30, 109, 0, 0, + 0, 0, 0, 32, 0, 0, 0, 0, 33, 0, + 72, 73, 34, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 36, 0, 37, 75, 0, 0, + 38, 0, 0, 77, 0, 79, 0, 81, 39, 40, + 257, 0, 41, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 90, 91, 92, + 258, 663, 0, 0, 0, 0, 0, 0, 0, 96, + 0, 0, 0, 0, 0, 98, 99, 100, 101, 0, + 0, 0, 102, 0, 103, 667, 0, 0, 0, 0, + 104, 105, 0, 57, 24, 0, 25, 0, 0, 26, + 256, 0, 0, 0, 27, 62, 63, 0, 28, 0, + 0, 0, 0, 0, 65, 106, 260, 30, 109, 0, 0, 0, 0, 0, 32, 0, 0, 0, 0, 33, - 0, 71, 72, 34, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 36, 0, 37, 74, 0, - 0, 38, 0, 0, 76, 0, 78, 0, 80, 39, - 40, 254, 0, 41, 0, 0, 0, 0, 0, 0, - 86, 0, 0, 87, 88, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 89, 90, - 91, 92, 301, 0, 0, 0, 0, 889, 0, 0, - 95, 0, 0, 0, 0, 0, 97, 98, 99, 100, - 0, 0, 0, 101, 0, 102, 0, 0, 0, 0, - 0, 103, 104, 0, 0, 0, 0, 0, 0, 56, - 24, 0, 25, 0, 0, 26, 253, 0, 0, 0, - 27, 61, 62, 0, 28, 0, 105, 302, 107, 108, - 64, 0, 0, 30, 0, 0, 0, 0, 0, 0, - 32, 0, 0, 0, 0, 33, 0, 71, 72, 34, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 36, 0, 37, 74, 0, 0, 38, 0, 0, - 76, 0, 78, 0, 80, 39, 40, 254, 0, 41, - 0, 0, 0, 0, 0, 0, 86, 0, 0, 87, - 88, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 89, 90, 91, 92, 301, 0, - 0, 0, 517, 0, 0, 0, 95, 0, 0, 0, - 0, 0, 97, 98, 99, 100, 0, 0, 0, 101, - 0, 102, 0, 0, 0, 0, 0, 103, 104, 0, - 0, 0, 0, 0, 0, 56, 24, 0, 25, 0, - 0, 26, 253, 0, 0, 0, 27, 61, 62, 0, - 28, 0, 105, 302, 107, 108, 64, 0, 0, 30, - 0, 0, 0, 0, 0, 0, 32, 0, 0, 0, - 0, 33, 0, 71, 72, 34, 0, 0, 0, 0, + 0, 72, 73, 34, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 36, 0, 37, 75, 0, + 0, 38, 0, 0, 77, 0, 79, 0, 81, 39, + 40, 257, 0, 41, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 90, 91, + 92, 258, 663, 0, 0, 0, 0, 0, 0, 0, + 96, 0, 0, 0, 0, 0, 98, 99, 100, 101, + 0, 0, 0, 102, 0, 103, 669, 0, 0, 0, + 0, 104, 105, 0, 57, 24, 0, 25, 0, 0, + 26, 256, 0, 0, 0, 27, 62, 63, 0, 28, + 0, 0, 0, 0, 0, 65, 106, 260, 30, 109, + 0, 0, 0, 0, 0, 32, 0, 0, 0, 0, + 33, 0, 72, 73, 34, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 36, 0, 37, 75, + 0, 0, 38, 0, 0, 77, 0, 79, 0, 81, + 39, 40, 257, 0, 41, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 90, + 91, 92, 258, 663, 0, 0, 0, 0, 0, 0, + 0, 96, 0, 0, 0, 0, 0, 98, 99, 100, + 101, 0, 0, 0, 102, 0, 103, 671, 0, 0, + 0, 0, 104, 105, 0, 57, 24, 0, 25, 0, + 0, 26, 256, 0, 0, 0, 27, 62, 63, 0, + 28, 0, 0, 0, 0, 0, 65, 106, 260, 30, + 109, 0, 0, 0, 0, 0, 32, 0, 0, 0, + 0, 33, 0, 72, 73, 34, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 36, 0, 37, - 74, 0, 0, 38, 0, 0, 76, 0, 78, 0, - 80, 39, 40, 254, 0, 41, 0, 0, 0, 0, - 0, 0, 86, 0, 0, 87, 88, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 89, 90, 91, 92, 301, 0, 0, 0, 511, 0, - 0, 0, 95, 0, 0, 0, 0, 0, 97, 98, - 99, 100, 0, 0, 0, 101, 0, 102, 0, 0, - 0, 0, 0, 103, 104, 0, 0, 0, 0, 0, - 0, 56, 24, 0, 25, 0, 0, 26, 253, 0, - 0, 0, 27, 61, 62, 0, 28, 0, 105, 302, - 107, 108, 64, 0, 0, 30, 0, 0, 0, 0, - 0, 0, 32, 0, 0, 0, 0, 33, 0, 71, - 72, 34, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 36, 0, 37, 74, 0, 0, 38, - 0, 0, 76, 0, 78, 0, 80, 39, 40, 254, - 0, 41, 0, 0, 0, 0, 0, 0, 86, 0, - 0, 87, 88, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 89, 90, 91, 92, - 301, 0, 0, 0, 0, 0, 0, 0, 95, 0, - 0, 0, 0, 0, 97, 98, 99, 100, 0, 0, - 0, 101, 0, 102, 0, 0, 0, 0, 0, 103, - 104, 0, 0, 0, 0, 0, 0, 56, 24, 0, - 25, 0, 0, 26, 253, 0, 0, 0, 27, 61, - 62, 0, 28, 0, 105, 302, 107, 108, 64, 0, - 0, 30, 0, 0, 0, 0, 0, 0, 32, 0, - 0, 0, 0, 33, 0, 71, 72, 34, 0, 0, + 75, 0, 0, 38, 0, 0, 77, 0, 79, 0, + 81, 39, 40, 257, 0, 41, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 90, 91, 92, 258, 663, 0, 0, 0, 0, 0, + 0, 0, 96, 0, 0, 0, 0, 0, 98, 99, + 100, 101, 0, 0, 0, 102, 0, 103, 673, 0, + 0, 0, 0, 104, 105, 0, 57, 24, 0, 25, + 0, 0, 26, 256, 0, 0, 0, 27, 62, 63, + 0, 28, 0, 0, 0, 0, 0, 65, 106, 260, + 30, 109, 0, 0, 0, 0, 0, 32, 0, 0, + 0, 0, 33, 0, 72, 73, 34, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 36, 0, + 37, 75, 0, 0, 38, 0, 0, 77, 0, 79, + 0, 81, 39, 40, 257, 0, 41, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 90, 91, 92, 258, 663, 0, 0, 0, 0, + 0, 0, 0, 96, 0, 0, 0, 0, 0, 98, + 99, 100, 101, 0, 0, 0, 102, 0, 103, 675, + 0, 0, 0, 0, 104, 105, 0, 57, 24, 0, + 25, 0, 0, 26, 256, 0, 0, 0, 27, 62, + 63, 0, 28, 0, 0, 0, 0, 0, 65, 106, + 260, 30, 109, 0, 0, 0, 0, 0, 32, 0, + 0, 0, 0, 33, 0, 72, 73, 34, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 36, - 0, 37, 74, 0, 0, 38, 0, 0, 76, 0, - 78, 0, 80, 39, 40, 254, 0, 41, 0, 0, - 0, 0, 0, 0, 86, 0, 0, 87, 88, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 89, 90, 91, 92, 93, 0, 0, 0, - 0, 0, 0, 0, 95, 0, 0, 0, 0, 0, - 97, 98, 99, 100, 0, 0, 0, 101, 0, 102, - 0, 0, 0, 0, 0, 103, 104, 0, 0, 0, - 0, 0, 0, 56, 24, 0, 25, 0, 0, 26, - 253, 0, 0, 0, 27, 61, 62, 0, 28, 0, - 105, 106, 107, 108, 64, 0, 0, 30, 0, 0, + 0, 37, 75, 0, 0, 38, 0, 0, 77, 0, + 79, 0, 81, 39, 40, 257, 0, 41, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 90, 91, 92, 258, 663, 0, 0, 0, + 0, 0, 0, 0, 96, 0, 0, 0, 0, 0, + 98, 99, 100, 101, 0, 0, 0, 102, 0, 103, + 677, 0, 0, 0, 0, 104, 105, 0, 57, 24, + 0, 25, 0, 0, 26, 256, 0, 0, 0, 27, + 62, 63, 0, 28, 0, 0, 0, 0, 0, 65, + 106, 260, 30, 109, 0, 0, 0, 0, 0, 32, + 0, 0, 0, 0, 33, 0, 72, 73, 34, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 36, 0, 37, 75, 0, 0, 38, 0, 0, 77, + 0, 79, 0, 81, 39, 40, 257, 0, 41, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 90, 91, 92, 258, 663, 0, 0, + 0, 0, 0, 0, 0, 96, 0, 0, 0, 0, + 0, 98, 99, 100, 101, 0, 0, 0, 102, 0, + 103, 679, 0, 0, 0, 0, 104, 105, 0, 57, + 24, 0, 25, 0, 0, 26, 256, 0, 0, 0, + 27, 62, 63, 0, 28, 0, 0, 0, 0, 0, + 65, 106, 260, 30, 109, 0, 0, 0, 0, 0, + 32, 0, 0, 0, 0, 33, 0, 72, 73, 34, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 36, 0, 37, 75, 0, 0, 38, 0, 0, + 77, 0, 79, 0, 81, 39, 40, 257, 0, 41, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 90, 91, 92, 258, 663, 0, + 0, 0, 0, 0, 0, 0, 96, 0, 0, 0, + 0, 0, 98, 99, 100, 101, 0, 0, 0, 102, + 0, 103, 681, 0, 0, 0, 0, 104, 105, 0, + 57, 24, 0, 25, 0, 0, 26, 256, 0, 0, + 0, 27, 62, 63, 0, 28, 0, 0, 0, 0, + 0, 65, 106, 260, 30, 109, 0, 0, 0, 0, + 0, 32, 0, 0, 0, 0, 33, 0, 72, 73, + 34, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 36, 0, 37, 75, 0, 0, 38, 0, + 0, 77, 0, 79, 0, 81, 39, 40, 257, 0, + 41, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 90, 91, 92, 258, 663, + 0, 0, 0, 0, 0, 0, 0, 96, 0, 0, + 0, 0, 0, 98, 99, 100, 101, 0, 0, 0, + 102, 0, 103, 683, 0, 0, 0, 0, 104, 105, + 0, 57, 24, 0, 25, 0, 0, 26, 256, 0, + 0, 0, 27, 62, 63, 0, 28, 0, 0, 0, + 0, 0, 65, 106, 260, 30, 109, 0, 0, 0, + 0, 0, 32, 0, 0, 0, 0, 33, 0, 72, + 73, 34, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 36, 0, 37, 75, 0, 0, 38, + 0, 0, 77, 0, 79, 0, 81, 39, 40, 257, + 0, 41, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 90, 91, 92, 258, + 663, 0, 0, 0, 0, 0, 0, 0, 96, 0, + 0, 0, 0, 0, 98, 99, 100, 101, 0, 0, + 0, 102, 0, 103, 685, 0, 0, 0, 0, 104, + 105, 0, 57, 24, 0, 25, 0, 0, 26, 256, + 0, 0, 0, 27, 62, 63, 0, 28, 0, 0, + 0, 0, 0, 65, 106, 260, 30, 109, 0, 0, + 0, 0, 0, 32, 0, 0, 0, 0, 33, 0, + 72, 73, 34, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 36, 0, 37, 75, 0, 0, + 38, 0, 0, 77, 0, 79, 0, 81, 39, 40, + 257, 0, 41, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 90, 91, 92, + 258, 663, 0, 0, 0, 0, 0, 0, 0, 96, + 0, 0, 0, 0, 0, 98, 99, 100, 101, 0, + 0, 0, 102, 0, 103, 687, 0, 0, 0, 0, + 104, 105, 0, 57, 24, 0, 25, 0, 0, 26, + 256, 0, 0, 0, 27, 62, 63, 0, 28, 0, + 0, 0, 0, 0, 65, 106, 260, 30, 109, 0, 0, 0, 0, 0, 32, 0, 0, 0, 0, 33, - 0, 71, 72, 34, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 36, 0, 37, 74, 0, - 0, 38, 0, 0, 76, 0, 78, 0, 80, 39, - 40, 254, 0, 41, 0, 0, 0, 0, 0, 0, - 86, 0, 0, 87, 88, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 89, 90, - 91, 92, 93, 0, 0, 0, 0, 0, 0, 0, - 95, 0, 0, 0, 0, 0, 97, 98, 99, 100, - 0, 0, 0, 101, 0, 102, 0, 0, 0, 0, - 0, 103, 104, 0, 0, 0, 0, 0, 0, 77, - 77, 0, 77, 0, 0, 77, 77, 0, 0, 0, - 77, 77, 77, 0, 77, 0, 105, 1044, 107, 108, - 77, 0, 0, 77, 0, 0, 0, 0, 0, 0, - 77, 0, 0, 0, 0, 77, 0, 77, 77, 77, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 77, 0, 77, 77, 0, 0, 77, 0, 0, - 77, 0, 77, 0, 77, 77, 77, 77, 0, 77, - 0, 0, 0, 0, 0, 0, 77, 0, 0, 77, - 77, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 77, 77, 77, 77, 77, 0, - 0, 0, 0, 0, 0, 0, 77, 0, 0, 0, - 0, 0, 77, 77, 77, 77, 0, 0, 0, 77, - 0, 77, 0, 0, 0, 0, 0, 77, 77, 0, - 0, 0, 0, 0, 0, 135, 135, 0, 135, 0, - 0, 135, 135, 0, 0, 0, 135, 135, 135, 0, - 135, 0, 77, 77, 77, 77, 135, 0, 0, 135, - 0, 0, 0, 0, 0, 0, 135, 0, 0, 0, - 0, 135, 0, 135, 135, 135, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 135, 0, 135, - 135, 0, 0, 135, 0, 0, 135, 0, 135, 0, - 135, 135, 135, 135, 0, 135, 0, 0, 0, 0, - 0, 0, 135, 0, 0, 135, 135, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 135, 135, 135, 135, 135, 0, 0, 0, 0, 0, - 0, 0, 135, 0, 0, 0, 0, 0, 135, 135, - 135, 135, 0, 0, 0, 135, 0, 135, 0, 0, - 0, 0, 0, 135, 135, 0, 0, 0, 0, 0, - 0, 56, 24, 0, 25, 0, 0, 26, 253, 0, - 0, 0, 27, 61, 62, 0, 28, 0, 135, 135, - 135, 135, 64, 0, 0, 30, 0, 0, 0, 0, - 0, 0, 32, 0, 27, 0, 27, 33, 0, 71, - 72, 34, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 36, 0, 37, 74, 27, 0, 38, - 0, 0, 76, 0, 78, 0, 80, 39, 40, 254, - 27, 41, 0, 0, 0, 27, 0, 0, 0, 0, - 27, 0, 27, 27, 27, 27, 0, 0, 0, 0, - 27, 0, 0, 0, 27, 0, 89, 90, 91, 255, - 301, 0, 0, 0, 0, 0, 27, 0, 95, 27, - 0, 27, 0, 0, 97, 98, 99, 100, 0, 0, - 0, 101, 0, 102, 0, 0, 0, 0, 0, 103, - 104, 0, 0, 0, 0, 27, 0, 0, 0, 0, - 0, 27, 27, 0, 0, 0, 0, 0, 0, 643, - 0, 643, 0, 643, 105, 256, 643, 108, 643, 643, - 0, 643, 0, 643, 0, 643, 0, 643, 643, 643, - 0, 0, 0, 643, 643, 0, 0, 0, 0, 643, - 0, 643, 643, 0, 0, 0, 643, 0, 0, 0, - 643, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 643, 643, 0, 643, 0, 0, 0, 643, 643, - 0, 0, 0, 0, 0, 0, 643, 643, 56, 24, - 643, 25, 0, 643, 26, 253, 0, 0, 643, 27, - 61, 62, 0, 28, 0, 0, 0, 0, 0, 64, + 0, 72, 73, 34, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 36, 0, 37, 75, 0, + 0, 38, 0, 0, 77, 0, 79, 0, 81, 39, + 40, 257, 0, 41, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 90, 91, + 92, 258, 663, 0, 0, 0, 0, 0, 0, 0, + 96, 0, 0, 0, 0, 0, 98, 99, 100, 101, + 0, 0, 0, 102, 0, 103, 858, 0, 0, 0, + 0, 104, 105, 0, 57, 24, 0, 25, 0, 0, + 26, 256, 0, 0, 0, 27, 62, 63, 0, 28, + 0, 0, 0, 0, 0, 65, 106, 260, 30, 109, + 0, 0, 0, 0, 0, 32, 0, 0, 0, 0, + 33, 0, 72, 73, 34, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 36, 0, 37, 75, + 0, 0, 38, 0, 0, 77, 0, 79, 0, 81, + 39, 40, 257, 0, 41, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 90, + 91, 92, 258, 347, 0, 0, 0, 0, 0, 0, + 0, 96, 0, 0, 0, 0, 0, 98, 99, 100, + 101, 0, 0, 0, 102, 0, 103, 519, 0, 0, + 0, 0, 104, 105, 347, 57, 24, 0, 25, 0, + 0, 26, 256, 0, 0, 0, 27, 62, 63, 0, + 28, 0, 0, 0, 0, 0, 65, 106, 260, 30, + 109, 0, 0, 0, 0, 0, 32, 0, 0, 0, + 347, 33, 0, 72, 73, 34, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 36, 0, 37, + 75, 0, 0, 38, 0, 0, 77, 0, 79, 0, + 81, 39, 40, 257, 0, 41, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 90, 91, 92, 258, 520, 0, 0, 0, 0, 0, + 0, 0, 96, 347, 347, 347, 347, 811, 0, 0, + 347, 347, 0, 0, 347, 347, 347, 347, 347, 347, + 347, 347, 347, 0, 347, 347, 347, 347, 347, 347, + 347, 347, 347, 347, 347, 347, 347, 347, 347, 347, + 347, 347, 347, 347, 347, 347, 0, 0, 106, 521, + 0, 0, 347, 0, 52, 347, 52, 0, 52, 0, + 52, 0, 0, 52, 0, 52, 52, 0, 52, 0, + 52, 0, 52, 0, 52, 52, 52, 52, 0, 0, + 52, 52, 0, 0, 0, 0, 52, 52, 52, 52, + 52, 0, 0, 52, 0, 52, 0, 52, 0, 52, + 52, 0, 52, 52, 52, 52, 0, 0, 52, 52, + 52, 52, 0, 0, 52, 52, 52, 0, 0, 0, + 0, 0, 0, 52, 52, 0, 52, 52, 0, 52, + 52, 52, 0, 0, 0, 52, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 52, 0, 52, 52, 51, + 0, 0, 0, 51, 0, 51, 0, 0, 51, 0, + 51, 51, 0, 51, 0, 51, 0, 51, 0, 51, + 51, 51, 51, 0, 0, 51, 51, 0, 0, 0, + 0, 51, 0, 51, 51, 51, 0, 0, 51, 0, + 51, 0, 51, 0, 0, 51, 0, 51, 51, 51, + 51, 52, 0, 0, 51, 51, 51, 0, 0, 51, + 51, 51, 0, 0, 0, 0, 0, 0, 51, 51, + 0, 51, 51, 0, 51, 51, 51, 0, 0, 0, + 51, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 51, 0, + 51, 0, 51, 0, 51, 0, 86, 51, 0, 51, + 51, 0, 51, 0, 51, 51, 51, 0, 51, 51, + 51, 51, 0, 0, 51, 51, 0, 0, 0, 0, + 51, 0, 51, 51, 51, 0, 0, 51, 0, 51, + 0, 51, 0, 0, 51, 0, 51, 51, 51, 51, + 0, 0, 0, 51, 51, 51, 51, 0, 51, 51, + 51, 0, 0, 0, 0, 0, 0, 51, 51, 0, + 51, 51, 0, 51, 51, 51, 0, 0, 0, 51, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 52, 0, 51, + 0, 52, 0, 52, 0, 87, 52, 0, 52, 52, + 0, 52, 0, 52, 51, 52, 0, 52, 52, 52, + 52, 0, 0, 52, 52, 0, 0, 0, 0, 52, + 0, 52, 52, 52, 0, 0, 52, 0, 52, 0, + 52, 0, 0, 52, 0, 52, 52, 52, 52, 0, + 0, 0, 52, 52, 52, 51, 0, 52, 52, 52, + 0, 0, 0, 0, 0, 0, 52, 52, 0, 52, + 52, 0, 52, 52, 52, 0, 0, 0, 52, 0, + 0, 0, 0, 51, 0, 0, 0, 51, 0, 51, + 0, 0, 51, 0, 51, 51, 0, 51, 52, 51, + 0, 51, 0, 51, 51, 51, 51, 0, 0, 51, + 51, 0, 0, 52, 0, 51, 0, 51, 51, 51, + 0, 0, 51, 0, 51, 0, 51, 0, 0, 51, + 0, 51, 51, 51, 51, 0, 0, 0, 51, 51, + 51, 0, 0, 51, 51, 51, 0, 0, 0, 0, + 0, 0, 51, 51, 52, 51, 51, 0, 51, 51, + 51, 0, 0, 0, 51, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 51, 0, 0, + 0, 51, 0, 51, 51, 0, 51, 0, 51, 51, + 222, 51, 0, 51, 0, 51, 0, 51, 51, 51, + 51, 0, 0, 51, 51, 0, 0, 0, 0, 51, + 0, 51, 51, 51, 0, 0, 51, 0, 51, 347, + 51, 0, 0, 51, 0, 51, 51, 51, 51, 0, + 0, 0, 51, 51, 51, 0, 0, 51, 51, 51, + 51, 0, 347, 0, 0, 0, 51, 51, 0, 51, + 51, 0, 51, 51, 51, 347, 0, 0, 51, 0, + 347, 0, 0, 347, 0, 347, 0, 347, 347, 347, + 347, 0, 0, 0, 0, 347, 0, 0, 51, 347, + 0, 0, 0, 347, 223, 0, 0, 0, 0, 369, + 0, 347, 0, 0, 347, 0, 347, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 369, 0, 0, 347, 0, 0, 0, 0, + 347, 0, 0, 0, 0, 369, 347, 347, 0, 273, + 369, 347, 0, 240, 51, 369, 0, 369, 369, 369, + 369, 0, 0, 0, 347, 369, 0, 0, 0, 369, + 0, 368, 0, 369, 0, 0, 0, 0, 0, 0, + 0, 369, 0, 0, 369, 0, 369, 0, 0, 0, + 0, 0, 0, 0, 368, 0, 347, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 368, 0, 471, + 369, 0, 368, 0, 0, 239, 369, 368, 0, 368, + 368, 368, 368, 0, 0, 0, 0, 368, 0, 0, + 0, 368, 472, 0, 0, 368, 0, 0, 0, 0, + 0, 0, 0, 368, 0, 473, 368, 471, 368, 0, + 475, 0, 0, 0, 0, 476, 0, 477, 478, 479, + 480, 0, 0, 0, 0, 481, 369, 0, 0, 482, + 472, 0, 368, 1412, 0, 0, 0, 0, 368, 0, + 0, 483, 0, 473, 484, 471, 485, 0, 475, 0, + 0, 0, 0, 476, 0, 477, 478, 479, 480, 0, + 0, 0, 0, 481, 0, 0, 0, 482, 472, 0, + 486, 1412, 0, 0, 0, 0, 1413, 0, 0, 483, + 0, 473, 484, 0, 485, 0, 475, 0, 368, 0, + 0, 476, 0, 477, 478, 479, 480, 0, 0, 0, + 0, 481, 0, 0, 0, 482, 0, 0, 486, 0, + 0, 0, 0, 0, 0, 0, 0, 483, 57, 24, + 484, 25, 485, 0, 26, 256, 1414, 0, 0, 27, + 62, 63, 0, 28, 0, 0, 0, 0, 0, 65, + 0, 0, 30, 0, 0, 0, 486, 0, 0, 32, + 0, 0, 0, 0, 33, 0, 72, 73, 34, 0, + 626, 0, 0, 0, 1414, 0, 0, 627, 0, 0, + 36, 0, 37, 75, 0, 0, 38, 0, 0, 77, + 0, 79, 0, 81, 39, 40, 257, 0, 41, 0, + 0, 0, 0, 0, 0, 628, 0, 0, 88, 89, + 0, 0, 1430, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 90, 91, 92, 93, 94, 0, 0, + 0, 0, 0, 0, 0, 96, 993, 0, 629, 0, + 0, 98, 99, 100, 101, 0, 0, 0, 102, 0, + 103, 0, 0, 0, 0, 0, 104, 105, 0, 0, + 0, 0, 0, 0, 57, 24, 0, 25, 0, 0, + 26, 256, 0, 0, 0, 27, 62, 63, 0, 28, + 0, 106, 107, 108, 109, 65, 0, 0, 30, 0, + 0, 0, 0, 0, 0, 32, 0, 0, 0, 0, + 33, 0, 72, 73, 34, 0, 626, 0, 0, 0, + 0, 0, 0, 627, 0, 0, 36, 0, 37, 75, + 0, 0, 38, 0, 0, 77, 0, 79, 0, 81, + 39, 40, 257, 0, 41, 0, 0, 0, 0, 0, + 0, 628, 0, 0, 88, 89, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 90, + 91, 92, 93, 94, 0, 0, 0, 0, 0, 0, + 0, 96, 0, 0, 629, 0, 0, 98, 99, 100, + 101, 0, 0, 0, 102, 0, 103, 0, 0, 0, + 0, 0, 104, 105, 0, 0, 0, 0, 0, 0, + 57, 24, 0, 25, 0, 0, 26, 256, 0, 0, + 0, 27, 62, 63, 0, 28, 0, 106, 107, 108, + 109, 65, 0, 0, 30, 0, 0, 0, 0, 0, + 0, 32, 0, 0, 0, 0, 33, 0, 72, 73, + 34, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 36, 0, 37, 75, 0, 0, 38, 0, + 0, 77, 0, 79, 0, 81, 39, 40, 257, 0, + 41, 0, 0, 85, 0, 0, 0, 87, 0, 0, + 88, 89, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 90, 91, 92, 93, 305, + 0, 0, 0, 0, 0, 0, 0, 96, 0, 0, + 0, 0, 0, 98, 99, 100, 101, 0, 0, 0, + 102, 0, 103, 0, 0, 0, 0, 0, 104, 105, + 0, 0, 0, 0, 0, 0, 57, 24, 0, 25, + 0, 0, 26, 256, 0, 0, 0, 27, 62, 63, + 0, 28, 0, 106, 306, 108, 109, 65, 0, 0, + 30, 0, 0, 0, 0, 0, 0, 32, 0, 0, + 0, 0, 33, 0, 72, 73, 34, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 36, 0, + 37, 75, 0, 0, 38, 0, 0, 77, 0, 79, + 0, 81, 39, 40, 257, 0, 41, 0, 0, 0, + 0, 0, 0, 87, 0, 0, 88, 89, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 90, 91, 92, 93, 305, 0, 0, 0, 540, + 0, 0, 0, 96, 0, 0, 0, 0, 0, 98, + 99, 100, 101, 0, 0, 0, 102, 0, 103, 0, + 0, 0, 0, 0, 104, 105, 0, 0, 0, 0, + 0, 0, 57, 24, 0, 25, 0, 0, 26, 256, + 0, 0, 0, 27, 62, 63, 0, 28, 0, 106, + 306, 108, 109, 65, 0, 0, 30, 0, 0, 0, + 0, 0, 0, 32, 0, 0, 0, 0, 33, 0, + 72, 73, 34, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 36, 0, 37, 75, 0, 0, + 38, 0, 0, 77, 0, 79, 0, 81, 39, 40, + 257, 0, 41, 0, 0, 0, 0, 0, 0, 87, + 0, 0, 88, 89, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 90, 91, 92, + 93, 305, 0, 0, 0, 534, 0, 0, 0, 96, + 0, 0, 0, 0, 0, 98, 99, 100, 101, 0, + 0, 0, 102, 0, 103, 0, 0, 0, 0, 0, + 104, 105, 0, 0, 0, 0, 0, 0, 57, 24, + 0, 25, 0, 0, 26, 256, 0, 0, 0, 27, + 62, 63, 0, 28, 0, 106, 306, 108, 109, 65, 0, 0, 30, 0, 0, 0, 0, 0, 0, 32, - 643, 643, 0, 0, 33, 0, 71, 72, 34, 0, - 0, 0, 0, 643, 0, 0, 0, 0, 0, 0, - 36, 0, 37, 74, 0, 0, 38, 0, 0, 76, - 0, 78, 0, 80, 39, 40, 254, 0, 41, 0, - 0, 84, 0, 0, 0, 0, 0, 0, 24, 0, - 25, 0, 0, 26, 643, 1235, 0, 0, 27, 0, - 0, 0, 28, 89, 90, 91, 255, 0, 0, 0, - 0, 30, 642, 0, 642, 95, 0, 642, 32, 642, - 642, 0, 642, 33, 642, 1236, 642, 34, 642, 642, - 642, 0, 0, 0, 642, 642, 0, 0, 0, 36, - 642, 37, 642, 642, 0, 38, 1237, 642, 0, 0, - 0, 642, 0, 39, 40, 0, 0, 41, 0, 0, - 322, 105, 256, 642, 0, 642, 0, 0, 0, 642, - 642, 0, 0, 0, 0, 0, 0, 642, 642, 0, - 642, 642, 642, 0, 642, 642, 0, 642, 642, 642, - 642, 0, 642, 0, 642, 0, 642, 642, 642, 0, - 0, 0, 642, 642, 0, 0, 0, 0, 642, 0, - 642, 642, 0, 0, 0, 642, 0, 0, 0, 642, - 0, 0, 0, 0, 642, 0, 0, 0, 0, 0, - 0, 642, 0, 642, 0, 0, 0, 642, 642, 0, - 0, 355, 0, 0, 0, 642, 642, 0, 0, 642, - 0, 0, 642, 0, 24, 0, 25, 642, 0, 26, - 0, 0, 1295, 0, 27, 642, 686, 0, 28, 0, - 687, 1296, 1297, 0, 0, 0, 1298, 30, 0, 0, - 0, 0, 1299, 0, 32, 0, 24, 0, 25, 33, - 0, 26, 0, 34, 1295, 0, 27, 0, 686, 0, - 28, 0, 687, 1296, 1297, 36, 0, 37, 1298, 30, - 0, 38, 0, 0, 1299, 0, 32, 0, 0, 39, - 40, 33, 0, 41, 0, 34, 1300, 0, 0, 0, - 47, 1301, 47, 642, 0, 47, 0, 36, 0, 37, - 47, 0, 0, 38, 47, 0, 0, 0, 0, 0, - 0, 39, 40, 47, 0, 41, 0, 0, 1300, 0, - 47, 0, 47, 1301, 47, 47, 1302, 47, 0, 47, - 0, 47, 47, 47, 0, 0, 47, 0, 47, 0, - 0, 47, 0, 47, 0, 47, 0, 47, 0, 0, - 47, 0, 47, 0, 0, 47, 47, 47, 0, 47, - 0, 47, 47, 47, 0, 47, 48, 1303, 48, 0, - 47, 48, 0, 47, 0, 47, 48, 0, 0, 47, - 48, 0, 47, 0, 0, 0, 0, 47, 47, 48, - 0, 47, 0, 0, 47, 0, 48, 154, 47, 1303, - 47, 48, 0, 47, 0, 48, 0, 48, 47, 48, - 0, 0, 47, 0, 48, 0, 0, 48, 0, 48, - 0, 47, 0, 48, 0, 0, 48, 154, 47, 0, - 0, 48, 48, 47, 0, 48, 0, 47, 48, 47, - 0, 47, 24, 47, 25, 0, 47, 26, 0, 47, - 0, 47, 27, 0, 0, 47, 28, 0, 47, 0, - 0, 0, 0, 47, 47, 30, 0, 47, 0, 0, - 47, 0, 32, 0, 0, 47, 0, 33, 0, 0, - 0, 34, 0, 570, 0, 0, 0, 24, 0, 25, - 571, 0, 26, 36, 0, 37, 0, 27, 0, 38, - 0, 28, 572, 0, 0, 29, 0, 39, 40, 0, - 30, 41, 0, 0, 573, 31, 0, 32, 0, 48, - 0, 0, 33, 0, 0, 33, 34, 35, 0, 0, - 0, 0, 0, 0, 0, 0, 33, 0, 36, 0, - 37, 33, 0, 0, 38, 33, 0, 0, 33, 0, - 0, 47, 39, 40, 0, 0, 41, 0, 0, 0, - 33, 33, 0, 0, 0, 33, 33, 0, 0, 0, - 0, 33, 0, 33, 33, 33, 33, 0, 0, 0, - 0, 33, 0, 0, 0, 33, 0, 33, 0, 0, - 0, 0, 0, 0, 0, 574, 0, 33, 0, 33, - 33, 31, 33, 0, 0, 0, 33, 0, 0, 0, - 0, 0, 31, 0, 0, 0, 0, 31, 0, 0, - 0, 31, 0, 0, 31, 0, 33, 0, 0, 0, - 0, 0, 33, 33, 0, 0, 31, 31, 0, 0, - 42, 31, 31, 0, 47, 0, 0, 31, 0, 31, - 31, 31, 31, 0, 0, 47, 0, 31, 0, 0, - 47, 31, 0, 31, 47, 0, 0, 47, 0, 0, - 0, 0, 0, 31, 0, 0, 31, 0, 31, 47, - 47, 0, 31, 0, 47, 47, 0, 47, 0, 0, - 47, 0, 47, 47, 47, 47, 0, 0, 47, 0, - 47, 0, 31, 47, 47, 0, 47, 47, 31, 31, - 47, 0, 0, 0, 0, 0, 47, 0, 0, 47, - 0, 47, 47, 47, 0, 47, 0, 47, 47, 47, - 0, 0, 0, 47, 0, 47, 47, 47, 47, 0, - 0, 0, 0, 47, 0, 47, 0, 47, 0, 47, - 0, 35, 47, 0, 0, 0, 0, 0, 0, 47, - 0, 0, 47, 0, 47, 47, 0, 47, 47, 0, - 47, 0, 0, 0, 0, 47, 0, 47, 47, 47, - 47, 0, 0, 0, 0, 47, 0, 0, 47, 47, - 47, 0, 0, 0, 36, 0, 0, 0, 0, 0, - 0, 47, 0, 47, 47, 47, 47, 0, 47, 0, - 0, 0, 0, 47, 0, 47, 47, 47, 47, 0, - 0, 0, 0, 47, 0, 0, 0, 47, 47, 0, - 47, 0, 47, 47, 0, 0, 196, 0, 0, 47, - 0, 47, 47, 47, 47, 47, 47, 0, 0, 0, - 0, 47, 0, 47, 47, 47, 47, 0, 0, 47, - 0, 47, 0, 0, 0, 47, 47, 0, 47, 0, - 47, 47, 0, 0, 198, 0, 0, 47, 0, 47, - 47, 47, 47, 0, 47, 0, 0, 0, 0, 47, - 0, 47, 47, 47, 47, 0, 0, 0, 0, 47, - 0, 0, 0, 47, 47, 0, 47, 0, 0, 0, - 0, 47, 299, 47, 0, 47, 0, 47, 47, 0, - 47, 0, 47, 0, 0, 0, 0, 47, 0, 47, - 47, 47, 47, 0, 47, 0, 0, 47, 0, 0, - 0, 47, 0, 0, 47, 0, 0, 47, 0, 0, - 300, 452, 47, 47, 0, 0, 47, 47, 47, 47, - 47, 47, 47, 0, 0, 47, 0, 47, 0, 0, - 0, 47, 0, 0, 453, 0, 0, 0, 0, 0, - 0, 452, 47, 47, 47, 47, 47, 454, 47, 0, - 0, 455, 456, 0, 0, 0, 0, 457, 0, 458, - 459, 460, 461, 0, 453, 0, 0, 462, 0, 0, - 0, 463, 47, 0, 0, 0, 0, 454, 0, 0, - 0, 0, 456, 464, 0, 0, 465, 457, 466, 458, - 459, 460, 461, 0, 0, 0, 0, 462, 0, 0, - 0, 463, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 467, 464, 0, 0, 465, 0, 466, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 467, + 0, 0, 0, 0, 33, 0, 72, 73, 34, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 36, 0, 37, 75, 0, 0, 38, 0, 0, 77, + 0, 79, 0, 81, 39, 40, 257, 0, 41, 0, + 0, 0, 0, 0, 0, 87, 0, 0, 88, 89, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 90, 91, 92, 93, 305, 0, 0, + 0, 0, 0, 0, 0, 96, 0, 0, 0, 0, + 0, 98, 99, 100, 101, 0, 0, 0, 102, 0, + 103, 0, 0, 0, 0, 0, 104, 105, 0, 0, + 0, 0, 0, 0, 57, 24, 0, 25, 0, 0, + 26, 256, 0, 0, 0, 27, 62, 63, 0, 28, + 0, 106, 306, 108, 109, 65, 0, 0, 30, 0, + 0, 0, 0, 0, 0, 32, 0, 0, 0, 0, + 33, 0, 72, 73, 34, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 36, 0, 37, 75, + 0, 0, 38, 0, 0, 77, 0, 79, 0, 81, + 39, 40, 257, 0, 41, 0, 0, 0, 0, 0, + 0, 87, 0, 0, 88, 89, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 90, + 91, 92, 93, 94, 0, 0, 0, 0, 0, 0, + 0, 96, 0, 0, 0, 0, 0, 98, 99, 100, + 101, 0, 0, 0, 102, 0, 103, 0, 0, 0, + 0, 0, 104, 105, 0, 0, 0, 0, 0, 0, + 661, 661, 0, 661, 0, 0, 661, 661, 0, 0, + 0, 661, 661, 661, 0, 661, 0, 106, 107, 108, + 109, 661, 0, 0, 661, 0, 0, 0, 0, 0, + 0, 661, 0, 0, 0, 0, 661, 0, 661, 661, + 661, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 661, 0, 661, 661, 0, 0, 661, 0, + 0, 661, 0, 661, 0, 661, 661, 661, 661, 0, + 661, 0, 0, 0, 0, 0, 0, 661, 0, 0, + 661, 661, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 661, 661, 661, 661, 661, + 0, 0, 0, 0, 0, 0, 0, 661, 0, 0, + 0, 0, 0, 661, 661, 661, 661, 0, 0, 0, + 661, 0, 661, 0, 0, 0, 0, 0, 661, 661, + 0, 0, 0, 0, 0, 0, 143, 143, 0, 143, + 0, 0, 143, 143, 0, 0, 0, 143, 143, 143, + 0, 143, 0, 661, 661, 661, 661, 143, 0, 0, + 143, 0, 0, 0, 0, 0, 0, 143, 0, 0, + 0, 0, 143, 0, 143, 143, 143, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 143, 0, + 143, 143, 0, 0, 143, 0, 0, 143, 0, 143, + 0, 143, 143, 143, 143, 0, 143, 0, 0, 0, + 0, 0, 0, 143, 0, 0, 143, 143, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 143, 143, 143, 143, 143, 0, 0, 0, 0, + 0, 0, 0, 143, 0, 0, 0, 0, 0, 143, + 143, 143, 143, 0, 0, 0, 143, 0, 143, 0, + 0, 0, 0, 0, 143, 143, 0, 0, 0, 0, + 0, 0, 57, 24, 0, 25, 0, 0, 26, 256, + 0, 0, 0, 27, 62, 63, 0, 28, 0, 143, + 143, 143, 143, 65, 0, 0, 30, 0, 0, 0, + 0, 0, 0, 32, 0, 31, 0, 0, 33, 0, + 72, 73, 34, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 36, 0, 37, 75, 31, 0, + 38, 0, 0, 77, 0, 79, 0, 81, 39, 40, + 257, 31, 41, 0, 0, 0, 31, 0, 0, 0, + 0, 31, 0, 31, 31, 31, 31, 0, 0, 31, + 0, 31, 0, 0, 0, 31, 0, 90, 91, 92, + 258, 663, 0, 0, 0, 0, 0, 31, 0, 96, + 31, 0, 31, 0, 0, 98, 99, 100, 101, 0, + 0, 0, 102, 0, 103, 0, 0, 0, 0, 0, + 104, 105, 0, 0, 0, 0, 31, 0, 0, 0, + 0, 0, 31, 31, 0, 0, 0, 0, 0, 0, + 706, 0, 706, 0, 706, 106, 260, 706, 109, 706, + 706, 0, 706, 0, 706, 0, 706, 0, 706, 706, + 706, 0, 0, 0, 706, 706, 0, 0, 0, 0, + 706, 0, 706, 706, 0, 0, 0, 706, 0, 0, + 0, 706, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 706, 706, 0, 706, 0, 0, 0, 706, + 706, 0, 0, 0, 0, 0, 0, 706, 706, 57, + 24, 706, 25, 0, 706, 26, 256, 0, 0, 706, + 27, 62, 63, 0, 28, 0, 0, 0, 0, 0, + 65, 0, 0, 30, 0, 0, 0, 0, 0, 0, + 32, 706, 706, 0, 0, 33, 0, 72, 73, 34, + 0, 0, 0, 0, 706, 0, 0, 0, 0, 0, + 0, 36, 0, 37, 75, 0, 0, 38, 0, 0, + 77, 0, 79, 0, 81, 39, 40, 257, 0, 41, + 0, 0, 85, 0, 0, 0, 0, 0, 0, 24, + 0, 25, 0, 0, 26, 706, 1318, 0, 0, 27, + 0, 0, 0, 28, 90, 91, 92, 258, 259, 0, + 0, 0, 30, 705, 0, 705, 96, 0, 705, 32, + 705, 705, 0, 705, 33, 705, 1319, 705, 34, 705, + 705, 705, 0, 0, 0, 705, 705, 0, 0, 0, + 36, 705, 37, 705, 705, 0, 38, 1320, 705, 0, + 0, 0, 705, 0, 39, 40, 0, 0, 41, 0, + 0, 327, 106, 260, 705, 0, 705, 0, 0, 0, + 705, 705, 0, 0, 0, 0, 0, 0, 705, 705, + 0, 705, 705, 705, 0, 705, 705, 0, 705, 705, + 705, 705, 0, 705, 0, 705, 0, 705, 705, 705, + 0, 0, 0, 705, 705, 0, 0, 0, 0, 705, + 0, 705, 705, 0, 0, 0, 705, 0, 0, 0, + 705, 0, 0, 0, 0, 705, 0, 0, 0, 0, + 0, 0, 705, 0, 705, 0, 0, 0, 705, 705, + 0, 0, 374, 0, 0, 0, 705, 705, 0, 0, + 705, 0, 0, 705, 0, 24, 0, 25, 705, 0, + 26, 0, 0, 1381, 0, 27, 705, 739, 0, 28, + 0, 740, 1382, 1383, 0, 0, 0, 1384, 30, 0, + 0, 0, 0, 1385, 0, 32, 0, 24, 0, 25, + 33, 0, 26, 0, 34, 1381, 0, 27, 0, 739, + 0, 28, 0, 740, 1382, 1383, 36, 0, 37, 1384, + 30, 0, 38, 0, 0, 1385, 0, 32, 0, 0, + 39, 40, 33, 0, 41, 0, 34, 1386, 0, 0, + 0, 51, 1387, 51, 705, 0, 51, 0, 36, 0, + 37, 51, 0, 0, 38, 51, 0, 0, 0, 0, + 0, 0, 39, 40, 51, 0, 41, 0, 0, 1386, + 0, 51, 0, 51, 1387, 51, 51, 1388, 51, 0, + 51, 0, 51, 51, 51, 0, 0, 51, 0, 51, + 0, 0, 51, 0, 51, 0, 51, 0, 51, 0, + 0, 51, 0, 51, 0, 0, 51, 51, 51, 0, + 51, 0, 51, 51, 51, 0, 51, 24, 1389, 25, + 0, 51, 26, 0, 51, 0, 51, 27, 0, 0, + 51, 28, 0, 51, 0, 0, 0, 0, 51, 51, + 30, 0, 51, 0, 0, 51, 0, 32, 162, 0, + 1389, 0, 33, 0, 0, 0, 34, 0, 598, 0, + 0, 0, 0, 0, 0, 599, 0, 0, 36, 0, + 37, 0, 0, 0, 38, 0, 0, 600, 162, 0, + 0, 0, 39, 40, 0, 0, 41, 0, 52, 601, + 52, 0, 0, 52, 51, 0, 0, 0, 52, 0, + 0, 0, 52, 0, 0, 0, 0, 0, 0, 0, + 0, 52, 0, 0, 0, 602, 0, 0, 52, 0, + 51, 0, 51, 52, 0, 51, 51, 52, 0, 52, + 51, 52, 0, 0, 51, 0, 52, 0, 0, 52, + 0, 52, 0, 51, 0, 52, 0, 0, 52, 0, + 51, 0, 0, 52, 52, 51, 0, 52, 0, 51, + 52, 51, 0, 51, 0, 0, 0, 0, 51, 0, + 603, 51, 0, 51, 0, 0, 0, 51, 0, 0, + 51, 0, 0, 0, 0, 51, 51, 0, 0, 51, + 0, 24, 51, 25, 0, 0, 26, 0, 0, 0, + 0, 27, 0, 0, 0, 28, 0, 0, 0, 29, + 0, 0, 0, 0, 30, 183, 0, 183, 0, 31, + 183, 32, 0, 0, 0, 183, 33, 0, 0, 183, + 34, 35, 0, 0, 0, 0, 0, 0, 183, 0, + 0, 52, 36, 0, 37, 183, 0, 0, 38, 0, + 183, 0, 0, 0, 183, 0, 39, 40, 0, 0, + 41, 0, 0, 42, 0, 182, 183, 182, 183, 0, + 182, 0, 183, 51, 0, 182, 0, 0, 0, 182, + 183, 183, 0, 0, 183, 0, 0, 183, 182, 192, + 0, 192, 0, 0, 192, 182, 0, 0, 0, 192, + 182, 0, 0, 192, 182, 0, 0, 0, 0, 0, + 0, 0, 192, 0, 0, 0, 182, 0, 182, 192, + 0, 0, 182, 0, 192, 0, 0, 0, 192, 0, + 182, 182, 0, 0, 182, 0, 37, 182, 0, 0, + 192, 0, 192, 0, 43, 0, 192, 37, 0, 0, + 0, 0, 37, 0, 192, 192, 37, 0, 192, 37, + 0, 192, 0, 0, 0, 0, 0, 0, 183, 0, + 0, 37, 37, 0, 0, 0, 37, 37, 0, 35, + 0, 0, 37, 0, 37, 37, 37, 37, 0, 0, + 35, 0, 37, 0, 0, 35, 37, 0, 37, 35, + 0, 0, 35, 0, 0, 0, 0, 0, 37, 0, + 37, 37, 0, 37, 35, 35, 0, 37, 182, 35, + 35, 0, 31, 0, 31, 35, 0, 35, 35, 35, + 35, 0, 0, 0, 0, 35, 0, 37, 0, 35, + 0, 35, 192, 37, 37, 31, 0, 0, 0, 0, + 0, 35, 0, 0, 35, 0, 35, 0, 31, 0, + 35, 0, 0, 31, 0, 51, 0, 0, 31, 0, + 31, 31, 31, 31, 0, 0, 51, 0, 31, 0, + 35, 51, 31, 0, 0, 51, 35, 35, 51, 0, + 0, 0, 0, 0, 31, 0, 0, 31, 0, 31, + 51, 51, 0, 0, 0, 51, 51, 0, 51, 0, + 0, 51, 0, 51, 51, 51, 51, 0, 0, 51, + 0, 51, 0, 31, 51, 51, 0, 51, 51, 31, + 31, 51, 0, 0, 0, 0, 0, 51, 0, 0, + 51, 0, 51, 51, 51, 0, 51, 0, 51, 51, + 51, 0, 0, 0, 51, 0, 51, 51, 51, 51, + 0, 0, 0, 0, 51, 0, 51, 0, 51, 0, + 51, 0, 39, 51, 0, 0, 0, 0, 0, 0, + 51, 0, 0, 51, 0, 51, 51, 0, 51, 51, + 0, 51, 0, 0, 0, 0, 51, 0, 51, 51, + 51, 51, 0, 0, 0, 0, 51, 0, 0, 51, + 51, 51, 0, 0, 0, 40, 0, 0, 0, 0, + 0, 0, 51, 0, 51, 51, 51, 51, 0, 51, + 0, 0, 0, 0, 51, 0, 51, 51, 51, 51, + 0, 0, 0, 0, 51, 0, 0, 0, 51, 51, + 0, 51, 0, 51, 51, 0, 0, 204, 0, 0, + 51, 0, 51, 51, 51, 51, 51, 51, 0, 0, + 0, 0, 51, 0, 51, 51, 51, 51, 0, 0, + 51, 0, 51, 0, 0, 0, 51, 51, 0, 51, + 0, 51, 51, 0, 0, 206, 0, 0, 51, 0, + 51, 51, 51, 51, 51, 51, 0, 0, 0, 0, + 51, 0, 51, 51, 51, 51, 0, 0, 0, 0, + 51, 0, 0, 0, 51, 51, 0, 51, 0, 0, + 0, 0, 471, 308, 0, 0, 51, 0, 51, 51, + 0, 51, 0, 51, 0, 0, 0, 0, 51, 0, + 51, 51, 51, 51, 0, 472, 51, 0, 51, 0, + 0, 0, 51, 0, 471, 51, 0, 0, 473, 0, + 0, 309, 474, 475, 51, 0, 0, 51, 476, 51, + 477, 478, 479, 480, 0, 0, 0, 472, 481, 0, + 0, 0, 482, 0, 0, 0, 0, 0, 0, 0, + 473, 0, 0, 51, 483, 475, 0, 484, 0, 485, + 476, 0, 477, 478, 479, 480, 0, 0, 0, 0, + 481, 0, 0, 0, 482, 0, 0, 0, 0, 0, + 0, 0, 0, 486, 0, 0, 483, 0, 0, 484, + 0, 485, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 486, }; protected static readonly short [] yyCheck = { 17, - 515, 18, 51, 17, 298, 4, 6, 51, 189, 234, - 469, 17, 299, 17, 288, 517, 232, 191, 354, 188, - 247, 68, 321, 20, 559, 339, 17, 84, 59, 491, - 157, 297, 354, 645, 646, 332, 370, 937, 295, 1113, - 87, 88, 87, 88, 58, 92, 721, 576, 723, 77, - 585, 59, 1148, 1149, 748, 73, 113, 0, 115, 77, - 277, 256, 328, 108, 256, 79, 781, 81, 59, 256, - 1242, 256, 63, 113, 256, 115, 256, 95, 942, 256, - 335, 256, 368, 256, 17, 268, 17, 1259, 256, 256, - 17, 256, 256, 768, 256, 268, 771, 282, 368, 256, - 368, 256, 1145, 1199, 256, 374, 256, 341, 376, 269, - 47, 391, 401, 414, 268, 17, 256, 891, 370, 1447, - 1448, 21, 374, 418, 413, 172, 286, 428, 902, 314, - 268, 1108, 418, 428, 414, 369, 665, 256, 276, 157, - 189, 17, 369, 157, 410, 189, 363, 416, 418, 323, - 256, 157, 52, 157, 199, 200, 343, 339, 17, 256, - 1203, 429, 344, 340, 346, 17, 157, 349, 350, 256, - 352, 353, 17, 17, 429, 256, 1504, 1198, 790, 17, - 372, 355, 374, 232, 339, 368, 360, 17, 232, 344, - 358, 346, 374, 256, 349, 350, 532, 352, 353, 1220, - 247, 418, 419, 256, 391, 1069, 363, 819, 256, 434, - 256, 258, 376, 375, 511, 256, 261, 433, 554, 374, - 514, 256, 724, 418, 157, 363, 157, 414, 228, 247, - 157, 381, 554, 418, 252, 375, 0, 429, 418, 422, - 576, 428, 287, 418, 0, 559, 1418, 429, 367, 422, - 369, 418, 371, 418, 285, 157, 424, 425, 426, 427, - 256, 418, 307, 320, 295, 439, 418, 324, 422, 375, - 288, 585, 329, 1445, 429, 293, 294, 285, 375, 326, - 418, 157, 369, 294, 331, 1457, 223, 1459, 1309, 329, - 308, 256, 1313, 374, 285, 306, 256, 315, 157, 317, - 474, 420, 316, 321, 423, 157, 351, 257, 256, 317, - 256, 1026, 157, 157, 257, 333, 334, 1338, 381, 157, - 372, 369, 369, 370, 999, 371, 317, 157, 381, 665, - 358, 372, 944, 339, 946, 339, 256, 949, 1412, 374, - 358, 870, 387, 388, 666, 262, 256, 256, 339, 1043, - 686, 369, 370, 256, 418, 373, 374, 375, 376, 377, - 378, 379, 380, 381, 382, 383, 418, 363, 415, 416, - 415, 416, 419, 1350, 370, 256, 372, 1092, 374, 371, - 368, 298, 1478, 256, 433, 256, 367, 405, 376, 433, - 256, 256, 256, 325, 443, 376, 266, 325, 1298, 256, - 574, 903, 1379, 1380, 374, 1382, 913, 418, 368, 374, - 709, 368, 1508, 587, 374, 589, 1393, 591, 266, 1396, - 882, 367, 418, 1035, 372, 1037, 1038, 61, 420, 358, - 376, 65, 66, 67, 1411, 69, 70, 662, 435, 483, - 74, 75, 335, 490, 314, 492, 416, 81, 1123, 83, - 370, 85, 449, 372, 374, 1130, 90, 91, 1435, 795, - 370, 378, 379, 372, 374, 368, 314, 694, 515, 726, - 484, 374, 429, 795, 277, 343, 701, 811, 281, 1154, - 114, 368, 656, 491, 341, 532, 418, 257, 369, 536, - 418, 993, 256, 343, 372, 513, 369, 515, 369, 517, - 491, 257, 676, 440, 441, 375, 372, 372, 372, 446, - 429, 1018, 369, 1020, 528, 529, 272, 372, 263, 368, - 256, 277, 1134, 391, 542, 281, 256, 375, 575, 547, - 363, 381, 368, 256, 870, 532, 1211, 363, 272, 342, - 296, 391, 429, 368, 368, 372, 414, 869, 305, 256, - 343, 429, 566, 559, 1166, 559, 339, 264, 363, 363, - 428, 363, 296, 373, 414, 369, 376, 323, 559, 305, - 315, 20, 256, 867, 429, 339, 594, 595, 428, 585, - 429, 585, 305, 369, 367, 418, 342, 256, 381, 323, - 817, 272, 418, 429, 585, 642, 277, 644, 391, 896, - 281, 1213, 429, 367, 429, 429, 653, 371, 735, 373, - 374, 375, 376, 418, 418, 296, 418, 381, 325, 1231, - 254, 414, 640, 257, 1159, 376, 306, 645, 646, 256, - 648, 305, 369, 313, 900, 428, 373, 367, 87, 88, - 263, 371, 323, 373, 374, 367, 376, 694, 363, 371, - 937, 381, 1226, 414, 369, 339, 1226, 398, 399, 108, - 344, 342, 346, 297, 711, 349, 350, 428, 352, 353, - 339, 994, 1226, 394, 395, 344, 694, 346, 429, 313, - 349, 350, 256, 352, 353, 415, 423, 687, 371, 357, - 373, 709, 315, 1155, 376, 726, 1270, 996, 420, 1022, - 1270, 369, 759, 418, 372, 373, 724, 339, 753, 392, - 393, 729, 339, 294, 1008, 762, 1270, 344, 386, 346, - 294, 391, 349, 350, 272, 352, 353, 256, 272, 412, - 721, 776, 723, 376, 961, 367, 1316, 420, 912, 256, - 423, 755, 1225, 1226, 414, 429, 791, 794, 296, 1329, - 199, 200, 296, 421, 1226, 773, 1226, 775, 428, 306, - 429, 308, 1245, 1226, 811, 779, 313, 781, 1348, 371, - 817, 256, 790, 418, 294, 323, 357, 768, 325, 323, - 771, 1226, 363, 428, 953, 357, 306, 1270, 369, 1272, - 1226, 372, 373, 811, 373, 844, 369, 376, 1270, 817, - 1270, 819, 429, 821, 386, 386, 1080, 1270, 381, 371, - 339, 373, 261, 1127, 386, 344, 339, 346, 381, 1113, - 349, 350, 339, 352, 353, 1270, 871, 344, 391, 346, - 874, 381, 349, 350, 1270, 352, 353, 418, 287, 256, - 421, 391, 1116, 1017, 367, 1159, 256, 865, 367, 867, - 299, 414, 486, 376, 418, 852, 306, 857, 307, 269, - 907, 357, 909, 313, 414, 428, 884, 374, 915, 376, - 1329, 371, 367, 891, 381, 325, 286, 373, 1152, 1106, - 1194, 376, 367, 901, 373, 903, 371, 376, 373, 374, - 386, 376, 367, 940, 528, 357, 381, 256, 1400, 367, - 429, 376, 351, 370, 368, 354, 384, 374, 376, 367, - 374, 373, 429, 371, 961, 373, 374, 381, 376, 354, - 355, 966, 339, 381, 386, 256, 944, 344, 946, 346, - 977, 949, 349, 350, 368, 352, 353, 367, 387, 388, - 382, 383, 376, 961, 1280, 371, 376, 373, 1173, 367, - 368, 1287, 6, 1169, 396, 397, 389, 415, 376, 1233, - 1462, 958, 1143, 17, 385, 370, 415, 416, 968, 374, - 970, 368, 972, 357, 371, 993, 373, 374, 996, 372, - 339, 374, 369, 376, 370, 344, 435, 346, 374, 373, - 349, 350, 400, 352, 353, 392, 393, 1499, 390, 370, - 449, 372, 386, 374, 418, 59, 1521, 1522, 999, 63, - 368, 1298, 1026, 415, 372, 412, 374, 1035, 376, 1037, - 1038, 368, 1040, 420, 368, 372, 423, 374, 372, 376, - 367, 368, 376, 87, 88, 371, 367, 368, 369, 376, - 371, 372, 368, 374, 369, 376, 418, 372, 374, 256, - 376, 1050, 370, 371, 108, 373, 374, 375, 418, 1106, - 368, 277, 1080, 371, 1108, 373, 374, 370, 371, 370, - 429, 374, 367, 374, 369, 372, 1094, 1095, 1092, 376, - 368, 369, 372, 532, 392, 393, 376, 418, 1106, 420, - 1107, 376, 423, 372, 1143, 1113, 1145, 376, 1116, 1143, - 372, 1145, 374, 157, 412, 554, 370, 372, 372, 376, - 374, 376, 420, 354, 355, 423, 1134, 372, 1412, 374, - 1169, 1127, 1140, 1127, 370, 1169, 372, 576, 370, 1303, - 372, 374, 1123, 376, 1152, 370, 1127, 372, 367, 1130, - 393, 394, 395, 396, 256, 199, 200, 294, 1166, 1167, - 367, 368, 1326, 1159, 1203, 1159, 368, 369, 357, 1203, - 386, 387, 388, 1154, 363, 370, 1340, 372, 1159, 372, - 369, 374, 373, 372, 373, 374, 1225, 1226, 372, 1224, - 374, 1225, 343, 370, 1358, 372, 1360, 386, 1194, 370, - 1194, 372, 374, 376, 376, 1213, 1245, 374, 374, 376, - 376, 1245, 374, 1194, 376, 376, 261, 261, 414, 415, - 364, 365, 294, 1231, 372, 1233, 665, 372, 373, 418, - 1211, 1270, 414, 1272, 364, 365, 1273, 418, 1272, 284, - 356, 285, 376, 287, 1279, 391, 392, 686, 418, 1111, - 1112, 369, 297, 389, 390, 299, 375, 302, 397, 398, - 1295, 1296, 307, 307, 309, 310, 311, 312, 418, 372, - 376, 372, 317, 317, 368, 374, 321, 372, 294, 1283, - 325, 372, 294, 1318, 374, 372, 1321, 372, 333, 372, - 374, 336, 93, 338, 256, 339, 97, 98, 99, 100, - 101, 102, 103, 104, 371, 376, 256, 351, 294, 294, - 354, 381, 372, 374, 753, 373, 1350, 362, 375, 374, - 373, 418, 381, 372, 374, 429, 374, 374, 374, 372, - 1334, 423, 374, 374, 367, 421, 372, 776, 373, 343, - 372, 294, 294, 387, 388, 1379, 1380, 374, 1382, 374, - 0, 1390, 791, 418, 371, 370, 795, 367, 256, 1393, - 256, 375, 1396, 374, 418, 256, 261, 256, 1407, 280, - 256, 415, 416, 418, 381, 367, 372, 1411, 368, 343, - 351, 1420, 1421, 370, 423, 376, 374, 371, 381, 284, - 372, 374, 1400, 370, 1398, 376, 372, 372, 347, 367, - 256, 1435, 297, 381, 1412, 256, 372, 302, 1447, 1448, - 305, 381, 307, 852, 309, 310, 311, 312, 372, 0, - 376, 1429, 317, 368, 347, 339, 321, 370, 374, 370, - 325, 870, 871, 375, 381, 370, 372, 368, 333, 348, - 374, 336, 372, 338, 418, 418, 348, 491, 376, 256, - 368, 367, 256, 368, 1462, 402, 403, 404, 405, 406, - 407, 408, 409, 410, 411, 1504, 367, 362, 367, 381, - 376, 356, 372, 337, 371, 368, 368, 305, 368, 418, - 374, 418, 369, 371, 1521, 1522, 418, 367, 532, 418, - 371, 1499, 418, 376, 371, 371, 371, 381, 937, 373, - 301, 1505, 1506, 371, 367, 371, 373, 369, 1512, 1513, - 554, 381, 372, 1521, 1522, 559, 374, 372, 256, 958, - 373, 367, 0, 418, 374, 374, 374, 966, 372, 376, - 372, 332, 576, 370, 368, 339, 418, 376, 376, 418, - 344, 585, 346, 347, 348, 349, 350, 351, 352, 353, - 354, 355, 356, 418, 372, 376, 372, 418, 381, 372, - 370, 381, 368, 372, 368, 315, 370, 263, 372, 371, - 374, 375, 376, 371, 368, 372, 372, 0, 0, 367, - 372, 376, 368, 384, 385, 386, 390, 376, 389, 390, - 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, - 401, 402, 403, 404, 0, 368, 372, 257, 372, 370, - 418, 261, 367, 372, 0, 368, 368, 373, 372, 370, - 367, 665, 272, 368, 372, 429, 368, 277, 418, 372, - 376, 281, 376, 418, 284, 376, 372, 376, 368, 367, - 372, 368, 686, 372, 368, 376, 296, 297, 367, 315, - 376, 301, 302, 376, 376, 376, 376, 307, 376, 309, - 310, 311, 312, 376, 376, 263, 50, 317, 12, 5, - 958, 321, 852, 323, 1272, 1106, 257, 721, 1106, 723, - 261, 1452, 1415, 333, 1245, 335, 336, 686, 338, 1468, - 1432, 272, 342, 1403, 1398, 1304, 277, 700, 874, 874, - 281, 869, 1316, 284, 1513, 874, 1335, 1146, 1258, 753, - 511, 1270, 362, 1421, 1420, 296, 297, 1507, 368, 369, - 301, 302, 1425, 1203, 768, 1506, 307, 771, 309, 310, - 311, 312, 776, 1360, 1304, 844, 317, 896, 1205, 265, - 321, 267, 323, 817, 270, 532, 369, 791, 1008, 275, - 729, 795, 333, 279, 335, 336, 694, 338, 71, 595, - 335, 342, 288, 726, 399, 401, 1205, 400, 402, 295, - 554, 403, 795, 404, 300, 1279, 1194, 1183, 304, 257, - 581, 362, 1127, 261, 157, 1224, 995, 1071, 369, 1095, - 316, 979, 318, 1022, 272, 1085, 322, 0, 1155, 277, - 1083, 1275, 917, 281, 330, 331, 284, 424, 334, 424, - 651, 337, 1167, 530, -1, -1, 850, -1, 296, 297, - 849, -1, -1, 301, 302, -1, 870, 871, -1, 307, - -1, 309, 310, 311, 312, -1, -1, 363, -1, 317, - 1279, 1280, -1, 321, -1, 323, -1, -1, 1287, -1, - -1, -1, -1, -1, -1, 333, 1295, 1296, 336, 1298, - 338, -1, -1, -1, 342, 1304, -1, -1, -1, -1, - 256, -1, -1, -1, -1, 261, 262, 1316, -1, 1318, - -1, -1, 1321, -1, 362, -1, -1, -1, -1, -1, - 1329, 369, 418, 937, -1, -1, -1, -1, 284, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 1348, - -1, 297, 298, -1, -1, -1, 302, -1, -1, 305, - -1, 307, 966, 309, 310, 311, 312, -1, -1, -1, - -1, 317, -1, -1, -1, 321, -1, -1, -1, 325, - -1, -1, -1, -1, -1, -1, -1, 333, -1, -1, - 336, -1, 338, 339, -1, 999, -1, -1, 344, -1, + 4, 302, 18, 303, 234, 17, 17, 540, 190, 236, + 52, 292, 488, 189, 538, 17, 510, 52, 326, 6, + 350, 69, 85, 20, 60, 301, 301, 587, 1001, 158, + 337, 594, 249, 389, 605, 78, 1183, 805, 1222, 299, + 88, 89, 0, 256, 114, 93, 116, 256, 59, 256, + 1325, 114, 256, 116, 614, 268, 74, 774, 333, 776, + 78, 60, 1216, 45, 17, 113, 48, 373, 1343, 80, + 256, 82, 17, 88, 89, 256, 256, 1261, 96, 256, + 1300, 256, 373, 256, 256, 256, 1006, 256, 368, 17, + 256, 0, 1276, 256, 109, 335, 376, 17, 62, 17, + 268, 256, 66, 67, 68, 256, 70, 71, 256, 294, + 827, 75, 76, 830, 256, 268, 263, 269, 82, 374, + 84, 306, 86, 256, 256, 173, 1280, 91, 92, 256, + 1058, 372, 368, 357, 286, 256, 343, 256, 374, 305, + 158, 17, 713, 264, 367, 256, 158, 158, 190, 429, + 282, 115, 368, 376, 429, 190, 158, 256, 358, 339, + 1088, 416, 386, 372, 344, 374, 346, 192, 315, 349, + 350, 388, 352, 353, 256, 1395, 17, 363, 256, 0, + 1400, 17, 314, 17, 391, 200, 201, 391, 429, 429, + 371, 363, 234, 429, 374, 256, 371, 256, 17, 234, + 248, 249, 418, 277, 325, 158, 256, 414, 381, 422, + 414, 693, 381, 158, 262, 368, 698, 699, 1138, 374, + 429, 428, 452, 17, 60, 367, 453, 534, 64, 371, + 158, 249, 418, 418, 1509, 1455, 537, 255, 158, 420, + 158, 418, 224, 230, 777, 420, 418, 418, 367, 429, + 265, 299, 371, 289, 422, 418, 367, 587, 369, 358, + 371, 1536, 325, 299, 334, 556, 329, 418, 17, 422, + 418, 334, 578, 1548, 292, 1550, 291, 840, 420, 297, + 298, 256, 158, 331, 614, 418, 418, 578, 336, 363, + 289, 418, 374, 257, 312, 256, 311, 261, 376, 257, + 348, 420, 320, 328, 322, 268, 367, 256, 326, 420, + 321, 257, 423, 276, 605, 376, 375, 158, 256, 1178, + 338, 339, 158, 322, 158, 424, 425, 426, 427, 344, + 345, 381, 256, 381, 377, 20, 384, 301, 350, 158, + 388, 389, 325, 1111, 418, 419, 1063, 256, 350, 374, + 256, 368, 256, 317, 379, 370, 1503, 262, 1217, 377, + 931, 292, 21, 256, 158, 256, 256, 256, 335, 277, + 388, 389, 256, 281, 392, 393, 394, 395, 396, 397, + 398, 399, 400, 401, 402, 1569, 434, 435, 363, 256, + 438, 406, 407, 298, 53, 370, 256, 372, 369, 374, + 363, 418, 373, 88, 89, 257, 424, 256, 714, 158, + 452, 1384, 256, 256, 375, 1599, 256, 452, 256, 434, + 435, 463, 713, 256, 109, 256, 256, 376, 463, 256, + 339, 964, 256, 458, 342, 418, 257, 375, 256, 256, + 371, 263, 256, 418, 926, 418, 370, 340, 739, 943, + 374, 272, 423, 289, 762, 418, 277, 454, 367, 976, + 281, 509, 371, 511, 373, 374, 375, 376, 493, 375, + 374, 468, 381, 378, 379, 296, 1193, 459, 460, 368, + 962, 372, 372, 465, 1201, 374, 322, 292, 372, 420, + 538, 351, 503, 315, 721, 266, 339, 341, 1180, 325, + 368, 344, 323, 346, 305, 372, 349, 350, 556, 352, + 353, 510, 560, 1230, 350, 200, 201, 873, 536, 779, + 538, 342, 540, 372, 1057, 369, 1008, 754, 1010, 1092, + 747, 1013, 372, 368, 372, 363, 367, 1219, 371, 369, + 367, 505, 553, 314, 371, 369, 373, 374, 566, 376, + 856, 369, 369, 571, 381, 369, 604, 266, 583, 556, + 372, 429, 367, 368, 401, 856, 391, 1084, 343, 1086, + 339, 582, 368, 1290, 363, 587, 413, 368, 603, 363, + 265, 1440, 256, 594, 343, 587, 429, 370, 552, 414, + 418, 374, 418, 618, 429, 368, 621, 622, 367, 1162, + 428, 305, 614, 368, 375, 314, 291, 1307, 626, 627, + 1469, 1470, 614, 1472, 372, 256, 391, 429, 303, 1101, + 294, 1103, 381, 1105, 930, 1484, 311, 928, 1487, 418, + 1306, 1307, 391, 429, 418, 368, 363, 1197, 429, 414, + 931, 374, 256, 1502, 428, 1538, 1539, 695, 381, 697, + 256, 958, 1328, 428, 1354, 414, 429, 372, 706, 344, + 345, 790, 879, 363, 429, 363, 375, 1526, 371, 428, + 294, 429, 371, 363, 510, 693, 375, 357, 1354, 369, + 698, 699, 306, 701, 709, 370, 961, 963, 373, 369, + 371, 418, 372, 373, 376, 272, 429, 256, 339, 747, + 1376, 1001, 1595, 344, 729, 346, 386, 363, 349, 350, + 343, 352, 353, 369, 429, 256, 764, 420, 418, 296, + 418, 406, 407, 1205, 1307, 339, 341, 1307, 418, 747, + 344, 779, 346, 374, 369, 349, 350, 1231, 352, 353, + 372, 421, 1403, 779, 762, 1307, 323, 429, 381, 434, + 435, 587, 1060, 740, 369, 818, 1417, 1239, 391, 777, + 256, 367, 418, 374, 305, 371, 784, 373, 374, 454, + 376, 1354, 1073, 821, 1354, 381, 1307, 1438, 614, 1303, + 339, 414, 272, 468, 339, 344, 418, 346, 429, 272, + 349, 350, 1354, 352, 353, 428, 811, 1307, 256, 391, + 1307, 812, 1307, 814, 256, 416, 296, 855, 1025, 415, + 1292, 339, 367, 296, 832, 429, 834, 269, 376, 367, + 835, 376, 414, 1354, 1154, 873, 844, 838, 376, 840, + 1312, 879, 339, 323, 286, 306, 428, 852, 1366, 367, + 323, 1017, 313, 339, 1354, 1373, 810, 1354, 344, 1354, + 346, 339, 381, 349, 350, 873, 352, 353, 394, 395, + 367, 879, 391, 881, 371, 883, 908, 1197, 1149, 339, + 429, 556, 370, 908, 367, 272, 374, 369, 367, 367, + 277, 339, 1183, 376, 281, 414, 344, 375, 346, 381, + 256, 349, 350, 578, 352, 353, 306, 367, 308, 296, + 367, 368, 367, 313, 376, 1186, 368, 357, 926, 376, + 928, 376, 374, 357, 6, 325, 913, 932, 371, 381, + 605, 969, 368, 373, 972, 17, 323, 945, 374, 373, + 978, 918, 950, 429, 367, 953, 386, 357, 774, 386, + 776, 1417, 386, 376, 962, 342, 964, 1228, 306, 967, + 975, 367, 368, 373, 1390, 313, 1004, 371, 1491, 1176, + 376, 1291, 368, 1399, 389, 1390, 386, 325, 60, 368, + 376, 429, 64, 339, 1399, 374, 369, 1025, 344, 372, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, - 356, -1, -1, -1, -1, -1, 362, 363, -1, -1, - -1, 367, 368, -1, 370, 371, 372, 373, 374, 375, - 376, 0, 378, 379, -1, 381, 382, 383, 384, 385, - 386, 387, 388, 389, 390, -1, 392, 393, 394, 395, - 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, - 406, 407, 408, 409, 410, 411, 412, 413, -1, -1, - 416, -1, 418, -1, 420, -1, -1, 423, -1, -1, - -1, -1, -1, 429, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 257, -1, -1, -1, 261, -1, - -1, 256, -1, -1, -1, -1, -1, 262, -1, 272, - -1, -1, -1, -1, 277, -1, -1, -1, 281, 1123, - -1, 284, -1, 1127, -1, -1, 1130, -1, -1, -1, - -1, -1, -1, 296, 297, 896, -1, -1, 301, 302, - -1, -1, 1146, 298, 307, -1, 309, 310, 311, 312, - 1154, -1, -1, -1, 317, 1159, -1, -1, 321, -1, - 323, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 333, -1, -1, 336, -1, 338, -1, -1, -1, 342, + 1008, 827, 1010, 1041, 830, 1013, 88, 89, 373, 1047, + 384, 376, 368, 256, 370, 368, 372, 1025, 374, 375, + 376, 374, 1242, 376, 370, 1030, 368, 109, 374, 1246, + 1553, 382, 383, 368, 376, 1022, 368, 372, 713, 374, + 372, 376, 1214, 1314, 376, 396, 397, 373, 385, 1057, + 376, 265, 1060, 267, 256, 1032, 270, 1034, 371, 1036, + 373, 275, 370, 371, 739, 279, 374, 1590, 1083, 373, + 400, 368, 376, 429, 288, 372, 158, 374, 390, 376, + 374, 295, 376, 256, 370, 1366, 300, 381, 374, 369, + 304, 1092, 1373, 1101, 1384, 1103, 339, 1105, 1612, 1613, + 1108, 344, 316, 346, 318, 415, 349, 350, 322, 352, + 353, 372, 371, 374, 373, 376, 330, 331, 200, 201, + 334, 398, 399, 337, 371, 1119, 373, 418, 370, 371, + 370, 373, 374, 375, 374, 372, 811, 339, 1176, 376, + 418, 1149, 344, 277, 346, 392, 393, 349, 350, 363, + 352, 353, 1154, 373, 372, 372, 1164, 1165, 376, 376, + 835, 1162, 1154, 370, 367, 412, 369, 374, 1176, 367, + 370, 1177, 372, 420, 374, 1183, 423, 852, 1186, 368, + 369, 856, 1214, 265, 1216, 372, 429, 374, 370, 1214, + 372, 1216, 374, 376, 372, 1197, 376, 1205, 376, 256, + 386, 387, 388, 1211, 418, 1197, 372, 289, 374, 291, + 1242, 256, 1503, 412, 413, 414, 415, 1242, 357, 373, + 1228, 303, 256, 370, 363, 372, 374, 376, 376, 311, + 369, 1239, 1240, 372, 373, 374, 376, 1063, 913, 370, + 322, 372, 370, 294, 372, 367, 294, 386, 1280, 371, + 343, 373, 374, 372, 376, 1280, 931, 932, 294, 381, + 367, 368, 344, 345, 370, 1303, 372, 372, 350, 374, + 372, 0, 374, 376, 1306, 1307, 370, 414, 372, 418, + 418, 1306, 1307, 370, 1292, 372, 354, 355, 370, 1291, + 374, 373, 376, 415, 418, 1303, 1328, 356, 256, 1291, + 1305, 354, 355, 1328, 1312, 374, 1314, 376, 368, 369, + 367, 368, 369, 369, 371, 372, 374, 374, 376, 376, + 1358, 357, 1354, 418, 406, 407, 1001, 363, 1154, 1354, + 374, 372, 376, 369, 414, 415, 372, 373, 364, 365, + 372, 373, 367, 368, 1376, 364, 365, 1022, 410, 411, + 386, 1376, 434, 435, 375, 1030, 408, 409, 372, 376, + 1365, 418, 368, 420, 374, 381, 423, 1193, 1369, 416, + 417, 1197, 372, 294, 1389, 1201, 1381, 1382, 294, 429, + 374, 339, 418, 372, 372, 421, 344, 374, 346, 347, + 348, 349, 350, 351, 352, 353, 354, 355, 356, 1414, + 1405, 372, 256, 1408, 1230, 428, 376, 371, 428, 256, + 368, 294, 370, 294, 372, 1430, 374, 375, 376, 381, + 372, 1422, 375, 374, 382, 383, 384, 385, 510, 373, + 373, 389, 390, 1448, 374, 1450, 394, 395, 396, 397, + 398, 399, 400, 401, 418, 381, 372, 374, 429, 1481, + 374, 374, 374, 372, 423, 413, 1481, 374, 367, 374, + 421, 372, 374, 373, 1290, 1291, 1498, 372, 343, 294, + 294, 429, 374, 1498, 556, 370, 418, 371, 367, 1511, + 1512, 418, 375, 1491, 256, 256, 1511, 1512, 1489, 374, + 256, 256, 280, 94, 381, 1503, 578, 98, 99, 100, + 101, 102, 103, 104, 105, 587, 1538, 1539, 261, 256, + 367, 372, 1520, 1538, 1539, 368, 343, 376, 370, 374, + 371, 370, 423, 605, 374, 381, 372, 256, 376, 372, + 372, 284, 614, 262, 372, 347, 367, 381, 256, 256, + 381, 376, 372, 1218, 297, 1553, 372, 368, 256, 302, + 347, 374, 370, 375, 307, 371, 309, 310, 311, 312, + 370, 292, 370, 1595, 317, 372, 339, 348, 321, 298, + 1595, 374, 368, 418, 1612, 1613, 256, 372, 371, 418, + 333, 372, 1590, 336, 348, 338, 368, 367, 367, 381, + 0, 376, 367, 356, 368, 1596, 1597, 374, 376, 368, + 368, 371, 1603, 1604, 1612, 1613, 305, 337, 1283, 362, + 339, 364, 365, 372, 372, 344, 368, 346, 347, 348, + 349, 350, 351, 352, 353, 354, 355, 356, 418, 371, + 1305, 713, 369, 367, 363, 418, 371, 376, 367, 368, + 381, 370, 371, 372, 371, 374, 375, 376, 371, 378, + 379, 418, 373, 382, 383, 384, 385, 739, 418, 371, + 389, 390, 367, 372, 371, 394, 395, 396, 397, 398, + 399, 400, 401, 369, 371, 381, 374, 372, 256, 373, + 373, 372, 374, 285, 413, 374, 374, 416, 372, 418, + 1365, 1366, 774, 418, 776, 376, 370, 376, 1373, 418, + 429, 376, 418, 372, 305, 418, 1381, 1382, 376, 1384, + 372, 381, 372, 368, 381, 1390, 370, 368, 367, 372, + 315, 263, 368, 371, 1399, 327, 371, 0, 1403, 811, + 1405, 372, 372, 1408, 0, 367, 337, 376, 368, 376, + 0, 256, 1417, 372, 368, 827, 347, 372, 830, 367, + 372, 370, 418, 835, 368, 372, 368, 372, 367, 370, + 418, 0, 418, 1438, 368, 372, 376, 372, 376, 368, + 852, 315, 368, 376, 856, 377, 378, 379, 380, 376, + 382, 383, 384, 385, 386, 387, 388, 389, 367, 372, + 392, 393, 394, 395, 396, 397, 398, 399, 368, 372, + 376, 368, 403, 404, 405, 367, 263, 408, 409, 410, + 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, + 421, 422, 423, 373, 339, 376, 51, 376, 376, 344, + 376, 346, 347, 348, 349, 350, 351, 352, 353, 354, + 355, 356, 376, 376, 376, 376, 256, 12, 5, 931, + 932, 261, 262, 368, 1022, 370, 1176, 372, 913, 374, + 375, 376, 1176, 1376, 1328, 1224, 368, 1543, 1506, 371, + 385, 373, 374, 1559, 284, 390, 1494, 1489, 1523, 381, + 753, 935, 1403, 1604, 1354, 400, 401, 297, 298, 935, + 392, 393, 302, 935, 1423, 305, 1342, 307, 413, 309, + 310, 311, 312, 930, 1512, 1516, 1598, 317, 1511, 1280, + 412, 321, 1597, 1450, 429, 325, 908, 1283, 420, 1001, + 556, 423, 953, 333, 784, 958, 336, 429, 338, 339, + 879, 1073, 388, 534, 344, 0, 346, 347, 348, 349, + 350, 351, 352, 353, 354, 355, 356, 747, 1030, 627, + 72, 779, 362, 363, 340, 418, 420, 367, 368, 419, + 370, 371, 372, 373, 374, 375, 376, 421, 378, 379, + 422, 381, 382, 383, 384, 385, 386, 387, 388, 389, + 390, 1063, 392, 393, 394, 395, 396, 397, 398, 399, + 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, + 410, 411, 412, 413, 423, 1182, 416, 578, 418, 610, + 420, 1365, 1258, 423, 158, 1291, 856, 256, 257, 429, + 1059, 1154, 1140, 1088, 1165, 264, 265, 266, 267, 268, + 1043, 270, 271, 1154, 273, 274, 275, 276, 277, 278, + 279, 280, 1152, 1231, 554, 1200, 285, 980, 287, 288, + 289, 290, 291, 292, 443, 443, 295, 704, 1360, 1240, + 299, 300, 663, 302, 303, 304, -1, 903, -1, -1, + -1, 0, 1154, 910, -1, 314, -1, 316, -1, 318, + 319, -1, -1, 322, -1, 324, 325, 326, 327, 328, + 329, 330, 331, 332, 333, 334, 335, -1, 337, -1, + -1, 340, 341, -1, -1, 344, 345, -1, -1, -1, + -1, 1193, -1, -1, -1, 1197, -1, -1, -1, 1201, + 359, 360, 361, 362, 363, -1, -1, -1, 367, 368, + -1, -1, 371, -1, 381, -1, 1218, 376, 377, 378, + 379, 380, -1, -1, -1, 384, -1, 386, 1230, -1, + -1, -1, -1, 392, 393, 402, 403, 404, 405, 406, + 407, 408, 409, 410, 411, -1, -1, -1, -1, 368, + -1, -1, 371, -1, 373, 374, -1, -1, 417, 418, + 419, 420, 783, 422, -1, -1, -1, -1, -1, -1, + 429, -1, 257, 392, 393, -1, 261, 0, -1, -1, + -1, 1283, -1, -1, -1, -1, -1, 272, 1290, 1291, + -1, -1, 277, 412, -1, -1, 281, -1, -1, 284, + -1, 420, -1, 1305, 423, -1, -1, -1, -1, -1, + 429, 296, 297, -1, -1, -1, 301, 302, -1, -1, + -1, -1, 307, -1, 309, 310, 311, 312, -1, -1, + -1, -1, 317, -1, -1, -1, 321, -1, 323, -1, + -1, -1, -1, -1, -1, -1, -1, -1, 333, -1, + 335, 336, -1, 338, -1, -1, -1, 342, -1, -1, + -1, -1, -1, 1365, 1366, -1, -1, -1, -1, -1, + -1, 1373, -1, -1, -1, -1, -1, 362, -1, 1381, + 1382, -1, 1384, 368, 369, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 1194, -1, -1, -1, -1, -1, -1, -1, 0, 362, - -1, 1205, -1, -1, -1, 368, 369, 1211, 363, -1, - -1, -1, -1, 368, 369, -1, 371, 372, 373, 374, - 1224, 376, -1, 378, 379, -1, 381, 382, 383, 384, - 385, -1, 387, 388, 389, 390, -1, 392, 393, 394, - 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, - 405, 406, 407, 408, 409, 410, 411, 412, 413, -1, - -1, -1, -1, 418, -1, 420, -1, -1, 423, -1, - -1, -1, -1, -1, 429, 1279, 1280, -1, -1, -1, - -1, -1, -1, 1287, -1, -1, -1, 256, 257, -1, - -1, 1295, 1296, -1, 1298, 264, 265, 266, 267, 268, - -1, 270, 271, -1, 273, 274, 275, 276, 277, 278, - 279, 280, -1, -1, 1318, -1, 285, 1321, 287, 288, - 289, 290, 291, 292, 0, -1, 295, -1, -1, -1, + -1, -1, -1, 1405, -1, -1, 1408, 256, 257, -1, + -1, -1, -1, -1, -1, 264, 265, 266, 267, 268, + -1, 270, 271, 0, 273, 274, 275, 276, 277, 278, + 279, -1, -1, -1, -1, -1, 285, 958, 287, 288, + 289, 290, 291, 292, -1, -1, 295, -1, -1, -1, 299, 300, -1, 302, 303, 304, -1, -1, -1, -1, -1, -1, -1, -1, -1, 314, -1, 316, -1, 318, 319, -1, -1, 322, -1, 324, 325, 326, 327, 328, @@ -11661,223 +13015,235 @@ void case_982() -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 359, 360, 361, 362, 363, -1, -1, -1, 367, 368, -1, -1, 371, -1, -1, -1, -1, 376, 377, 378, - 379, 380, -1, -1, -1, 384, -1, 386, -1, -1, + 379, 380, -1, 256, -1, 384, -1, 386, 261, 262, -1, -1, -1, 392, 393, -1, -1, -1, -1, -1, + -1, -1, -1, 0, -1, -1, -1, -1, -1, -1, + -1, 284, -1, -1, -1, -1, -1, -1, 417, 418, + 419, 420, -1, 422, 297, 298, -1, -1, -1, 302, + 429, -1, 305, -1, 307, -1, 309, 310, 311, 312, + -1, -1, -1, -1, 317, -1, -1, -1, 321, -1, + -1, -1, 325, -1, -1, -1, -1, -1, -1, -1, + 333, -1, -1, 336, -1, 338, 339, -1, -1, -1, + -1, 344, -1, 346, 347, 348, 349, 350, 351, 352, + 353, 354, 355, 356, 357, -1, -1, -1, -1, 362, + 363, -1, -1, -1, 367, 368, 369, 370, 371, 372, + 373, 374, 375, 376, -1, 378, 379, -1, -1, 382, + 383, 384, 385, 386, -1, -1, 389, 390, -1, -1, + -1, 394, 395, 396, 397, 398, 399, 400, 401, 256, + -1, -1, -1, 0, 261, 262, -1, -1, -1, -1, + 413, -1, -1, 416, -1, 418, -1, 420, -1, -1, + 423, -1, -1, -1, -1, -1, 429, 284, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 417, 418, - 419, 420, -1, 422, 256, 257, -1, -1, -1, -1, - 429, -1, 264, 265, 266, 267, 268, -1, 270, 271, - 0, 273, 274, 275, 276, 277, 278, 279, -1, -1, - -1, -1, -1, 285, -1, 287, 288, 289, 290, 291, - 292, -1, -1, 295, -1, -1, -1, 299, 300, -1, - 302, 303, 304, -1, -1, -1, -1, -1, -1, -1, - -1, -1, 314, -1, 316, -1, 318, 319, -1, -1, - 322, -1, 324, 325, 326, 327, 328, 329, 330, 331, - 332, 333, 334, 335, -1, 337, -1, -1, 340, 341, - -1, -1, 344, 345, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 359, 360, 361, - 362, 363, -1, -1, -1, 367, 368, -1, -1, 371, - -1, -1, -1, -1, 376, 377, 378, 379, 380, -1, - 256, -1, 384, -1, 386, 261, 262, -1, -1, -1, - 392, 393, -1, -1, -1, -1, -1, -1, -1, -1, - 0, -1, -1, -1, -1, -1, -1, -1, 284, -1, - -1, -1, -1, -1, -1, 417, 418, 419, 420, -1, - 422, 297, 298, -1, -1, -1, 302, 429, -1, 305, - -1, 307, -1, 309, 310, 311, 312, -1, -1, -1, - -1, 317, -1, -1, -1, 321, -1, -1, -1, 325, - -1, -1, -1, -1, -1, -1, -1, 333, -1, -1, - 336, -1, 338, 339, -1, -1, -1, -1, 344, -1, - 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, - 356, 357, -1, -1, -1, -1, 362, 363, -1, -1, - -1, 367, 368, 369, 370, 371, 372, 373, 374, 375, - 376, -1, 378, 379, -1, -1, 382, 383, 384, 385, - 386, -1, -1, 389, 390, -1, -1, -1, 394, 395, - 396, 397, 398, 399, 400, 401, 256, -1, -1, -1, - 0, 261, 262, -1, -1, -1, -1, 413, -1, -1, - 416, -1, 418, -1, 420, -1, -1, 423, -1, -1, - -1, -1, -1, 429, 284, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 297, 298, -1, - -1, -1, 302, -1, -1, 305, -1, 307, -1, 309, - 310, 311, 312, -1, -1, -1, -1, 317, -1, -1, - -1, 321, -1, -1, -1, 325, -1, -1, -1, -1, - -1, -1, -1, 333, -1, -1, 336, -1, 338, 339, - -1, -1, -1, -1, 344, -1, 346, 347, 348, 349, - 350, 351, 352, 353, 354, 355, 356, -1, -1, -1, - -1, -1, 362, 363, 0, -1, -1, 367, 368, 369, - 370, 371, 372, -1, 374, 375, 376, -1, 378, 379, - -1, -1, 382, 383, 384, 385, 256, -1, -1, 389, - 390, 261, 262, -1, 394, 395, 396, 397, 398, 399, - 400, 401, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 413, 284, -1, 416, -1, 418, -1, - 420, -1, -1, 423, -1, -1, -1, 297, 298, 429, - -1, -1, 302, -1, -1, 305, -1, 307, -1, 309, - 310, 311, 312, -1, -1, -1, -1, 317, -1, -1, - -1, 321, -1, -1, -1, 325, -1, -1, -1, -1, - -1, -1, -1, 333, -1, -1, 336, -1, 338, 339, - -1, -1, -1, -1, 344, -1, 346, 347, 348, 349, - 350, 351, 352, 353, 354, 355, 356, -1, -1, -1, - -1, -1, 362, 363, -1, -1, -1, 367, 368, 369, - 370, 371, 372, -1, 374, 375, 376, -1, 378, 379, - 0, -1, 382, 383, 384, 385, 256, -1, -1, 389, - 390, 261, 262, -1, 394, 395, 396, 397, 398, 399, - 400, 401, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 413, 284, -1, 416, -1, 418, -1, - 420, -1, -1, 423, -1, -1, -1, 297, 298, 429, - -1, -1, 302, -1, -1, 305, -1, 307, -1, 309, - 310, 311, 312, -1, -1, -1, -1, 317, -1, -1, - -1, 321, -1, -1, -1, 325, -1, -1, -1, -1, - -1, -1, -1, 333, -1, -1, 336, -1, 338, 339, - -1, -1, -1, -1, 344, -1, 346, 347, 348, 349, - 350, 351, 352, 353, 354, 355, 356, -1, -1, -1, - 256, -1, 362, 363, -1, -1, 262, 367, 368, -1, - 370, 371, 372, -1, 374, 375, 376, -1, 378, 379, - -1, -1, 382, 383, 384, 385, -1, -1, -1, 389, - 390, -1, -1, -1, 394, 395, 396, 397, 398, 399, - 400, 401, 298, -1, -1, -1, -1, -1, 0, -1, - -1, -1, -1, 413, -1, -1, 416, -1, 418, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 429, + 297, 298, -1, -1, -1, 302, -1, -1, 305, -1, + 307, -1, 309, 310, 311, 312, -1, -1, -1, -1, + 317, -1, -1, -1, 321, -1, -1, -1, 325, -1, + -1, -1, -1, -1, -1, -1, 333, -1, -1, 336, + -1, 338, 339, -1, -1, -1, -1, 344, -1, 346, + 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, + -1, -1, -1, -1, -1, 362, 363, 0, -1, -1, + 367, 368, 369, 370, 371, 372, -1, 374, 375, 376, + -1, 378, 379, -1, -1, 382, 383, 384, 385, 256, + -1, -1, 389, 390, 261, 262, -1, 394, 395, 396, + 397, 398, 399, 400, 401, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 413, 284, -1, 416, + -1, 418, -1, 420, -1, -1, 423, -1, -1, -1, + 297, 298, 429, -1, -1, 302, -1, -1, 305, -1, + 307, -1, 309, 310, 311, 312, -1, -1, -1, -1, + 317, -1, -1, -1, 321, -1, -1, -1, 325, -1, + -1, -1, -1, -1, -1, -1, 333, -1, -1, 336, + -1, 338, 339, -1, -1, -1, -1, 344, -1, 346, + 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, + -1, -1, -1, -1, -1, 362, 363, -1, -1, -1, + 367, 368, 369, 370, 371, 372, -1, 374, 375, 376, + -1, 378, 379, -1, -1, 382, 383, 384, 385, 256, + -1, -1, 389, 390, 261, 262, -1, 394, 395, 396, + 397, 398, 399, 400, 401, -1, 0, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 413, 284, -1, 416, + -1, 418, -1, 420, -1, -1, 423, -1, -1, -1, + 297, 298, 429, -1, -1, 302, -1, -1, 305, -1, + 307, -1, 309, 310, 311, 312, -1, -1, -1, -1, + 317, -1, -1, -1, 321, -1, -1, -1, 325, -1, + -1, -1, -1, -1, -1, -1, 333, -1, -1, 336, + -1, 338, 339, -1, -1, -1, -1, 344, -1, 346, + 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, + -1, -1, 0, 256, -1, 362, 363, -1, -1, 262, + 367, 368, -1, 370, 371, 372, -1, 374, 375, 376, + -1, 378, 379, -1, -1, 382, 383, 384, 385, -1, + -1, -1, 389, 390, -1, -1, -1, 394, 395, 396, + 397, 398, 399, 400, 401, 298, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 413, -1, -1, 416, + -1, 418, -1, -1, -1, 0, -1, -1, -1, -1, + -1, -1, 429, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 339, -1, -1, -1, + -1, 344, -1, 346, 347, 348, 349, 350, 351, 352, + 353, 354, 355, 356, 357, -1, -1, -1, -1, -1, + 363, -1, -1, -1, 367, 368, 369, 370, 371, 372, + 373, 374, 375, 376, -1, 378, 379, -1, -1, 382, + 383, 384, 385, 386, 0, -1, 389, 390, -1, -1, + -1, 394, 395, 396, 397, 398, 399, 400, 401, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 339, -1, -1, -1, -1, 344, -1, - 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, - 356, 357, -1, -1, 256, -1, -1, 363, -1, -1, - -1, 367, 368, 369, 370, 371, 372, 373, 374, 375, - 376, -1, 378, 379, -1, -1, 382, 383, 384, 385, - 386, 0, -1, 389, 390, -1, -1, -1, 394, 395, - 396, 397, 398, 399, 400, 401, 256, -1, -1, -1, - -1, -1, 262, -1, -1, -1, -1, 413, -1, -1, - 416, -1, 418, -1, 420, -1, -1, 423, -1, -1, - -1, -1, -1, 429, 0, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 339, 298, -1, - -1, -1, 344, -1, 346, 347, 348, 349, 350, 351, - 352, 353, 354, 355, 356, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 368, 0, 370, -1, - 372, -1, 374, 375, 376, -1, -1, -1, -1, 339, - -1, -1, -1, -1, 344, -1, 346, 347, 348, 349, - 350, 351, 352, 353, 354, 355, 356, -1, -1, -1, - -1, -1, -1, 363, -1, -1, -1, 367, 368, -1, - 370, 371, 372, -1, 374, 375, 376, -1, 378, 379, - -1, -1, 382, 383, 384, 385, -1, 429, -1, 389, - 390, -1, -1, -1, 394, 395, 396, 397, 398, 399, - 400, 401, -1, -1, -1, -1, -1, 0, -1, -1, - -1, -1, -1, 413, 256, 257, 416, -1, 418, 261, - -1, -1, -1, 265, -1, 267, -1, -1, 270, 429, - 272, 273, -1, 275, -1, 277, -1, 279, -1, 281, - 282, 283, 284, -1, -1, 287, 288, -1, -1, -1, - 0, 293, -1, 295, 296, 297, -1, -1, 300, 301, - 302, -1, 304, -1, -1, 307, -1, 309, 310, 311, - 312, -1, -1, -1, 316, 317, 318, -1, -1, 321, - 322, 323, -1, -1, -1, -1, -1, -1, 330, 331, - -1, 333, 334, 0, 336, 337, 338, -1, 257, -1, - 342, -1, 261, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 272, -1, -1, -1, -1, 277, -1, - 362, -1, 281, -1, -1, 284, 368, 369, -1, -1, - -1, -1, -1, -1, -1, 377, 0, 296, 297, -1, + 413, -1, -1, 416, -1, 418, -1, 420, -1, -1, + 423, -1, 256, 257, -1, -1, 429, 261, -1, -1, + -1, 265, -1, 267, -1, -1, 270, -1, 272, 273, + -1, 275, -1, 277, -1, 279, -1, 281, 282, 283, + 284, -1, -1, 287, 288, -1, -1, -1, 0, 293, + -1, 295, 296, 297, -1, -1, 300, 301, 302, -1, + 304, -1, -1, 307, -1, 309, 310, 311, 312, -1, + -1, -1, 316, 317, 318, -1, -1, 321, 322, 323, + -1, -1, -1, -1, -1, -1, 330, 331, -1, 333, + 334, 0, 336, 337, 338, -1, -1, -1, 342, 257, + -1, -1, -1, 261, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 272, -1, -1, -1, 362, 277, + -1, -1, -1, 281, 368, 369, 284, -1, -1, -1, + -1, -1, -1, 377, 0, -1, -1, -1, 296, 297, + -1, -1, -1, 301, 302, -1, -1, -1, -1, 307, + -1, 309, 310, 311, 312, -1, -1, -1, -1, 317, + -1, -1, 257, 321, -1, 323, 261, -1, -1, -1, + -1, -1, -1, -1, 418, 333, -1, 272, 336, -1, + 338, -1, 277, -1, 342, -1, 281, -1, -1, 284, + -1, -1, -1, -1, -1, -1, -1, 0, -1, -1, + -1, 296, 297, -1, 362, -1, 301, 302, -1, 367, + 368, 369, 307, -1, 309, 310, 311, 312, -1, -1, + -1, -1, 317, -1, -1, -1, 321, -1, 323, -1, + -1, 257, -1, -1, -1, 261, -1, -1, 333, -1, + 335, 336, -1, 338, 0, -1, 272, 342, -1, -1, + -1, 277, -1, -1, -1, 281, -1, -1, 284, -1, + -1, -1, -1, -1, -1, -1, -1, 362, -1, -1, + 296, 297, -1, -1, 369, 301, 302, -1, -1, -1, + -1, 307, -1, 309, 310, 311, 312, -1, -1, -1, + -1, 317, -1, -1, -1, 321, -1, 323, -1, -1, + -1, -1, -1, -1, -1, 257, -1, 333, -1, 261, + 336, 0, 338, -1, -1, -1, 342, -1, -1, -1, + 272, -1, -1, -1, -1, 277, -1, -1, -1, 281, + -1, -1, 284, -1, -1, -1, 362, -1, -1, -1, + -1, -1, 368, 369, 296, 297, -1, -1, 257, 301, + 302, -1, 261, -1, 0, 307, -1, 309, 310, 311, + 312, -1, -1, 272, -1, 317, -1, -1, 277, 321, + -1, 323, 281, -1, -1, 284, -1, -1, -1, -1, + -1, 333, -1, -1, 336, -1, 338, 296, 297, -1, + 342, 257, 301, 302, -1, 261, -1, 0, 307, -1, + 309, 310, 311, 312, -1, -1, 272, -1, 317, -1, + 362, 277, 321, -1, 323, 281, 368, 369, 284, -1, + -1, -1, -1, -1, 333, -1, -1, 336, -1, 338, + 296, 297, -1, 342, -1, 301, 302, -1, -1, -1, + -1, 307, -1, 309, 310, 311, 312, -1, -1, -1, + -1, 317, -1, 362, 257, 321, -1, 323, 261, -1, + 369, -1, -1, -1, -1, -1, -1, 333, -1, 272, + 336, -1, 338, -1, 277, -1, 342, -1, 281, -1, + -1, 284, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 296, 297, -1, 362, -1, 301, 302, + -1, 257, -1, -1, 307, 261, 309, 310, 311, 312, + -1, -1, -1, -1, 317, -1, 272, -1, 321, -1, + 323, 277, -1, -1, -1, 281, -1, -1, 284, -1, + 333, -1, -1, 336, -1, 338, -1, -1, -1, 342, + 296, 297, -1, -1, -1, 301, 302, -1, -1, -1, + -1, 307, -1, 309, 310, 311, 312, -1, -1, 362, + -1, 317, -1, -1, -1, 321, -1, 323, 257, -1, + -1, -1, 261, -1, -1, -1, -1, 333, -1, -1, + 336, -1, 338, 272, -1, -1, 342, -1, 277, -1, + -1, -1, 281, -1, -1, 284, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 362, 296, 297, -1, -1, 257, 301, 302, -1, 261, -1, -1, 307, -1, 309, 310, 311, 312, -1, -1, 272, -1, 317, -1, -1, 277, 321, -1, 323, 281, -1, -1, 284, -1, - -1, -1, -1, -1, 333, -1, 418, 336, -1, 338, + -1, -1, -1, -1, 333, -1, -1, 336, -1, 338, 296, 297, -1, 342, 257, 301, 302, -1, 261, -1, -1, 307, -1, 309, 310, 311, 312, -1, -1, 272, - -1, 317, -1, 362, 277, 321, -1, 323, 281, 368, - 369, 284, -1, -1, -1, -1, -1, 333, -1, -1, + -1, 317, -1, 362, 277, 321, -1, 323, 281, -1, + -1, 284, -1, -1, -1, -1, -1, 333, -1, -1, 336, -1, 338, 296, 297, -1, 342, -1, 301, 302, -1, -1, -1, -1, 307, -1, 309, 310, 311, 312, -1, -1, -1, -1, 317, -1, 362, -1, 321, -1, 323, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 333, -1, -1, 336, 257, 338, -1, -1, 261, 342, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 272, - -1, -1, -1, -1, 277, -1, -1, -1, 281, 362, - -1, 284, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 296, 297, -1, -1, 257, 301, 302, - -1, 261, -1, -1, 307, -1, 309, 310, 311, 312, - -1, -1, 272, -1, 317, -1, -1, 277, 321, -1, - 323, 281, -1, -1, 284, -1, -1, -1, -1, -1, - 333, -1, -1, 336, -1, 338, 296, 297, -1, 342, - 257, 301, 302, -1, 261, -1, -1, 307, -1, 309, - 310, 311, 312, -1, -1, 272, -1, 317, -1, 362, - 277, 321, -1, 323, 281, -1, -1, 284, -1, -1, - -1, -1, -1, 333, -1, -1, 336, -1, 338, 296, - 297, -1, 342, 257, 301, 302, -1, 261, -1, -1, - 307, -1, 309, 310, 311, 312, -1, -1, 272, -1, - 317, -1, 362, 277, 321, -1, 323, 281, -1, -1, - 284, -1, -1, -1, -1, -1, 333, -1, -1, 336, - -1, 338, 296, 297, -1, 342, -1, 301, 302, -1, - -1, -1, -1, 307, -1, 309, 310, 311, 312, -1, - -1, -1, -1, 317, -1, 362, -1, 321, -1, 323, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 333, - -1, 256, 336, -1, 338, -1, -1, -1, 342, 264, - 265, 266, 267, -1, -1, 270, 271, -1, 273, 274, - 275, 276, 277, 278, 279, -1, -1, -1, 362, -1, - 285, -1, 287, 288, 289, 290, 291, 292, -1, -1, - 295, -1, -1, -1, 299, 300, -1, 302, 303, 304, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 314, - -1, 316, -1, 318, 319, -1, -1, 322, -1, 324, - 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, - 335, -1, 337, -1, -1, 340, 341, -1, 256, 344, - 345, -1, -1, -1, 262, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 359, 360, 361, 362, 363, -1, - -1, -1, 367, -1, -1, -1, 371, -1, -1, -1, - -1, 376, 377, 378, 379, 380, -1, -1, -1, 384, - 298, 386, -1, -1, -1, -1, -1, 392, 393, -1, + 333, -1, 256, 336, -1, 338, -1, -1, -1, 342, + 264, 265, 266, 267, -1, -1, 270, 271, -1, 273, + 274, 275, 276, 277, 278, 279, -1, -1, -1, 362, + -1, 285, -1, 287, 288, 289, 290, 291, 292, -1, + -1, 295, -1, -1, -1, 299, 300, -1, 302, 303, + 304, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 314, -1, 316, -1, 318, 319, -1, -1, 322, -1, + 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, + 334, 335, -1, 337, -1, -1, 340, 341, -1, 256, + 344, 345, -1, -1, -1, 262, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 359, 360, 361, 362, 363, + -1, -1, -1, 367, -1, -1, -1, 371, -1, -1, + -1, -1, 376, 377, 378, 379, 380, -1, -1, -1, + 384, 298, 386, -1, -1, -1, -1, -1, 392, 393, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 256, -1, -1, -1, -1, -1, - 262, -1, 417, 418, 419, 420, -1, -1, -1, -1, - -1, 339, -1, -1, 429, -1, 344, -1, 346, 347, + -1, -1, -1, -1, -1, 256, -1, -1, -1, -1, + -1, 262, -1, 417, 418, 419, 420, -1, -1, -1, + -1, -1, 339, -1, -1, 429, -1, 344, -1, 346, + 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, + 357, -1, -1, -1, -1, -1, 363, 298, -1, -1, + -1, 368, 369, 370, 371, 372, 373, 374, 375, 376, + -1, 378, 379, -1, 381, 382, 383, 384, 385, 386, + 387, 388, 389, 390, -1, 392, 393, 394, 395, 396, + 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, + 407, 408, 409, 410, 411, 412, 413, 414, 256, -1, + -1, 418, -1, 420, 262, -1, 423, -1, -1, -1, + -1, -1, 429, -1, -1, -1, -1, 368, -1, -1, + 371, -1, 373, 374, -1, -1, -1, 378, 379, -1, + -1, 382, 383, 384, 385, 386, 387, 388, 389, 390, + 298, 392, 393, 394, 395, 396, 397, 398, 399, 400, + 401, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, 412, 413, -1, -1, -1, -1, -1, -1, 420, + -1, -1, 423, -1, -1, -1, -1, -1, 429, -1, + -1, 339, -1, -1, -1, -1, 344, -1, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, - -1, -1, -1, -1, -1, 363, 298, -1, -1, -1, - 368, 369, 370, 371, 372, 373, 374, 375, 376, -1, + -1, -1, -1, -1, -1, 363, -1, -1, -1, -1, + 368, 369, 370, 371, 372, 373, 374, 375, 376, 256, 378, 379, -1, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, -1, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, -1, 256, -1, -1, 418, -1, 420, 262, -1, 423, -1, -1, -1, -1, - -1, 429, -1, -1, -1, -1, 368, -1, -1, 371, - -1, 373, 374, -1, -1, -1, 378, 379, -1, -1, - 382, 383, 384, 385, 386, 387, 388, 389, 390, 298, - 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, + -1, 429, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, 298, + -1, -1, 339, -1, -1, -1, -1, 344, -1, 346, + 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 412, 413, -1, -1, -1, -1, -1, -1, 420, -1, - -1, 423, -1, -1, -1, -1, -1, 429, -1, 285, + -1, 368, -1, 370, -1, 372, -1, 374, 375, 376, 339, -1, -1, -1, -1, 344, -1, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 367, 368, - 369, 370, 371, 372, 373, 374, 375, 376, 256, 378, - 379, 327, 381, 382, 383, 384, 385, 386, 387, 388, - 389, 390, -1, 392, 393, 394, 395, 396, 397, 398, + 369, 370, 371, 372, 373, 374, 375, 376, -1, 378, + 379, -1, 381, 382, 383, 384, 385, 386, 387, 388, + 389, 390, 429, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, - 409, 410, 411, 412, 413, -1, 256, -1, -1, -1, - -1, 420, 262, -1, -1, -1, -1, -1, -1, -1, - 429, 377, 378, 379, 380, -1, 382, 383, 384, 385, - 386, 387, 388, 389, -1, -1, 392, 393, 394, 395, - 396, 397, 398, 399, -1, -1, -1, -1, 298, -1, - -1, 339, -1, -1, -1, -1, 344, -1, 346, 347, - 348, 349, 350, 351, 352, 353, 354, 355, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 368, -1, 370, -1, 372, -1, 374, 375, 376, 339, + 409, 410, 411, 412, 413, -1, 256, 256, -1, -1, + -1, 420, 262, -1, -1, -1, 265, -1, 267, -1, + 429, 270, -1, -1, -1, -1, 275, -1, -1, -1, + 279, -1, -1, -1, -1, -1, -1, -1, -1, 288, + -1, -1, -1, -1, -1, -1, 295, -1, 298, -1, + -1, 300, -1, -1, -1, 304, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 316, -1, 318, + -1, -1, -1, 322, -1, -1, -1, 256, -1, -1, + -1, 330, 331, 262, -1, 334, -1, -1, 337, 339, -1, -1, -1, -1, 344, -1, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 367, 368, -1, + -1, -1, -1, -1, 363, -1, -1, 367, 368, 298, 370, 371, 372, 373, 374, 375, 376, -1, 378, 379, -1, 381, 382, 383, 384, 385, 386, 387, 388, 389, - 390, 429, 392, 393, 394, 395, 396, 397, 398, 399, + 390, -1, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, - 410, 411, 412, 413, -1, 256, 256, -1, -1, -1, - 420, 262, -1, 423, -1, 265, -1, 267, -1, 429, - 270, -1, -1, -1, -1, 275, -1, -1, -1, 279, - -1, -1, -1, -1, -1, -1, -1, -1, 288, -1, - -1, -1, -1, -1, -1, 295, -1, 298, -1, -1, - 300, -1, -1, -1, 304, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 316, -1, 318, -1, - -1, -1, 322, -1, -1, -1, -1, -1, -1, -1, - 330, 331, -1, -1, 334, -1, -1, 337, 339, -1, - -1, -1, -1, 344, -1, 346, 347, 348, 349, 350, + 410, 411, 412, 413, -1, 256, -1, -1, -1, 418, + 420, 262, -1, 423, -1, -1, -1, -1, -1, 429, + -1, -1, -1, -1, 363, -1, -1, -1, -1, 368, + 369, -1, 371, 372, 373, 374, -1, 376, -1, 378, + 379, -1, 381, 382, 383, 384, 385, 298, 387, 388, + 389, 390, -1, 392, 393, 394, 395, 396, 397, 398, + 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, + 409, 410, 411, 412, 413, -1, -1, -1, -1, 418, + -1, 420, -1, -1, 423, -1, -1, -1, 339, -1, + 429, -1, -1, 344, -1, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, -1, -1, -1, -1, - -1, -1, -1, 363, -1, -1, -1, 368, -1, 370, + -1, -1, -1, -1, -1, -1, -1, 368, -1, 370, 371, 372, 373, 374, 375, 376, -1, 378, 379, -1, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, -1, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, - 411, 412, 413, -1, 256, 256, -1, -1, 418, 420, + 411, 412, 413, -1, 256, 256, -1, -1, -1, 420, 262, -1, 423, -1, 265, -1, 267, -1, 429, 270, -1, -1, -1, -1, 275, -1, -1, -1, 279, -1, -1, -1, -1, -1, -1, -1, -1, 288, -1, -1, @@ -11927,27 +13293,27 @@ void case_982() 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, -1, -1, -1, -1, 418, -1, 420, -1, -1, 423, -1, 418, -1, -1, -1, 429, -1, -1, 339, -1, - -1, -1, -1, 344, -1, 346, 347, 348, 349, 350, + -1, -1, 256, 344, -1, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 368, -1, 370, -1, 372, -1, 374, 375, 376, -1, 378, 379, -1, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, - 261, -1, -1, 394, 395, 396, 397, 398, 399, 400, + -1, -1, -1, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, - 411, 256, 413, 284, -1, -1, -1, 262, -1, -1, - -1, -1, -1, -1, -1, -1, 297, -1, 429, -1, - -1, 302, -1, -1, 305, -1, 307, -1, 309, 310, - 311, 312, -1, -1, -1, -1, 317, -1, -1, -1, - 321, -1, -1, 298, 325, -1, -1, -1, -1, -1, - -1, -1, 333, -1, -1, 336, -1, 338, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 256, + 411, 256, 413, -1, -1, -1, -1, 262, -1, -1, + -1, -1, -1, -1, -1, 339, -1, -1, 429, -1, + 344, -1, 346, 347, 348, 349, 350, 351, 352, 353, + 354, 355, 356, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 298, 368, -1, 370, -1, 372, -1, + 374, 375, 376, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 390, -1, -1, 256, -1, -1, -1, -1, -1, 262, -1, -1, -1, -1, - -1, 362, -1, -1, 339, -1, -1, -1, -1, 344, + -1, -1, -1, -1, 339, -1, -1, -1, -1, 344, -1, 346, 347, 348, 349, 350, 351, 352, 353, 354, - 355, 356, -1, -1, -1, -1, -1, -1, -1, -1, + 355, 356, -1, -1, -1, 429, -1, -1, -1, -1, -1, 298, -1, 368, -1, 370, -1, 372, -1, 374, 375, 376, -1, 378, 379, -1, -1, 382, 383, 384, - 385, 386, 387, 388, 389, 390, -1, 418, -1, 394, + 385, 386, 387, 388, 389, 390, -1, -1, -1, 394, 395, 396, 397, 398, 399, 400, 401, -1, -1, -1, -1, -1, 339, -1, -1, -1, -1, 344, 413, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, @@ -11964,166 +13330,178 @@ void case_982() 353, 354, 355, 356, -1, -1, -1, -1, -1, -1, -1, -1, -1, 298, -1, 368, -1, 370, -1, 372, -1, 374, 375, 376, -1, 378, 379, -1, -1, 382, - 383, 384, 385, -1, -1, -1, 389, 390, -1, 256, + 383, 384, 385, -1, -1, -1, 389, 390, -1, -1, -1, 394, 395, 396, 397, 398, 399, 400, 401, -1, -1, -1, -1, -1, 339, -1, -1, -1, -1, 344, 413, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, -1, -1, -1, -1, 429, -1, -1, -1, -1, -1, -1, 368, -1, 370, -1, 372, -1, 374, 375, 376, -1, 378, 379, -1, -1, 382, 383, 384, - 385, -1, -1, -1, 389, 390, -1, 256, -1, 394, - 395, 396, 397, 398, 399, 400, 401, -1, -1, -1, - -1, -1, 339, -1, -1, -1, -1, 344, 413, 346, - 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, - -1, -1, -1, -1, 429, -1, -1, -1, -1, -1, - -1, 368, -1, 370, -1, 372, -1, 374, 375, 376, - -1, -1, -1, -1, -1, 382, 383, 384, 385, -1, - -1, -1, 389, 390, -1, 256, -1, 394, 395, 396, - 397, 398, 399, 400, 401, -1, -1, -1, -1, -1, - 339, -1, -1, -1, -1, 344, 413, 346, 347, 348, - 349, 350, 351, 352, 353, 354, 355, 356, -1, -1, - -1, -1, 429, -1, -1, -1, -1, -1, -1, 368, - -1, 370, -1, 372, -1, 374, 375, 376, -1, -1, - -1, -1, -1, 382, 383, 384, 385, -1, -1, -1, - 389, 390, -1, 256, -1, 394, 395, 396, 397, 398, - 399, 400, 401, -1, -1, -1, -1, -1, 339, -1, - -1, -1, -1, 344, 413, 346, 347, 348, 349, 350, - 351, 352, 353, 354, 355, 356, -1, -1, -1, -1, - 429, -1, -1, -1, -1, -1, -1, 368, -1, 370, - -1, 372, -1, 374, 375, 376, -1, -1, -1, -1, - -1, 382, 383, 384, 385, -1, -1, -1, 389, 390, - -1, 256, -1, 394, 395, 396, 397, 398, 399, 400, - 401, -1, -1, -1, -1, -1, 339, -1, -1, -1, - -1, 344, 413, 346, 347, 348, 349, 350, 351, 352, - 353, 354, 355, 356, -1, -1, -1, -1, 429, -1, - -1, -1, -1, -1, -1, 368, -1, 370, -1, 372, - -1, 374, 375, 376, -1, -1, -1, -1, -1, 382, - 383, 384, 385, -1, -1, -1, 389, 390, -1, 256, - -1, -1, -1, 396, 397, 398, 399, 400, 401, -1, - -1, -1, -1, -1, 339, -1, -1, -1, -1, 344, - 413, 346, 347, 348, 349, 350, 351, 352, 353, 354, - 355, 356, -1, -1, -1, -1, 429, -1, -1, -1, - -1, -1, -1, 368, -1, 370, -1, 372, -1, 374, - 375, 376, -1, -1, -1, -1, -1, 382, 383, 384, - 385, -1, -1, -1, 389, 390, -1, 256, -1, -1, - -1, 396, 397, 398, 399, 400, 401, -1, -1, -1, - -1, -1, 339, -1, -1, -1, -1, 344, 413, 346, - 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, - -1, -1, -1, -1, 429, -1, -1, -1, -1, -1, - -1, 368, -1, 370, -1, 372, -1, 374, 375, 376, - -1, -1, -1, -1, -1, 382, 383, 384, 385, -1, - -1, -1, 389, 390, -1, 256, -1, -1, -1, 396, - 397, 398, 399, 400, 401, -1, -1, -1, -1, -1, - 339, -1, -1, -1, -1, 344, 413, 346, 347, 348, - 349, 350, 351, 352, 353, 354, 355, 356, -1, -1, - -1, -1, 429, -1, -1, -1, -1, -1, -1, 368, - -1, 370, -1, 372, -1, 374, 375, 376, -1, -1, - -1, -1, -1, 382, 383, 384, 385, -1, -1, -1, - 389, 390, -1, 256, -1, -1, -1, 396, 397, 398, - 399, 400, 401, -1, -1, -1, -1, -1, 339, -1, - -1, -1, -1, 344, 413, 346, 347, 348, 349, 350, - 351, 352, 353, 354, 355, 356, -1, -1, -1, -1, - 429, -1, -1, -1, -1, -1, -1, 368, -1, 370, - -1, 372, -1, 374, 375, 376, -1, -1, -1, -1, - -1, 382, 383, 384, 385, -1, -1, -1, 389, 390, - -1, 256, -1, -1, -1, 396, 397, 398, 399, 400, - 401, -1, -1, -1, -1, -1, 339, -1, -1, -1, - -1, 344, 413, 346, 347, 348, 349, 350, 351, 352, - 353, 354, 355, 356, -1, -1, -1, -1, 429, -1, - -1, -1, -1, -1, -1, 368, -1, 370, -1, 372, - -1, 374, 375, 376, -1, -1, -1, -1, -1, -1, - -1, 384, 385, -1, -1, -1, 389, 390, -1, 256, - -1, -1, -1, -1, -1, 398, 399, 400, 401, -1, - -1, -1, -1, -1, 339, -1, -1, -1, -1, 344, - 413, 346, 347, 348, 349, 350, 351, 352, 353, 354, - 355, 356, -1, -1, -1, -1, 429, -1, -1, -1, - -1, -1, -1, 368, -1, 370, -1, 372, -1, 374, - 375, 376, -1, -1, -1, -1, -1, -1, -1, 384, - 385, -1, -1, -1, 389, 390, -1, 256, -1, -1, - -1, -1, -1, 398, 399, 400, 401, -1, -1, -1, - -1, -1, 339, -1, -1, -1, -1, 344, 413, 346, - 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, - -1, -1, -1, -1, 429, -1, -1, -1, -1, -1, - -1, 368, -1, 370, -1, 372, -1, 374, 375, 376, - -1, -1, -1, -1, -1, -1, -1, 384, 385, -1, - -1, -1, 389, 390, -1, 256, -1, -1, -1, -1, - -1, 398, 399, 400, 401, -1, -1, -1, -1, -1, - 339, -1, -1, -1, -1, 344, 413, 346, 347, 348, - 349, 350, 351, 352, 353, 354, 355, 356, -1, -1, - -1, -1, 429, -1, -1, -1, -1, -1, -1, 368, - -1, 370, -1, 372, -1, 374, 375, 376, -1, -1, - -1, -1, -1, -1, -1, 384, 385, -1, -1, -1, - 389, 390, -1, 256, -1, -1, -1, -1, -1, -1, - -1, 400, 401, -1, -1, -1, -1, -1, 339, -1, - -1, -1, -1, 344, 413, 346, 347, 348, 349, 350, - 351, 352, 353, 354, 355, 356, -1, -1, -1, -1, - 429, -1, -1, -1, -1, -1, -1, 368, -1, 370, - -1, 372, -1, 374, 375, 376, -1, -1, -1, -1, - -1, -1, -1, 384, 385, -1, -1, -1, 389, 390, - -1, 256, -1, -1, -1, -1, -1, -1, -1, 400, - 401, -1, -1, -1, -1, -1, 339, -1, -1, -1, - -1, 344, 413, 346, 347, 348, 349, 350, 351, 352, - 353, 354, 355, 356, -1, -1, -1, -1, 429, -1, - -1, -1, -1, -1, -1, 368, -1, 370, -1, 372, - -1, 374, 375, 376, -1, -1, -1, -1, -1, -1, - -1, -1, 385, -1, -1, -1, 389, 390, -1, 256, - -1, -1, -1, -1, -1, -1, -1, 400, 401, -1, - -1, -1, -1, -1, 339, -1, -1, -1, -1, 344, - 413, 346, 347, 348, 349, 350, 351, 352, 353, 354, - 355, 356, -1, -1, -1, -1, 429, -1, -1, -1, - -1, -1, -1, 368, -1, 370, -1, 372, -1, 374, - 375, 376, -1, -1, -1, -1, -1, -1, -1, -1, - 385, -1, -1, -1, 389, 390, -1, 256, -1, -1, - -1, -1, -1, -1, -1, 400, 401, -1, -1, -1, - -1, -1, 339, -1, -1, -1, -1, 344, 413, 346, - 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, - -1, -1, -1, -1, 429, -1, -1, -1, -1, -1, - -1, 368, -1, 370, -1, 372, -1, 374, 375, 376, - -1, -1, -1, -1, -1, -1, -1, -1, 385, -1, - -1, -1, -1, 390, -1, 256, -1, -1, -1, -1, - -1, -1, -1, 400, 401, -1, -1, -1, -1, -1, - 339, -1, -1, -1, -1, 344, 413, 346, 347, 348, - 349, 350, 351, 352, 353, 354, 355, 356, -1, -1, - -1, -1, 429, -1, -1, -1, -1, -1, -1, 368, - -1, 370, -1, 372, -1, 374, 375, 376, -1, -1, - -1, -1, -1, -1, -1, -1, 385, -1, -1, -1, - -1, 390, -1, 256, -1, -1, -1, -1, -1, -1, - -1, 400, 401, -1, -1, -1, -1, -1, 339, -1, - -1, -1, -1, 344, 413, 346, 347, 348, 349, 350, - 351, 352, 353, 354, 355, 356, -1, -1, -1, -1, - 429, -1, -1, -1, -1, -1, -1, 368, -1, 370, - -1, 372, -1, 374, 375, 376, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 390, - -1, 256, -1, -1, -1, -1, -1, -1, -1, 400, - 401, -1, -1, -1, -1, -1, 339, -1, -1, -1, - -1, 344, 413, 346, 347, 348, 349, 350, 351, 352, - 353, 354, 355, 356, -1, -1, -1, -1, 429, -1, - -1, -1, -1, -1, -1, 368, -1, 370, -1, 372, - -1, 374, 375, 376, -1, -1, -1, 256, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 390, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 400, 401, -1, - -1, -1, -1, -1, 339, -1, -1, -1, -1, 344, - 413, 346, 347, 348, 349, 350, 351, 352, 353, 354, - 355, 356, -1, -1, -1, -1, 429, -1, -1, -1, - -1, -1, -1, 368, -1, 370, -1, 372, -1, 374, - 375, 376, -1, -1, -1, -1, 262, -1, -1, -1, - 266, -1, -1, -1, -1, 390, -1, -1, -1, -1, - 339, -1, -1, -1, -1, 344, 401, 346, 347, 348, - 349, 350, 351, 352, 353, 354, 355, 356, 413, -1, - -1, -1, 298, -1, -1, -1, -1, -1, -1, 368, - -1, 370, -1, 372, 429, 374, 375, 376, 314, -1, + 385, -1, -1, -1, 389, 390, -1, -1, -1, 394, + 395, 396, 397, 398, 399, 400, 401, -1, 256, -1, + 256, -1, -1, -1, -1, -1, 264, 265, 413, 267, + -1, -1, 270, 271, -1, -1, -1, 275, 276, 277, + -1, 279, -1, -1, 429, -1, -1, 285, -1, -1, + 288, -1, -1, -1, -1, -1, -1, 295, -1, -1, + -1, -1, 300, -1, 302, 303, 304, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, 316, -1, + 318, 319, -1, -1, 322, -1, -1, 325, -1, 327, + -1, 329, 330, 331, 332, -1, 334, -1, -1, -1, + -1, -1, -1, 339, 256, -1, -1, -1, 344, -1, + 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, + 356, 359, 360, 361, 362, 363, -1, -1, -1, -1, + -1, -1, 368, 371, 370, -1, 372, -1, 374, 375, + 376, -1, -1, -1, -1, -1, 382, 383, 384, 385, + -1, -1, -1, 389, 390, -1, -1, -1, 394, 395, + 396, 397, 398, 399, 400, 401, -1, -1, -1, -1, + -1, -1, 256, -1, -1, -1, -1, 413, -1, 417, + 418, -1, -1, -1, -1, -1, -1, 339, -1, -1, + 428, 429, 344, 429, 346, 347, 348, 349, 350, 351, + 352, 353, 354, 355, 356, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 368, -1, 370, -1, + 372, -1, 374, 375, 376, -1, -1, -1, -1, -1, + 382, 383, 384, 385, -1, -1, -1, 389, 390, -1, + 256, -1, 394, 395, 396, 397, 398, 399, 400, 401, + -1, -1, -1, -1, -1, 339, -1, -1, -1, -1, + 344, 413, 346, 347, 348, 349, 350, 351, 352, 353, + 354, 355, 356, -1, -1, -1, -1, 429, -1, -1, + -1, -1, -1, -1, 368, -1, 370, -1, 372, -1, + 374, 375, 376, -1, -1, -1, -1, -1, 382, 383, + 384, 385, -1, -1, -1, 389, 390, -1, 256, -1, + -1, -1, 396, 397, 398, 399, 400, 401, -1, -1, + -1, -1, -1, 339, -1, -1, -1, -1, 344, 413, + 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, + 356, -1, -1, -1, -1, 429, -1, -1, -1, -1, + -1, -1, 368, -1, 370, -1, 372, -1, 374, 375, + 376, -1, -1, -1, -1, -1, 382, 383, 384, 385, + -1, -1, -1, 389, 390, -1, 256, -1, -1, -1, + 396, 397, 398, 399, 400, 401, -1, -1, -1, -1, + -1, 339, -1, -1, -1, -1, 344, 413, 346, 347, + 348, 349, 350, 351, 352, 353, 354, 355, 356, -1, + -1, -1, -1, 429, -1, -1, -1, -1, -1, -1, + 368, -1, 370, -1, 372, -1, 374, 375, 376, -1, + -1, -1, -1, -1, 382, 383, 384, 385, -1, -1, + -1, 389, 390, -1, 256, -1, -1, -1, 396, 397, + 398, 399, 400, 401, -1, -1, -1, -1, -1, 339, + -1, -1, -1, -1, 344, 413, 346, 347, 348, 349, + 350, 351, 352, 353, 354, 355, 356, -1, -1, -1, + -1, 429, -1, -1, -1, -1, -1, -1, 368, -1, + 370, -1, 372, -1, 374, 375, 376, -1, -1, -1, + -1, -1, 382, 383, 384, 385, -1, -1, -1, 389, + 390, -1, 256, -1, -1, -1, 396, 397, 398, 399, + 400, 401, -1, -1, -1, -1, -1, 339, -1, -1, + -1, -1, 344, 413, 346, 347, 348, 349, 350, 351, + 352, 353, 354, 355, 356, -1, -1, -1, -1, 429, + -1, -1, -1, -1, -1, -1, 368, -1, 370, -1, + 372, -1, 374, 375, 376, -1, -1, -1, -1, -1, + 382, 383, 384, 385, -1, -1, -1, 389, 390, -1, + 256, -1, -1, -1, 396, 397, 398, 399, 400, 401, + -1, -1, -1, -1, -1, 339, -1, -1, -1, -1, + 344, 413, 346, 347, 348, 349, 350, 351, 352, 353, + 354, 355, 356, -1, -1, -1, -1, 429, -1, -1, + -1, -1, -1, -1, 368, -1, 370, -1, 372, -1, + 374, 375, 376, -1, -1, -1, -1, -1, -1, -1, + 384, 385, -1, -1, -1, 389, 390, -1, 256, -1, + -1, -1, -1, -1, 398, 399, 400, 401, -1, -1, + -1, -1, -1, 339, -1, -1, -1, -1, 344, 413, + 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, + 356, -1, -1, -1, -1, 429, -1, -1, -1, -1, + -1, -1, 368, -1, 370, -1, 372, -1, 374, 375, + 376, -1, -1, -1, -1, -1, -1, -1, 384, 385, + -1, -1, -1, 389, 390, -1, 256, -1, -1, -1, + -1, -1, 398, 399, 400, 401, -1, -1, -1, -1, + -1, 339, -1, -1, -1, -1, 344, 413, 346, 347, + 348, 349, 350, 351, 352, 353, 354, 355, 356, -1, + -1, -1, -1, 429, -1, -1, -1, -1, -1, -1, + 368, -1, 370, -1, 372, -1, 374, 375, 376, -1, + -1, -1, -1, -1, -1, -1, 384, 385, -1, -1, + -1, 389, 390, -1, 256, -1, -1, -1, -1, -1, + 398, 399, 400, 401, -1, -1, -1, -1, -1, 339, + -1, -1, -1, -1, 344, 413, 346, 347, 348, 349, + 350, 351, 352, 353, 354, 355, 356, -1, -1, -1, + -1, 429, -1, -1, -1, -1, -1, -1, 368, -1, + 370, -1, 372, -1, 374, 375, 376, -1, -1, -1, + -1, -1, -1, -1, 384, 385, -1, -1, -1, 389, + 390, -1, 256, -1, -1, -1, -1, -1, -1, -1, + 400, 401, -1, -1, -1, -1, -1, 339, -1, -1, + -1, -1, 344, 413, 346, 347, 348, 349, 350, 351, + 352, 353, 354, 355, 356, -1, -1, -1, -1, 429, + -1, -1, -1, -1, -1, -1, 368, -1, 370, -1, + 372, -1, 374, 375, 376, -1, -1, -1, -1, -1, + -1, -1, 384, 385, -1, -1, -1, 389, 390, -1, + 256, -1, -1, -1, -1, -1, -1, -1, 400, 401, + -1, -1, -1, -1, -1, 339, -1, -1, -1, -1, + 344, 413, 346, 347, 348, 349, 350, 351, 352, 353, + 354, 355, 356, -1, -1, -1, -1, 429, -1, -1, + -1, -1, -1, -1, 368, -1, 370, -1, 372, -1, + 374, 375, 376, -1, -1, -1, -1, -1, -1, -1, + -1, 385, -1, -1, -1, 389, 390, -1, 256, -1, + -1, -1, -1, -1, -1, -1, 400, 401, -1, -1, + -1, -1, -1, 339, -1, -1, -1, -1, 344, 413, + 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, + 356, -1, -1, -1, -1, 429, -1, -1, -1, -1, + -1, -1, 368, -1, 370, -1, 372, -1, 374, 375, + 376, -1, -1, -1, -1, -1, -1, -1, -1, 385, + -1, -1, -1, 389, 390, -1, 256, -1, -1, -1, + -1, -1, -1, -1, 400, 401, -1, -1, -1, -1, + -1, 339, -1, -1, -1, -1, 344, 413, 346, 347, + 348, 349, 350, 351, 352, 353, 354, 355, 356, -1, + -1, -1, -1, 429, -1, -1, -1, -1, -1, -1, + 368, -1, 370, -1, 372, -1, 374, 375, 376, -1, + -1, -1, -1, -1, -1, -1, -1, 385, -1, -1, + -1, -1, 390, -1, 256, -1, -1, -1, -1, -1, + -1, -1, 400, 401, -1, -1, -1, -1, -1, 339, + -1, -1, -1, -1, 344, 413, 346, 347, 348, 349, + 350, 351, 352, 353, 354, 355, 356, -1, -1, -1, + -1, 429, -1, -1, -1, -1, -1, -1, 368, -1, + 370, -1, 372, -1, 374, 375, 376, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 390, -1, 256, -1, -1, -1, -1, -1, -1, -1, + 400, 401, -1, -1, -1, -1, -1, 339, -1, -1, + -1, -1, 344, 413, 346, 347, 348, 349, 350, 351, + 352, 353, 354, 355, 356, -1, -1, -1, -1, 429, + -1, -1, -1, -1, -1, -1, 368, -1, 370, -1, + 372, -1, 374, 375, 376, -1, -1, -1, 256, -1, + -1, -1, -1, -1, -1, -1, -1, -1, 390, -1, + -1, -1, -1, -1, -1, -1, -1, -1, 400, 401, + -1, -1, -1, -1, -1, 339, -1, -1, -1, -1, + 344, 413, 346, 347, 348, 349, 350, 351, 352, 353, + 354, 355, 356, -1, -1, -1, -1, 429, -1, -1, + -1, -1, -1, -1, 368, -1, 370, -1, 372, -1, + 374, 375, 376, -1, -1, -1, -1, 262, -1, -1, + -1, 266, -1, -1, -1, -1, 390, -1, -1, -1, + -1, 339, -1, -1, -1, -1, 344, 401, 346, 347, + 348, 349, 350, 351, 352, 353, 354, 355, 356, 413, + -1, -1, -1, 298, -1, -1, -1, -1, -1, -1, + 368, -1, 370, -1, 372, 429, 374, 375, 376, 314, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 390, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 401, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 413, -1, -1, -1, -1, + -1, -1, 357, -1, -1, -1, -1, -1, 363, -1, + -1, 429, -1, 368, 369, -1, 371, -1, 373, -1, + 375, 376, -1, 378, 379, -1, 381, 382, 383, 384, + 385, 386, 387, 388, 389, 390, -1, 392, 393, 394, + 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, + 405, 406, 407, 408, 409, 410, 411, 412, 413, -1, + -1, 256, -1, 418, -1, 420, -1, -1, 423, 264, + 265, 266, 267, 268, 429, 270, 271, -1, 273, 274, + 275, 276, 277, 278, 279, -1, -1, -1, -1, -1, + 285, -1, 287, 288, 289, 290, 291, 292, -1, -1, + 295, -1, -1, -1, 299, 300, -1, 302, 303, 304, + -1, -1, -1, -1, -1, -1, -1, -1, -1, 314, + -1, 316, -1, 318, 319, -1, -1, 322, -1, 324, + 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, + 335, -1, 337, -1, -1, 340, 341, -1, -1, 344, + 345, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 359, 360, 361, 362, 363, -1, + -1, -1, 367, -1, -1, -1, 371, -1, -1, -1, + -1, 376, 377, 378, 379, 380, -1, -1, -1, 384, + -1, 386, -1, -1, -1, -1, -1, 392, 393, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 390, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, 401, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 413, -1, -1, -1, -1, -1, - -1, 357, -1, -1, -1, -1, -1, 363, -1, -1, - 429, -1, 368, 369, -1, 371, -1, 373, -1, 375, - 376, -1, 378, 379, -1, 381, 382, 383, 384, 385, - 386, 387, 388, 389, 390, -1, 392, 393, 394, 395, - 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, - 406, 407, 408, 409, 410, 411, 412, 413, -1, -1, - 256, -1, 418, -1, 420, -1, -1, 423, 264, 265, - 266, 267, -1, 429, 270, 271, -1, 273, 274, 275, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 256, -1, 417, 418, 419, 420, -1, 422, 264, 265, + 266, 267, -1, -1, 270, 271, -1, 273, 274, 275, 276, 277, 278, 279, -1, -1, -1, -1, -1, 285, -1, 287, 288, 289, 290, 291, 292, -1, -1, 295, -1, -1, -1, 299, 300, -1, 302, 303, 304, -1, @@ -12185,24 +13563,24 @@ void case_982() -1, 386, -1, -1, -1, -1, -1, 392, 393, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 256, -1, - -1, -1, 417, 418, 419, 420, 264, 265, 266, 267, - -1, -1, 270, 271, -1, 273, 274, 275, 276, 277, - 278, 279, -1, -1, -1, -1, -1, 285, -1, 287, - 288, 289, 290, 291, 292, -1, -1, 295, -1, -1, - -1, 299, 300, -1, 302, 303, 304, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 314, -1, 316, -1, - 318, 319, -1, -1, 322, -1, 324, 325, 326, 327, - 328, 329, 330, 331, 332, 333, 334, 335, -1, 337, - -1, -1, 340, 341, -1, -1, 344, 345, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 359, 360, 361, 362, 363, -1, -1, -1, 367, - -1, -1, -1, 371, -1, -1, -1, -1, 376, 377, + -1, -1, 417, 418, 419, 420, 264, 265, -1, 267, + -1, -1, 270, 271, -1, 256, -1, 275, 276, 277, + -1, 279, -1, -1, 265, -1, 267, 285, -1, 270, + 288, -1, -1, -1, 275, -1, -1, 295, 279, -1, + -1, -1, 300, -1, 302, 303, 304, 288, 306, -1, + -1, -1, -1, -1, 295, 313, -1, -1, 316, 300, + 318, 319, -1, 304, 322, -1, -1, 325, -1, 327, + -1, 329, 330, 331, 332, 316, 334, 318, -1, -1, + -1, 322, -1, 341, -1, -1, 344, 345, -1, 330, + 331, -1, -1, 334, -1, -1, 337, -1, -1, -1, + -1, 359, 360, 361, 362, 363, -1, -1, -1, -1, + -1, -1, -1, 371, -1, -1, 374, -1, -1, 377, 378, 379, 380, -1, -1, -1, 384, -1, 386, -1, -1, -1, -1, -1, 392, 393, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 256, -1, -1, -1, 417, 418, 419, 420, 264, 265, -1, 267, -1, -1, 270, - 271, -1, -1, -1, 275, 276, 277, -1, 279, -1, + 271, -1, 256, -1, 275, 276, 277, 418, 279, -1, -1, 265, -1, 267, 285, -1, 270, 288, -1, -1, -1, 275, -1, -1, 295, 279, -1, -1, -1, 300, -1, 302, 303, 304, 288, -1, -1, -1, -1, -1, @@ -12213,215 +13591,650 @@ void case_982() 334, -1, -1, 337, -1, -1, -1, -1, 359, 360, 361, 362, 363, -1, -1, -1, 367, 368, -1, -1, 371, -1, -1, -1, -1, -1, 377, 378, 379, 380, - -1, -1, -1, 384, -1, 386, -1, -1, 372, -1, + -1, -1, -1, 384, -1, 386, -1, -1, -1, -1, + -1, 392, 393, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 256, -1, -1, -1, 417, 418, 419, 420, + 264, 265, -1, 267, -1, -1, 270, 271, -1, -1, + -1, 275, 276, 277, 418, 279, -1, -1, 265, -1, + 267, 285, -1, 270, 288, -1, -1, -1, 275, -1, + -1, 295, 279, -1, -1, -1, 300, -1, 302, 303, + 304, 288, 306, -1, -1, -1, -1, -1, 295, 313, + -1, -1, 316, 300, 318, 319, -1, 304, 322, -1, + -1, 325, -1, 327, -1, 329, 330, 331, 332, 316, + 334, 318, -1, -1, -1, 322, -1, 341, -1, -1, + 344, 345, -1, 330, 331, -1, -1, 334, -1, -1, + 337, -1, -1, -1, -1, 359, 360, 361, 362, 363, + -1, -1, -1, -1, -1, -1, -1, 371, -1, -1, + -1, -1, -1, 377, 378, 379, 380, -1, -1, -1, + 384, -1, 386, -1, -1, 372, -1, -1, 392, 393, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, 256, + -1, -1, -1, 417, 418, 419, 420, 264, 265, -1, + 267, -1, -1, 270, 271, -1, -1, -1, 275, 276, + 277, 418, 279, -1, -1, 265, -1, 267, 285, -1, + 270, 288, -1, -1, -1, 275, -1, -1, 295, 279, + -1, -1, -1, 300, -1, 302, 303, 304, 288, -1, + -1, -1, -1, -1, -1, 295, -1, -1, -1, 316, + 300, 318, 319, 320, 304, 322, -1, -1, 325, -1, + 327, -1, 329, 330, 331, 332, 316, 334, 318, -1, + -1, -1, 322, -1, 341, -1, -1, 344, 345, -1, + 330, 331, -1, -1, 334, -1, -1, 337, -1, -1, + -1, -1, 359, 360, 361, 362, 363, -1, -1, -1, + 367, -1, -1, -1, 371, -1, -1, -1, -1, -1, + 377, 378, 379, 380, -1, -1, -1, 384, -1, 386, + 370, -1, -1, -1, -1, 392, 393, -1, -1, -1, + -1, -1, -1, 264, 265, -1, 267, -1, -1, 270, + 271, -1, -1, -1, 275, 276, 277, -1, 279, -1, + 417, 418, 419, 420, 285, -1, -1, 288, -1, -1, + -1, -1, -1, -1, 295, -1, -1, -1, 418, 300, + -1, 302, 303, 304, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 316, -1, 318, 319, -1, + -1, 322, -1, -1, 325, -1, 327, -1, 329, 330, + 331, 332, -1, 334, -1, -1, -1, -1, -1, -1, + 341, -1, -1, 344, 345, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, 359, 360, + 361, 362, 363, -1, -1, -1, 367, 368, -1, -1, + 371, -1, -1, -1, -1, -1, 377, 378, 379, 380, + -1, -1, -1, 384, -1, 386, -1, -1, -1, -1, + -1, 392, 393, -1, -1, -1, -1, -1, -1, 264, + 265, -1, 267, -1, -1, 270, 271, -1, -1, -1, + 275, 276, 277, -1, 279, -1, 417, 418, 419, 420, + 285, -1, -1, 288, -1, -1, -1, 428, -1, -1, + 295, -1, -1, -1, -1, 300, -1, 302, 303, 304, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, 316, -1, 318, 319, -1, -1, 322, -1, -1, + 325, -1, 327, -1, 329, 330, 331, 332, -1, 334, + -1, -1, -1, -1, -1, -1, 341, -1, -1, 344, + 345, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 359, 360, 361, 362, 363, -1, + -1, -1, 367, -1, -1, -1, 371, -1, -1, -1, + -1, -1, 377, 378, 379, 380, -1, -1, -1, 384, + -1, 386, -1, -1, -1, -1, -1, 392, 393, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 256, -1, 417, 418, 419, 420, -1, -1, 264, 265, + -1, 267, -1, 428, 270, 271, -1, -1, -1, 275, + 276, 277, -1, 279, -1, -1, -1, -1, -1, 285, + -1, -1, 288, -1, -1, -1, -1, -1, -1, 295, + -1, -1, -1, -1, 300, -1, 302, 303, 304, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 316, -1, 318, 319, -1, -1, 322, -1, -1, 325, + -1, 327, -1, 329, 330, 331, 332, -1, 334, -1, + -1, -1, -1, -1, -1, 341, -1, -1, 344, 345, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 359, 360, 361, 362, 363, -1, -1, + -1, 367, -1, -1, -1, 371, -1, -1, -1, -1, + -1, 377, 378, 379, 380, -1, -1, -1, 384, -1, + 386, -1, -1, -1, -1, -1, 392, 393, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, 256, + -1, 417, 418, 419, 420, 262, -1, 264, 265, -1, + 267, -1, -1, 270, 271, -1, -1, -1, 275, 276, + 277, -1, 279, -1, -1, -1, -1, -1, 285, -1, + -1, 288, -1, -1, -1, -1, -1, -1, 295, -1, + -1, 298, -1, 300, -1, 302, 303, 304, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, 316, + -1, 318, 319, -1, -1, 322, -1, -1, 325, -1, + 327, -1, 329, 330, 331, 332, -1, 334, -1, -1, + -1, -1, -1, -1, -1, -1, 343, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 359, 360, 361, 362, 363, -1, -1, -1, + -1, -1, -1, -1, 371, -1, 373, -1, -1, -1, + 377, 378, 379, 380, 381, -1, -1, 384, -1, 386, + 256, -1, -1, -1, -1, 392, 393, -1, 264, 265, + -1, 267, -1, -1, 270, 271, -1, -1, -1, 275, + 276, 277, -1, 279, -1, -1, -1, -1, -1, 285, + 417, 418, 288, 420, -1, -1, -1, -1, -1, 295, + -1, -1, -1, -1, 300, -1, 302, 303, 304, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 316, -1, 318, 319, -1, -1, 322, -1, -1, 325, + -1, 327, -1, 329, 330, 331, 332, -1, 334, -1, + -1, -1, -1, -1, -1, 341, -1, -1, 344, 345, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 359, 360, 361, 362, 363, -1, -1, + -1, -1, 368, -1, -1, 371, -1, -1, -1, -1, + -1, 377, 378, 379, 380, -1, -1, -1, 384, -1, + 386, -1, -1, -1, -1, -1, 392, 393, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 256, -1, -1, + -1, 417, 418, 419, 420, 264, 265, -1, 267, -1, + -1, 270, 271, -1, -1, -1, 275, 276, 277, -1, + 279, -1, -1, 265, -1, 267, 285, -1, 270, 288, + -1, -1, -1, 275, -1, -1, 295, 279, -1, -1, + -1, 300, -1, 302, 303, 304, 288, -1, -1, -1, + -1, -1, -1, 295, -1, -1, -1, 316, 300, 318, + 319, -1, 304, 322, -1, -1, 325, -1, 327, -1, + 329, 330, 331, 332, 316, 334, 318, -1, -1, -1, + 322, -1, 341, -1, -1, 344, 345, -1, 330, 331, + -1, -1, 334, -1, -1, 337, -1, -1, -1, -1, + 359, 360, 361, 362, 363, -1, -1, -1, -1, 368, + -1, -1, 371, -1, -1, -1, -1, -1, 377, 378, + 379, 380, -1, -1, -1, 384, -1, 386, -1, -1, + -1, -1, -1, 392, 393, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 256, -1, -1, -1, 417, 418, + 419, 420, 264, 265, -1, 267, -1, -1, 270, 271, + -1, -1, -1, 275, 276, 277, 418, 279, -1, -1, + 265, -1, 267, 285, -1, 270, 288, -1, -1, -1, + 275, -1, -1, 295, 279, -1, -1, -1, 300, -1, + 302, 303, 304, 288, -1, -1, -1, -1, -1, -1, + 295, -1, -1, -1, 316, 300, 318, 319, -1, 304, + 322, -1, -1, 325, -1, 327, -1, 329, 330, 331, + 332, 316, 334, 318, -1, -1, -1, 322, -1, 341, + -1, -1, 344, 345, -1, 330, 331, -1, -1, 334, + -1, -1, 337, -1, -1, -1, -1, 359, 360, 361, + 362, 363, -1, -1, -1, -1, -1, -1, -1, 371, + -1, -1, -1, -1, -1, 377, 378, 379, 380, -1, + -1, -1, 384, -1, 386, -1, -1, -1, -1, -1, + 392, 393, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, 256, -1, -1, -1, 417, 418, 419, 420, 264, + 265, -1, 267, -1, -1, 270, 271, -1, -1, -1, + 275, 276, 277, 418, 279, -1, -1, -1, -1, -1, + 285, -1, -1, 288, -1, -1, -1, -1, -1, -1, + 295, -1, -1, -1, -1, 300, -1, 302, 303, 304, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, 316, -1, 318, 319, -1, -1, 322, -1, -1, + 325, -1, 327, -1, 329, 330, 331, 332, -1, 334, + -1, -1, -1, -1, -1, -1, 341, -1, -1, 344, + 345, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 359, 360, 361, 362, 363, -1, + -1, -1, -1, -1, -1, -1, 371, -1, -1, -1, + -1, -1, 377, 378, 379, 380, -1, -1, -1, 384, + -1, 386, -1, -1, -1, -1, -1, 392, 393, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 256, -1, 417, 418, 419, 420, 262, -1, 264, 265, + -1, 267, -1, -1, 270, 271, -1, -1, -1, 275, + 276, 277, -1, 279, -1, -1, -1, -1, -1, 285, + -1, -1, 288, -1, -1, -1, -1, -1, -1, 295, + -1, -1, 298, -1, 300, -1, 302, 303, 304, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 316, -1, 318, 319, -1, -1, 322, -1, -1, 325, + -1, 327, -1, 329, 330, 331, 332, -1, 334, -1, + -1, -1, -1, -1, -1, -1, -1, 343, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 359, 360, 361, 362, 363, -1, -1, + -1, -1, -1, -1, -1, 371, -1, 373, -1, -1, + -1, 377, 378, 379, 380, -1, -1, -1, 384, -1, + 386, 256, -1, -1, -1, -1, 392, 393, -1, 264, + 265, -1, 267, -1, -1, 270, 271, -1, -1, -1, + 275, 276, 277, -1, 279, -1, -1, -1, -1, -1, + 285, 417, 418, 288, 420, -1, -1, -1, -1, -1, + 295, -1, -1, -1, -1, 300, -1, 302, 303, 304, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, 316, -1, 318, 319, -1, -1, 322, -1, -1, + 325, -1, 327, -1, 329, 330, 331, 332, -1, 334, + -1, -1, -1, -1, -1, -1, 341, -1, -1, 344, + 345, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 359, 360, 361, 362, 363, -1, + -1, -1, -1, -1, -1, -1, 371, -1, -1, -1, + -1, -1, 377, 378, 379, 380, -1, -1, -1, 384, + -1, 386, -1, -1, -1, -1, -1, 392, 393, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, 256, -1, + -1, -1, 417, 418, 419, 420, 264, 265, -1, 267, + -1, -1, 270, 271, -1, -1, -1, 275, 276, 277, + -1, 279, -1, -1, 265, -1, 267, 285, -1, 270, + 288, -1, -1, -1, 275, -1, -1, 295, 279, -1, + -1, -1, 300, -1, 302, 303, 304, 288, -1, -1, + -1, -1, -1, -1, 295, -1, -1, -1, 316, 300, + 318, 319, -1, 304, 322, -1, -1, 325, -1, 327, + -1, 329, 330, 331, 332, 316, 334, 318, -1, -1, + -1, 322, -1, 341, -1, -1, 344, 345, -1, 330, + 331, -1, -1, 334, -1, -1, 337, -1, -1, -1, + -1, 359, 360, 361, 362, 363, -1, -1, -1, -1, + -1, -1, -1, 371, -1, -1, -1, -1, -1, 377, + 378, 379, 380, -1, -1, -1, 384, -1, 386, -1, + -1, -1, -1, -1, 392, 393, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 256, -1, -1, -1, 417, + 418, 419, 420, 264, 265, -1, 267, -1, -1, 270, + 271, -1, -1, -1, 275, 276, 277, 418, 279, -1, + -1, 265, -1, 267, 285, -1, 270, 288, -1, -1, + -1, 275, -1, -1, 295, 279, -1, -1, -1, 300, + -1, 302, 303, 304, 288, -1, -1, -1, -1, -1, + -1, 295, -1, -1, -1, 316, 300, 318, 319, -1, + 304, 322, -1, -1, 325, -1, 327, -1, 329, 330, + 331, 332, 316, 334, 318, -1, -1, -1, 322, -1, + 341, -1, -1, 344, 345, -1, 330, 331, -1, -1, + 334, -1, -1, 337, -1, -1, -1, -1, 359, 360, + 361, 362, 363, -1, -1, -1, -1, -1, -1, -1, + 371, -1, -1, -1, -1, -1, 377, 378, 379, 380, + -1, -1, -1, 384, -1, 386, -1, -1, -1, -1, -1, 392, 393, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, 256, -1, -1, -1, 417, 418, 419, 420, + -1, -1, 256, -1, -1, -1, 417, 418, 419, 420, + 264, 265, -1, 267, -1, -1, 270, 271, -1, -1, + -1, 275, 276, 277, 418, 279, -1, -1, 265, -1, + 267, 285, -1, 270, 288, -1, -1, -1, 275, -1, + -1, 295, 279, -1, -1, -1, 300, -1, 302, 303, + 304, 288, -1, -1, -1, -1, -1, -1, 295, -1, + -1, -1, 316, 300, 318, 319, -1, 304, 322, -1, + -1, 325, -1, 327, -1, 329, 330, 331, 332, 316, + 334, 318, -1, -1, -1, 322, -1, 341, -1, -1, + 344, 345, -1, 330, 331, -1, -1, 334, -1, -1, + 337, -1, -1, -1, -1, 359, 360, 361, 362, 363, + -1, -1, -1, -1, -1, -1, -1, 371, -1, -1, + -1, -1, -1, 377, 378, 379, 380, -1, -1, -1, + 384, -1, 386, -1, -1, -1, -1, -1, 392, 393, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, 256, + -1, -1, -1, 417, 418, 419, 420, 264, 265, -1, + 267, -1, -1, 270, 271, -1, -1, -1, 275, 276, + 277, 418, 279, -1, -1, -1, -1, -1, 285, -1, + -1, 288, -1, -1, -1, -1, -1, -1, 295, -1, + -1, -1, -1, 300, -1, 302, 303, 304, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, 316, + -1, 318, 319, -1, -1, 322, -1, -1, 325, -1, + 327, -1, 329, 330, 331, 332, -1, 334, -1, -1, + -1, -1, -1, -1, 341, -1, -1, 344, 345, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 359, 360, 361, 362, 363, -1, -1, -1, + -1, -1, -1, -1, 371, -1, -1, -1, -1, -1, + 377, 378, 379, 380, -1, -1, -1, 384, -1, 386, + -1, -1, -1, -1, -1, 392, 393, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, 256, -1, + 417, 418, 419, 420, 262, -1, 264, 265, -1, 267, + -1, -1, 270, 271, -1, -1, -1, 275, 276, 277, + -1, 279, -1, -1, -1, -1, -1, 285, -1, -1, + 288, -1, -1, -1, -1, -1, -1, 295, -1, -1, + 298, -1, 300, -1, 302, 303, 304, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, 316, -1, + 318, 319, -1, -1, 322, -1, -1, 325, -1, 327, + -1, 329, 330, 331, 332, -1, 334, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, 359, 360, 361, 362, 363, -1, -1, -1, -1, + -1, -1, -1, 371, -1, 373, -1, -1, -1, 377, + 378, 379, 380, -1, -1, -1, 384, -1, 386, 256, + -1, -1, -1, -1, 392, 393, -1, 264, 265, -1, + 267, -1, -1, 270, 271, -1, -1, -1, 275, 276, + 277, -1, 279, -1, -1, -1, -1, -1, 285, 417, + 418, 288, 420, -1, -1, -1, -1, -1, 295, -1, + -1, -1, -1, 300, -1, 302, 303, 304, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, 316, + -1, 318, 319, -1, -1, 322, -1, -1, 325, -1, + 327, -1, 329, 330, 331, 332, -1, 334, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 359, 360, 361, 362, 363, -1, -1, -1, + -1, -1, -1, -1, 371, -1, 373, -1, -1, -1, + 377, 378, 379, 380, -1, -1, -1, 384, -1, 386, + 256, -1, -1, -1, -1, 392, 393, -1, 264, 265, + -1, 267, -1, -1, 270, 271, -1, -1, -1, 275, + 276, 277, -1, 279, -1, -1, -1, -1, -1, 285, + 417, 418, 288, 420, -1, -1, -1, -1, -1, 295, + -1, -1, -1, -1, 300, -1, 302, 303, 304, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 316, -1, 318, 319, -1, -1, 322, -1, -1, 325, + -1, 327, -1, 329, 330, 331, 332, -1, 334, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 359, 360, 361, 362, 363, -1, -1, + -1, -1, -1, -1, -1, 371, -1, -1, -1, -1, + -1, 377, 378, 379, 380, -1, -1, -1, 384, -1, + 386, 256, -1, -1, -1, -1, 392, 393, -1, 264, + 265, -1, 267, -1, -1, 270, 271, -1, -1, -1, + 275, 276, 277, -1, 279, -1, -1, -1, -1, -1, + 285, 417, 418, 288, 420, -1, -1, -1, -1, -1, + 295, -1, -1, -1, -1, 300, -1, 302, 303, 304, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, 316, -1, 318, 319, -1, -1, 322, -1, -1, + 325, -1, 327, -1, 329, 330, 331, 332, -1, 334, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 359, 360, 361, 362, 363, -1, + -1, -1, -1, -1, -1, -1, 371, -1, -1, -1, + -1, -1, 377, 378, 379, 380, -1, -1, -1, 384, + -1, 386, 256, -1, -1, -1, -1, 392, 393, -1, 264, 265, -1, 267, -1, -1, 270, 271, -1, -1, - -1, 275, 276, 277, 418, 279, -1, -1, 265, -1, - 267, 285, -1, 270, 288, -1, -1, -1, 275, -1, - -1, 295, 279, -1, -1, -1, 300, -1, 302, 303, - 304, 288, 306, -1, -1, -1, -1, -1, 295, 313, - -1, -1, 316, 300, 318, 319, -1, 304, 322, -1, - -1, 325, -1, 327, -1, 329, 330, 331, 332, 316, - 334, 318, -1, -1, -1, 322, -1, 341, -1, -1, - 344, 345, -1, 330, 331, -1, -1, 334, -1, -1, - 337, -1, -1, -1, -1, 359, 360, 361, 362, 363, + -1, 275, 276, 277, -1, 279, -1, -1, -1, -1, + -1, 285, 417, 418, 288, 420, -1, -1, -1, -1, + -1, 295, -1, -1, -1, -1, 300, -1, 302, 303, + 304, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 316, -1, 318, 319, -1, -1, 322, -1, + -1, 325, -1, 327, -1, 329, 330, 331, 332, -1, + 334, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 359, 360, 361, 362, 363, -1, -1, -1, -1, -1, -1, -1, 371, -1, -1, -1, -1, -1, 377, 378, 379, 380, -1, -1, -1, - 384, -1, 386, 370, -1, -1, -1, -1, 392, 393, + 384, -1, 386, 256, -1, -1, -1, -1, 392, 393, + -1, 264, 265, -1, 267, -1, -1, 270, 271, -1, + -1, -1, 275, 276, 277, -1, 279, -1, -1, -1, + -1, -1, 285, 417, 418, 288, 420, -1, -1, -1, + -1, -1, 295, -1, -1, -1, -1, 300, -1, 302, + 303, 304, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 316, -1, 318, 319, -1, -1, 322, + -1, -1, 325, -1, 327, -1, 329, 330, 331, 332, + -1, 334, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 256, - -1, -1, -1, 417, 418, 419, 420, 264, 265, -1, - 267, -1, -1, 270, 271, -1, -1, -1, 275, 276, - 277, 418, 279, -1, -1, 265, -1, 267, 285, -1, - 270, 288, -1, -1, -1, 275, -1, -1, 295, 279, - -1, -1, -1, 300, -1, 302, 303, 304, 288, -1, - -1, -1, -1, -1, -1, 295, -1, -1, -1, 316, - 300, 318, 319, 320, 304, 322, -1, -1, 325, -1, - 327, -1, 329, 330, 331, 332, 316, 334, 318, -1, - -1, -1, 322, -1, 341, -1, -1, 344, 345, -1, - 330, 331, -1, -1, 334, -1, -1, 337, -1, -1, - -1, -1, 359, 360, 361, 362, 363, -1, -1, -1, - 367, -1, -1, -1, 371, -1, -1, -1, -1, -1, - 377, 378, 379, 380, -1, -1, -1, 384, -1, 386, - -1, -1, -1, -1, -1, 392, 393, -1, -1, -1, - -1, -1, -1, 264, 265, -1, 267, -1, -1, 270, + -1, -1, -1, -1, -1, -1, 359, 360, 361, 362, + 363, -1, -1, -1, -1, -1, -1, -1, 371, -1, + -1, -1, -1, -1, 377, 378, 379, 380, -1, -1, + -1, 384, -1, 386, 256, -1, -1, -1, -1, 392, + 393, -1, 264, 265, -1, 267, -1, -1, 270, 271, + -1, -1, -1, 275, 276, 277, -1, 279, -1, -1, + -1, -1, -1, 285, 417, 418, 288, 420, -1, -1, + -1, -1, -1, 295, -1, -1, -1, -1, 300, -1, + 302, 303, 304, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 316, -1, 318, 319, -1, -1, + 322, -1, -1, 325, -1, 327, -1, 329, 330, 331, + 332, -1, 334, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 359, 360, 361, + 362, 363, -1, -1, -1, -1, -1, -1, -1, 371, + -1, -1, -1, -1, -1, 377, 378, 379, 380, -1, + -1, -1, 384, -1, 386, 256, -1, -1, -1, -1, + 392, 393, -1, 264, 265, -1, 267, -1, -1, 270, 271, -1, -1, -1, 275, 276, 277, -1, 279, -1, - 417, 418, 419, 420, 285, -1, -1, 288, -1, -1, - -1, -1, -1, -1, 295, -1, -1, -1, 418, 300, + -1, -1, -1, -1, 285, 417, 418, 288, 420, -1, + -1, -1, -1, -1, 295, -1, -1, -1, -1, 300, -1, 302, 303, 304, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 316, -1, 318, 319, -1, -1, 322, -1, -1, 325, -1, 327, -1, 329, 330, 331, 332, -1, 334, -1, -1, -1, -1, -1, -1, - 341, -1, -1, 344, 345, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 359, 360, - 361, 362, 363, -1, -1, -1, 367, 368, -1, -1, + 361, 362, 363, -1, -1, -1, -1, -1, -1, -1, 371, -1, -1, -1, -1, -1, 377, 378, 379, 380, - -1, -1, -1, 384, -1, 386, -1, -1, -1, -1, - -1, 392, 393, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 384, -1, 386, 256, -1, -1, -1, + -1, 392, 393, -1, 264, 265, -1, 267, -1, -1, + 270, 271, -1, -1, -1, 275, 276, 277, -1, 279, + -1, -1, -1, -1, -1, 285, 417, 418, 288, 420, + -1, -1, -1, -1, -1, 295, -1, -1, -1, -1, + 300, -1, 302, 303, 304, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 316, -1, 318, 319, + -1, -1, 322, -1, -1, 325, -1, 327, -1, 329, + 330, 331, 332, -1, 334, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 256, -1, 417, 418, 419, 420, - -1, -1, 264, 265, -1, 267, -1, 428, 270, 271, - -1, -1, -1, 275, 276, 277, -1, 279, -1, -1, - 265, -1, 267, 285, -1, 270, 288, -1, -1, -1, - 275, -1, -1, 295, 279, -1, -1, -1, 300, -1, - 302, 303, 304, 288, -1, -1, -1, -1, -1, -1, - 295, -1, -1, -1, 316, 300, 318, 319, 320, 304, - 322, -1, -1, 325, -1, 327, -1, 329, 330, 331, - 332, 316, 334, 318, -1, -1, -1, 322, -1, 341, - -1, -1, 344, 345, -1, 330, 331, -1, -1, 334, - -1, -1, 337, -1, -1, -1, -1, 359, 360, 361, - 362, 363, -1, -1, -1, 367, -1, -1, -1, 371, - -1, -1, -1, -1, -1, 377, 378, 379, 380, -1, - -1, -1, 384, -1, 386, -1, -1, -1, -1, -1, - 392, 393, -1, -1, -1, -1, -1, -1, 264, 265, + -1, -1, -1, -1, -1, -1, -1, -1, -1, 359, + 360, 361, 362, 363, -1, -1, -1, -1, -1, -1, + -1, 371, -1, -1, -1, -1, -1, 377, 378, 379, + 380, -1, -1, -1, 384, -1, 386, 256, -1, -1, + -1, -1, 392, 393, -1, 264, 265, -1, 267, -1, + -1, 270, 271, -1, -1, -1, 275, 276, 277, -1, + 279, -1, -1, -1, -1, -1, 285, 417, 418, 288, + 420, -1, -1, -1, -1, -1, 295, -1, -1, -1, + -1, 300, -1, 302, 303, 304, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 316, -1, 318, + 319, -1, -1, 322, -1, -1, 325, -1, 327, -1, + 329, 330, 331, 332, -1, 334, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 359, 360, 361, 362, 363, -1, -1, -1, -1, -1, + -1, -1, 371, -1, -1, -1, -1, -1, 377, 378, + 379, 380, -1, -1, -1, 384, -1, 386, 256, -1, + -1, -1, -1, 392, 393, -1, 264, 265, -1, 267, + -1, -1, 270, 271, -1, -1, -1, 275, 276, 277, + -1, 279, -1, -1, -1, -1, -1, 285, 417, 418, + 288, 420, -1, -1, -1, -1, -1, 295, -1, -1, + -1, -1, 300, -1, 302, 303, 304, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, 316, -1, + 318, 319, -1, -1, 322, -1, -1, 325, -1, 327, + -1, 329, 330, 331, 332, -1, 334, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, 359, 360, 361, 362, 363, -1, -1, -1, -1, + -1, -1, -1, 371, -1, -1, -1, -1, -1, 377, + 378, 379, 380, -1, -1, -1, 384, -1, 386, 256, + -1, -1, -1, -1, 392, 393, -1, 264, 265, -1, + 267, -1, -1, 270, 271, -1, -1, -1, 275, 276, + 277, -1, 279, -1, -1, -1, -1, -1, 285, 417, + 418, 288, 420, -1, -1, -1, -1, -1, 295, -1, + -1, -1, -1, 300, -1, 302, 303, 304, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, 316, + -1, 318, 319, -1, -1, 322, -1, -1, 325, -1, + 327, -1, 329, 330, 331, 332, -1, 334, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 359, 360, 361, 362, 363, -1, -1, -1, + -1, -1, -1, -1, 371, -1, -1, -1, -1, -1, + 377, 378, 379, 380, -1, -1, -1, 384, -1, 386, + 256, -1, -1, -1, -1, 392, 393, -1, 264, 265, -1, 267, -1, -1, 270, 271, -1, -1, -1, 275, - 276, 277, -1, 279, -1, 417, 418, 419, 420, 285, - -1, -1, 288, -1, -1, -1, -1, -1, -1, 295, - -1, -1, -1, 418, 300, -1, 302, 303, 304, -1, + 276, 277, -1, 279, -1, -1, -1, -1, -1, 285, + 417, 418, 288, 420, -1, -1, -1, -1, -1, 295, + -1, -1, -1, -1, 300, -1, 302, 303, 304, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 316, -1, 318, 319, -1, -1, 322, -1, -1, 325, -1, 327, -1, 329, 330, 331, 332, -1, 334, -1, - -1, -1, -1, -1, -1, 341, -1, -1, 344, 345, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 359, 360, 361, 362, 363, -1, -1, - -1, 367, -1, -1, -1, 371, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 371, -1, -1, -1, -1, -1, 377, 378, 379, 380, -1, -1, -1, 384, -1, - 386, -1, -1, -1, -1, -1, 392, 393, -1, -1, + 386, 256, -1, -1, -1, -1, 392, 393, -1, 264, + 265, -1, 267, -1, -1, 270, 271, -1, -1, -1, + 275, 276, 277, -1, 279, -1, -1, -1, -1, -1, + 285, 417, 418, 288, 420, -1, -1, -1, -1, -1, + 295, -1, -1, -1, -1, 300, -1, 302, 303, 304, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 256, - -1, 417, 418, 419, 420, -1, -1, 264, 265, -1, - 267, -1, 428, 270, 271, -1, -1, -1, 275, 276, - 277, -1, 279, -1, -1, 265, -1, 267, 285, -1, - 270, 288, -1, -1, -1, 275, -1, -1, 295, 279, - -1, -1, -1, 300, -1, 302, 303, 304, 288, -1, - -1, -1, -1, -1, -1, 295, -1, -1, -1, 316, - 300, 318, 319, -1, 304, 322, -1, -1, 325, -1, - 327, -1, 329, 330, 331, 332, 316, 334, 318, -1, - -1, -1, 322, -1, 341, -1, -1, 344, 345, -1, - 330, 331, -1, -1, 334, -1, -1, 337, -1, -1, - -1, -1, 359, 360, 361, 362, 363, -1, -1, -1, - 367, -1, -1, -1, 371, -1, -1, -1, -1, -1, - 377, 378, 379, 380, -1, -1, -1, 384, -1, 386, - -1, -1, -1, -1, -1, 392, 393, -1, -1, -1, + -1, 316, -1, 318, 319, -1, -1, 322, -1, -1, + 325, -1, 327, -1, 329, 330, 331, 332, -1, 334, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 256, -1, -1, -1, - 417, 418, 419, 420, 264, 265, -1, 267, -1, -1, - 270, 271, -1, -1, -1, 275, 276, 277, 418, 279, - -1, -1, 265, -1, 267, 285, -1, 270, 288, -1, - -1, -1, 275, -1, -1, 295, 279, -1, -1, -1, - 300, -1, 302, 303, 304, 288, -1, -1, -1, -1, - -1, -1, 295, -1, -1, -1, 316, 300, 318, 319, - -1, 304, 322, -1, -1, 325, -1, 327, -1, 329, - 330, 331, 332, 316, 334, 318, -1, -1, -1, 322, - -1, 341, -1, -1, 344, 345, -1, 330, 331, -1, - -1, 334, -1, -1, 337, -1, -1, -1, -1, 359, - 360, 361, 362, 363, -1, -1, -1, -1, -1, -1, - -1, 371, -1, -1, -1, -1, -1, 377, 378, 379, - 380, -1, -1, -1, 384, -1, 386, -1, -1, -1, - -1, -1, 392, 393, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 256, -1, -1, -1, 417, 418, 419, - 420, 264, 265, -1, 267, -1, -1, 270, 271, -1, - -1, -1, 275, 276, 277, 418, 279, -1, -1, 265, - -1, 267, 285, -1, 270, 288, -1, -1, -1, 275, - -1, -1, 295, 279, -1, -1, -1, 300, -1, 302, - 303, 304, 288, -1, -1, -1, -1, -1, -1, 295, - -1, -1, -1, 316, 300, 318, 319, -1, 304, 322, + -1, -1, -1, -1, 359, 360, 361, 362, 363, -1, + -1, -1, -1, -1, -1, -1, 371, -1, -1, -1, + -1, -1, 377, 378, 379, 380, -1, -1, -1, 384, + -1, 386, 256, -1, -1, -1, -1, 392, 393, -1, + 264, 265, -1, 267, -1, -1, 270, 271, -1, -1, + -1, 275, 276, 277, -1, 279, -1, -1, -1, -1, + -1, 285, 417, 418, 288, 420, -1, -1, -1, -1, + -1, 295, -1, -1, -1, -1, 300, -1, 302, 303, + 304, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 316, -1, 318, 319, -1, -1, 322, -1, + -1, 325, -1, 327, -1, 329, 330, 331, 332, -1, + 334, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 359, 360, 361, 362, 363, + -1, -1, -1, -1, -1, -1, -1, 371, -1, -1, + -1, -1, -1, 377, 378, 379, 380, -1, -1, -1, + 384, -1, 386, 256, -1, -1, -1, -1, 392, 393, + -1, 264, 265, -1, 267, -1, -1, 270, 271, -1, + -1, -1, 275, 276, 277, -1, 279, -1, -1, -1, + -1, -1, 285, 417, 418, 288, 420, -1, -1, -1, + -1, -1, 295, -1, -1, -1, -1, 300, -1, 302, + 303, 304, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 316, -1, 318, 319, -1, -1, 322, -1, -1, 325, -1, 327, -1, 329, 330, 331, 332, - 316, 334, 318, -1, -1, -1, 322, -1, 341, -1, - -1, 344, 345, -1, 330, 331, -1, -1, 334, -1, - -1, 337, -1, -1, -1, -1, 359, 360, 361, 362, + -1, 334, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 359, 360, 361, 362, 363, -1, -1, -1, -1, -1, -1, -1, 371, -1, -1, -1, -1, -1, 377, 378, 379, 380, -1, -1, - -1, 384, -1, 386, -1, -1, -1, -1, -1, 392, - 393, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, 384, -1, 386, 256, -1, -1, -1, -1, 392, + 393, -1, 264, 265, -1, 267, -1, -1, 270, 271, + -1, -1, -1, 275, 276, 277, -1, 279, -1, -1, + -1, -1, -1, 285, 417, 418, 288, 420, -1, -1, + -1, -1, -1, 295, -1, -1, -1, -1, 300, -1, + 302, 303, 304, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 316, -1, 318, 319, -1, -1, + 322, -1, -1, 325, -1, 327, -1, 329, 330, 331, + 332, -1, 334, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 359, 360, 361, + 362, 363, -1, -1, -1, -1, -1, -1, -1, 371, + -1, -1, -1, -1, -1, 377, 378, 379, 380, -1, + -1, -1, 384, -1, 386, 256, -1, -1, -1, -1, + 392, 393, -1, 264, 265, -1, 267, -1, -1, 270, + 271, -1, -1, -1, 275, 276, 277, -1, 279, -1, + -1, -1, -1, -1, 285, 417, 418, 288, 420, -1, + -1, -1, -1, -1, 295, -1, -1, -1, -1, 300, + -1, 302, 303, 304, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 316, -1, 318, 319, -1, + -1, 322, -1, -1, 325, -1, 327, -1, 329, 330, + 331, 332, -1, 334, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, 359, 360, + 361, 362, 363, -1, -1, -1, -1, -1, -1, -1, + 371, -1, -1, -1, -1, -1, 377, 378, 379, 380, + -1, -1, -1, 384, -1, 386, 256, -1, -1, -1, + -1, 392, 393, -1, 264, 265, -1, 267, -1, -1, + 270, 271, -1, -1, -1, 275, 276, 277, -1, 279, + -1, -1, -1, -1, -1, 285, 417, 418, 288, 420, + -1, -1, -1, -1, -1, 295, -1, -1, -1, -1, + 300, -1, 302, 303, 304, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 316, -1, 318, 319, + -1, -1, 322, -1, -1, 325, -1, 327, -1, 329, + 330, 331, 332, -1, 334, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, 359, + 360, 361, 362, 363, -1, -1, -1, -1, -1, -1, + -1, 371, -1, -1, -1, -1, -1, 377, 378, 379, + 380, -1, -1, -1, 384, -1, 386, 256, -1, -1, + -1, -1, 392, 393, -1, 264, 265, -1, 267, -1, + -1, 270, 271, -1, -1, -1, 275, 276, 277, -1, + 279, -1, -1, -1, -1, -1, 285, 417, 418, 288, + 420, -1, -1, -1, -1, -1, 295, -1, -1, -1, + -1, 300, -1, 302, 303, 304, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 316, -1, 318, + 319, -1, -1, 322, -1, -1, 325, -1, 327, -1, + 329, 330, 331, 332, -1, 334, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 359, 360, 361, 362, 363, -1, -1, -1, -1, -1, + -1, -1, 371, -1, -1, -1, -1, -1, 377, 378, + 379, 380, -1, -1, -1, 384, -1, 386, 256, -1, + -1, -1, -1, 392, 393, -1, 264, 265, -1, 267, + -1, -1, 270, 271, -1, -1, -1, 275, 276, 277, + -1, 279, -1, -1, -1, -1, -1, 285, 417, 418, + 288, 420, -1, -1, -1, -1, -1, 295, -1, -1, + -1, -1, 300, -1, 302, 303, 304, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, 316, -1, + 318, 319, -1, -1, 322, -1, -1, 325, -1, 327, + -1, 329, 330, 331, 332, -1, 334, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 256, -1, -1, -1, 417, 418, 419, 420, 264, 265, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, 359, 360, 361, 362, 363, -1, -1, -1, -1, + -1, -1, -1, 371, -1, -1, -1, -1, -1, 377, + 378, 379, 380, -1, -1, -1, 384, -1, 386, 256, + -1, -1, -1, -1, 392, 393, -1, 264, 265, -1, + 267, -1, -1, 270, 271, -1, -1, -1, 275, 276, + 277, -1, 279, -1, -1, -1, -1, -1, 285, 417, + 418, 288, 420, -1, -1, -1, -1, -1, 295, -1, + -1, -1, -1, 300, -1, 302, 303, 304, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, 316, + -1, 318, 319, -1, -1, 322, -1, -1, 325, -1, + 327, -1, 329, 330, 331, 332, -1, 334, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 359, 360, 361, 362, 363, -1, -1, -1, + -1, -1, -1, -1, 371, -1, -1, -1, -1, -1, + 377, 378, 379, 380, -1, -1, -1, 384, -1, 386, + 256, -1, -1, -1, -1, 392, 393, -1, 264, 265, -1, 267, -1, -1, 270, 271, -1, -1, -1, 275, - 276, 277, 418, 279, -1, -1, 265, -1, 267, 285, - -1, 270, 288, -1, -1, -1, 275, -1, -1, 295, - 279, -1, -1, -1, 300, -1, 302, 303, 304, 288, - -1, -1, -1, -1, -1, -1, 295, -1, -1, -1, - 316, 300, 318, 319, -1, 304, 322, -1, -1, 325, - -1, 327, -1, 329, 330, 331, 332, 316, 334, 318, - -1, -1, -1, 322, -1, 341, -1, -1, 344, 345, - -1, 330, 331, -1, -1, 334, -1, -1, 337, -1, + 276, 277, -1, 279, -1, -1, -1, -1, -1, 285, + 417, 418, 288, 420, -1, -1, -1, -1, -1, 295, + -1, -1, -1, -1, 300, -1, 302, 303, 304, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 316, -1, 318, 319, -1, -1, 322, -1, -1, 325, + -1, 327, -1, 329, 330, 331, 332, -1, 334, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 359, 360, 361, 362, 363, -1, -1, -1, -1, -1, -1, -1, 371, -1, -1, -1, -1, -1, 377, 378, 379, 380, -1, -1, -1, 384, -1, - 386, -1, -1, -1, -1, -1, 392, 393, -1, -1, + 386, 256, -1, -1, -1, -1, 392, 393, -1, 264, + 265, -1, 267, -1, -1, 270, 271, -1, -1, -1, + 275, 276, 277, -1, 279, -1, -1, -1, -1, -1, + 285, 417, 418, 288, 420, -1, -1, -1, -1, -1, + 295, -1, -1, -1, -1, 300, -1, 302, 303, 304, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 256, -1, -1, - -1, 417, 418, 419, 420, 264, 265, -1, 267, -1, - -1, 270, 271, -1, -1, -1, 275, 276, 277, 418, - 279, -1, -1, 265, -1, 267, 285, -1, 270, 288, - -1, -1, -1, 275, -1, -1, 295, 279, -1, -1, - -1, 300, -1, 302, 303, 304, 288, -1, -1, -1, - -1, -1, -1, 295, -1, -1, -1, 316, 300, 318, - 319, -1, 304, 322, -1, -1, 325, -1, 327, -1, - 329, 330, 331, 332, 316, 334, 318, -1, -1, -1, - 322, -1, 341, -1, -1, 344, 345, -1, 330, 331, - -1, -1, 334, -1, -1, 337, -1, -1, -1, -1, - 359, 360, 361, 362, 363, -1, -1, -1, -1, -1, - -1, -1, 371, -1, -1, -1, -1, -1, 377, 378, - 379, 380, -1, -1, -1, 384, -1, 386, -1, -1, - -1, -1, -1, 392, 393, -1, -1, -1, -1, -1, + -1, 316, -1, 318, 319, -1, -1, 322, -1, -1, + 325, -1, 327, -1, 329, 330, 331, 332, -1, 334, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 256, -1, -1, -1, 417, 418, - 419, 420, 264, 265, -1, 267, -1, -1, 270, 271, - -1, -1, -1, 275, 276, 277, 418, 279, -1, -1, - 265, -1, 267, 285, -1, 270, 288, -1, -1, -1, - 275, -1, -1, 295, 279, -1, -1, -1, 300, -1, - 302, 303, 304, 288, -1, -1, -1, -1, -1, -1, - 295, -1, -1, -1, 316, 300, 318, 319, -1, 304, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 359, 360, 361, 362, 363, -1, + -1, -1, -1, -1, -1, -1, 371, -1, -1, -1, + -1, -1, 377, 378, 379, 380, -1, -1, -1, 384, + -1, 386, 256, -1, -1, -1, -1, 392, 393, -1, + 264, 265, -1, 267, -1, -1, 270, 271, -1, -1, + -1, 275, 276, 277, -1, 279, -1, -1, -1, -1, + -1, 285, 417, 418, 288, 420, -1, -1, -1, -1, + -1, 295, -1, -1, -1, -1, 300, -1, 302, 303, + 304, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 316, -1, 318, 319, -1, -1, 322, -1, + -1, 325, -1, 327, -1, 329, 330, 331, 332, -1, + 334, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 359, 360, 361, 362, 363, + -1, -1, -1, -1, -1, -1, -1, 371, -1, -1, + -1, -1, -1, 377, 378, 379, 380, -1, -1, -1, + 384, -1, 386, 256, -1, -1, -1, -1, 392, 393, + -1, 264, 265, -1, 267, -1, -1, 270, 271, -1, + -1, -1, 275, 276, 277, -1, 279, -1, -1, -1, + -1, -1, 285, 417, 418, 288, 420, -1, -1, -1, + -1, -1, 295, -1, -1, -1, -1, 300, -1, 302, + 303, 304, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 316, -1, 318, 319, -1, -1, 322, + -1, -1, 325, -1, 327, -1, 329, 330, 331, 332, + -1, 334, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 359, 360, 361, 362, + 363, -1, -1, -1, -1, -1, -1, -1, 371, -1, + -1, -1, -1, -1, 377, 378, 379, 380, -1, -1, + -1, 384, -1, 386, 256, -1, -1, -1, -1, 392, + 393, -1, 264, 265, -1, 267, -1, -1, 270, 271, + -1, -1, -1, 275, 276, 277, -1, 279, -1, -1, + -1, -1, -1, 285, 417, 418, 288, 420, -1, -1, + -1, -1, -1, 295, -1, -1, -1, -1, 300, -1, + 302, 303, 304, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 316, -1, 318, 319, -1, -1, 322, -1, -1, 325, -1, 327, -1, 329, 330, 331, - 332, 316, 334, 318, -1, -1, -1, 322, -1, 341, - -1, -1, 344, 345, -1, 330, 331, -1, -1, 334, - -1, -1, 337, -1, -1, -1, -1, 359, 360, 361, + 332, -1, 334, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 359, 360, 361, 362, 363, -1, -1, -1, -1, -1, -1, -1, 371, -1, -1, -1, -1, -1, 377, 378, 379, 380, -1, - -1, -1, 384, -1, 386, -1, -1, -1, -1, -1, - 392, 393, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 256, -1, -1, -1, 417, 418, 419, 420, 264, - 265, -1, 267, -1, -1, 270, 271, -1, -1, -1, - 275, 276, 277, 418, 279, -1, -1, -1, -1, -1, - 285, -1, -1, 288, -1, -1, -1, -1, -1, -1, - 295, -1, -1, -1, -1, 300, -1, 302, 303, 304, + -1, -1, 384, -1, 386, 256, -1, -1, -1, -1, + 392, 393, -1, 264, 265, -1, 267, -1, -1, 270, + 271, -1, -1, -1, 275, 276, 277, -1, 279, -1, + -1, -1, -1, -1, 285, 417, 418, 288, 420, -1, + -1, -1, -1, -1, 295, -1, -1, -1, -1, 300, + -1, 302, 303, 304, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 316, -1, 318, 319, -1, + -1, 322, -1, -1, 325, -1, 327, -1, 329, 330, + 331, 332, -1, 334, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 316, -1, 318, 319, -1, -1, 322, -1, -1, - 325, -1, 327, -1, 329, 330, 331, 332, -1, 334, - -1, -1, -1, -1, -1, -1, 341, -1, -1, 344, - 345, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 359, 360, 361, 362, 363, -1, - -1, -1, -1, -1, -1, -1, 371, -1, -1, -1, - -1, -1, 377, 378, 379, 380, -1, -1, -1, 384, - -1, 386, -1, -1, -1, -1, -1, 392, 393, -1, + -1, -1, -1, -1, -1, -1, -1, -1, 359, 360, + 361, 362, 363, -1, -1, -1, -1, -1, -1, -1, + 371, -1, -1, -1, -1, -1, 377, 378, 379, 380, + -1, -1, -1, 384, -1, 386, 256, -1, -1, -1, + -1, 392, 393, -1, 264, 265, -1, 267, -1, -1, + 270, 271, -1, -1, -1, 275, 276, 277, -1, 279, + -1, -1, -1, -1, -1, 285, 417, 418, 288, 420, + -1, -1, -1, -1, -1, 295, -1, -1, -1, -1, + 300, -1, 302, 303, 304, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 316, -1, 318, 319, + -1, -1, 322, -1, -1, 325, -1, 327, -1, 329, + 330, 331, 332, -1, 334, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 256, -1, - -1, -1, 417, 418, 419, 420, 264, 265, -1, 267, - -1, -1, 270, 271, -1, -1, -1, 275, 276, 277, - -1, 279, -1, -1, -1, -1, -1, 285, -1, -1, - 288, -1, -1, -1, 261, -1, -1, 295, -1, -1, - -1, 262, 300, -1, 302, 303, 304, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 284, 316, -1, - 318, 319, -1, -1, 322, -1, -1, 325, -1, 327, - 297, 329, 330, 331, 332, 302, 334, 298, -1, -1, - 307, -1, 309, 310, 311, 312, -1, -1, 315, -1, - 317, -1, -1, -1, 321, -1, -1, -1, -1, -1, - -1, 359, 360, 361, 362, -1, 333, -1, -1, 336, - -1, 338, -1, 371, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, 359, + 360, 361, 362, 363, -1, -1, -1, -1, -1, -1, + -1, 371, -1, -1, -1, -1, -1, 377, 378, 379, + 380, -1, -1, -1, 384, -1, 386, 256, -1, -1, + -1, -1, 392, 393, 262, 264, 265, -1, 267, -1, + -1, 270, 271, -1, -1, -1, 275, 276, 277, -1, + 279, -1, -1, -1, -1, -1, 285, 417, 418, 288, + 420, -1, -1, -1, -1, -1, 295, -1, -1, -1, + 298, 300, -1, 302, 303, 304, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 316, -1, 318, + 319, -1, -1, 322, -1, -1, 325, -1, 327, -1, + 329, 330, 331, 332, -1, 334, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 362, -1, -1, -1, -1, - -1, 368, 369, -1, -1, -1, -1, -1, -1, -1, - 371, 372, 373, 374, 375, -1, -1, 378, 379, 417, - 418, 382, 383, 384, 385, 386, 387, 388, 389, 390, - -1, 392, 393, 394, 395, 396, 397, 398, 399, 400, - 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, - 411, 412, 413, -1, 261, -1, 263, -1, 265, 420, - 267, -1, 423, 270, -1, 272, 273, -1, 275, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 359, 360, 361, 362, 363, -1, -1, -1, -1, -1, + -1, -1, 371, 371, 372, 373, 374, 375, -1, -1, + 378, 379, -1, -1, 382, 383, 384, 385, 386, 387, + 388, 389, 390, -1, 392, 393, 394, 395, 396, 397, + 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, + 408, 409, 410, 411, 412, 413, -1, -1, 417, 418, + -1, -1, 420, -1, 261, 423, 263, -1, 265, -1, + 267, -1, -1, 270, -1, 272, 273, -1, 275, -1, 277, -1, 279, -1, 281, 282, 283, 284, -1, -1, 287, 288, -1, -1, -1, -1, 293, 294, 295, 296, 297, -1, -1, 300, -1, 302, -1, 304, -1, 306, @@ -12476,301 +14289,307 @@ void case_982() 304, -1, -1, 307, -1, 309, 310, 311, 312, -1, -1, -1, 316, 317, 318, -1, -1, 321, 322, 323, 418, -1, 284, -1, -1, -1, 330, 331, -1, 333, - 334, 261, 336, 337, 338, 297, -1, -1, 342, -1, + 334, -1, 336, 337, 338, 297, -1, -1, 342, -1, 302, -1, -1, 305, -1, 307, -1, 309, 310, 311, - 312, -1, -1, -1, 284, 317, -1, -1, 362, 321, - -1, -1, -1, 325, 368, -1, -1, 297, -1, -1, - -1, 333, 302, -1, 336, -1, 338, 307, -1, 309, - 310, 311, 312, -1, -1, -1, -1, 317, -1, -1, - -1, 321, -1, -1, -1, 357, -1, -1, -1, -1, - 362, -1, -1, 333, -1, -1, 336, 369, 338, 371, - -1, 373, -1, -1, 418, 264, 265, -1, 267, -1, - -1, 270, 271, -1, 386, -1, 275, 276, 277, -1, - 279, -1, 362, -1, -1, -1, 285, -1, -1, 288, - -1, -1, -1, -1, -1, -1, 295, -1, -1, -1, - -1, 300, -1, 302, 303, 304, 418, 306, -1, -1, - -1, -1, -1, -1, 313, -1, -1, 316, -1, 318, - 319, -1, -1, 322, -1, -1, 325, -1, 327, -1, - 329, 330, 331, 332, -1, 334, -1, -1, 418, -1, - -1, -1, 341, -1, -1, 344, 345, -1, -1, -1, + 312, -1, -1, -1, -1, 317, -1, -1, 362, 321, + -1, -1, -1, 325, 368, -1, -1, -1, -1, 261, + -1, 333, -1, -1, 336, -1, 338, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 359, 360, 361, 362, 363, -1, -1, -1, -1, -1, - -1, -1, 371, 372, -1, 374, -1, -1, 377, 378, - 379, 380, -1, -1, -1, 384, -1, 386, -1, -1, - -1, -1, -1, 392, 393, -1, -1, -1, -1, -1, - -1, 264, 265, -1, 267, -1, -1, 270, 271, -1, - -1, -1, 275, 276, 277, -1, 279, -1, 417, 418, - 419, 420, 285, -1, -1, 288, -1, -1, -1, -1, - -1, -1, 295, -1, -1, -1, -1, 300, -1, 302, - 303, 304, -1, 306, -1, -1, -1, -1, -1, -1, - 313, -1, -1, 316, -1, 318, 319, -1, -1, 322, - -1, -1, 325, -1, 327, -1, 329, 330, 331, 332, - -1, 334, -1, -1, -1, -1, -1, -1, 341, -1, - -1, 344, 345, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 359, 360, 361, 362, - 363, -1, -1, -1, -1, -1, -1, -1, 371, -1, - -1, 374, -1, -1, 377, 378, 379, 380, -1, -1, - -1, 384, -1, 386, -1, -1, -1, -1, -1, 392, - 393, -1, -1, -1, -1, -1, -1, 264, 265, -1, - 267, -1, -1, 270, 271, -1, -1, -1, 275, 276, - 277, -1, 279, -1, 417, 418, 419, 420, 285, -1, - -1, 288, -1, -1, -1, -1, -1, -1, 295, -1, - -1, -1, -1, 300, -1, 302, 303, 304, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 316, - -1, 318, 319, -1, -1, 322, -1, -1, 325, -1, - 327, -1, 329, 330, 331, 332, -1, 334, -1, -1, - 337, -1, -1, -1, 341, -1, -1, 344, 345, -1, + -1, -1, 284, -1, -1, 357, -1, -1, -1, -1, + 362, -1, -1, -1, -1, 297, 368, 369, -1, 371, + 302, 373, -1, 305, 418, 307, -1, 309, 310, 311, + 312, -1, -1, -1, 386, 317, -1, -1, -1, 321, + -1, 261, -1, 325, -1, -1, -1, -1, -1, -1, + -1, 333, -1, -1, 336, -1, 338, -1, -1, -1, + -1, -1, -1, -1, 284, -1, 418, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 297, -1, 261, + 362, -1, 302, -1, -1, 305, 368, 307, -1, 309, + 310, 311, 312, -1, -1, -1, -1, 317, -1, -1, + -1, 321, 284, -1, -1, 325, -1, -1, -1, -1, + -1, -1, -1, 333, -1, 297, 336, 261, 338, -1, + 302, -1, -1, -1, -1, 307, -1, 309, 310, 311, + 312, -1, -1, -1, -1, 317, 418, -1, -1, 321, + 284, -1, 362, 325, -1, -1, -1, -1, 368, -1, + -1, 333, -1, 297, 336, 261, 338, -1, 302, -1, + -1, -1, -1, 307, -1, 309, 310, 311, 312, -1, + -1, -1, -1, 317, -1, -1, -1, 321, 284, -1, + 362, 325, -1, -1, -1, -1, 368, -1, -1, 333, + -1, 297, 336, -1, 338, -1, 302, -1, 418, -1, + -1, 307, -1, 309, 310, 311, 312, -1, -1, -1, + -1, 317, -1, -1, -1, 321, -1, -1, 362, -1, + -1, -1, -1, -1, -1, -1, -1, 333, 264, 265, + 336, 267, 338, -1, 270, 271, 418, -1, -1, 275, + 276, 277, -1, 279, -1, -1, -1, -1, -1, 285, + -1, -1, 288, -1, -1, -1, 362, -1, -1, 295, + -1, -1, -1, -1, 300, -1, 302, 303, 304, -1, + 306, -1, -1, -1, 418, -1, -1, 313, -1, -1, + 316, -1, 318, 319, -1, -1, 322, -1, -1, 325, + -1, 327, -1, 329, 330, 331, 332, -1, 334, -1, + -1, -1, -1, -1, -1, 341, -1, -1, 344, 345, + -1, -1, 418, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 359, 360, 361, 362, 363, -1, -1, + -1, -1, -1, -1, -1, 371, 372, -1, 374, -1, + -1, 377, 378, 379, 380, -1, -1, -1, 384, -1, + 386, -1, -1, -1, -1, -1, 392, 393, -1, -1, + -1, -1, -1, -1, 264, 265, -1, 267, -1, -1, + 270, 271, -1, -1, -1, 275, 276, 277, -1, 279, + -1, 417, 418, 419, 420, 285, -1, -1, 288, -1, + -1, -1, -1, -1, -1, 295, -1, -1, -1, -1, + 300, -1, 302, 303, 304, -1, 306, -1, -1, -1, + -1, -1, -1, 313, -1, -1, 316, -1, 318, 319, + -1, -1, 322, -1, -1, 325, -1, 327, -1, 329, + 330, 331, 332, -1, 334, -1, -1, -1, -1, -1, + -1, 341, -1, -1, 344, 345, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, 359, + 360, 361, 362, 363, -1, -1, -1, -1, -1, -1, + -1, 371, -1, -1, 374, -1, -1, 377, 378, 379, + 380, -1, -1, -1, 384, -1, 386, -1, -1, -1, + -1, -1, 392, 393, -1, -1, -1, -1, -1, -1, + 264, 265, -1, 267, -1, -1, 270, 271, -1, -1, + -1, 275, 276, 277, -1, 279, -1, 417, 418, 419, + 420, 285, -1, -1, 288, -1, -1, -1, -1, -1, + -1, 295, -1, -1, -1, -1, 300, -1, 302, 303, + 304, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 316, -1, 318, 319, -1, -1, 322, -1, + -1, 325, -1, 327, -1, 329, 330, 331, 332, -1, + 334, -1, -1, 337, -1, -1, -1, 341, -1, -1, + 344, 345, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 359, 360, 361, 362, 363, + -1, -1, -1, -1, -1, -1, -1, 371, -1, -1, + -1, -1, -1, 377, 378, 379, 380, -1, -1, -1, + 384, -1, 386, -1, -1, -1, -1, -1, 392, 393, + -1, -1, -1, -1, -1, -1, 264, 265, -1, 267, + -1, -1, 270, 271, -1, -1, -1, 275, 276, 277, + -1, 279, -1, 417, 418, 419, 420, 285, -1, -1, + 288, -1, -1, -1, -1, -1, -1, 295, -1, -1, + -1, -1, 300, -1, 302, 303, 304, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, 316, -1, + 318, 319, -1, -1, 322, -1, -1, 325, -1, 327, + -1, 329, 330, 331, 332, -1, 334, -1, -1, -1, + -1, -1, -1, 341, -1, -1, 344, 345, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, 359, 360, 361, 362, 363, -1, -1, -1, - -1, -1, -1, -1, 371, -1, -1, -1, -1, -1, - 377, 378, 379, 380, -1, -1, -1, 384, -1, 386, - -1, -1, -1, -1, -1, 392, 393, -1, -1, -1, - -1, -1, -1, 264, 265, -1, 267, -1, -1, 270, - 271, -1, -1, -1, 275, 276, 277, -1, 279, -1, - 417, 418, 419, 420, 285, -1, -1, 288, -1, -1, - -1, -1, -1, -1, 295, -1, -1, -1, -1, 300, - -1, 302, 303, 304, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 316, -1, 318, 319, -1, - -1, 322, -1, -1, 325, -1, 327, -1, 329, 330, - 331, 332, -1, 334, -1, -1, -1, -1, -1, -1, - 341, -1, -1, 344, 345, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 359, 360, - 361, 362, 363, -1, -1, -1, -1, 368, -1, -1, - 371, -1, -1, -1, -1, -1, 377, 378, 379, 380, - -1, -1, -1, 384, -1, 386, -1, -1, -1, -1, - -1, 392, 393, -1, -1, -1, -1, -1, -1, 264, - 265, -1, 267, -1, -1, 270, 271, -1, -1, -1, - 275, 276, 277, -1, 279, -1, 417, 418, 419, 420, - 285, -1, -1, 288, -1, -1, -1, -1, -1, -1, - 295, -1, -1, -1, -1, 300, -1, 302, 303, 304, + -1, 359, 360, 361, 362, 363, -1, -1, -1, 367, + -1, -1, -1, 371, -1, -1, -1, -1, -1, 377, + 378, 379, 380, -1, -1, -1, 384, -1, 386, -1, + -1, -1, -1, -1, 392, 393, -1, -1, -1, -1, + -1, -1, 264, 265, -1, 267, -1, -1, 270, 271, + -1, -1, -1, 275, 276, 277, -1, 279, -1, 417, + 418, 419, 420, 285, -1, -1, 288, -1, -1, -1, + -1, -1, -1, 295, -1, -1, -1, -1, 300, -1, + 302, 303, 304, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 316, -1, 318, 319, -1, -1, + 322, -1, -1, 325, -1, 327, -1, 329, 330, 331, + 332, -1, 334, -1, -1, -1, -1, -1, -1, 341, + -1, -1, 344, 345, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 359, 360, 361, + 362, 363, -1, -1, -1, 367, -1, -1, -1, 371, + -1, -1, -1, -1, -1, 377, 378, 379, 380, -1, + -1, -1, 384, -1, 386, -1, -1, -1, -1, -1, + 392, 393, -1, -1, -1, -1, -1, -1, 264, 265, + -1, 267, -1, -1, 270, 271, -1, -1, -1, 275, + 276, 277, -1, 279, -1, 417, 418, 419, 420, 285, + -1, -1, 288, -1, -1, -1, -1, -1, -1, 295, + -1, -1, -1, -1, 300, -1, 302, 303, 304, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 316, -1, 318, 319, -1, -1, 322, -1, -1, - 325, -1, 327, -1, 329, 330, 331, 332, -1, 334, - -1, -1, -1, -1, -1, -1, 341, -1, -1, 344, - 345, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 359, 360, 361, 362, 363, -1, - -1, -1, 367, -1, -1, -1, 371, -1, -1, -1, - -1, -1, 377, 378, 379, 380, -1, -1, -1, 384, - -1, 386, -1, -1, -1, -1, -1, 392, 393, -1, - -1, -1, -1, -1, -1, 264, 265, -1, 267, -1, - -1, 270, 271, -1, -1, -1, 275, 276, 277, -1, - 279, -1, 417, 418, 419, 420, 285, -1, -1, 288, - -1, -1, -1, -1, -1, -1, 295, -1, -1, -1, - -1, 300, -1, 302, 303, 304, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 316, -1, 318, - 319, -1, -1, 322, -1, -1, 325, -1, 327, -1, - 329, 330, 331, 332, -1, 334, -1, -1, -1, -1, - -1, -1, 341, -1, -1, 344, 345, -1, -1, -1, + 316, -1, 318, 319, -1, -1, 322, -1, -1, 325, + -1, 327, -1, 329, 330, 331, 332, -1, 334, -1, + -1, -1, -1, -1, -1, 341, -1, -1, 344, 345, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 359, 360, 361, 362, 363, -1, -1, -1, 367, -1, - -1, -1, 371, -1, -1, -1, -1, -1, 377, 378, - 379, 380, -1, -1, -1, 384, -1, 386, -1, -1, - -1, -1, -1, 392, 393, -1, -1, -1, -1, -1, - -1, 264, 265, -1, 267, -1, -1, 270, 271, -1, - -1, -1, 275, 276, 277, -1, 279, -1, 417, 418, - 419, 420, 285, -1, -1, 288, -1, -1, -1, -1, - -1, -1, 295, -1, -1, -1, -1, 300, -1, 302, - 303, 304, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 316, -1, 318, 319, -1, -1, 322, - -1, -1, 325, -1, 327, -1, 329, 330, 331, 332, - -1, 334, -1, -1, -1, -1, -1, -1, 341, -1, - -1, 344, 345, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 359, 360, 361, 362, - 363, -1, -1, -1, -1, -1, -1, -1, 371, -1, - -1, -1, -1, -1, 377, 378, 379, 380, -1, -1, - -1, 384, -1, 386, -1, -1, -1, -1, -1, 392, - 393, -1, -1, -1, -1, -1, -1, 264, 265, -1, - 267, -1, -1, 270, 271, -1, -1, -1, 275, 276, - 277, -1, 279, -1, 417, 418, 419, 420, 285, -1, - -1, 288, -1, -1, -1, -1, -1, -1, 295, -1, - -1, -1, -1, 300, -1, 302, 303, 304, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 316, - -1, 318, 319, -1, -1, 322, -1, -1, 325, -1, - 327, -1, 329, 330, 331, 332, -1, 334, -1, -1, - -1, -1, -1, -1, 341, -1, -1, 344, 345, -1, + -1, -1, -1, 359, 360, 361, 362, 363, -1, -1, + -1, -1, -1, -1, -1, 371, -1, -1, -1, -1, + -1, 377, 378, 379, 380, -1, -1, -1, 384, -1, + 386, -1, -1, -1, -1, -1, 392, 393, -1, -1, + -1, -1, -1, -1, 264, 265, -1, 267, -1, -1, + 270, 271, -1, -1, -1, 275, 276, 277, -1, 279, + -1, 417, 418, 419, 420, 285, -1, -1, 288, -1, + -1, -1, -1, -1, -1, 295, -1, -1, -1, -1, + 300, -1, 302, 303, 304, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 316, -1, 318, 319, + -1, -1, 322, -1, -1, 325, -1, 327, -1, 329, + 330, 331, 332, -1, 334, -1, -1, -1, -1, -1, + -1, 341, -1, -1, 344, 345, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, 359, + 360, 361, 362, 363, -1, -1, -1, -1, -1, -1, + -1, 371, -1, -1, -1, -1, -1, 377, 378, 379, + 380, -1, -1, -1, 384, -1, 386, -1, -1, -1, + -1, -1, 392, 393, -1, -1, -1, -1, -1, -1, + 264, 265, -1, 267, -1, -1, 270, 271, -1, -1, + -1, 275, 276, 277, -1, 279, -1, 417, 418, 419, + 420, 285, -1, -1, 288, -1, -1, -1, -1, -1, + -1, 295, -1, -1, -1, -1, 300, -1, 302, 303, + 304, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 316, -1, 318, 319, -1, -1, 322, -1, + -1, 325, -1, 327, -1, 329, 330, 331, 332, -1, + 334, -1, -1, -1, -1, -1, -1, 341, -1, -1, + 344, 345, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 359, 360, 361, 362, 363, + -1, -1, -1, -1, -1, -1, -1, 371, -1, -1, + -1, -1, -1, 377, 378, 379, 380, -1, -1, -1, + 384, -1, 386, -1, -1, -1, -1, -1, 392, 393, + -1, -1, -1, -1, -1, -1, 264, 265, -1, 267, + -1, -1, 270, 271, -1, -1, -1, 275, 276, 277, + -1, 279, -1, 417, 418, 419, 420, 285, -1, -1, + 288, -1, -1, -1, -1, -1, -1, 295, -1, -1, + -1, -1, 300, -1, 302, 303, 304, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, 316, -1, + 318, 319, -1, -1, 322, -1, -1, 325, -1, 327, + -1, 329, 330, 331, 332, -1, 334, -1, -1, -1, + -1, -1, -1, 341, -1, -1, 344, 345, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, 359, 360, 361, 362, 363, -1, -1, -1, - -1, -1, -1, -1, 371, -1, -1, -1, -1, -1, - 377, 378, 379, 380, -1, -1, -1, 384, -1, 386, - -1, -1, -1, -1, -1, 392, 393, -1, -1, -1, - -1, -1, -1, 264, 265, -1, 267, -1, -1, 270, - 271, -1, -1, -1, 275, 276, 277, -1, 279, -1, - 417, 418, 419, 420, 285, -1, -1, 288, -1, -1, - -1, -1, -1, -1, 295, -1, -1, -1, -1, 300, - -1, 302, 303, 304, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 316, -1, 318, 319, -1, - -1, 322, -1, -1, 325, -1, 327, -1, 329, 330, - 331, 332, -1, 334, -1, -1, -1, -1, -1, -1, - 341, -1, -1, 344, 345, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 359, 360, - 361, 362, 363, -1, -1, -1, -1, -1, -1, -1, - 371, -1, -1, -1, -1, -1, 377, 378, 379, 380, - -1, -1, -1, 384, -1, 386, -1, -1, -1, -1, - -1, 392, 393, -1, -1, -1, -1, -1, -1, 264, - 265, -1, 267, -1, -1, 270, 271, -1, -1, -1, - 275, 276, 277, -1, 279, -1, 417, 418, 419, 420, + -1, 359, 360, 361, 362, 363, -1, -1, -1, -1, + -1, -1, -1, 371, -1, -1, -1, -1, -1, 377, + 378, 379, 380, -1, -1, -1, 384, -1, 386, -1, + -1, -1, -1, -1, 392, 393, -1, -1, -1, -1, + -1, -1, 264, 265, -1, 267, -1, -1, 270, 271, + -1, -1, -1, 275, 276, 277, -1, 279, -1, 417, + 418, 419, 420, 285, -1, -1, 288, -1, -1, -1, + -1, -1, -1, 295, -1, 261, -1, -1, 300, -1, + 302, 303, 304, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 316, -1, 318, 319, 284, -1, + 322, -1, -1, 325, -1, 327, -1, 329, 330, 331, + 332, 297, 334, -1, -1, -1, 302, -1, -1, -1, + -1, 307, -1, 309, 310, 311, 312, -1, -1, 315, + -1, 317, -1, -1, -1, 321, -1, 359, 360, 361, + 362, 363, -1, -1, -1, -1, -1, 333, -1, 371, + 336, -1, 338, -1, -1, 377, 378, 379, 380, -1, + -1, -1, 384, -1, 386, -1, -1, -1, -1, -1, + 392, 393, -1, -1, -1, -1, 362, -1, -1, -1, + -1, -1, 368, 369, -1, -1, -1, -1, -1, -1, + 263, -1, 265, -1, 267, 417, 418, 270, 420, 272, + 273, -1, 275, -1, 277, -1, 279, -1, 281, 282, + 283, -1, -1, -1, 287, 288, -1, -1, -1, -1, + 293, -1, 295, 296, -1, -1, -1, 300, -1, -1, + -1, 304, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 315, 316, -1, 318, -1, -1, -1, 322, + 323, -1, -1, -1, -1, -1, -1, 330, 331, 264, + 265, 334, 267, -1, 337, 270, 271, -1, -1, 342, + 275, 276, 277, -1, 279, -1, -1, -1, -1, -1, 285, -1, -1, 288, -1, -1, -1, -1, -1, -1, - 295, -1, -1, -1, -1, 300, -1, 302, 303, 304, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 295, 364, 365, -1, -1, 300, -1, 302, 303, 304, + -1, -1, -1, -1, 377, -1, -1, -1, -1, -1, -1, 316, -1, 318, 319, -1, -1, 322, -1, -1, 325, -1, 327, -1, 329, 330, 331, 332, -1, 334, - -1, -1, -1, -1, -1, -1, 341, -1, -1, 344, - 345, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 359, 360, 361, 362, 363, -1, - -1, -1, -1, -1, -1, -1, 371, -1, -1, -1, - -1, -1, 377, 378, 379, 380, -1, -1, -1, 384, - -1, 386, -1, -1, -1, -1, -1, 392, 393, -1, - -1, -1, -1, -1, -1, 264, 265, -1, 267, -1, - -1, 270, 271, -1, -1, -1, 275, 276, 277, -1, - 279, -1, 417, 418, 419, 420, 285, -1, -1, 288, - -1, -1, -1, -1, -1, -1, 295, -1, -1, -1, - -1, 300, -1, 302, 303, 304, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 316, -1, 318, - 319, -1, -1, 322, -1, -1, 325, -1, 327, -1, - 329, 330, 331, 332, -1, 334, -1, -1, -1, -1, - -1, -1, 341, -1, -1, 344, 345, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 359, 360, 361, 362, 363, -1, -1, -1, -1, -1, - -1, -1, 371, -1, -1, -1, -1, -1, 377, 378, - 379, 380, -1, -1, -1, 384, -1, 386, -1, -1, - -1, -1, -1, 392, 393, -1, -1, -1, -1, -1, - -1, 264, 265, -1, 267, -1, -1, 270, 271, -1, - -1, -1, 275, 276, 277, -1, 279, -1, 417, 418, - 419, 420, 285, -1, -1, 288, -1, -1, -1, -1, - -1, -1, 295, -1, 261, -1, 263, 300, -1, 302, - 303, 304, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 316, -1, 318, 319, 284, -1, 322, - -1, -1, 325, -1, 327, -1, 329, 330, 331, 332, - 297, 334, -1, -1, -1, 302, -1, -1, -1, -1, - 307, -1, 309, 310, 311, 312, -1, -1, -1, -1, - 317, -1, -1, -1, 321, -1, 359, 360, 361, 362, - 363, -1, -1, -1, -1, -1, 333, -1, 371, 336, - -1, 338, -1, -1, 377, 378, 379, 380, -1, -1, - -1, 384, -1, 386, -1, -1, -1, -1, -1, 392, - 393, -1, -1, -1, -1, 362, -1, -1, -1, -1, - -1, 368, 369, -1, -1, -1, -1, -1, -1, 263, - -1, 265, -1, 267, 417, 418, 270, 420, 272, 273, - -1, 275, -1, 277, -1, 279, -1, 281, 282, 283, + -1, -1, 337, -1, -1, -1, -1, -1, -1, 265, + -1, 267, -1, -1, 270, 418, 272, -1, -1, 275, + -1, -1, -1, 279, 359, 360, 361, 362, 363, -1, + -1, -1, 288, 265, -1, 267, 371, -1, 270, 295, + 272, 273, -1, 275, 300, 277, 302, 279, 304, 281, + 282, 283, -1, -1, -1, 287, 288, -1, -1, -1, + 316, 293, 318, 295, 296, -1, 322, 323, 300, -1, + -1, -1, 304, -1, 330, 331, -1, -1, 334, -1, + -1, 337, 417, 418, 316, -1, 318, -1, -1, -1, + 322, 323, -1, -1, -1, -1, -1, -1, 330, 331, + -1, 265, 334, 267, -1, 337, 270, -1, 272, 273, + 342, 275, -1, 277, -1, 279, -1, 281, 282, 283, -1, -1, -1, 287, 288, -1, -1, -1, -1, 293, -1, 295, 296, -1, -1, -1, 300, -1, -1, -1, - 304, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 315, 316, -1, 318, -1, -1, -1, 322, 323, - -1, -1, -1, -1, -1, -1, 330, 331, 264, 265, - 334, 267, -1, 337, 270, 271, -1, -1, 342, 275, - 276, 277, -1, 279, -1, -1, -1, -1, -1, 285, - -1, -1, 288, -1, -1, -1, -1, -1, -1, 295, - 364, 365, -1, -1, 300, -1, 302, 303, 304, -1, - -1, -1, -1, 377, -1, -1, -1, -1, -1, -1, - 316, -1, 318, 319, -1, -1, 322, -1, -1, 325, - -1, 327, -1, 329, 330, 331, 332, -1, 334, -1, - -1, 337, -1, -1, -1, -1, -1, -1, 265, -1, - 267, -1, -1, 270, 418, 272, -1, -1, 275, -1, - -1, -1, 279, 359, 360, 361, 362, -1, -1, -1, - -1, 288, 265, -1, 267, 371, -1, 270, 295, 272, - 273, -1, 275, 300, 277, 302, 279, 304, 281, 282, - 283, -1, -1, -1, 287, 288, -1, -1, -1, 316, - 293, 318, 295, 296, -1, 322, 323, 300, -1, -1, - -1, 304, -1, 330, 331, -1, -1, 334, -1, -1, - 337, 417, 418, 316, -1, 318, -1, -1, -1, 322, - 323, -1, -1, -1, -1, -1, -1, 330, 331, -1, - 265, 334, 267, -1, 337, 270, -1, 272, 273, 342, - 275, -1, 277, -1, 279, -1, 281, 282, 283, -1, - -1, -1, 287, 288, -1, -1, -1, -1, 293, -1, - 295, 296, -1, -1, -1, 300, -1, -1, -1, 304, - -1, -1, -1, -1, 377, -1, -1, -1, -1, -1, - -1, 316, -1, 318, -1, -1, -1, 322, 323, -1, - -1, 418, -1, -1, -1, 330, 331, -1, -1, 334, - -1, -1, 337, -1, 265, -1, 267, 342, -1, 270, - -1, -1, 273, -1, 275, 418, 277, -1, 279, -1, - 281, 282, 283, -1, -1, -1, 287, 288, -1, -1, - -1, -1, 293, -1, 295, -1, 265, -1, 267, 300, - -1, 270, -1, 304, 273, -1, 275, -1, 277, -1, - 279, -1, 281, 282, 283, 316, -1, 318, 287, 288, - -1, 322, -1, -1, 293, -1, 295, -1, -1, 330, - 331, 300, -1, 334, -1, 304, 337, -1, -1, -1, - 265, 342, 267, 418, -1, 270, -1, 316, -1, 318, - 275, -1, -1, 322, 279, -1, -1, -1, -1, -1, - -1, 330, 331, 288, -1, 334, -1, -1, 337, -1, - 295, -1, 265, 342, 267, 300, 377, 270, -1, 304, - -1, 306, 275, 308, -1, -1, 279, -1, 313, -1, - -1, 316, -1, 318, -1, 288, -1, 322, -1, -1, - 325, -1, 295, -1, -1, 330, 331, 300, -1, 334, - -1, 304, 337, 306, -1, 308, 265, 418, 267, -1, - 313, 270, -1, 316, -1, 318, 275, -1, -1, 322, - 279, -1, 325, -1, -1, -1, -1, 330, 331, 288, - -1, 334, -1, -1, 337, -1, 295, 372, 265, 418, - 267, 300, -1, 270, -1, 304, -1, 306, 275, 308, - -1, -1, 279, -1, 313, -1, -1, 316, -1, 318, - -1, 288, -1, 322, -1, -1, 325, 370, 295, -1, - -1, 330, 331, 300, -1, 334, -1, 304, 337, 306, - -1, 308, 265, 418, 267, -1, 313, 270, -1, 316, - -1, 318, 275, -1, -1, 322, 279, -1, 325, -1, - -1, -1, -1, 330, 331, 288, -1, 334, -1, -1, - 337, -1, 295, -1, -1, 418, -1, 300, -1, -1, - -1, 304, -1, 306, -1, -1, -1, 265, -1, 267, - 313, -1, 270, 316, -1, 318, -1, 275, -1, 322, - -1, 279, 325, -1, -1, 283, -1, 330, 331, -1, - 288, 334, -1, -1, 337, 293, -1, 295, -1, 418, - -1, -1, 300, -1, -1, 261, 304, 305, -1, -1, - -1, -1, -1, -1, -1, -1, 272, -1, 316, -1, - 318, 277, -1, -1, 322, 281, -1, -1, 284, -1, - -1, 418, 330, 331, -1, -1, 334, -1, -1, -1, - 296, 297, -1, -1, -1, 301, 302, -1, -1, -1, - -1, 307, -1, 309, 310, 311, 312, -1, -1, -1, - -1, 317, -1, -1, -1, 321, -1, 323, -1, -1, - -1, -1, -1, -1, -1, 418, -1, 333, -1, 335, - 336, 261, 338, -1, -1, -1, 342, -1, -1, -1, - -1, -1, 272, -1, -1, -1, -1, 277, -1, -1, - -1, 281, -1, -1, 284, -1, 362, -1, -1, -1, - -1, -1, 368, 369, -1, -1, 296, 297, -1, -1, - 418, 301, 302, -1, 261, -1, -1, 307, -1, 309, - 310, 311, 312, -1, -1, 272, -1, 317, -1, -1, - 277, 321, -1, 323, 281, -1, -1, 284, -1, -1, - -1, -1, -1, 333, -1, -1, 336, -1, 338, 296, - 297, -1, 342, -1, 301, 302, -1, 261, -1, -1, - 307, -1, 309, 310, 311, 312, -1, -1, 272, -1, - 317, -1, 362, 277, 321, -1, 323, 281, 368, 369, - 284, -1, -1, -1, -1, -1, 333, -1, -1, 336, - -1, 338, 296, 297, -1, 342, -1, 301, 302, 261, - -1, -1, -1, 307, -1, 309, 310, 311, 312, -1, - -1, -1, -1, 317, -1, 362, -1, 321, -1, 323, - -1, 368, 284, -1, -1, -1, -1, -1, -1, 333, - -1, -1, 336, -1, 338, 297, -1, 261, 342, -1, - 302, -1, -1, -1, -1, 307, -1, 309, 310, 311, - 312, -1, -1, -1, -1, 317, -1, -1, 362, 321, - 284, -1, -1, -1, 368, -1, -1, -1, -1, -1, - -1, 333, -1, 297, 336, 261, 338, -1, 302, -1, - -1, -1, -1, 307, -1, 309, 310, 311, 312, -1, - -1, -1, -1, 317, -1, -1, -1, 321, 284, -1, - 362, -1, 364, 365, -1, -1, 368, -1, -1, 333, - -1, 297, 336, 261, 338, 263, 302, -1, -1, -1, - -1, 307, -1, 309, 310, 311, 312, -1, -1, 315, - -1, 317, -1, -1, -1, 321, 284, -1, 362, -1, - 364, 365, -1, -1, 368, -1, -1, 333, -1, 297, - 336, 261, 338, -1, 302, -1, -1, -1, -1, 307, - -1, 309, 310, 311, 312, -1, -1, -1, -1, 317, - -1, -1, -1, 321, 284, -1, 362, -1, -1, -1, - -1, 261, 368, 263, -1, 333, -1, 297, 336, -1, - 338, -1, 302, -1, -1, -1, -1, 307, -1, 309, - 310, 311, 312, -1, 284, -1, -1, 317, -1, -1, - -1, 321, -1, -1, 362, -1, -1, 297, -1, -1, - 368, 261, 302, 333, -1, -1, 336, 307, 338, 309, - 310, 311, 312, -1, -1, 315, -1, 317, -1, -1, - -1, 321, -1, -1, 284, -1, -1, -1, -1, -1, - -1, 261, 362, 333, 364, 365, 336, 297, 338, -1, - -1, 301, 302, -1, -1, -1, -1, 307, -1, 309, - 310, 311, 312, -1, 284, -1, -1, 317, -1, -1, - -1, 321, 362, -1, -1, -1, -1, 297, -1, -1, - -1, -1, 302, 333, -1, -1, 336, 307, 338, 309, - 310, 311, 312, -1, -1, -1, -1, 317, -1, -1, - -1, 321, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, 362, 333, -1, -1, 336, -1, 338, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 304, -1, -1, -1, -1, 377, -1, -1, -1, -1, + -1, -1, 316, -1, 318, -1, -1, -1, 322, 323, + -1, -1, 418, -1, -1, -1, 330, 331, -1, -1, + 334, -1, -1, 337, -1, 265, -1, 267, 342, -1, + 270, -1, -1, 273, -1, 275, 418, 277, -1, 279, + -1, 281, 282, 283, -1, -1, -1, 287, 288, -1, + -1, -1, -1, 293, -1, 295, -1, 265, -1, 267, + 300, -1, 270, -1, 304, 273, -1, 275, -1, 277, + -1, 279, -1, 281, 282, 283, 316, -1, 318, 287, + 288, -1, 322, -1, -1, 293, -1, 295, -1, -1, + 330, 331, 300, -1, 334, -1, 304, 337, -1, -1, + -1, 265, 342, 267, 418, -1, 270, -1, 316, -1, + 318, 275, -1, -1, 322, 279, -1, -1, -1, -1, + -1, -1, 330, 331, 288, -1, 334, -1, -1, 337, + -1, 295, -1, 265, 342, 267, 300, 377, 270, -1, + 304, -1, 306, 275, 308, -1, -1, 279, -1, 313, + -1, -1, 316, -1, 318, -1, 288, -1, 322, -1, + -1, 325, -1, 295, -1, -1, 330, 331, 300, -1, + 334, -1, 304, 337, 306, -1, 308, 265, 418, 267, + -1, 313, 270, -1, 316, -1, 318, 275, -1, -1, + 322, 279, -1, 325, -1, -1, -1, -1, 330, 331, + 288, -1, 334, -1, -1, 337, -1, 295, 372, -1, + 418, -1, 300, -1, -1, -1, 304, -1, 306, -1, + -1, -1, -1, -1, -1, 313, -1, -1, 316, -1, + 318, -1, -1, -1, 322, -1, -1, 325, 370, -1, + -1, -1, 330, 331, -1, -1, 334, -1, 265, 337, + 267, -1, -1, 270, 418, -1, -1, -1, 275, -1, + -1, -1, 279, -1, -1, -1, -1, -1, -1, -1, + -1, 288, -1, -1, -1, 363, -1, -1, 295, -1, + 265, -1, 267, 300, -1, 270, 418, 304, -1, 306, + 275, 308, -1, -1, 279, -1, 313, -1, -1, 316, + -1, 318, -1, 288, -1, 322, -1, -1, 325, -1, + 295, -1, -1, 330, 331, 300, -1, 334, -1, 304, + 337, 306, -1, 308, -1, -1, -1, -1, 313, -1, + 418, 316, -1, 318, -1, -1, -1, 322, -1, -1, + 325, -1, -1, -1, -1, 330, 331, -1, -1, 334, + -1, 265, 337, 267, -1, -1, 270, -1, -1, -1, + -1, 275, -1, -1, -1, 279, -1, -1, -1, 283, + -1, -1, -1, -1, 288, 265, -1, 267, -1, 293, + 270, 295, -1, -1, -1, 275, 300, -1, -1, 279, + 304, 305, -1, -1, -1, -1, -1, -1, 288, -1, + -1, 418, 316, -1, 318, 295, -1, -1, 322, -1, + 300, -1, -1, -1, 304, -1, 330, 331, -1, -1, + 334, -1, -1, 337, -1, 265, 316, 267, 318, -1, + 270, -1, 322, 418, -1, 275, -1, -1, -1, 279, + 330, 331, -1, -1, 334, -1, -1, 337, 288, 265, + -1, 267, -1, -1, 270, 295, -1, -1, -1, 275, + 300, -1, -1, 279, 304, -1, -1, -1, -1, -1, + -1, -1, 288, -1, -1, -1, 316, -1, 318, 295, + -1, -1, 322, -1, 300, -1, -1, -1, 304, -1, + 330, 331, -1, -1, 334, -1, 261, 337, -1, -1, + 316, -1, 318, -1, 418, -1, 322, 272, -1, -1, + -1, -1, 277, -1, 330, 331, 281, -1, 334, 284, + -1, 337, -1, -1, -1, -1, -1, -1, 418, -1, + -1, 296, 297, -1, -1, -1, 301, 302, -1, 261, + -1, -1, 307, -1, 309, 310, 311, 312, -1, -1, + 272, -1, 317, -1, -1, 277, 321, -1, 323, 281, + -1, -1, 284, -1, -1, -1, -1, -1, 333, -1, + 335, 336, -1, 338, 296, 297, -1, 342, 418, 301, + 302, -1, 261, -1, 263, 307, -1, 309, 310, 311, + 312, -1, -1, -1, -1, 317, -1, 362, -1, 321, + -1, 323, 418, 368, 369, 284, -1, -1, -1, -1, + -1, 333, -1, -1, 336, -1, 338, -1, 297, -1, + 342, -1, -1, 302, -1, 261, -1, -1, 307, -1, + 309, 310, 311, 312, -1, -1, 272, -1, 317, -1, + 362, 277, 321, -1, -1, 281, 368, 369, 284, -1, + -1, -1, -1, -1, 333, -1, -1, 336, -1, 338, + 296, 297, -1, -1, -1, 301, 302, -1, 261, -1, + -1, 307, -1, 309, 310, 311, 312, -1, -1, 272, + -1, 317, -1, 362, 277, 321, -1, 323, 281, 368, + 369, 284, -1, -1, -1, -1, -1, 333, -1, -1, + 336, -1, 338, 296, 297, -1, 342, -1, 301, 302, + 261, -1, -1, -1, 307, -1, 309, 310, 311, 312, + -1, -1, -1, -1, 317, -1, 362, -1, 321, -1, + 323, -1, 368, 284, -1, -1, -1, -1, -1, -1, + 333, -1, -1, 336, -1, 338, 297, -1, 261, 342, + -1, 302, -1, -1, -1, -1, 307, -1, 309, 310, + 311, 312, -1, -1, -1, -1, 317, -1, -1, 362, + 321, 284, -1, -1, -1, 368, -1, -1, -1, -1, + -1, -1, 333, -1, 297, 336, 261, 338, -1, 302, + -1, -1, -1, -1, 307, -1, 309, 310, 311, 312, + -1, -1, -1, -1, 317, -1, -1, -1, 321, 284, + -1, 362, -1, 364, 365, -1, -1, 368, -1, -1, + 333, -1, 297, 336, 261, 338, 263, 302, -1, -1, + -1, -1, 307, -1, 309, 310, 311, 312, -1, -1, + 315, -1, 317, -1, -1, -1, 321, 284, -1, 362, + -1, 364, 365, -1, -1, 368, -1, -1, 333, -1, + 297, 336, 261, 338, 263, 302, -1, -1, -1, -1, + 307, -1, 309, 310, 311, 312, -1, -1, -1, -1, + 317, -1, -1, -1, 321, 284, -1, 362, -1, -1, + -1, -1, 261, 368, -1, -1, 333, -1, 297, 336, + -1, 338, -1, 302, -1, -1, -1, -1, 307, -1, + 309, 310, 311, 312, -1, 284, 315, -1, 317, -1, + -1, -1, 321, -1, 261, 362, -1, -1, 297, -1, + -1, 368, 301, 302, 333, -1, -1, 336, 307, 338, + 309, 310, 311, 312, -1, -1, -1, 284, 317, -1, + -1, -1, 321, -1, -1, -1, -1, -1, -1, -1, + 297, -1, -1, 362, 333, 302, -1, 336, -1, 338, + 307, -1, 309, 310, 311, 312, -1, -1, -1, -1, + 317, -1, -1, -1, 321, -1, -1, -1, -1, -1, + -1, -1, -1, 362, -1, -1, 333, -1, -1, 336, + -1, 338, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, 362, + -1, -1, -1, -1, -1, 362, }; -#line 6654 "cs-parser.jay" +#line 7153 "cs-parser.jay" // // A class used to hold info about an operator declarator @@ -12793,7 +14612,7 @@ void Error_ExpectingTypeName (Expression expr) if (expr is Invocation){ report.Error (1002, expr.Location, "Expecting `;'"); } else { - Expression.Error_InvalidExpressionStatement (report, expr.Location); + expr.Error_InvalidExpressionStatement (report); } } @@ -12834,6 +14653,16 @@ void Error_MissingInitializer (Location loc) report.Error (210, loc, "You must provide an initializer in a fixed or using statement declaration"); } +object Error_AwaitAsIdentifier (object token) +{ + if (async_block) { + report.Error (4003, GetLocation (token), "`await' cannot be used as an identifier within an async method or lambda expression"); + return new LocatedToken ("await", GetLocation (token)); + } + + return token; +} + void push_current_container (TypeDefinition tc, object partial_token) { if (module.Evaluator != null){ @@ -12883,15 +14712,37 @@ List> GetModifierLocations () return result; } -string CheckAttributeTarget (string a, Location l) +[System.Diagnostics.Conditional ("FULL_AST")] +void PushLocation (Location loc) +{ + if (location_stack == null) + location_stack = new Stack (); + + location_stack.Push (loc); +} + +Location PopLocation () +{ + if (location_stack == null) + return Location.Null; + + return location_stack.Pop (); +} + +string CheckAttributeTarget (int token, string a, Location l) { switch (a) { case "assembly" : case "module" : case "field" : case "method" : case "param" : case "property" : case "type" : return a; } - report.Warning (658, 1, l, - "`{0}' is invalid attribute target. All attributes in this attribute section will be ignored", a); + if (!Tokenizer.IsValidIdentifier (a)) { + Error_SyntaxError (token); + } else { + report.Warning (658, 1, l, + "`{0}' is invalid attribute target. All attributes in this attribute section will be ignored", a); + } + return string.Empty; } @@ -12943,7 +14794,7 @@ public CSharpParser (SeekableStreamReader reader, CompilationSourceFile file, Re lang_version = settings.Version; yacc_verbose_flag = settings.VerboseParserFlag; doc_support = settings.DocumentationFile != null; - lexer = new Tokenizer (reader, file, session); + lexer = new Tokenizer (reader, file, session, report); oob_stack = new Stack (); lbag = session.LocationsBag; use_global_stacks = session.UseJayGlobalArrays; @@ -12970,7 +14821,8 @@ public void parse () } if (e is yyParser.yyException) { - report.Error (-25, lexer.Location, "Parsing error"); + if (report.Errors == 0) + report.Error (-25, lexer.Location, "Parsing error"); } else { // Used by compiler-tester to test internal errors if (yacc_verbose_flag > 0 || e is FatalException) @@ -13004,7 +14856,7 @@ void FeatureIsNotAvailable (Location loc, string feature) Location GetLocation (object obj) { - var lt = obj as Tokenizer.LocatedToken; + var lt = obj as LocatedToken; if (lt != null) return lt.Location; @@ -13082,7 +14934,7 @@ AnonymousMethodExpression end_anonymous (ParametersBlock anon_block) retval = current_anonymous_method; async_block = (bool) oob_stack.Pop (); - current_variable = (BlockVariableDeclaration) oob_stack.Pop (); + current_variable = (BlockVariable) oob_stack.Pop (); current_local_parameters = (ParametersCompiled) oob_stack.Pop (); current_anonymous_method = (AnonymousMethodExpression) oob_stack.Pop (); @@ -13106,6 +14958,10 @@ void Error_SyntaxError (int error_code, int token, string msg) // An error message has been reported by tokenizer if (token == Token.ERROR) return; + + // Avoid duplicit error message after unterminated string literals + if (token == Token.LITERAL && lexer.Location.Column == 0) + return; string symbol = GetSymbolName (token); string expecting = GetExpecting (); @@ -13187,7 +15043,7 @@ string GetSymbolName (int token) case Token.LITERAL: return ((Constant)lexer.Value).GetValue ().ToString (); case Token.IDENTIFIER: - return ((Tokenizer.LocatedToken)lexer.Value).Value; + return ((LocatedToken)lexer.Value).Value; case Token.BOOL: return "bool"; diff --git a/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/cs-parser.jay b/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/cs-parser.jay index 1299f6d93..f3c9ae005 100644 --- a/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/cs-parser.jay +++ b/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/cs-parser.jay @@ -35,7 +35,8 @@ namespace Mono.CSharp Arglist = 1 << 5, DefaultValue = 1 << 6, - All = Ref | Out | This | Params | Arglist | DefaultValue + All = Ref | Out | This | Params | Arglist | DefaultValue, + PrimaryConstructor = Ref | Out | Params | DefaultValue } static readonly object ModifierNone = 0; @@ -54,7 +55,7 @@ namespace Mono.CSharp /// Block current_block; - BlockVariableDeclaration current_variable; + BlockVariable current_variable; Delegate current_delegate; @@ -116,6 +117,8 @@ namespace Mono.CSharp // Keeps track of global data changes to undo on parser error // public Undo undo; + + bool? interactive_async; Stack linq_clause_blocks; @@ -139,15 +142,15 @@ namespace Mono.CSharp // LocationsBag lbag; List> mod_locations; - Location parameterModifierLocation, savedLocation, savedOpenLocation, savedCloseLocation; + Location parameterModifierLocation, savedLocation, savedEventAssignLocation; Location savedAttrParenOpenLocation, savedAttrParenCloseLocation, savedOperatorLocation; Stack> locationListStack = new Stack> (); // used for type parameters Stack opt_intoStack = new Stack (); bool HadAttributeParens; - List attributeCommas = new List (); List attributeArgumentCommas = new List (); List parameterListCommas = new List (); + Stack location_stack; %} %token EOF @@ -425,7 +428,7 @@ extern_alias_directives extern_alias_directive : EXTERN_ALIAS IDENTIFIER IDENTIFIER SEMICOLON { - var lt = (Tokenizer.LocatedToken) $2; + var lt = (LocatedToken) $2; string s = lt.Value; if (s != "alias") { syntax_error (lt.Location, "`alias' expected"); @@ -433,7 +436,7 @@ extern_alias_directive if (lang_version == LanguageVersion.ISO_1) FeatureIsNotAvailable (lt.Location, "external alias"); - lt = (Tokenizer.LocatedToken) $3; + lt = (LocatedToken) $3; if (lt.Value == QualifiedAliasMember.GlobalAlias) { RootNamespace.Error_GlobalNamespaceRedefined (report, lt.Location); } @@ -473,7 +476,7 @@ using_namespace } | USING IDENTIFIER ASSIGN namespace_or_type_expr SEMICOLON { - var lt = (Tokenizer.LocatedToken) $2; + var lt = (LocatedToken) $2; if (lang_version != LanguageVersion.ISO_1 && lt.Value == "global") { report.Warning (440, 2, lt.Location, "An alias named `global' will not be used when resolving `global::'. The global namespace will be used instead"); @@ -529,7 +532,7 @@ namespace_declaration if (doc_support) Lexer.doc_state = XmlCommentState.Allowed; } - opt_extern_alias_directives opt_using_directives opt_namespace_or_type_declarations CLOSE_BRACE opt_semicolon + opt_extern_alias_directives opt_using_directives opt_namespace_or_type_declarations CLOSE_BRACE opt_semicolon_error { if ($11 != null) lbag.AddLocation (current_container, GetLocation ($2), GetLocation ($5), GetLocation ($10), GetLocation ($11)); @@ -538,20 +541,38 @@ namespace_declaration current_container = current_namespace = current_namespace.Parent; } + | opt_attributes NAMESPACE namespace_name + { + report.Error (1514, lexer.Location, "Unexpected symbol `{0}', expecting `.' or `{{'", GetSymbolName (yyToken)); + + var name = (MemberName) $3; + var ns = new NamespaceContainer (name, current_namespace); + lbag.AddLocation (ns, GetLocation ($2)); + current_namespace.AddTypeContainer (ns); + } + ; + +opt_semicolon_error + : /* empty */ + | SEMICOLON + | error + { + Error_SyntaxError (yyToken); + $$ = null; + } ; namespace_name : IDENTIFIER { - var lt = (Tokenizer.LocatedToken) $1; + var lt = (LocatedToken) $1; $$ = new MemberName (lt.Value, lt.Location); } | namespace_name DOT IDENTIFIER { - var lt = (Tokenizer.LocatedToken) $3; - $$ = new MemberName ((MemberName) $1, lt.Value, lt.Location) { - DotLocation = GetLocation ($2) - }; + var lt = (LocatedToken) $3; + $$ = new MemberName ((MemberName) $1, lt.Value, lt.Location); + lbag.AddLocation ($$, GetLocation ($2)); } | error { @@ -650,23 +671,14 @@ attribute_sections { var sect = (List) $1; $$ = new Attributes (sect); - if (locationListStack.Count > 0) - lbag.AddLocation (sect, locationListStack.Pop ()); - if (attributeCommas.Count > 0) { - lbag.AppendTo (sect, attributeCommas); - attributeCommas.Clear (); - } } | attribute_sections attribute_section { Attributes attrs = $1 as Attributes; var sect = (List) $2; - - if (locationListStack.Count > 0) - lbag.AddLocation (sect, locationListStack.Pop ()); if (attrs == null) attrs = new Attributes (sect); - else + else if (sect != null) attrs.AddAttributes (sect); $$ = attrs; } @@ -675,8 +687,8 @@ attribute_sections attribute_section : OPEN_BRACKET { + PushLocation (GetLocation ($1)); lexer.parsing_attribute_section = true; - savedOpenLocation = GetLocation ($1); } attribute_section_cont { @@ -700,45 +712,55 @@ attribute_section_cont $$ = new List (0); else $$ = $4; - - current_attr_target = null; - lexer.parsing_attribute_section = false; + lbag.InsertLocation ($$, 0, GetLocation ($2)); + lbag.InsertLocation ($$, 0, PopLocation ()); + lbag.InsertLocation ($$, 0, PopLocation ()); if ($5 != null) { - locationListStack.Push (new List(new [] { savedOpenLocation, savedCloseLocation, GetLocation ($2), GetLocation ($5), GetLocation ($6) })); + lbag.AddLocation ($$, GetLocation ($5), GetLocation ($6)); } else { - locationListStack.Push (new List(new [] { savedOpenLocation, savedCloseLocation, GetLocation ($2), GetLocation ($6) })); + lbag.AddLocation ($$, GetLocation ($6)); } + + current_attr_target = null; + lexer.parsing_attribute_section = false; } | attribute_list opt_comma CLOSE_BRACKET { $$ = $1; + lbag.InsertLocation ($$, 0, PopLocation ()); if ($2 != null) { - locationListStack.Push (new List(new [] { savedOpenLocation, GetLocation ($2), GetLocation ($3) })); + lbag.AddLocation ($$, GetLocation($2), GetLocation ($3)); } else { - locationListStack.Push (new List(new [] { savedOpenLocation, GetLocation ($3) })); + lbag.AddLocation ($$, GetLocation($3)); } } + | IDENTIFIER error + { + Error_SyntaxError (yyToken); + + var lt = (LocatedToken) $1; + var tne = new SimpleName (lt.Value, null, lt.Location); + + $$ = new List () { + new Attribute (null, tne, null, GetLocation ($1), false) + }; + } + | error + { + CheckAttributeTarget (yyToken, GetTokenName (yyToken), GetLocation ($1)); + $$ = null; + } ; attribute_target : IDENTIFIER { - var lt = (Tokenizer.LocatedToken) $1; - $$ = CheckAttributeTarget (lt.Value, lt.Location); - savedCloseLocation = GetLocation ($1); - } - | EVENT { $$ = "event"; savedCloseLocation = GetLocation ($1); } - | RETURN { $$ = "return"; savedCloseLocation = GetLocation ($1); } - | error - { - if (yyToken == Token.IDENTIFIER) { - Error_SyntaxError (yyToken); - $$ = null; - } else { - string name = GetTokenName (yyToken); - $$ = CheckAttributeTarget (name, GetLocation ($1)); - } + var lt = (LocatedToken) $1; + $$ = CheckAttributeTarget (yyToken, lt.Value, lt.Location); + PushLocation (GetLocation ($1)); } + | EVENT { $$ = "event"; PushLocation (GetLocation ($1)); } + | RETURN { $$ = "return"; PushLocation (GetLocation ($1)); } ; attribute_list @@ -749,8 +771,10 @@ attribute_list | attribute_list COMMA attribute { var attrs = (List) $1; - attrs.Add ((Attribute) $3); - attributeCommas.Add (GetLocation ($2)); + if (attrs != null) { + attrs.Add ((Attribute) $3); + lbag.AddLocation (attrs, GetLocation ($2)); + } $$ = attrs; } @@ -846,6 +870,11 @@ positional_or_named_argument $$ = new Argument ((Expression) $1); } | named_argument + | error + { + Error_SyntaxError (yyToken); + $$ = null; + } ; named_attribute_argument @@ -856,14 +885,14 @@ named_attribute_argument expression { --lexer.parsing_block; - var lt = (Tokenizer.LocatedToken) $1; + var lt = (LocatedToken) $1; $$ = new NamedArgument (lt.Value, lt.Location, (Expression) $4); lbag.AddLocation ($$, GetLocation($2)); } ; named_argument - : identifier_inside_body COLON opt_named_modifier expression + : identifier_inside_body COLON opt_named_modifier expression_or_error { if (lang_version <= LanguageVersion.V_3) FeatureIsNotAvailable (GetLocation ($1), "named argument"); @@ -871,7 +900,7 @@ named_argument // Avoid boxing in common case (no modifier) var arg_mod = $3 == null ? Argument.AType.None : (Argument.AType) $3; - var lt = (Tokenizer.LocatedToken) $1; + var lt = (LocatedToken) $1; $$ = new NamedArgument (lt.Value, lt.Location, (Expression) $4, arg_mod); lbag.AddLocation ($$, GetLocation($2)); } @@ -898,10 +927,12 @@ class_member_declarations : class_member_declaration { lexer.parsing_modifiers = true; + lexer.parsing_block = 0; } | class_member_declarations class_member_declaration { lexer.parsing_modifiers = true; + lexer.parsing_block = 0; } ; @@ -917,13 +948,14 @@ class_member_declaration | destructor_declaration | type_declaration | attributes_without_members + | incomplete_member | error { report.Error (1519, lexer.Location, "Unexpected symbol `{0}' in class, struct, or interface member declaration", GetSymbolName (yyToken)); $$ = null; lexer.parsing_generic_declaration = false; - } + } ; struct_declaration @@ -932,20 +964,26 @@ struct_declaration opt_partial STRUCT { - lexer.ConstraintsParsing = true; } type_declaration_name { + lexer.ConstraintsParsing = true; + valid_param_mod = ParameterModifierType.PrimaryConstructor; push_current_container (new Struct (current_container, (MemberName) $6, (Modifiers) $2, (Attributes) $1), $3); lbag.AddMember (current_container, GetModifierLocations (), GetLocation ($4)); } + opt_primary_parameters opt_class_base opt_type_parameter_constraints_clauses { + valid_param_mod = 0; lexer.ConstraintsParsing = false; - if ($9 != null) - current_container.SetConstraints ((List) $9); + if ($8 != null) + current_type.PrimaryConstructorParameters = (ParametersCompiled) $8; + + if ($10 != null) + current_container.SetConstraints ((List) $10); if (doc_support) current_container.PartialContainer.DocComment = Lexer.consume_doc_comment (); @@ -967,9 +1005,9 @@ struct_declaration opt_semicolon { if ($16 == null) { - lbag.AppendToMember (current_container, GetLocation ($11), GetLocation ($14)); + lbag.AppendToMember (current_container, GetLocation ($12), GetLocation ($15)); } else { - lbag.AppendToMember (current_container, GetLocation ($11), GetLocation ($14), GetLocation ($16)); + lbag.AppendToMember (current_container, GetLocation ($12), GetLocation ($15), GetLocation ($17)); } $$ = pop_current_class (); } @@ -984,7 +1022,7 @@ constant_declaration opt_modifiers CONST type IDENTIFIER { - var lt = (Tokenizer.LocatedToken) $5; + var lt = (LocatedToken) $5; var mod = (Modifiers) $2; current_field = new Const (current_type, (FullNamedExpression) $4, mod, new MemberName (lt.Value, lt.Location), (Attributes) $1); current_type.AddMember (current_field); @@ -1006,6 +1044,14 @@ constant_declaration lbag.AddMember (current_field, GetModifierLocations (), GetLocation ($3), GetLocation ($9)); current_field = null; } + | opt_attributes + opt_modifiers + CONST type error + { + Error_SyntaxError (yyToken); + + current_type.AddMember (new Const (current_type, (FullNamedExpression) $4, (Modifiers) $2, MemberName.Null, (Attributes) $1)); + } ; opt_constant_declarators @@ -1027,7 +1073,7 @@ constant_declarators constant_declarator : COMMA IDENTIFIER constant_initializer { - var lt = (Tokenizer.LocatedToken) $2; + var lt = (LocatedToken) $2; $$ = new FieldDeclarator (new SimpleMemberName (lt.Value, lt.Location), (ConstInitializer) $3); lbag.AddLocation ($$, GetLocation ($1)); } @@ -1067,7 +1113,7 @@ field_declaration if (type.Type != null && type.Type.Kind == MemberKind.Void) report.Error (670, GetLocation ($3), "Fields cannot have void type"); - var lt = (Tokenizer.LocatedToken) $4; + var lt = (LocatedToken) $4; current_field = new Field (current_type, type, (Modifiers) $2, new MemberName (lt.Value, lt.Location), (Attributes) $1); current_type.AddField (current_field); $$ = current_field; @@ -1092,7 +1138,7 @@ field_declaration if (lang_version < LanguageVersion.ISO_2) FeatureIsNotAvailable (GetLocation ($3), "fixed size buffers"); - var lt = (Tokenizer.LocatedToken) $5; + var lt = (LocatedToken) $5; current_field = new FixedField (current_type, (FullNamedExpression) $4, (Modifiers) $2, new MemberName (lt.Value, lt.Location), (Attributes) $1); @@ -1156,7 +1202,7 @@ field_declarators field_declarator : COMMA IDENTIFIER { - var lt = (Tokenizer.LocatedToken) $2; + var lt = (LocatedToken) $2; $$ = new FieldDeclarator (new SimpleMemberName (lt.Value, lt.Location), null); lbag.AddLocation ($$, GetLocation ($1)); } @@ -1167,7 +1213,7 @@ field_declarator variable_initializer { --lexer.parsing_block; - var lt = (Tokenizer.LocatedToken) $2; + var lt = (LocatedToken) $2; $$ = new FieldDeclarator (new SimpleMemberName (lt.Value, lt.Location), (Expression) $5); lbag.AddLocation ($$, GetLocation ($1), GetLocation ($3)); } @@ -1192,7 +1238,7 @@ fixed_field_declarators fixed_field_declarator : COMMA IDENTIFIER fixed_field_size { - var lt = (Tokenizer.LocatedToken) $2; + var lt = (LocatedToken) $2; $$ = new FieldDeclarator (new SimpleMemberName (lt.Value, lt.Location), (ConstInitializer) $3); lbag.AddLocation ($$, GetLocation ($1)); } @@ -1233,10 +1279,7 @@ method_declaration if (doc_support) Lexer.doc_state = XmlCommentState.NotAllowed; - // Add it early in the case of body being eof for full ast - Method m = (Method) $1; - async_block = (m.ModFlags & Modifiers.ASYNC) != 0; - current_type.AddMember (m); + // Was added earlier in the case of body being eof for full ast } method_body { @@ -1276,26 +1319,35 @@ method_header } opt_formal_parameter_list CLOSE_PARENS { - lexer.ConstraintsParsing = true; - } - opt_type_parameter_constraints_clauses - { - lexer.ConstraintsParsing = false; valid_param_mod = 0; MemberName name = (MemberName) $4; current_local_parameters = (ParametersCompiled) $7; var method = Method.Create (current_type, (FullNamedExpression) $3, (Modifiers) $2, - name, current_local_parameters, (Attributes) $1, $10 != null); + name, current_local_parameters, (Attributes) $1); + + current_type.AddMember (method); + + async_block = (method.ModFlags & Modifiers.ASYNC) != 0; - if ($10 != null) - method.SetConstraints ((List) $10); - if (doc_support) method.DocComment = Lexer.consume_doc_comment (); lbag.AddMember (method, GetModifierLocations (), GetLocation ($5), GetLocation ($8)); $$ = method; + + lexer.ConstraintsParsing = true; + } + opt_type_parameter_constraints_clauses + { + lexer.ConstraintsParsing = false; + + if ($10 != null) { + var method = (Method) $9; + method.SetConstraints ((List) $10); + } + + $$ = $9; } | opt_attributes opt_modifiers @@ -1326,10 +1378,14 @@ method_header modifiers |= Modifiers.PARTIAL; var method = Method.Create (current_type, new TypeExpression (compiler.BuiltinTypes.Void, GetLocation ($4)), - modifiers, name, current_local_parameters, (Attributes) $1, $11 != null); + modifiers, name, current_local_parameters, (Attributes) $1); - if ($11 != null) - method.SetConstraints ((List) $11); + current_type.AddMember (method); + + async_block = (method.ModFlags & Modifiers.ASYNC) != 0; + + if ($12 != null) + method.SetConstraints ((List) $12); if (doc_support) method.DocComment = Lexer.consume_doc_comment (); @@ -1348,7 +1404,9 @@ method_header "Member modifier `{0}' must precede the member type and name", ModifiersExtensions.Name ((Modifiers) $4)); var method = Method.Create (current_type, (FullNamedExpression) $3, - 0, name, (ParametersCompiled) $7, (Attributes) $1, false); + 0, name, (ParametersCompiled) $7, (Attributes) $1); + + current_type.AddMember (method); current_local_parameters = (ParametersCompiled) $7; @@ -1367,7 +1425,9 @@ method_header MemberName name = (MemberName) $4; var method = Method.Create (current_type, (FullNamedExpression) $3, (Modifiers) $2, - name, current_local_parameters, (Attributes) $1, false); + name, current_local_parameters, (Attributes) $1); + + current_type.AddMember (method); if (doc_support) method.DocComment = Lexer.consume_doc_comment (); @@ -1500,18 +1560,18 @@ fixed_parameter : opt_attributes opt_parameter_modifier parameter_type - IDENTIFIER + identifier_inside_body { - var lt = (Tokenizer.LocatedToken) $4; + var lt = (LocatedToken) $4; $$ = new Parameter ((FullNamedExpression) $3, lt.Value, (Parameter.Modifier) $2, (Attributes) $1, lt.Location); lbag.AddLocation ($$, parameterModifierLocation); } | opt_attributes opt_parameter_modifier parameter_type - IDENTIFIER OPEN_BRACKET CLOSE_BRACKET + identifier_inside_body OPEN_BRACKET CLOSE_BRACKET { - var lt = (Tokenizer.LocatedToken) $4; + var lt = (LocatedToken) $4; report.Error (1552, lt.Location, "Array type specifier, [], must appear before parameter name"); $$ = new Parameter ((FullNamedExpression) $3, lt.Value, (Parameter.Modifier) $2, (Attributes) $1, lt.Location); lbag.AddLocation ($$, parameterModifierLocation); @@ -1535,7 +1595,7 @@ fixed_parameter | opt_attributes opt_parameter_modifier parameter_type - IDENTIFIER + identifier_inside_body ASSIGN { ++lexer.parsing_block; @@ -1570,7 +1630,7 @@ fixed_parameter if ((valid_param_mod & ParameterModifierType.DefaultValue) == 0) report.Error (1065, GetLocation ($5), "Optional parameter is not valid in this context"); - var lt = (Tokenizer.LocatedToken) $4; + var lt = (LocatedToken) $4; $$ = new Parameter ((FullNamedExpression) $3, lt.Value, mod, (Attributes) $1, lt.Location); lbag.AddLocation ($$, parameterModifierLocation, GetLocation ($5)); // parameterModifierLocation should be ignored when mod == NONE @@ -1642,7 +1702,7 @@ parameter_modifier parameter_array : opt_attributes params_modifier type IDENTIFIER { - var lt = (Tokenizer.LocatedToken) $4; + var lt = (LocatedToken) $4; $$ = new ParamsParameter ((FullNamedExpression) $3, lt.Value, (Attributes) $1, lt.Location); lbag.AddLocation ($$, savedLocation); } @@ -1650,14 +1710,15 @@ parameter_array { report.Error (1751, GetLocation ($2), "Cannot specify a default value for a parameter array"); - var lt = (Tokenizer.LocatedToken) $4; + var lt = (LocatedToken) $4; $$ = new ParamsParameter ((FullNamedExpression) $3, lt.Value, (Attributes) $1, lt.Location); lbag.AddLocation ($$, savedLocation); } | opt_attributes params_modifier type error { Error_SyntaxError (yyToken); - $$ = null; + + $$ = new ParamsParameter ((FullNamedExpression) $3, null, (Attributes) $1, Location.Null); } ; @@ -1736,7 +1797,7 @@ indexer_declaration { valid_param_mod = ParameterModifierType.Params | ParameterModifierType.DefaultValue; } - opt_formal_parameter_list CLOSE_BRACKET OPEN_BRACE + opt_formal_parameter_list CLOSE_BRACKET { valid_param_mod = 0; var type = (FullNamedExpression) $3; @@ -1745,7 +1806,7 @@ indexer_declaration current_property = indexer; current_type.AddIndexer (indexer); - lbag.AddMember (current_property, GetModifierLocations (), GetLocation ($5), GetLocation ($8), GetLocation ($9)); + lbag.AddMember (current_property, GetModifierLocations (), GetLocation ($5), GetLocation ($8)); if (type.Type != null && type.Type.Kind == MemberKind.Void) report.Error (620, GetLocation ($3), "`{0}': indexer return type cannot be `void'", indexer.GetSignatureForError ()); @@ -1761,7 +1822,7 @@ indexer_declaration lexer.PropertyParsing = true; } - accessor_declarations + OPEN_BRACE accessor_declarations { lexer.PropertyParsing = false; } @@ -1773,7 +1834,7 @@ indexer_declaration if (doc_support) current_property.DocComment = ConsumeStoredComment (); - lbag.AppendToMember (current_property, GetLocation ($12)); + lbag.AppendToMember (current_property, GetLocation ($10), GetLocation ($13)); current_property = null; } ; @@ -1912,10 +1973,10 @@ interface_declaration opt_partial INTERFACE { - lexer.ConstraintsParsing = true; } type_declaration_name { + lexer.ConstraintsParsing = true; push_current_container (new Interface (current_container, (MemberName) $6, (Modifiers) $2, (Attributes) $1), $3); lbag.AddMember (current_container, GetModifierLocations (), GetLocation ($4)); } @@ -1964,10 +2025,12 @@ interface_member_declarations : interface_member_declaration { lexer.parsing_modifiers = true; + lexer.parsing_block = 0; } | interface_member_declarations interface_member_declaration { lexer.parsing_modifiers = true; + lexer.parsing_block = 0; } ; @@ -2024,7 +2087,7 @@ operator_declaration lbag.AddMember (op, GetModifierLocations (), lbag.GetLocations (decl)); if ($5 == null) { // Semicolon - lbag.AppendTo (op, savedLocation); + lbag.AddLocation (op, savedLocation); } } @@ -2075,11 +2138,11 @@ operator_declarator Operator.GetName (op)); } } else { - if (p_count > 2) { + if (p_count == 1) { + report.Error (1019, loc, "Overloadable unary operator expected"); + } else if (p_count != 2) { report.Error (1534, loc, "Overloaded binary operator `{0}' takes two parameters", Operator.GetName (op)); - } else if (p_count != 2) { - report.Error (1019, loc, "Overloadable unary operator expected"); } } @@ -2133,7 +2196,11 @@ conversion_operator_declarator Location loc = GetLocation ($2); current_local_parameters = (ParametersCompiled)$6; - + + if (current_local_parameters.Count != 1) { + report.Error (1535, loc, "Overloaded unary operator `implicit' takes one parameter"); + } + if (doc_support) { tmpComment = Lexer.consume_doc_comment (); Lexer.doc_state = XmlCommentState.NotAllowed; @@ -2152,7 +2219,11 @@ conversion_operator_declarator Location loc = GetLocation ($2); current_local_parameters = (ParametersCompiled)$6; - + + if (current_local_parameters.Count != 1) { + report.Error (1535, loc, "Overloaded unary operator `explicit' takes one parameter"); + } + if (doc_support) { tmpComment = Lexer.consume_doc_comment (); Lexer.doc_state = XmlCommentState.NotAllowed; @@ -2208,7 +2279,7 @@ constructor_declarator valid_param_mod = 0; current_local_parameters = (ParametersCompiled) $6; - var lt = (Tokenizer.LocatedToken) $3; + var lt = (LocatedToken) $3; var mods = (Modifiers) $2; var c = new Constructor (current_type, lt.Value, mods, (Attributes) $1, current_local_parameters, lt.Location); @@ -2305,7 +2376,7 @@ destructor_declaration } IDENTIFIER OPEN_PARENS CLOSE_PARENS method_body { - var lt = (Tokenizer.LocatedToken) $5; + var lt = (LocatedToken) $5; if (lt.Value != current_container.MemberName.Name){ report.Error (574, lt.Location, "Name of destructor must match name of class"); } else if (current_container.Kind != MemberKind.Class){ @@ -2349,8 +2420,11 @@ event_declaration current_event_field.DocComment = Lexer.consume_doc_comment (); Lexer.doc_state = XmlCommentState.Allowed; } - - lbag.AddMember (current_event_field, GetModifierLocations (), GetLocation ($3), GetLocation ($9)); + if (current_event_field.Initializer != null) { + lbag.AddMember (current_event_field, GetModifierLocations (), GetLocation ($3), savedEventAssignLocation, GetLocation ($9)); + } else { + lbag.AddMember (current_event_field, GetModifierLocations (), GetLocation ($3), GetLocation ($9)); + } current_event_field = null; } | opt_attributes @@ -2382,6 +2456,14 @@ event_declaration current_event = null; current_local_parameters = null; } + | opt_attributes + opt_modifiers + EVENT type error + { + Error_SyntaxError (yyToken); + + current_type.AddMember (new EventField (current_type, (FullNamedExpression) $4, (Modifiers) $2, MemberName.Null, (Attributes) $1)); + } ; opt_event_initializer @@ -2393,6 +2475,7 @@ opt_event_initializer event_variable_initializer { --lexer.parsing_block; + savedEventAssignLocation = GetLocation ($1); current_event_field.Initializer = (Expression) $3; } ; @@ -2416,7 +2499,7 @@ event_declarators event_declarator : COMMA IDENTIFIER { - var lt = (Tokenizer.LocatedToken) $2; + var lt = (LocatedToken) $2; $$ = new FieldDeclarator (new SimpleMemberName (lt.Value, lt.Location), null); lbag.AddLocation ($$, GetLocation ($1)); } @@ -2427,7 +2510,7 @@ event_declarator event_variable_initializer { --lexer.parsing_block; - var lt = (Tokenizer.LocatedToken) $2; + var lt = (LocatedToken) $2; $$ = new FieldDeclarator (new SimpleMemberName (lt.Value, lt.Location), (Expression) $5); lbag.AddLocation ($$, GetLocation ($1), GetLocation ($3)); } @@ -2544,6 +2627,24 @@ attributes_without_members lexer.putback ('}'); } ; + +// For full ast try to recover incomplete ambiguous member +// declaration in form on class X { public int } +incomplete_member + : opt_attributes opt_modifiers member_type CLOSE_BRACE + { + report.Error (1519, lexer.Location, "Unexpected symbol `}' in class, struct, or interface member declaration"); + + lexer.putback ('}'); + + lexer.parsing_generic_declaration = false; + FullNamedExpression type = (FullNamedExpression) $3; + current_field = new Field (current_type, type, (Modifiers) $2, MemberName.Null, (Attributes) $1); + current_type.AddField (current_field); + lbag.AddMember (current_field, GetModifierLocations ()); + $$ = current_field; + } + ; enum_declaration : opt_attributes @@ -2574,6 +2675,8 @@ enum_declaration } opt_enum_member_declarations { + lexer.parsing_modifiers = true; + // here will be evaluated after CLOSE_BLACE is consumed. if (doc_support) Lexer.doc_state = XmlCommentState.Allowed; @@ -2631,7 +2734,7 @@ enum_member_declarations enum_member_declaration : opt_attributes IDENTIFIER { - var lt = (Tokenizer.LocatedToken) $2; + var lt = (LocatedToken) $2; var em = new EnumMember ((Enum) current_type, new MemberName (lt.Value, lt.Location), (Attributes) $1); ((Enum) current_type).AddEnumMember (em); @@ -2654,7 +2757,7 @@ enum_member_declaration { --lexer.parsing_block; - var lt = (Tokenizer.LocatedToken) $2; + var lt = (LocatedToken) $2; var em = new EnumMember ((Enum) current_type, new MemberName (lt.Value, lt.Location), (Attributes) $1); em.Initializer = new ConstInitializer (em, (Expression) $5, GetLocation ($4)); ((Enum) current_type).AddEnumMember (em); @@ -2668,7 +2771,7 @@ enum_member_declaration { Error_SyntaxError (yyToken); - var lt = (Tokenizer.LocatedToken) $2; + var lt = (LocatedToken) $2; var em = new EnumMember ((Enum) current_type, new MemberName (lt.Value, lt.Location), (Attributes) $1); ((Enum) current_type).AddEnumMember (em); @@ -2742,11 +2845,11 @@ namespace_or_type_expr : member_name | qualified_alias_member IDENTIFIER opt_type_argument_list { - var lt1 = (Tokenizer.LocatedToken) $1; - var lt2 = (Tokenizer.LocatedToken) $2; + var lt1 = (LocatedToken) $1; + var lt2 = (LocatedToken) $2; $$ = new QualifiedAliasMember (lt1.Value, lt2.Value, (TypeArguments) $3, lt1.Location); - lbag.AddLocation ($$, GetLocation ($2)); + lbag.AddLocation ($$, savedLocation, GetLocation ($2)); } ; @@ -2754,7 +2857,7 @@ member_name : simple_name_expr | namespace_or_type_expr DOT IDENTIFIER opt_type_argument_list { - var lt = (Tokenizer.LocatedToken) $3; + var lt = (LocatedToken) $3; $$ = new MemberAccess ((Expression) $1, lt.Value, (TypeArguments) $4, lt.Location); lbag.AddLocation ($$, GetLocation ($2)); } @@ -2763,7 +2866,7 @@ member_name simple_name_expr : IDENTIFIER opt_type_argument_list { - var lt = (Tokenizer.LocatedToken) $1; + var lt = (LocatedToken) $1; $$ = new SimpleName (lt.Value, (TypeArguments)$2, lt.Location); } ; @@ -2819,7 +2922,7 @@ type_declaration_name opt_type_parameter_list { lexer.parsing_generic_declaration = false; - var lt = (Tokenizer.LocatedToken) $1; + var lt = (LocatedToken) $1; $$ = new MemberName (lt.Value, (TypeParameters)$3, lt.Location); } ; @@ -2839,7 +2942,7 @@ method_declaration_name | explicit_interface IDENTIFIER opt_type_parameter_list { lexer.parsing_generic_declaration = false; - var lt = (Tokenizer.LocatedToken) $2; + var lt = (LocatedToken) $2; $$ = new MemberName (lt.Value, (TypeParameters) $3, (ATypeNameExpression) $1, lt.Location); } ; @@ -2860,21 +2963,21 @@ indexer_declaration_name explicit_interface : IDENTIFIER opt_type_argument_list DOT { - var lt = (Tokenizer.LocatedToken) $1; + var lt = (LocatedToken) $1; $$ = new SimpleName (lt.Value, (TypeArguments) $2, lt.Location); lbag.AddLocation ($$, GetLocation ($3)); } | qualified_alias_member IDENTIFIER opt_type_argument_list DOT { - var lt1 = (Tokenizer.LocatedToken) $1; - var lt2 = (Tokenizer.LocatedToken) $2; + var lt1 = (LocatedToken) $1; + var lt2 = (LocatedToken) $2; $$ = new QualifiedAliasMember (lt1.Value, lt2.Value, (TypeArguments) $3, lt1.Location); - lbag.AddLocation ($$, GetLocation ($4)); + lbag.AddLocation ($$, savedLocation, GetLocation ($4)); } | explicit_interface IDENTIFIER opt_type_argument_list DOT { - var lt = (Tokenizer.LocatedToken) $2; + var lt = (LocatedToken) $2; $$ = new MemberAccess ((ATypeNameExpression) $1, lt.Value, (TypeArguments) $3, lt.Location); lbag.AddLocation ($$, GetLocation ($4)); } @@ -2915,8 +3018,11 @@ type_parameters type_parameter : opt_attributes opt_type_parameter_variance IDENTIFIER { - var lt = (Tokenizer.LocatedToken)$3; - $$ = new TypeParameter (new MemberName (lt.Value, lt.Location), (Attributes)$1, (Variance) $2); + var lt = (LocatedToken)$3; + var variance = (VarianceDecl) $2; + $$ = new TypeParameter (new MemberName (lt.Value, lt.Location), (Attributes)$1, variance); + if (variance != null) + lbag.AddLocation ($$, savedLocation); } | error { @@ -2925,7 +3031,7 @@ type_parameter else Error_SyntaxError (yyToken); - $$ = new TypeParameter (MemberName.Null, null, Variance.None); + $$ = new TypeParameter (MemberName.Null, null, null); } ; @@ -3028,7 +3134,7 @@ type_list { var types = (List) $1; types.Add ((FullNamedExpression) $3); - lbag.AppendTo (types, GetLocation ($2)); + lbag.AddLocation (types, GetLocation ($2)); $$ = types; } ; @@ -3100,11 +3206,11 @@ primary_expression primary_expression_or_type : IDENTIFIER opt_type_argument_list { - var lt = (Tokenizer.LocatedToken) $1; + var lt = (LocatedToken) $1; $$ = new SimpleName (lt.Value, (TypeArguments)$2, lt.Location); } | IDENTIFIER GENERATE_COMPLETION { - var lt = (Tokenizer.LocatedToken) $1; + var lt = (LocatedToken) $1; $$ = new CompletionSimpleName (MemberName.MakeName (lt.Value, null), lt.Location); } | member_access @@ -3145,50 +3251,53 @@ close_parens parenthesized_expression : OPEN_PARENS expression CLOSE_PARENS { - $$ = new ParenthesizedExpression ((Expression) $2); + $$ = new ParenthesizedExpression ((Expression) $2, GetLocation ($1)); lbag.AddLocation ($$, GetLocation ($1), GetLocation ($3)); } | OPEN_PARENS expression COMPLETE_COMPLETION { - $$ = new ParenthesizedExpression ((Expression) $2); + $$ = new ParenthesizedExpression ((Expression) $2, GetLocation ($1)); } ; member_access - : primary_expression DOT IDENTIFIER opt_type_argument_list + : primary_expression DOT identifier_inside_body opt_type_argument_list { - var lt = (Tokenizer.LocatedToken) $3; - $$ = new MemberAccess ((Expression) $1, lt.Value, (TypeArguments) $4, lt.Location) { - DotLocation = GetLocation ($2) - }; + var lt = (LocatedToken) $3; + $$ = new MemberAccess ((Expression) $1, lt.Value, (TypeArguments) $4, lt.Location); + lbag.AddLocation ($$, GetLocation ($2)); } - | builtin_types DOT IDENTIFIER opt_type_argument_list + | builtin_types DOT identifier_inside_body opt_type_argument_list { - var lt = (Tokenizer.LocatedToken) $3; - $$ = new MemberAccess ((Expression) $1, lt.Value, (TypeArguments) $4, lt.Location) { - DotLocation = GetLocation ($2) - }; + var lt = (LocatedToken) $3; + $$ = new MemberAccess ((Expression) $1, lt.Value, (TypeArguments) $4, lt.Location); + lbag.AddLocation ($$, GetLocation ($2)); } - | BASE DOT IDENTIFIER opt_type_argument_list + | BASE DOT identifier_inside_body opt_type_argument_list { - var lt = (Tokenizer.LocatedToken) $3; - $$ = new MemberAccess (new BaseThis (GetLocation ($1)), lt.Value, (TypeArguments) $4, lt.Location) { - DotLocation = GetLocation ($2) - }; + var lt = (LocatedToken) $3; + $$ = new MemberAccess (new BaseThis (GetLocation ($1)), lt.Value, (TypeArguments) $4, lt.Location); + lbag.AddLocation ($$, GetLocation ($2)); } - | qualified_alias_member IDENTIFIER opt_type_argument_list + | AWAIT DOT identifier_inside_body opt_type_argument_list { - var lt1 = (Tokenizer.LocatedToken) $1; - var lt2 = (Tokenizer.LocatedToken) $2; + var lt = (LocatedToken) $3; + $$ = new MemberAccess (new SimpleName ("await", ((LocatedToken) $1).Location), lt.Value, (TypeArguments) $4, lt.Location); + lbag.AddLocation ($$, GetLocation ($2)); + } + | qualified_alias_member identifier_inside_body opt_type_argument_list + { + var lt1 = (LocatedToken) $1; + var lt2 = (LocatedToken) $2; $$ = new QualifiedAliasMember (lt1.Value, lt2.Value, (TypeArguments) $3, lt1.Location); - lbag.AddLocation ($$, GetLocation ($2)); + lbag.AddLocation ($$, savedLocation, GetLocation ($2)); } | primary_expression DOT GENERATE_COMPLETION { $$ = new CompletionMemberAccess ((Expression) $1, null,GetLocation ($3)); } | primary_expression DOT IDENTIFIER GENERATE_COMPLETION { - var lt = (Tokenizer.LocatedToken) $3; + var lt = (LocatedToken) $3; $$ = new CompletionMemberAccess ((Expression) $1, lt.Value, lt.Location); } | builtin_types DOT GENERATE_COMPLETION @@ -3196,7 +3305,7 @@ member_access $$ = new CompletionMemberAccess ((Expression) $1, null, lexer.Location); } | builtin_types DOT IDENTIFIER GENERATE_COMPLETION { - var lt = (Tokenizer.LocatedToken) $3; + var lt = (LocatedToken) $3; $$ = new CompletionMemberAccess ((Expression) $1, lt.Value, lt.Location); } ; @@ -3214,7 +3323,13 @@ invocation_expression $$ = new Invocation ((Expression) $1, (Arguments) $3); lbag.AddLocation ($$, GetLocation ($2)); } - + | primary_expression open_parens_any error + { + Error_SyntaxError (yyToken); + + $$ = new Invocation ((Expression) $1, null); + lbag.AddLocation ($$, GetLocation ($2)); + } ; opt_object_or_collection_initializer @@ -3226,17 +3341,16 @@ object_or_collection_initializer : OPEN_BRACE opt_member_initializer_list close_brace_or_complete_completion { if ($2 == null) { - $$ = new CollectionOrObjectInitializers (new List (), GetLocation ($1)); - lbag.AddLocation ($$, GetLocation ($1), GetLocation ($3)); + $$ = new CollectionOrObjectInitializers (GetLocation ($1)); } else { $$ = new CollectionOrObjectInitializers ((List) $2, GetLocation ($1)); - lbag.AddLocation ($$, GetLocation ($1), GetLocation ($3)); } + lbag.AddLocation ($$, GetLocation ($3)); } | OPEN_BRACE member_initializer_list COMMA CLOSE_BRACE { $$ = new CollectionOrObjectInitializers ((List) $2, GetLocation ($1)); - lbag.AddLocation ($$, GetLocation ($1), GetLocation ($3), GetLocation ($4)); + lbag.AddLocation ($$, GetLocation ($3), GetLocation ($4)); } ; @@ -3259,7 +3373,7 @@ member_initializer_list { var a = (List)$1; a.Add ((Expression) $3); - lbag.AppendTo (a, GetLocation ($2)); + lbag.AddLocation (a, GetLocation ($2)); $$ = a; } | member_initializer_list error { @@ -3271,7 +3385,13 @@ member_initializer_list member_initializer : IDENTIFIER ASSIGN initializer_value { - var lt = (Tokenizer.LocatedToken) $1; + var lt = (LocatedToken) $1; + $$ = new ElementInitializer (lt.Value, (Expression)$3, lt.Location); + lbag.AddLocation ($$, GetLocation ($2)); + } + | AWAIT ASSIGN initializer_value + { + var lt = (LocatedToken) Error_AwaitAsIdentifier ($1); $$ = new ElementInitializer (lt.Value, (Expression)$3, lt.Location); lbag.AddLocation ($$, GetLocation ($2)); } @@ -3289,18 +3409,18 @@ member_initializer | OPEN_BRACE expression_list CLOSE_BRACE { if ($2 == null) - $$ = null; + $$ = new CollectionElementInitializer (GetLocation ($1)); else { $$ = new CollectionElementInitializer ((List)$2, GetLocation ($1)); lbag.AddLocation ($$, GetLocation ($2)); - } + } } | OPEN_BRACE CLOSE_BRACE { report.Error (1920, GetLocation ($1), "An element initializer cannot be empty"); - $$ = new CollectionElementInitializer (new List (), GetLocation ($1)); + $$ = new CollectionElementInitializer (GetLocation ($1)); lbag.AddLocation ($$, GetLocation ($2)); - } + } ; initializer_value @@ -3327,7 +3447,7 @@ argument_list Error_NamedArgumentExpected ((NamedArgument) list [list.Count - 1]); list.Add ((Argument) $3); - lbag.AppendTo (list, GetLocation ($2)); + lbag.AddLocation (list, GetLocation ($2)); $$ = list; } | argument_list COMMA named_argument @@ -3342,12 +3462,13 @@ argument_list } list.Add (a); - lbag.AppendTo (list, GetLocation ($2)); + lbag.AddLocation (list, GetLocation ($2)); $$ = list; } | argument_list COMMA error { - lexer.putback (')'); // TODO: Wrong but what can I do + if (lexer.putback_char == -1) + lexer.putback (')'); // TODO: Wrong but what can I do Error_SyntaxError (yyToken); $$ = $1; } @@ -3417,23 +3538,19 @@ element_access ; expression_list - : expression + : expression_or_error { var list = new List (4); list.Add ((Expression) $1); $$ = list; } - | expression_list COMMA expression + | expression_list COMMA expression_or_error { var list = (List) $1; list.Add ((Expression) $3); - lbag.AppendTo (list, GetLocation ($2)); + lbag.AddLocation (list, GetLocation ($2)); $$ = list; } - | expression_list error { - Error_SyntaxError (yyToken); - $$ = $1; - } ; expression_list_arguments @@ -3450,7 +3567,7 @@ expression_list_arguments Error_NamedArgumentExpected ((NamedArgument) args [args.Count - 1]); args.Add ((Argument) $3); - lbag.AppendTo (args, GetLocation ($2)); + lbag.AddLocation (args, GetLocation ($2)); $$ = args; } ; @@ -3580,6 +3697,10 @@ anonymous_type_expression // TODO: lbag comma location lbag.AddLocation ($$, GetLocation ($2), GetLocation ($4)); } + | NEW OPEN_BRACE GENERATE_COMPLETION + { + $$ = new EmptyCompletion (); + } ; anonymous_type_parameters_opt_comma @@ -3603,22 +3724,30 @@ anonymous_type_parameters { var a = (List) $1; a.Add ((AnonymousTypeParameter) $3); - lbag.AppendTo (a, GetLocation ($2)); + lbag.AddLocation (a, GetLocation ($2)); $$ = a; } + | COMPLETE_COMPLETION + { + $$ = new EmptyCompletion (); + } + | anonymous_type_parameter COMPLETE_COMPLETION + { + $$ = $1; + } ; anonymous_type_parameter - : IDENTIFIER ASSIGN variable_initializer + : identifier_inside_body ASSIGN variable_initializer { - var lt = (Tokenizer.LocatedToken)$1; + var lt = (LocatedToken)$1; $$ = new AnonymousTypeParameter ((Expression)$3, lt.Value, lt.Location); lbag.AddLocation ($$, GetLocation ($2)); } - | IDENTIFIER + | identifier_inside_body { - var lt = (Tokenizer.LocatedToken)$1; + var lt = (LocatedToken)$1; $$ = new AnonymousTypeParameter (new SimpleName (lt.Value, lt.Location), lt.Value, lt.Location); } @@ -3716,7 +3845,7 @@ variable_initializer_list { var list = (List) $1; list.Add ((Expression) $3); - lbag.AppendTo (list, GetLocation ($2)); + lbag.AddLocation (list, GetLocation ($2)); $$ = list; } ; @@ -3747,33 +3876,37 @@ typeof_type_expression unbound_type_name : identifier_inside_body generic_dimension { - var lt = (Tokenizer.LocatedToken) $1; + var lt = (LocatedToken) $1; - $$ = new SimpleName (lt.Value, (int) $2, lt.Location); + var sn = new SimpleName (lt.Value, (int) $2, lt.Location); + $$ = sn; + lbag.AddLocation (sn.TypeArguments, Lexer.GetGenericDimensionLocations ()); } | qualified_alias_member identifier_inside_body generic_dimension { - var lt1 = (Tokenizer.LocatedToken) $1; - var lt2 = (Tokenizer.LocatedToken) $2; + var lt1 = (LocatedToken) $1; + var lt2 = (LocatedToken) $2; - $$ = new QualifiedAliasMember (lt1.Value, lt2.Value, (int) $3, lt1.Location); - lbag.AddLocation ($$, GetLocation ($2)); + var qam = new QualifiedAliasMember (lt1.Value, lt2.Value, (int) $3, lt1.Location); + $$ = qam; + lbag.AddLocation (qam.TypeArguments, Lexer.GetGenericDimensionLocations ()); + lbag.AddLocation ($$, savedLocation, GetLocation ($2)); } | unbound_type_name DOT identifier_inside_body { - var lt = (Tokenizer.LocatedToken) $3; + var lt = (LocatedToken) $3; - $$ = new MemberAccess ((Expression) $1, lt.Value, lt.Location) { - DotLocation = GetLocation ($2) - }; + $$ = new MemberAccess ((Expression) $1, lt.Value, lt.Location); + lbag.AddLocation ($$, savedLocation, GetLocation ($2)); } | unbound_type_name DOT identifier_inside_body generic_dimension { - var lt = (Tokenizer.LocatedToken) $3; + var lt = (LocatedToken) $3; - $$ = new MemberAccess ((Expression) $1, lt.Value, (int) $4, lt.Location) { - DotLocation = GetLocation ($2) - }; + var ma = new MemberAccess ((Expression) $1, lt.Value, (int) $4, lt.Location); + $$ = ma; + lbag.AddLocation ($$, savedLocation, GetLocation ($2)); + lbag.AddLocation (ma.TypeArguments, Lexer.GetGenericDimensionLocations ()); } | namespace_or_type_expr DOT identifier_inside_body generic_dimension { @@ -3781,10 +3914,10 @@ unbound_type_name if (tne.HasTypeArguments) Error_TypeExpected (GetLocation ($4)); - var lt = (Tokenizer.LocatedToken) $3; - $$ = new MemberAccess (tne, lt.Value, (int) $4, lt.Location) { - DotLocation = GetLocation ($2) - }; + var lt = (LocatedToken) $3; + var ma = new MemberAccess (tne, lt.Value, (int) $4, lt.Location); + $$ = ma; + lbag.AddLocation (ma.TypeArguments, Lexer.GetGenericDimensionLocations ()); } ; @@ -3801,10 +3934,10 @@ generic_dimension qualified_alias_member : IDENTIFIER DOUBLE_COLON { - var lt = (Tokenizer.LocatedToken) $1; + var lt = (LocatedToken) $1; if (lang_version == LanguageVersion.ISO_1) FeatureIsNotAvailable (lt.Location, "namespace alias qualifier"); - + savedLocation = GetLocation ($2); $$ = lt; } ; @@ -3815,6 +3948,13 @@ sizeof_expression $$ = new SizeOf ((Expression) $3, GetLocation ($1)); lbag.AddLocation ($$, GetLocation ($2), GetLocation ($4)); } + | SIZEOF open_parens_any type error + { + Error_SyntaxError (yyToken); + + $$ = new SizeOf ((Expression) $3, GetLocation ($1)); + lbag.AddLocation ($$, GetLocation ($2)); + } ; checked_expression @@ -3823,6 +3963,12 @@ checked_expression $$ = new CheckedExpr ((Expression) $3, GetLocation ($1)); lbag.AddLocation ($$, GetLocation ($2), GetLocation ($4)); } + | CHECKED error + { + Error_SyntaxError (yyToken); + + $$ = new CheckedExpr (null, GetLocation ($1)); + } ; unchecked_expression @@ -3831,12 +3977,18 @@ unchecked_expression $$ = new UnCheckedExpr ((Expression) $3, GetLocation ($1)); lbag.AddLocation ($$, GetLocation ($2), GetLocation ($4)); } + | UNCHECKED error + { + Error_SyntaxError (yyToken); + + $$ = new UnCheckedExpr (null, GetLocation ($1)); + } ; pointer_member_access : primary_expression OP_PTR IDENTIFIER opt_type_argument_list { - var lt = (Tokenizer.LocatedToken) $3; + var lt = (LocatedToken) $3; $$ = new MemberAccess (new Indirection ((Expression) $1, GetLocation ($2)), lt.Value, (TypeArguments) $4, lt.Location); } ; @@ -3850,7 +4002,7 @@ anonymous_method_expression { $$ = end_anonymous ((ParametersBlock) $4); if ((ParametersCompiled) $2 != ParametersCompiled.Undefined) { - lbag.AddLocation ($$, GetLocation ($1), savedOpenLocation, savedCloseLocation); + lbag.AddLocation ($$, GetLocation ($1), PopLocation (), PopLocation ()); } else { lbag.AddLocation ($$, GetLocation ($1)); } @@ -3864,7 +4016,7 @@ anonymous_method_expression $$ = end_anonymous ((ParametersBlock) $5); if ((ParametersCompiled) $3 != ParametersCompiled.Undefined) { - lbag.AddLocation ($$, GetLocation ($1), GetLocation ($2), savedOpenLocation, savedCloseLocation); + lbag.AddLocation ($$, GetLocation ($1), GetLocation ($2), PopLocation (), PopLocation ()); } else { lbag.AddLocation ($$, GetLocation ($1), GetLocation ($2)); } @@ -3888,8 +4040,8 @@ anonymous_method_signature { valid_param_mod = 0; $$ = $3; - savedOpenLocation = GetLocation ($1); - savedCloseLocation = GetLocation ($2); + PushLocation (GetLocation ($3)); + PushLocation (GetLocation ($1)); } ; @@ -3925,9 +4077,12 @@ unary_expression if (current_anonymous_method is LambdaExpression) { report.Error (4034, GetLocation ($1), "The `await' operator can only be used when its containing lambda expression is marked with the `async' modifier"); - } else if (current_anonymous_method is AnonymousMethodExpression) { + } else if (current_anonymous_method != null) { report.Error (4035, GetLocation ($1), "The `await' operator can only be used when its containing anonymous method is marked with the `async' modifier"); + } else if (interactive_async != null) { + current_block.Explicit.RegisterAsyncAwait (); + interactive_async = true; } else { report.Error (4033, GetLocation ($1), "The `await' operator can only be used when its containing method is marked with the `async' modifier"); @@ -3938,6 +4093,31 @@ unary_expression $$ = new Await ((Expression) $2, GetLocation ($1)); } + | BANG error + { + Error_SyntaxError (yyToken); + + $$ = new Unary (Unary.Operator.LogicalNot, null, GetLocation ($1)); + } + | TILDE error + { + Error_SyntaxError (yyToken); + + $$ = new Unary (Unary.Operator.OnesComplement, null, GetLocation ($1)); + } + | OPEN_PARENS_CAST type CLOSE_PARENS error + { + Error_SyntaxError (yyToken); + + $$ = new Cast ((FullNamedExpression) $2, null, GetLocation ($1)); + lbag.AddLocation ($$, GetLocation ($3)); + } + | AWAIT error + { + Error_SyntaxError (yyToken); + + $$ = new Await (null, GetLocation ($1)); + } ; // @@ -3970,6 +4150,42 @@ prefixed_unary_expression { $$ = new Unary (Unary.Operator.AddressOf, (Expression) $2, GetLocation ($1)); } + | PLUS error + { + Error_SyntaxError (yyToken); + + $$ = new Unary (Unary.Operator.UnaryPlus, null, GetLocation ($1)); + } + | MINUS error + { + Error_SyntaxError (yyToken); + + $$ = new Unary (Unary.Operator.UnaryNegation, null, GetLocation ($1)); + } + | OP_INC error + { + Error_SyntaxError (yyToken); + + $$ = new UnaryMutator (UnaryMutator.Mode.PreIncrement, null, GetLocation ($1)); + } + | OP_DEC error + { + Error_SyntaxError (yyToken); + + $$ = new UnaryMutator (UnaryMutator.Mode.PreDecrement, null, GetLocation ($1)); + } + | STAR error + { + Error_SyntaxError (yyToken); + + $$ = new Indirection (null, GetLocation ($1)); + } + | BITWISE_AND error + { + Error_SyntaxError (yyToken); + + $$ = new Unary (Unary.Operator.AddressOf, null, GetLocation ($1)); + } ; multiplicative_expression @@ -3989,6 +4205,27 @@ multiplicative_expression $$ = new Binary (Binary.Operator.Modulus, (Expression) $1, (Expression) $3); lbag.AddLocation ($$, GetLocation ($2)); } + | multiplicative_expression STAR error + { + Error_SyntaxError (yyToken); + + $$ = new Binary (Binary.Operator.Multiply, (Expression) $1, null); + lbag.AddLocation ($$, GetLocation ($2)); + } + | multiplicative_expression DIV error + { + Error_SyntaxError (yyToken); + + $$ = new Binary (Binary.Operator.Division, (Expression) $1, null); + lbag.AddLocation ($$, GetLocation ($2)); + } + | multiplicative_expression PERCENT error + { + Error_SyntaxError (yyToken); + + $$ = new Binary (Binary.Operator.Modulus, (Expression) $1, null); + lbag.AddLocation ($$, GetLocation ($2)); + } ; additive_expression @@ -4011,20 +4248,70 @@ additive_expression { $$ = new Is ((Expression) $1, (Expression) $3, GetLocation ($2)); } - ; - -shift_expression - : additive_expression - | shift_expression OP_SHIFT_LEFT additive_expression + | additive_expression PLUS error { - $$ = new Binary (Binary.Operator.LeftShift, (Expression) $1, (Expression) $3); + Error_SyntaxError (yyToken); + + $$ = new Binary (Binary.Operator.Addition, (Expression) $1, null); lbag.AddLocation ($$, GetLocation ($2)); } - | shift_expression OP_SHIFT_RIGHT additive_expression + | additive_expression MINUS error + { + Error_SyntaxError (yyToken); + + $$ = new Binary (Binary.Operator.Subtraction, (Expression) $1, null); + lbag.AddLocation ($$, GetLocation ($2)); + } + | additive_expression AS error + { + Error_SyntaxError (yyToken); + + $$ = new As ((Expression) $1, null, GetLocation ($2)); + } + | additive_expression IS error + { + Error_SyntaxError (yyToken); + + $$ = new Is ((Expression) $1, null, GetLocation ($2)); + } + | AWAIT IS type + { + var lt = (LocatedToken) $1; + $$ = new Is (new SimpleName (lt.Value, lt.Location), (Expression) $3, GetLocation ($2)); + } + | AWAIT AS type + { + var lt = (LocatedToken) $1; + $$ = new As (new SimpleName (lt.Value, lt.Location), (Expression) $3, GetLocation ($2)); + } + ; + +shift_expression + : additive_expression + | shift_expression OP_SHIFT_LEFT additive_expression + { + $$ = 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); lbag.AddLocation ($$, GetLocation ($2)); } + | shift_expression OP_SHIFT_LEFT error + { + Error_SyntaxError (yyToken); + + $$ = new Binary (Binary.Operator.LeftShift, (Expression) $1, null); + lbag.AddLocation ($$, GetLocation ($2)); + } + | shift_expression OP_SHIFT_RIGHT error + { + Error_SyntaxError (yyToken); + + $$ = new Binary (Binary.Operator.RightShift, (Expression) $1, null); + lbag.AddLocation ($$, GetLocation ($2)); + } ; relational_expression @@ -4049,6 +4336,34 @@ relational_expression $$ = new Binary (Binary.Operator.GreaterThanOrEqual, (Expression) $1, (Expression) $3); lbag.AddLocation ($$, GetLocation ($2)); } + | relational_expression OP_LT error + { + Error_SyntaxError (yyToken); + + $$ = new Binary (Binary.Operator.LessThan, (Expression) $1, null); + lbag.AddLocation ($$, GetLocation ($2)); + } + | relational_expression OP_GT error + { + Error_SyntaxError (yyToken); + + $$ = new Binary (Binary.Operator.GreaterThan, (Expression) $1, null); + lbag.AddLocation ($$, GetLocation ($2)); + } + | relational_expression OP_LE error + { + Error_SyntaxError (yyToken); + + $$ = new Binary (Binary.Operator.LessThanOrEqual, (Expression) $1, null); + lbag.AddLocation ($$, GetLocation ($2)); + } + | relational_expression OP_GE error + { + Error_SyntaxError (yyToken); + + $$ = new Binary (Binary.Operator.GreaterThanOrEqual, (Expression) $1, null); + lbag.AddLocation ($$, GetLocation ($2)); + } ; equality_expression @@ -4063,6 +4378,20 @@ equality_expression $$ = new Binary (Binary.Operator.Inequality, (Expression) $1, (Expression) $3); lbag.AddLocation ($$, GetLocation ($2)); } + | equality_expression OP_EQ error + { + Error_SyntaxError (yyToken); + + $$ = new Binary (Binary.Operator.Equality, (Expression) $1, null); + lbag.AddLocation ($$, GetLocation ($2)); + } + | equality_expression OP_NE error + { + Error_SyntaxError (yyToken); + + $$ = new Binary (Binary.Operator.Inequality, (Expression) $1, null); + lbag.AddLocation ($$, GetLocation ($2)); + } ; and_expression @@ -4072,6 +4401,13 @@ and_expression $$ = new Binary (Binary.Operator.BitwiseAnd, (Expression) $1, (Expression) $3); lbag.AddLocation ($$, GetLocation ($2)); } + | and_expression BITWISE_AND error + { + Error_SyntaxError (yyToken); + + $$ = new Binary (Binary.Operator.BitwiseAnd, (Expression) $1, null); + lbag.AddLocation ($$, GetLocation ($2)); + } ; exclusive_or_expression @@ -4081,6 +4417,13 @@ exclusive_or_expression $$ = new Binary (Binary.Operator.ExclusiveOr, (Expression) $1, (Expression) $3); lbag.AddLocation ($$, GetLocation ($2)); } + | exclusive_or_expression CARRET error + { + Error_SyntaxError (yyToken); + + $$ = new Binary (Binary.Operator.ExclusiveOr, (Expression) $1, null); + lbag.AddLocation ($$, GetLocation ($2)); + } ; inclusive_or_expression @@ -4090,6 +4433,13 @@ inclusive_or_expression $$ = new Binary (Binary.Operator.BitwiseOr, (Expression) $1, (Expression) $3); lbag.AddLocation ($$, GetLocation ($2)); } + | inclusive_or_expression BITWISE_OR error + { + Error_SyntaxError (yyToken); + + $$ = new Binary (Binary.Operator.BitwiseOr, (Expression) $1, null); + lbag.AddLocation ($$, GetLocation ($2)); + } ; conditional_and_expression @@ -4099,6 +4449,13 @@ conditional_and_expression $$ = new Binary (Binary.Operator.LogicalAnd, (Expression) $1, (Expression) $3); lbag.AddLocation ($$, GetLocation ($2)); } + | conditional_and_expression OP_AND error + { + Error_SyntaxError (yyToken); + + $$ = new Binary (Binary.Operator.LogicalAnd, (Expression) $1, null); + lbag.AddLocation ($$, GetLocation ($2)); + } ; conditional_or_expression @@ -4108,6 +4465,13 @@ conditional_or_expression $$ = new Binary (Binary.Operator.LogicalOr, (Expression) $1, (Expression) $3); lbag.AddLocation ($$, GetLocation ($2)); } + | conditional_or_expression OP_OR error + { + Error_SyntaxError (yyToken); + + $$ = new Binary (Binary.Operator.LogicalOr, (Expression) $1, null); + lbag.AddLocation ($$, GetLocation ($2)); + } ; null_coalescing_expression @@ -4124,7 +4488,7 @@ null_coalescing_expression conditional_expression : null_coalescing_expression - | null_coalescing_expression INTERR expression COLON expression_or_error + | null_coalescing_expression INTERR expression COLON expression { $$ = new Conditional (new BooleanExpression ((Expression) $1), (Expression) $3, (Expression) $5, GetLocation ($2)); lbag.AddLocation ($$, GetLocation ($4)); @@ -4132,7 +4496,23 @@ conditional_expression | null_coalescing_expression INTERR expression error { Error_SyntaxError (yyToken); + + $$ = new Conditional (new BooleanExpression ((Expression) $1), (Expression) $3, null, GetLocation ($2)); + } + | null_coalescing_expression INTERR expression COLON error + { + Error_SyntaxError (yyToken); + + $$ = new Conditional (new BooleanExpression ((Expression) $1), (Expression) $3, null, GetLocation ($2)); + lbag.AddLocation ($$, GetLocation ($4)); + } + | null_coalescing_expression INTERR expression COLON CLOSE_BRACE + { + Error_SyntaxError (Token.CLOSE_BRACE); + $$ = new Conditional (new BooleanExpression ((Expression) $1), (Expression) $3, null, GetLocation ($2)); + lbag.AddLocation ($$, GetLocation ($4)); + lexer.putback ('}'); } ; @@ -4220,19 +4600,24 @@ lambda_parameter_list lambda_parameter : parameter_modifier parameter_type identifier_inside_body { - var lt = (Tokenizer.LocatedToken) $3; + var lt = (LocatedToken) $3; $$ = new Parameter ((FullNamedExpression) $2, lt.Value, (Parameter.Modifier) $1, null, lt.Location); } | parameter_type identifier_inside_body { - var lt = (Tokenizer.LocatedToken) $2; + var lt = (LocatedToken) $2; $$ = new Parameter ((FullNamedExpression) $1, lt.Value, Parameter.Modifier.NONE, null, lt.Location); } | IDENTIFIER { - var lt = (Tokenizer.LocatedToken) $1; + var lt = (LocatedToken) $1; + $$ = new ImplicitLambdaParameter (lt.Value, lt.Location); + } + | AWAIT + { + var lt = (LocatedToken) Error_AwaitAsIdentifier ($1); $$ = new ImplicitLambdaParameter (lt.Value, lt.Location); } ; @@ -4247,36 +4632,53 @@ opt_lambda_parameter_list ; lambda_expression_body - : lambda_expression_body_simple - | block - ; - -lambda_expression_body_simple : { start_block (Location.Null); } - expression_or_error // Have to close block when error occurs + expression // All expressions must handle error or current block won't be restored and breaking ast completely { Block b = end_block (Location.Null); b.IsCompilerGenerated = true; b.AddStatement (new ContextualReturn ((Expression) $2)); $$ = b; } + | block + | error + { + // Handles only cases like foo = x.FirstOrDefault (l => ); + // where we must restore current_variable + Block b = end_block (Location.Null); + b.IsCompilerGenerated = true; + + Error_SyntaxError (yyToken); + $$ = null; + } ; - + expression_or_error : expression | error { - Error_SyntaxError (yyToken); - $$ = EmptyExpression.Null; + Error_SyntaxError (yyToken); + $$ = null; } ; - + lambda_expression : IDENTIFIER ARROW { - var lt = (Tokenizer.LocatedToken) $1; + var lt = (LocatedToken) $1; + Parameter p = new ImplicitLambdaParameter (lt.Value, lt.Location); + start_anonymous (true, new ParametersCompiled (p), false, lt.Location); + } + lambda_expression_body + { + $$ = end_anonymous ((ParametersBlock) $4); + lbag.AddLocation ($$, GetLocation ($2)); + } + | AWAIT ARROW + { + var lt = (LocatedToken) Error_AwaitAsIdentifier ($1); Parameter p = new ImplicitLambdaParameter (lt.Value, lt.Location); start_anonymous (true, new ParametersCompiled (p), false, lt.Location); } @@ -4287,7 +4689,7 @@ lambda_expression } | ASYNC identifier_inside_body ARROW { - var lt = (Tokenizer.LocatedToken) $2; + var lt = (LocatedToken) $2; Parameter p = new ImplicitLambdaParameter (lt.Value, lt.Location); start_anonymous (true, new ParametersCompiled (p), true, lt.Location); } @@ -4370,6 +4772,51 @@ boolean_expression } ; +opt_primary_parameters + : /* empty */ + { + $$ = null; + } + | primary_parameters + ; + +primary_parameters + : OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS + { + $$ = $2; + + // Cannot use opt_formal_parameter_list because it can be shared instance for empty parameters + lbag.AppendToMember (current_container, GetLocation ($1), GetLocation ($3)); + } + ; + +opt_primary_parameters_with_class_base + : /* empty */ + { + $$ = null; + } + | class_base + { + $$ = null; + } + | primary_parameters + { + $$ = $1; + } + | primary_parameters class_base OPEN_PARENS + { + ++lexer.parsing_block; + } + opt_argument_list CLOSE_PARENS + { + lbag.AppendToMember (current_container, GetLocation ($3), GetLocation ($6)); + ((Class)current_type).PrimaryConstructorBaseArguments = (Arguments) $5; + --lexer.parsing_block; + + $$ = $1; + } + ; + // // 10 classes // @@ -4379,10 +4826,11 @@ class_declaration opt_partial CLASS { - lexer.ConstraintsParsing = true; } type_declaration_name { + lexer.ConstraintsParsing = true; + Class c = new Class (current_container, (MemberName) $6, (Modifiers) $2, (Attributes) $1); if (((c.ModFlags & Modifiers.STATIC) != 0) && lang_version == LanguageVersion.ISO_1) { FeatureIsNotAvailable (c.Location, "static classes"); @@ -4390,12 +4838,17 @@ class_declaration push_current_container (c, $3); lbag.AddMember (current_container, GetModifierLocations (), GetLocation ($4)); + valid_param_mod = ParameterModifierType.PrimaryConstructor; } - opt_class_base + opt_primary_parameters_with_class_base opt_type_parameter_constraints_clauses { + valid_param_mod = 0; lexer.ConstraintsParsing = false; + if ($8 != null) + current_type.PrimaryConstructorParameters = (ParametersCompiled) $8; + if ($9 != null) current_container.SetConstraints ((List) $9); @@ -4548,16 +5001,20 @@ modifier opt_class_base : /* empty */ - | COLON type_list + | class_base + ; + +class_base + : COLON type_list { - current_type.AddBasesForPart ((List) $2); + current_type.SetBaseTypes ((List) $2); lbag.AppendToMember (current_type, GetLocation ($1)); } | COLON type_list error { Error_SyntaxError (yyToken); - current_type.AddBasesForPart ((List) $2); + current_type.SetBaseTypes ((List) $2); } ; @@ -4597,7 +5054,7 @@ type_parameter_constraints_clauses type_parameter_constraints_clause : WHERE IDENTIFIER COLON type_parameter_constraints { - var lt = (Tokenizer.LocatedToken) $2; + var lt = (LocatedToken) $2; $$ = new Constraints (new SimpleMemberName (lt.Value, lt.Location), (List) $4, GetLocation ($1)); lbag.AddLocation ($$, GetLocation ($3)); } @@ -4605,7 +5062,7 @@ type_parameter_constraints_clause { Error_SyntaxError (yyToken); - var lt = (Tokenizer.LocatedToken) $2; + var lt = (LocatedToken) $2; $$ = new Constraints (new SimpleMemberName (lt.Value, lt.Location), null, GetLocation ($1)); } ; @@ -4638,7 +5095,7 @@ type_parameter_constraints } constraints.Add ((FullNamedExpression) $3); - lbag.AppendTo (constraints, GetLocation ($2)); + lbag.AddLocation (constraints, GetLocation ($2)); $$ = constraints; } ; @@ -4669,7 +5126,7 @@ type_parameter_constraint opt_type_parameter_variance : /* empty */ { - $$ = Variance.None; + $$ = null; } | type_parameter_variance { @@ -4683,12 +5140,12 @@ opt_type_parameter_variance type_parameter_variance : OUT { - $$ = Variance.Covariant; + $$ = new VarianceDecl (Variance.Covariant, GetLocation ($1)); savedLocation = GetLocation ($1); } | IN { - $$ = Variance.Contravariant; + $$ = new VarianceDecl (Variance.Contravariant, GetLocation ($1)); savedLocation = GetLocation ($1); } ; @@ -4750,6 +5207,19 @@ block_prepared } ; +block_prepared_strict + : OPEN_BRACE + { + ++lexer.parsing_block; + current_block.StartLocation = GetLocation ($1); + } + opt_statement_list CLOSE_BRACE + { + --lexer.parsing_block; + $$ = end_block (GetLocation ($4)); + } + ; + opt_statement_list : /* empty */ | statement_list @@ -4774,7 +5244,7 @@ statement | IDENTIFIER error { Error_SyntaxError (yyToken); - var lt =(Tokenizer.LocatedToken) $1; + var lt =(LocatedToken) $1; var sn = new SimpleName (lt.Value, lt.Location); current_block.AddStatement(new StatementErrorExpression (sn)); $$ = null; @@ -4872,7 +5342,7 @@ empty_statement labeled_statement : identifier_inside_body COLON { - var lt = (Tokenizer.LocatedToken) $1; + var lt = (LocatedToken) $1; LabeledStatement labeled = new LabeledStatement (lt.Value, current_block, lt.Location); lbag.AddLocation (labeled, GetLocation ($2)); current_block.AddLabel (labeled); @@ -4982,33 +5452,33 @@ identifier_inside_body : IDENTIFIER | AWAIT { - if (async_block) { - report.Error (4003, GetLocation ($1), "`await' cannot be used as an identifier within an async method or lambda expression"); - $$ = new Tokenizer.LocatedToken ("await", GetLocation ($1)); - } + $$ = Error_AwaitAsIdentifier ($1); } ; block_variable_declaration : variable_type identifier_inside_body { - var lt = (Tokenizer.LocatedToken) $2; + var lt = (LocatedToken) $2; var li = new LocalVariable (current_block, lt.Value, lt.Location); current_block.AddLocalName (li); - current_variable = new BlockVariableDeclaration ((FullNamedExpression) $1, li); + current_variable = new BlockVariable ((FullNamedExpression) $1, li); } opt_local_variable_initializer opt_variable_declarators semicolon_or_handle_error_close_brace { $$ = current_variable; current_variable = null; - lbag.AppendTo ($$, GetLocation ($6)); + if ($4 != null) + lbag.AddLocation ($$, PopLocation (), GetLocation ($6)); + else + lbag.AddLocation ($$, GetLocation ($6)); } | CONST variable_type identifier_inside_body { - var lt = (Tokenizer.LocatedToken) $3; + var lt = (LocatedToken) $3; var li = new LocalVariable (current_block, lt.Value, LocalVariable.Flags.Constant, lt.Location); current_block.AddLocalName (li); - current_variable = new BlockConstantDeclaration ((FullNamedExpression) $2, li); + current_variable = new BlockConstant ((FullNamedExpression) $2, li); } const_variable_initializer opt_const_declarators SEMICOLON { @@ -5037,21 +5507,8 @@ opt_local_variable_initializer | ASSIGN block_variable_initializer { current_variable.Initializer = (Expression) $2; - lbag.AppendTo (current_variable, GetLocation ($1)); - } - | ASSIGN error - { - if (yyToken == Token.OPEN_BRACKET_EXPR) { - report.Error (650, lexer.Location, - "Syntax error, bad array declarator. To declare a managed array the rank specifier precedes the variable's identifier. To declare a fixed size buffer field, use the fixed keyword before the field type"); - current_variable.Initializer = ErrorExpression.Create (650, lexer.Location, - "Syntax error, bad array declarator. To declare a managed array the rank specifier precedes the variable's identifier. To declare a fixed size buffer field, use the fixed keyword before the field type"); - } else { - Error_SyntaxError (yyToken); - current_variable.Initializer = ErrorExpression.Create (0, lexer.Location, - "Syntax error"); - } - lbag.AppendTo (current_variable, GetLocation ($1)); + PushLocation (GetLocation ($1)); + $$ = current_variable; } | error { @@ -5088,18 +5545,18 @@ variable_declarators variable_declarator : COMMA identifier_inside_body { - var lt = (Tokenizer.LocatedToken) $2; + var lt = (LocatedToken) $2; var li = new LocalVariable (current_variable.Variable, lt.Value, lt.Location); - var d = new BlockVariableDeclaration.Declarator (li, null); + var d = new BlockVariableDeclarator (li, null); current_variable.AddDeclarator (d); current_block.AddLocalName (li); lbag.AddLocation (d, GetLocation ($1)); } | COMMA identifier_inside_body ASSIGN block_variable_initializer { - var lt = (Tokenizer.LocatedToken) $2; + var lt = (LocatedToken) $2; var li = new LocalVariable (current_variable.Variable, lt.Value, lt.Location); - var d = new BlockVariableDeclaration.Declarator (li, (Expression) $4); + var d = new BlockVariableDeclarator (li, (Expression) $4); current_variable.AddDeclarator (d); current_block.AddLocalName (li); lbag.AddLocation (d, GetLocation ($1), GetLocation ($3)); @@ -5131,9 +5588,9 @@ const_declarators const_declarator : COMMA identifier_inside_body ASSIGN constant_initializer_expr { - var lt = (Tokenizer.LocatedToken) $2; + var lt = (LocatedToken) $2; var li = new LocalVariable (current_block, lt.Value, LocalVariable.Flags.Constant, lt.Location); - var d = new BlockVariableDeclaration.Declarator (li, (Expression) $4); + var d = new BlockVariableDeclarator (li, (Expression) $4); current_variable.AddDeclarator (d); current_block.AddLocalName (li); lbag.AddLocation (d, GetLocation ($1), GetLocation ($3)); @@ -5183,8 +5640,8 @@ statement_expression { ExpressionStatement s = $1 as ExpressionStatement; if (s == null) { - Expression.Error_InvalidExpressionStatement (report, GetLocation ($1)); - $$ = new StatementErrorExpression ($1 as Expression); + var expr = $1 as Expression; + $$ = new StatementErrorExpression (expr); } else { $$ = new StatementExpression (s); } @@ -5195,10 +5652,7 @@ interactive_statement_expression : expression { Expression expr = (Expression) $1; - ExpressionStatement s; - - s = new OptionalAssign (new SimpleName ("$retval", lexer.Location), expr, lexer.Location); - $$ = new StatementExpression (s); + $$ = new StatementExpression (new OptionalAssign (expr, lexer.Location)); } | error { @@ -5249,7 +5703,7 @@ switch_statement } opt_switch_sections CLOSE_BRACE { - $$ = new Switch ((Expression) $3, (ExplicitBlock) current_block.Explicit, (List) $7, GetLocation ($1)); + $$ = new Switch ((Expression) $3, (ExplicitBlock) current_block.Explicit, GetLocation ($1)); end_block (GetLocation ($8)); lbag.AddStatement ($$, GetLocation ($2), GetLocation ($4), GetLocation ($5), GetLocation ($8)); } @@ -5257,7 +5711,7 @@ switch_statement { Error_SyntaxError (yyToken); - $$ = new Switch ((Expression) $3, null, null, GetLocation ($1)); + $$ = new Switch ((Expression) $3, null, GetLocation ($1)); lbag.AddStatement ($$, GetLocation ($2)); } ; @@ -5266,58 +5720,33 @@ opt_switch_sections : /* empty */ { report.Warning (1522, 1, current_block.StartLocation, "Empty switch block"); - $$ = new List (); } | switch_sections ; switch_sections : switch_section - { - var sections = new List (4); - - sections.Add ((SwitchSection) $1); - $$ = sections; - } | switch_sections switch_section - { - var sections = (List) $1; - - sections.Add ((SwitchSection) $2); - $$ = sections; - } | error { Error_SyntaxError (yyToken); - $$ = new List (); } ; switch_section - : switch_labels - { - current_block = current_block.CreateSwitchBlock (lexer.Location); - } - statement_list - { - $$ = new SwitchSection ((List) $1, current_block); - } + : switch_labels statement_list ; switch_labels : switch_label { - var labels = new List (2); - - labels.Add ((SwitchLabel) $1); - $$ = labels; + var label = (SwitchLabel) $1; + label.SectionStart = true; + current_block.AddStatement (label); } | switch_labels switch_label { - var labels = (List) ($1); - labels.Add ((SwitchLabel) $2); - - $$ = labels; + current_block.AddStatement ((Statement) $2); } ; @@ -5405,7 +5834,7 @@ for_statement_cont { For f = (For) $0; f.Initializer = (Statement) $1; - lbag.AppendTo (f, GetLocation ($2)); + lbag.AddLocation (f, GetLocation ($2)); $$ = f; } for_statement_condition @@ -5416,7 +5845,7 @@ for_statement_cont report.Error (1525, GetLocation ($2), "Unexpected symbol ')', expected ';'"); For f = (For) $0; f.Initializer = (Statement) $1; - lbag.AppendTo (f, GetLocation ($2)); + lbag.AddLocation (f, GetLocation ($2)); $$ = end_block (GetLocation ($2)); } ; @@ -5426,7 +5855,7 @@ for_statement_condition { For f = (For) $0; f.Condition = (BooleanExpression) $1; - lbag.AppendTo (f, GetLocation ($2)); + lbag.AddLocation (f, GetLocation ($2)); $$ = f; } for_statement_end @@ -5438,7 +5867,7 @@ for_statement_condition report.Error (1525, GetLocation ($2), "Unexpected symbol ')', expected ';'"); For f = (For) $0; f.Condition = (BooleanExpression) $1; - lbag.AppendTo (f, GetLocation ($2)); + lbag.AddLocation (f, GetLocation ($2)); $$ = end_block (GetLocation ($2)); } ; @@ -5454,7 +5883,7 @@ for_statement_end Warning_EmptyStatement (GetLocation ($3)); f.Statement = (Statement) $3; - lbag.AppendTo (f, GetLocation ($2)); + lbag.AddLocation (f, GetLocation ($2)); $$ = end_block (GetLocation ($2)); } @@ -5473,14 +5902,17 @@ opt_for_initializer for_initializer : variable_type identifier_inside_body { - var lt = (Tokenizer.LocatedToken) $2; + var lt = (LocatedToken) $2; var li = new LocalVariable (current_block, lt.Value, lt.Location); current_block.AddLocalName (li); - current_variable = new BlockVariableDeclaration ((FullNamedExpression) $1, li); + current_variable = new BlockVariable ((FullNamedExpression) $1, li); } opt_local_variable_initializer opt_variable_declarators { $$ = current_variable; + if ($4 != null) + lbag.AddLocation (current_variable, PopLocation ()); + current_variable = null; } | statement_expression_list @@ -5510,7 +5942,7 @@ statement_expression_list lbag.AddStatement (sl, GetLocation ($2)); } else { sl.Add ((Statement) $3); - lbag.AppendTo (sl, GetLocation ($2)); + lbag.AddLocation (sl, GetLocation ($2)); } @@ -5539,7 +5971,7 @@ foreach_statement start_block (GetLocation ($2)); current_block.IsCompilerGenerated = true; - var lt = (Tokenizer.LocatedToken) $4; + var lt = (LocatedToken) $4; var li = new LocalVariable (current_block, lt.Value, LocalVariable.Flags.ForeachVariable | LocalVariable.Flags.Used, lt.Location); current_block.AddLocalName (li); @@ -5553,7 +5985,8 @@ foreach_statement { start_block (GetLocation ($2)); current_block.IsCompilerGenerated = true; - var lt = (Tokenizer.LocatedToken) $4; + + var lt = (LocatedToken) $4; var li = new LocalVariable (current_block, lt.Value, LocalVariable.Flags.ForeachVariable | LocalVariable.Flags.Used, lt.Location); current_block.AddLocalName (li); $$ = li; @@ -5573,7 +6006,7 @@ foreach_statement { start_block (GetLocation ($2)); current_block.IsCompilerGenerated = true; - var lt = $4 as Tokenizer.LocatedToken; + var lt = $4 as LocatedToken; var li = lt != null ? new LocalVariable (current_block, lt.Value, LocalVariable.Flags.ForeachVariable | LocalVariable.Flags.Used, lt.Location) : null; Foreach f = new Foreach ((Expression) $3, li, null, null, null, GetLocation ($1)); @@ -5625,7 +6058,7 @@ continue_statement goto_statement : GOTO identifier_inside_body SEMICOLON { - var lt = (Tokenizer.LocatedToken) $2; + var lt = (LocatedToken) $2; $$ = new Goto (lt.Value, GetLocation ($1)); lbag.AddStatement ($$, GetLocation ($2), GetLocation ($3)); } @@ -5665,6 +6098,11 @@ throw_statement $$ = new Throw ((Expression) $2, GetLocation ($1)); lbag.AddStatement ($$, GetLocation ($3)); } + | THROW expression error + { + Error_SyntaxError (yyToken); + $$ = new Throw ((Expression) $2, GetLocation ($1)); + } | THROW error { Error_SyntaxError (yyToken); @@ -5675,7 +6113,7 @@ throw_statement yield_statement : identifier_inside_body RETURN opt_expression SEMICOLON { - var lt = (Tokenizer.LocatedToken) $1; + var lt = (LocatedToken) $1; string s = lt.Value; if (s != "yield"){ report.Error (1003, lt.Location, "; expected"); @@ -5693,7 +6131,7 @@ yield_statement { Error_SyntaxError (yyToken); - var lt = (Tokenizer.LocatedToken) $1; + var lt = (LocatedToken) $1; string s = lt.Value; if (s != "yield"){ report.Error (1003, lt.Location, "; expected"); @@ -5709,7 +6147,7 @@ yield_statement } | identifier_inside_body BREAK SEMICOLON { - var lt = (Tokenizer.LocatedToken) $1; + var lt = (LocatedToken) $1; string s = lt.Value; if (s != "yield"){ report.Error (1003, lt.Location, "; expected"); @@ -5717,7 +6155,7 @@ yield_statement FeatureIsNotAvailable (lt.Location, "iterators"); } - current_block.Explicit.RegisterIteratorYield (); + current_block.ParametersBlock.TopBlock.IsIterator = true; $$ = new YieldBreak (lt.Location); lbag.AddStatement ($$, GetLocation ($2), GetLocation ($3)); } @@ -5735,13 +6173,12 @@ try_statement } | TRY block FINALLY block { - $$ = new TryFinally ((Statement) $2, (Block) $4, GetLocation ($1)); + $$ = new TryFinally ((Statement) $2, (ExplicitBlock) $4, GetLocation ($1)); lbag.AddStatement ($$, GetLocation ($3)); } | TRY block catch_clauses FINALLY block { - var loc = GetLocation ($1); - $$ = new TryFinally (new TryCatch ((Block) $2, (List) $3, loc, true), (Block) $5, loc); + $$ = new TryFinally (new TryCatch ((Block) $2, (List) $3, GetLocation ($1), true), (ExplicitBlock) $5, GetLocation ($1)); lbag.AddStatement ($$, GetLocation ($4)); } | TRY block error @@ -5764,7 +6201,8 @@ catch_clauses var l = (List) $1; Catch c = (Catch) $2; - if (l [l.Count - 1].IsGeneral) { + var prev_catch = l [l.Count - 1]; + if (prev_catch.IsGeneral && prev_catch.Filter == null) { report.Error (1017, c.loc, "Try statement already has an empty catch block"); } @@ -5779,18 +6217,20 @@ opt_identifier ; catch_clause - : CATCH block + : CATCH opt_catch_filter block { - $$ = new Catch ((Block) $2, GetLocation ($1)); + var c = new Catch ((ExplicitBlock) $3, GetLocation ($1)); + c.Filter = (CatchFilterExpression) $2; + $$ = c; } | CATCH open_parens_any type opt_identifier CLOSE_PARENS { start_block (GetLocation ($2)); - var c = new Catch (current_block, GetLocation ($1)); + var c = new Catch ((ExplicitBlock) current_block, GetLocation ($1)); c.TypeExpression = (FullNamedExpression) $3; if ($4 != null) { - var lt = (Tokenizer.LocatedToken) $4; + var lt = (LocatedToken) $4; c.Variable = new LocalVariable (current_block, lt.Value, lt.Location); current_block.AddLocalName (c.Variable); } @@ -5798,8 +6238,9 @@ catch_clause lbag.AddLocation (c, GetLocation ($2), GetLocation ($5)); $$ = c; } - block_prepared + opt_catch_filter block_prepared { + ((Catch) $6).Filter = (CatchFilterExpression) $7; $$ = $6; } | CATCH open_parens_any error @@ -5813,6 +6254,41 @@ catch_clause $$ = new Catch (null, GetLocation ($1)); } + | CATCH open_parens_any type opt_identifier CLOSE_PARENS error + { + Error_SyntaxError (yyToken); + + // Required otherwise missing block could not be detected because + // start_block is run early + var c = new Catch (null, GetLocation ($1)); + c.TypeExpression = (FullNamedExpression) $3; + + if ($4 != null) { + var lt = (LocatedToken) $4; + c.Variable = new LocalVariable (current_block, lt.Value, lt.Location); + } + + if ($4 != null) { + var lt = (LocatedToken) $4; + c.Variable = new LocalVariable (current_block, lt.Value, lt.Location); + } + + lbag.AddLocation (c, GetLocation ($2), GetLocation ($5)); + + $$ = c; + } + ; + +opt_catch_filter + : /* empty */ + | IF open_parens_any expression CLOSE_PARENS + { + if (lang_version <= LanguageVersion.V_5) + FeatureIsNotAvailable (GetLocation ($1), "exception filter"); + + $$ = new CatchFilterExpression ((Expression) $3, GetLocation ($1)); + lbag.AddLocation ($$, GetLocation ($2), GetLocation ($4)); + } ; checked_statement @@ -5863,7 +6339,7 @@ fixed_statement start_block (GetLocation ($2)); current_block.IsCompilerGenerated = true; - var lt = (Tokenizer.LocatedToken) $4; + var lt = (LocatedToken) $4; var li = new LocalVariable (current_block, lt.Value, LocalVariable.Flags.FixedVariable | LocalVariable.Flags.Used, lt.Location); current_block.AddLocalName (li); current_variable = new Fixed.VariableDeclaration ((FullNamedExpression) $3, li); @@ -5891,7 +6367,7 @@ using_statement start_block (GetLocation ($2)); current_block.IsCompilerGenerated = true; - var lt = (Tokenizer.LocatedToken) $4; + var lt = (LocatedToken) $4; var li = new LocalVariable (current_block, lt.Value, LocalVariable.Flags.UsingVariable | LocalVariable.Flags.Used, lt.Location); current_block.AddLocalName (li); current_variable = new Using.VariableDeclaration ((FullNamedExpression) $3, li); @@ -5945,7 +6421,7 @@ using_or_fixed_variable_initializer | ASSIGN variable_initializer { current_variable.Initializer = (Expression) $2; - lbag.AppendTo (current_variable, GetLocation ($1)); + lbag.AddLocation (current_variable, GetLocation ($1)); $$ = current_variable; } ; @@ -5997,23 +6473,23 @@ first_from_clause { current_block = new Linq.QueryBlock (current_block, lexer.Location); - var lt = (Tokenizer.LocatedToken) $2; + var lt = (LocatedToken) $2; var rv = new Linq.RangeVariable (lt.Value, lt.Location); - var start = new Linq.QueryStartClause ((Linq.QueryBlock)current_block, (Expression)$4, rv, GetLocation ($1)); - lbag.AddLocation (start, GetLocation ($3)); - $$ = new Linq.QueryExpression (start); + var clause = new Linq.QueryStartClause ((Linq.QueryBlock)current_block, (Expression)$4, rv, GetLocation ($1)); + lbag.AddLocation (clause, GetLocation ($3)); + $$ = new Linq.QueryExpression (clause); } | FROM_FIRST type identifier_inside_body IN expression { current_block = new Linq.QueryBlock (current_block, lexer.Location); - var lt = (Tokenizer.LocatedToken) $3; + var lt = (LocatedToken) $3; var rv = new Linq.RangeVariable (lt.Value, lt.Location); - var start = new Linq.QueryStartClause ((Linq.QueryBlock)current_block, (Expression)$5, rv, GetLocation ($1)) { - IdentifierType = (FullNamedExpression)$2 + var clause = new Linq.QueryStartClause ((Linq.QueryBlock)current_block, (Expression)$5, rv, GetLocation ($1)) { + IdentifierType = (FullNamedExpression)$2 }; - lbag.AddLocation (start, GetLocation ($4)); - $$ = new Linq.QueryExpression (start); + lbag.AddLocation (clause, GetLocation ($4)); + $$ = new Linq.QueryExpression (clause); } ; @@ -6022,23 +6498,23 @@ nested_from_clause { current_block = new Linq.QueryBlock (current_block, lexer.Location); - var lt = (Tokenizer.LocatedToken) $2; + var lt = (LocatedToken) $2; var rv = new Linq.RangeVariable (lt.Value, lt.Location); - var start = new Linq.QueryStartClause ((Linq.QueryBlock)current_block, (Expression)$4, rv, GetLocation ($1)); - lbag.AddLocation (start, GetLocation ($3)); - $$ = new Linq.QueryExpression (start); + var clause = new Linq.QueryStartClause ((Linq.QueryBlock)current_block, (Expression)$4, rv, GetLocation ($1)); + lbag.AddLocation (clause, GetLocation ($3)); + $$ = new Linq.QueryExpression (clause); } | FROM type identifier_inside_body IN expression { current_block = new Linq.QueryBlock (current_block, lexer.Location); - var lt = (Tokenizer.LocatedToken) $3; + var lt = (LocatedToken) $3; var rv = new Linq.RangeVariable (lt.Value, lt.Location); - var start = new Linq.QueryStartClause ((Linq.QueryBlock)current_block, (Expression)$5, rv, GetLocation ($1)) { - IdentifierType = (FullNamedExpression)$2 + var clause = new Linq.QueryStartClause ((Linq.QueryBlock)current_block, (Expression)$5, rv, GetLocation ($1)) { + IdentifierType = (FullNamedExpression)$2 }; - lbag.AddLocation (start, GetLocation ($4)); - $$ = new Linq.QueryExpression (start); + lbag.AddLocation (clause, GetLocation ($4)); + $$ = new Linq.QueryExpression (clause); } ; @@ -6049,14 +6525,13 @@ from_clause } expression_or_error { - var lt = (Tokenizer.LocatedToken) $2; + var lt = (LocatedToken) $2; var sn = new Linq.RangeVariable (lt.Value, lt.Location); $$ = new Linq.SelectMany ((Linq.QueryBlock)current_block, sn, (Expression)$5, GetLocation ($1)); current_block.SetEndLocation (lexer.Location); current_block = current_block.Parent; ((Linq.QueryBlock)current_block).AddRangeVariable (sn); - lbag.AddLocation ($$, GetLocation ($3)); } | FROM type identifier_inside_body IN @@ -6065,7 +6540,7 @@ from_clause } expression_or_error { - var lt = (Tokenizer.LocatedToken) $3; + var lt = (LocatedToken) $3; var sn = new Linq.RangeVariable (lt.Value, lt.Location); $$ = new Linq.SelectMany ((Linq.QueryBlock)current_block, sn, (Expression)$6, GetLocation ($1)) { @@ -6149,15 +6624,29 @@ select_or_group_clause current_block = new Linq.QueryBlock (current_block, lexer.Location); } - BY expression_or_error + by_expression { - $$ = new Linq.GroupBy ((Linq.QueryBlock)current_block, (Expression)$3, linq_clause_blocks.Pop (), (Expression)$6, GetLocation ($1)); - lbag.AddLocation ($$, GetLocation ($5)); + var obj = (object[]) $5; + + $$ = new Linq.GroupBy ((Linq.QueryBlock)current_block, (Expression)$3, linq_clause_blocks.Pop (), (Expression)obj[0], GetLocation ($1)); + lbag.AddLocation ($$, (Location) obj[1]); current_block.SetEndLocation (lexer.Location); current_block = current_block.Parent; } ; + +by_expression + : BY expression_or_error + { + $$ = new object[] { $2, GetLocation ($1) }; + } + | error + { + Error_SyntaxError (yyToken); + $$ = new object[2] { null, Location.Null }; + } + ; query_body_clauses : query_body_clause @@ -6183,7 +6672,7 @@ let_clause } expression_or_error { - var lt = (Tokenizer.LocatedToken) $2; + var lt = (LocatedToken) $2; var sn = new Linq.RangeVariable (lt.Value, lt.Location); $$ = new Linq.Let ((Linq.QueryBlock) current_block, sn, (Expression)$5, GetLocation ($1)); lbag.AddLocation ($$, GetLocation ($3)); @@ -6242,7 +6731,7 @@ join_clause var outer_selector = linq_clause_blocks.Pop (); var block = linq_clause_blocks.Pop (); - var lt = (Tokenizer.LocatedToken) $2; + var lt = (LocatedToken) $2; var sn = new Linq.RangeVariable (lt.Value, lt.Location); Linq.RangeVariable into; @@ -6262,7 +6751,7 @@ join_clause ((Linq.QueryBlock)current_block).AddRangeVariable (sn); - lt = (Tokenizer.LocatedToken) $12; + lt = (LocatedToken) $12; into = new Linq.RangeVariable (lt.Value, lt.Location); $$ = new Linq.GroupJoin (block, sn, (Expression)$5, outer_selector, (Linq.QueryBlock) current_block, into, GetLocation ($1)); @@ -6304,7 +6793,7 @@ join_clause var outer_selector = linq_clause_blocks.Pop (); var block = linq_clause_blocks.Pop (); - var lt = (Tokenizer.LocatedToken) $3; + var lt = (LocatedToken) $3; var sn = new Linq.RangeVariable (lt.Value, lt.Location); Linq.RangeVariable into; @@ -6326,7 +6815,7 @@ join_clause ((Linq.QueryBlock)current_block).AddRangeVariable (sn); - lt = (Tokenizer.LocatedToken) $13; + lt = (LocatedToken) $13; into = new Linq.RangeVariable (lt.Value, lt.Location); // TODO: $$ = new Linq.GroupJoin (block, sn, (Expression)$6, outer_selector, (Linq.QueryBlock) current_block, into, GetLocation ($1)) { @@ -6353,6 +6842,7 @@ orderby_clause : ORDERBY { current_block = new Linq.QueryBlock (current_block, lexer.Location); + lbag.AddLocation (current_block, GetLocation ($1)); } orderings { @@ -6451,7 +6941,7 @@ opt_query_continuation query_body { var current_block = linq_clause_blocks.Pop (); - var lt = (Tokenizer.LocatedToken) $2; + var lt = (LocatedToken) $2; var rv = new Linq.RangeVariable (lt.Value, lt.Location); $$ = new Linq.QueryStartClause ((Linq.QueryBlock)current_block, null, rv, GetLocation ($1)) { next = (Linq.AQueryClause)$4 @@ -6489,27 +6979,30 @@ interactive_parsing mods |= Modifiers.UNSAFE; current_local_parameters = pars; - Method method = new Method ( + var method = new InteractiveMethod ( current_type, new TypeExpression (compiler.BuiltinTypes.Void, Location.Null), mods, - new MemberName ("Host"), - pars, - null /* attributes */); + pars); current_type.AddMember (method); - oob_stack.Push (method); + + interactive_async = false; + ++lexer.parsing_block; start_block (lexer.Location); } interactive_statement_list opt_COMPLETE_COMPLETION { --lexer.parsing_block; - Method method = (Method) oob_stack.Pop (); - + var method = (InteractiveMethod) oob_stack.Pop (); method.Block = (ToplevelBlock) end_block(lexer.Location); + if (interactive_async == true) { + method.ChangeToAsync (); + } + InteractiveResult = (Class) pop_current_class (); current_local_parameters = null; } @@ -6552,11 +7045,17 @@ doc_cref module.DocumentationBuilder.ParsedParameters = (List)$2; $$ = null; } + | VOID opt_doc_method_sig + { + module.DocumentationBuilder.ParsedBuiltinType = new TypeExpression (compiler.BuiltinTypes.Void, GetLocation ($1)); + module.DocumentationBuilder.ParsedParameters = (List)$2; + $$ = null; + } | builtin_types DOT IDENTIFIER opt_doc_method_sig { module.DocumentationBuilder.ParsedBuiltinType = (TypeExpression)$1; module.DocumentationBuilder.ParsedParameters = (List)$4; - var lt = (Tokenizer.LocatedToken) $3; + var lt = (LocatedToken) $3; $$ = new MemberName (lt.Value); } | doc_type_declaration_name DOT THIS @@ -6590,7 +7089,7 @@ doc_cref } | OPERATOR overloadable_operator opt_doc_method_sig { - var p = (List)$3 ?? new List (1); + var p = (List)$3; module.DocumentationBuilder.ParsedParameters = p; module.DocumentationBuilder.ParsedOperator = (Operator.OpType) $2; $$ = null; @@ -6673,7 +7172,7 @@ void Error_ExpectingTypeName (Expression expr) if (expr is Invocation){ report.Error (1002, expr.Location, "Expecting `;'"); } else { - Expression.Error_InvalidExpressionStatement (report, expr.Location); + expr.Error_InvalidExpressionStatement (report); } } @@ -6714,6 +7213,16 @@ void Error_MissingInitializer (Location loc) report.Error (210, loc, "You must provide an initializer in a fixed or using statement declaration"); } +object Error_AwaitAsIdentifier (object token) +{ + if (async_block) { + report.Error (4003, GetLocation (token), "`await' cannot be used as an identifier within an async method or lambda expression"); + return new LocatedToken ("await", GetLocation (token)); + } + + return token; +} + void push_current_container (TypeDefinition tc, object partial_token) { if (module.Evaluator != null){ @@ -6763,15 +7272,37 @@ List> GetModifierLocations () return result; } -string CheckAttributeTarget (string a, Location l) +[System.Diagnostics.Conditional ("FULL_AST")] +void PushLocation (Location loc) +{ + if (location_stack == null) + location_stack = new Stack (); + + location_stack.Push (loc); +} + +Location PopLocation () +{ + if (location_stack == null) + return Location.Null; + + return location_stack.Pop (); +} + +string CheckAttributeTarget (int token, string a, Location l) { switch (a) { case "assembly" : case "module" : case "field" : case "method" : case "param" : case "property" : case "type" : return a; } - report.Warning (658, 1, l, - "`{0}' is invalid attribute target. All attributes in this attribute section will be ignored", a); + if (!Tokenizer.IsValidIdentifier (a)) { + Error_SyntaxError (token); + } else { + report.Warning (658, 1, l, + "`{0}' is invalid attribute target. All attributes in this attribute section will be ignored", a); + } + return string.Empty; } @@ -6823,7 +7354,7 @@ public CSharpParser (SeekableStreamReader reader, CompilationSourceFile file, Re lang_version = settings.Version; yacc_verbose_flag = settings.VerboseParserFlag; doc_support = settings.DocumentationFile != null; - lexer = new Tokenizer (reader, file, session); + lexer = new Tokenizer (reader, file, session, report); oob_stack = new Stack (); lbag = session.LocationsBag; use_global_stacks = session.UseJayGlobalArrays; @@ -6850,7 +7381,8 @@ public void parse () } if (e is yyParser.yyException) { - report.Error (-25, lexer.Location, "Parsing error"); + if (report.Errors == 0) + report.Error (-25, lexer.Location, "Parsing error"); } else { // Used by compiler-tester to test internal errors if (yacc_verbose_flag > 0 || e is FatalException) @@ -6884,7 +7416,7 @@ void FeatureIsNotAvailable (Location loc, string feature) Location GetLocation (object obj) { - var lt = obj as Tokenizer.LocatedToken; + var lt = obj as LocatedToken; if (lt != null) return lt.Location; @@ -6962,7 +7494,7 @@ AnonymousMethodExpression end_anonymous (ParametersBlock anon_block) retval = current_anonymous_method; async_block = (bool) oob_stack.Pop (); - current_variable = (BlockVariableDeclaration) oob_stack.Pop (); + current_variable = (BlockVariable) oob_stack.Pop (); current_local_parameters = (ParametersCompiled) oob_stack.Pop (); current_anonymous_method = (AnonymousMethodExpression) oob_stack.Pop (); @@ -6986,6 +7518,10 @@ void Error_SyntaxError (int error_code, int token, string msg) // An error message has been reported by tokenizer if (token == Token.ERROR) return; + + // Avoid duplicit error message after unterminated string literals + if (token == Token.LITERAL && lexer.Location.Column == 0) + return; string symbol = GetSymbolName (token); string expecting = GetExpecting (); @@ -7067,7 +7603,7 @@ string GetSymbolName (int token) case Token.LITERAL: return ((Constant)lexer.Value).GetValue ().ToString (); case Token.IDENTIFIER: - return ((Tokenizer.LocatedToken)lexer.Value).Value; + return ((LocatedToken)lexer.Value).Value; case Token.BOOL: return "bool"; diff --git a/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/cs-tokenizer.cs b/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/cs-tokenizer.cs index f8926924e..9b692bf46 100644 --- a/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/cs-tokenizer.cs +++ b/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/cs-tokenizer.cs @@ -20,6 +20,44 @@ using System.Collections; namespace Mono.CSharp { + // + // This class has to be used by parser only, it reuses token + // details once a file is parsed + // + public class LocatedToken + { + public int row, column; + public string value; + public SourceFile file; + + public LocatedToken () + { + } + + public LocatedToken (string value, Location loc) + { + this.value = value; + file = loc.SourceFile; + row = loc.Row; + column = loc.Column; + } + + public override string ToString () + { + return string.Format ("Token '{0}' at {1},{2}", Value, row, column); + } + + public Location Location + { + get { return new Location (file, row, column); } + } + + public string Value + { + get { return value; } + } + } + /// /// Tokenizer for C# source code. /// @@ -66,42 +104,6 @@ namespace Mono.CSharp } } - // - // This class has to be used by parser only, it reuses token - // details after each file parse completion - // - public class LocatedToken - { - public int row, column; - public string value; - public SourceFile file; - - public LocatedToken () - { - } - - public LocatedToken (string value, Location loc) - { - this.value = value; - file = loc.SourceFile; - row = loc.Row; - column = loc.Column; - } - - public override string ToString () - { - return string.Format ("Token '{0}' at {1},{2}", Value, row, column); - } - - public Location Location { - get { return new Location (file, row, column); } - } - - public string Value { - get { return value; } - } - } - public class LocatedTokenBuffer { readonly LocatedToken[] buffer; @@ -186,6 +188,8 @@ namespace Mono.CSharp readonly CompilationSourceFile source_file; public CompilationSourceFile SourceFile { get { return source_file; } } readonly CompilerContext context; + readonly Report Report; + SourceFile current_source; Location hidden_block_start; @@ -197,7 +201,7 @@ namespace Mono.CSharp readonly int tab_size; bool handle_get_set = false; bool handle_remove_add = false; - bool handle_where = false; + bool handle_where; bool handle_typeof = false; bool lambda_arguments_parsing; List escaped_identifiers; @@ -247,6 +251,9 @@ namespace Mono.CSharp public const int EvalCompilationUnitParserCharacter = 0x100001; public const int EvalUsingDeclarationsParserCharacter = 0x100002; public const int DocumentationXref = 0x100003; + + const int UnicodeLS = 0x2028; + const int UnicodePS = 0x2029; // // XML documentation buffer. The save point is used to divide @@ -439,7 +446,7 @@ namespace Mono.CSharp } } - public Tokenizer (SeekableStreamReader input, CompilationSourceFile file, ParserSession session) + public Tokenizer (SeekableStreamReader input, CompilationSourceFile file, ParserSession session, Report report) { this.source_file = file; this.context = file.Compiler; @@ -448,6 +455,7 @@ namespace Mono.CSharp this.id_builder = session.IDBuilder; this.number_builder = session.NumberBuilder; this.ltb = new LocatedTokenBuffer (session.LocatedTokens); + this.Report = report; reader = input; @@ -710,7 +718,7 @@ namespace Mono.CSharp } break; case Token.WHERE: - if (!handle_where && !query_parsing) + if (!(handle_where && current_token != Token.COLON) && !query_parsing) res = -1; break; case Token.FROM: @@ -719,7 +727,7 @@ namespace Mono.CSharp // followed by any token except ; , = // if (!query_parsing) { - if (lambda_arguments_parsing) { + if (lambda_arguments_parsing || parsing_block == 0) { res = -1; break; } @@ -742,7 +750,7 @@ namespace Mono.CSharp case Token.UINT: case Token.ULONG: next_token = xtoken (); - if (next_token == Token.SEMICOLON || next_token == Token.COMMA || next_token == Token.EQUALS) + if (next_token == Token.SEMICOLON || next_token == Token.COMMA || next_token == Token.EQUALS || next_token == Token.ASSIGN) goto default; res = Token.FROM_FIRST; @@ -782,6 +790,7 @@ namespace Mono.CSharp case Token.NAMESPACE: // TODO: some explanation needed check_incorrect_doc_comment (); + parsing_modifiers = false; break; case Token.PARTIAL: @@ -815,8 +824,17 @@ namespace Mono.CSharp Report.Error (267, Location, "The `partial' modifier can be used only immediately before `class', `struct', `interface', or `void' keyword"); return token (); - } + } + // HACK: A token is not a keyword so we need to restore identifiers buffer + // which has been overwritten before we grabbed the identifier + id_builder[0] = 'p'; + id_builder[1] = 'a'; + id_builder[2] = 'r'; + id_builder[3] = 't'; + id_builder[4] = 'i'; + id_builder[5] = 'a'; + id_builder[6] = 'l'; res = -1; break; @@ -839,8 +857,10 @@ namespace Mono.CSharp case Token.IDENTIFIER: PushPosition (); xtoken (); - if (xtoken () != Token.ARROW) + if (xtoken () != Token.ARROW) { + PopPosition (); goto default; + } PopPosition (); break; @@ -927,7 +947,27 @@ namespace Mono.CSharp if (c < 0x80) return false; - return Char.IsLetter (c) || Char.GetUnicodeCategory (c) == UnicodeCategory.ConnectorPunctuation; + return is_identifier_part_character_slow_part (c); + } + + static bool is_identifier_part_character_slow_part (char c) + { + if (Char.IsLetter (c)) + return true; + + switch (Char.GetUnicodeCategory (c)) { + case UnicodeCategory.ConnectorPunctuation: + + // combining-character: A Unicode character of classes Mn or Mc + case UnicodeCategory.NonSpacingMark: + case UnicodeCategory.SpacingCombiningMark: + + // decimal-digit-character: A Unicode character of the class Nd + case UnicodeCategory.DecimalDigitNumber: + return true; + } + + return false; } public static bool IsKeyword (string s) @@ -964,8 +1004,12 @@ namespace Mono.CSharp // // Expression inside parens is single type, (int[]) // - if (is_type) + if (is_type) { + if (current_token == Token.SEMICOLON) + return Token.OPEN_PARENS; + return Token.OPEN_PARENS_CAST; + } // // Expression is possible cast, look at next token, (T)null @@ -1022,6 +1066,7 @@ namespace Mono.CSharp continue; case Token.IDENTIFIER: + case Token.AWAIT: switch (ptoken) { case Token.DOT: if (bracket_level == 0) { @@ -1182,16 +1227,26 @@ namespace Mono.CSharp return false; } + List genericLocs = new List (); + + public List GetGenericDimensionLocations () + { + return genericLocs; + } + bool parse_generic_dimension (out int dimension) { dimension = 1; again: int the_token = token (); - if (the_token == Token.OP_GENERICS_GT) + if (the_token == Token.OP_GENERICS_GT) { + genericLocs.Add (Location); return true; + } else if (the_token == Token.COMMA) { dimension++; + genericLocs.Add (Location); goto again; } @@ -1203,7 +1258,9 @@ namespace Mono.CSharp int the_token; PushPosition (); + sbag.Suppress = true; the_token = token (); + sbag.Suppress = false; PopPosition (); return the_token; @@ -1213,7 +1270,7 @@ namespace Mono.CSharp // Tonizes `?' using custom disambiguous rules to return one // of following tokens: INTERR_NULLABLE, OP_COALESCING, INTERR // - // Tricky expression look like: + // Tricky expression looks like: // // Foo ? a = x ? b : c; // @@ -1263,6 +1320,8 @@ namespace Mono.CSharp case Token.OPEN_BRACKET: case Token.OP_GENERICS_GT: case Token.INTERR: + case Token.OP_COALESCING: + case Token.COLON: next_token = Token.INTERR_NULLABLE; break; @@ -1290,18 +1349,27 @@ namespace Mono.CSharp int interrs = 1; int colons = 0; int braces = 0; + int parens = 0; // // All shorcuts failed, do it hard way // while ((ntoken = xtoken ()) != Token.EOF) { - if (ntoken == Token.OPEN_BRACE) { + switch (ntoken) { + case Token.OPEN_BRACE: ++braces; continue; - } - - if (ntoken == Token.CLOSE_BRACE) { + case Token.OPEN_PARENS: + case Token.OPEN_PARENS_CAST: + case Token.OPEN_PARENS_LAMBDA: + ++parens; + continue; + case Token.CLOSE_BRACE: --braces; continue; + case Token.CLOSE_PARENS: + if (parens > 0) + --parens; + continue; } if (braces != 0) @@ -1309,6 +1377,9 @@ namespace Mono.CSharp if (ntoken == Token.SEMICOLON) break; + + if (parens != 0) + continue; if (ntoken == Token.COLON) { if (++colons == interrs) @@ -1401,7 +1472,7 @@ namespace Mono.CSharp // if we have not seen anything in between // report this error // - Report.Warning (78, 4, Location, "The 'l' suffix is easily confused with the digit '1' (use 'L' for clarity)"); + Report.Warning (78, 4, Location, "The `l' suffix is easily confused with the digit `1' (use `L' for clarity)"); } goto case 'L'; @@ -1557,13 +1628,13 @@ namespace Mono.CSharp // // Invoked if we know we have .digits or digits // - int is_number (int c) + int is_number (int c, bool dotLead) { ILiteralConstant res; #if FULL_AST int read_start = reader.Position - 1; - if (c == '.') { + if (dotLead) { // // Caller did peek_char // @@ -1574,7 +1645,7 @@ namespace Mono.CSharp var loc = Location; bool hasLeadingDot = c == '.'; - if (c >= '0' && c <= '9'){ + if (!dotLead){ if (c == '0'){ int peek = peek_char (); @@ -1588,7 +1659,7 @@ namespace Mono.CSharp } } decimal_digits (c); - c = get_char (); + c = peek_char (); } // @@ -1597,9 +1668,12 @@ namespace Mono.CSharp // bool is_real = false; if (c == '.'){ + if (!dotLead) + get_char (); + if (decimal_digits ('.')){ is_real = true; - c = get_char (); + c = peek_char (); } else { putback ('.'); number_pos--; @@ -1613,6 +1687,7 @@ namespace Mono.CSharp if (c == 'e' || c == 'E'){ is_real = true; + get_char (); if (number_pos == MaxNumberLength) Error_NumericConstantTooLong (); number_builder [number_pos++] = (char) c; @@ -1635,18 +1710,17 @@ namespace Mono.CSharp } decimal_digits (c); - c = get_char (); + c = peek_char (); } var type = real_type_suffix (c); if (type == TypeCode.Empty && !is_real) { - putback (c); res = adjust_int (c, loc); } else { is_real = true; - if (type == TypeCode.Empty) { - putback (c); + if (type != TypeCode.Empty) { + get_char (); } res = adjust_real (type, loc); @@ -1794,43 +1868,35 @@ namespace Mono.CSharp x = reader.Read (); } - if (x == '\r') { - if (peek_char () == '\n') { - putback_char = -1; + if (x <= 13) { + if (x == '\r') { + if (peek_char () == '\n') { + putback_char = -1; + advance_line (SpecialsBag.NewLine.Windows); + } else { + advance_line (SpecialsBag.NewLine.Unix); + } + + x = '\n'; + } else if (x == '\n') { + advance_line (SpecialsBag.NewLine.Unix); + } else { + col++; } - - x = '\n'; - advance_line (); - } else if (x == '\n') { - advance_line (); + } else if (x >= UnicodeLS && x <= UnicodePS) { + advance_line (SpecialsBag.NewLine.Unix); } else { col++; } - 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 () + bool recordNewLine = true; + void advance_line (SpecialsBag.NewLine newLine) { + if (recordNewLine) + sbag.AddNewLine (line, col, newLine); line++; ref_line++; previous_col = col; @@ -1858,7 +1924,7 @@ namespace Mono.CSharp 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) { + if (c == '\n' || col == 0 || (c >= UnicodeLS && c <= UnicodePS)) { // It won't happen though. line--; ref_line--; @@ -1893,11 +1959,11 @@ namespace Mono.CSharp int TokenizePreprocessorIdentifier (out int c) { - int endLine, endCol; - return TokenizePreprocessorIdentifier (out c, out endLine, out endCol); + int startCol, endLine, endCol; + return TokenizePreprocessorIdentifier (out c, out startCol, out endLine, out endCol); } - int TokenizePreprocessorIdentifier (out int c, out int endLine, out int endCol) + int TokenizePreprocessorIdentifier (out int c, out int startCol, out int endLine, out int endCol) { // skip over white space do { @@ -1905,7 +1971,7 @@ namespace Mono.CSharp endCol = col; c = get_char (); } while (c == ' ' || c == '\t'); - + startCol = col; int pos = 0; while (c != -1 && c >= 'a' && c <= 'z') { id_builder[pos++] = (char) c; @@ -1937,8 +2003,8 @@ namespace Mono.CSharp tokens_seen = false; arg = ""; - int endLine, endCol; - var cmd = GetPreprocessorDirective (id_builder, TokenizePreprocessorIdentifier (out c, out endLine, out endCol)); + int startCol2, endLine, endCol; + var cmd = GetPreprocessorDirective (id_builder, TokenizePreprocessorIdentifier (out c, out startCol2, out endLine, out endCol)); if ((cmd & PreprocessorDirective.CustomArgumentsParsing) != 0) { if (position_stack.Count == 0) @@ -1951,9 +2017,8 @@ namespace Mono.CSharp c = get_char (); } int has_identifier_argument = (int)(cmd & PreprocessorDirective.RequiresArgument); - int pos = 0; - while (c != -1 && c != '\n' && c != '\r') { + while (c != -1 && c != '\n' && c != UnicodeLS && c != UnicodePS) { if (c == '\\' && has_identifier_argument >= 0) { if (has_identifier_argument != 0) { has_identifier_argument = 1; @@ -1980,10 +2045,7 @@ namespace Mono.CSharp // Eat single-line comments // get_char (); - do { - c = get_char (); - } while (c != -1 && c != '\n'); - + ReadToEndOfLine (); break; } @@ -2018,6 +2080,9 @@ namespace Mono.CSharp bool PreProcessLine () { Location loc = Location; + #if FULL_AST + var lineDirective = sbag.GetCurrentLineProcessorDirective(); + #endif int c; @@ -2050,10 +2115,7 @@ namespace Mono.CSharp // // Eat any remaining characters to continue parsing on next line // - while (c != -1 && c != '\n') { - c = get_char (); - } - + ReadToEndOfLine (); return false; } @@ -2062,12 +2124,12 @@ namespace Mono.CSharp // // Eat any remaining characters to continue parsing on next line // - while (c != -1 && c != '\n') { - c = get_char (); - } - + ReadToEndOfLine (); return new_line != 0; } + #if FULL_AST + lineDirective.LineNumber = new_line; + #endif c = get_char (); if (c == ' ') { @@ -2079,13 +2141,11 @@ namespace Mono.CSharp c = 0; } - if (c != '\n' && c != '/' && c != '"') { + if (c != '\n' && c != '/' && c != '"' && c != UnicodeLS && c != UnicodePS) { // // Eat any remaining characters to continue parsing on next line // - while (c != -1 && c != '\n') { - c = get_char (); - } + ReadToEndOfLine (); Report.Error (1578, loc, "Filename, single-line comment or end-of-line expected"); return true; @@ -2094,6 +2154,9 @@ namespace Mono.CSharp string new_file_name = null; if (c == '"') { new_file_name = TokenizeFileName (ref c); + #if FULL_AST + lineDirective.FileName = new_file_name; + #endif // skip over white space while (c == ' ' || c == '\t') { @@ -2101,16 +2164,15 @@ namespace Mono.CSharp } } - if (c == '\n') { + if (c == '\n' || c == UnicodeLS || c == UnicodePS) { + } else if (c == '/') { ReadSingleLineComment (); } else { // // Eat any remaining characters to continue parsing on next line // - while (c != -1 && c != '\n') { - c = get_char (); - } + ReadToEndOfLine (); Error_EndLineExpected (); return true; @@ -2345,7 +2407,7 @@ namespace Mono.CSharp string TokenizeFileName (ref int c) { var string_builder = new StringBuilder (); - while (c != -1 && c != '\n') { + while (c != -1 && c != '\n' && c != UnicodeLS && c != UnicodePS) { c = get_char (); if (c == '"') { c = get_char (); @@ -2393,16 +2455,21 @@ namespace Mono.CSharp Report.Warning (1692, 1, Location, "Invalid number"); // Read everything till the end of the line or file - do { - c = get_char (); - } while (c != -1 && c != '\n'); + ReadToEndOfLine (); } } return number; } - - + + void ReadToEndOfLine () + { + int c; + do { + c = get_char (); + } while (c != -1 && c != '\n' && c != UnicodeLS && c != UnicodePS); + } + void ReadSingleLineComment () { if (peek_char () != '/') @@ -2416,20 +2483,30 @@ namespace Mono.CSharp if (position_stack.Count == 0) sbag.PushCommentChar (c); var pc = peek_char (); - if ((pc == '\n' || pc == -1) && position_stack.Count == 0) + if ((pc == '\n' || pc == -1 || pc == UnicodeLS || pc == UnicodePS) && position_stack.Count == 0) sbag.EndComment (line, col + 1); - } while (c != -1 && c != '\n'); + } while (c != -1 && c != '\n' && c != UnicodeLS && c != UnicodePS); } /// /// Handles #pragma directive /// - void ParsePragmaDirective (string arg) + void ParsePragmaDirective () { int c; - int length = TokenizePreprocessorIdentifier (out c); + int startCol, endLine, endCol; + int length = TokenizePreprocessorIdentifier (out c, out startCol, out endLine, out endCol); + #if FULL_AST + var pragmaDirective = sbag.GetPragmaPreProcessorDirective(); + if (pragmaDirective != null) + pragmaDirective.WarningColumn = startCol; + #endif if (length == pragma_warning.Length && IsTokenIdentifierEqual (pragma_warning)) { - length = TokenizePreprocessorIdentifier (out c); + length = TokenizePreprocessorIdentifier (out c, out startCol, out endLine, out endCol); + #if FULL_AST + if (pragmaDirective != null) + pragmaDirective.DisableRestoreColumn = startCol; + #endif // // #pragma warning disable @@ -2437,6 +2514,10 @@ namespace Mono.CSharp // if (length == pragma_warning_disable.Length) { bool disable = IsTokenIdentifierEqual (pragma_warning_disable); + #if FULL_AST + if (pragmaDirective != null) + pragmaDirective.Disalbe = disable; + #endif if (disable || IsTokenIdentifierEqual (pragma_warning_restore)) { // skip over white space while (c == ' ' || c == '\t') @@ -2444,7 +2525,7 @@ namespace Mono.CSharp var loc = Location; - if (c == '\n' || c == '/') { + if (c == '\n' || c == '/' || c == UnicodeLS || c == UnicodePS) { if (c == '/') ReadSingleLineComment (); @@ -2462,15 +2543,25 @@ namespace Mono.CSharp // int code; do { + var startLoc = loc; + #if FULL_AST + // int read_start = reader.Position; + #endif code = TokenizePragmaNumber (ref c); if (code > 0) { + #if FULL_AST + var literal = new IntConstant(context.BuiltinTypes, code, startLoc); + if (pragmaDirective != null) + pragmaDirective.Codes.Add (literal); + // literal.ParsedValue = reader.ReadChars (read_start, reader.Position + 1); + #endif if (disable) { Report.RegisterWarningRegion (loc).WarningDisable (loc, code, context.Report); } else { Report.RegisterWarningRegion (loc).WarningEnable (loc, code, context); } } - } while (code >= 0 && c != '\n' && c != -1); + } while (code >= 0 && c != '\n' && c != -1 && c != UnicodeLS && c != UnicodePS); } return; @@ -2478,9 +2569,14 @@ namespace Mono.CSharp } Report.Warning (1634, 1, Location, "Expected disable or restore"); + + // Eat any remaining characters on the line + ReadToEndOfLine (); + return; } + // // #pragma checksum // @@ -2797,6 +2893,7 @@ namespace Mono.CSharp } if ((state & TAKING) != 0) { + sbag.SkipIf (); ifstack.Push (0); return false; } @@ -2806,6 +2903,7 @@ namespace Mono.CSharp return true; } + sbag.SkipIf (); ifstack.Push (state); return false; } @@ -2850,7 +2948,8 @@ namespace Mono.CSharp } case PreprocessorDirective.Define: if (any_token_seen){ - Error_TokensSeen (); + if (caller_is_taking) + Error_TokensSeen (); return caller_is_taking; } PreProcessDefinition (true, arg, caller_is_taking); @@ -2858,7 +2957,8 @@ namespace Mono.CSharp case PreprocessorDirective.Undef: if (any_token_seen){ - Error_TokensSeen (); + if (caller_is_taking) + Error_TokensSeen (); return caller_is_taking; } PreProcessDefinition (false, arg, caller_is_taking); @@ -2889,7 +2989,7 @@ namespace Mono.CSharp Report.FeatureIsNotAvailable (context, Location, "#pragma"); } - ParsePragmaDirective (arg); + ParsePragmaDirective (); return true; case PreprocessorDirective.Line: @@ -2908,16 +3008,27 @@ namespace Mono.CSharp int c; int pos = 0; Location start_location = Location; - if (quoted) + if (quoted) { start_location = start_location - 1; + recordNewLine = false; + } #if FULL_AST int reader_pos = reader.Position; #endif while (true){ - c = get_char_withwithoutskippingwindowseol (); + // Cannot use get_char because of \r in quoted strings + if (putback_char != -1) { + c = putback_char; + putback_char = -1; + } else { + c = reader.Read (); + } + if (c == '"') { + ++col; + if (quoted && peek_char () == '"') { if (pos == value_builder.Length) Array.Resize (ref value_builder, pos * 2); @@ -2942,21 +3053,37 @@ namespace Mono.CSharp reader.ReadChars (reader_pos - 2, reader.Position - 1) : reader.ReadChars (reader_pos - 1, reader.Position); #endif - + recordNewLine = true; return Token.LITERAL; } - if (c == '\n') { + if (c == '\n' || c == UnicodeLS || c == UnicodePS) { if (!quoted) { Report.Error (1010, Location, "Newline in constant"); + + + // Don't add \r to string literal + if (pos > 1 && value_builder [pos - 1] == '\r') { + advance_line (SpecialsBag.NewLine.Windows); + --pos; + } else { + advance_line (SpecialsBag.NewLine.Unix); + } + val = new StringLiteral (context.BuiltinTypes, new string (value_builder, 0, pos), start_location); + recordNewLine = true; return Token.LITERAL; } + + advance_line (SpecialsBag.NewLine.Unix); } else if (c == '\\' && !quoted) { + ++col; int surrogate; c = escape (c, out surrogate); - if (c == -1) + if (c == -1) { + recordNewLine = true; return Token.ERROR; + } if (surrogate != 0) { if (pos == value_builder.Length) Array.Resize (ref value_builder, pos * 2); @@ -2966,7 +3093,10 @@ namespace Mono.CSharp } } else if (c == -1) { Report.Error (1039, Location, "Unterminated string literal"); + recordNewLine = true; return Token.EOF; + } else { + ++col; } if (pos == value_builder.Length) @@ -2974,6 +3104,7 @@ namespace Mono.CSharp value_builder[pos++] = (char) c; } + recordNewLine = true; } private int consume_identifier (int s) @@ -3031,7 +3162,7 @@ namespace Mono.CSharp continue; } - } else if (Char.IsLetter ((char) c) || Char.GetUnicodeCategory ((char) c) == UnicodeCategory.ConnectorPunctuation) { + } else if (is_identifier_part_character_slow_part ((char) c)) { id_builder [pos++] = (char) c; continue; } @@ -3166,6 +3297,8 @@ namespace Mono.CSharp case '\v': case '\r': case '\n': + case UnicodeLS: + case UnicodePS: case '/': next = peek_token (); if (next == Token.COMMA || next == Token.CLOSE_BRACKET) @@ -3196,6 +3329,7 @@ namespace Mono.CSharp case Token.FOREACH: case Token.TYPEOF: case Token.WHILE: + case Token.SWITCH: case Token.USING: case Token.DEFAULT: case Token.DELEGATE: @@ -3392,7 +3526,7 @@ namespace Mono.CSharp d = peek_char (); int endLine = line, endCol = col; - while ((d = get_char ()) != -1 && (d != '\n') && d != '\r') { + while ((d = get_char ()) != -1 && (d != '\n') && d != '\r' && d != UnicodePS && d != UnicodeLS) { if (position_stack.Count == 0) sbag.PushCommentChar (d); endLine = line; @@ -3400,14 +3534,15 @@ namespace Mono.CSharp } if (position_stack.Count == 0) sbag.EndComment (endLine, endCol + 1); - any_token_seen |= tokens_seen; tokens_seen = false; comments_seen = false; continue; } else if (d == '*'){ - if (position_stack.Count == 0) + if (position_stack.Count == 0) { sbag.StartComment (SpecialsBag.CommentType.Multi, startsLine, line, col); + recordNewLine = false; + } get_char (); bool docAppend = false; if (doc_processing && peek_char () == '*') { @@ -3416,6 +3551,7 @@ namespace Mono.CSharp if (peek_char () == '/') { ch = get_char (); if (position_stack.Count == 0) { + recordNewLine = true; sbag.EndComment (line, col + 1); } continue; @@ -3439,8 +3575,10 @@ namespace Mono.CSharp while ((d = get_char ()) != -1){ if (d == '*' && peek_char () == '/'){ get_char (); - if (position_stack.Count == 0) + if (position_stack.Count == 0) { + recordNewLine = true; sbag.EndComment (line, col + 1); + } comments_seen = true; break; } else { @@ -3450,7 +3588,7 @@ namespace Mono.CSharp if (docAppend) xml_comment_buffer.Append ((char) d); - if (d == '\n'){ + if (d == '\n' || d == UnicodeLS || d == UnicodePS){ any_token_seen |= tokens_seen; tokens_seen = false; // @@ -3498,9 +3636,11 @@ namespace Mono.CSharp case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': tokens_seen = true; - return is_number (c); + return is_number (c, false); case '\n': // white space + case UnicodeLS: + case UnicodePS: any_token_seen |= tokens_seen; tokens_seen = false; comments_seen = false; @@ -3510,20 +3650,21 @@ namespace Mono.CSharp tokens_seen = true; d = peek_char (); if (d >= '0' && d <= '9') - return is_number (c); + return is_number (c, true); ltb.CreateOptional (current_source, ref_line, col, ref val); return Token.DOT; case '#': if (tokens_seen || comments_seen) { - Eror_WrongPreprocessorLocation (); + Eror_WrongPreprocessorLocation(); return Token.ERROR; } - - if (ParsePreprocessingDirective (true)) + + if (ParsePreprocessingDirective(true)) continue; - sbag.StartComment (SpecialsBag.CommentType.InactiveCode, false, line, 1); + sbag.StartComment(SpecialsBag.CommentType.InactiveCode, false, line, 1); + recordNewLine = false; bool directive_expected = false; while ((c = get_char ()) != -1) { if (col == 1) { @@ -3538,18 +3679,24 @@ namespace Mono.CSharp continue; } - if (c == ' ' || c == '\t' || c == '\n' || c == '\f' || c == '\v' ) { + if (c == ' ' || c == '\t' || c == '\n' || c == '\f' || c == '\v' || c == UnicodeLS || c == UnicodePS) { sbag.PushCommentChar (c); continue; } if (c == '#') { - if (ParsePreprocessingDirective (false)) + var oldNL = recordNewLine; + recordNewLine = true; + var continueNormalLexing = ParsePreprocessingDirective(false); + recordNewLine = oldNL; + if (continueNormalLexing) break; + sbag.StartComment(SpecialsBag.CommentType.InactiveCode, false, line, 1); } sbag.PushCommentChar (c); directive_expected = false; } + recordNewLine = true; sbag.EndComment (line, col); if (c != -1) { tokens_seen = false; @@ -3625,7 +3772,7 @@ namespace Mono.CSharp return Token.LITERAL; } - if (c == '\n') { + if (c == '\n' || c == UnicodeLS || c == UnicodePS) { Report.Error (1010, start_location, "Newline in constant"); return Token.ERROR; } @@ -3646,7 +3793,7 @@ namespace Mono.CSharp // Try to recover, read until newline or next "'" while ((c = get_char ()) != -1) { - if (c == '\n' || c == '\'') + if (c == '\n' || c == '\'' || c == UnicodeLS || c == UnicodePS) break; } } @@ -3662,6 +3809,8 @@ namespace Mono.CSharp { int d; if (handle_typeof) { + genericLocs.Clear (); + genericLocs.Add (Location); PushPosition (); if (parse_generic_dimension (out d)) { val = d; @@ -3780,10 +3929,6 @@ namespace Mono.CSharp return null; } - Report Report { - get { return context.Report; } - } - void reset_doc_comment () { xml_comment_buffer.Length = 0; diff --git a/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/decl.cs b/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/decl.cs index 11eca1e7e..56d423ad2 100644 --- a/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/decl.cs +++ b/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/decl.cs @@ -53,12 +53,6 @@ namespace Mono.CSharp { : this (name, Location.Null) { } -#if FULL_AST - public Location DotLocation { - get; - set; - } -#endif public MemberName (string name, Location loc) : this (null, name, loc) { } @@ -300,7 +294,8 @@ namespace Mono.CSharp { HasStructLayout = 1 << 15, // Has StructLayoutAttribute HasInstanceConstructor = 1 << 16, HasUserOperators = 1 << 17, - CanBeReused = 1 << 18 + CanBeReused = 1 << 18, + InterfacesExpanded = 1 << 19 } /// @@ -308,7 +303,7 @@ namespace Mono.CSharp { /// internal Flags caching_flags; - public MemberCore (TypeContainer parent, MemberName name, Attributes attrs) + protected MemberCore (TypeContainer parent, MemberName name, Attributes attrs) { this.Parent = parent; member_name = name; @@ -440,7 +435,7 @@ namespace Mono.CSharp { if ((mod_flags & Modifiers.COMPILER_GENERATED) != 0) return true; - return Parent == null ? false : Parent.IsCompilerGenerated; + return Parent != null && Parent.IsCompilerGenerated; } } @@ -472,7 +467,7 @@ namespace Mono.CSharp { caching_flags |= Flags.IsAssigned; } - public void SetConstraints (List constraints_list) + public virtual void SetConstraints (List constraints_list) { var tparams = member_name.TypeParameters; if (tparams == null) { @@ -889,7 +884,7 @@ namespace Mono.CSharp { if (GetAttributeObsolete () != null) return true; - return Parent == null ? false : Parent.IsObsolete; + return Parent != null && Parent.IsObsolete; } } @@ -898,7 +893,7 @@ namespace Mono.CSharp { if ((ModFlags & Modifiers.UNSAFE) != 0) return true; - return Parent == null ? false : Parent.IsUnsafe; + return Parent != null && Parent.IsUnsafe; } } @@ -942,7 +937,8 @@ namespace Mono.CSharp { InflatedExpressionType = 1 << 19, InflatedNullableType = 1 << 20, GenericIterateInterface = 1 << 21, - GenericTask = 1 << 22 + GenericTask = 1 << 22, + InterfacesImported = 1 << 23, } // @@ -972,7 +968,10 @@ namespace Mono.CSharp { this.definition = definition; this.modifiers = modifiers; - state = StateFlags.Obsolete_Undetected | StateFlags.CLSCompliant_Undetected | StateFlags.MissingDependency_Undetected; + if (kind == MemberKind.MissingType) + state = StateFlags.MissingDependency; + else + state = StateFlags.Obsolete_Undetected | StateFlags.CLSCompliant_Undetected | StateFlags.MissingDependency_Undetected; } #region Properties @@ -1086,7 +1085,12 @@ namespace Mono.CSharp { // will contain types only but it can have numerous values for members // like methods where both return type and all parameters are checked // - public List GetMissingDependencies () + public List GetMissingDependencies () + { + return GetMissingDependencies (this); + } + + public List GetMissingDependencies (MemberSpec caller) { if ((state & (StateFlags.MissingDependency | StateFlags.MissingDependency_Undetected)) == 0) return null; @@ -1094,11 +1098,11 @@ namespace Mono.CSharp { state &= ~StateFlags.MissingDependency_Undetected; var imported = definition as ImportedDefinition; - List missing; + List missing; if (imported != null) { - missing = ResolveMissingDependencies (); + missing = ResolveMissingDependencies (caller); } else if (this is ElementTypeSpec) { - missing = ((ElementTypeSpec) this).Element.GetMissingDependencies (); + missing = ((ElementTypeSpec) this).Element.GetMissingDependencies (caller); } else { missing = null; } @@ -1110,7 +1114,7 @@ namespace Mono.CSharp { return missing; } - public abstract List ResolveMissingDependencies (); + public abstract List ResolveMissingDependencies (MemberSpec caller); protected virtual bool IsNotCLSCompliant (out bool attrValue) { @@ -1162,7 +1166,7 @@ namespace Mono.CSharp { var ctype = ctx.CurrentType; if (ma == Modifiers.PRIVATE) { - if (ctype == null) + if (ctype == null || parentType == null) return false; // // It's only accessible to the current class or children @@ -1228,7 +1232,7 @@ namespace Mono.CSharp { return (state & StateFlags.CLSCompliant) != 0; } - public bool IsConditionallyExcluded (IMemberContext ctx, Location loc) + public bool IsConditionallyExcluded (IMemberContext ctx) { if ((Kind & (MemberKind.Class | MemberKind.Method)) == 0) return false; @@ -1276,6 +1280,11 @@ namespace Mono.CSharp { void SetIsUsed (); } + public interface IMethodDefinition : IMemberDefinition + { + MethodBase Metadata { get; } + } + public interface IParametersMember : IInterfaceMemberSpec { AParametersCollection Parameters { get; } diff --git a/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/delegate.cs b/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/delegate.cs index f2923aa5b..907e6df0e 100644 --- a/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/delegate.cs +++ b/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/delegate.cs @@ -153,7 +153,7 @@ namespace Mono.CSharp { Report.SymbolRelatedToPreviousError (partype); Report.Error (59, Location, "Inconsistent accessibility: parameter type `{0}' is less accessible than delegate `{1}'", - TypeManager.CSharpName (partype), GetSignatureForError ()); + partype.GetSignatureForError (), GetSignatureForError ()); } } @@ -169,7 +169,7 @@ namespace Mono.CSharp { Report.SymbolRelatedToPreviousError (ret_type); Report.Error (58, Location, "Inconsistent accessibility: return type `" + - TypeManager.CSharpName (ret_type) + "' is less " + + ret_type.GetSignatureForError () + "' is less " + "accessible than delegate `" + GetSignatureForError () + "'"); return false; } @@ -181,7 +181,7 @@ namespace Mono.CSharp { return false; } - TypeManager.CheckTypeVariance (ret_type, Variance.Covariant, this); + VarianceDecl.CheckTypeVariance (ret_type, Variance.Covariant, this); var resolved_rt = new TypeExpression (ret_type, Location); InvokeBuilder = new Method (this, resolved_rt, MethodModifiers, new MemberName (InvokeMethodName), p, null); @@ -191,13 +191,13 @@ namespace Mono.CSharp { // Don't emit async method for compiler generated delegates (e.g. dynamic site containers) // if (!IsCompilerGenerated) { - DefineAsyncMethods (Parameters.CallingConvention, resolved_rt); + DefineAsyncMethods (resolved_rt); } return true; } - void DefineAsyncMethods (CallingConventions cc, TypeExpression returnType) + void DefineAsyncMethods (TypeExpression returnType) { var iasync_result = Module.PredefinedTypes.IAsyncResult; var async_callback = Module.PredefinedTypes.AsyncCallback; @@ -297,6 +297,12 @@ namespace Mono.CSharp { if (!Parameters.IsEmpty) { parameters.ResolveDefaultValues (this); } + + InvokeBuilder.PrepareEmit (); + if (BeginInvokeBuilder != null) { + BeginInvokeBuilder.PrepareEmit (); + EndInvokeBuilder.PrepareEmit (); + } } public override void Emit () @@ -436,17 +442,20 @@ namespace Mono.CSharp { protected MethodSpec constructor_method; protected MethodGroupExpr method_group; + public bool AllowSpecialMethodsInvocation { get; set; } + public override bool ContainsEmitWithAwait () { - return false; + var instance = method_group.InstanceExpression; + return instance != null && instance.ContainsEmitWithAwait (); } - public static Arguments CreateDelegateMethodArguments (AParametersCollection pd, TypeSpec[] types, Location loc) + public static Arguments CreateDelegateMethodArguments (ResolveContext rc, AParametersCollection pd, TypeSpec[] types, Location loc) { Arguments delegate_arguments = new Arguments (pd.Count); for (int i = 0; i < pd.Count; ++i) { Argument.AType atype_modifier; - switch (pd.FixedParameters [i].ModFlags) { + switch (pd.FixedParameters [i].ModFlags & Parameter.Modifier.RefOutMask) { case Parameter.Modifier.REF: atype_modifier = Argument.AType.Ref; break; @@ -458,7 +467,11 @@ namespace Mono.CSharp { break; } - delegate_arguments.Add (new Argument (new TypeExpression (types [i], loc), atype_modifier)); + var ptype = types[i]; + if (ptype.BuiltinType == BuiltinTypeSpec.Type.Dynamic) + ptype = rc.BuiltinTypes.Object; + + delegate_arguments.Add (new Argument (new TypeExpression (ptype, loc), atype_modifier)); } return delegate_arguments; @@ -494,7 +507,7 @@ namespace Mono.CSharp { var invoke_method = Delegate.GetInvokeMethod (type); - Arguments arguments = CreateDelegateMethodArguments (invoke_method.Parameters, invoke_method.Parameters.Types, loc); + Arguments arguments = CreateDelegateMethodArguments (ec, invoke_method.Parameters, invoke_method.Parameters.Types, loc); method_group = method_group.OverloadResolve (ec, ref arguments, this, OverloadResolver.Restrictions.CovariantDelegate); if (method_group == null) return null; @@ -507,7 +520,8 @@ namespace Mono.CSharp { return null; } - Invocation.IsSpecialMethodInvocation (ec, delegate_method, loc); + if (!AllowSpecialMethodsInvocation) + Invocation.IsSpecialMethodInvocation (ec, delegate_method, loc); ExtensionMethodGroupExpr emg = method_group as ExtensionMethodGroupExpr; if (emg != null) { @@ -515,11 +529,11 @@ namespace Mono.CSharp { TypeSpec e_type = emg.ExtensionExpression.Type; if (TypeSpec.IsValueType (e_type)) { ec.Report.Error (1113, loc, "Extension method `{0}' of value type `{1}' cannot be used to create delegates", - delegate_method.GetSignatureForError (), TypeManager.CSharpName (e_type)); + delegate_method.GetSignatureForError (), e_type.GetSignatureForError ()); } } - TypeSpec rt = delegate_method.ReturnType; + TypeSpec rt = method_group.BestCandidateReturnType; if (rt.BuiltinType == BuiltinTypeSpec.Type.Dynamic) rt = ec.BuiltinTypes.Object; @@ -528,7 +542,7 @@ namespace Mono.CSharp { Error_ConversionFailed (ec, delegate_method, ret_expr); } - if (delegate_method.IsConditionallyExcluded (ec, loc)) { + if (method_group.IsConditionallyExcluded) { ec.Report.SymbolRelatedToPreviousError (delegate_method); MethodOrOperator m = delegate_method.MemberDefinition as MethodOrOperator; if (m != null && m.IsPartialDefinition) { @@ -568,6 +582,11 @@ namespace Mono.CSharp { ec.Emit (OpCodes.Newobj, constructor_method); } + public override void FlowAnalysis (FlowAnalysisContext fc) { + base.FlowAnalysis (fc); + method_group.FlowAnalysis (fc); + } + void Error_ConversionFailed (ResolveContext ec, MethodSpec method, Expression return_type) { var invoke_method = Delegate.GetInvokeMethod (type); @@ -579,8 +598,8 @@ namespace Mono.CSharp { ec.Report.SymbolRelatedToPreviousError (method); if (ec.Module.Compiler.Settings.Version == LanguageVersion.ISO_1) { ec.Report.Error (410, loc, "A method or delegate `{0} {1}' parameters and return type must be same as delegate `{2} {3}' parameters and return type", - TypeManager.CSharpName (method.ReturnType), member_name, - TypeManager.CSharpName (invoke_method.ReturnType), Delegate.FullDelegateDesc (invoke_method)); + method.ReturnType.GetSignatureForError (), member_name, + invoke_method.ReturnType.GetSignatureForError (), Delegate.FullDelegateDesc (invoke_method)); return; } @@ -592,7 +611,7 @@ namespace Mono.CSharp { ec.Report.Error (407, loc, "A method or delegate `{0} {1}' return type does not match delegate `{2} {3}' return type", return_type.GetSignatureForError (), member_name, - TypeManager.CSharpName (invoke_method.ReturnType), Delegate.FullDelegateDesc (invoke_method)); + invoke_method.ReturnType.GetSignatureForError (), Delegate.FullDelegateDesc (invoke_method)); } public static bool ImplicitStandardConversionExists (ResolveContext ec, MethodGroupExpr mg, TypeSpec target_type) @@ -602,7 +621,7 @@ namespace Mono.CSharp { var invoke = Delegate.GetInvokeMethod (target_type); - Arguments arguments = CreateDelegateMethodArguments (invoke.Parameters, invoke.Parameters.Types, mg.Location); + Arguments arguments = CreateDelegateMethodArguments (ec, invoke.Parameters, invoke.Parameters.Types, mg.Location); return mg.OverloadResolve (ec, ref arguments, null, OverloadResolver.Restrictions.CovariantDelegate | OverloadResolver.Restrictions.ProbingOnly) != null; } @@ -638,18 +657,111 @@ namespace Mono.CSharp { // public class ImplicitDelegateCreation : DelegateCreation { - ImplicitDelegateCreation (TypeSpec t, MethodGroupExpr mg, Location l) + Field mg_cache; + + public ImplicitDelegateCreation (TypeSpec delegateType, MethodGroupExpr mg, Location loc) { - type = t; + type = delegateType; this.method_group = mg; - loc = l; + this.loc = loc; + } + + // + // Returns true when type is MVAR or has MVAR reference + // + public static bool ContainsMethodTypeParameter (TypeSpec type) + { + var tps = type as TypeParameterSpec; + if (tps != null) + return tps.IsMethodOwned; + + var ec = type as ElementTypeSpec; + if (ec != null) + return ContainsMethodTypeParameter (ec.Element); + + foreach (var t in type.TypeArguments) { + if (ContainsMethodTypeParameter (t)) { + return true; + } + } + + if (type.IsNested) + return ContainsMethodTypeParameter (type.DeclaringType); + + return false; + } + + bool HasMvar () + { + if (ContainsMethodTypeParameter (type)) + return false; + + var best = method_group.BestCandidate; + if (ContainsMethodTypeParameter (best.DeclaringType)) + return false; + + if (best.TypeArguments != null) { + foreach (var ta in best.TypeArguments) { + if (ContainsMethodTypeParameter (ta)) + return false; + } + } + + return true; } - static public Expression Create (ResolveContext ec, MethodGroupExpr mge, - TypeSpec target_type, Location loc) + protected override Expression DoResolve (ResolveContext ec) { - ImplicitDelegateCreation d = new ImplicitDelegateCreation (target_type, mge, loc); - return d.DoResolve (ec); + var expr = base.DoResolve (ec); + if (expr == null) + return ErrorExpression.Instance; + + if (ec.IsInProbingMode) + return expr; + + // + // Cache any static delegate creation + // + if (method_group.InstanceExpression != null) + return expr; + + // + // Cannot easily cache types with MVAR + // + if (!HasMvar ()) + return expr; + + // + // Create type level cache for a delegate instance + // + var parent = ec.CurrentMemberDefinition.Parent.PartialContainer; + int id = parent.MethodGroupsCounter++; + + mg_cache = new Field (parent, new TypeExpression (type, loc), + Modifiers.STATIC | Modifiers.PRIVATE | Modifiers.COMPILER_GENERATED, + new MemberName (CompilerGeneratedContainer.MakeName (null, "f", "mg$cache", id), loc), null); + mg_cache.Define (); + parent.AddField (mg_cache); + + return expr; + } + + public override void Emit (EmitContext ec) + { + Label l_initialized = ec.DefineLabel (); + + if (mg_cache != null) { + ec.Emit (OpCodes.Ldsfld, mg_cache.Spec); + ec.Emit (OpCodes.Brtrue_S, l_initialized); + } + + base.Emit (ec); + + if (mg_cache != null) { + ec.Emit (OpCodes.Stsfld, mg_cache.Spec); + ec.MarkLabel (l_initialized); + ec.Emit (OpCodes.Ldsfld, mg_cache.Spec); + } } } @@ -741,6 +853,13 @@ namespace Mono.CSharp { return CreateExpressionFactoryCall (ec, "Invoke", args); } + public override void FlowAnalysis (FlowAnalysisContext fc) + { + InstanceExpr.FlowAnalysis (fc); + if (arguments != null) + arguments.FlowAnalysis (fc); + } + protected override Expression DoResolve (ResolveContext ec) { TypeSpec del_type = InstanceExpr.Type; @@ -770,7 +889,7 @@ namespace Mono.CSharp { // var call = new CallEmitter (); call.InstanceExpression = InstanceExpr; - call.EmitPredefined (ec, method, arguments); + call.EmitPredefined (ec, method, arguments, loc); } public override void EmitStatement (EmitContext ec) diff --git a/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/doc.cs b/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/doc.cs index 6cc53d505..35fe58529 100644 --- a/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/doc.cs +++ b/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/doc.cs @@ -147,16 +147,13 @@ namespace Mono.CSharp } // FIXME: it could be done with XmlReader - var ds_target = mc as TypeContainer; - if (ds_target == null) - ds_target = mc.Parent; foreach (XmlElement see in n.SelectNodes (".//see")) - HandleSee (mc, ds_target, see); + HandleSee (mc, see); foreach (XmlElement seealso in n.SelectNodes (".//seealso")) - HandleSeeAlso (mc, ds_target, seealso); + HandleSeeAlso (mc, seealso); foreach (XmlElement see in n.SelectNodes (".//exception")) - HandleException (mc, ds_target, see); + HandleException (mc, see); foreach (XmlElement node in n.SelectNodes (".//typeparam")) HandleTypeParam (mc, node); foreach (XmlElement node in n.SelectNodes (".//typeparamref")) @@ -175,28 +172,31 @@ namespace Mono.CSharp bool keep_include_node = false; string file = el.GetAttribute ("file"); string path = el.GetAttribute ("path"); + if (file == "") { Report.Warning (1590, 1, mc.Location, "Invalid XML `include' element. Missing `file' attribute"); el.ParentNode.InsertBefore (el.OwnerDocument.CreateComment (" Include tag is invalid "), el); keep_include_node = true; - } - else if (path.Length == 0) { + } else if (path.Length == 0) { Report.Warning (1590, 1, mc.Location, "Invalid XML `include' element. Missing `path' attribute"); el.ParentNode.InsertBefore (el.OwnerDocument.CreateComment (" Include tag is invalid "), el); keep_include_node = true; - } - else { + } else { XmlDocument doc; - if (!StoredDocuments.TryGetValue (file, out doc)) { + Exception exception = null; + var full_path = Path.Combine (Path.GetDirectoryName (mc.Location.NameFullPath), file); + + if (!StoredDocuments.TryGetValue (full_path, out doc)) { try { doc = new XmlDocument (); - doc.Load (file); - StoredDocuments.Add (file, doc); - } catch (Exception) { + doc.Load (full_path); + StoredDocuments.Add (full_path, doc); + } catch (Exception e) { + exception = e; el.ParentNode.InsertBefore (el.OwnerDocument.CreateComment (String.Format (" Badly formed XML in at comment file `{0}': cannot be included ", file)), el); - Report.Warning (1592, 1, mc.Location, "Badly formed XML in included comments file -- `{0}'", file); } } + if (doc != null) { try { XmlNodeList nl = doc.SelectNodes (path); @@ -208,36 +208,42 @@ namespace Mono.CSharp foreach (XmlNode n in nl) el.ParentNode.InsertBefore (el.OwnerDocument.ImportNode (n, true), el); } catch (Exception ex) { + exception = ex; el.ParentNode.InsertBefore (el.OwnerDocument.CreateComment (" Failed to insert some or all of included XML "), el); - Report.Warning (1589, 1, mc.Location, "Unable to include XML fragment `{0}' of file `{1}' ({2})", path, file, ex.Message); } } + + if (exception != null) { + Report.Warning (1589, 1, mc.Location, "Unable to include XML fragment `{0}' of file `{1}'. {2}", + path, file, exception.Message); + } } + return keep_include_node; } // // Handles elements. // - void HandleSee (MemberCore mc, TypeContainer ds, XmlElement see) + void HandleSee (MemberCore mc, XmlElement see) { - HandleXrefCommon (mc, ds, see); + HandleXrefCommon (mc, see); } // // Handles elements. // - void HandleSeeAlso (MemberCore mc, TypeContainer ds, XmlElement seealso) + void HandleSeeAlso (MemberCore mc, XmlElement seealso) { - HandleXrefCommon (mc, ds, seealso); + HandleXrefCommon (mc, seealso); } // // Handles elements. // - void HandleException (MemberCore mc, TypeContainer ds, XmlElement seealso) + void HandleException (MemberCore mc, XmlElement seealso) { - HandleXrefCommon (mc, ds, seealso); + HandleXrefCommon (mc, seealso); } // @@ -291,13 +297,13 @@ namespace Mono.CSharp return context.LookupNamespaceOrType (mn.Name, mn.Arity, LookupMode.Probing, Location.Null); var left = ResolveMemberName (context, mn.Left); - var ns = left as Namespace; + var ns = left as NamespaceExpression; if (ns != null) return ns.LookupTypeOrNamespace (context, mn.Name, mn.Arity, LookupMode.Probing, Location.Null); TypeExpr texpr = left as TypeExpr; if (texpr != null) { - var found = MemberCache.FindNestedType (texpr.Type, ParsedName.Name, ParsedName.Arity); + var found = MemberCache.FindNestedType (texpr.Type, mn.Name, mn.Arity); if (found != null) return new TypeExpression (found, Location.Null); @@ -310,7 +316,7 @@ namespace Mono.CSharp // // Processes "see" or "seealso" elements from cref attribute. // - void HandleXrefCommon (MemberCore mc, TypeContainer ds, XmlElement xref) + void HandleXrefCommon (MemberCore mc, XmlElement xref) { string cref = xref.GetAttribute ("cref"); // when, XmlReader, "if (cref == null)" @@ -331,7 +337,7 @@ namespace Mono.CSharp var report = new Report (doc_module.Compiler, new NullReportPrinter ()); if (session == null) - session = new ParserSession () { + session = new ParserSession { UseJayGlobalArrays = true }; @@ -377,7 +383,7 @@ namespace Mono.CSharp } else if (ParsedName.Left != null) { fne = ResolveMemberName (mc, ParsedName.Left); if (fne != null) { - var ns = fne as Namespace; + var ns = fne as NamespaceExpression; if (ns != null) { fne = ns.LookupTypeOrNamespace (mc, ParsedName.Name, ParsedName.Arity, LookupMode.Probing, Location.Null); if (fne != null) { diff --git a/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/driver.cs b/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/driver.cs index 5f2ac1e74..6ef6859e8 100644 --- a/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/driver.cs +++ b/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/driver.cs @@ -57,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, session); + Tokenizer lexer = new Tokenizer (reader, file, session, ctx.Report); int token, tokens = 0, errors = 0; while ((token = lexer.token ()) != Token.EOF){ @@ -78,9 +78,9 @@ namespace Mono.CSharp Location.Initialize (sources); - var session = new ParserSession () { + var session = new ParserSession { UseJayGlobalArrays = true, - LocatedTokens = new Tokenizer.LocatedToken[15000] + LocatedTokens = new LocatedToken[15000] }; for (int i = 0; i < sources.Count; ++i) { @@ -173,7 +173,7 @@ namespace Mono.CSharp parser.parse (); return parser; } - + public static int Main (string[] args) { Location.InEmacs = Environment.GetEnvironmentVariable ("EMACS") == "t"; @@ -332,6 +332,7 @@ namespace Mono.CSharp tr.Start (TimeReporter.TimerType.CreateTypeTotal); module.CreateContainer (); importer.AddCompiledAssembly (assembly); + references_loader.CompiledAssembly = assembly; tr.Stop (TimeReporter.TimerType.CreateTypeTotal); references_loader.LoadReferences (module); @@ -419,7 +420,7 @@ namespace Mono.CSharp public ModuleContainer ModuleCompiled { get; set; } public LocationsBag LocationsBag { get; set; } public SpecialsBag SpecialsBag { get; set; } - public IEnumerable Conditionals { get; set; } + public IDictionary Conditionals { get; set; } public object LastYYValue { get; set; } } diff --git a/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/dynamic.cs b/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/dynamic.cs index b9d6967dc..939984e5c 100644 --- a/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/dynamic.cs +++ b/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/dynamic.cs @@ -13,7 +13,7 @@ using System; using System.Linq; using SLE = System.Linq.Expressions; -#if NET_4_0 || MONODROID +#if NET_4_0 || MOBILE_DYNAMIC using System.Dynamic; #endif @@ -63,7 +63,7 @@ namespace Mono.CSharp // public class RuntimeValueExpression : Expression, IDynamicAssign, IMemoryLocation { -#if !NET_4_0 && !MONODROID +#if !NET_4_0 && !MOBILE_DYNAMIC public class DynamicMetaObject { public TypeSpec RuntimeType; @@ -146,7 +146,7 @@ namespace Mono.CSharp return base.MakeExpression (ctx); #else -#if NET_4_0 || MONODROID +#if NET_4_0 || MOBILE_DYNAMIC if (type.IsStruct && !obj.Expression.Type.IsValueType) return SLE.Expression.Unbox (obj.Expression, type.GetMetaInfo ()); @@ -181,7 +181,7 @@ namespace Mono.CSharp return this; } -#if NET_4_0 || MONODROID +#if NET_4_0 || MOBILE_DYNAMIC public override SLE.Expression MakeExpression (BuilderContext ctx) { #if STATIC @@ -224,8 +224,8 @@ namespace Mono.CSharp // protected class BinderFlags : EnumConstant { - DynamicExpressionStatement statement; - CSharpBinderFlags flags; + readonly DynamicExpressionStatement statement; + readonly CSharpBinderFlags flags; public BinderFlags (CSharpBinderFlags flags, DynamicExpressionStatement statement) : base (statement.loc) @@ -391,7 +391,7 @@ namespace Mono.CSharp if (!has_ref_out_argument) { string d_name = isStatement ? "Action" : "Func"; - TypeExpr te = null; + TypeSpec te = null; Namespace type_ns = module.GlobalRootNamespace.GetNamespace ("System", true); if (type_ns != null) { te = type_ns.LookupType (module, d_name, dyn_args_count + default_args, LookupMode.Normal, loc); @@ -412,9 +412,9 @@ namespace Mono.CSharp targs[targs.Length - 1] = new TypeExpression (t, loc); } - del_type = new GenericTypeExpr (te.Type, new TypeArguments (targs), loc); + del_type = new GenericTypeExpr (te, new TypeArguments (targs), loc); if (targs_for_instance != null) - del_type_instance_access = new GenericTypeExpr (te.Type, new TypeArguments (targs_for_instance), loc); + del_type_instance_access = new GenericTypeExpr (te, new TypeArguments (targs_for_instance), loc); else del_type_instance_access = del_type; } @@ -447,8 +447,17 @@ namespace Mono.CSharp d.CreateContainer (); d.DefineContainer (); d.Define (); + d.PrepareEmit (); site.AddTypeContainer (d); + + // + // Add new container to inflated site container when the + // member cache already exists + // + if (site.CurrentType is InflatedTypeSpec && index > 0) + site.CurrentType.MemberCache.AddMember (d.CurrentType); + del_type = new TypeExpression (d.CurrentType, loc); if (targs_for_instance != null) { del_type_instance_access = null; @@ -531,6 +540,11 @@ namespace Mono.CSharp } } + public override void FlowAnalysis (FlowAnalysisContext fc) + { + arguments.FlowAnalysis (fc); + } + public static MemberAccess GetBinderNamespace (Location loc) { return new MemberAccess (new MemberAccess ( @@ -611,6 +625,11 @@ namespace Mono.CSharp stmt.Emit (ec); } } + + public override void FlowAnalysis (FlowAnalysisContext fc) + { + invoke.FlowAnalysis (fc); + } } class DynamicConversion : DynamicExpressionStatement, IDynamicBinder diff --git a/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/ecore.cs b/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/ecore.cs index cf1de9483..593ab6bcb 100644 --- a/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/ecore.cs +++ b/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/ecore.cs @@ -3,11 +3,11 @@ // // Author: // Miguel de Icaza (miguel@ximian.com) -// Marek Safar (marek.safar@seznam.cz) +// Marek Safar (marek.safar@gmail.com) // // Copyright 2001, 2002, 2003 Ximian, Inc. // Copyright 2003-2008 Novell, Inc. -// Copyright 2011 Xamarin Inc. +// Copyright 2011-2012 Xamarin Inc. // // @@ -152,6 +152,35 @@ namespace Mono.CSharp { } } + // + // Used to workaround parser limitation where we cannot get + // start of statement expression location + // + public virtual Location StartLocation { + get { + return loc; + } + } + + public virtual MethodGroupExpr CanReduceLambda (AnonymousMethodBody body) + { + // + // Return method-group expression when the expression can be used as + // lambda replacement. A good example is array sorting where instead of + // code like + // + // Array.Sort (s, (a, b) => String.Compare (a, b)); + // + // we can use method group directly + // + // Array.Sort (s, String.Compare); + // + // Correct overload will be used because we do the reduction after + // best candidate was found. + // + return null; + } + // // Returns true when the expression during Emit phase breaks stack // by using await expression @@ -222,17 +251,22 @@ namespace Mono.CSharp { public void Error_ConstantCanBeInitializedWithNullOnly (ResolveContext rc, TypeSpec type, Location loc, string name) { rc.Report.Error (134, loc, "A constant `{0}' of reference type `{1}' can only be initialized with null", - name, TypeManager.CSharpName (type)); + name, type.GetSignatureForError ()); } - public static void Error_InvalidExpressionStatement (Report Report, Location loc) + protected virtual void Error_InvalidExpressionStatement (Report report, Location loc) { - Report.Error (201, loc, "Only assignment, call, increment, decrement, await, and new object expressions can be used as a statement"); + report.Error (201, loc, "Only assignment, call, increment, decrement, await, and new object expressions can be used as a statement"); } - public void Error_InvalidExpressionStatement (BlockContext ec) + public void Error_InvalidExpressionStatement (BlockContext bc) { - Error_InvalidExpressionStatement (ec.Report, loc); + Error_InvalidExpressionStatement (bc.Report, loc); + } + + public void Error_InvalidExpressionStatement (Report report) + { + Error_InvalidExpressionStatement (report, loc); } public static void Error_VoidInvalidInTheContext (Location loc, Report Report) @@ -248,7 +282,10 @@ namespace Mono.CSharp { protected void Error_ValueCannotBeConvertedCore (ResolveContext ec, Location loc, TypeSpec target, bool expl) { // The error was already reported as CS1660 - if (type == InternalType.AnonymousMethod || type == InternalType.ErrorType) + if (type == InternalType.AnonymousMethod) + return; + + if (type == InternalType.ErrorType || target == InternalType.ErrorType) return; string from_type = type.GetSignatureForError (); @@ -278,7 +315,7 @@ namespace Mono.CSharp { } } - public void Error_TypeArgumentsCannotBeUsed (IMemberContext context, MemberSpec member, int arity, Location loc) + public void Error_TypeArgumentsCannotBeUsed (IMemberContext context, MemberSpec member, Location loc) { // Better message for possible generic expressions if (member != null && (member.Kind & MemberKind.GenericMask) != 0) { @@ -302,7 +339,7 @@ namespace Mono.CSharp { } } - public void Error_TypeArgumentsCannotBeUsed (IMemberContext context, string exprType, string name, Location loc) + public static void Error_TypeArgumentsCannotBeUsed (IMemberContext context, string exprType, string name, Location loc) { context.Module.Compiler.Report.Error (307, loc, "The {0} `{1}' cannot be used with type arguments", exprType, name); @@ -317,20 +354,15 @@ namespace Mono.CSharp { { ec.Report.SymbolRelatedToPreviousError (type); ec.Report.Error (117, loc, "`{0}' does not contain a definition for `{1}'", - TypeManager.CSharpName (type), name); + type.GetSignatureForError (), name); } public virtual void Error_ValueAssignment (ResolveContext rc, Expression rhs) { if (rhs == EmptyExpression.LValueMemberAccess || rhs == EmptyExpression.LValueMemberOutAccess) { - rc.Report.SymbolRelatedToPreviousError (type); - if (rc.CurrentInitializerVariable != null) { - rc.Report.Error (1918, loc, "Members of value type `{0}' cannot be assigned using a property `{1}' object initializer", - type.GetSignatureForError (), GetSignatureForError ()); - } else { - rc.Report.Error (1612, loc, "Cannot modify a value type return value of `{0}'. Consider storing the value in a temporary variable", - GetSignatureForError ()); - } + // Already reported as CS1612 + } else if (rhs == EmptyExpression.OutAccess) { + rc.Report.Error (1510, loc, "A ref or out argument must be an assignable variable"); } else { rc.Report.Error (131, loc, "The left-hand side of an assignment must be a variable, a property or an indexer"); } @@ -341,6 +373,11 @@ namespace Mono.CSharp { rc.Report.Error (242, loc, "The operation in question is undefined on void pointers"); } + public static void Warning_UnreachableExpression (ResolveContext rc, Location loc) + { + rc.Report.Warning (429, 4, loc, "Unreachable expression code detected"); + } + public ResolveFlags ExprClassToResolveFlags { get { switch (eclass) { @@ -367,6 +404,27 @@ namespace Mono.CSharp { } } + // + // Implements identical simple name and type-name resolution + // + public Expression ProbeIdenticalTypeName (ResolveContext rc, Expression left, SimpleName name) + { + var t = left.Type; + if (t.Kind == MemberKind.InternalCompilerType || t is ElementTypeSpec || t.Arity > 0) + return left; + + // In a member access of the form E.I, if E is a single identifier, and if the meaning of E as a simple-name is + // a constant, field, property, local variable, or parameter with the same type as the meaning of E as a type-name + + if (left is MemberExpr || left is VariableReference) { + var identical_type = rc.LookupNamespaceOrType (name.Name, 0, LookupMode.Probing, loc) as TypeExpr; + if (identical_type != null && identical_type.Type == left.Type) + return identical_type; + } + + return left; + } + public virtual string GetSignatureForError () { return type.GetDefinition ().GetSignatureForError (); @@ -382,8 +440,14 @@ namespace Mono.CSharp { /// public Expression Resolve (ResolveContext ec, ResolveFlags flags) { - if (eclass != ExprClass.Unresolved) + if (eclass != ExprClass.Unresolved) { + if ((flags & ExprClassToResolveFlags) == 0) { + Error_UnexpectedKind (ec, flags, loc); + return null; + } + return this; + } Expression e; try { @@ -402,7 +466,8 @@ namespace Mono.CSharp { return e; } catch (Exception ex) { - if (loc.IsNull || ec.Module.Compiler.Settings.DebugFlags > 0 || ex is CompletionResult || ec.Report.IsDisabled || ex is FatalException) + if (loc.IsNull || ec.Module.Compiler.Settings.BreakOnInternalError || ex is CompletionResult || ec.Report.IsDisabled || ex is FatalException || + ec.Report.Printer is NullReportPrinter) throw; ec.Report.Error (584, loc, "Internal compiler error: {0}", ex.Message); @@ -444,10 +509,7 @@ namespace Mono.CSharp { if (e == null) { if (errors == ec.Report.Errors) { - if (out_access) - ec.Report.Error (1510, loc, "A ref or out argument must be an assignable variable"); - else - Error_ValueAssignment (ec, right_side); + Error_ValueAssignment (ec, right_side); } return null; } @@ -461,10 +523,33 @@ namespace Mono.CSharp { return e; } - public virtual void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType) + public Constant ResolveLabelConstant (ResolveContext rc) + { + var expr = Resolve (rc); + if (expr == null) + return null; + + Constant c = expr as Constant; + if (c == null) { + if (expr.type != InternalType.ErrorType) + rc.Report.Error (150, expr.StartLocation, "A constant value is expected"); + + return null; + } + + return c; + } + + public virtual void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType, TypeSpec parameterType) { - rc.Module.Compiler.Report.Error (182, loc, - "An attribute argument must be a constant expression, typeof expression or array creation expression"); + if (Attribute.IsValidArgumentType (parameterType)) { + rc.Module.Compiler.Report.Error (182, loc, + "An attribute argument must be a constant expression, typeof expression or array creation expression"); + } else { + rc.Module.Compiler.Report.Error (181, loc, + "Attribute constructor parameter has type `{0}', which is not a valid attribute parameter type", + targetType.GetSignatureForError ()); + } } /// @@ -633,13 +718,20 @@ namespace Mono.CSharp { { var ctors = MemberCache.FindMembers (type, Constructor.ConstructorName, true); if (ctors == null) { - rc.Report.SymbolRelatedToPreviousError (type); - if (type.IsStruct) { + switch (type.Kind) { + case MemberKind.Struct: + rc.Report.SymbolRelatedToPreviousError (type); // Report meaningful error for struct as they always have default ctor in C# context OverloadResolver.Error_ConstructorMismatch (rc, type, args == null ? 0 : args.Count, loc); - } else { + break; + case MemberKind.MissingType: + case MemberKind.InternalCompilerType: + break; + default: + rc.Report.SymbolRelatedToPreviousError (type); rc.Report.Error (143, loc, "The class `{0}' has no constructors defined", type.GetSignatureForError ()); + break; } return null; @@ -682,7 +774,7 @@ namespace Mono.CSharp { if ((member.Modifiers & Modifiers.OVERRIDE) != 0 && member.Kind != MemberKind.Event) continue; - if ((member.Modifiers & Modifiers.BACKING_FIELD) != 0) + if ((member.Modifiers & Modifiers.BACKING_FIELD) != 0 || member.Kind == MemberKind.Operator) continue; if ((arity > 0 || (restrictions & MemberLookupRestrictions.ExactArity) != 0) && member.Arity != arity) @@ -711,8 +803,18 @@ namespace Mono.CSharp { } if ((restrictions & MemberLookupRestrictions.InvocableOnly) != 0) { - if (member is MethodSpec) + if (member is MethodSpec) { + // + // Interface members that are hidden by class members are removed from the set. This + // step only has an effect if T is a type parameter and T has both an effective base + // class other than object and a non-empty effective interface set + // + var tps = queried_type as TypeParameterSpec; + if (tps != null && tps.HasTypeConstraint) + members = RemoveHiddenTypeParameterMethods (members); + return new MethodGroupExpr (members, queried_type, loc); + } if (!Invocation.IsMemberInvocable (member)) continue; @@ -721,6 +823,23 @@ namespace Mono.CSharp { if (non_method == null || member is MethodSpec || non_method.IsNotCSharpCompatible) { non_method = member; } else if (!errorMode && !member.IsNotCSharpCompatible) { + // + // Interface members that are hidden by class members are removed from the set when T is a type parameter and + // T has both an effective base class other than object and a non-empty effective interface set. + // + // The spec has more complex rules but we simply remove all members declared in an interface declaration. + // + var tps = queried_type as TypeParameterSpec; + if (tps != null && tps.HasTypeConstraint) { + if (non_method.DeclaringType.IsClass && member.DeclaringType.IsInterface) + continue; + + if (non_method.DeclaringType.IsInterface && member.DeclaringType.IsInterface) { + non_method = member; + continue; + } + } + ambig_non_method = member; } } @@ -750,6 +869,54 @@ namespace Mono.CSharp { return null; } + static IList RemoveHiddenTypeParameterMethods (IList members) + { + if (members.Count < 2) + return members; + + // + // If M is a method, then all non-method members declared in an interface declaration + // are removed from the set, and all methods with the same signature as M declared in + // an interface declaration are removed from the set + // + + bool copied = false; + for (int i = 0; i < members.Count; ++i) { + var method = members[i] as MethodSpec; + if (method == null) { + if (!copied) { + copied = true; + members = new List (members); + } + + members.RemoveAt (i--); + continue; + } + + if (!method.DeclaringType.IsInterface) + continue; + + for (int ii = 0; ii < members.Count; ++ii) { + var candidate = members[ii] as MethodSpec; + if (candidate == null || !candidate.DeclaringType.IsClass) + continue; + + if (!TypeSpecComparer.Override.IsEqual (candidate.Parameters, method.Parameters)) + continue; + + if (!copied) { + copied = true; + members = new List (members); + } + + members.RemoveAt (i--); + break; + } + } + + return members; + } + protected virtual void Error_NegativeArrayIndex (ResolveContext ec, Location loc) { throw new NotImplementedException (); @@ -769,6 +936,10 @@ namespace Mono.CSharp { ec.Report.Error (1944, loc, "An expression tree cannot contain an unsafe pointer operation"); } + public virtual void FlowAnalysis (FlowAnalysisContext fc) + { + } + /// /// Returns an expression that can be used to invoke operator true /// on the expression if it exists. @@ -840,7 +1011,7 @@ namespace Mono.CSharp { /// /// Reports that we were expecting `expr' to be of class `expected' /// - public void Error_UnexpectedKind (IMemberContext ctx, Expression memberExpr, string expected, string was, Location loc) + public static void Error_UnexpectedKind (IMemberContext ctx, Expression memberExpr, string expected, string was, Location loc) { var name = memberExpr.GetSignatureForError (); @@ -893,7 +1064,7 @@ namespace Mono.CSharp { // // Converts `source' to an int, uint, long or ulong. // - protected Expression ConvertExpressionToArrayIndex (ResolveContext ec, Expression source) + protected Expression ConvertExpressionToArrayIndex (ResolveContext ec, Expression source, bool pointerArray = false) { var btypes = ec.BuiltinTypes; @@ -920,6 +1091,9 @@ namespace Mono.CSharp { } } + if (pointerArray) + return converted; + // // Only positive constants are allowed at compile time // @@ -1019,7 +1193,11 @@ namespace Mono.CSharp { /// being that they would support an extra Emition interface that /// does not leave a result on the stack. /// - public abstract class ExpressionStatement : Expression { + public abstract class ExpressionStatement : Expression + { + public virtual void MarkReachable (Reachability rc) + { + } public ExpressionStatement ResolveStatement (BlockContext ec) { @@ -1028,18 +1206,60 @@ namespace Mono.CSharp { return null; ExpressionStatement es = e as ExpressionStatement; - if (es == null) + if (es == null || e is AnonymousMethodBody) Error_InvalidExpressionStatement (ec); - if (ec.CurrentAnonymousMethod is AsyncInitializer && !(e is Assign) && - (e.Type.IsGenericTask || e.Type == ec.Module.PredefinedTypes.Task.TypeSpec)) { - ec.Report.Warning (4014, 1, e.Location, - "The statement is not awaited and execution of current method continues before the call is completed. Consider using `await' operator"); + // + // This is quite expensive warning, try to limit the damage + // + if (MemberAccess.IsValidDotExpression (e.Type) && !(e is Assign || e is Await)) { + WarningAsyncWithoutWait (ec, e); } return es; } + static void WarningAsyncWithoutWait (BlockContext bc, Expression e) + { + if (bc.CurrentAnonymousMethod is AsyncInitializer) { + var awaiter = new AwaitStatement.AwaitableMemberAccess (e) { + ProbingMode = true + }; + + // + // Need to do full resolve because GetAwaiter can be extension method + // available only in this context + // + var mg = awaiter.Resolve (bc) as MethodGroupExpr; + if (mg == null) + return; + + var arguments = new Arguments (0); + mg = mg.OverloadResolve (bc, ref arguments, null, OverloadResolver.Restrictions.ProbingOnly); + if (mg == null) + return; + + // + // Use same check rules as for real await + // + var awaiter_definition = bc.Module.GetAwaiter (mg.BestCandidateReturnType); + if (!awaiter_definition.IsValidPattern || !awaiter_definition.INotifyCompletion) + return; + + bc.Report.Warning (4014, 1, e.Location, + "The statement is not awaited and execution of current method continues before the call is completed. Consider using `await' operator"); + return; + } + + var inv = e as Invocation; + if (inv != null && inv.MethodGroup != null && inv.MethodGroup.BestCandidate.IsAsync) { + // The warning won't be reported for imported methods to maintain warning compatiblity with csc + bc.Report.Warning (4014, 1, e.Location, + "The statement is not awaited and execution of current method continues before the call is completed. Consider using `await' operator or calling `Wait' method"); + return; + } + } + /// /// Requests the expression to be emitted in a `statement' /// context. This means that no new value is left on the @@ -1114,6 +1334,11 @@ namespace Mono.CSharp { child.Emit (ec); } + public override void FlowAnalysis (FlowAnalysisContext fc) + { + child.FlowAnalysis (fc); + } + public override SLE.Expression MakeExpression (BuilderContext ctx) { #if STATIC @@ -1144,8 +1369,20 @@ namespace Mono.CSharp { public static Expression Create (Expression child, TypeSpec type) { Constant c = child as Constant; - if (c != null) - return new EmptyConstantCast (c, type); + if (c != null) { + var enum_constant = c as EnumConstant; + if (enum_constant != null) + c = enum_constant.Child; + + if (!(c is ReducedExpression.ReducedConstantExpression)) { + if (c.Type == type) + return c; + + var res = c.ConvertImplicitly (type); + if (res != null) + return res; + } + } EmptyCast e = child as EmptyCast; if (e != null) @@ -1351,9 +1588,9 @@ namespace Mono.CSharp { Child.Emit (ec); } - public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType) + public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType, TypeSpec parameterType) { - Child.EncodeAttributeValue (rc, enc, Child.Type); + Child.EncodeAttributeValue (rc, enc, Child.Type, parameterType); } public override void EmitBranchable (EmitContext ec, Label label, bool on_true) @@ -1368,7 +1605,7 @@ namespace Mono.CSharp { public override string GetSignatureForError() { - return TypeManager.CSharpName (Type); + return Type.GetSignatureForError (); } public override object GetValue () @@ -1427,7 +1664,7 @@ namespace Mono.CSharp { } } - public override Constant ConvertExplicitly(bool in_checked_context, TypeSpec target_type) + public override Constant ConvertExplicitly (bool in_checked_context, TypeSpec target_type) { if (Child.Type == target_type) return Child; @@ -1471,16 +1708,16 @@ namespace Mono.CSharp { return this; } - public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType) + public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType, TypeSpec parameterType) { // Only boxing to object type is supported if (targetType.BuiltinType != BuiltinTypeSpec.Type.Object) { - base.EncodeAttributeValue (rc, enc, targetType); + base.EncodeAttributeValue (rc, enc, targetType, parameterType); return; } enc.Encode (child.Type); - child.EncodeAttributeValue (rc, enc, child.Type); + child.EncodeAttributeValue (rc, enc, child.Type, parameterType); } public override void Emit (EmitContext ec) @@ -1571,7 +1808,11 @@ namespace Mono.CSharp { public override void Emit (EmitContext ec) { base.Emit (ec); + Emit (ec, mode); + } + public static void Emit (EmitContext ec, Mode mode) + { if (ec.HasSet (EmitContext.Options.CheckedScope)) { switch (mode){ case Mode.I1_U1: ec.Emit (OpCodes.Conv_Ovf_U1); break; @@ -1840,7 +2081,7 @@ namespace Mono.CSharp { // public class ReducedExpression : Expression { - sealed class ReducedConstantExpression : EmptyConstantCast + public sealed class ReducedConstantExpression : EmptyConstantCast { readonly Expression orig_expr; @@ -1850,6 +2091,12 @@ namespace Mono.CSharp { this.orig_expr = orig_expr; } + public Expression OriginalExpression { + get { + return orig_expr; + } + } + public override Constant ConvertImplicitly (TypeSpec target_type) { Constant c = base.ConvertImplicitly (target_type); @@ -1872,15 +2119,15 @@ namespace Mono.CSharp { return c; } - public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType) + public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType, TypeSpec parameterType) { // // LAMESPEC: Reduced conditional expression is allowed as an attribute argument // if (orig_expr is Conditional) - child.EncodeAttributeValue (rc, enc, targetType); + child.EncodeAttributeValue (rc, enc, targetType,parameterType); else - base.EncodeAttributeValue (rc, enc, targetType); + base.EncodeAttributeValue (rc, enc, targetType, parameterType); } } @@ -1923,6 +2170,11 @@ namespace Mono.CSharp { { stm.EmitStatement (ec); } + + public override void FlowAnalysis (FlowAnalysisContext fc) + { + stm.FlowAnalysis (fc); + } } readonly Expression expr, orig_expr; @@ -2026,6 +2278,11 @@ namespace Mono.CSharp { expr.EmitBranchable (ec, target, on_true); } + public override void FlowAnalysis (FlowAnalysisContext fc) + { + expr.FlowAnalysis (fc); + } + public override SLE.Expression MakeExpression (BuilderContext ctx) { return orig_expr.MakeExpression (ctx); @@ -2062,11 +2319,11 @@ namespace Mono.CSharp { protected override Expression DoResolve (ResolveContext rc) { expr = expr.Resolve (rc); - if (expr != null) { - type = expr.Type; - eclass = expr.eclass; - } + if (expr == null) + return null; + type = expr.Type; + eclass = expr.eclass; return this; } @@ -2121,7 +2378,38 @@ namespace Mono.CSharp { { throw new InternalErrorException ("Missing Resolve call"); } + } + public class UnreachableExpression : Expression + { + public UnreachableExpression (Expression expr) + { + this.loc = expr.Location; + } + + public override Expression CreateExpressionTree (ResolveContext ec) + { + // TODO: is it ok + throw new NotImplementedException (); + } + + protected override Expression DoResolve (ResolveContext rc) + { + throw new NotSupportedException (); + } + + public override void FlowAnalysis (FlowAnalysisContext fc) + { + fc.Report.Warning (429, 4, loc, "Unreachable expression code detected"); + } + + public override void Emit (EmitContext ec) + { + } + + public override void EmitBranchable (EmitContext ec, Label target, bool on_true) + { + } } // @@ -2252,19 +2540,12 @@ namespace Mono.CSharp { protected override Expression DoResolve (ResolveContext rc) { - var e = SimpleNameResolve (rc, null, false); - - var fe = e as FieldExpr; - if (fe != null) { - fe.VerifyAssignedStructField (rc, null); - } - - return e; + return SimpleNameResolve (rc, null); } public override Expression DoResolveLValue (ResolveContext ec, Expression right_side) { - return SimpleNameResolve (ec, right_side, false); + return SimpleNameResolve (ec, right_side); } protected virtual void Error_TypeOrNamespaceNotFound (IMemberContext ctx) @@ -2272,7 +2553,7 @@ namespace Mono.CSharp { if (ctx.CurrentType != null) { var member = MemberLookup (ctx, false, ctx.CurrentType, Name, 0, MemberLookupRestrictions.ExactArity, loc) as MemberExpr; if (member != null) { - member.Error_UnexpectedKind (ctx, member, "type", member.KindName, loc); + Error_UnexpectedKind (ctx, member, "type", member.KindName, loc); return; } } @@ -2288,16 +2569,22 @@ namespace Mono.CSharp { retval = ctx.LookupNamespaceOrType (Name, -System.Math.Max (1, Arity), LookupMode.Probing, loc); if (retval != null) { - Error_TypeArgumentsCannotBeUsed (ctx, retval.Type, Arity, loc); + Error_TypeArgumentsCannotBeUsed (ctx, retval.Type, loc); return; } 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); + if (ctx is UsingAliasNamespace.AliasContext) { + report.Error (246, loc, + "The type or namespace name `{1}' could not be found. Consider using fully qualified name `{0}.{1}'", + ns_candidates[0], Name); + } else { + 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?", @@ -2305,15 +2592,15 @@ namespace Mono.CSharp { } } - public override FullNamedExpression ResolveAsTypeOrNamespace (IMemberContext ec) + public override FullNamedExpression ResolveAsTypeOrNamespace (IMemberContext mc) { - FullNamedExpression fne = ec.LookupNamespaceOrType (Name, Arity, LookupMode.Normal, loc); + FullNamedExpression fne = mc.LookupNamespaceOrType (Name, Arity, LookupMode.Normal, loc); if (fne != null) { if (fne.Type != null && Arity > 0) { if (HasTypeArguments) { GenericTypeExpr ct = new GenericTypeExpr (fne.Type, targs, loc); - if (ct.ResolveAsType (ec) == null) + if (ct.ResolveAsType (mc) == null) return null; return ct; @@ -2325,25 +2612,25 @@ namespace Mono.CSharp { // // dynamic namespace is ignored when dynamic is allowed (does not apply to types) // - if (!(fne is Namespace)) + if (!(fne is NamespaceExpression)) return fne; } - if (Arity == 0 && Name == "dynamic" && ec.Module.Compiler.Settings.Version > LanguageVersion.V_3) { - if (!ec.Module.PredefinedAttributes.Dynamic.IsDefined) { - ec.Module.Compiler.Report.Error (1980, Location, + if (Arity == 0 && Name == "dynamic" && mc.Module.Compiler.Settings.Version > LanguageVersion.V_3) { + if (!mc.Module.PredefinedAttributes.Dynamic.IsDefined) { + mc.Module.Compiler.Report.Error (1980, Location, "Dynamic keyword requires `{0}' to be defined. Are you missing System.Core.dll assembly reference?", - ec.Module.PredefinedAttributes.Dynamic.GetSignatureForError ()); + mc.Module.PredefinedAttributes.Dynamic.GetSignatureForError ()); } fne = new DynamicTypeExpr (loc); - fne.ResolveAsType (ec); + fne.ResolveAsType (mc); } if (fne != null) return fne; - Error_TypeOrNamespaceNotFound (ec); + Error_TypeOrNamespaceNotFound (mc); return null; } @@ -2499,6 +2786,17 @@ namespace Mono.CSharp { ct = ct.DeclaringType; } while (ct != null); + } else { + var cos = rc.CurrentMemberDefinition.Parent as ClassOrStruct; + if (cos != null && cos.PrimaryConstructorParameters != null) { + foreach (var p in cos.PrimaryConstructorParameters.FixedParameters) { + if (p.Name == Name) { + rc.Report.Error (9007, loc, "Primary constructor parameter `{0}' is not available in this context when using ref or out modifier", + Name); + return null; + } + } + } } if ((restrictions & MemberLookupRestrictions.InvocableOnly) == 0) { @@ -2511,7 +2809,7 @@ namespace Mono.CSharp { } else { var me = MemberLookup (rc, false, rc.CurrentType, Name, Arity, restrictions & ~MemberLookupRestrictions.InvocableOnly, loc) as MemberExpr; if (me != null) { - me.Error_UnexpectedKind (rc, me, "method group", me.KindName, loc); + Error_UnexpectedKind (rc, me, "method group", me.KindName, loc); return ErrorExpression.Instance; } } @@ -2519,12 +2817,15 @@ namespace Mono.CSharp { e = rc.LookupNamespaceOrType (Name, -System.Math.Max (1, Arity), LookupMode.Probing, loc); if (e != null) { if (e.Type.Arity != Arity) { - Error_TypeArgumentsCannotBeUsed (rc, e.Type, Arity, loc); + Error_TypeArgumentsCannotBeUsed (rc, e.Type, loc); return e; } if (e is TypeExpr) { - e.Error_UnexpectedKind (rc, e, "variable", e.ExprClassName, loc); + // TypeExpression does not have correct location + if (e is TypeExpression) + e = new TypeExpression (e.Type, loc); + return e; } } @@ -2546,19 +2847,19 @@ namespace Mono.CSharp { } } - Expression SimpleNameResolve (ResolveContext ec, Expression right_side, bool intermediate) + Expression SimpleNameResolve (ResolveContext ec, Expression right_side) { Expression e = LookupNameExpression (ec, right_side == null ? MemberLookupRestrictions.ReadAccess : MemberLookupRestrictions.None); if (e == null) return null; - if (right_side != null) { - if (e is FullNamedExpression && e.eclass != ExprClass.Unresolved) { - e.Error_UnexpectedKind (ec, e, "variable", e.ExprClassName, loc); - return null; - } + if (e is FullNamedExpression && e.eclass != ExprClass.Unresolved) { + Error_UnexpectedKind (ec, e, "variable", e.ExprClassName, loc); + return e; + } + if (right_side != null) { e = e.ResolveLValue (ec, right_side); } else { e = e.Resolve (ec); @@ -2611,7 +2912,7 @@ namespace Mono.CSharp { TypeExpr te = fne as TypeExpr; if (te == null) { - fne.Error_UnexpectedKind (mc, fne, "type", fne.ExprClassName, loc); + Error_UnexpectedKind (mc, fne, "type", fne.ExprClassName, loc); return null; } @@ -2705,6 +3006,114 @@ namespace Mono.CSharp { } } + public class NamespaceExpression : FullNamedExpression + { + readonly Namespace ns; + + public NamespaceExpression (Namespace ns, Location loc) + { + this.ns = ns; + this.Type = InternalType.Namespace; + this.eclass = ExprClass.Namespace; + this.loc = loc; + } + + public Namespace Namespace { + get { + return ns; + } + } + + protected override Expression DoResolve (ResolveContext rc) + { + throw new NotImplementedException (); + } + + public override FullNamedExpression ResolveAsTypeOrNamespace (IMemberContext mc) + { + return this; + } + + public void Error_NamespaceDoesNotExist (IMemberContext ctx, string name, int arity) + { + var retval = Namespace.LookupType (ctx, name, arity, LookupMode.IgnoreAccessibility, loc); + if (retval != null) { +// ctx.Module.Compiler.Report.SymbolRelatedToPreviousError (retval.MemberDefinition); + ErrorIsInaccesible (ctx, retval.GetSignatureForError (), loc); + return; + } + + retval = Namespace.LookupType (ctx, name, -System.Math.Max (1, arity), LookupMode.Probing, loc); + if (retval != null) { + Error_TypeArgumentsCannotBeUsed (ctx, retval, loc); + return; + } + + Namespace ns; + if (arity > 0 && Namespace.TryGetNamespace (name, out ns)) { + Error_TypeArgumentsCannotBeUsed (ctx, ExprClassName, ns.GetSignatureForError (), loc); + return; + } + + string assembly = null; + string possible_name = Namespace.GetSignatureForError () + "." + 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.Forms"; + break; + } + + assembly = assembly == null ? "an" : "`" + assembly + "'"; + + if (Namespace 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 {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 {2} assembly reference?", + name, GetSignatureForError (), assembly); + } + } + + public override string GetSignatureForError () + { + return ns.GetSignatureForError (); + } + + public FullNamedExpression LookupTypeOrNamespace (IMemberContext ctx, string name, int arity, LookupMode mode, Location loc) + { + return ns.LookupTypeOrNamespace (ctx, name, arity, mode, loc); + } + } + /// /// This class denotes an expression which evaluates to a member /// of a struct or a class. @@ -2780,7 +3189,21 @@ namespace Mono.CSharp { // TypeSpec[] targs = null; if (method.DeclaringType != InstanceExpression.Type) { - var base_override = MemberCache.FindMember (InstanceExpression.Type, new MemberFilter (method), BindingRestriction.InstanceOnly) as MethodSpec; + // + // Candidate can have inflated MVAR parameters and we need to find + // base match for original definition not inflated parameter types + // + var parameters = method.Parameters; + if (method.Arity > 0) { + parameters = ((IParametersMember) method.MemberDefinition).Parameters; + var inflated = method.DeclaringType as InflatedTypeSpec; + if (inflated != null) { + parameters = parameters.Inflate (inflated.CreateLocalInflator (rc)); + } + } + + var filter = new MemberFilter (method.Name, method.Arity, MemberKind.Method, parameters, null); + var base_override = MemberCache.FindMember (InstanceExpression.Type, filter, BindingRestriction.InstanceOnly | BindingRestriction.OverrideOnly) as MethodSpec; if (base_override != null && base_override.DeclaringType != method.DeclaringType) { if (base_override.IsGeneric) targs = method.TypeArguments; @@ -2824,6 +3247,7 @@ namespace Mono.CSharp { // Only base will allow this invocation to happen. // if (method.IsAbstract) { + rc.Report.SymbolRelatedToPreviousError (method); Error_CannotCallAbstractBase (rc, method.GetSignatureForError ()); } @@ -2917,36 +3341,73 @@ namespace Mono.CSharp { rc.Report.Error (205, loc, "Cannot call an abstract base member `{0}'", name); } - public static void Error_ProtectedMemberAccess (ResolveContext rc, MemberSpec member, TypeSpec qualifier, Location loc) - { - rc.Report.SymbolRelatedToPreviousError (member); - rc.Report.Error (1540, loc, - "Cannot access protected member `{0}' via a qualifier of type `{1}'. The qualifier must be of type `{2}' or derived from it", - member.GetSignatureForError (), qualifier.GetSignatureForError (), rc.CurrentType.GetSignatureForError ()); - } + public static void Error_ProtectedMemberAccess (ResolveContext rc, MemberSpec member, TypeSpec qualifier, Location loc) + { + rc.Report.SymbolRelatedToPreviousError (member); + rc.Report.Error (1540, loc, + "Cannot access protected member `{0}' via a qualifier of type `{1}'. The qualifier must be of type `{2}' or derived from it", + member.GetSignatureForError (), qualifier.GetSignatureForError (), rc.CurrentType.GetSignatureForError ()); + } + + public override void FlowAnalysis (FlowAnalysisContext fc) + { + if (InstanceExpression != null) + InstanceExpression.FlowAnalysis (fc); + } + + public bool ResolveInstanceExpression (ResolveContext rc, Expression rhs) + { + if (!ResolveInstanceExpressionCore (rc, rhs)) + return false; + + // + // Check intermediate value modification which won't have any effect + // + if (rhs != null && InstanceExpression.Type.IsStruct) { + var fexpr = InstanceExpression as FieldExpr; + if (fexpr != null) { + if (!fexpr.Spec.IsReadOnly || rc.HasAny (ResolveContext.Options.FieldInitializerScope | ResolveContext.Options.ConstructorScope)) + return true; + + if (fexpr.IsStatic) { + rc.Report.Error (1650, loc, "Fields of static readonly field `{0}' cannot be assigned to (except in a static constructor or a variable initializer)", + fexpr.GetSignatureForError ()); + } else { + rc.Report.Error (1648, loc, "Members of readonly field `{0}' cannot be modified (except in a constructor or a variable initializer)", + fexpr.GetSignatureForError ()); + } + + return true; + } + + if (InstanceExpression is PropertyExpr || InstanceExpression is IndexerExpr || InstanceExpression is Invocation) { + if (rc.CurrentInitializerVariable != null) { + rc.Report.Error (1918, loc, "Members of value type `{0}' cannot be assigned using a property `{1}' object initializer", + InstanceExpression.Type.GetSignatureForError (), InstanceExpression.GetSignatureForError ()); + } else { + rc.Report.Error (1612, loc, + "Cannot modify a value type return value of `{0}'. Consider storing the value in a temporary variable", + InstanceExpression.GetSignatureForError ()); + } - // - // Implements identicial simple name and type-name - // - public Expression ProbeIdenticalTypeName (ResolveContext rc, Expression left, SimpleName name) - { - var t = left.Type; - if (t.Kind == MemberKind.InternalCompilerType || t is ElementTypeSpec || t.Arity > 0) - return left; + return true; + } - // In a member access of the form E.I, if E is a single identifier, and if the meaning of E as a simple-name is - // a constant, field, property, local variable, or parameter with the same type as the meaning of E as a type-name + var lvr = InstanceExpression as LocalVariableReference; + if (lvr != null) { - if (left is MemberExpr || left is VariableReference) { - var identical_type = rc.LookupNamespaceOrType (name.Name, 0, LookupMode.Probing, loc) as TypeExpr; - if (identical_type != null && identical_type.Type == left.Type) - return identical_type; + if (!lvr.local_info.IsReadonly) + return true; + + rc.Report.Error (1654, loc, "Cannot assign to members of `{0}' because it is a `{1}'", + InstanceExpression.GetSignatureForError (), lvr.local_info.GetReadOnlyContext ()); + } } - return left; + return true; } - public bool ResolveInstanceExpression (ResolveContext rc, Expression rhs) + bool ResolveInstanceExpressionCore (ResolveContext rc, Expression rhs) { if (IsStatic) { if (InstanceExpression != null) { @@ -2977,14 +3438,25 @@ namespace Mono.CSharp { if (InstanceExpression == null || InstanceExpression is TypeExpr) { if (InstanceExpression != null || !This.IsThisAvailable (rc, true)) { - if (rc.HasSet (ResolveContext.Options.FieldInitializerScope)) + if (rc.HasSet (ResolveContext.Options.FieldInitializerScope)) { rc.Report.Error (236, loc, "A field initializer cannot reference the nonstatic field, method, or property `{0}'", GetSignatureForError ()); - else - rc.Report.Error (120, loc, - "An object reference is required to access non-static member `{0}'", - GetSignatureForError ()); + } else { + var fe = this as FieldExpr; + if (fe != null && fe.Spec.MemberDefinition is PrimaryConstructorField) { + if (rc.HasSet (ResolveContext.Options.BaseInitializer)) { + rc.Report.Error (9005, loc, "Constructor initializer cannot access primary constructor parameters"); + } else { + rc.Report.Error (9006, loc, "An object reference is required to access primary constructor parameter `{0}'", + fe.Name); + } + } else { + rc.Report.Error (120, loc, + "An object reference is required to access non-static member `{0}'", + GetSignatureForError ()); + } + } InstanceExpression = new CompilerGeneratedThis (rc.CurrentType, loc).Resolve (rc); return false; @@ -2996,45 +3468,25 @@ namespace Mono.CSharp { DeclaringType.GetSignatureForError (), rc.CurrentType.GetSignatureForError ()); } - InstanceExpression = new This (loc); - if (this is FieldExpr && rc.CurrentBlock.ParametersBlock.TopBlock.ThisVariable != null) { - using (rc.Set (ResolveContext.Options.OmitStructFlowAnalysis)) { - InstanceExpression = InstanceExpression.Resolve (rc); - } - } else { - InstanceExpression = InstanceExpression.Resolve (rc); - } - + InstanceExpression = new This (loc).Resolve (rc); return false; } var me = InstanceExpression as MemberExpr; if (me != null) { - me.ResolveInstanceExpression (rc, rhs); - - // 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 ()); - } + me.ResolveInstanceExpressionCore (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 ()); } return true; } - // - // Run member-access postponed check once we know that - // the expression is not field expression which is the only - // expression which can use uninitialized this - // - if (InstanceExpression is This && !(this is FieldExpr) && rc.CurrentBlock.ParametersBlock.TopBlock.ThisVariable != null) { - ((This)InstanceExpression).CheckStructThisDefiniteAssignment (rc); - } - // // Additional checks for l-value member access // @@ -3133,7 +3585,7 @@ namespace Mono.CSharp { class ExtensionMethodGroupExpr : MethodGroupExpr, OverloadResolver.IErrorHandler { ExtensionMethodCandidates candidates; - public readonly Expression ExtensionExpression; + public Expression ExtensionExpression; public ExtensionMethodGroupExpr (ExtensionMethodCandidates candidates, Expression extensionExpr, Location loc) : base (candidates.Methods.Cast().ToList (), extensionExpr.Type, loc) @@ -3177,8 +3629,16 @@ namespace Mono.CSharp { if (arguments == null) arguments = new Arguments (1); + ExtensionExpression = ExtensionExpression.Resolve (ec); + if (ExtensionExpression == null) + return null; + + var cand = candidates; arguments.Insert (0, new Argument (ExtensionExpression, Argument.AType.ExtensionType)); var res = base.OverloadResolve (ec, ref arguments, ehandler ?? this, restr); + + // Restore candidates in case we are running in probing mode + candidates = cand; // Store resolved argument and restore original arguments if (res == null) { @@ -3241,6 +3701,8 @@ namespace Mono.CSharp { /// public class MethodGroupExpr : MemberExpr, OverloadResolver.IBaseMembersProvider { + static readonly MemberSpec[] Excluded = new MemberSpec[0]; + protected IList Methods; MethodSpec best_candidate; TypeSpec best_candidate_return; @@ -3290,6 +3752,12 @@ namespace Mono.CSharp { } } + public bool IsConditionallyExcluded { + get { + return Methods == Excluded; + } + } + public override bool IsInstance { get { if (best_candidate != null) @@ -3299,6 +3767,12 @@ namespace Mono.CSharp { } } + public override bool IsSideEffectFree { + get { + return InstanceExpression == null || InstanceExpression.IsSideEffectFree; + } + } + public override bool IsStatic { get { if (best_candidate != null) @@ -3353,7 +3827,7 @@ namespace Mono.CSharp { return null; } - if (best_candidate.IsConditionallyExcluded (ec, loc)) + if (IsConditionallyExcluded) ec.Report.Error (765, loc, "Partial methods with only a defining declaration or removed conditional methods cannot be used in an expression tree"); @@ -3388,7 +3862,7 @@ namespace Mono.CSharp { public override void Error_ValueCannotBeConverted (ResolveContext ec, TypeSpec target, bool expl) { ec.Report.Error (428, loc, "Cannot convert method group `{0}' to non-delegate type `{1}'. Consider using parentheses to invoke the method", - Name, TypeManager.CSharpName (target)); + Name, target.GetSignatureForError ()); } public static bool IsExtensionMethodArgument (Expression expr) @@ -3448,7 +3922,7 @@ namespace Mono.CSharp { InstanceExpression = ProbeIdenticalTypeName (ec, InstanceExpression, simple_name); } - InstanceExpression.Resolve (ec); + InstanceExpression.Resolve (ec, ResolveFlags.VariableOrValue | ResolveFlags.MethodGroup | ResolveFlags.Type); } } @@ -3463,7 +3937,7 @@ namespace Mono.CSharp { best_candidate_return = best_candidate.ReturnType; } - if (best_candidate.IsGeneric && TypeParameterSpec.HasAnyTypeParameterConstrained (best_candidate.GenericDefinition)) { + if (best_candidate.IsGeneric && (restr & OverloadResolver.Restrictions.ProbingOnly) == 0 && TypeParameterSpec.HasAnyTypeParameterConstrained (best_candidate.GenericDefinition)) { ConstraintChecker cc = new ConstraintChecker (ec); cc.CheckAll (best_candidate.GetGenericMethodDefinition (), best_candidate.TypeArguments, best_candidate.Constraints, loc); } @@ -3478,6 +3952,10 @@ namespace Mono.CSharp { ErrorIsInaccesible (ec, best_candidate.GetSignatureForError (), loc); } + // Speed up the check by not doing it on disallowed targets + if (best_candidate_return.Kind == MemberKind.Void && best_candidate.IsConditionallyExcluded (ec)) + Methods = Excluded; + return this; } @@ -3522,10 +4000,9 @@ namespace Mono.CSharp { // public virtual MethodGroupExpr LookupExtensionMethod (ResolveContext rc) { - if (InstanceExpression == null) + if (InstanceExpression == null || InstanceExpression.eclass == ExprClass.Type) return null; - InstanceExpression = InstanceExpression.Resolve (rc); if (!IsExtensionMethodArgument (InstanceExpression)) return null; @@ -3795,11 +4272,7 @@ namespace Mono.CSharp { // better conversion is performed between underlying types Y1 and Y2 // if (p.IsGenericTask || q.IsGenericTask) { - if (am.Block.IsAsync) { - if (p.IsGenericTask != q.IsGenericTask) { - return 0; - } - + if (am.Block.IsAsync && p.IsGenericTask && q.IsGenericTask) { q = q.TypeArguments[0]; p = p.TypeArguments[0]; } @@ -3937,7 +4410,7 @@ namespace Mono.CSharp { AParametersCollection best_pd = ((IParametersMember) best).Parameters; bool better_at_least_one = false; - bool same = true; + bool are_equivalent = true; int args_count = args == null ? 0 : args.Count; int j = 0; Argument a = null; @@ -3982,7 +4455,7 @@ namespace Mono.CSharp { if (TypeSpecComparer.IsEqual (ct, bt)) continue; - same = false; + are_equivalent = false; int result = BetterExpressionConversion (ec, a, ct, bt); // for each argument, the conversion to 'ct' should be no worse than @@ -4000,67 +4473,63 @@ namespace Mono.CSharp { return true; // - // This handles the case - // - // Add (float f1, float f2, float f3); - // Add (params decimal [] foo); - // - // The call Add (3, 4, 5) should be ambiguous. Without this check, the - // first candidate would've chosen as better. + // Tie-breaking rules are applied only for equivalent parameter types // - if (!same && !a.IsDefaultArgument) + if (!are_equivalent) return false; // - // The two methods have equal non-optional parameter types, apply tie-breaking rules + // If candidate is applicable in its normal form and best has a params array and is applicable + // only in its expanded form, then candidate is better // + if (candidate_params != best_params) + return !candidate_params; // - // This handles the following cases: - // - // Foo (int i) is better than Foo (int i, long l = 0) - // Foo (params int[] args) is better than Foo (int i = 0, params int[] args) - // - // Prefer non-optional version - // - // LAMESPEC: Specification claims this should be done at last but the opposite is true + // We have not reached end of parameters list due to params or used default parameters // - if (candidate_params == best_params && candidate_pd.Count != best_pd.Count) { - if (candidate_pd.Count >= best_pd.Count) - return false; + while (j < candidate_pd.Count && j < best_pd.Count) { + var cand_param = candidate_pd.FixedParameters [j]; + var best_param = best_pd.FixedParameters [j]; - if (j < candidate_pd.Count && candidate_pd.FixedParameters[j].HasDefaultValue) - return false; + if (candidate_pd.Count == best_pd.Count) { + // + // LAMESPEC: + // + // void Foo (int i = 0) is better than void Foo (params int[]) for Foo () + // void Foo (string[] s, string value = null) is better than Foo (string s, params string[]) for Foo (null) or Foo () + // + if (cand_param.HasDefaultValue != best_param.HasDefaultValue) + return cand_param.HasDefaultValue; - return true; + if (cand_param.HasDefaultValue) { + ++j; + continue; + } + } else { + // + // Neither is better when not all arguments are provided + // + // void Foo (string s, int i = 0) <-> Foo (string s, int i = 0, int i2 = 0) + // void Foo (string s, int i = 0) <-> Foo (string s, byte i = 0) + // void Foo (string s, params int[]) <-> Foo (string s, params byte[]) + // + if (cand_param.HasDefaultValue && best_param.HasDefaultValue) + return false; + } + + break; } + if (candidate_pd.Count != best_pd.Count) + return candidate_pd.Count < best_pd.Count; + // // One is a non-generic method and second is a generic method, then non-generic is better // if (best.IsGeneric != candidate.IsGeneric) return best.IsGeneric; - // - // This handles the following cases: - // - // Trim () is better than Trim (params char[] chars) - // Concat (string s1, string s2, string s3) is better than - // Concat (string s1, params string [] srest) - // Foo (int, params int [] rest) is better than Foo (params int [] rest) - // - // Prefer non-expanded version - // - if (candidate_params != best_params) - return best_params; - - int candidate_param_count = candidate_pd.Count; - int best_param_count = best_pd.Count; - - if (candidate_param_count != best_param_count) - // can only happen if (candidate_params && best_params) - return candidate_param_count > best_param_count && best_pd.HasParams; - // // Both methods have the same number of parameters, and the parameters have equal types // Pick the "more specific" signature using rules over original (non-inflated) types @@ -4172,6 +4641,9 @@ namespace Mono.CSharp { } else if (arg_count > param_count) { int args_gap = System.Math.Abs (arg_count - param_count); return int.MaxValue - 10000 + args_gap; + } else if (arg_count < param_count - optional_count) { + int args_gap = System.Math.Abs (param_count - optional_count - arg_count); + return int.MaxValue - 10000 + args_gap; } } else if (arg_count != param_count) { int args_gap = System.Math.Abs (arg_count - param_count); @@ -4231,7 +4703,10 @@ namespace Mono.CSharp { ++arg_count; temp = null; } else { - temp = arguments[index]; + if (index == arg_count) + return (i + 1) * 3; + + temp = arguments [index]; // The slot has been taken by positional argument if (temp != null && !(temp is NamedArgument)) @@ -4243,6 +4718,11 @@ namespace Mono.CSharp { arg_moved = true; } + if (arguments == orig_args) { + arguments = new Arguments (orig_args.Count); + arguments.AddRange (orig_args); + } + arguments[index] = arguments[i]; arguments[i] = temp; @@ -4280,7 +4760,8 @@ namespace Mono.CSharp { if (g_args_count != type_arguments.Count) return int.MaxValue - 20000 + System.Math.Abs (type_arguments.Count - g_args_count); - ms = ms.MakeGenericMethod (ec, type_arguments.Arguments); + if (type_arguments.Arguments != null) + ms = ms.MakeGenericMethod (ec, type_arguments.Arguments); } else { // // Deploy custom error reporting for infered anonymous expression or lambda methods. When @@ -4346,7 +4827,8 @@ namespace Mono.CSharp { } candidate = ms; - ptypes = ms.Parameters.Types; + pd = ms.Parameters; + ptypes = pd.Types; } else { if (type_arguments != null) return int.MaxValue - 15000; @@ -4374,18 +4856,15 @@ namespace Mono.CSharp { // if the type matches // Expression e = fp.DefaultValue; - if (!(e is Constant) || e.Type.IsGenericOrParentIsGeneric || e.Type.IsGenericParameter) { - // - // LAMESPEC: No idea what the exact rules are for System.Reflection.Missing.Value instead of null - // - if (e == EmptyExpression.MissingValue && ptypes[i].BuiltinType == BuiltinTypeSpec.Type.Object || ptypes[i].BuiltinType == BuiltinTypeSpec.Type.Dynamic) { - e = new MemberAccess (new MemberAccess (new MemberAccess ( - new QualifiedAliasMember (QualifiedAliasMember.GlobalAlias, "System", loc), "Reflection", loc), "Missing", loc), "Value", loc); - } else { - e = new DefaultValueExpression (new TypeExpression (ptypes [i], loc), loc); + if (e != null) { + e = ResolveDefaultValueArgument (ec, ptypes[i], e, loc); + if (e == null) { + // Restore for possible error reporting + for (int ii = i; ii < arg_count; ++ii) + arguments.RemoveAt (i); + + return (arg_count - i) * 2 + 1; } - - e = e.Resolve (ec); } if ((fp.ModFlags & Parameter.Modifier.CallerMask) != 0) { @@ -4442,17 +4921,18 @@ namespace Mono.CSharp { // It can be applicable in expanded form (when not doing exact match like for delegates) // if (score != 0 && (p_mod & Parameter.Modifier.PARAMS) != 0 && (restrictions & Restrictions.CovariantDelegate) == 0) { - if (!params_expanded_form) + if (!params_expanded_form) { pt = ((ElementTypeSpec) pt).Element; + } if (score > 0) score = IsArgumentCompatible (ec, a, Parameter.Modifier.NONE, pt); - if (score == 0) { - params_expanded_form = true; - } else if (score < 0) { + if (score < 0) { params_expanded_form = true; dynamicArgument = true; + } else if (score == 0 || arg_count > pd.Count) { + params_expanded_form = true; } } @@ -4463,12 +4943,6 @@ namespace Mono.CSharp { } } - // - // When params parameter has no argument it will be provided later if the method is the best candidate - // - if (arg_count + 1 == pd.Count && (cpd.FixedParameters [arg_count].ModFlags & Parameter.Modifier.PARAMS) != 0) - params_expanded_form = true; - // // Restore original arguments for dynamic binder to keep the intention of original source code // @@ -4478,6 +4952,31 @@ namespace Mono.CSharp { return 0; } + public static Expression ResolveDefaultValueArgument (ResolveContext ec, TypeSpec ptype, Expression e, Location loc) + { + if (e is Constant && e.Type == ptype) + return e; + + // + // LAMESPEC: No idea what the exact rules are for System.Reflection.Missing.Value instead of null + // + if (e == EmptyExpression.MissingValue && ptype.BuiltinType == BuiltinTypeSpec.Type.Object || ptype.BuiltinType == BuiltinTypeSpec.Type.Dynamic) { + e = new MemberAccess (new MemberAccess (new MemberAccess ( + new QualifiedAliasMember (QualifiedAliasMember.GlobalAlias, "System", loc), "Reflection", loc), "Missing", loc), "Value", loc); + } else if (e is Constant) { + // + // Handles int to int? conversions, DefaultParameterValue check + // + e = Convert.ImplicitConversionStandard (ec, e, ptype, loc); + if (e == null) + return null; + } else { + e = new DefaultValueExpression (new TypeExpression (ptype, loc), loc); + } + + return e.Resolve (ec); + } + // // Tests argument compatibility with the parameter // The possible return values are @@ -4527,7 +5026,7 @@ namespace Mono.CSharp { // is used as argument or delegate conversion // if (!Convert.ImplicitConversionExists (ec, argument.Expr, parameter)) { - return 2; + return parameter.IsDelegate && argument.Expr is AnonymousMethodExpression ? 2 : 3; } } @@ -4734,8 +5233,7 @@ namespace Mono.CSharp { } // Restore expanded arguments - if (candidate_args != args) - candidate_args = args; + candidate_args = args; } } while (best_candidate_rate != 0 && (type_members = base_provider.GetBaseMembers (type_members[0].DeclaringType.BaseType)) != null); @@ -4832,7 +5330,7 @@ namespace Mono.CSharp { } } - if (invocable_member != null) { + if (invocable_member != null && !IsProbingOnly) { rc.Report.SymbolRelatedToPreviousError (best_candidate); rc.Report.SymbolRelatedToPreviousError (invocable_member); rc.Report.Warning (467, 2, loc, "Ambiguity between method `{0}' and invocable non-method `{1}'. Using method group", @@ -4852,13 +5350,18 @@ namespace Mono.CSharp { return null; // - // Check ObsoleteAttribute on the best method + // Don't run possibly expensive checks in probing mode // - ObsoleteAttribute oa = best_candidate.GetAttributeObsolete (); - if (oa != null && !rc.IsObsolete) - AttributeTester.Report_ObsoleteMessage (oa, best_candidate.GetSignatureForError (), loc, rc.Report); + if (!IsProbingOnly && !rc.IsInProbingMode) { + // + // Check ObsoleteAttribute on the best method + // + ObsoleteAttribute oa = best_candidate.GetAttributeObsolete (); + if (oa != null && !rc.IsObsolete) + AttributeTester.Report_ObsoleteMessage (oa, best_candidate.GetSignatureForError (), loc, rc.Report); - best_candidate.MemberDefinition.SetIsUsed (); + best_candidate.MemberDefinition.SetIsUsed (); + } args = best_candidate_args; return (T) best_candidate; @@ -4881,7 +5384,7 @@ namespace Mono.CSharp { if (a is CollectionElementInitializer.ElementInitializerArgument) { ec.Report.SymbolRelatedToPreviousError (method); if ((expected_par.FixedParameters[idx].ModFlags & Parameter.Modifier.RefOutMask) != 0) { - ec.Report.Error (1954, loc, "The best overloaded collection initalizer method `{0}' cannot have 'ref', or `out' modifier", + ec.Report.Error (1954, loc, "The best overloaded collection initalizer method `{0}' cannot have `ref' or `out' modifier", TypeManager.CSharpSignature (method)); return; } @@ -4901,21 +5404,26 @@ namespace Mono.CSharp { string index = (idx + 1).ToString (); if (((mod & Parameter.Modifier.RefOutMask) ^ (a.Modifier & Parameter.Modifier.RefOutMask)) != 0) { if ((mod & Parameter.Modifier.RefOutMask) == 0) - ec.Report.Error (1615, loc, "Argument `#{0}' does not require `{1}' modifier. Consider removing `{1}' modifier", + ec.Report.Error (1615, a.Expr.Location, "Argument `#{0}' does not require `{1}' modifier. Consider removing `{1}' modifier", index, Parameter.GetModifierSignature (a.Modifier)); else - ec.Report.Error (1620, loc, "Argument `#{0}' is missing `{1}' modifier", + ec.Report.Error (1620, a.Expr.Location, "Argument `#{0}' is missing `{1}' modifier", index, Parameter.GetModifierSignature (mod)); } else { string p1 = a.GetSignatureForError (); - string p2 = TypeManager.CSharpName (paramType); + string p2 = paramType.GetSignatureForError (); if (p1 == p2) { p1 = a.Type.GetSignatureForErrorIncludingAssemblyName (); p2 = paramType.GetSignatureForErrorIncludingAssemblyName (); } - ec.Report.Error (1503, loc, + if ((mod & Parameter.Modifier.RefOutMask) != 0) { + p1 = Parameter.GetModifierSignature (a.Modifier) + " " + p1; + p2 = Parameter.GetModifierSignature (a.Modifier) + " " + p2; + } + + ec.Report.Error (1503, a.Expr.Location, "Argument `#{0}' cannot convert `{1}' expression to type `{2}'", index, p1, p2); } } @@ -4930,7 +5438,7 @@ namespace Mono.CSharp { if (ta_count != best_candidate.Arity && (ta_count > 0 || ((IParametersMember) best_candidate).Parameters.IsEmpty)) { var mg = new MethodGroupExpr (new [] { best_candidate }, best_candidate.DeclaringType, loc); - mg.Error_TypeArgumentsCannotBeUsed (rc, best_candidate, ta_count, loc); + mg.Error_TypeArgumentsCannotBeUsed (rc, best_candidate, loc); return; } @@ -4948,8 +5456,7 @@ namespace Mono.CSharp { // For candidates which match on parameters count report more details about incorrect arguments // if (pm != null) { - int unexpanded_count = ((IParametersMember) best_candidate).Parameters.HasParams ? pm.Parameters.Count - 1 : pm.Parameters.Count; - if (pm.Parameters.Count == arg_count || params_expanded || unexpanded_count == arg_count) { + if (pm.Parameters.Count == arg_count || params_expanded || HasUnfilledParams (best_candidate, pm, args)) { // Reject any inaccessible member if (!best_candidate.IsAccessible (rc) || !best_candidate.DeclaringType.IsAccessible (rc)) { rc.Report.SymbolRelatedToPreviousError (best_candidate); @@ -4963,7 +5470,7 @@ namespace Mono.CSharp { if (ms.TypeArguments != null) constr_ok = new ConstraintChecker (rc.MemberContext).CheckAll (ms.GetGenericMethodDefinition (), ms.TypeArguments, ms.Constraints, loc); - if (ta_count == 0) { + if (ta_count == 0 && ms.TypeArguments == null) { if (custom_errors != null && custom_errors.TypeInferenceFailed (rc, best_candidate)) return; @@ -5003,6 +5510,39 @@ namespace Mono.CSharp { } } + static bool HasUnfilledParams (MemberSpec best_candidate, IParametersMember pm, Arguments args) + { + var p = ((IParametersMember)best_candidate).Parameters; + if (!p.HasParams) + return false; + + string name = null; + for (int i = p.Count - 1; i != 0; --i) { + var fp = p.FixedParameters [i]; + if ((fp.ModFlags & Parameter.Modifier.PARAMS) == 0) + continue; + + name = fp.Name; + break; + } + + foreach (var arg in args) { + var na = arg as NamedArgument; + if (na == null) + continue; + + if (na.Name == name) { + name = null; + break; + } + } + + if (name == null) + return false; + + return args.Count + 1 == pm.Parameters.Count; + } + bool VerifyArguments (ResolveContext ec, ref Arguments args, MemberSpec member, IParametersMember pm, bool chose_params_expanded) { var pd = pm.Parameters; @@ -5018,6 +5558,9 @@ namespace Mono.CSharp { for (; a_idx < arg_count; a_idx++, ++a_pos) { a = args[a_idx]; + if (a == null) + continue; + if (p_mod != Parameter.Modifier.PARAMS) { p_mod = pd.FixedParameters[a_idx].ModFlags; pt = ptypes[a_idx]; @@ -5059,7 +5602,7 @@ namespace Mono.CSharp { "The best overloaded method match for `{0}' does not contain a parameter named `{1}'", TypeManager.CSharpSignature (member), na.Name); } - } else if (args[name_index] != a) { + } else if (args[name_index] != a && args[name_index] != null) { if (IsDelegateInvoke) ec.Report.SymbolRelatedToPreviousError (DelegateType); else @@ -5079,7 +5622,7 @@ namespace Mono.CSharp { return false; } - Expression conv = null; + Expression conv; if (a.ArgType == Argument.AType.ExtensionType) { if (a.Expr.Type == pt || TypeSpecComparer.IsEqual (a.Expr.Type, pt)) { conv = a.Expr; @@ -5104,6 +5647,7 @@ namespace Mono.CSharp { params_initializers.Add (a.Expr); args.RemoveAt (a_idx--); --arg_count; + a.Expr = conv; continue; } @@ -5203,7 +5747,7 @@ namespace Mono.CSharp { var c = constant.GetConstant (rc); // Creates reference expression to the constant value - return Constant.CreateConstant (constant.MemberType, c.GetValue (), loc); + return Constant.CreateConstantFromValue (constant.MemberType, c.GetValue (), loc); } public override void Emit (EmitContext ec) @@ -5323,6 +5867,14 @@ namespace Mono.CSharp { } } + protected override void CloneTo (CloneContext clonectx, Expression target) + { + var t = (FieldExpr) target; + + if (InstanceExpression != null) + t.InstanceExpression = InstanceExpression.Clone (clonectx); + } + public override Expression CreateExpressionTree (ResolveContext ec) { return CreateExpressionTree (ec, true); @@ -5373,18 +5925,14 @@ namespace Mono.CSharp { // "a.b" is initialized, not whether the whole struct "a" is initialized. if (lvalue_instance) { - using (ec.With (ResolveContext.Options.DoFlowAnalysis, false)) { - bool out_access = rhs == EmptyExpression.OutAccess || rhs == EmptyExpression.LValueMemberOutAccess; + bool out_access = rhs == EmptyExpression.OutAccess || rhs == EmptyExpression.LValueMemberOutAccess; - Expression right_side = - out_access ? EmptyExpression.LValueMemberOutAccess : EmptyExpression.LValueMemberAccess; + Expression right_side = + out_access ? EmptyExpression.LValueMemberOutAccess : EmptyExpression.LValueMemberAccess; - InstanceExpression = InstanceExpression.ResolveLValue (ec, right_side); - } + InstanceExpression = InstanceExpression.ResolveLValue (ec, right_side); } else { - using (ec.With (ResolveContext.Options.DoFlowAnalysis, false)) { - InstanceExpression = InstanceExpression.Resolve (ec, ResolveFlags.VariableOrValue); - } + InstanceExpression = InstanceExpression.Resolve (ec, ResolveFlags.VariableOrValue); } if (InstanceExpression == null) @@ -5397,10 +5945,6 @@ namespace Mono.CSharp { var fb = spec as FixedFieldSpec; IVariableReference var = InstanceExpression as IVariableReference; - 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)) { @@ -5424,78 +5968,109 @@ namespace Mono.CSharp { // if (var != null && var.VariableInfo != null && InstanceExpression.Type.IsStruct) { variable_info = var.VariableInfo.GetStructFieldInfo (Name); - if (rhs != null && variable_info != null) - variable_info.SetStructFieldAssigned (ec, Name); } eclass = ExprClass.Variable; return this; } - public void VerifyAssignedStructField (ResolveContext rc, Expression rhs) + public void SetFieldAssigned (FlowAnalysisContext fc) { - var fe = this; + if (!IsInstance) + return; - do { - var var = fe.InstanceExpression as IVariableReference; - if (var != null) { - var vi = var.VariableInfo; + bool lvalue_instance = spec.DeclaringType.IsStruct; + if (lvalue_instance) { + var var = InstanceExpression as IVariableReference; + if (var != null && var.VariableInfo != null) { + fc.SetStructFieldAssigned (var.VariableInfo, Name); + } + } - if (vi != null && !vi.IsStructFieldAssigned (rc, fe.Name) && (rhs == null || !fe.type.IsStruct)) { - if (rhs != null) { - rc.Report.Warning (1060, 1, fe.loc, "Use of possibly unassigned field `{0}'", fe.Name); - } else { - rc.Report.Error (170, fe.loc, "Use of possibly unassigned field `{0}'", fe.Name); + var fe = InstanceExpression as FieldExpr; + if (fe != null) { + Expression instance; + + do { + instance = fe.InstanceExpression; + var fe_instance = instance as FieldExpr; + if ((fe_instance != null && !fe_instance.IsStatic) || instance is LocalVariableReference) { + if (TypeSpec.IsReferenceType (fe.Type) && instance.Type.IsStruct) { + var var = InstanceExpression as IVariableReference; + if (var != null && var.VariableInfo == null) { + var var_inst = instance as IVariableReference; + if (var_inst == null || (var_inst.VariableInfo != null && !fc.IsDefinitelyAssigned (var_inst.VariableInfo))) + fc.Report.Warning (1060, 1, fe.loc, "Use of possibly unassigned field `{0}'", fe.Name); + } } - return; + if (fe_instance != null) { + fe = fe_instance; + continue; + } } + + break; + } while (true); + + if (instance != null && TypeSpec.IsReferenceType (instance.Type)) + instance.FlowAnalysis (fc); + } else { + if (TypeSpec.IsReferenceType (InstanceExpression.Type)) + InstanceExpression.FlowAnalysis (fc); + } + } + + Expression Error_AssignToReadonly (ResolveContext rc, Expression right_side) + { + // The return value is always null. Returning a value simplifies calling code. + + if (right_side == EmptyExpression.OutAccess) { + if (IsStatic) { + rc.Report.Error (199, loc, "A static readonly field `{0}' cannot be passed ref or out (except in a static constructor)", + GetSignatureForError ()); + } else { + rc.Report.Error (192, loc, "A readonly field `{0}' cannot be passed ref or out (except in a constructor)", + GetSignatureForError ()); } - fe = fe.InstanceExpression as FieldExpr; - - } while (fe != null); - } - - static readonly int [] codes = { - 191, // instance, write access - 192, // instance, out access - 198, // static, write access - 199, // static, out access - 1648, // member of value instance, write access - 1649, // member of value instance, out access - 1650, // member of value static, write access - 1651 // member of value static, out access - }; - - static readonly string [] msgs = { - /*0191*/ "A readonly field `{0}' cannot be assigned to (except in a constructor or a variable initializer)", - /*0192*/ "A readonly field `{0}' cannot be passed ref or out (except in a constructor)", - /*0198*/ "A static readonly field `{0}' cannot be assigned to (except in a static constructor or a variable initializer)", - /*0199*/ "A static readonly field `{0}' cannot be passed ref or out (except in a static constructor)", - /*1648*/ "Members of readonly field `{0}' cannot be modified (except in a constructor or a variable initializer)", - /*1649*/ "Members of readonly field `{0}' cannot be passed ref or out (except in a constructor)", - /*1650*/ "Fields of static readonly field `{0}' cannot be assigned to (except in a static constructor or a variable initializer)", - /*1651*/ "Fields of static readonly field `{0}' cannot be passed ref or out (except in a static constructor)" - }; - - // The return value is always null. Returning a value simplifies calling code. - Expression Report_AssignToReadonly (ResolveContext ec, Expression right_side) - { - int i = 0; - if (right_side == EmptyExpression.OutAccess || right_side == EmptyExpression.LValueMemberOutAccess) - i += 1; - if (IsStatic) - i += 2; - if (right_side == EmptyExpression.LValueMemberAccess || right_side == EmptyExpression.LValueMemberOutAccess) - i += 4; - ec.Report.Error (codes [i], loc, msgs [i], GetSignatureForError ()); + return null; + } + + if (right_side == EmptyExpression.LValueMemberAccess) { + // Already reported as CS1648/CS1650 + return null; + } + + if (right_side == EmptyExpression.LValueMemberOutAccess) { + if (IsStatic) { + rc.Report.Error (1651, loc, "Fields of static readonly field `{0}' cannot be passed ref or out (except in a static constructor)", + GetSignatureForError ()); + } else { + rc.Report.Error (1649, loc, "Members of readonly field `{0}' cannot be passed ref or out (except in a constructor)", + GetSignatureForError ()); + } + return null; + } + + if (IsStatic) { + rc.Report.Error (198, loc, "A static readonly field `{0}' cannot be assigned to (except in a static constructor or a variable initializer)", + GetSignatureForError ()); + } else { + rc.Report.Error (191, loc, "A readonly field `{0}' cannot be assigned to (except in a constructor or a variable initializer)", + GetSignatureForError ()); + } return null; } - + override public Expression DoResolveLValue (ResolveContext ec, Expression right_side) { + if (spec is FixedFieldSpec) { + // It could be much better error message but we want to be error compatible + Error_ValueAssignment (ec, right_side); + } + Expression e = DoResolve (ec, right_side); if (e == null) @@ -5513,19 +6088,19 @@ namespace Mono.CSharp { if (spec.IsReadOnly) { // InitOnly fields can only be assigned in constructors or initializers if (!ec.HasAny (ResolveContext.Options.FieldInitializerScope | ResolveContext.Options.ConstructorScope)) - return Report_AssignToReadonly (ec, right_side); + return Error_AssignToReadonly (ec, right_side); if (ec.HasSet (ResolveContext.Options.ConstructorScope)) { // InitOnly fields cannot be assigned-to in a different constructor from their declaring type if (ec.CurrentMemberDefinition.Parent.PartialContainer.Definition != spec.DeclaringType.GetDefinition ()) - return Report_AssignToReadonly (ec, right_side); + return Error_AssignToReadonly (ec, right_side); // static InitOnly fields cannot be assigned-to in an instance constructor if (IsStatic && !ec.IsStatic) - return Report_AssignToReadonly (ec, right_side); + return Error_AssignToReadonly (ec, right_side); // instance constructors can't modify InitOnly fields of other instances of the same type if (!IsStatic && !(InstanceExpression is This)) - return Report_AssignToReadonly (ec, right_side); + return Error_AssignToReadonly (ec, right_side); } } @@ -5540,6 +6115,23 @@ namespace Mono.CSharp { return this; } + public override void FlowAnalysis (FlowAnalysisContext fc) + { + var var = InstanceExpression as IVariableReference; + if (var != null) { + var vi = var.VariableInfo; + if (vi != null && !fc.IsStructFieldDefinitelyAssigned (vi, Name)) { + fc.Report.Error (170, loc, "Use of possibly unassigned field `{0}'", Name); + return; + } + + if (TypeSpec.IsValueType (InstanceExpression.Type) && InstanceExpression is VariableReference) + return; + } + + base.FlowAnalysis (fc); + } + public override int GetHashCode () { return spec.GetHashCode (); @@ -5616,13 +6208,8 @@ namespace Mono.CSharp { public void EmitAssign (EmitContext ec, Expression source, bool leave_copy, bool isCompound) { bool has_await_source = ec.HasSet (BuilderContext.Options.AsyncBody) && source.ContainsEmitWithAwait (); - if (isCompound && !(source is DynamicExpressionStatement)) { - if (has_await_source) { - if (IsInstance) - InstanceExpression = InstanceExpression.EmitToField (ec); - } else { - prepared = true; - } + if (isCompound && !(source is DynamicExpressionStatement) && !has_await_source) { + prepared = true; } if (IsInstance) { @@ -5634,7 +6221,7 @@ namespace Mono.CSharp { source.Emit (ec); - if (leave_copy) { + if (leave_copy || ec.NotifyEvaluatorOnStore) { ec.Emit (OpCodes.Dup); if (!IsStatic) { temp = new LocalTemporary (this.Type); @@ -5651,6 +6238,16 @@ namespace Mono.CSharp { ec.Emit (OpCodes.Stsfld, spec); else ec.Emit (OpCodes.Stfld, spec); + + if (ec.NotifyEvaluatorOnStore) { + if (!IsStatic) + throw new NotImplementedException ("instance field write"); + + if (leave_copy) + ec.Emit (OpCodes.Dup); + + ec.Module.Evaluator.EmitValueChangedCallback (ec, Name, type, loc); + } if (temp != null) { temp.Emit (ec); @@ -5713,7 +6310,6 @@ namespace Mono.CSharp { var temp = ec.GetTemporaryLocal (type); ec.Emit (OpCodes.Stloc, temp); ec.Emit (OpCodes.Ldloca, temp); - ec.FreeTemporaryLocal (temp, type); return; } @@ -5758,6 +6354,8 @@ namespace Mono.CSharp { // sealed class PropertyExpr : PropertyOrIndexerExpr { + Arguments arguments; + public PropertyExpr (PropertySpec spec, Location l) : base (l) { @@ -5769,9 +6367,10 @@ namespace Mono.CSharp { protected override Arguments Arguments { get { - return null; + return arguments; } set { + arguments = value; } } @@ -5811,6 +6410,21 @@ namespace Mono.CSharp { #endregion + public override MethodGroupExpr CanReduceLambda (AnonymousMethodBody body) + { + if (best_candidate == null || !(best_candidate.IsStatic || InstanceExpression is This)) + return null; + + var args_count = arguments == null ? 0 : arguments.Count; + if (args_count != body.Parameters.Count && args_count == 0) + return null; + + var mg = MethodGroupExpr.CreatePredefined (best_candidate.Get, DeclaringType, loc); + mg.InstanceExpression = InstanceExpression; + + return mg; + } + public static PropertyExpr CreatePredefined (PropertySpec spec, Location loc) { return new PropertyExpr (spec, loc) { @@ -5928,7 +6542,7 @@ namespace Mono.CSharp { } } } else { - args = new Arguments (1); + args = arguments ?? new Arguments (1); if (leave_copy) { source.Emit (ec); @@ -5978,6 +6592,22 @@ namespace Mono.CSharp { } DoBestMemberChecks (rc, best_candidate); + + // Handling of com-imported properties with any number of default property parameters + if (best_candidate.HasGet && !best_candidate.Get.Parameters.IsEmpty) { + var p = best_candidate.Get.Parameters; + arguments = new Arguments (p.Count); + for (int i = 0; i < p.Count; ++i) { + arguments.Add (new Argument (OverloadResolver.ResolveDefaultValueArgument (rc, p.Types [i], p.FixedParameters [i].DefaultValue, loc))); + } + } else if (best_candidate.HasSet && best_candidate.Set.Parameters.Count > 1) { + var p = best_candidate.Set.Parameters; + arguments = new Arguments (p.Count - 1); + for (int i = 0; i < p.Count - 1; ++i) { + arguments.Add (new Argument (OverloadResolver.ResolveDefaultValueArgument (rc, p.Types [i], p.FixedParameters [i].DefaultValue, loc))); + } + } + return this; } @@ -6057,11 +6687,6 @@ namespace Mono.CSharp { return null; } - // if the property/indexer returns a value type, and we try to set a field in it - if (right_side == EmptyExpression.LValueMemberAccess || right_side == EmptyExpression.LValueMemberOutAccess) { - Error_ValueAssignment (ec, right_side); - } - if (eclass == ExprClass.Unresolved) { var expr = OverloadResolve (ec, right_side); if (expr == null) @@ -6069,6 +6694,8 @@ namespace Mono.CSharp { if (expr != this) return expr.ResolveLValue (ec, right_side); + } else { + ResolveInstanceExpression (ec, right_side); } if (!ResolveSetter (ec)) @@ -6131,7 +6758,7 @@ namespace Mono.CSharp { best_candidate.GetSignatureForError ()); return false; } - } else if (!best_candidate.Get.IsAccessible (rc)) { + } else if (!best_candidate.Get.IsAccessible (rc) || !best_candidate.Get.DeclaringType.IsAccessible (rc)) { if (best_candidate.HasDifferentAccessibility) { rc.Report.SymbolRelatedToPreviousError (best_candidate.Get); rc.Report.Error (271, loc, "The property or indexer `{0}' cannot be used in this context because the get accessor is inaccessible", @@ -6158,7 +6785,7 @@ namespace Mono.CSharp { return false; } - if (!best_candidate.Set.IsAccessible (rc)) { + if (!best_candidate.Set.IsAccessible (rc) || !best_candidate.Set.DeclaringType.IsAccessible (rc)) { if (best_candidate.HasDifferentAccessibility) { rc.Report.SymbolRelatedToPreviousError (best_candidate.Set); rc.Report.Error (272, loc, "The property or indexer `{0}' cannot be used in this context because the set accessor is inaccessible", @@ -6378,6 +7005,11 @@ namespace Mono.CSharp { DoEmit (ec); } + protected override bool DoFlowAnalysis (FlowAnalysisContext fc) + { + return false; + } + protected override void CloneTo (CloneContext clonectx, Statement target) { // Nothing @@ -6421,8 +7053,9 @@ namespace Mono.CSharp { // Don't capture temporary variables except when using // state machine redirection and block yields // - if (ec.CurrentAnonymousMethod != null && ec.CurrentAnonymousMethod.IsIterator && - ec.CurrentBlock.Explicit.HasYield && ec.IsVariableCapturingRequired) { + if (ec.CurrentAnonymousMethod is StateMachineInitializer && + (ec.CurrentBlock.Explicit.HasYield || ec.CurrentBlock.Explicit.HasAwait) && + ec.IsVariableCapturingRequired) { AnonymousMethodStorey storey = li.Block.Explicit.CreateAnonymousMethodStorey (ec); storey.CaptureLocalVariable (ec, li); } @@ -6478,10 +7111,6 @@ namespace Mono.CSharp { public override VariableInfo VariableInfo { get { return null; } } - - public override void VerifyAssigned (ResolveContext rc) - { - } } /// @@ -6557,5 +7186,10 @@ namespace Mono.CSharp { { return visitor.Visit (this); } + + protected override bool DoFlowAnalysis(FlowAnalysisContext fc) + { + return false; + } } } diff --git a/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/enum.cs b/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/enum.cs index 126d2de86..ab3f9fe5b 100644 --- a/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/enum.cs +++ b/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/enum.cs @@ -66,7 +66,7 @@ namespace Mono.CSharp { var underlying = ((Enum) Parent).UnderlyingType; if (expr != null) { - expr = expr.ImplicitConversionRequired (rc, underlying, Location); + expr = expr.ImplicitConversionRequired (rc, underlying); if (expr != null && !IsValidEnumType (expr.Type)) { Enum.Error_1008 (Location, Report); expr = null; @@ -269,7 +269,7 @@ namespace Mono.CSharp { case BuiltinTypeSpec.Type.ULong: case BuiltinTypeSpec.Type.UShort: Report.Warning (3009, 1, Location, "`{0}': base type `{1}' is not CLS-compliant", - GetSignatureForError (), TypeManager.CSharpName (UnderlyingType)); + GetSignatureForError (), UnderlyingType.GetSignatureForError ()); break; } diff --git a/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/eval.cs b/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/eval.cs index 0d1264516..1645b6019 100644 --- a/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/eval.cs +++ b/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/eval.cs @@ -71,6 +71,8 @@ namespace Mono.CSharp readonly ModuleContainer module; readonly ReflectionImporter importer; readonly CompilationSourceFile source_file; + + int? listener_id; public Evaluator (CompilerContext ctx) { @@ -128,6 +130,12 @@ namespace Mono.CSharp Location.Initialize (ctx.SourceFiles); } + /// + /// When set evaluator will automatically wait on Task of async methods. When not + /// set it's called responsibility to handle Task execution + /// + public bool WaitOnTask { get; set; } + /// /// If true, turns type expressions into valid expressions /// and calls the describe method on it @@ -223,9 +231,16 @@ namespace Mono.CSharp bool partial_input; CSharpParser parser = ParseString (ParseMode.Silent, input, out partial_input); + + // Terse mode, try to provide the trailing semicolon automatically. if (parser == null && Terse && partial_input){ bool ignore; - parser = ParseString (ParseMode.Silent, input + ";", out ignore); + + // check if the source would compile with a block, if so, we should not + // add the semicolon. + var needs_block = ParseString (ParseMode.Silent, input + "{}", out ignore) != null; + if (!needs_block) + parser = ParseString (ParseMode.Silent, input + ";", out ignore); } if (parser == null){ compiled = null; @@ -275,6 +290,30 @@ namespace Mono.CSharp return compiled; } + static MethodInfo listener_proxy_value; + internal void EmitValueChangedCallback (EmitContext ec, string name, TypeSpec type, Location loc) + { + if (listener_id == null) + listener_id = ListenerProxy.Register (ModificationListener); + + if (listener_proxy_value == null) + listener_proxy_value = typeof (ListenerProxy).GetMethod ("ValueChanged"); + +#if STATIC + throw new NotSupportedException (); +#else + // object value, int row, int col, string name, int listenerId + if (type.IsStructOrEnum) + ec.Emit (OpCodes.Box, type); + + ec.EmitInt (loc.Row); + ec.EmitInt (loc.Column); + ec.Emit (OpCodes.Ldstr, name); + ec.EmitInt (listener_id.Value); + ec.Emit (OpCodes.Call, listener_proxy_value); +#endif + } + /// /// Evaluates and expression or statement and returns any result values. /// @@ -325,6 +364,11 @@ namespace Mono.CSharp Console.WriteLine ("Interrupted!\n{0}", e); } finally { invoking = false; + + if (listener_id != null) { + ListenerProxy.Unregister (listener_id.Value); + listener_id = null; + } } // @@ -354,8 +398,14 @@ namespace Mono.CSharp if (parser == null){ return null; } - - Class parser_result = parser.InteractiveResult; + + Class host = parser.InteractiveResult; + + var base_class_imported = importer.ImportType (base_class); + var baseclass_list = new List (1) { + new TypeExpression (base_class_imported, host.Location) + }; + host.SetBaseTypes (baseclass_list); #if NET_4_0 var access = AssemblyBuilderAccess.RunAndCollect; @@ -367,13 +417,15 @@ namespace Mono.CSharp module.SetDeclaringAssembly (a); // Need to setup MemberCache - parser_result.CreateContainer (); + host.CreateContainer (); + // Need to setup base type + host.DefineContainer (); - var method = parser_result.Members[0] as Method; + var method = host.Members[0] as Method; BlockContext bc = new BlockContext (method, method.Block, ctx.BuiltinTypes.Void); try { - method.Block.Resolve (null, bc, method); + method.Block.Resolve (bc, method); } catch (CompletionResult cr) { prefix = cr.BaseText; return cr.Result; @@ -419,11 +471,14 @@ namespace Mono.CSharp throw new ArgumentException ("Syntax error on input: partial input"); if (result_set == false) - throw new ArgumentException ("The expression did not set a result"); + throw new ArgumentException ("The expression failed to resolve"); return result; } + // Experimental + public Action ModificationListener { get; set; } + enum InputKind { EOF, StatementOrExpression, @@ -443,8 +498,11 @@ namespace Mono.CSharp // InputKind ToplevelOrStatement (SeekableStreamReader seekable) { - Tokenizer tokenizer = new Tokenizer (seekable, source_file, new ParserSession ()); + Tokenizer tokenizer = new Tokenizer (seekable, source_file, new ParserSession (), ctx.Report); + // Prefer contextual block keywords over identifiers + tokenizer.parsing_block++; + int t = tokenizer.token (); switch (t){ case Token.EOF: @@ -576,6 +634,7 @@ namespace Mono.CSharp if (kind == InputKind.StatementOrExpression){ parser.Lexer.putback_char = Tokenizer.EvalStatementParserCharacter; + parser.Lexer.parsing_block++; ctx.Settings.StatementMode = true; } else { parser.Lexer.putback_char = Tokenizer.EvalCompilationUnitParserCharacter; @@ -641,19 +700,59 @@ namespace Mono.CSharp new TypeExpression (base_class_imported, host.Location) }; - host.AddBasesForPart (baseclass_list); - - host.CreateContainer (); - host.DefineContainer (); - host.Define (); + host.SetBaseTypes (baseclass_list); expression_method = (Method) host.Members[0]; + + if ((expression_method.ModFlags & Modifiers.ASYNC) != 0) { + // + // Host method is async. When WaitOnTask is set we wrap it with wait + // + // void AsyncWait (ref object $retval) { + // $retval = Host(); + // ((Task)$retval).Wait(); // When WaitOnTask is set + // } + // + var p = new ParametersCompiled ( + new Parameter (new TypeExpression (module.Compiler.BuiltinTypes.Object, Location.Null), "$retval", Parameter.Modifier.REF, null, Location.Null) + ); + + var method = new Method(host, new TypeExpression(module.Compiler.BuiltinTypes.Void, Location.Null), + Modifiers.PUBLIC | Modifiers.STATIC, new MemberName("AsyncWait"), p, null); + + method.Block = new ToplevelBlock(method.Compiler, p, Location.Null); + method.Block.AddStatement(new StatementExpression (new SimpleAssign( + new SimpleName(p [0].Name, Location.Null), + new Invocation(new SimpleName(expression_method.MemberName.Name, Location.Null), new Arguments(0)), + Location.Null), Location.Null)); + + if (WaitOnTask) { + var task = new Cast (expression_method.TypeExpression, new SimpleName (p [0].Name, Location.Null), Location.Null); + + method.Block.AddStatement (new StatementExpression (new Invocation ( + new MemberAccess (task, "Wait", Location.Null), + new Arguments (0)), Location.Null)); + } + + host.AddMember(method); + + expression_method = method; + } + + host.CreateContainer(); + host.DefineContainer(); + host.Define(); + } else { expression_method = null; } module.CreateContainer (); - source_file.EnableUsingClausesRedefinition (); + + // Disable module and source file re-definition checks + module.EnableRedefinition (); + source_file.EnableRedefinition (); + module.Define (); if (Report.Errors != 0){ @@ -664,10 +763,12 @@ namespace Mono.CSharp } if (host != null){ + host.PrepareEmit (); host.EmitContainer (); } module.EmitContainer (); + if (Report.Errors != 0){ if (undo != null) undo.ExecuteUndo (); @@ -977,9 +1078,7 @@ 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" + @@ -1037,6 +1136,27 @@ namespace Mono.CSharp #endif } + class InteractiveMethod : Method + { + public InteractiveMethod(TypeDefinition parent, FullNamedExpression returnType, Modifiers mod, ParametersCompiled parameters) + : base(parent, returnType, mod, new MemberName("Host"), parameters, null) + { + } + + public void ChangeToAsync () + { + ModFlags |= Modifiers.ASYNC; + ModFlags &= ~Modifiers.UNSAFE; + type_expr = new TypeExpression(Module.PredefinedTypes.Task.TypeSpec, Location); + parameters = ParametersCompiled.EmptyReadOnlyParameters; + } + + public override string GetSignatureForError() + { + return "InteractiveHost"; + } + } + class HoistedEvaluatorVariable : HoistedVariable { public HoistedEvaluatorVariable (Field field) @@ -1057,11 +1177,17 @@ namespace Mono.CSharp /// the return value for an invocation. /// class OptionalAssign : SimpleAssign { - public OptionalAssign (Expression t, Expression s, Location loc) - : base (t, s, loc) + public OptionalAssign (Expression s, Location loc) + : base (null, s, loc) { } + public override Location StartLocation { + get { + return Location.Null; + } + } + protected override Expression DoResolve (ResolveContext ec) { Expression clone = source.Clone (new CloneContext ()); @@ -1074,7 +1200,7 @@ namespace Mono.CSharp // A useful feature for the REPL: if we can resolve the expression // as a type, Describe the type; // - if (ec.Module.Evaluator.DescribeTypeExpressions){ + if (ec.Module.Evaluator.DescribeTypeExpressions && !(ec.CurrentAnonymousMethod is AsyncInitializer)) { var old_printer = ec.Report.SetPrinter (new SessionReportPrinter ()); Expression tclone; try { @@ -1100,17 +1226,34 @@ namespace Mono.CSharp } source = clone; + + var host = (Method) ec.MemberContext.CurrentMemberDefinition; + + if (host.ParameterInfo.IsEmpty) { + eclass = ExprClass.Value; + type = InternalType.FakeInternalType; + return this; + } + + target = new SimpleName (host.ParameterInfo[0].Name, Location); + return base.DoResolve (ec); } + + public override void EmitStatement(EmitContext ec) + { + if (target == null) { + source.Emit (ec); + return; + } + + base.EmitStatement(ec); + } } public class Undo { List undo_actions; - - public Undo () - { - } public void AddTypeContainer (TypeContainer current_container, TypeDefinition tc) { @@ -1122,10 +1265,13 @@ namespace Mono.CSharp if (undo_actions == null) undo_actions = new List (); - var existing = current_container.Containers.FirstOrDefault (l => l.Basename == tc.Basename); - if (existing != null) { - current_container.RemoveContainer (existing); - undo_actions.Add (() => current_container.AddTypeContainer (existing)); + if (current_container.Containers != null) + { + var existing = current_container.Containers.FirstOrDefault (l => l.Basename == tc.Basename); + if (existing != null) { + current_container.RemoveContainer (existing); + undo_actions.Add (() => current_container.AddTypeContainer (existing)); + } } undo_actions.Add (() => current_container.RemoveContainer (tc)); @@ -1143,5 +1289,38 @@ namespace Mono.CSharp undo_actions = null; } } - + + static class ListenerProxy + { + static readonly Dictionary> listeners = new Dictionary> (); + + static int counter; + + public static int Register (Action listener) + { + lock (listeners) { + var id = counter++; + listeners.Add (id, listener); + return id; + } + } + + public static void Unregister (int listenerId) + { + lock (listeners) { + listeners.Remove (listenerId); + } + } + + public static void ValueChanged (object value, int row, int col, string name, int listenerId) + { + Action action; + lock (listeners) { + if (!listeners.TryGetValue (listenerId, out action)) + return; + } + + action (name, row, col, value); + } + } } diff --git a/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/expression.cs b/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/expression.cs index 458df5c49..cae61ece4 100644 --- a/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/expression.cs +++ b/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/expression.cs @@ -80,7 +80,12 @@ namespace Mono.CSharp public override void Emit (EmitContext ec) { var call = new CallEmitter (); - call.EmitPredefined (ec, oper, arguments); + call.EmitPredefined (ec, oper, arguments, loc); + } + + public override void FlowAnalysis (FlowAnalysisContext fc) + { + arguments.FlowAnalysis (fc); } public override SLE.Expression MakeExpression (BuilderContext ctx) @@ -95,10 +100,10 @@ namespace Mono.CSharp public class ParenthesizedExpression : ShimExpression { - public ParenthesizedExpression (Expression expr) + public ParenthesizedExpression (Expression expr, Location loc) : base (expr) { - loc = expr.Location; + this.loc = loc; } protected override Expression DoResolve (ResolveContext ec) @@ -296,10 +301,33 @@ namespace Mono.CSharp return new ULongConstant (ec.BuiltinTypes, ~((ULongConstant) e).Value, e.Location); } if (e is EnumConstant) { - e = TryReduceConstant (ec, ((EnumConstant)e).Child); - if (e != null) - e = new EnumConstant (e, expr_type); - return e; + var res = TryReduceConstant (ec, ((EnumConstant)e).Child); + if (res != null) { + // + // Numeric promotion upgraded types to int but for enum constant + // original underlying constant type is needed + // + if (res.Type.BuiltinType == BuiltinTypeSpec.Type.Int) { + int v = ((IntConstant) res).Value; + switch (((EnumConstant) e).Child.Type.BuiltinType) { + case BuiltinTypeSpec.Type.UShort: + res = new UShortConstant (ec.BuiltinTypes, (ushort) v, e.Location); + break; + case BuiltinTypeSpec.Type.Short: + res = new ShortConstant (ec.BuiltinTypes, (short) v, e.Location); + break; + case BuiltinTypeSpec.Type.Byte: + res = new ByteConstant (ec.BuiltinTypes, (byte) v, e.Location); + break; + case BuiltinTypeSpec.Type.SByte: + res = new SByteConstant (ec.BuiltinTypes, (sbyte) v, e.Location); + break; + } + } + + res = new EnumConstant (res, expr_type); + } + return res; } return null; } @@ -572,6 +600,31 @@ namespace Mono.CSharp Expr.EmitSideEffect (ec); } + public static void Error_Ambiguous (ResolveContext rc, string oper, TypeSpec type, Location loc) + { + rc.Report.Error (35, loc, "Operator `{0}' is ambiguous on an operand of type `{1}'", + oper, type.GetSignatureForError ()); + } + + public override void FlowAnalysis (FlowAnalysisContext fc) + { + if (Oper == Operator.AddressOf) { + var vr = Expr as VariableReference; + if (vr != null && vr.VariableInfo != null) + fc.SetVariableAssigned (vr.VariableInfo); + + return; + } + + Expr.FlowAnalysis (fc); + + if (Oper == Operator.LogicalNot) { + var temp = fc.DefiniteAssignmentOnTrue; + fc.DefiniteAssignmentOnTrue = fc.DefiniteAssignmentOnFalse; + fc.DefiniteAssignmentOnFalse = temp; + } + } + // // Converts operator to System.Linq.Expressions.ExpressionType enum name // @@ -627,7 +680,7 @@ namespace Mono.CSharp return is_checked ? SLE.Expression.NegateChecked (expr) : SLE.Expression.Negate (expr); case Operator.LogicalNot: return SLE.Expression.Not (expr); -#if NET_4_0 || MONODROID +#if NET_4_0 || MOBILE_DYNAMIC case Operator.OnesComplement: return SLE.Expression.OnesComplement (expr); #endif @@ -757,8 +810,7 @@ namespace Mono.CSharp int result = OverloadResolver.BetterTypeConversion (ec, best_expr.Type, t); if (result == 0) { if ((oper_expr is UserOperatorCall || oper_expr is UserCast) && (best_expr is UserOperatorCall || best_expr is UserCast)) { - ec.Report.Error (35, loc, "Operator `{0}' is ambiguous on an operand of type `{1}'", - OperName (Oper), expr.Type.GetSignatureForError ()); + Error_Ambiguous (ec, OperName (Oper), expr.Type, loc); } else { Error_OperatorCannotBeApplied (ec, loc, OperName (Oper), expr.Type); } @@ -824,6 +876,12 @@ namespace Mono.CSharp get { return true; } } + public override Location StartLocation { + get { + return expr.StartLocation; + } + } + protected override void CloneTo (CloneContext clonectx, Expression t) { Indirection target = (Indirection) t; @@ -1043,6 +1101,12 @@ namespace Mono.CSharp } } + public override Location StartLocation { + get { + return (mode & Mode.IsPost) != 0 ? expr.Location : loc; + } + } + public override bool ContainsEmitWithAwait () { return expr.ContainsEmitWithAwait (); @@ -1187,14 +1251,33 @@ namespace Mono.CSharp source = operation; } else { + Expression best_source = null; foreach (var t in ec.BuiltinTypes.OperatorsUnaryMutator) { source = Convert.ImplicitUserConversion (ec, operation, t, loc); // LAMESPEC: It should error on ambiguous operators but that would make us incompatible - if (source != null) { - break; + if (source == null) + continue; + + if (best_source == null) { + best_source = source; + continue; + } + + var better = OverloadResolver.BetterTypeConversion (ec, best_source.Type, source.Type); + if (better == 1) + continue; + + if (better == 2) { + best_source = source; + continue; } + + Unary.Error_Ambiguous (ec, OperName (mode), type, loc); + break; } + + source = best_source; } // ++/-- on enum types @@ -1262,6 +1345,11 @@ namespace Mono.CSharp EmitCode (ec, false); } + public override void FlowAnalysis (FlowAnalysisContext fc) + { + expr.FlowAnalysis (fc); + } + // // Converts operator to System.Linq.Expressions.ExpressionType enum name // @@ -1275,7 +1363,7 @@ namespace Mono.CSharp } -#if NET_4_0 || MONODROID +#if NET_4_0 || MOBILE_DYNAMIC public override SLE.Expression MakeExpression (BuilderContext ctx) { var target = ((RuntimeValueExpression) expr).MetaObject.Expression; @@ -1284,6 +1372,11 @@ namespace Mono.CSharp } #endif + public static string OperName (Mode oper) + { + return (oper & Mode.IsDecrement) != 0 ? "--" : "++"; + } + protected override void CloneTo (CloneContext clonectx, Expression t) { UnaryMutator target = (UnaryMutator) t; @@ -1307,7 +1400,7 @@ namespace Mono.CSharp protected Expression expr; protected TypeSpec probe_type_expr; - public Probe (Expression expr, Expression probe_type, Location l) + protected Probe (Expression expr, Expression probe_type, Location l) { ProbeType = probe_type; loc = l; @@ -1336,8 +1429,9 @@ namespace Mono.CSharp return null; if (probe_type_expr.IsStatic) { - ec.Report.Error (-244, loc, "The `{0}' operator cannot be applied to an operand of a static type", - OperatorName); + ec.Report.Error (7023, loc, "The second operand of `is' or `as' operator cannot be static type `{0}'", + probe_type_expr.GetSignatureForError ()); + return null; } if (expr.Type.IsPointer || probe_type_expr.IsPointer) { @@ -1355,6 +1449,16 @@ namespace Mono.CSharp return this; } + public override void EmitSideEffect (EmitContext ec) + { + expr.EmitSideEffect (ec); + } + + public override void FlowAnalysis (FlowAnalysisContext fc) + { + expr.FlowAnalysis (fc); + } + protected abstract string OperatorName { get; } protected override void CloneTo (CloneContext clonectx, Expression t) @@ -1420,17 +1524,20 @@ namespace Mono.CSharp } ec.Emit (on_true ? OpCodes.Brtrue : OpCodes.Brfalse, target); } - - Expression CreateConstantResult (ResolveContext ec, bool result) + + Expression CreateConstantResult (ResolveContext rc, bool result) { if (result) - ec.Report.Warning (183, 1, loc, "The given expression is always of the provided (`{0}') type", - TypeManager.CSharpName (probe_type_expr)); + rc.Report.Warning (183, 1, loc, "The given expression is always of the provided (`{0}') type", + probe_type_expr.GetSignatureForError ()); else - ec.Report.Warning (184, 1, loc, "The given expression is never of the provided (`{0}') type", - TypeManager.CSharpName (probe_type_expr)); + rc.Report.Warning (184, 1, loc, "The given expression is never of the provided (`{0}') type", + probe_type_expr.GetSignatureForError ()); - return ReducedExpression.Create (new BoolConstant (ec.BuiltinTypes, result, loc), this); + var c = new BoolConstant (rc.BuiltinTypes, result, loc); + return expr.IsSideEffectFree ? + ReducedExpression.Create (c, this) : + new SideEffectConstant (c, this, loc); } protected override Expression DoResolve (ResolveContext ec) @@ -1493,9 +1600,16 @@ namespace Mono.CSharp // if (Convert.ExplicitReferenceConversionExists (d, t)) return this; + + // + // open generic type + // + if (d is InflatedTypeSpec && InflatedTypeSpec.ContainsTypeParameter (d)) + return this; } else { - if (TypeManager.IsGenericParameter (t)) - return ResolveGenericParameter (ec, d, (TypeParameterSpec) t); + var tps = t as TypeParameterSpec; + if (tps != null) + return ResolveGenericParameter (ec, d, tps); if (t.BuiltinType == BuiltinTypeSpec.Type.Dynamic) { ec.Report.Warning (1981, 3, loc, @@ -1517,10 +1631,19 @@ namespace Mono.CSharp } } else { if (Convert.ImplicitReferenceConversionExists (d, t)) { + var c = expr as Constant; + if (c != null) + return CreateConstantResult (ec, !c.IsNull); + // - // Do not optimize for imported type + // Do not optimize for imported type or dynamic type // - if (d.MemberDefinition.IsImported && d.BuiltinType != BuiltinTypeSpec.Type.None) + if (d.MemberDefinition.IsImported && d.BuiltinType != BuiltinTypeSpec.Type.None && + d.MemberDefinition.DeclaringAssembly != t.MemberDefinition.DeclaringAssembly) { + return this; + } + + if (d.BuiltinType == BuiltinTypeSpec.Type.Dynamic) return this; // @@ -1531,9 +1654,14 @@ namespace Mono.CSharp this).Resolve (ec); } - if (Convert.ExplicitReferenceConversionExists (d, t)) { + if (Convert.ExplicitReferenceConversionExists (d, t)) + return this; + + // + // open generic type + // + if ((d is InflatedTypeSpec || d.IsArray) && InflatedTypeSpec.ContainsTypeParameter (d)) return this; - } } } @@ -1547,8 +1675,8 @@ namespace Mono.CSharp return CreateConstantResult (ec, false); } - if (TypeManager.IsGenericParameter (expr.Type)) { - if (expr.Type == d && TypeSpec.IsValueType (t)) + if (expr.Type.IsGenericParameter) { + if (expr.Type == d && TypeSpec.IsValueType (t) && TypeSpec.IsValueType (d)) return CreateConstantResult (ec, true); expr = new BoxedCast (expr, d); @@ -1618,7 +1746,7 @@ namespace Mono.CSharp } else { ec.Report.Error (77, loc, "The `as' operator cannot be used with a non-nullable value type `{0}'", - TypeManager.CSharpName (type)); + type.GetSignatureForError ()); } return null; } @@ -1650,8 +1778,10 @@ namespace Mono.CSharp return this; } - ec.Report.Error (39, loc, "Cannot convert type `{0}' to `{1}' via a built-in conversion", - TypeManager.CSharpName (etype), TypeManager.CSharpName (type)); + if (etype != InternalType.ErrorType) { + ec.Report.Error (39, loc, "Cannot convert type `{0}' to `{1}' via a built-in conversion", + etype.GetSignatureForError (), type.GetSignatureForError ()); + } return null; } @@ -1690,7 +1820,7 @@ namespace Mono.CSharp return null; if (type.IsStatic) { - ec.Report.Error (716, loc, "Cannot convert to static type `{0}'", TypeManager.CSharpName (type)); + ec.Report.Error (716, loc, "Cannot convert to static type `{0}'", type.GetSignatureForError ()); return null; } @@ -1702,7 +1832,7 @@ namespace Mono.CSharp Constant c = expr as Constant; if (c != null) { - c = c.TryReduce (ec, type); + c = c.Reduce (ec, type); if (c != null) return c; } @@ -1827,7 +1957,7 @@ namespace Mono.CSharp temp_storage.Release (ec); } -#if (NET_4_0 || MONODROID) && !STATIC +#if (NET_4_0 || MOBILE_DYNAMIC) && !STATIC public override SLE.Expression MakeExpression (BuilderContext ctx) { return SLE.Expression.Default (type.GetMetaInfo ()); @@ -1856,6 +1986,8 @@ namespace Mono.CSharp { protected readonly TypeSpec left; protected readonly TypeSpec right; + protected readonly TypeSpec left_unwrap; + protected readonly TypeSpec right_unwrap; public readonly Operator OperatorsMask; public TypeSpec ReturnType; @@ -1879,45 +2011,213 @@ namespace Mono.CSharp if ((op_mask & Operator.ValuesOnlyMask) != 0) throw new InternalErrorException ("Only masked values can be used"); + if ((op_mask & Operator.NullableMask) != 0) { + left_unwrap = Nullable.NullableInfo.GetUnderlyingType (ltype); + right_unwrap = Nullable.NullableInfo.GetUnderlyingType (rtype); + } else { + left_unwrap = ltype; + right_unwrap = rtype; + } + this.left = ltype; this.right = rtype; this.OperatorsMask = op_mask; this.ReturnType = return_type; } - public virtual Expression ConvertResult (ResolveContext ec, Binary b) + public bool IsLifted { + get { + return (OperatorsMask & Operator.NullableMask) != 0; + } + } + + public virtual Expression ConvertResult (ResolveContext rc, Binary b) { + Constant c; + + var left_expr = b.left; + var right_expr = b.right; + b.type = ReturnType; - b.left = Convert.ImplicitConversion (ec, b.left, left, b.left.Location); - b.right = Convert.ImplicitConversion (ec, b.right, right, b.right.Location); + if (IsLifted) { + if (rc.HasSet (ResolveContext.Options.ExpressionTreeConversion)) { + b.left = Convert.ImplicitConversion (rc, b.left, left, b.left.Location); + b.right = Convert.ImplicitConversion (rc, b.right, right, b.right.Location); + } + + if (right_expr.IsNull) { + if ((b.oper & Operator.EqualityMask) != 0) { + if (!left_expr.Type.IsNullableType && BuiltinTypeSpec.IsPrimitiveType (left_expr.Type)) + return b.CreateLiftedValueTypeResult (rc, left_expr.Type); + } else if ((b.oper & Operator.BitwiseMask) != 0) { + if (left_unwrap.BuiltinType != BuiltinTypeSpec.Type.Bool) + return Nullable.LiftedNull.CreateFromExpression (rc, b); + } else { + b.left = Convert.ImplicitConversion (rc, b.left, left, b.left.Location); + b.right = Convert.ImplicitConversion (rc, b.right, right, b.right.Location); + + if ((b.Oper & (Operator.ArithmeticMask | Operator.ShiftMask)) != 0) + return Nullable.LiftedNull.CreateFromExpression (rc, b); + + return b.CreateLiftedValueTypeResult (rc, left); + } + } else if (left_expr.IsNull) { + if ((b.oper & Operator.EqualityMask) != 0) { + if (!right_expr.Type.IsNullableType && BuiltinTypeSpec.IsPrimitiveType (right_expr.Type)) + return b.CreateLiftedValueTypeResult (rc, right_expr.Type); + } else if ((b.oper & Operator.BitwiseMask) != 0) { + if (right_unwrap.BuiltinType != BuiltinTypeSpec.Type.Bool) + return Nullable.LiftedNull.CreateFromExpression (rc, b); + } else { + b.left = Convert.ImplicitConversion (rc, b.left, left, b.left.Location); + b.right = Convert.ImplicitConversion (rc, b.right, right, b.right.Location); + + if ((b.Oper & (Operator.ArithmeticMask | Operator.ShiftMask)) != 0) + return Nullable.LiftedNull.CreateFromExpression (rc, b); + + return b.CreateLiftedValueTypeResult (rc, right); + } + } + } // // A user operators does not support multiple user conversions, but decimal type // is considered to be predefined type therefore we apply predefined operators rules // and then look for decimal user-operator implementation // - if (left.BuiltinType == BuiltinTypeSpec.Type.Decimal) - return b.ResolveUserOperator (ec, b.left, b.right); + if (left.BuiltinType == BuiltinTypeSpec.Type.Decimal) { + b.left = Convert.ImplicitConversion (rc, b.left, left, b.left.Location); + b.right = Convert.ImplicitConversion (rc, b.right, right, b.right.Location); + + return b.ResolveUserOperator (rc, b.left, b.right); + } - var c = b.right as Constant; + c = right_expr as Constant; if (c != null) { - if (c.IsDefaultValue && (b.oper == Operator.Addition || b.oper == Operator.Subtraction || (b.oper == Operator.BitwiseOr && !(b is Nullable.LiftedBinaryOperator)))) - return ReducedExpression.Create (b.left, b).Resolve (ec); + if (c.IsDefaultValue) { + // + // Optimizes + // + // (expr + 0) to expr + // (expr - 0) to expr + // (bool? | false) to bool? + // + if (b.oper == Operator.Addition || b.oper == Operator.Subtraction || + (b.oper == Operator.BitwiseOr && left_unwrap.BuiltinType == BuiltinTypeSpec.Type.Bool && c is BoolConstant)) { + b.left = Convert.ImplicitConversion (rc, b.left, left, b.left.Location); + return ReducedExpression.Create (b.left, b).Resolve (rc); + } + + // + // Optimizes (value &/&& 0) to 0 + // + if ((b.oper == Operator.BitwiseAnd || b.oper == Operator.LogicalAnd) && !IsLifted) { + Constant side_effect = new SideEffectConstant (c, b.left, c.Location); + return ReducedExpression.Create (side_effect, b); + } + } else { + // + // Optimizes (bool? & true) to bool? + // + if (IsLifted && left_unwrap.BuiltinType == BuiltinTypeSpec.Type.Bool && b.oper == Operator.BitwiseAnd) { + return ReducedExpression.Create (b.left, b).Resolve (rc); + } + } + if ((b.oper == Operator.Multiply || b.oper == Operator.Division) && c.IsOneInteger) - return ReducedExpression.Create (b.left, b).Resolve (ec); - return b; + return ReducedExpression.Create (b.left, b).Resolve (rc); + + if ((b.oper & Operator.ShiftMask) != 0 && c is IntConstant) { + b.right = new IntConstant (rc.BuiltinTypes, ((IntConstant) c).Value & GetShiftMask (left_unwrap), b.right.Location); + } } c = b.left as Constant; if (c != null) { - if (c.IsDefaultValue && (b.oper == Operator.Addition || (b.oper == Operator.BitwiseOr && !(b is Nullable.LiftedBinaryOperator)))) - return ReducedExpression.Create (b.right, b).Resolve (ec); + if (c.IsDefaultValue) { + // + // Optimizes + // + // (0 + expr) to expr + // (false | bool?) to bool? + // + if (b.oper == Operator.Addition || + (b.oper == Operator.BitwiseOr && right_unwrap.BuiltinType == BuiltinTypeSpec.Type.Bool && c is BoolConstant)) { + b.right = Convert.ImplicitConversion (rc, b.right, right, b.right.Location); + return ReducedExpression.Create (b.right, b).Resolve (rc); + } + + // + // Optimizes (false && expr) to false + // + if (b.oper == Operator.LogicalAnd && c.Type.BuiltinType == BuiltinTypeSpec.Type.Bool) { + // No rhs side-effects + Expression.Warning_UnreachableExpression (rc, b.right.StartLocation); + return ReducedExpression.Create (c, b); + } + + // + // Optimizes (0 & value) to 0 + // + if (b.oper == Operator.BitwiseAnd && !IsLifted) { + Constant side_effect = new SideEffectConstant (c, b.right, c.Location); + return ReducedExpression.Create (side_effect, b); + } + } else { + // + // Optimizes (true & bool?) to bool? + // + if (IsLifted && left_unwrap.BuiltinType == BuiltinTypeSpec.Type.Bool && b.oper == Operator.BitwiseAnd) { + return ReducedExpression.Create (b.right, b).Resolve (rc); + } + + // + // Optimizes (true || expr) to true + // + if (b.oper == Operator.LogicalOr && c.Type.BuiltinType == BuiltinTypeSpec.Type.Bool) { + // No rhs side-effects + Expression.Warning_UnreachableExpression (rc, b.right.StartLocation); + return ReducedExpression.Create (c, b); + } + } + if (b.oper == Operator.Multiply && c.IsOneInteger) - return ReducedExpression.Create (b.right, b).Resolve (ec); - return b; + return ReducedExpression.Create (b.right, b).Resolve (rc); + } + + if (IsLifted) { + var lifted = new Nullable.LiftedBinaryOperator (b); + + TypeSpec ltype, rtype; + if (b.left.Type.IsNullableType) { + lifted.UnwrapLeft = new Nullable.Unwrap (b.left); + ltype = left_unwrap; + } else { + ltype = left; + } + + if (b.right.Type.IsNullableType) { + lifted.UnwrapRight = new Nullable.Unwrap (b.right); + rtype = right_unwrap; + } else { + rtype = right; + } + + lifted.Left = b.left.IsNull ? + b.left : + Convert.ImplicitConversion (rc, lifted.UnwrapLeft ?? b.left, ltype, b.left.Location); + + lifted.Right = b.right.IsNull ? + b.right : + Convert.ImplicitConversion (rc, lifted.UnwrapRight ?? b.right, rtype, b.right.Location); + + return lifted.Resolve (rc); } + b.left = Convert.ImplicitConversion (rc, b.left, left, b.left.Location); + b.right = Convert.ImplicitConversion (rc, b.right, right, b.right.Location); + return b; } @@ -1941,16 +2241,22 @@ namespace Mono.CSharp public PredefinedOperator ResolveBetterOperator (ResolveContext ec, PredefinedOperator best_operator) { + if ((OperatorsMask & Operator.DecomposedMask) != 0) + return best_operator; + + if ((best_operator.OperatorsMask & Operator.DecomposedMask) != 0) + return this; + int result = 0; if (left != null && best_operator.left != null) { - result = OverloadResolver.BetterTypeConversion (ec, best_operator.left, left); + result = OverloadResolver.BetterTypeConversion (ec, best_operator.left_unwrap, left_unwrap); } // // When second argument is same as the first one, the result is same // if (right != null && (left != right || best_operator.left != best_operator.right)) { - result |= OverloadResolver.BetterTypeConversion (ec, best_operator.right, right); + result |= OverloadResolver.BetterTypeConversion (ec, best_operator.right_unwrap, right_unwrap); } if (result == 0 || result > 2) @@ -1995,44 +2301,6 @@ namespace Mono.CSharp } } - sealed class PredefinedShiftOperator : PredefinedOperator - { - public PredefinedShiftOperator (TypeSpec ltype, TypeSpec rtype, Operator op_mask) - : base (ltype, rtype, op_mask) - { - } - - public override Expression ConvertResult (ResolveContext ec, Binary b) - { - b.left = Convert.ImplicitConversion (ec, b.left, left, b.left.Location); - - Expression expr_tree_expr = Convert.ImplicitConversion (ec, b.right, right, b.right.Location); - - int right_mask = left.BuiltinType == BuiltinTypeSpec.Type.Int || left.BuiltinType == BuiltinTypeSpec.Type.UInt ? 0x1f : 0x3f; - - // - // b = b.left >> b.right & (0x1f|0x3f) - // - b.right = new Binary (Operator.BitwiseAnd, - b.right, new IntConstant (ec.BuiltinTypes, right_mask, b.right.Location)).Resolve (ec); - - // - // Expression tree representation does not use & mask - // - b.right = ReducedExpression.Create (b.right, expr_tree_expr).Resolve (ec); - b.type = ReturnType; - - // - // Optimize shift by 0 - // - var c = b.right as Constant; - if (c != null && c.IsDefaultValue) - return ReducedExpression.Create (b.left, b).Resolve (ec); - - return b; - } - } - sealed class PredefinedEqualityOperator : PredefinedOperator { MethodSpec equal_method, inequal_method; @@ -2186,21 +2454,23 @@ namespace Mono.CSharp LogicalMask = 1 << 10, AdditionMask = 1 << 11, SubtractionMask = 1 << 12, - RelationalMask = 1 << 13 + RelationalMask = 1 << 13, + + DecomposedMask = 1 << 19, + NullableMask = 1 << 20, } - protected enum State + [Flags] + enum State : byte { None = 0, Compound = 1 << 1, - LeftNullLifted = 1 << 2, - RightNullLifted = 1 << 3 } readonly Operator oper; - protected Expression left, right; - protected State state; - Expression enum_conversion; + Expression left, right; + State state; + ConvCast.Mode enum_conversion; public Binary (Operator oper, Expression left, Expression right, bool isCompound) : this (oper, left, right) @@ -2243,6 +2513,12 @@ namespace Mono.CSharp } } + public override Location StartLocation { + get { + return left.StartLocation; + } + } + #endregion /// @@ -2328,18 +2604,63 @@ namespace Mono.CSharp return; string l, r; - l = TypeManager.CSharpName (left.Type); - r = TypeManager.CSharpName (right.Type); + l = left.Type.GetSignatureForError (); + r = right.Type.GetSignatureForError (); ec.Report.Error (19, loc, "Operator `{0}' cannot be applied to operands of type `{1}' and `{2}'", oper, l, r); } - protected void Error_OperatorCannotBeApplied (ResolveContext ec, Expression left, Expression right) + void Error_OperatorCannotBeApplied (ResolveContext ec, Expression left, Expression right) { Error_OperatorCannotBeApplied (ec, left, right, OperName (oper), loc); } + public override void FlowAnalysis (FlowAnalysisContext fc) + { + if ((oper & Operator.LogicalMask) == 0) { + fc.DefiniteAssignmentOnTrue = fc.DefiniteAssignmentOnFalse = fc.DefiniteAssignment; + left.FlowAnalysis (fc); + fc.DefiniteAssignmentOnTrue = fc.DefiniteAssignmentOnFalse = fc.DefiniteAssignment; + right.FlowAnalysis (fc); + return; + } + + // + // Optimized version when on-true/on-false data are not needed + // + bool set_on_true_false; + if (fc.DefiniteAssignmentOnTrue == null && fc.DefiniteAssignmentOnFalse == null) { + fc.DefiniteAssignmentOnFalse = fc.DefiniteAssignmentOnTrue = fc.DefiniteAssignment; + set_on_true_false = false; + } else { + set_on_true_false = true; + } + + left.FlowAnalysis (fc); + var left_fc = fc.DefiniteAssignment; + var left_fc_ontrue = fc.DefiniteAssignmentOnTrue; + var left_fc_onfalse = fc.DefiniteAssignmentOnFalse; + + fc.DefiniteAssignmentOnTrue = fc.DefiniteAssignmentOnFalse = fc.DefiniteAssignment = new DefiniteAssignmentBitSet ( + oper == Operator.LogicalOr ? left_fc_onfalse : left_fc_ontrue); + right.FlowAnalysis (fc); + fc.DefiniteAssignment = left_fc; + + if (!set_on_true_false) { + fc.DefiniteAssignmentOnFalse = fc.DefiniteAssignmentOnTrue = null; + return; + } + + if (oper == Operator.LogicalOr) { + fc.DefiniteAssignmentOnTrue = new DefiniteAssignmentBitSet (left_fc_ontrue); + fc.DefiniteAssignmentOnFalse = left_fc_onfalse | fc.DefiniteAssignmentOnFalse; + } else { + fc.DefiniteAssignmentOnTrue = left_fc_ontrue | fc.DefiniteAssignmentOnTrue; + fc.DefiniteAssignmentOnFalse = new DefiniteAssignmentBitSet (left_fc_onfalse); + } + } + // // Converts operator to System.Linq.Expressions.ExpressionType enum name // @@ -2434,7 +2755,7 @@ namespace Mono.CSharp return left.ContainsEmitWithAwait () || right.ContainsEmitWithAwait (); } - public static void EmitOperatorOpcode (EmitContext ec, Operator oper, TypeSpec l) + public static void EmitOperatorOpcode (EmitContext ec, Operator oper, TypeSpec l, Expression right) { OpCode opcode; @@ -2491,6 +2812,11 @@ namespace Mono.CSharp break; case Operator.RightShift: + if (!(right is IntConstant)) { + ec.EmitInt (GetShiftMask (l)); + ec.Emit (OpCodes.And); + } + if (IsUnsigned (l)) opcode = OpCodes.Shr_Un; else @@ -2498,6 +2824,11 @@ namespace Mono.CSharp break; case Operator.LeftShift: + if (!(right is IntConstant)) { + ec.EmitInt (GetShiftMask (l)); + ec.Emit (OpCodes.And); + } + opcode = OpCodes.Shl; break; @@ -2566,6 +2897,11 @@ namespace Mono.CSharp ec.Emit (opcode); } + static int GetShiftMask (TypeSpec type) + { + return type.BuiltinType == BuiltinTypeSpec.Type.Int || type.BuiltinType == BuiltinTypeSpec.Type.UInt ? 0x1f : 0x3f; + } + static bool IsUnsigned (TypeSpec t) { switch (t.BuiltinType) { @@ -2585,8 +2921,10 @@ namespace Mono.CSharp return t.BuiltinType == BuiltinTypeSpec.Type.Float || t.BuiltinType == BuiltinTypeSpec.Type.Double; } - Expression ResolveOperator (ResolveContext ec) + public Expression ResolveOperator (ResolveContext rc) { + eclass = ExprClass.Value; + TypeSpec l = left.Type; TypeSpec r = right.Type; Expression expr; @@ -2595,57 +2933,109 @@ namespace Mono.CSharp // // Handles predefined primitive types // - if (BuiltinTypeSpec.IsPrimitiveType (l) && BuiltinTypeSpec.IsPrimitiveType (r)) { + if ((BuiltinTypeSpec.IsPrimitiveType (l) || (l.IsNullableType && BuiltinTypeSpec.IsPrimitiveType (Nullable.NullableInfo.GetUnderlyingType (l)))) && + (BuiltinTypeSpec.IsPrimitiveType (r) || (r.IsNullableType && BuiltinTypeSpec.IsPrimitiveType (Nullable.NullableInfo.GetUnderlyingType (r))))) { if ((oper & Operator.ShiftMask) == 0) { - if (l.BuiltinType != BuiltinTypeSpec.Type.Bool && !DoBinaryOperatorPromotion (ec)) + if (!DoBinaryOperatorPromotion (rc)) return null; - primitives_only = true; + primitives_only = BuiltinTypeSpec.IsPrimitiveType (l) && BuiltinTypeSpec.IsPrimitiveType (r); } } else { // Pointers if (l.IsPointer || r.IsPointer) - return ResolveOperatorPointer (ec, l, r); + return ResolveOperatorPointer (rc, l, r); + + // User operators + expr = ResolveUserOperator (rc, left, right); + if (expr != null) + return expr; + - // Enums bool lenum = l.IsEnum; bool renum = r.IsEnum; - if (lenum || renum) { - expr = ResolveOperatorEnum (ec, lenum, renum, l, r); + if ((oper & (Operator.ComparisonMask | Operator.BitwiseMask)) != 0) { + // + // Enumerations + // + if (IsEnumOrNullableEnum (l) || IsEnumOrNullableEnum (r)) { + expr = ResolveSingleEnumOperators (rc, lenum, renum, l, r); - if (expr != null) - return expr; - } + if (expr == null) + return null; - // Delegates - if ((oper == Operator.Addition || oper == Operator.Subtraction) && (l.IsDelegate || r.IsDelegate)) { - - expr = ResolveOperatorDelegate (ec, l, r); + if ((oper & Operator.BitwiseMask) != 0) { + expr = EmptyCast.Create (expr, type); + AddEnumResultCast (type); - // TODO: Can this be ambiguous - if (expr != null) + if (oper == Operator.BitwiseAnd && left.Type.IsEnum && right.Type.IsEnum) { + expr = OptimizeAndOperation (expr); + } + } + + left = ConvertEnumOperandToUnderlyingType (rc, left, r.IsNullableType); + right = ConvertEnumOperandToUnderlyingType (rc, right, l.IsNullableType); return expr; - } + } + } else if ((oper == Operator.Addition || oper == Operator.Subtraction)) { + if (IsEnumOrNullableEnum (l) || IsEnumOrNullableEnum (r)) { + // + // Enumerations + // + expr = ResolveEnumOperators (rc, lenum, renum, l, r); - // User operators - expr = ResolveUserOperator (ec, left, right); - if (expr != null) - return expr; + // + // We cannot break here there is also Enum + String possible match + // which is not ambiguous with predefined enum operators + // + if (expr != null) { + left = ConvertEnumOperandToUnderlyingType (rc, left, false); + right = ConvertEnumOperandToUnderlyingType (rc, right, false); - // Predefined reference types equality - if ((oper & Operator.EqualityMask) != 0) { - expr = ResolveOperatorEquality (ec, l, r); - if (expr != null) - return expr; + return expr; + } + } else if (l.IsDelegate || r.IsDelegate) { + // + // Delegates + // + expr = ResolveOperatorDelegate (rc, l, r); + + // TODO: Can this be ambiguous + if (expr != null) + return expr; + } } } + + // + // Equality operators are more complicated + // + if ((oper & Operator.EqualityMask) != 0) { + return ResolveEquality (rc, l, r, primitives_only); + } + + expr = ResolveOperatorPredefined (rc, rc.BuiltinTypes.OperatorsBinaryStandard, primitives_only); + if (expr != null) + return expr; + + if (primitives_only) + return null; + + // + // Lifted operators have lower priority + // + return ResolveOperatorPredefined (rc, rc.Module.OperatorsBinaryLifted, false); + } - return ResolveOperatorPredefined (ec, ec.BuiltinTypes.OperatorsBinaryStandard, primitives_only, null); + static bool IsEnumOrNullableEnum (TypeSpec type) + { + return type.IsEnum || (type.IsNullableType && Nullable.NullableInfo.GetUnderlyingType (type).IsEnum); } + // at least one of 'left' or 'right' is an enumeration constant (EnumConstant or SideEffectConstant or ...) // if 'left' is not an enumeration constant, create one from the type of 'right' - Constant EnumLiftUp (ResolveContext ec, Constant left, Constant right, Location loc) + Constant EnumLiftUp (ResolveContext ec, Constant left, Constant right) { switch (oper) { case Operator.BitwiseOr: @@ -2661,7 +3051,7 @@ namespace Mono.CSharp return left; if (left.IsZeroInteger) - return left.TryReduce (ec, right.Type); + return left.Reduce (ec, right.Type); break; @@ -2704,9 +3094,10 @@ namespace Mono.CSharp // FIXME: consider constants + var ltype = lcast != null ? lcast.UnderlyingType : rcast.UnderlyingType; ec.Report.Warning (675, 3, loc, "The operator `|' used on the sign-extended type `{0}'. Consider casting to a smaller unsigned type first", - TypeManager.CSharpName (lcast != null ? lcast.UnderlyingType : rcast.UnderlyingType)); + ltype.GetSignatureForError ()); } public static PredefinedOperator[] CreatePointerOperatorsTable (BuiltinTypes types) @@ -2746,8 +3137,9 @@ namespace Mono.CSharp public static PredefinedOperator[] CreateStandardOperatorsTable (BuiltinTypes types) { TypeSpec bool_type = types.Bool; - return new PredefinedOperator[] { - new PredefinedOperator (types.Int, Operator.ArithmeticMask | Operator.BitwiseMask), + + return new [] { + new PredefinedOperator (types.Int, Operator.ArithmeticMask | Operator.BitwiseMask | Operator.ShiftMask), new PredefinedOperator (types.UInt, Operator.ArithmeticMask | Operator.BitwiseMask), new PredefinedOperator (types.Long, Operator.ArithmeticMask | Operator.BitwiseMask), new PredefinedOperator (types.ULong, Operator.ArithmeticMask | Operator.BitwiseMask), @@ -2764,15 +3156,64 @@ namespace Mono.CSharp new PredefinedOperator (types.Decimal, Operator.ComparisonMask, bool_type), new PredefinedStringOperator (types.String, Operator.AdditionMask, types.String), - new PredefinedStringOperator (types.String, types.Object, Operator.AdditionMask, types.String), - new PredefinedStringOperator (types.Object, types.String, Operator.AdditionMask, types.String), + // Remaining string operators are in lifted tables new PredefinedOperator (bool_type, Operator.BitwiseMask | Operator.LogicalMask | Operator.EqualityMask, bool_type), - new PredefinedShiftOperator (types.Int, types.Int, Operator.ShiftMask), - new PredefinedShiftOperator (types.UInt, types.Int, Operator.ShiftMask), - new PredefinedShiftOperator (types.Long, types.Int, Operator.ShiftMask), - new PredefinedShiftOperator (types.ULong, types.Int, Operator.ShiftMask) + new PredefinedOperator (types.UInt, types.Int, Operator.ShiftMask), + new PredefinedOperator (types.Long, types.Int, Operator.ShiftMask), + new PredefinedOperator (types.ULong, types.Int, Operator.ShiftMask) + }; + + } + public static PredefinedOperator[] CreateStandardLiftedOperatorsTable (ModuleContainer module) + { + var nullable = module.PredefinedTypes.Nullable.TypeSpec; + if (nullable == null) + return new PredefinedOperator [0]; + + var types = module.Compiler.BuiltinTypes; + var bool_type = types.Bool; + + var nullable_bool = nullable.MakeGenericType (module, new[] { bool_type }); + var nullable_int = nullable.MakeGenericType (module, new[] { types.Int }); + var nullable_uint = nullable.MakeGenericType (module, new[] { types.UInt }); + var nullable_long = nullable.MakeGenericType (module, new[] { types.Long }); + var nullable_ulong = nullable.MakeGenericType (module, new[] { types.ULong }); + var nullable_float = nullable.MakeGenericType (module, new[] { types.Float }); + var nullable_double = nullable.MakeGenericType (module, new[] { types.Double }); + var nullable_decimal = nullable.MakeGenericType (module, new[] { types.Decimal }); + + return new[] { + new PredefinedOperator (nullable_int, Operator.NullableMask | Operator.ArithmeticMask | Operator.BitwiseMask | Operator.ShiftMask), + new PredefinedOperator (nullable_uint, Operator.NullableMask | Operator.ArithmeticMask | Operator.BitwiseMask), + new PredefinedOperator (nullable_long, Operator.NullableMask | Operator.ArithmeticMask | Operator.BitwiseMask), + new PredefinedOperator (nullable_ulong, Operator.NullableMask | Operator.ArithmeticMask | Operator.BitwiseMask), + new PredefinedOperator (nullable_float, Operator.NullableMask | Operator.ArithmeticMask), + new PredefinedOperator (nullable_double, Operator.NullableMask | Operator.ArithmeticMask), + new PredefinedOperator (nullable_decimal, Operator.NullableMask | Operator.ArithmeticMask), + + new PredefinedOperator (nullable_int, Operator.NullableMask | Operator.ComparisonMask, bool_type), + new PredefinedOperator (nullable_uint, Operator.NullableMask | Operator.ComparisonMask, bool_type), + new PredefinedOperator (nullable_long, Operator.NullableMask | Operator.ComparisonMask, bool_type), + new PredefinedOperator (nullable_ulong, Operator.NullableMask | Operator.ComparisonMask, bool_type), + new PredefinedOperator (nullable_float, Operator.NullableMask | Operator.ComparisonMask, bool_type), + new PredefinedOperator (nullable_double, Operator.NullableMask | Operator.ComparisonMask, bool_type), + new PredefinedOperator (nullable_decimal, Operator.NullableMask | Operator.ComparisonMask, bool_type), + + new PredefinedOperator (nullable_bool, Operator.NullableMask | Operator.BitwiseMask, nullable_bool), + + new PredefinedOperator (nullable_uint, nullable_int, Operator.NullableMask | Operator.ShiftMask), + new PredefinedOperator (nullable_long, nullable_int, Operator.NullableMask | Operator.ShiftMask), + new PredefinedOperator (nullable_ulong, nullable_int, Operator.NullableMask | Operator.ShiftMask), + + // + // Not strictly lifted but need to be in second group otherwise expressions like + // int + null would resolve to +(object, string) instead of +(int?, int?) + // + new PredefinedStringOperator (types.String, types.Object, Operator.AdditionMask, types.String), + new PredefinedStringOperator (types.Object, types.String, Operator.AdditionMask, types.String), + }; } @@ -2780,113 +3221,168 @@ namespace Mono.CSharp { TypeSpec bool_type = types.Bool; - return new PredefinedOperator[] { + return new[] { new PredefinedEqualityOperator (types.String, bool_type), new PredefinedEqualityOperator (types.Delegate, bool_type), - new PredefinedOperator (bool_type, Operator.EqualityMask, bool_type) + new PredefinedOperator (bool_type, Operator.EqualityMask, bool_type), + new PredefinedOperator (types.Int, Operator.EqualityMask, bool_type), + new PredefinedOperator (types.UInt, Operator.EqualityMask, bool_type), + new PredefinedOperator (types.Long, Operator.EqualityMask, bool_type), + new PredefinedOperator (types.ULong, Operator.EqualityMask, bool_type), + new PredefinedOperator (types.Float, Operator.EqualityMask, bool_type), + new PredefinedOperator (types.Double, Operator.EqualityMask, bool_type), + new PredefinedOperator (types.Decimal, Operator.EqualityMask, bool_type), + }; + } + + public static PredefinedOperator[] CreateEqualityLiftedOperatorsTable (ModuleContainer module) + { + var nullable = module.PredefinedTypes.Nullable.TypeSpec; + + if (nullable == null) + return new PredefinedOperator [0]; + + var types = module.Compiler.BuiltinTypes; + var bool_type = types.Bool; + var nullable_bool = nullable.MakeGenericType (module, new [] { bool_type }); + var nullable_int = nullable.MakeGenericType (module, new[] { types.Int }); + var nullable_uint = nullable.MakeGenericType (module, new[] { types.UInt }); + var nullable_long = nullable.MakeGenericType (module, new[] { types.Long }); + var nullable_ulong = nullable.MakeGenericType (module, new[] { types.ULong }); + var nullable_float = nullable.MakeGenericType (module, new[] { types.Float }); + var nullable_double = nullable.MakeGenericType (module, new[] { types.Double }); + var nullable_decimal = nullable.MakeGenericType (module, new[] { types.Decimal }); + + return new [] { + new PredefinedOperator (nullable_bool, Operator.NullableMask | Operator.EqualityMask, bool_type), + new PredefinedOperator (nullable_int, Operator.NullableMask | Operator.EqualityMask, bool_type), + new PredefinedOperator (nullable_uint, Operator.NullableMask | Operator.EqualityMask, bool_type), + new PredefinedOperator (nullable_long, Operator.NullableMask | Operator.EqualityMask, bool_type), + new PredefinedOperator (nullable_ulong, Operator.NullableMask | Operator.EqualityMask, bool_type), + new PredefinedOperator (nullable_float, Operator.NullableMask | Operator.EqualityMask, bool_type), + new PredefinedOperator (nullable_double, Operator.NullableMask | Operator.EqualityMask, bool_type), + new PredefinedOperator (nullable_decimal, Operator.NullableMask | Operator.EqualityMask, bool_type) }; } // - // Rules used during binary numeric promotion + // 7.2.6.2 Binary numeric promotions // - static bool DoNumericPromotion (ResolveContext rc, ref Expression prim_expr, ref Expression second_expr, TypeSpec type) + bool DoBinaryOperatorPromotion (ResolveContext rc) { - Expression temp; + TypeSpec ltype = left.Type; + if (ltype.IsNullableType) { + ltype = Nullable.NullableInfo.GetUnderlyingType (ltype); + } - Constant c = prim_expr as Constant; - if (c != null) { - temp = c.ConvertImplicitly (type); - if (temp != null) { - prim_expr = temp; - return true; - } + // + // This is numeric promotion code only + // + if (ltype.BuiltinType == BuiltinTypeSpec.Type.Bool) + return true; + + TypeSpec rtype = right.Type; + if (rtype.IsNullableType) { + rtype = Nullable.NullableInfo.GetUnderlyingType (rtype); } - if (type.BuiltinType == BuiltinTypeSpec.Type.UInt) { - switch (prim_expr.Type.BuiltinType) { - case BuiltinTypeSpec.Type.Int: - case BuiltinTypeSpec.Type.Short: - case BuiltinTypeSpec.Type.SByte: - case BuiltinTypeSpec.Type.Long: - type = rc.BuiltinTypes.Long; + var lb = ltype.BuiltinType; + var rb = rtype.BuiltinType; + TypeSpec type; + Expression expr; - if (type != second_expr.Type) { - c = second_expr as Constant; - if (c != null) - temp = c.ConvertImplicitly (type); - else - temp = Convert.ImplicitNumericConversion (second_expr, type); - if (temp == null) - return false; - second_expr = temp; - } - break; + if (lb == BuiltinTypeSpec.Type.Decimal || rb == BuiltinTypeSpec.Type.Decimal) { + type = rc.BuiltinTypes.Decimal; + } else if (lb == BuiltinTypeSpec.Type.Double || rb == BuiltinTypeSpec.Type.Double) { + type = rc.BuiltinTypes.Double; + } else if (lb == BuiltinTypeSpec.Type.Float || rb == BuiltinTypeSpec.Type.Float) { + type = rc.BuiltinTypes.Float; + } else if (lb == BuiltinTypeSpec.Type.ULong || rb == BuiltinTypeSpec.Type.ULong) { + type = rc.BuiltinTypes.ULong; + + if (IsSignedType (lb)) { + expr = ConvertSignedConstant (left, type); + if (expr == null) + return false; + left = expr; + } else if (IsSignedType (rb)) { + expr = ConvertSignedConstant (right, type); + if (expr == null) + return false; + right = expr; } - } else if (type.BuiltinType == BuiltinTypeSpec.Type.ULong) { - // - // A compile-time error occurs if the other operand is of type sbyte, short, int, or long - // - switch (type.BuiltinType) { - case BuiltinTypeSpec.Type.Int: - case BuiltinTypeSpec.Type.Long: - case BuiltinTypeSpec.Type.Short: - case BuiltinTypeSpec.Type.SByte: - return false; + + } else if (lb == BuiltinTypeSpec.Type.Long || rb == BuiltinTypeSpec.Type.Long) { + type = rc.BuiltinTypes.Long; + } else if (lb == BuiltinTypeSpec.Type.UInt || rb == BuiltinTypeSpec.Type.UInt) { + type = rc.BuiltinTypes.UInt; + + if (IsSignedType (lb)) { + expr = ConvertSignedConstant (left, type); + if (expr == null) + type = rc.BuiltinTypes.Long; + } else if (IsSignedType (rb)) { + expr = ConvertSignedConstant (right, type); + if (expr == null) + type = rc.BuiltinTypes.Long; } + } else { + type = rc.BuiltinTypes.Int; } - temp = Convert.ImplicitNumericConversion (prim_expr, type); - if (temp == null) - return false; - - prim_expr = temp; - return true; - } + if (ltype != type) { + expr = PromoteExpression (rc, left, type); + if (expr == null) + return false; - // - // 7.2.6.2 Binary numeric promotions - // - public bool DoBinaryOperatorPromotion (ResolveContext ec) - { - TypeSpec ltype = left.Type; - TypeSpec rtype = right.Type; - Expression temp; + left = expr; + } - foreach (TypeSpec t in ec.BuiltinTypes.BinaryPromotionsTypes) { - if (t == ltype) - return t == rtype || DoNumericPromotion (ec, ref right, ref left, t); + if (rtype != type) { + expr = PromoteExpression (rc, right, type); + if (expr == null) + return false; - if (t == rtype) - return t == ltype || DoNumericPromotion (ec, ref left, ref right, t); + right = expr; } - TypeSpec int32 = ec.BuiltinTypes.Int; - if (ltype != int32) { - Constant c = left as Constant; - if (c != null) - temp = c.ConvertImplicitly (int32); - else - temp = Convert.ImplicitNumericConversion (left, int32); + return true; + } - if (temp == null) - return false; - left = temp; + static bool IsSignedType (BuiltinTypeSpec.Type type) + { + switch (type) { + case BuiltinTypeSpec.Type.Int: + case BuiltinTypeSpec.Type.Short: + case BuiltinTypeSpec.Type.SByte: + case BuiltinTypeSpec.Type.Long: + return true; + default: + return false; } + } - if (rtype != int32) { - Constant c = right as Constant; - if (c != null) - temp = c.ConvertImplicitly (int32); - else - temp = Convert.ImplicitNumericConversion (right, int32); + static Expression ConvertSignedConstant (Expression expr, TypeSpec type) + { + var c = expr as Constant; + if (c == null) + return null; - if (temp == null) - return false; - right = temp; + return c.ConvertImplicitly (type); + } + + static Expression PromoteExpression (ResolveContext rc, Expression expr, TypeSpec type) + { + if (expr.Type.IsNullableType) { + return Convert.ImplicitConversionStandard (rc, expr, + rc.Module.PredefinedTypes.Nullable.TypeSpec.MakeGenericType (rc, new[] { type }), expr.Location); } - return true; + var c = expr as Constant; + if (c != null) + return c.ConvertImplicitly (type); + + return Convert.ImplicitNumericConversion (expr, type); } protected override Expression DoResolve (ResolveContext ec) @@ -2910,31 +3406,18 @@ namespace Mono.CSharp if (left == null) return null; - Constant lc = left as Constant; - - if (lc != null && lc.Type.BuiltinType == BuiltinTypeSpec.Type.Bool && - ((oper == Operator.LogicalAnd && lc.IsDefaultValue) || - (oper == Operator.LogicalOr && !lc.IsDefaultValue))) { - - // FIXME: resolve right expression as unreachable - // right.Resolve (ec); - - ec.Report.Warning (429, 4, loc, "Unreachable expression code detected"); - return left; - } - right = right.Resolve (ec); if (right == null) return null; - eclass = ExprClass.Value; + Constant lc = left as Constant; Constant rc = right as Constant; // The conversion rules are ignored in enum context but why if (!ec.HasSet (ResolveContext.Options.EnumScope) && lc != null && rc != null && (left.Type.IsEnum || right.Type.IsEnum)) { - lc = EnumLiftUp (ec, lc, rc, loc); + lc = EnumLiftUp (ec, lc, rc); if (lc != null) - rc = EnumLiftUp (ec, rc, lc, loc); + rc = EnumLiftUp (ec, rc, lc); } if (rc != null && lc != null) { @@ -2953,93 +3436,94 @@ namespace Mono.CSharp CheckOutOfRangeComparison (ec, rc, left.Type); } - if (left.Type.BuiltinType == BuiltinTypeSpec.Type.Dynamic || right.Type.BuiltinType == BuiltinTypeSpec.Type.Dynamic) { - var lt = left.Type; - var rt = right.Type; - if (lt.Kind == MemberKind.Void || lt == InternalType.MethodGroup || lt == InternalType.AnonymousMethod || - rt.Kind == MemberKind.Void || rt == InternalType.MethodGroup || rt == InternalType.AnonymousMethod) { - Error_OperatorCannotBeApplied (ec, left, right); - return null; - } + if (left.Type.BuiltinType == BuiltinTypeSpec.Type.Dynamic || right.Type.BuiltinType == BuiltinTypeSpec.Type.Dynamic) + return DoResolveDynamic (ec); - Arguments args; + return DoResolveCore (ec, left, right); + } - // - // Special handling for logical boolean operators which require rhs not to be - // evaluated based on lhs value - // - if ((oper & Operator.LogicalMask) != 0) { - Expression cond_left, cond_right, expr; + Expression DoResolveDynamic (ResolveContext rc) + { + var lt = left.Type; + var rt = right.Type; + if (lt.Kind == MemberKind.Void || lt == InternalType.MethodGroup || lt == InternalType.AnonymousMethod || + rt.Kind == MemberKind.Void || rt == InternalType.MethodGroup || rt == InternalType.AnonymousMethod) { + Error_OperatorCannotBeApplied (rc, left, right); + return null; + } - args = new Arguments (2); + Arguments args; - if (lt.BuiltinType == BuiltinTypeSpec.Type.Dynamic) { - LocalVariable temp = LocalVariable.CreateCompilerGenerated (lt, ec.CurrentBlock, loc); + // + // Special handling for logical boolean operators which require rhs not to be + // evaluated based on lhs value + // + if ((oper & Operator.LogicalMask) != 0) { + Expression cond_left, cond_right, expr; - var cond_args = new Arguments (1); - cond_args.Add (new Argument (new SimpleAssign (temp.CreateReferenceExpression (ec, loc), left).Resolve (ec))); + args = new Arguments (2); - // - // dynamic && bool => IsFalse (temp = left) ? temp : temp && right; - // dynamic || bool => IsTrue (temp = left) ? temp : temp || right; - // - left = temp.CreateReferenceExpression (ec, loc); - if (oper == Operator.LogicalAnd) { - expr = DynamicUnaryConversion.CreateIsFalse (ec, cond_args, loc); - cond_left = left; - } else { - expr = DynamicUnaryConversion.CreateIsTrue (ec, cond_args, loc); - cond_left = left; - } + if (lt.BuiltinType == BuiltinTypeSpec.Type.Dynamic) { + LocalVariable temp = LocalVariable.CreateCompilerGenerated (lt, rc.CurrentBlock, loc); + + var cond_args = new Arguments (1); + cond_args.Add (new Argument (new SimpleAssign (temp.CreateReferenceExpression (rc, loc), left).Resolve (rc))); - args.Add (new Argument (left)); - args.Add (new Argument (right)); - cond_right = new DynamicExpressionStatement (this, args, loc); + // + // dynamic && bool => IsFalse (temp = left) ? temp : temp && right; + // dynamic || bool => IsTrue (temp = left) ? temp : temp || right; + // + left = temp.CreateReferenceExpression (rc, loc); + if (oper == Operator.LogicalAnd) { + expr = DynamicUnaryConversion.CreateIsFalse (rc, cond_args, loc); + cond_left = left; } else { - LocalVariable temp = LocalVariable.CreateCompilerGenerated (ec.BuiltinTypes.Bool, ec.CurrentBlock, loc); + expr = DynamicUnaryConversion.CreateIsTrue (rc, cond_args, loc); + cond_left = left; + } - args.Add (new Argument (temp.CreateReferenceExpression (ec, loc).Resolve (ec))); - args.Add (new Argument (right)); - right = new DynamicExpressionStatement (this, args, loc); + args.Add (new Argument (left)); + args.Add (new Argument (right)); + cond_right = new DynamicExpressionStatement (this, args, loc); + } else { + LocalVariable temp = LocalVariable.CreateCompilerGenerated (rc.BuiltinTypes.Bool, rc.CurrentBlock, loc); - // - // bool && dynamic => (temp = left) ? temp && right : temp; - // bool || dynamic => (temp = left) ? temp : temp || right; - // - if (oper == Operator.LogicalAnd) { - cond_left = right; - cond_right = temp.CreateReferenceExpression (ec, loc); - } else { - cond_left = temp.CreateReferenceExpression (ec, loc); - cond_right = right; - } + if (!Convert.ImplicitConversionExists (rc, left, temp.Type) && (oper == Operator.LogicalAnd ? GetOperatorFalse (rc, left, loc) : GetOperatorTrue (rc, left, loc)) == null) { + rc.Report.Error (7083, left.Location, + "Expression must be implicitly convertible to Boolean or its type `{0}' must define operator `{1}'", + lt.GetSignatureForError (), oper == Operator.LogicalAnd ? "false" : "true"); + return null; + } + + args.Add (new Argument (temp.CreateReferenceExpression (rc, loc).Resolve (rc))); + args.Add (new Argument (right)); + right = new DynamicExpressionStatement (this, args, loc); - expr = new BooleanExpression (new SimpleAssign (temp.CreateReferenceExpression (ec, loc), left)); + // + // bool && dynamic => (temp = left) ? temp && right : temp; + // bool || dynamic => (temp = left) ? temp : temp || right; + // + if (oper == Operator.LogicalAnd) { + cond_left = right; + cond_right = temp.CreateReferenceExpression (rc, loc); + } else { + cond_left = temp.CreateReferenceExpression (rc, loc); + cond_right = right; } - return new Conditional (expr, cond_left, cond_right, loc).Resolve (ec); + expr = new BooleanExpression (new SimpleAssign (temp.CreateReferenceExpression (rc, loc), left)); } - args = new Arguments (2); - args.Add (new Argument (left)); - args.Add (new Argument (right)); - return new DynamicExpressionStatement (this, args, loc).Resolve (ec); - } - - if (ec.Module.Compiler.Settings.Version >= LanguageVersion.ISO_2 && - ((left.Type.IsNullableType && (right is NullLiteral || right.Type.IsNullableType || TypeSpec.IsValueType (right.Type))) || - (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); - lifted.state = state; - return lifted.Resolve (ec); + return new Conditional (expr, cond_left, cond_right, loc).Resolve (rc); } - return DoResolveCore (ec, left, right); + args = new Arguments (2); + args.Add (new Argument (left)); + args.Add (new Argument (right)); + return new DynamicExpressionStatement (this, args, loc).Resolve (rc); } - protected Expression DoResolveCore (ResolveContext ec, Expression left_orig, Expression right_orig) + Expression DoResolveCore (ResolveContext ec, Expression left_orig, Expression right_orig) { Expression expr = ResolveOperator (ec); if (expr == null) @@ -3055,6 +3539,11 @@ namespace Mono.CSharp } public override SLE.Expression MakeExpression (BuilderContext ctx) + { + return MakeExpression (ctx, left, right); + } + + public SLE.Expression MakeExpression (BuilderContext ctx, Expression left, Expression right) { var le = left.MakeExpression (ctx); var re = right.MakeExpression (ctx); @@ -3141,15 +3630,14 @@ namespace Mono.CSharp if (method == null) return new EmptyExpression (ec.BuiltinTypes.Decimal); - MethodGroupExpr mg = MethodGroupExpr.CreatePredefined (method, ec.BuiltinTypes.Delegate, loc); - Expression expr = new UserOperatorCall (mg.BestCandidate, args, CreateExpressionTree, loc); + Expression expr = new UserOperatorCall (method, args, CreateExpressionTree, loc); return new ClassCast (expr, l); } // - // Enumeration operators + // Resolves enumeration operators where only single predefined overload exists, handles lifted versions too // - Expression ResolveOperatorEnum (ResolveContext ec, bool lenum, bool renum, TypeSpec ltype, TypeSpec rtype) + Expression ResolveSingleEnumOperators (ResolveContext rc, bool lenum, bool renum, TypeSpec ltype, TypeSpec rtype) { // // bool operator == (E x, E y); @@ -3163,264 +3651,393 @@ namespace Mono.CSharp // E operator | (E x, E y); // E operator ^ (E x, E y); // - // U operator - (E e, E f) - // E operator - (E e, U x) - // E operator - (U x, E e) // LAMESPEC: Not covered by the specification - // - // E operator + (E e, U x) - // E operator + (U x, E e) - // - Expression ltemp = left; - Expression rtemp = right; - TypeSpec underlying_type; - TypeSpec underlying_type_result; - TypeSpec res_type; Expression expr; - - // - // LAMESPEC: There is never ambiguous conversion between enum operators - // the one which contains more enum parameters always wins even if there - // is an implicit conversion involved - // - if ((oper & (Operator.ComparisonMask | Operator.BitwiseMask)) != 0) { - if (renum) { - underlying_type = EnumSpec.GetUnderlyingType (rtype); - expr = Convert.ImplicitConversion (ec, left, rtype, loc); - if (expr == null) - return null; + if ((oper & Operator.ComparisonMask) != 0) { + type = rc.BuiltinTypes.Bool; + } else { + if (lenum) + type = ltype; + else if (renum) + type = rtype; + else if (ltype.IsNullableType && Nullable.NullableInfo.GetUnderlyingType (ltype).IsEnum) + type = ltype; + else + type = rtype; + } - left = expr; - ltype = expr.Type; - } else if (lenum) { - underlying_type = EnumSpec.GetUnderlyingType (ltype); - expr = Convert.ImplicitConversion (ec, right, ltype, loc); - if (expr == null) - return null; + if (ltype == rtype) { + if (lenum || renum) + return this; + var lifted = new Nullable.LiftedBinaryOperator (this); + lifted.Left = left; + lifted.Right = right; + return lifted.Resolve (rc); + } + + if (renum && !ltype.IsNullableType) { + expr = Convert.ImplicitConversion (rc, left, rtype, loc); + if (expr != null) { + left = expr; + return this; + } + } else if (lenum && !rtype.IsNullableType) { + expr = Convert.ImplicitConversion (rc, right, ltype, loc); + if (expr != null) { right = expr; - rtype = expr.Type; - } else { - return null; + return this; } + } - if ((oper & Operator.BitwiseMask) != 0) { - res_type = ltype; - underlying_type_result = underlying_type; - } else { - res_type = null; - underlying_type_result = null; - } - } else if (oper == Operator.Subtraction) { - if (renum) { - underlying_type = EnumSpec.GetUnderlyingType (rtype); - if (ltype != rtype) { - expr = Convert.ImplicitConversion (ec, left, rtype, left.Location); - if (expr == null) { - expr = Convert.ImplicitConversion (ec, left, underlying_type, left.Location); - if (expr == null) - return null; - - res_type = rtype; - } else { - res_type = underlying_type; - } + // + // Now try lifted version of predefined operator + // + var nullable_type = rc.Module.PredefinedTypes.Nullable.TypeSpec; + if (nullable_type != null) { + if (renum && !ltype.IsNullableType) { + var lifted_type = nullable_type.MakeGenericType (rc.Module, new[] { rtype }); + expr = Convert.ImplicitConversion (rc, left, lifted_type, loc); + if (expr != null) { left = expr; - } else { - res_type = underlying_type; + right = Convert.ImplicitConversion (rc, right, lifted_type, loc); } - underlying_type_result = underlying_type; - } else if (lenum) { - underlying_type = EnumSpec.GetUnderlyingType (ltype); - expr = Convert.ImplicitConversion (ec, right, ltype, right.Location); - if (expr == null || expr is EnumConstant) { - expr = Convert.ImplicitConversion (ec, right, underlying_type, right.Location); - if (expr == null) - return null; + if ((oper & Operator.BitwiseMask) != 0) + type = lifted_type; - res_type = ltype; - } else { - res_type = underlying_type; + if (left.IsNull) { + if ((oper & Operator.BitwiseMask) != 0) + return Nullable.LiftedNull.CreateFromExpression (rc, this); + + return CreateLiftedValueTypeResult (rc, rtype); } - right = expr; - underlying_type_result = underlying_type; - } else { - return null; - } - } else if (oper == Operator.Addition) { - if (lenum) { - underlying_type = EnumSpec.GetUnderlyingType (ltype); - res_type = ltype; + if (expr != null) { + var lifted = new Nullable.LiftedBinaryOperator (this); + lifted.Left = expr; + lifted.Right = right; + return lifted.Resolve (rc); + } + } else if (lenum && !rtype.IsNullableType) { + var lifted_type = nullable_type.MakeGenericType (rc.Module, new[] { ltype }); - if (rtype != underlying_type && (state & (State.RightNullLifted | State.LeftNullLifted)) == 0) { - expr = Convert.ImplicitConversion (ec, right, underlying_type, right.Location); + expr = Convert.ImplicitConversion (rc, right, lifted_type, loc); + if (expr != null) { + right = expr; + left = Convert.ImplicitConversion (rc, left, lifted_type, loc); + } + + if ((oper & Operator.BitwiseMask) != 0) + type = lifted_type; + + if (right.IsNull) { + if ((oper & Operator.BitwiseMask) != 0) + return Nullable.LiftedNull.CreateFromExpression (rc, this); + + return CreateLiftedValueTypeResult (rc, ltype); + } + + if (expr != null) { + var lifted = new Nullable.LiftedBinaryOperator (this); + lifted.Left = left; + lifted.Right = expr; + return lifted.Resolve (rc); + } + } else if (rtype.IsNullableType && Nullable.NullableInfo.GetUnderlyingType (rtype).IsEnum) { + if (left.IsNull) { + if (rc.HasSet (ResolveContext.Options.ExpressionTreeConversion)) + left = Convert.ImplicitConversion (rc, left, rtype, left.Location); + + if ((oper & Operator.RelationalMask) != 0) + return CreateLiftedValueTypeResult (rc, rtype); + + if ((oper & Operator.BitwiseMask) != 0) + return Nullable.LiftedNull.CreateFromExpression (rc, this); + + // Equality operators are valid between E? and null + expr = left; + } else { + expr = Convert.ImplicitConversion (rc, left, Nullable.NullableInfo.GetUnderlyingType (rtype), loc); if (expr == null) return null; + } - right = expr; + if (expr != null) { + var lifted = new Nullable.LiftedBinaryOperator (this); + lifted.Left = expr; + lifted.Right = right; + return lifted.Resolve (rc); } - } else { - underlying_type = EnumSpec.GetUnderlyingType (rtype); - res_type = rtype; - if (ltype != underlying_type) { - expr = Convert.ImplicitConversion (ec, left, underlying_type, left.Location); + } else if (ltype.IsNullableType && Nullable.NullableInfo.GetUnderlyingType (ltype).IsEnum) { + if (right.IsNull) { + if (rc.HasSet (ResolveContext.Options.ExpressionTreeConversion)) + right = Convert.ImplicitConversion (rc, right, ltype, right.Location); + + if ((oper & Operator.RelationalMask) != 0) + return CreateLiftedValueTypeResult (rc, ltype); + + if ((oper & Operator.BitwiseMask) != 0) + return Nullable.LiftedNull.CreateFromExpression (rc, this); + + // Equality operators are valid between E? and null + expr = right; + } else { + expr = Convert.ImplicitConversion (rc, right, Nullable.NullableInfo.GetUnderlyingType (ltype), loc); if (expr == null) return null; + } - left = expr; + if (expr != null) { + var lifted = new Nullable.LiftedBinaryOperator (this); + lifted.Left = left; + lifted.Right = expr; + return lifted.Resolve (rc); } } - - underlying_type_result = underlying_type; - } else { - return null; } - // Unwrap the constant correctly, so DoBinaryOperatorPromotion can do the magic - // with constants and expressions - if (left.Type != underlying_type) { - if (left is Constant) - left = ((Constant) left).ConvertExplicitly (false, underlying_type); + return null; + } + + static Expression ConvertEnumOperandToUnderlyingType (ResolveContext rc, Expression expr, bool liftType) + { + TypeSpec underlying_type; + if (expr.Type.IsNullableType) { + var nt = Nullable.NullableInfo.GetUnderlyingType (expr.Type); + if (nt.IsEnum) + underlying_type = EnumSpec.GetUnderlyingType (nt); else - left = EmptyCast.Create (left, underlying_type); + underlying_type = nt; + } else if (expr.Type.IsEnum) { + underlying_type = EnumSpec.GetUnderlyingType (expr.Type); + } else { + underlying_type = expr.Type; } - if (right.Type != underlying_type) { - if (right is Constant) - right = ((Constant) right).ConvertExplicitly (false, underlying_type); - else - right = EmptyCast.Create (right, underlying_type); + switch (underlying_type.BuiltinType) { + case BuiltinTypeSpec.Type.SByte: + case BuiltinTypeSpec.Type.Byte: + case BuiltinTypeSpec.Type.Short: + case BuiltinTypeSpec.Type.UShort: + underlying_type = rc.BuiltinTypes.Int; + break; } + if (expr.Type.IsNullableType || liftType) + underlying_type = rc.Module.PredefinedTypes.Nullable.TypeSpec.MakeGenericType (rc.Module, new[] { underlying_type }); + + if (expr.Type == underlying_type) + return expr; + + return EmptyCast.Create (expr, underlying_type); + } + + Expression ResolveEnumOperators (ResolveContext rc, bool lenum, bool renum, TypeSpec ltype, TypeSpec rtype) + { // - // C# specification uses explicit cast syntax which means binary promotion - // should happen, however it seems that csc does not do that + // U operator - (E e, E f) + // E operator - (E e, U x) // Internal decomposition operator + // E operator - (U x, E e) // Internal decomposition operator // - if (!DoBinaryOperatorPromotion (ec)) { - left = ltemp; - right = rtemp; - return null; + // E operator + (E e, U x) + // E operator + (U x, E e) + // + + TypeSpec enum_type; + + if (lenum) + enum_type = ltype; + else if (renum) + enum_type = rtype; + else if (ltype.IsNullableType && Nullable.NullableInfo.GetUnderlyingType (ltype).IsEnum) + enum_type = ltype; + else + enum_type = rtype; + + Expression expr; + if (!enum_type.IsNullableType) { + expr = ResolveOperatorPredefined (rc, rc.Module.GetPredefinedEnumAritmeticOperators (enum_type, false), false); + if (expr != null) { + if (oper == Operator.Subtraction) + expr = ConvertEnumSubtractionResult (rc, expr); + else + expr = ConvertEnumAdditionalResult (expr, enum_type); + + AddEnumResultCast (expr.Type); + + return expr; + } + + enum_type = rc.Module.PredefinedTypes.Nullable.TypeSpec.MakeGenericType (rc.Module, new[] { enum_type }); } - if (underlying_type_result != null && left.Type != underlying_type_result) { - enum_conversion = Convert.ExplicitNumericConversion (ec, new EmptyExpression (left.Type), underlying_type_result); + expr = ResolveOperatorPredefined (rc, rc.Module.GetPredefinedEnumAritmeticOperators (enum_type, true), false); + if (expr != null) { + if (oper == Operator.Subtraction) + expr = ConvertEnumSubtractionResult (rc, expr); + else + expr = ConvertEnumAdditionalResult (expr, enum_type); + + AddEnumResultCast (expr.Type); } - expr = ResolveOperatorPredefined (ec, ec.BuiltinTypes.OperatorsBinaryStandard, true, res_type); - if (expr == null) - return null; + return expr; + } - if (!IsCompound) - return expr; + static Expression ConvertEnumAdditionalResult (Expression expr, TypeSpec enumType) + { + return EmptyCast.Create (expr, enumType); + } + Expression ConvertEnumSubtractionResult (ResolveContext rc, Expression expr) + { // - // Section: 7.16.2 + // Enumeration subtraction has different result type based on + // best overload // + TypeSpec result_type; + if (left.Type == right.Type) { + var c = right as EnumConstant; + if (c != null && c.IsZeroInteger && !right.Type.IsEnum) { + // + // LAMESPEC: This is quite unexpected for expression E - 0 the return type is + // E which is not what expressions E - 1 or 0 - E return + // + result_type = left.Type; + } else { + result_type = left.Type.IsNullableType ? + Nullable.NullableInfo.GetEnumUnderlyingType (rc.Module, left.Type) : + EnumSpec.GetUnderlyingType (left.Type); + } + } else { + if (IsEnumOrNullableEnum (left.Type)) { + result_type = left.Type; + } else { + result_type = right.Type; + } - // - // If the return type of the selected operator is implicitly convertible to the type of x - // - if (Convert.ImplicitConversionExists (ec, expr, ltype)) - return expr; + if (expr is Nullable.LiftedBinaryOperator && !result_type.IsNullableType) + result_type = rc.Module.PredefinedTypes.Nullable.TypeSpec.MakeGenericType (rc.Module, new[] { result_type }); + } - // - // Otherwise, if the selected operator is a predefined operator, if the return type of the - // selected operator is explicitly convertible to the type of x, and if y is implicitly - // convertible to the type of x or the operator is a shift operator, then the operation - // is evaluated as x = (T)(x op y), where T is the type of x - // - expr = Convert.ExplicitConversion (ec, expr, ltype, loc); - if (expr == null) - return null; + return EmptyCast.Create (expr, result_type); + } + + void AddEnumResultCast (TypeSpec type) + { + if (type.IsNullableType) + type = Nullable.NullableInfo.GetUnderlyingType (type); - if (Convert.ImplicitConversionExists (ec, ltemp, ltype)) - return expr; + if (type.IsEnum) + type = EnumSpec.GetUnderlyingType (type); - return null; + switch (type.BuiltinType) { + case BuiltinTypeSpec.Type.SByte: + enum_conversion = ConvCast.Mode.I4_I1; + break; + case BuiltinTypeSpec.Type.Byte: + enum_conversion = ConvCast.Mode.I4_U1; + break; + case BuiltinTypeSpec.Type.Short: + enum_conversion = ConvCast.Mode.I4_I2; + break; + case BuiltinTypeSpec.Type.UShort: + enum_conversion = ConvCast.Mode.I4_U2; + break; + } } // - // 7.9.6 Reference type equality operators + // Equality operators rules // - Expression ResolveOperatorEquality (ResolveContext ec, TypeSpec l, TypeSpec r) + Expression ResolveEquality (ResolveContext ec, TypeSpec l, TypeSpec r, bool primitives_only) { Expression result; type = ec.BuiltinTypes.Bool; + bool no_arg_conv = false; - // - // a, Both operands are reference-type values or the value null - // b, One operand is a value of type T where T is a type-parameter and - // the other operand is the value null. Furthermore T does not have the - // value type constraint - // - // LAMESPEC: Very confusing details in the specification, basically any - // reference like type-parameter is allowed - // - var tparam_l = l as TypeParameterSpec; - var tparam_r = r as TypeParameterSpec; - if (tparam_l != null) { - if (right is NullLiteral && !tparam_l.HasSpecialStruct) { - left = new BoxedCast (left, ec.BuiltinTypes.Object); - return this; - } + if (!primitives_only) { - if (!tparam_l.IsReferenceType) - return null; + // + // a, Both operands are reference-type values or the value null + // b, One operand is a value of type T where T is a type-parameter and + // the other operand is the value null. Furthermore T does not have the + // value type constraint + // + // LAMESPEC: Very confusing details in the specification, basically any + // reference like type-parameter is allowed + // + var tparam_l = l as TypeParameterSpec; + var tparam_r = r as TypeParameterSpec; + if (tparam_l != null) { + if (right is NullLiteral) { + if (tparam_l.GetEffectiveBase ().BuiltinType == BuiltinTypeSpec.Type.ValueType) + return null; - l = tparam_l.GetEffectiveBase (); - left = new BoxedCast (left, l); - } else if (left is NullLiteral && tparam_r == null) { - if (!TypeSpec.IsReferenceType (r) || r.Kind == MemberKind.InternalCompilerType) - return null; + left = new BoxedCast (left, ec.BuiltinTypes.Object); + return this; + } - return this; - } + if (!tparam_l.IsReferenceType) + return null; - if (tparam_r != null) { - if (left is NullLiteral && !tparam_r.HasSpecialStruct) { - right = new BoxedCast (right, ec.BuiltinTypes.Object); - return this; + l = tparam_l.GetEffectiveBase (); + left = new BoxedCast (left, l); + } else if (left is NullLiteral && tparam_r == null) { + if (TypeSpec.IsReferenceType (r)) + return this; + + if (r.Kind == MemberKind.InternalCompilerType) + return null; } - if (!tparam_r.IsReferenceType) - return null; + if (tparam_r != null) { + if (left is NullLiteral) { + if (tparam_r.GetEffectiveBase ().BuiltinType == BuiltinTypeSpec.Type.ValueType) + return null; - r = tparam_r.GetEffectiveBase (); - right = new BoxedCast (right, r); - } else if (right is NullLiteral) { - if (!TypeSpec.IsReferenceType (l) || l.Kind == MemberKind.InternalCompilerType) - return null; + right = new BoxedCast (right, ec.BuiltinTypes.Object); + return this; + } - return this; - } + if (!tparam_r.IsReferenceType) + return null; - bool no_arg_conv = false; + r = tparam_r.GetEffectiveBase (); + right = new BoxedCast (right, r); + } else if (right is NullLiteral) { + if (TypeSpec.IsReferenceType (l)) + return this; - // - // LAMESPEC: method groups can be compared when they convert to other side delegate - // - if (l.IsDelegate) { - if (right.eclass == ExprClass.MethodGroup) { - result = Convert.ImplicitConversion (ec, right, l, loc); + if (l.Kind == MemberKind.InternalCompilerType) + return null; + } + + // + // LAMESPEC: method groups can be compared when they convert to other side delegate + // + if (l.IsDelegate) { + if (right.eclass == ExprClass.MethodGroup) { + result = Convert.ImplicitConversion (ec, right, l, loc); + if (result == null) + return null; + + right = result; + r = l; + } else if (r.IsDelegate && l != r) { + return null; + } + } else if (left.eclass == ExprClass.MethodGroup && r.IsDelegate) { + result = Convert.ImplicitConversionRequired (ec, left, r, loc); if (result == null) return null; - right = result; - r = l; - } else if (r.IsDelegate && l != r) { - return null; + left = result; + l = r; + } else { + no_arg_conv = l == r && !l.IsStruct; } - } else if (left.eclass == ExprClass.MethodGroup && r.IsDelegate) { - result = Convert.ImplicitConversionRequired (ec, left, r, loc); - if (result == null) - return null; - - left = result; - l = r; - } else { - no_arg_conv = l == r && !l.IsStruct; } // @@ -3438,9 +4055,34 @@ namespace Mono.CSharp // not apply when both operands are of same reference type // if (r.BuiltinType != BuiltinTypeSpec.Type.Object && l.BuiltinType != BuiltinTypeSpec.Type.Object) { - result = ResolveOperatorPredefined (ec, ec.BuiltinTypes.OperatorsBinaryEquality, no_arg_conv, null); + result = ResolveOperatorPredefined (ec, ec.BuiltinTypes.OperatorsBinaryEquality, no_arg_conv); if (result != null) return result; + + // + // Now try lifted version of predefined operators + // + if (no_arg_conv && !l.IsNullableType) { + // + // Optimizes cases which won't match + // + } else { + result = ResolveOperatorPredefined (ec, ec.Module.OperatorsBinaryEqualityLifted, no_arg_conv); + if (result != null) + return result; + } + + // + // The == and != operators permit one operand to be a value of a nullable + // type and the other to be the null literal, even if no predefined or user-defined + // operator (in unlifted or lifted form) exists for the operation. + // + if ((l.IsNullableType && right.IsNull) || (r.IsNullableType && left.IsNull)) { + var lifted = new Nullable.LiftedBinaryOperator (this); + lifted.Left = left; + lifted.Right = right; + return lifted.Resolve (ec); + } } // @@ -3464,12 +4106,12 @@ namespace Mono.CSharp if (!TypeSpec.IsReferenceType (l) || !TypeSpec.IsReferenceType (r)) return null; - if (l.BuiltinType == BuiltinTypeSpec.Type.String || l.BuiltinType == BuiltinTypeSpec.Type.Delegate || MemberCache.GetUserOperator (l, CSharp.Operator.OpType.Equality, false) != null) + if (l.BuiltinType == BuiltinTypeSpec.Type.String || l.BuiltinType == BuiltinTypeSpec.Type.Delegate || l.IsDelegate || MemberCache.GetUserOperator (l, CSharp.Operator.OpType.Equality, false) != null) ec.Report.Warning (253, 2, loc, "Possible unintended reference comparison. Consider casting the right side expression to type `{0}' to get value comparison", l.GetSignatureForError ()); - if (r.BuiltinType == BuiltinTypeSpec.Type.String || r.BuiltinType == BuiltinTypeSpec.Type.Delegate || MemberCache.GetUserOperator (r, CSharp.Operator.OpType.Equality, false) != null) + if (r.BuiltinType == BuiltinTypeSpec.Type.String || r.BuiltinType == BuiltinTypeSpec.Type.Delegate || r.IsDelegate || MemberCache.GetUserOperator (r, CSharp.Operator.OpType.Equality, false) != null) ec.Report.Warning (252, 2, loc, "Possible unintended reference comparison. Consider casting the left side expression to type `{0}' to get value comparison", r.GetSignatureForError ()); @@ -3508,13 +4150,13 @@ namespace Mono.CSharp return this; } - return ResolveOperatorPredefined (ec, ec.BuiltinTypes.OperatorsBinaryUnsafe, false, null); + return ResolveOperatorPredefined (ec, ec.BuiltinTypes.OperatorsBinaryUnsafe, false); } // // Build-in operators method overloading // - protected virtual Expression ResolveOperatorPredefined (ResolveContext ec, PredefinedOperator [] operators, bool primitives_only, TypeSpec enum_type) + Expression ResolveOperatorPredefined (ResolveContext ec, PredefinedOperator [] operators, bool primitives_only) { PredefinedOperator best_operator = null; TypeSpec l = left.Type; @@ -3545,7 +4187,7 @@ namespace Mono.CSharp if (best_operator == null) { ec.Report.Error (34, loc, "Operator `{0}' is ambiguous on operands of type `{1}' and `{2}'", - OperName (oper), TypeManager.CSharpName (l), TypeManager.CSharpName (r)); + OperName (oper), l.GetSignatureForError (), r.GetSignatureForError ()); best_operator = po; break; @@ -3555,41 +4197,62 @@ namespace Mono.CSharp if (best_operator == null) return null; - Expression expr = best_operator.ConvertResult (ec, this); + return best_operator.ConvertResult (ec, this); + } - // - // Optimize &/&& constant expressions with 0 value - // - if (oper == Operator.BitwiseAnd || oper == Operator.LogicalAnd) { - Constant rc = right as Constant; - Constant lc = left as Constant; - if (((lc != null && lc.IsDefaultValue) || (rc != null && rc.IsDefaultValue)) && !(this is Nullable.LiftedBinaryOperator)) { - // - // The result is a constant with side-effect - // - Constant side_effect = rc == null ? - new SideEffectConstant (lc, right, loc) : - new SideEffectConstant (rc, left, loc); + // + // Optimize & constant expressions with 0 value + // + Expression OptimizeAndOperation (Expression expr) + { + Constant rc = right as Constant; + Constant lc = left as Constant; + if ((lc != null && lc.IsDefaultValue) || (rc != null && rc.IsDefaultValue)) { + // + // The result is a constant with side-effect + // + Constant side_effect = rc == null ? + new SideEffectConstant (lc, right, loc) : + new SideEffectConstant (rc, left, loc); - return ReducedExpression.Create (side_effect, expr); - } + return ReducedExpression.Create (side_effect, expr); } - if (enum_type == null) - return expr; + return expr; + } - // - // HACK: required by enum_conversion - // - expr.Type = enum_type; - return EmptyCast.Create (expr, enum_type); + // + // Value types can be compared with the null literal because of the lifting + // language rules. However the result is always true or false. + // + public Expression CreateLiftedValueTypeResult (ResolveContext rc, TypeSpec valueType) + { + if (rc.HasSet (ResolveContext.Options.ExpressionTreeConversion)) { + type = rc.BuiltinTypes.Bool; + return this; + } + + // FIXME: Handle side effect constants + Constant c = new BoolConstant (rc.BuiltinTypes, Oper == Operator.Inequality, loc); + + if ((Oper & Operator.EqualityMask) != 0) { + rc.Report.Warning (472, 2, loc, "The result of comparing value type `{0}' with null is always `{1}'", + valueType.GetSignatureForError (), c.GetValueAsLiteral ()); + } else { + rc.Report.Warning (464, 2, loc, "The result of comparing type `{0}' with null is always `{1}'", + valueType.GetSignatureForError (), c.GetValueAsLiteral ()); + } + + return c; } // // Performs user-operator overloading // - protected virtual Expression ResolveUserOperator (ResolveContext ec, Expression left, Expression right) + Expression ResolveUserOperator (ResolveContext rc, Expression left, Expression right) { + Expression oper_expr; + var op = ConvertBinaryToUserOperator (oper); var l = left.Type; if (l.IsNullableType) @@ -3611,7 +4274,7 @@ namespace Mono.CSharp Arguments args = new Arguments (2); Argument larg = new Argument (left); - args.Add (larg); + args.Add (larg); Argument rarg = new Argument (right); args.Add (rarg); @@ -3625,50 +4288,198 @@ namespace Mono.CSharp left_operators = right_operators; } - var res = new OverloadResolver (left_operators, OverloadResolver.Restrictions.ProbingOnly | - OverloadResolver.Restrictions.NoBaseMembers | OverloadResolver.Restrictions.BaseMembersIncluded, loc); + const OverloadResolver.Restrictions restr = OverloadResolver.Restrictions.ProbingOnly | + OverloadResolver.Restrictions.NoBaseMembers | OverloadResolver.Restrictions.BaseMembersIncluded; - var oper_method = res.ResolveOperator (ec, ref args); - if (oper_method == null) - return null; + var res = new OverloadResolver (left_operators, restr, loc); - var llifted = (state & State.LeftNullLifted) != 0; - var rlifted = (state & State.RightNullLifted) != 0; - if ((Oper & Operator.EqualityMask) != 0) { - var parameters = oper_method.Parameters; - // LAMESPEC: No idea why this is not allowed - if ((left is Nullable.Unwrap || right is Nullable.Unwrap) && parameters.Types [0] != parameters.Types [1]) + var oper_method = res.ResolveOperator (rc, ref args); + if (oper_method == null) { + // + // Logical && and || cannot be lifted + // + if ((oper & Operator.LogicalMask) != 0) + return null; + + // + // Apply lifted user operators only for liftable types. Implicit conversion + // to nullable types is not allowed + // + if (!IsLiftedOperatorApplicable ()) + return null; + + // TODO: Cache the result in module container + var lifted_methods = CreateLiftedOperators (rc, left_operators); + if (lifted_methods == null) + return null; + + res = new OverloadResolver (lifted_methods, restr | OverloadResolver.Restrictions.ProbingOnly, loc); + + oper_method = res.ResolveOperator (rc, ref args); + if (oper_method == null) return null; - // Binary operation was lifted but we have found a user operator - // which requires value-type argument, we downgrade ourself back to - // binary operation - // LAMESPEC: The user operator is not called (it cannot be we are passing null to struct) - // but compilation succeeds - if ((llifted && !parameters.Types[0].IsStruct) || (rlifted && !parameters.Types[1].IsStruct)) { - state &= ~(State.LeftNullLifted | State.RightNullLifted); + MethodSpec best_original = null; + foreach (MethodSpec ms in left_operators) { + if (ms.MemberDefinition == oper_method.MemberDefinition) { + best_original = ms; + break; + } } - } - Expression oper_expr; + if (rc.HasSet (ResolveContext.Options.ExpressionTreeConversion)) { + // + // Expression trees use lifted notation in this case + // + this.left = Convert.ImplicitConversion (rc, left, oper_method.Parameters.Types[0], left.Location); + this.right = Convert.ImplicitConversion (rc, right, oper_method.Parameters.Types[1], left.Location); + } + + var ptypes = best_original.Parameters.Types; + + if (left.IsNull || right.IsNull) { + // + // The lifted operator produces the value false if one or both operands are null for + // relational operators. + // + if ((oper & Operator.ComparisonMask) != 0) { + // + // CSC BUG: This should be different warning, csc reports CS0458 with bool? which is wrong + // because return type is actually bool + // + // For some reason CSC does not report this warning for equality operators + // + return CreateLiftedValueTypeResult (rc, left.IsNull ? ptypes [1] : ptypes [0]); + } + + // The lifted operator produces a null value if one or both operands are null + // + if ((oper & (Operator.ArithmeticMask | Operator.ShiftMask | Operator.BitwiseMask)) != 0) { + type = oper_method.ReturnType; + return Nullable.LiftedNull.CreateFromExpression (rc, this); + } + } + + type = oper_method.ReturnType; + var lifted = new Nullable.LiftedBinaryOperator (this); + lifted.UserOperator = best_original; + + if (left.Type.IsNullableType && !ptypes[0].IsNullableType) { + lifted.UnwrapLeft = new Nullable.Unwrap (left); + } - // TODO: CreateExpressionTree is allocated every time + if (right.Type.IsNullableType && !ptypes[1].IsNullableType) { + lifted.UnwrapRight = new Nullable.Unwrap (right); + } + + lifted.Left = Convert.ImplicitConversion (rc, lifted.UnwrapLeft ?? left, ptypes[0], left.Location); + lifted.Right = Convert.ImplicitConversion (rc, lifted.UnwrapRight ?? right, ptypes[1], right.Location); + + return lifted.Resolve (rc); + } + if ((oper & Operator.LogicalMask) != 0) { + // TODO: CreateExpressionTree is allocated every time oper_expr = new ConditionalLogicalOperator (oper_method, args, CreateExpressionTree, - oper == Operator.LogicalAnd, loc).Resolve (ec); + oper == Operator.LogicalAnd, loc).Resolve (rc); } else { oper_expr = new UserOperatorCall (oper_method, args, CreateExpressionTree, loc); } - if (!llifted) - this.left = larg.Expr; - - if (!rlifted) - this.right = rarg.Expr; + this.left = larg.Expr; + this.right = rarg.Expr; return oper_expr; } + bool IsLiftedOperatorApplicable () + { + if (left.Type.IsNullableType) { + if ((oper & Operator.EqualityMask) != 0) + return !right.IsNull; + + return true; + } + + if (right.Type.IsNullableType) { + if ((oper & Operator.EqualityMask) != 0) + return !left.IsNull; + + return true; + } + + if (TypeSpec.IsValueType (left.Type)) + return right.IsNull; + + if (TypeSpec.IsValueType (right.Type)) + return left.IsNull; + + return false; + } + + List CreateLiftedOperators (ResolveContext rc, IList operators) + { + var nullable_type = rc.Module.PredefinedTypes.Nullable.TypeSpec; + if (nullable_type == null) + return null; + + // + // Lifted operators permit predefined and user-defined operators that operate + // on non-nullable value types to also be used with nullable forms of those types. + // Lifted operators are constructed from predefined and user-defined operators + // that meet certain requirements + // + List lifted = null; + foreach (MethodSpec oper in operators) { + TypeSpec rt; + if ((Oper & Operator.ComparisonMask) != 0) { + // + // Result type must be of type bool for lifted comparison operators + // + rt = oper.ReturnType; + if (rt.BuiltinType != BuiltinTypeSpec.Type.Bool) + continue; + } else { + if (!TypeSpec.IsNonNullableValueType (oper.ReturnType)) + continue; + + rt = null; + } + + var ptypes = oper.Parameters.Types; + if (!TypeSpec.IsNonNullableValueType (ptypes [0]) || !TypeSpec.IsNonNullableValueType (ptypes [1])) + continue; + + // + // LAMESPEC: I am not sure why but for equality operators to be lifted + // both types have to match + // + if ((Oper & Operator.EqualityMask) != 0 && ptypes [0] != ptypes [1]) + continue; + + if (lifted == null) + lifted = new List (); + + // + // The lifted form is constructed by adding a single ? modifier to each operand and + // result type except for comparison operators where return type is bool + // + if (rt == null) + rt = nullable_type.MakeGenericType (rc.Module, new[] { oper.ReturnType }); + + var parameters = ParametersCompiled.CreateFullyResolved ( + nullable_type.MakeGenericType (rc.Module, new [] { ptypes[0] }), + nullable_type.MakeGenericType (rc.Module, new [] { ptypes[1] })); + + var lifted_op = new MethodSpec (oper.Kind, oper.DeclaringType, oper.MemberDefinition, + rt, parameters, oper.Modifiers); + + lifted.Add (lifted_op); + } + + return lifted; + } + // // Merge two sets of user operators into one, they are mostly distinguish // except when they share base type and it contains an operator @@ -3701,7 +4512,7 @@ namespace Mono.CSharp } catch (OverflowException) { ec.Report.Warning (652, 2, loc, "A comparison between a constant and a variable is useless. The constant is out of the range of the variable type `{0}'", - TypeManager.CSharpName (type)); + type.GetSignatureForError ()); } } } @@ -3716,6 +4527,14 @@ namespace Mono.CSharp /// public override void EmitBranchable (EmitContext ec, Label target, bool on_true) { + if (ec.HasSet (BuilderContext.Options.AsyncBody) && right.ContainsEmitWithAwait ()) { + left = left.EmitToField (ec); + + if ((oper & Operator.LogicalMask) == 0) { + right = right.EmitToField (ec); + } + } + // // This is more complicated than it looks, but its just to avoid // duplicated tests: basically, we allow ==, !=, >, <, >= and <= @@ -3868,11 +4687,6 @@ namespace Mono.CSharp } public override void Emit (EmitContext ec) - { - EmitOperator (ec, left.Type); - } - - protected virtual void EmitOperator (EmitContext ec, TypeSpec l) { if (ec.HasSet (BuilderContext.Options.AsyncBody) && right.ContainsEmitWithAwait ()) { left = left.EmitToField (ec); @@ -3913,16 +4727,22 @@ namespace Mono.CSharp } } + EmitOperator (ec, left, right); + } + + public void EmitOperator (EmitContext ec, Expression left, Expression right) + { left.Emit (ec); right.Emit (ec); - EmitOperatorOpcode (ec, oper, l); + + EmitOperatorOpcode (ec, oper, left.Type, right); // - // Nullable enum could require underlying type cast and we cannot simply wrap binary - // expression because that would wrap lifted binary operation + // Emit result enumerable conversion this way because it's quite complicated get it + // to resolved tree because expression tree cannot see it. // - if (enum_conversion != null) - enum_conversion.Emit (ec); + if (enum_conversion != 0) + ConvCast.Emit (ec, enum_conversion); } public override void EmitSideEffect (EmitContext ec) @@ -3992,7 +4812,7 @@ namespace Mono.CSharp return CreateExpressionTree (ec, null); } - Expression CreateExpressionTree (ResolveContext ec, Expression method) + public Expression CreateExpressionTree (ResolveContext ec, Expression method) { string method_name; bool lift_arg = false; @@ -4205,6 +5025,12 @@ namespace Mono.CSharp public override void Emit (EmitContext ec) { + // Optimize by removing any extra null arguments, they are no-op + for (int i = 0; i < arguments.Count; ++i) { + if (arguments[i].Expr is NullConstant) + arguments.RemoveAt (i--); + } + var members = GetConcatMethodCandidates (); var res = new OverloadResolver (members, OverloadResolver.Restrictions.NoBaseMembers, loc); var method = res.ResolveMember (new ResolveContext (ec.MemberContext), ref arguments); @@ -4214,6 +5040,11 @@ namespace Mono.CSharp } } + public override void FlowAnalysis (FlowAnalysisContext fc) + { + arguments.FlowAnalysis (fc); + } + public override SLE.Expression MakeExpression (BuilderContext ctx) { if (arguments.Count != 2) @@ -4244,7 +5075,7 @@ namespace Mono.CSharp AParametersCollection pd = oper.Parameters; if (!TypeSpecComparer.IsEqual (type, pd.Types[0]) || !TypeSpecComparer.IsEqual (type, pd.Types[1])) { ec.Report.Error (217, loc, - "A user-defined operator `{0}' must have parameters and return values of the same type in order to be applicable as a short circuit operator", + "A user-defined operator `{0}' must have each parameter type and return type of the same type in order to be applicable as a short circuit operator", oper.GetSignatureForError ()); return null; } @@ -4255,7 +5086,7 @@ namespace Mono.CSharp if (op_true == null || op_false == null) { ec.Report.Error (218, loc, "The type `{0}' must have operator `true' and operator `false' defined when `{1}' is used as a short circuit operator", - TypeManager.CSharpName (type), oper.GetSignatureForError ()); + type.GetSignatureForError (), oper.GetSignatureForError ()); return null; } @@ -4303,7 +5134,7 @@ namespace Mono.CSharp public class PointerArithmetic : Expression { Expression left, right; - Binary.Operator op; + readonly Binary.Operator op; // // We assume that `l' is always a pointer @@ -4435,7 +5266,7 @@ namespace Mono.CSharp if (rtype.BuiltinType == BuiltinTypeSpec.Type.Long || rtype.BuiltinType == BuiltinTypeSpec.Type.ULong) ec.Emit (OpCodes.Conv_I8); - Binary.EmitOperatorOpcode (ec, Binary.Operator.Multiply, rtype); + Binary.EmitOperatorOpcode (ec, Binary.Operator.Multiply, rtype, right); } if (left_const == null) { @@ -4444,7 +5275,7 @@ namespace Mono.CSharp else if (rtype.BuiltinType == BuiltinTypeSpec.Type.ULong) ec.Emit (OpCodes.Conv_U); - Binary.EmitOperatorOpcode (ec, op, op_type); + Binary.EmitOperatorOpcode (ec, op, op_type, right); } } } @@ -4583,32 +5414,8 @@ namespace Mono.CSharp protected override Expression DoResolve (ResolveContext ec) { expr = expr.Resolve (ec); - - // - // Unreachable code needs different resolve path. For instance for await - // expression to not generate unreachable resumable statement - // - Constant c = expr as Constant; - if (c != null && ec.CurrentBranching != null) { - bool unreachable = ec.CurrentBranching.CurrentUsageVector.IsUnreachable; - - if (c.IsDefaultValue) { - ec.CurrentBranching.CurrentUsageVector.IsUnreachable = true; - true_expr = true_expr.Resolve (ec); - ec.CurrentBranching.CurrentUsageVector.IsUnreachable = unreachable; - - false_expr = false_expr.Resolve (ec); - } else { - true_expr = true_expr.Resolve (ec); - - ec.CurrentBranching.CurrentUsageVector.IsUnreachable = true; - false_expr = false_expr.Resolve (ec); - ec.CurrentBranching.CurrentUsageVector.IsUnreachable = unreachable; - } - } else { - true_expr = true_expr.Resolve (ec); - false_expr = false_expr.Resolve (ec); - } + true_expr = true_expr.Resolve (ec); + false_expr = false_expr.Resolve (ec); if (true_expr == null || false_expr == null || expr == null) return null; @@ -4630,24 +5437,48 @@ namespace Mono.CSharp // type = false_type; - if (false_type.BuiltinType != BuiltinTypeSpec.Type.Dynamic && Convert.ImplicitConversion (ec, false_expr, true_type, loc) != null) { - ec.Report.Error (172, true_expr.Location, - "Type of conditional expression cannot be determined as `{0}' and `{1}' convert implicitly to each other", - true_type.GetSignatureForError (), false_type.GetSignatureForError ()); - return null; + if (false_type.BuiltinType != BuiltinTypeSpec.Type.Dynamic) { + var conv_false_expr = Convert.ImplicitConversion (ec, false_expr, true_type, loc); + // + // LAMESPEC: There seems to be hardcoded promotition to int type when + // both sides are numeric constants and one side is int constant and + // other side is numeric constant convertible to int. + // + // var res = condition ? (short)1 : 1; + // + // Type of res is int even if according to the spec the conversion is + // ambiguous because 1 literal can be converted to short. + // + if (conv_false_expr != null) { + if (conv_false_expr.Type.BuiltinType == BuiltinTypeSpec.Type.Int && conv is Constant) { + type = true_type; + conv_false_expr = null; + } else if (type.BuiltinType == BuiltinTypeSpec.Type.Int && conv_false_expr is Constant) { + conv_false_expr = null; + } + } + + if (conv_false_expr != null) { + ec.Report.Error (172, true_expr.Location, + "Type of conditional expression cannot be determined as `{0}' and `{1}' convert implicitly to each other", + true_type.GetSignatureForError (), false_type.GetSignatureForError ()); + } } true_expr = conv; + if (true_expr.Type != type) + true_expr = EmptyCast.Create (true_expr, type); } else if ((conv = Convert.ImplicitConversion (ec, false_expr, true_type, loc)) != null) { false_expr = conv; } else { ec.Report.Error (173, true_expr.Location, "Type of conditional expression cannot be determined because there is no implicit conversion between `{0}' and `{1}'", - TypeManager.CSharpName (true_type), TypeManager.CSharpName (false_type)); + true_type.GetSignatureForError (), false_type.GetSignatureForError ()); return null; } - } + } + Constant c = expr as Constant; if (c != null) { bool is_false = c.IsDefaultValue; @@ -4655,8 +5486,8 @@ namespace Mono.CSharp // Don't issue the warning for constant expressions // if (!(is_false ? true_expr is Constant : false_expr is Constant)) { - ec.Report.Warning (429, 4, is_false ? true_expr.Location : false_expr.Location, - "Unreachable expression code detected"); + // CSC: Missing warning + Warning_UnreachableExpression (ec, is_false ? true_expr.Location : false_expr.Location); } return ReducedExpression.Create ( @@ -4675,12 +5506,46 @@ namespace Mono.CSharp expr.EmitBranchable (ec, false_target, false); true_expr.Emit (ec); + // + // Verifier doesn't support interface merging. When there are two types on + // the stack without common type hint and the common type is an interface. + // Use temporary local to give verifier hint on what type to unify the stack + // + if (type.IsInterface && true_expr is EmptyCast && false_expr is EmptyCast) { + var temp = ec.GetTemporaryLocal (type); + ec.Emit (OpCodes.Stloc, temp); + ec.Emit (OpCodes.Ldloc, temp); + ec.FreeTemporaryLocal (temp, type); + } + ec.Emit (OpCodes.Br, end_target); ec.MarkLabel (false_target); false_expr.Emit (ec); ec.MarkLabel (end_target); } + public override void FlowAnalysis (FlowAnalysisContext fc) + { + fc.DefiniteAssignmentOnTrue = fc.DefiniteAssignmentOnFalse = fc.DefiniteAssignment; + + expr.FlowAnalysis (fc); + var da_true = fc.DefiniteAssignmentOnTrue; + var da_false = fc.DefiniteAssignmentOnFalse; + + fc.DefiniteAssignment = new DefiniteAssignmentBitSet (da_true); + true_expr.FlowAnalysis (fc); + var true_fc = fc.DefiniteAssignment; + + fc.DefiniteAssignment = new DefiniteAssignmentBitSet (da_false); + false_expr.FlowAnalysis (fc); + + fc.DefiniteAssignment &= true_fc; + if (fc.DefiniteAssignmentOnTrue != null) + fc.DefiniteAssignmentOnTrue = fc.DefiniteAssignment; + if (fc.DefiniteAssignmentOnFalse != null) + fc.DefiniteAssignmentOnFalse = fc.DefiniteAssignment; + } + protected override void CloneTo (CloneContext clonectx, Expression t) { Conditional target = (Conditional) t; @@ -4703,7 +5568,6 @@ namespace Mono.CSharp #region Abstract public abstract HoistedVariable GetHoistedVariable (AnonymousExpression ae); public abstract void SetHasAddressTaken (); - public abstract void VerifyAssigned (ResolveContext rc); public abstract bool IsLockedByStatement { get; set; } @@ -4936,17 +5800,17 @@ namespace Mono.CSharp #endregion - public override void VerifyAssigned (ResolveContext rc) + public override void FlowAnalysis (FlowAnalysisContext fc) { - VariableInfo variable_info = local_info.VariableInfo; + VariableInfo variable_info = VariableInfo; if (variable_info == null) return; - if (variable_info.IsAssigned (rc)) + if (fc.IsDefinitelyAssigned (variable_info)) return; - rc.Report.Error (165, loc, "Use of unassigned local variable `{0}'", Name); - variable_info.SetAssigned (rc); + fc.Report.Error (165, loc, "Use of unassigned local variable `{0}'", Name); + variable_info.SetAssigned (fc.DefiniteAssignment, true); } public override void SetHasAddressTaken () @@ -4983,8 +5847,6 @@ namespace Mono.CSharp { local_info.SetIsUsed (); - VerifyAssigned (ec); - DoResolveBase (ec); return this; } @@ -4999,22 +5861,22 @@ namespace Mono.CSharp local_info.SetIsUsed (); if (local_info.IsReadonly && !ec.HasAny (ResolveContext.Options.FieldInitializerScope | ResolveContext.Options.UsingInitializerScope)) { - int code; - string msg; - if (rhs == EmptyExpression.OutAccess) { - code = 1657; msg = "Cannot pass `{0}' as a ref or out argument because it is a `{1}'"; - } else if (rhs == EmptyExpression.LValueMemberAccess) { - code = 1654; msg = "Cannot assign to members of `{0}' because it is a `{1}'"; - } else if (rhs == EmptyExpression.LValueMemberOutAccess) { - code = 1655; msg = "Cannot pass members of `{0}' as ref or out arguments because it is a `{1}'"; - } else if (rhs == EmptyExpression.UnaryAddress) { - code = 459; msg = "Cannot take the address of {1} `{0}'"; + if (rhs == EmptyExpression.LValueMemberAccess) { + // CS1654 already reported } else { - code = 1656; msg = "Cannot assign to `{0}' because it is a `{1}'"; + int code; + string msg; + if (rhs == EmptyExpression.OutAccess) { + code = 1657; msg = "Cannot pass `{0}' as a ref or out argument because it is a `{1}'"; + } else if (rhs == EmptyExpression.LValueMemberOutAccess) { + code = 1655; msg = "Cannot pass members of `{0}' as ref or out arguments because it is a `{1}'"; + } else if (rhs == EmptyExpression.UnaryAddress) { + code = 459; msg = "Cannot take the address of {1} `{0}'"; + } else { + code = 1656; msg = "Cannot assign to `{0}' because it is a `{1}'"; + } + ec.Report.Error (code, loc, msg, Name, local_info.GetReadOnlyContext ()); } - ec.Report.Error (code, loc, msg, Name, local_info.GetReadOnlyContext ()); - } else if (VariableInfo != null) { - VariableInfo.SetAssigned (ec); } if (eclass == ExprClass.Unresolved) @@ -5139,12 +6001,6 @@ namespace Mono.CSharp Parameter.HasAddressTaken = true; } - void SetAssigned (ResolveContext ec) - { - if (HasOutModifier && ec.DoFlowAnalysis) - ec.CurrentBranching.SetAssigned (VariableInfo); - } - bool DoResolveBase (ResolveContext ec) { if (eclass != ExprClass.Unresolved) @@ -5205,24 +6061,11 @@ namespace Mono.CSharp return Parameter.ExpressionTreeVariableReference (); } - // - // Notice that for ref/out parameters, the type exposed is not the - // same type exposed externally. - // - // for "ref int a": - // externally we expose "int&" - // here we expose "int". - // - // We record this in "is_ref". This means that the type system can treat - // the type as it is expected, but when we generate the code, we generate - // the alternate kind of code. - // protected override Expression DoResolve (ResolveContext ec) { if (!DoResolveBase (ec)) return null; - VerifyAssigned (ec); return this; } @@ -5231,19 +6074,23 @@ namespace Mono.CSharp if (!DoResolveBase (ec)) return null; - SetAssigned (ec); + if (Parameter.HoistedVariant != null) + Parameter.HoistedVariant.IsAssigned = true; + return base.DoResolveLValue (ec, right_side); } - public override void VerifyAssigned (ResolveContext rc) + public override void FlowAnalysis (FlowAnalysisContext fc) { - // HACK: Variables are not captured in probing mode - if (rc.IsInProbingMode) + VariableInfo variable_info = VariableInfo; + if (variable_info == null) + return; + + if (fc.IsDefinitelyAssigned (variable_info)) return; - if (HasOutModifier && !VariableInfo.IsAssigned (rc)) { - rc.Report.Error (269, loc, "Use of unassigned out parameter `{0}'", Name); - } + fc.Report.Error (269, loc, "Use of unassigned out parameter `{0}'", Name); + fc.SetVariableAssigned (variable_info); } } @@ -5265,8 +6112,7 @@ namespace Mono.CSharp this.expr = expr; this.arguments = arguments; if (expr != null) { - var ma = expr as MemberAccess; - loc = ma != null ? ma.GetLeftExpressionLocation () : expr.Location; + loc = expr.Location; } } @@ -5288,8 +6134,59 @@ namespace Mono.CSharp return mg; } } + + public override Location StartLocation { + get { + return expr.StartLocation; + } + } + #endregion + public override MethodGroupExpr CanReduceLambda (AnonymousMethodBody body) + { + if (MethodGroup == null) + return null; + + var candidate = MethodGroup.BestCandidate; + if (candidate == null || !(candidate.IsStatic || Exp is This)) + return null; + + var args_count = arguments == null ? 0 : arguments.Count; + if (args_count != body.Parameters.Count) + return null; + + var lambda_parameters = body.Block.Parameters.FixedParameters; + for (int i = 0; i < args_count; ++i) { + var pr = arguments[i].Expr as ParameterReference; + if (pr == null) + return null; + + if (lambda_parameters[i] != pr.Parameter) + return null; + + if ((lambda_parameters[i].ModFlags & Parameter.Modifier.RefOutMask) != (pr.Parameter.ModFlags & Parameter.Modifier.RefOutMask)) + return null; + } + + var emg = MethodGroup as ExtensionMethodGroupExpr; + if (emg != null) { + var mg = MethodGroupExpr.CreatePredefined (candidate, candidate.DeclaringType, MethodGroup.Location); + if (candidate.IsGeneric) { + var targs = new TypeExpression [candidate.Arity]; + for (int i = 0; i < targs.Length; ++i) { + targs[i] = new TypeExpression (candidate.TypeArguments[i], MethodGroup.Location); + } + + mg.SetTypeArguments (null, new TypeArguments (targs)); + } + + return mg; + } + + return MethodGroup; + } + protected override void CloneTo (CloneContext clonectx, Expression t) { Invocation target = (Invocation) t; @@ -5330,7 +6227,7 @@ namespace Mono.CSharp if (member_expr != null) member_expr = member_expr.Resolve (ec); } else { - member_expr = expr.Resolve (ec, ResolveFlags.VariableOrValue | ResolveFlags.MethodGroup); + member_expr = expr.Resolve (ec); } if (member_expr == null) @@ -5359,7 +6256,7 @@ namespace Mono.CSharp } else { if (member_expr is RuntimeValueExpression) { ec.Report.Error (Report.RuntimeErrorId, loc, "Cannot invoke a non-delegate type `{0}'", - member_expr.Type.GetSignatureForError ()); ; + member_expr.Type.GetSignatureForError ()); return null; } @@ -5461,6 +6358,17 @@ namespace Mono.CSharp return mg.OverloadResolve (ec, ref arguments, null, OverloadResolver.Restrictions.None); } + public override void FlowAnalysis (FlowAnalysisContext fc) + { + if (mg.IsConditionallyExcluded) + return; + + mg.FlowAnalysis (fc); + + if (arguments != null) + arguments.FlowAnalysis (fc); + } + public override string GetSignatureForError () { return mg.GetSignatureForError (); @@ -5501,6 +6409,9 @@ namespace Mono.CSharp public override void Emit (EmitContext ec) { + if (mg.IsConditionallyExcluded) + return; + mg.EmitCall (ec, arguments); } @@ -5684,7 +6595,7 @@ namespace Mono.CSharp if (type.IsPointer) { ec.Report.Error (1919, loc, "Unsafe type `{0}' cannot be used in an object creation expression", - TypeManager.CSharpName (type)); + type.GetSignatureForError ()); return null; } @@ -5707,13 +6618,13 @@ namespace Mono.CSharp if ((tparam.SpecialConstraint & (SpecialConstraint.Struct | SpecialConstraint.Constructor)) == 0 && !TypeSpec.IsValueType (tparam)) { ec.Report.Error (304, loc, "Cannot create an instance of the variable type `{0}' because it does not have the new() constraint", - TypeManager.CSharpName (type)); + type.GetSignatureForError ()); } if ((arguments != null) && (arguments.Count != 0)) { ec.Report.Error (417, loc, "`{0}': cannot provide arguments when creating an instance of a variable type", - TypeManager.CSharpName (type)); + type.GetSignatureForError ()); } return this; @@ -5721,7 +6632,7 @@ namespace Mono.CSharp if (type.IsStatic) { ec.Report.SymbolRelatedToPreviousError (type); - ec.Report.Error (712, loc, "Cannot create an instance of the static class `{0}'", TypeManager.CSharpName (type)); + ec.Report.Error (712, loc, "Cannot create an instance of the static class `{0}'", type.GetSignatureForError ()); return null; } @@ -5733,7 +6644,7 @@ namespace Mono.CSharp } ec.Report.SymbolRelatedToPreviousError (type); - ec.Report.Error (144, loc, "Cannot create an instance of the abstract class or interface `{0}'", TypeManager.CSharpName (type)); + ec.Report.Error (144, loc, "Cannot create an instance of the abstract class or interface `{0}'", type.GetSignatureForError ()); return null; } @@ -5854,14 +6765,16 @@ namespace Mono.CSharp } if (vr != null) { + ec.MarkCallEntry (loc); ec.Emit (OpCodes.Call, method); return false; } } if (type is TypeParameterSpec) - return DoEmitTypeParameter (ec); + return DoEmitTypeParameter (ec); + ec.MarkCallEntry (loc); ec.Emit (OpCodes.Newobj, method); return true; } @@ -5877,7 +6790,7 @@ namespace Mono.CSharp if (!Emit (ec, v)) v.Emit (ec); } - + public override void EmitStatement (EmitContext ec) { LocalTemporary v = null; @@ -5890,6 +6803,12 @@ namespace Mono.CSharp ec.Emit (OpCodes.Pop); } + public override void FlowAnalysis (FlowAnalysisContext fc) + { + if (arguments != null) + arguments.FlowAnalysis (fc); + } + public void AddressOf (EmitContext ec, AddressOp mode) { EmitAddressOf (ec, mode); @@ -5955,7 +6874,7 @@ namespace Mono.CSharp public class ArrayInitializer : Expression { List elements; - BlockVariableDeclaration variable; + BlockVariable variable; public ArrayInitializer (List init, Location loc) { @@ -5991,7 +6910,7 @@ namespace Mono.CSharp } } - public BlockVariableDeclaration VariableDeclaration { + public BlockVariable VariableDeclaration { get { return variable; } @@ -6049,6 +6968,11 @@ namespace Mono.CSharp { throw new InternalErrorException ("Missing Resolve call"); } + + public override void FlowAnalysis (FlowAnalysisContext fc) + { + throw new InternalErrorException ("Missing Resolve call"); + } public override object Accept (StructuralVisitor visitor) { @@ -6078,7 +7002,7 @@ namespace Mono.CSharp protected List arguments; protected TypeSpec array_element_type; - int num_arguments = 0; + int num_arguments; protected int dimensions; protected readonly ComposedTypeSpecifier rank; Expression first_emit; @@ -6159,7 +7083,7 @@ namespace Mono.CSharp // 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 (); + array_data = new List (probe.Count); bounds = new Dictionary (); } @@ -6314,6 +7238,17 @@ namespace Mono.CSharp ec.Report.Error (248, loc, "Cannot create an array with a negative size"); } + public override void FlowAnalysis (FlowAnalysisContext fc) + { + foreach (var arg in arguments) + arg.FlowAnalysis (fc); + + if (array_data != null) { + foreach (var ad in array_data) + ad.FlowAnalysis (fc); + } + } + bool InitializersContainAwait () { if (array_data == null) @@ -6465,12 +7400,12 @@ namespace Mono.CSharp } break; case BuiltinTypeSpec.Type.Float: - element = BitConverter.GetBytes ((float) v); + var fval = SingleConverter.SingleToInt32Bits((float) v); - for (int j = 0; j < factor; ++j) - data[idx + j] = element[j]; - if (!BitConverter.IsLittleEndian) - System.Array.Reverse (data, idx, 4); + data[idx] = (byte) (fval & 0xff); + data[idx + 1] = (byte) ((fval >> 8) & 0xff); + data[idx + 2] = (byte) ((fval >> 16) & 0xff); + data[idx + 3] = (byte) (fval >> 24); break; case BuiltinTypeSpec.Type.Double: element = BitConverter.GetBytes ((double) v); @@ -6553,7 +7488,7 @@ namespace Mono.CSharp return data; } -#if NET_4_0 || MONODROID +#if NET_4_0 || MOBILE_DYNAMIC public override SLE.Expression MakeExpression (BuilderContext ctx) { #if STATIC @@ -6604,7 +7539,7 @@ namespace Mono.CSharp // // This always expect the top value on the stack to be the array // - void EmitDynamicInitializers (EmitContext ec, bool emitConstants, FieldExpr stackArray) + void EmitDynamicInitializers (EmitContext ec, bool emitConstants, StackFieldExpr stackArray) { int dims = bounds.Count; var current_pos = new int [dims]; @@ -6624,7 +7559,7 @@ namespace Mono.CSharp e = e.EmitToField (ec); } - stackArray.Emit (ec); + stackArray.EmitLoad (ec); } else { ec.Emit (OpCodes.Dup); } @@ -6636,26 +7571,8 @@ namespace Mono.CSharp // If we are dealing with a struct, get the // address of it, so we can store it. // - if (dims == 1 && etype.IsStruct) { - switch (etype.BuiltinType) { - case BuiltinTypeSpec.Type.Byte: - case BuiltinTypeSpec.Type.SByte: - case BuiltinTypeSpec.Type.Bool: - case BuiltinTypeSpec.Type.Short: - case BuiltinTypeSpec.Type.UShort: - case BuiltinTypeSpec.Type.Char: - case BuiltinTypeSpec.Type.Int: - case BuiltinTypeSpec.Type.UInt: - case BuiltinTypeSpec.Type.Long: - case BuiltinTypeSpec.Type.ULong: - case BuiltinTypeSpec.Type.Float: - case BuiltinTypeSpec.Type.Double: - break; - default: - ec.Emit (OpCodes.Ldelema, etype); - break; - } - } + if (dims == 1 && etype.IsStruct && !BuiltinTypeSpec.IsPrimitiveType (etype)) + ec.Emit (OpCodes.Ldelema, etype); e.Emit (ec); @@ -6672,11 +7589,16 @@ namespace Mono.CSharp current_pos [j] = 0; } } + + if (stackArray != null) + stackArray.PrepareCleanup (ec); } public override void Emit (EmitContext ec) { - EmitToFieldSource (ec); + var await_field = EmitToFieldSource (ec); + if (await_field != null) + await_field.Emit (ec); } protected sealed override FieldExpr EmitToFieldSource (EmitContext ec) @@ -6686,7 +7608,7 @@ namespace Mono.CSharp first_emit_temp.Store (ec); } - FieldExpr await_stack_field; + StackFieldExpr await_stack_field; if (ec.HasSet (BuilderContext.Options.AsyncBody) && InitializersContainAwait ()) { await_stack_field = ec.GetTemporaryField (type); ec.EmitThis (); @@ -6730,18 +7652,18 @@ namespace Mono.CSharp return await_stack_field; } - public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType) + public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType, TypeSpec parameterType) { // no multi dimensional or jagged arrays if (arguments.Count != 1 || array_element_type.IsArray) { - base.EncodeAttributeValue (rc, enc, targetType); + base.EncodeAttributeValue (rc, enc, targetType, parameterType); return; } // No array covariance, except for array -> object if (type != targetType) { if (targetType.BuiltinType != BuiltinTypeSpec.Type.Object) { - base.EncodeAttributeValue (rc, enc, targetType); + base.EncodeAttributeValue (rc, enc, targetType, parameterType); return; } @@ -6755,7 +7677,7 @@ namespace Mono.CSharp if (array_data == null) { IntConstant ic = arguments[0] as IntConstant; if (ic == null || !ic.IsDefaultValue) { - base.EncodeAttributeValue (rc, enc, targetType); + base.EncodeAttributeValue (rc, enc, targetType, parameterType); } else { enc.Encode (0); } @@ -6765,7 +7687,7 @@ namespace Mono.CSharp enc.Encode (array_data.Count); foreach (var element in array_data) { - element.EncodeAttributeValue (rc, enc, array_element_type); + element.EncodeAttributeValue (rc, enc, array_element_type, parameterType); } } @@ -6797,38 +7719,7 @@ namespace Mono.CSharp // class ImplicitlyTypedArrayCreation : ArrayCreation { - sealed class InferenceContext : TypeInferenceContext - { - class ExpressionBoundInfo : BoundInfo - { - readonly Expression expr; - - public ExpressionBoundInfo (Expression expr) - : base (expr.Type, BoundKind.Lower) - { - this.expr = expr; - } - - public override bool Equals (BoundInfo other) - { - // We are using expression not type for conversion check - // no optimization based on types is possible - return false; - } - - public override Expression GetTypeExpression () - { - return expr; - } - } - - public void AddExpression (Expression expr) - { - AddToBounds (new ExpressionBoundInfo (expr), 0); - } - } - - InferenceContext best_type_inference; + TypeInferenceContext best_type_inference; public ImplicitlyTypedArrayCreation (ComposedTypeSpecifier rank, ArrayInitializer initializers, Location loc) : base (null, rank, initializers, loc) @@ -6847,7 +7738,7 @@ namespace Mono.CSharp dimensions = rank.Dimension; - best_type_inference = new InferenceContext (); + best_type_inference = new TypeInferenceContext (); if (!ResolveInitializers (ec)) return null; @@ -6892,7 +7783,7 @@ namespace Mono.CSharp { element = element.Resolve (ec); if (element != null) - best_type_inference.AddExpression (element); + best_type_inference.AddCommonTypeBound (element.Type); return element; } @@ -6989,7 +7880,7 @@ namespace Mono.CSharp #endregion - public void CheckStructThisDefiniteAssignment (ResolveContext rc) + void CheckStructThisDefiniteAssignment (FlowAnalysisContext fc) { // // It's null for all cases when we don't need to check `this' @@ -6998,13 +7889,10 @@ namespace Mono.CSharp if (variable_info == null) return; - if (rc.OmitStructFlowAnalysis) + if (fc.IsDefinitelyAssigned (variable_info)) return; - if (!variable_info.IsAssigned (rc)) { - rc.Report.Error (188, loc, - "The `this' object cannot be used before all of its fields are assigned to"); - } + fc.Report.Error (188, loc, "The `this' object cannot be used before all of its fields are assigned to"); } protected virtual void Error_ThisNotAvailable (ResolveContext ec) @@ -7020,6 +7908,11 @@ namespace Mono.CSharp } } + public override void FlowAnalysis (FlowAnalysisContext fc) + { + CheckStructThisDefiniteAssignment (fc); + } + public override HoistedVariable GetHoistedVariable (AnonymousExpression ae) { if (ae == null) @@ -7065,7 +7958,7 @@ namespace Mono.CSharp // Hoisted this is almost like hoisted variable but not exactly. When // there is no variable hoisted we can simply emit an instance method // without lifting this into a storey. Unfotunatelly this complicates - // this in other cases because we don't know where this will be hoisted + // things in other cases because we don't know where this will be hoisted // until top-level block is fully resolved // top.AddThisReferenceFromChildrenBlock (block.Explicit); @@ -7077,9 +7970,6 @@ namespace Mono.CSharp protected override Expression DoResolve (ResolveContext ec) { ResolveBase (ec); - - CheckStructThisDefiniteAssignment (ec); - return this; } @@ -7088,9 +7978,6 @@ namespace Mono.CSharp if (eclass == ExprClass.Unresolved) ResolveBase (ec); - if (variable_info != null) - variable_info.SetAssigned (ec); - if (type.IsClass){ if (right_side == EmptyExpression.UnaryAddress) ec.Report.Error (459, loc, "Cannot take the address of `this' because it is read-only"); @@ -7126,12 +8013,6 @@ namespace Mono.CSharp { // Nothing } - - public override void VerifyAssigned (ResolveContext rc) - { - - } - public override object Accept (StructuralVisitor visitor) { @@ -7268,7 +8149,7 @@ namespace Mono.CSharp } } - public class RefValueExpr : ShimExpression + public class RefValueExpr : ShimExpression, IAssignMethod { FullNamedExpression texpr; @@ -7306,13 +8187,44 @@ namespace Mono.CSharp return this; } + public override Expression DoResolveLValue (ResolveContext rc, Expression right_side) + { + return DoResolve (rc); + } + public override void Emit (EmitContext ec) { expr.Emit (ec); ec.Emit (OpCodes.Refanyval, type); ec.EmitLoadFromPtr (type); } - + + public void Emit (EmitContext ec, bool leave_copy) + { + throw new NotImplementedException (); + } + + public void EmitAssign (EmitContext ec, Expression source, bool leave_copy, bool isCompound) + { + expr.Emit (ec); + ec.Emit (OpCodes.Refanyval, type); + source.Emit (ec); + + LocalTemporary temporary = null; + if (leave_copy) { + ec.Emit (OpCodes.Dup); + temporary = new LocalTemporary (source.Type); + temporary.Store (ec); + } + + ec.EmitStoreFromPtr (type); + + if (temporary != null) { + temporary.Emit (ec); + temporary.Release (ec); + } + } + public override object Accept (StructuralVisitor visitor) { return visitor.Visit (this); @@ -7503,7 +8415,7 @@ namespace Mono.CSharp return false; } - public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType) + public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType, TypeSpec parameterType) { // Target type is not System.Type therefore must be object // and we need to use different encoding sequence @@ -7730,7 +8642,7 @@ namespace Mono.CSharp if (!ec.IsUnsafe) { ec.Report.Error (233, loc, "`{0}' does not have a predefined size, therefore sizeof can only be used in an unsafe context (consider using System.Runtime.InteropServices.Marshal.SizeOf)", - TypeManager.CSharpName (type_queried)); + type_queried.GetSignatureForError ()); } type = ec.BuiltinTypes.Int; @@ -7788,7 +8700,7 @@ namespace Mono.CSharp public override FullNamedExpression ResolveAsTypeOrNamespace (IMemberContext ec) { if (alias == GlobalAlias) { - expr = ec.Module.GlobalRootNamespace; + expr = new NamespaceExpression (ec.Module.GlobalRootNamespace, loc); return base.ResolveAsTypeOrNamespace (ec); } @@ -7848,13 +8760,6 @@ namespace Mono.CSharp public class MemberAccess : ATypeNameExpression { protected Expression expr; - -#if FULL_AST - public Location DotLocation { - get; - set; - } -#endif public MemberAccess (Expression expr, string id) : base (id, expr.Location) @@ -7886,52 +8791,33 @@ namespace Mono.CSharp } } - protected override Expression DoResolve (ResolveContext rc) - { - var e = DoResolveName (rc, null); - - if (!rc.OmitStructFlowAnalysis) { - var fe = e as FieldExpr; - if (fe != null) { - fe.VerifyAssignedStructField (rc, null); - } + public override Location StartLocation { + get { + return expr == null ? loc : expr.StartLocation; } - - return e; } - public override Expression DoResolveLValue (ResolveContext rc, Expression rhs) + protected override Expression DoResolve (ResolveContext rc) { - var e = DoResolveName (rc, rhs); - - if (!rc.OmitStructFlowAnalysis) { - var fe = e as FieldExpr; - if (fe != null && fe.InstanceExpression is FieldExpr) { - fe = (FieldExpr) fe.InstanceExpression; - fe.VerifyAssignedStructField (rc, rhs); - } - } + var e = LookupNameExpression (rc, MemberLookupRestrictions.ReadAccess); + if (e != null) + e = e.Resolve (rc, ResolveFlags.VariableOrValue | ResolveFlags.Type | ResolveFlags.MethodGroup); return e; } - Expression DoResolveName (ResolveContext rc, Expression right_side) + public override Expression DoResolveLValue (ResolveContext rc, Expression rhs) { - Expression e = LookupNameExpression (rc, right_side == null ? MemberLookupRestrictions.ReadAccess : MemberLookupRestrictions.None); - if (e == null) - return null; - - if (right_side != null) { - if (e is TypeExpr) { - e.Error_UnexpectedKind (rc, ResolveFlags.VariableOrValue, loc); - return null; - } + var e = LookupNameExpression (rc, MemberLookupRestrictions.None); - e = e.ResolveLValue (rc, right_side); - } else { - e = e.Resolve (rc, ResolveFlags.VariableOrValue | ResolveFlags.Type); + if (e is TypeExpr) { + e.Error_UnexpectedKind (rc, ResolveFlags.VariableOrValue, loc); + return null; } + if (e != null) + e = e.ResolveLValue (rc, rhs); + return e; } @@ -7943,18 +8829,6 @@ 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 | @@ -7968,43 +8842,33 @@ namespace Mono.CSharp var sn = expr as SimpleName; const ResolveFlags flags = ResolveFlags.VariableOrValue | ResolveFlags.Type; - // - // Resolve the expression with flow analysis turned off, we'll do the definite - // assignment checks later. This is because we don't know yet what the expression - // will resolve to - it may resolve to a FieldExpr and in this case we must do the - // definite assignment check on the actual field and not on the whole struct. - // - using (rc.Set (ResolveContext.Options.OmitStructFlowAnalysis)) { - if (sn != null) { - expr = sn.LookupNameExpression (rc, MemberLookupRestrictions.ReadAccess | MemberLookupRestrictions.ExactArity); + if (sn != null) { + expr = sn.LookupNameExpression (rc, MemberLookupRestrictions.ReadAccess | MemberLookupRestrictions.ExactArity); - // - // Resolve expression which does have type set as we need expression type - // with disable flow analysis as we don't know whether left side expression - // is used as variable or type - // - if (expr is VariableReference || expr is ConstantExpr || expr is Linq.TransparentMemberAccess) { - using (rc.With (ResolveContext.Options.DoFlowAnalysis, false)) { - expr = expr.Resolve (rc); - } - } else if (expr is TypeParameterExpr) { - expr.Error_UnexpectedKind (rc, flags, sn.Location); - expr = null; - } - } else { - expr = expr.Resolve (rc, flags); + // + // Resolve expression which does have type set as we need expression type + // with disable flow analysis as we don't know whether left side expression + // is used as variable or type + // + if (expr is VariableReference || expr is ConstantExpr || expr is Linq.TransparentMemberAccess || expr is EventExpr) { + expr = expr.Resolve (rc); + } else if (expr is TypeParameterExpr) { + expr.Error_UnexpectedKind (rc, flags, sn.Location); + expr = null; } + } else { + expr = expr.Resolve (rc, flags); } if (expr == null) return null; - Namespace ns = expr as Namespace; + var ns = expr as NamespaceExpression; if (ns != null) { var retval = ns.LookupTypeOrNamespace (rc, Name, Arity, LookupMode.Normal, loc); if (retval == null) { - ns.Error_NamespaceDoesNotExist (rc, Name, Arity, loc); + ns.Error_NamespaceDoesNotExist (rc, Name, Arity); return null; } @@ -8021,16 +8885,6 @@ namespace Mono.CSharp if (me != null) me.ResolveInstanceExpression (rc, null); - // - // Run defined assigned checks on expressions resolved with - // disabled flow-analysis - // - if (sn != null) { - var vr = expr as VariableReference; - if (vr != null) - vr.VerifyAssigned (rc); - } - Arguments args = new Arguments (1); args.Add (new Argument (expr)); return new DynamicMemberBinder (Name, args, loc); @@ -8061,16 +8915,6 @@ namespace Mono.CSharp emg.SetTypeArguments (rc, targs); } - // - // Run defined assigned checks on expressions resolved with - // disabled flow-analysis - // - if (sn != null && !errorMode) { - var vr = expr as VariableReference; - if (vr != null) - vr.VerifyAssigned (rc); - } - // TODO: it should really skip the checks bellow return emg.Resolve (rc); } @@ -8091,7 +8935,7 @@ namespace Mono.CSharp return null; } - if (member_lookup is MethodGroupExpr) { + if (member_lookup is MethodGroupExpr || member_lookup is PropertyExpr) { // Leave it to overload resolution to report correct error } else if (!(member_lookup is TypeExpr)) { // TODO: rc.SymbolRelatedToPreviousError @@ -8110,13 +8954,9 @@ namespace Mono.CSharp TypeExpr texpr = member_lookup as TypeExpr; if (texpr != null) { - if (!(expr is TypeExpr)) { - me = expr as MemberExpr; - if (me == null || me.ProbeIdenticalTypeName (rc, expr, sn) == expr) { - rc.Report.Error (572, loc, "`{0}': cannot reference a type through an expression; try `{1}' instead", - Name, member_lookup.GetSignatureForError ()); - return null; - } + if (!(expr is TypeExpr) && (sn == null || expr.ProbeIdenticalTypeName (rc, expr, sn) == expr)) { + rc.Report.Error (572, loc, "`{0}': cannot reference a type through an expression. Consider using `{1}' instead", + Name, texpr.GetSignatureForError ()); } if (!texpr.Type.IsAccessible (rc)) { @@ -8147,16 +8987,6 @@ namespace Mono.CSharp me.SetTypeArguments (rc, targs); } - // - // Run defined assigned checks on expressions resolved with - // disabled flow-analysis - // - if (sn != null && !(me is FieldExpr && TypeSpec.IsValueType (expr_type))) { - var vr = expr as VariableReference; - if (vr != null) - vr.VerifyAssigned (rc); - } - return me; } @@ -8173,12 +9003,12 @@ namespace Mono.CSharp if (expr_resolved == null) return null; - Namespace ns = expr_resolved as Namespace; + var ns = expr_resolved as NamespaceExpression; if (ns != null) { FullNamedExpression retval = ns.LookupTypeOrNamespace (rc, Name, Arity, LookupMode.Normal, loc); if (retval == null) { - ns.Error_NamespaceDoesNotExist (rc, Name, Arity, loc); + ns.Error_NamespaceDoesNotExist (rc, Name, Arity); } else if (HasTypeArguments) { retval = new GenericTypeExpr (retval.Type, targs, loc); if (retval.ResolveAsType (rc) == null) @@ -8257,13 +9087,13 @@ namespace Mono.CSharp var nested = MemberCache.FindNestedType (expr_type, Name, -System.Math.Max (1, Arity)); if (nested != null) { - Error_TypeArgumentsCannotBeUsed (rc, nested, Arity, expr.Location); + Error_TypeArgumentsCannotBeUsed (rc, nested, expr.Location); return; } var any_other_member = MemberLookup (rc, false, expr_type, Name, 0, MemberLookupRestrictions.None, loc); if (any_other_member != null) { - any_other_member.Error_UnexpectedKind (rc, any_other_member, "type", any_other_member.ExprClassName, loc); + Error_UnexpectedKind (rc, any_other_member, "type", any_other_member.ExprClassName, loc); return; } @@ -8271,12 +9101,17 @@ namespace Mono.CSharp Name, expr_type.GetSignatureForError ()); } + protected override void Error_InvalidExpressionStatement (Report report, Location loc) + { + base.Error_InvalidExpressionStatement (report, LeftExpression.Location); + } + protected override void Error_TypeDoesNotContainDefinition (ResolveContext ec, TypeSpec type, string name) { 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); + var cand = ec.Module.GlobalRootNamespace.FindExtensionMethodNamespaces (ec, name, Arity); string missing; // a using directive or an assembly reference if (cand != null) { @@ -8364,6 +9199,11 @@ namespace Mono.CSharp Expr.EmitBranchable (ec, target, on_true); } + public override void FlowAnalysis (FlowAnalysisContext fc) + { + Expr.FlowAnalysis (fc); + } + public override SLE.Expression MakeExpression (BuilderContext ctx) { using (ctx.With (BuilderContext.Options.CheckedScope, true)) { @@ -8436,6 +9276,11 @@ namespace Mono.CSharp Expr.EmitBranchable (ec, target, on_true); } + public override void FlowAnalysis (FlowAnalysisContext fc) + { + Expr.FlowAnalysis (fc); + } + protected override void CloneTo (CloneContext clonectx, Expression t) { UnCheckedExpr target = (UnCheckedExpr) t; @@ -8467,6 +9312,12 @@ namespace Mono.CSharp this.Arguments = args; } + public override Location StartLocation { + get { + return Expr.StartLocation; + } + } + public override bool ContainsEmitWithAwait () { return Expr.ContainsEmitWithAwait () || Arguments.ContainsEmitWithAwait (); @@ -8513,17 +9364,24 @@ namespace Mono.CSharp return CreateExpressionFactoryCall (ec, "ArrayIndex", args); } - Expression MakePointerAccess (ResolveContext ec, TypeSpec type) + Expression MakePointerAccess (ResolveContext rc, TypeSpec type) { if (Arguments.Count != 1){ - ec.Report.Error (196, loc, "A pointer must be indexed by only one value"); + rc.Report.Error (196, loc, "A pointer must be indexed by only one value"); return null; } - if (Arguments [0] is NamedArgument) - Error_NamedArgument ((NamedArgument) Arguments[0], ec.Report); + var arg = Arguments[0]; + if (arg is NamedArgument) + Error_NamedArgument ((NamedArgument) arg, rc.Report); + + var index = arg.Expr.Resolve (rc); + if (index == null) + return null; + + index = ConvertExpressionToArrayIndex (rc, index, true); - Expression p = new PointerArithmetic (Binary.Operator.Addition, Expr, Arguments [0].Expr.Resolve (ec), type, loc); + Expression p = new PointerArithmetic (Binary.Operator.Addition, Expr, index, type, loc); return new Indirection (p, loc); } @@ -8555,11 +9413,6 @@ namespace Mono.CSharp if (res == null) return null; - bool lvalue_instance = rhs != null && type.IsStruct && (Expr is Invocation || Expr is PropertyExpr); - if (lvalue_instance) { - Expr.Error_ValueAssignment (ec, EmptyExpression.LValueMemberAccess); - } - return res.ResolveLValue (ec, rhs); } @@ -8573,6 +9426,12 @@ namespace Mono.CSharp Report.Error (1742, na.Location, "An element access expression cannot use named argument"); } + public override void FlowAnalysis (FlowAnalysisContext fc) + { + Expr.FlowAnalysis (fc); + Arguments.FlowAnalysis (fc); + } + public override string GetSignatureForError () { return Expr.GetSignatureForError (); @@ -8616,6 +9475,10 @@ namespace Mono.CSharp { var ac = (ArrayContainer) ea.Expr.Type; + if (!has_await_args.HasValue && ec.HasSet (BuilderContext.Options.AsyncBody) && ea.Arguments.ContainsEmitWithAwait ()) { + LoadInstanceAndArguments (ec, false, true); + } + LoadInstanceAndArguments (ec, false, false); if (ac.Element.IsGenericParameter && mode == AddressOp.Load) @@ -8675,6 +9538,11 @@ namespace Mono.CSharp ec.Report.Warning (251, 2, loc, "Indexing an array with a negative index (array indices always start at zero)"); } + public override void FlowAnalysis (FlowAnalysisContext fc) + { + ea.FlowAnalysis (fc); + } + // // Load the array arguments into the stack. // @@ -8807,12 +9675,13 @@ namespace Mono.CSharp // CallRef (ref a[await Task.Factory.StartNew (() => 1)]); // ea.Expr = ea.Expr.EmitToField (ec); + ea.Arguments = ea.Arguments.Emit (ec, false, true); return this; } public SLE.Expression MakeAssignExpression (BuilderContext ctx, Expression source) { -#if NET_4_0 || MONODROID +#if NET_4_0 || MOBILE_DYNAMIC return SLE.Expression.ArrayAccess (ea.Expr.MakeExpression (ctx), MakeExpressionArguments (ctx)); #else throw new NotImplementedException (); @@ -8972,6 +9841,13 @@ namespace Mono.CSharp } } + public override void FlowAnalysis (FlowAnalysisContext fc) + { + // TODO: Check the order + base.FlowAnalysis (fc); + arguments.FlowAnalysis (fc); + } + public override string GetSignatureForError () { return best_candidate.GetSignatureForError (); @@ -8984,7 +9860,7 @@ namespace Mono.CSharp #else var value = new[] { source.MakeExpression (ctx) }; var args = Arguments.MakeExpression (arguments, ctx).Concat (value); -#if NET_4_0 || MONODROID +#if NET_4_0 || MOBILE_DYNAMIC return SLE.Expression.Block ( SLE.Expression.Call (InstanceExpression.MakeExpression (ctx), (MethodInfo) Setter.GetMetaInfo (), args), value [0]); @@ -9129,8 +10005,8 @@ namespace Mono.CSharp { base.Emit (ec); - var context_type = ec.CurrentType; - if (context_type.IsStruct) { + if (type == ec.Module.Compiler.BuiltinTypes.ValueType) { + var context_type = ec.CurrentType; ec.Emit (OpCodes.Ldobj, context_type); ec.Emit (OpCodes.Box, context_type); } @@ -9201,6 +10077,10 @@ namespace Mono.CSharp loc = Location.Null; } + protected override void CloneTo (CloneContext clonectx, Expression target) + { + } + public override bool ContainsEmitWithAwait () { return false; @@ -9351,6 +10231,9 @@ namespace Mono.CSharp public UserCast (MethodSpec method, Expression source, Location l) { + if (source == null) + throw new ArgumentNullException ("source"); + this.method = method; this.source = source; type = method.ReturnType; @@ -9390,9 +10273,15 @@ namespace Mono.CSharp public override void Emit (EmitContext ec) { source.Emit (ec); + ec.MarkCallEntry (loc); ec.Emit (OpCodes.Call, method); } + public override void FlowAnalysis (FlowAnalysisContext fc) + { + source.FlowAnalysis (fc); + } + public override string GetSignatureForError () { return TypeManager.CSharpSignature (method); @@ -9921,6 +10810,12 @@ namespace Mono.CSharp this.loc = loc; } + public CollectionElementInitializer (Location loc) + : base (null, null) + { + this.loc = loc; + } + public override Expression CreateExpressionTree (ResolveContext ec) { Arguments args = new Arguments (2); @@ -9957,9 +10852,11 @@ namespace Mono.CSharp { IList initializers; bool is_collection_initialization; - - public static readonly CollectionOrObjectInitializers Empty = - new CollectionOrObjectInitializers (Array.AsReadOnly (new Expression [0]), Location.Null); + + public CollectionOrObjectInitializers (Location loc) + : this (new Expression[0], loc) + { + } public CollectionOrObjectInitializers (IList initializers, Location loc) { @@ -10045,8 +10942,8 @@ namespace Mono.CSharp ec.Report.Error (1922, loc, "A field or property `{0}' cannot be initialized with a collection " + "object initializer because type `{1}' does not implement `{2}' interface", ec.CurrentInitializerVariable.GetSignatureForError (), - TypeManager.CSharpName (ec.CurrentInitializerVariable.Type), - TypeManager.CSharpName (ec.BuiltinTypes.IEnumerable)); + ec.CurrentInitializerVariable.Type.GetSignatureForError (), + ec.BuiltinTypes.IEnumerable.GetSignatureForError ()); return null; } is_collection_initialization = true; @@ -10080,7 +10977,7 @@ namespace Mono.CSharp if (is_collection_initialization) { if (TypeManager.HasElementType (type)) { ec.Report.Error (1925, loc, "Cannot initialize object of type `{0}' with a collection initializer", - TypeManager.CSharpName (type)); + type.GetSignatureForError ()); } } @@ -10101,6 +10998,12 @@ namespace Mono.CSharp e.EmitStatement (ec); } } + + public override void FlowAnalysis (FlowAnalysisContext fc) + { + foreach (var initializer in initializers) + initializer.FlowAnalysis (fc); + } } // @@ -10169,6 +11072,7 @@ namespace Mono.CSharp CollectionOrObjectInitializers initializers; IMemoryLocation instance; + DynamicExpressionStatement dynamic; public NewInitialize (FullNamedExpression requested_type, Arguments arguments, CollectionOrObjectInitializers initializers, Location l) : base (requested_type, arguments, l) @@ -10213,16 +11117,46 @@ namespace Mono.CSharp if (type == null) return null; + if (type.IsDelegate) { + ec.Report.Error (1958, Initializers.Location, + "Object and collection initializers cannot be used to instantiate a delegate"); + } + Expression previous = ec.CurrentInitializerVariable; ec.CurrentInitializerVariable = new InitializerTargetExpression (this); initializers.Resolve (ec); ec.CurrentInitializerVariable = previous; + + dynamic = e as DynamicExpressionStatement; + if (dynamic != null) + return this; + return e; } + public override void Emit (EmitContext ec) + { + if (method == null && TypeSpec.IsValueType (type) && initializers.Initializers.Count > 1 && ec.HasSet (BuilderContext.Options.AsyncBody) && initializers.ContainsEmitWithAwait ()) { + var fe = ec.GetTemporaryField (type); + + if (!Emit (ec, fe)) + fe.Emit (ec); + + return; + } + + base.Emit (ec); + } + public override bool Emit (EmitContext ec, IMemoryLocation target) { - bool left_on_stack = base.Emit (ec, target); + bool left_on_stack; + if (dynamic != null) { + dynamic.Emit (ec); + left_on_stack = true; + } else { + left_on_stack = base.Emit (ec, target); + } if (initializers.IsEmpty) return left_on_stack; @@ -10230,6 +11164,8 @@ namespace Mono.CSharp LocalTemporary temp = null; instance = target as LocalTemporary; + if (instance == null) + instance = target as StackFieldExpr; if (instance == null) { if (!left_on_stack) { @@ -10278,6 +11214,12 @@ namespace Mono.CSharp return instance; } + public override void FlowAnalysis (FlowAnalysisContext fc) + { + base.FlowAnalysis (fc); + initializers.FlowAnalysis (fc); + } + public override object Accept (StructuralVisitor visitor) { return visitor.Visit (this); @@ -10332,6 +11274,7 @@ namespace Mono.CSharp type.Define (); if ((ec.Report.Errors - errors) == 0) { parent.Module.AddAnonymousType (type); + type.PrepareEmit (); } return type; @@ -10400,11 +11343,6 @@ namespace Mono.CSharp eclass = ExprClass.Value; return this; } - - public override void EmitStatement (EmitContext ec) - { - base.EmitStatement (ec); - } public override object Accept (StructuralVisitor visitor) { @@ -10467,4 +11405,13 @@ namespace Mono.CSharp Name, initializer); } } + + public class CatchFilterExpression : BooleanExpression + { + public CatchFilterExpression (Expression expr, Location loc) + : base (expr) + { + this.loc = loc; + } + } } diff --git a/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/field.cs b/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/field.cs index 580b192a6..b7f686e02 100644 --- a/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/field.cs +++ b/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/field.cs @@ -42,6 +42,11 @@ namespace Mono.CSharp public Expression Initializer { get; private set; } #endregion + + public virtual FullNamedExpression GetFieldTypeExpression (FieldBase field) + { + return new TypeExpression (field.MemberType, Name.Location); + } } // @@ -217,7 +222,9 @@ namespace Mono.CSharp if (MemberType.IsStatic) Error_VariableOfStaticClass (Location, GetSignatureForError (), MemberType, Report); - CheckBase (); + if (!IsCompilerGenerated) + CheckBase (); + IsTypePermitted (); } @@ -352,9 +359,9 @@ namespace Mono.CSharp return fs; } - public override List ResolveMissingDependencies () + public override List ResolveMissingDependencies (MemberSpec caller) { - return memberType.ResolveMissingDependencies (); + return memberType.ResolveMissingDependencies (this); } } @@ -364,7 +371,7 @@ namespace Mono.CSharp public class FixedField : FieldBase { public const string FixedElementName = "FixedElementField"; - static int GlobalCounter = 0; + static int GlobalCounter; TypeBuilder fixed_buffer_type; @@ -394,7 +401,7 @@ namespace Mono.CSharp public override Constant ConvertInitializer (ResolveContext rc, Constant expr) { - return expr.ImplicitConversionRequired (rc, rc.BuiltinTypes.Int, Location); + return expr.ImplicitConversionRequired (rc, rc.BuiltinTypes.Int); } public override bool Define () @@ -407,9 +414,8 @@ namespace Mono.CSharp "`{0}': Fixed size buffers type must be one of the following: bool, byte, short, int, long, char, sbyte, ushort, uint, ulong, float or double", GetSignatureForError ()); } else if (declarators != null) { - var t = new TypeExpression (MemberType, TypeExpression.Location); foreach (var d in declarators) { - var f = new FixedField (Parent, t, ModFlags, new MemberName (d.Name.Value, d.Name.Location), OptAttributes); + var f = new FixedField (Parent, d.GetFieldTypeExpression (this), ModFlags, new MemberName (d.Name.Value, d.Name.Location), OptAttributes); f.initializer = d.Initializer; ((ConstInitializer) f.initializer).Name = d.Name.Value; f.Define (); @@ -428,7 +434,7 @@ namespace Mono.CSharp FieldBuilder = Parent.TypeBuilder.DefineField (Name, fixed_buffer_type, ModifiersExtensions.FieldAttr (ModFlags)); var element_spec = new FieldSpec (null, this, MemberType, ffield, ModFlags); - spec = new FixedFieldSpec (Parent.Definition, this, FieldBuilder, element_spec, ModFlags); + spec = new FixedFieldSpec (Module, Parent.Definition, this, FieldBuilder, element_spec, ModFlags); Parent.MemberCache.AddMember (spec); return true; @@ -486,7 +492,7 @@ namespace Mono.CSharp if (buffer_size > int.MaxValue / type_size) { Report.Error (1664, Location, "Fixed size buffer `{0}' of length `{1}' and type `{2}' exceeded 2^31 limit", - GetSignatureForError (), buffer_size.ToString (), TypeManager.CSharpName (MemberType)); + GetSignatureForError (), buffer_size.ToString (), MemberType.GetSignatureForError ()); return; } @@ -538,8 +544,8 @@ namespace Mono.CSharp { readonly FieldSpec element; - public FixedFieldSpec (TypeSpec declaringType, IMemberDefinition definition, FieldInfo info, FieldSpec element, Modifiers modifiers) - : base (declaringType, definition, element.MemberType, info, modifiers) + public FixedFieldSpec (ModuleContainer module, TypeSpec declaringType, IMemberDefinition definition, FieldInfo info, FieldSpec element, Modifiers modifiers) + : base (declaringType, definition, PointerContainer.MakeType (module, element.MemberType), info, modifiers) { this.element = element; @@ -552,10 +558,10 @@ namespace Mono.CSharp return element; } } - + public TypeSpec ElementType { get { - return MemberType; + return element.MemberType; } } } @@ -645,8 +651,7 @@ namespace Mono.CSharp if (declarators != null) { 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); + var f = new Field (Parent, d.GetFieldTypeExpression (this), ModFlags, new MemberName (d.Name.Value, d.Name.Location), OptAttributes); if (d.Initializer != null) f.initializer = d.Initializer; @@ -668,7 +673,7 @@ namespace Mono.CSharp if ((ModFlags & Modifiers.VOLATILE) != 0) { if (!CanBeVolatile ()) { Report.Error (677, Location, "`{0}': A volatile field cannot be of the type `{1}'", - GetSignatureForError (), TypeManager.CSharpName (MemberType)); + GetSignatureForError (), MemberType.GetSignatureForError ()); } if ((ModFlags & Modifiers.READONLY) != 0) { @@ -690,4 +695,39 @@ namespace Mono.CSharp return true; } } + + class PrimaryConstructorField : Field + { + // + // Proxy resolved parameter type expression to avoid type double resolve + // and problems with correct resolve context on partial classes + // + sealed class TypeExpressionFromParameter : TypeExpr + { + Parameter parameter; + + public TypeExpressionFromParameter (Parameter parameter) + { + this.parameter = parameter; + eclass = ExprClass.Type; + loc = parameter.Location; + } + + public override TypeSpec ResolveAsType (IMemberContext mc) + { + return parameter.Type; + } + } + + public PrimaryConstructorField (TypeDefinition parent, Parameter parameter) + : base (parent, new TypeExpressionFromParameter (parameter), Modifiers.PRIVATE, new MemberName (parameter.Name, parameter.Location), null) + { + caching_flags |= Flags.IsUsed | Flags.IsAssigned; + } + + public override string GetSignatureForError () + { + return MemberName.Name; + } + } } diff --git a/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/flowanalysis.cs b/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/flowanalysis.cs index 5efeccb8f..4f54f268d 100644 --- a/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/flowanalysis.cs +++ b/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/flowanalysis.cs @@ -17,1055 +17,6 @@ using System.Collections.Generic; namespace Mono.CSharp { - // - // A new instance of this class is created every time a new block is resolved - // and if there's branching in the block's control flow. - // - public abstract class FlowBranching - { - // - // The type of a FlowBranching. - // - public enum BranchingType : byte { - // Normal (conditional or toplevel) block. - Block, - - // Conditional. - Conditional, - - // A loop block. - Loop, - - // The statement embedded inside a loop - Embedded, - - // part of a block headed by a jump target - Labeled, - - // TryCatch block. - TryCatch, - - // TryFinally, Using, Lock, CollectionForeach - Exception, - - // Switch block. - Switch, - - // The toplevel block of a function - Toplevel, - - // An iterator block - Iterator - } - - // - // The type of one sibling of a branching. - // - public enum SiblingType : byte { - Block, - Conditional, - SwitchSection, - Try, - Catch, - Finally - } - - public static FlowBranching CreateBranching (FlowBranching parent, BranchingType type, Block block, Location loc) - { - switch (type) { - case BranchingType.Exception: - case BranchingType.Labeled: - case BranchingType.Toplevel: - case BranchingType.TryCatch: - throw new InvalidOperationException (); - - case BranchingType.Switch: - return new FlowBranchingBreakable (parent, type, SiblingType.SwitchSection, block, loc); - - case BranchingType.Block: - return new FlowBranchingBlock (parent, type, SiblingType.Block, block, loc); - - case BranchingType.Loop: - return new FlowBranchingBreakable (parent, type, SiblingType.Conditional, block, loc); - - case BranchingType.Embedded: - return new FlowBranchingContinuable (parent, type, SiblingType.Conditional, block, loc); - - default: - return new FlowBranchingBlock (parent, type, SiblingType.Conditional, block, loc); - } - } - - // - // The type of this flow branching. - // - public readonly BranchingType Type; - - // - // The block this branching is contained in. This may be null if it's not - // a top-level block and it doesn't declare any local variables. - // - public readonly Block Block; - - // - // The parent of this branching or null if this is the top-block. - // - public readonly FlowBranching Parent; - - // - // Start-Location of this flow branching. - // - public readonly Location Location; - - static int next_id = 0; - int id; - - // - // The vector contains a BitArray with information about which local variables - // and parameters are already initialized at the current code position. - // - public class UsageVector { - // - // The type of this branching. - // - public readonly SiblingType Type; - - // - // Start location of this branching. - // - public Location Location; - - // - // This is only valid for SwitchSection, Try, Catch and Finally. - // - public readonly Block Block; - - // - // The number of locals in this block. - // - public readonly int CountLocals; - - // - // If not null, then we inherit our state from this vector and do a - // copy-on-write. If null, then we're the first sibling in a top-level - // block and inherit from the empty vector. - // - public readonly UsageVector InheritsFrom; - - // - // This is used to construct a list of UsageVector's. - // - public UsageVector Next; - - // - // Private. - // - MyBitVector locals; - bool is_unreachable; - - static int next_id = 0; - int id; - - // - // Normally, you should not use any of these constructors. - // - public UsageVector (SiblingType type, UsageVector parent, Block block, Location loc, int num_locals) - { - this.Type = type; - this.Block = block; - this.Location = loc; - this.InheritsFrom = parent; - this.CountLocals = num_locals; - - locals = num_locals == 0 - ? MyBitVector.Empty - : new MyBitVector (parent == null ? MyBitVector.Empty : parent.locals, num_locals); - - if (parent != null) - is_unreachable = parent.is_unreachable; - - id = ++next_id; - - } - - public UsageVector (SiblingType type, UsageVector parent, Block block, Location loc) - : this (type, parent, block, loc, parent.CountLocals) - { } - - private UsageVector (MyBitVector locals, bool is_unreachable, Block block, Location loc) - { - this.Type = SiblingType.Block; - this.Location = loc; - this.Block = block; - - this.is_unreachable = is_unreachable; - - this.locals = locals; - - id = ++next_id; - - } - - // - // This does a deep copy of the usage vector. - // - public UsageVector Clone () - { - UsageVector retval = new UsageVector (Type, null, Block, Location, CountLocals); - - retval.locals = locals.Clone (); - retval.is_unreachable = is_unreachable; - - return retval; - } - - public bool IsAssigned (VariableInfo var, bool ignoreReachability) - { - if (!ignoreReachability && !var.IsParameter && IsUnreachable) - return true; - - return var.IsAssigned (locals); - } - - public void SetAssigned (VariableInfo var) - { - if (!var.IsParameter && IsUnreachable) - return; - - var.SetAssigned (locals); - } - - public bool IsFieldAssigned (VariableInfo var, string name) - { - if (/*!var.IsParameter &&*/ IsUnreachable) - return true; - - return var.IsStructFieldAssigned (locals, name); - } - - public void SetFieldAssigned (VariableInfo var, string name) - { - if (/*!var.IsParameter &&*/ IsUnreachable) - return; - - var.SetStructFieldAssigned (locals, name); - } - - public bool IsUnreachable { - get { - return is_unreachable; - } - set { - is_unreachable = value; - } - } - - public void ResetBarrier () - { - is_unreachable = false; - } - - public void Goto () - { - is_unreachable = true; - } - - public static UsageVector MergeSiblings (UsageVector sibling_list, Location loc) - { - if (sibling_list.Next == null) - return sibling_list; - - MyBitVector locals = null; - bool is_unreachable = sibling_list.is_unreachable; - - if (!sibling_list.IsUnreachable) - locals &= sibling_list.locals; - - for (UsageVector child = sibling_list.Next; child != null; child = child.Next) { - is_unreachable &= child.is_unreachable; - - if (!child.IsUnreachable) - locals &= child.locals; - } - - return new UsageVector (locals, is_unreachable, null, loc); - } - - // - // Merges a child branching. - // - public UsageVector MergeChild (UsageVector child, bool overwrite) - { - Report.Debug (2, " MERGING CHILD EFFECTS", this, child, Type); - - bool new_isunr = child.is_unreachable; - - // - // We've now either reached the point after the branching or we will - // never get there since we always return or always throw an exception. - // - // If we can reach the point after the branching, mark all locals and - // parameters as initialized which have been initialized in all branches - // we need to look at (see above). - // - - if ((Type == SiblingType.SwitchSection) && !new_isunr) { - Report.Error (163, Location, - "Control cannot fall through from one " + - "case label to another"); - return child; - } - - locals |= child.locals; - - // throw away un-necessary information about variables in child blocks - if (locals.Count != CountLocals) - locals = new MyBitVector (locals, CountLocals); - - if (overwrite) - is_unreachable = new_isunr; - else - is_unreachable |= new_isunr; - - return child; - } - - public void MergeOrigins (UsageVector o_vectors) - { - Report.Debug (1, " MERGING BREAK ORIGINS", this); - - if (o_vectors == null) - return; - - if (IsUnreachable && locals != null) - locals.SetAll (true); - - for (UsageVector vector = o_vectors; vector != null; vector = vector.Next) { - Report.Debug (1, " MERGING BREAK ORIGIN", vector); - if (vector.IsUnreachable) - continue; - locals &= vector.locals; - is_unreachable &= vector.is_unreachable; - } - - Report.Debug (1, " MERGING BREAK ORIGINS DONE", this); - } - - // - // Debugging stuff. - // - - public override string ToString () - { - return String.Format ("Vector ({0},{1},{2}-{3})", Type, id, is_unreachable, locals); - } - } - - // - // Creates a new flow branching which is contained in `parent'. - // You should only pass non-null for the `block' argument if this block - // introduces any new variables - in this case, we need to create a new - // usage vector with a different size than our parent's one. - // - protected FlowBranching (FlowBranching parent, BranchingType type, SiblingType stype, - Block block, Location loc) - { - Parent = parent; - Block = block; - Location = loc; - Type = type; - id = ++next_id; - - UsageVector vector; - if (Block != null) { - UsageVector parent_vector = parent != null ? parent.CurrentUsageVector : null; - vector = new UsageVector (stype, parent_vector, Block, loc, Block.AssignableSlots); - } else { - vector = new UsageVector (stype, Parent.CurrentUsageVector, null, loc); - } - - AddSibling (vector); - } - - public abstract UsageVector CurrentUsageVector { - get; - } - - // - // Creates a sibling of the current usage vector. - // - public virtual void CreateSibling (Block block, SiblingType type) - { - UsageVector vector = new UsageVector ( - type, Parent.CurrentUsageVector, block, Location); - AddSibling (vector); - - Report.Debug (1, " CREATED SIBLING", CurrentUsageVector); - } - - public void CreateSibling () - { - CreateSibling (null, SiblingType.Conditional); - } - - protected abstract void AddSibling (UsageVector uv); - - protected abstract UsageVector Merge (); - - public UsageVector MergeChild (FlowBranching child) - { - return CurrentUsageVector.MergeChild (child.Merge (), true); - } - - public virtual bool CheckRethrow (Location loc) - { - return Parent.CheckRethrow (loc); - } - - public virtual bool AddResumePoint (ResumableStatement stmt, out int pc) - { - return Parent.AddResumePoint (stmt, out pc); - } - - // returns true if we crossed an unwind-protected region (try/catch/finally, lock, using, ...) - public virtual bool AddBreakOrigin (UsageVector vector, Location loc) - { - return Parent.AddBreakOrigin (vector, loc); - } - - // returns true if we crossed an unwind-protected region (try/catch/finally, lock, using, ...) - public virtual bool AddContinueOrigin (UsageVector vector, Location loc) - { - return Parent.AddContinueOrigin (vector, loc); - } - - // returns true if we crossed an unwind-protected region (try/catch/finally, lock, using, ...) - public virtual bool AddReturnOrigin (UsageVector vector, ExitStatement stmt) - { - return Parent.AddReturnOrigin (vector, stmt); - } - - // returns true if we crossed an unwind-protected region (try/catch/finally, lock, using, ...) - public virtual bool AddGotoOrigin (UsageVector vector, Goto goto_stmt) - { - return Parent.AddGotoOrigin (vector, goto_stmt); - } - - public bool IsAssigned (VariableInfo vi) - { - return CurrentUsageVector.IsAssigned (vi, false); - } - - public bool IsStructFieldAssigned (VariableInfo vi, string field_name) - { - return CurrentUsageVector.IsAssigned (vi, false) || CurrentUsageVector.IsFieldAssigned (vi, field_name); - } - - protected static Report Report { - get { return RootContext.ToplevelTypes.Compiler.Report; } - } - - public void SetAssigned (VariableInfo vi) - { - CurrentUsageVector.SetAssigned (vi); - } - - public void SetFieldAssigned (VariableInfo vi, string name) - { - CurrentUsageVector.SetFieldAssigned (vi, name); - } - -#if DEBUG - public override string ToString () - { - StringBuilder sb = new StringBuilder (); - sb.Append (GetType ()); - sb.Append (" ("); - - sb.Append (id); - sb.Append (","); - sb.Append (Type); - if (Block != null) { - sb.Append (" - "); - sb.Append (Block.ID); - sb.Append (" - "); - sb.Append (Block.StartLocation); - } - sb.Append (" - "); - // sb.Append (Siblings.Length); - // sb.Append (" - "); - sb.Append (CurrentUsageVector); - sb.Append (")"); - return sb.ToString (); - } -#endif - - public string Name { - get { return String.Format ("{0} ({1}:{2}:{3})", GetType (), id, Type, Location); } - } - } - - public class FlowBranchingBlock : FlowBranching - { - UsageVector sibling_list = null; - - public FlowBranchingBlock (FlowBranching parent, BranchingType type, - SiblingType stype, Block block, Location loc) - : base (parent, type, stype, block, loc) - { } - - public override UsageVector CurrentUsageVector { - get { return sibling_list; } - } - - protected override void AddSibling (UsageVector sibling) - { - if (sibling_list != null && sibling_list.Type == SiblingType.Block) - throw new InternalErrorException ("Blocks don't have sibling flow paths"); - sibling.Next = sibling_list; - sibling_list = sibling; - } - - public override bool AddGotoOrigin (UsageVector vector, Goto goto_stmt) - { - LabeledStatement stmt = Block == null ? null : Block.LookupLabel (goto_stmt.Target); - if (stmt == null) - return Parent.AddGotoOrigin (vector, goto_stmt); - - // forward jump - goto_stmt.SetResolvedTarget (stmt); - stmt.AddUsageVector (vector); - return false; - } - - public static void Error_UnknownLabel (Location loc, string label, Report Report) - { - Report.Error(159, loc, "The label `{0}:' could not be found within the scope of the goto statement", - label); - } - - protected override UsageVector Merge () - { - Report.Debug (2, " MERGING SIBLINGS", Name); - UsageVector vector = UsageVector.MergeSiblings (sibling_list, Location); - Report.Debug (2, " MERGING SIBLINGS DONE", Name, vector); - return vector; - } - } - - public class FlowBranchingBreakable : FlowBranchingBlock - { - UsageVector break_origins; - - public FlowBranchingBreakable (FlowBranching parent, BranchingType type, SiblingType stype, Block block, Location loc) - : base (parent, type, stype, block, loc) - { } - - public override bool AddBreakOrigin (UsageVector vector, Location loc) - { - vector = vector.Clone (); - vector.Next = break_origins; - break_origins = vector; - return false; - } - - protected override UsageVector Merge () - { - UsageVector vector = base.Merge (); - vector.MergeOrigins (break_origins); - return vector; - } - } - - public class FlowBranchingContinuable : FlowBranchingBlock - { - UsageVector continue_origins; - - public FlowBranchingContinuable (FlowBranching parent, BranchingType type, SiblingType stype, Block block, Location loc) - : base (parent, type, stype, block, loc) - { } - - public override bool AddContinueOrigin (UsageVector vector, Location loc) - { - vector = vector.Clone (); - vector.Next = continue_origins; - continue_origins = vector; - return false; - } - - protected override UsageVector Merge () - { - UsageVector vector = base.Merge (); - vector.MergeOrigins (continue_origins); - return vector; - } - } - - public class FlowBranchingLabeled : FlowBranchingBlock - { - LabeledStatement stmt; - UsageVector actual; - - public FlowBranchingLabeled (FlowBranching parent, LabeledStatement stmt) - : base (parent, BranchingType.Labeled, SiblingType.Conditional, null, stmt.loc) - { - this.stmt = stmt; - CurrentUsageVector.MergeOrigins (stmt.JumpOrigins); - actual = CurrentUsageVector.Clone (); - - // stand-in for backward jumps - CurrentUsageVector.ResetBarrier (); - } - - public override bool AddGotoOrigin (UsageVector vector, Goto goto_stmt) - { - if (goto_stmt.Target != stmt.Name) - return Parent.AddGotoOrigin (vector, goto_stmt); - - // backward jump - goto_stmt.SetResolvedTarget (stmt); - actual.MergeOrigins (vector.Clone ()); - - return false; - } - - protected override UsageVector Merge () - { - UsageVector vector = base.Merge (); - - if (actual.IsUnreachable) - Report.Warning (162, 2, stmt.loc, "Unreachable code detected"); - - actual.MergeChild (vector, false); - return actual; - } - } - - public class FlowBranchingIterator : FlowBranchingBlock - { - readonly Iterator iterator; - - public FlowBranchingIterator (FlowBranching parent, Iterator iterator) - : base (parent, BranchingType.Iterator, SiblingType.Block, iterator.Block, iterator.Location) - { - this.iterator = iterator; - } - - public override bool AddResumePoint (ResumableStatement stmt, out int pc) - { - pc = iterator.AddResumePoint (stmt); - return false; - } - } - - public class FlowBranchingToplevel : FlowBranchingBlock - { - UsageVector return_origins; - - public FlowBranchingToplevel (FlowBranching parent, ParametersBlock stmt) - : base (parent, BranchingType.Toplevel, SiblingType.Conditional, stmt, stmt.loc) - { - } - - public override bool CheckRethrow (Location loc) - { - Report.Error (156, loc, "A throw statement with no arguments is not allowed outside of a catch clause"); - return false; - } - - public override bool AddResumePoint (ResumableStatement stmt, out int pc) - { - throw new InternalErrorException ("A yield in a non-iterator block"); - } - - public override bool AddBreakOrigin (UsageVector vector, Location loc) - { - Report.Error (139, loc, "No enclosing loop out of which to break or continue"); - return false; - } - - public override bool AddContinueOrigin (UsageVector vector, Location loc) - { - Report.Error (139, loc, "No enclosing loop out of which to break or continue"); - return false; - } - - public override bool AddReturnOrigin (UsageVector vector, ExitStatement stmt) - { - vector = vector.Clone (); - vector.Location = stmt.loc; - vector.Next = return_origins; - return_origins = vector; - return false; - } - - public override bool AddGotoOrigin (UsageVector vector, Goto goto_stmt) - { - string name = goto_stmt.Target; - LabeledStatement s = Block.LookupLabel (name); - if (s != null) - throw new InternalErrorException ("Shouldn't get here"); - - if (Parent == null) { - Error_UnknownLabel (goto_stmt.loc, name, Report); - return false; - } - - int errors = Report.Errors; - Parent.AddGotoOrigin (vector, goto_stmt); - if (errors == Report.Errors) - Report.Error (1632, goto_stmt.loc, "Control cannot leave the body of an anonymous method"); - return false; - } - - protected override UsageVector Merge () - { - for (UsageVector origin = return_origins; origin != null; origin = origin.Next) - Block.ParametersBlock.CheckOutParameters (origin); - - UsageVector vector = base.Merge (); - Block.ParametersBlock.CheckOutParameters (vector); - // Note: we _do_not_ merge in the return origins - return vector; - } - - public bool End () - { - return Merge ().IsUnreachable; - } - } - - public class FlowBranchingTryCatch : FlowBranchingBlock - { - readonly TryCatch tc; - - public FlowBranchingTryCatch (FlowBranching parent, TryCatch stmt) - : base (parent, BranchingType.Block, SiblingType.Try, null, stmt.loc) - { - this.tc = stmt; - } - - public override bool CheckRethrow (Location loc) - { - return CurrentUsageVector.Next != null || Parent.CheckRethrow (loc); - } - - public override bool AddResumePoint (ResumableStatement stmt, out int pc) - { - int errors = Report.Errors; - Parent.AddResumePoint (tc.IsTryCatchFinally ? stmt : tc, out pc); - if (errors == Report.Errors) { - if (stmt is AwaitStatement) { - if (CurrentUsageVector.Next != null) { - Report.Error (1985, stmt.loc, "The `await' operator cannot be used in the body of a catch clause"); - } else { - this.tc.AddResumePoint (stmt, pc); - } - } else { - if (CurrentUsageVector.Next == null) - Report.Error (1626, stmt.loc, "Cannot yield a value in the body of a try block with a catch clause"); - else - Report.Error (1631, stmt.loc, "Cannot yield a value in the body of a catch clause"); - } - } - - return true; - } - - public override bool AddBreakOrigin (UsageVector vector, Location loc) - { - Parent.AddBreakOrigin (vector, loc); - tc.SomeCodeFollows (); - return true; - } - - public override bool AddContinueOrigin (UsageVector vector, Location loc) - { - Parent.AddContinueOrigin (vector, loc); - tc.SomeCodeFollows (); - return true; - } - - public override bool AddReturnOrigin (UsageVector vector, ExitStatement exit_stmt) - { - Parent.AddReturnOrigin (vector, exit_stmt); - tc.SomeCodeFollows (); - return true; - } - - public override bool AddGotoOrigin (UsageVector vector, Goto goto_stmt) - { - Parent.AddGotoOrigin (vector, goto_stmt); - return true; - } - } - - public class FlowBranchingAsync : FlowBranchingBlock - { - readonly AsyncInitializer async_init; - - public FlowBranchingAsync (FlowBranching parent, AsyncInitializer async_init) - : base (parent, BranchingType.Block, SiblingType.Try, null, async_init.Location) - { - this.async_init = async_init; - } -/* - public override bool CheckRethrow (Location loc) - { - return CurrentUsageVector.Next != null || Parent.CheckRethrow (loc); - } -*/ - public override bool AddResumePoint (ResumableStatement stmt, out int pc) - { - pc = async_init.AddResumePoint (stmt); - return true; - } - - public override bool AddBreakOrigin (UsageVector vector, Location loc) - { - Parent.AddBreakOrigin (vector, loc); - return true; - } - - public override bool AddContinueOrigin (UsageVector vector, Location loc) - { - Parent.AddContinueOrigin (vector, loc); - return true; - } - - public override bool AddReturnOrigin (UsageVector vector, ExitStatement exit_stmt) - { - Parent.AddReturnOrigin (vector, exit_stmt); - return true; - } - - public override bool AddGotoOrigin (UsageVector vector, Goto goto_stmt) - { - Parent.AddGotoOrigin (vector, goto_stmt); - return true; - } - } - - public class FlowBranchingTryFinally : FlowBranching - { - ExceptionStatement stmt; - UsageVector current_vector; - UsageVector try_vector; - UsageVector finally_vector; - - abstract class SavedOrigin { - public readonly SavedOrigin Next; - public readonly UsageVector Vector; - - protected SavedOrigin (SavedOrigin next, UsageVector vector) - { - Next = next; - Vector = vector.Clone (); - } - - protected abstract void DoPropagateFinally (FlowBranching parent); - public void PropagateFinally (UsageVector finally_vector, FlowBranching parent) - { - if (finally_vector != null) - Vector.MergeChild (finally_vector, false); - DoPropagateFinally (parent); - } - } - - class BreakOrigin : SavedOrigin { - Location Loc; - public BreakOrigin (SavedOrigin next, UsageVector vector, Location loc) - : base (next, vector) - { - Loc = loc; - } - - protected override void DoPropagateFinally (FlowBranching parent) - { - parent.AddBreakOrigin (Vector, Loc); - } - } - - class ContinueOrigin : SavedOrigin { - Location Loc; - public ContinueOrigin (SavedOrigin next, UsageVector vector, Location loc) - : base (next, vector) - { - Loc = loc; - } - - protected override void DoPropagateFinally (FlowBranching parent) - { - parent.AddContinueOrigin (Vector, Loc); - } - } - - class ReturnOrigin : SavedOrigin { - public ExitStatement Stmt; - - public ReturnOrigin (SavedOrigin next, UsageVector vector, ExitStatement stmt) - : base (next, vector) - { - Stmt = stmt; - } - - protected override void DoPropagateFinally (FlowBranching parent) - { - parent.AddReturnOrigin (Vector, Stmt); - } - } - - class GotoOrigin : SavedOrigin { - public Goto Stmt; - - public GotoOrigin (SavedOrigin next, UsageVector vector, Goto stmt) - : base (next, vector) - { - Stmt = stmt; - } - - protected override void DoPropagateFinally (FlowBranching parent) - { - parent.AddGotoOrigin (Vector, Stmt); - } - } - - SavedOrigin saved_origins; - - public FlowBranchingTryFinally (FlowBranching parent, - ExceptionStatement stmt) - : base (parent, BranchingType.Exception, SiblingType.Try, - null, stmt.loc) - { - this.stmt = stmt; - } - - protected override void AddSibling (UsageVector sibling) - { - switch (sibling.Type) { - case SiblingType.Try: - try_vector = sibling; - break; - case SiblingType.Finally: - finally_vector = sibling; - break; - default: - throw new InvalidOperationException (); - } - current_vector = sibling; - } - - public override UsageVector CurrentUsageVector { - get { return current_vector; } - } - - public override bool CheckRethrow (Location loc) - { - if (!Parent.CheckRethrow (loc)) - return false; - if (finally_vector == null) - return true; - Report.Error (724, loc, "A throw statement with no arguments is not allowed inside of a finally clause nested inside of the innermost catch clause"); - return false; - } - - public override bool AddResumePoint (ResumableStatement stmt, out int pc) - { - int errors = Report.Errors; - Parent.AddResumePoint (this.stmt, out pc); - if (errors == Report.Errors) { - if (finally_vector == null) - this.stmt.AddResumePoint (stmt, pc); - else { - if (stmt is AwaitStatement) { - Report.Error (1984, stmt.loc, "The `await' operator cannot be used in the body of a finally clause"); - } else { - Report.Error (1625, stmt.loc, "Cannot yield in the body of a finally clause"); - } - } - } - return true; - } - - public override bool AddBreakOrigin (UsageVector vector, Location loc) - { - if (finally_vector != null) { - int errors = Report.Errors; - Parent.AddBreakOrigin (vector, loc); - if (errors == Report.Errors) - Report.Error (157, loc, "Control cannot leave the body of a finally clause"); - } else { - saved_origins = new BreakOrigin (saved_origins, vector, loc); - } - - // either the loop test or a back jump will follow code - stmt.SomeCodeFollows (); - return true; - } - - public override bool AddContinueOrigin (UsageVector vector, Location loc) - { - if (finally_vector != null) { - int errors = Report.Errors; - Parent.AddContinueOrigin (vector, loc); - if (errors == Report.Errors) - Report.Error (157, loc, "Control cannot leave the body of a finally clause"); - } else { - saved_origins = new ContinueOrigin (saved_origins, vector, loc); - } - - // either the loop test or a back jump will follow code - stmt.SomeCodeFollows (); - return true; - } - - public override bool AddReturnOrigin (UsageVector vector, ExitStatement exit_stmt) - { - if (finally_vector != null) { - int errors = Report.Errors; - Parent.AddReturnOrigin (vector, exit_stmt); - if (errors == Report.Errors) - exit_stmt.Error_FinallyClause (Report); - } else { - saved_origins = new ReturnOrigin (saved_origins, vector, exit_stmt); - } - - // sets ec.NeedReturnLabel() - stmt.SomeCodeFollows (); - return true; - } - - public override bool AddGotoOrigin (UsageVector vector, Goto goto_stmt) - { - LabeledStatement s = current_vector.Block == null ? null : current_vector.Block.LookupLabel (goto_stmt.Target); - if (s != null) - throw new InternalErrorException ("Shouldn't get here"); - - if (finally_vector != null) { - int errors = Report.Errors; - Parent.AddGotoOrigin (vector, goto_stmt); - if (errors == Report.Errors) - Report.Error (157, goto_stmt.loc, "Control cannot leave the body of a finally clause"); - } else { - saved_origins = new GotoOrigin (saved_origins, vector, goto_stmt); - } - return true; - } - - protected override UsageVector Merge () - { - UsageVector vector = try_vector.Clone (); - - if (finally_vector != null) - vector.MergeChild (finally_vector, false); - - for (SavedOrigin origin = saved_origins; origin != null; origin = origin.Next) - origin.PropagateFinally (finally_vector, Parent); - - return vector; - } - } - // // This is used by the flow analysis code to keep track of the type of local variables. // @@ -1178,23 +129,22 @@ namespace Mono.CSharp // A struct's constructor must always assign all fields. // This method checks whether it actually does so. // - public bool IsFullyInitialized (BlockContext ec, VariableInfo vi, Location loc) + public bool IsFullyInitialized (FlowAnalysisContext fc, VariableInfo vi, Location loc) { if (struct_info == null) return true; bool ok = true; - FlowBranching branching = ec.CurrentBranching; for (int i = 0; i < struct_info.Count; i++) { - var field = struct_info.Fields [i]; + var field = struct_info.Fields[i]; - if (!branching.IsStructFieldAssigned (vi, field.Name)) { + if (!fc.IsStructFieldDefinitelyAssigned (vi, field.Name)) { if (field.MemberDefinition is Property.BackingField) { - ec.Report.Error (843, loc, + fc.Report.Error (843, loc, "An automatically implemented property `{0}' must be fully assigned before control leaves the constructor. Consider calling the default struct contructor from a constructor initializer", field.GetSignatureForError ()); } else { - ec.Report.Error (171, loc, + fc.Report.Error (171, loc, "Field `{0}' must be fully assigned before control leaves the constructor", field.GetSignatureForError ()); } @@ -1317,14 +267,16 @@ namespace Mono.CSharp } } - // - // This is used by the flow analysis code to store information about a single local variable - // or parameter. Depending on the variable's type, we need to allocate one or more elements - // in the BitVector - if it's a fundamental or reference type, we just need to know whether - // it has been assigned or not, but for structs, we need this information for each of its fields. - // - public class VariableInfo { + // + // This is used by definite assignment analysis code to store information about a local variable + // or parameter. Depending on the variable's type, we need to allocate one or more elements + // in the BitVector - if it's a fundamental or reference type, we just need to know whether + // it has been assigned or not, but for structs, we need this information for each of its fields. + // + public class VariableInfo + { readonly string Name; + readonly TypeInfo TypeInfo; // @@ -1337,12 +289,12 @@ namespace Mono.CSharp // The first bit always specifies whether the variable as such has been assigned while // the remaining bits contain this information for each of a struct's fields. // - public readonly int Length; + readonly int Length; // // If this is a parameter of local variable. // - public readonly bool IsParameter; + public bool IsParameter; VariableInfo[] sub_info; @@ -1369,7 +321,7 @@ namespace Mono.CSharp Initialize (); } - protected void Initialize () + void Initialize () { TypeInfo[] sub_fields = TypeInfo.SubStructInfo; if (sub_fields != null) { @@ -1382,24 +334,24 @@ namespace Mono.CSharp sub_info = new VariableInfo [0]; } - public VariableInfo (LocalVariable local_info, int offset) - : this (local_info.Name, local_info.Type, offset) + public static VariableInfo Create (BlockContext bc, LocalVariable variable) { - this.IsParameter = false; + var info = new VariableInfo (variable.Name, variable.Type, bc.AssignmentInfoOffset); + bc.AssignmentInfoOffset += info.Length; + return info; } - public VariableInfo (ParametersCompiled ip, int i, int offset) - : this (ip.FixedParameters [i].Name, ip.Types [i], offset) + public static VariableInfo Create (BlockContext bc, Parameter parameter) { - this.IsParameter = true; - } + var info = new VariableInfo (parameter.Name, parameter.Type, bc.AssignmentInfoOffset) { + IsParameter = true + }; - public bool IsAssigned (ResolveContext ec) - { - return !ec.DoFlowAnalysis || ec.CurrentBranching.IsAssigned (this); + bc.AssignmentInfoOffset += info.Length; + return info; } - public bool IsAssigned (MyBitVector vector) + public bool IsAssigned (DefiniteAssignmentBitSet vector) { if (vector == null) return true; @@ -1438,23 +390,18 @@ namespace Mono.CSharp return false; } - vector [Offset] = true; + vector.Set (Offset); return true; } public bool IsEverAssigned { get; set; } - public bool IsStructFieldAssigned (ResolveContext ec, string name) + public bool IsFullyInitialized (FlowAnalysisContext fc, Location loc) { - return !ec.DoFlowAnalysis || ec.CurrentBranching.IsStructFieldAssigned (this, name); + return TypeInfo.IsFullyInitialized (fc, this, loc); } - public bool IsFullyInitialized (BlockContext bc, Location loc) - { - return TypeInfo.IsFullyInitialized (bc, this, loc); - } - - public bool IsStructFieldAssigned (MyBitVector vector, string field_name) + public bool IsStructFieldAssigned (DefiniteAssignmentBitSet vector, string field_name) { int field_idx = TypeInfo.GetFieldIndex (field_name); @@ -1464,31 +411,20 @@ namespace Mono.CSharp return vector [Offset + field_idx]; } - public void SetStructFieldAssigned (ResolveContext ec, string name) - { - if (ec.DoFlowAnalysis) - ec.CurrentBranching.SetFieldAssigned (this, name); - } - - public void SetAssigned (ResolveContext ec) - { - if (ec.DoFlowAnalysis) - ec.CurrentBranching.SetAssigned (this); - } - - public void SetAssigned (MyBitVector vector) + public void SetAssigned (DefiniteAssignmentBitSet vector, bool generatedAssignment) { if (Length == 1) - vector[Offset] = true; + vector.Set (Offset); else - vector.SetRange (Offset, Length); + vector.Set (Offset, Length); - IsEverAssigned = true; + if (!generatedAssignment) + IsEverAssigned = true; } - public void SetStructFieldAssigned (MyBitVector vector, string field_name) + public void SetStructFieldAssigned (DefiniteAssignmentBitSet vector, string field_name) { - if (vector[Offset]) + if (vector [Offset]) return; int field_idx = TypeInfo.GetFieldIndex (field_name); @@ -1498,15 +434,15 @@ namespace Mono.CSharp var complex_field = TypeInfo.GetStructField (field_name); if (complex_field != null) { - vector.SetRange (Offset + complex_field.Offset, complex_field.TotalLength); + vector.Set (Offset + complex_field.Offset, complex_field.TotalLength); } else { - vector[Offset + field_idx] = true; + vector.Set (Offset + field_idx); } IsEverAssigned = true; // - // Each field must be assigned + // Each field must be assigned before setting master bit // for (int i = Offset + 1; i < TypeInfo.TotalLength + Offset; i++) { if (!vector[i]) @@ -1517,7 +453,7 @@ namespace Mono.CSharp // Set master struct flag to assigned when all tested struct // fields have been assigned // - vector[Offset] = true; + vector.Set (Offset); } public VariableInfo GetStructFieldInfo (string fieldName) @@ -1532,274 +468,211 @@ namespace Mono.CSharp public override string ToString () { - return String.Format ("VariableInfo ({0}:{1}:{2}:{3}:{4})", - Name, TypeInfo, Offset, Length, IsParameter); + return String.Format ("Name={0} Offset={1} Length={2} {3})", Name, Offset, Length, TypeInfo); } } - // - // This is a special bit vector which can inherit from another bit vector doing a - // copy-on-write strategy. The inherited vector may have a smaller size than the - // current one. - // - public class MyBitVector { - public readonly int Count; - public static readonly MyBitVector Empty = new MyBitVector (); - - // Invariant: vector != null => vector.Count == Count - // Invariant: vector == null || shared == null - // i.e., at most one of 'vector' and 'shared' can be non-null. They can both be null -- that means all-ones - // The object in 'shared' cannot be modified, while 'vector' can be freely modified - System.Collections.BitArray vector, shared; + public struct Reachability + { + readonly bool unreachable; - MyBitVector () + Reachability (bool unreachable) { - shared = new System.Collections.BitArray (0, false); + this.unreachable = unreachable; + } + + public bool IsUnreachable { + get { + return unreachable; + } } - public MyBitVector (MyBitVector InheritsFrom, int Count) + public static Reachability CreateUnreachable () { - if (InheritsFrom != null) - shared = InheritsFrom.MakeShared (Count); + return new Reachability (true); + } - this.Count = Count; + public static Reachability operator & (Reachability a, Reachability b) + { + return new Reachability (a.unreachable && b.unreachable); } - System.Collections.BitArray MakeShared (int new_count) + public static Reachability operator | (Reachability a, Reachability b) { - // Post-condition: vector == null + return new Reachability (a.unreachable | b.unreachable); + } + } - // ensure we don't leak out dirty bits from the BitVector we inherited from - if (new_count > Count && - ((shared != null && shared.Count > Count) || - (shared == null && vector == null))) - initialize_vector (); + // + // Special version of bit array. Many operations can be simplified because + // we are always dealing with arrays of same sizes + // + public class DefiniteAssignmentBitSet + { + const uint copy_on_write_flag = 1u << 31; - if (vector != null) { - shared = vector; - vector = null; - } + uint bits; - return shared; - } + // Used when bits overflows + int[] large_bits; - // - // Get/set bit `index' in the bit vector. - // - public bool this [int index] { - get { - if (index >= Count) - // FIXME: Disabled due to missing anonymous method flow analysis - // throw new ArgumentOutOfRangeException (); - return true; - - if (vector != null) - return vector [index]; - if (shared == null) - return true; - if (index < shared.Count) - return shared [index]; - return false; - } + public static readonly DefiniteAssignmentBitSet Empty = new DefiniteAssignmentBitSet (0); - set { - // Only copy the vector if we're actually modifying it. - if (this [index] != value) { - if (vector == null) - initialize_vector (); - vector [index] = value; - } - } + public DefiniteAssignmentBitSet (int length) + { + if (length > 31) + large_bits = new int[(length + 31) / 32]; } - // - // Performs an `or' operation on the bit vector. The `new_vector' may have a - // different size than the current one. - // - private MyBitVector Or (MyBitVector new_vector) + public DefiniteAssignmentBitSet (DefiniteAssignmentBitSet source) { - if (Count == 0 || new_vector.Count == 0) - return this; - - var o = new_vector.vector != null ? new_vector.vector : new_vector.shared; - - if (o == null) { - int n = new_vector.Count; - if (n < Count) { - for (int i = 0; i < n; ++i) - this [i] = true; - } else { - SetAll (true); - } - return this; + if (source.large_bits != null) { + large_bits = source.large_bits; + bits = source.bits | copy_on_write_flag; + } else { + bits = source.bits & ~copy_on_write_flag; } + } - if (Count == o.Count) { - if (vector == null) { - if (shared == null) - return this; - initialize_vector (); - } - vector.Or (o); - return this; - } + public static DefiniteAssignmentBitSet operator & (DefiniteAssignmentBitSet a, DefiniteAssignmentBitSet b) + { + if (AreEqual (a, b)) + return a; - int min = o.Count; - if (Count < min) - min = Count; + DefiniteAssignmentBitSet res; + if (a.large_bits == null) { + res = new DefiniteAssignmentBitSet (a); + res.bits &= (b.bits & ~copy_on_write_flag); + return res; + } - for (int i = 0; i < min; i++) { - if (o [i]) - this [i] = true; + res = new DefiniteAssignmentBitSet (a); + res.Clone (); + var dest = res.large_bits; + var src = b.large_bits; + for (int i = 0; i < dest.Length; ++i) { + dest[i] &= src[i]; } - return this; + return res; } - // - // Performs an `and' operation on the bit vector. The `new_vector' may have - // a different size than the current one. - // - private MyBitVector And (MyBitVector new_vector) + public static DefiniteAssignmentBitSet operator | (DefiniteAssignmentBitSet a, DefiniteAssignmentBitSet b) { - if (Count == 0) - return this; - - var o = new_vector.vector != null ? new_vector.vector : new_vector.shared; + if (AreEqual (a, b)) + return a; - if (o == null) { - for (int i = new_vector.Count; i < Count; ++i) - this [i] = false; - return this; + DefiniteAssignmentBitSet res; + if (a.large_bits == null) { + res = new DefiniteAssignmentBitSet (a); + res.bits |= b.bits; + res.bits &= ~copy_on_write_flag; + return res; } - if (o.Count == 0) { - SetAll (false); - return this; - } + res = new DefiniteAssignmentBitSet (a); + res.Clone (); + var dest = res.large_bits; + var src = b.large_bits; - if (Count == o.Count) { - if (vector == null) { - if (shared == null) { - shared = new_vector.MakeShared (Count); - return this; - } - initialize_vector (); - } - vector.And (o); - return this; + for (int i = 0; i < dest.Length; ++i) { + dest[i] |= src[i]; } - int min = o.Count; - if (Count < min) - min = Count; + return res; + } - for (int i = 0; i < min; i++) { - if (! o [i]) - this [i] = false; - } + public static DefiniteAssignmentBitSet And (List das) + { + if (das.Count == 0) + throw new ArgumentException ("Empty das"); - for (int i = min; i < Count; i++) - this [i] = false; + DefiniteAssignmentBitSet res = das[0]; + for (int i = 1; i < das.Count; ++i) { + res &= das[i]; + } - return this; + return res; } - public static MyBitVector operator & (MyBitVector a, MyBitVector b) - { - if (a == b) - return a; - if (a == null) - return b.Clone (); - if (b == null) - return a.Clone (); - if (a.Count > b.Count) - return a.Clone ().And (b); - else - return b.Clone ().And (a); + bool CopyOnWrite { + get { + return (bits & copy_on_write_flag) != 0; + } } - public static MyBitVector operator | (MyBitVector a, MyBitVector b) - { - if (a == b) - return a; - if (a == null) - return new MyBitVector (null, b.Count); - if (b == null) - return new MyBitVector (null, a.Count); - if (a.Count > b.Count) - return a.Clone ().Or (b); - else - return b.Clone ().Or (a); + int Length { + get { + return large_bits == null ? 31 : large_bits.Length * 32; + } } - public MyBitVector Clone () + public void Set (int index) { - return Count == 0 ? Empty : new MyBitVector (this, Count); + if (CopyOnWrite && !this[index]) + Clone (); + + SetBit (index); } - public void SetRange (int offset, int length) + public void Set (int index, int length) { - if (offset > Count || offset + length > Count) - throw new ArgumentOutOfRangeException ("flow-analysis"); - - if (shared == null && vector == null) - return; + for (int i = 0; i < length; ++i) { + if (CopyOnWrite && !this[index + i]) + Clone (); - int i = 0; - if (shared != null) { - if (offset + length <= shared.Count) { - for (; i < length; ++i) - if (!shared [i+offset]) - break; - if (i == length) - return; - } - initialize_vector (); + SetBit (index + i); } - for (; i < length; ++i) - vector [i+offset] = true; + } + public bool this[int index] { + get { + return GetBit (index); + } } - public void SetAll (bool value) + public override string ToString () { - // Don't clobber Empty - if (Count == 0) - return; - shared = value ? null : Empty.MakeShared (Count); - vector = null; + var length = Length; + StringBuilder sb = new StringBuilder (length); + for (int i = 0; i < length; ++i) { + sb.Append (this[i] ? '1' : '0'); + } + + return sb.ToString (); } - void initialize_vector () + void Clone () { - // Post-condition: vector != null - if (shared == null) { - vector = new System.Collections.BitArray (Count, true); - return; - } + large_bits = (int[]) large_bits.Clone (); + } - vector = new System.Collections.BitArray (shared); - if (Count != vector.Count) - vector.Length = Count; - shared = null; + bool GetBit (int index) + { + return large_bits == null ? + (bits & (1 << index)) != 0 : + (large_bits[index >> 5] & (1 << (index & 31))) != 0; } - StringBuilder Dump (StringBuilder sb) + void SetBit (int index) { - var dump = vector == null ? shared : vector; - if (dump == null) - return sb.Append ("/"); - if (dump == shared) - sb.Append ("="); - for (int i = 0; i < dump.Count; i++) - sb.Append (dump [i] ? "1" : "0"); - return sb; + if (large_bits == null) + bits = (uint) ((int) bits | (1 << index)); + else + large_bits[index >> 5] |= (1 << (index & 31)); } - public override string ToString () + static bool AreEqual (DefiniteAssignmentBitSet a, DefiniteAssignmentBitSet b) { - return Dump (new StringBuilder ("{")).Append ("}").ToString (); + if (a.large_bits == null) + return (a.bits & ~copy_on_write_flag) == (b.bits & ~copy_on_write_flag); + + for (int i = 0; i < a.large_bits.Length; ++i) { + if (a.large_bits[i] != b.large_bits[i]) + return false; + } + + return true; } } } diff --git a/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/generic.cs b/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/generic.cs index 9bf70dc76..123534d9f 100644 --- a/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/generic.cs +++ b/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/generic.cs @@ -28,6 +28,50 @@ using System.Reflection.Emit; #endif namespace Mono.CSharp { + public class VarianceDecl + { + public VarianceDecl (Variance variance, Location loc) + { + this.Variance = variance; + this.Location = loc; + } + + public Variance Variance { get; private set; } + public Location Location { get; private set; } + + public static Variance CheckTypeVariance (TypeSpec t, Variance expected, IMemberContext member) + { + var tp = t as TypeParameterSpec; + if (tp != null) { + var v = tp.Variance; + if (expected == Variance.None && v != expected || + expected == Variance.Covariant && v == Variance.Contravariant || + expected == Variance.Contravariant && v == Variance.Covariant) { + ((TypeParameter) tp.MemberDefinition).ErrorInvalidVariance (member, expected); + } + + return expected; + } + + if (t.TypeArguments.Length > 0) { + var targs_definition = t.MemberDefinition.TypeParameters; + TypeSpec[] targs = TypeManager.GetTypeArguments (t); + for (int i = 0; i < targs.Length; ++i) { + var v = targs_definition[i].Variance; + CheckTypeVariance (targs[i], (Variance) ((int) v * (int) expected), member); + } + + return expected; + } + + var ac = t as ArrayContainer; + if (ac != null) + return CheckTypeVariance (ac.Element, expected, member); + + return Variance.None; + } + } + public enum Variance { // @@ -73,9 +117,9 @@ namespace Mono.CSharp { // public class Constraints { - SimpleMemberName tparam; - List constraints; - Location loc; + readonly SimpleMemberName tparam; + readonly List constraints; + readonly Location loc; bool resolved; bool resolving; @@ -224,8 +268,7 @@ namespace Mono.CSharp { iface_found = true; continue; } - - + var constraint_tp = type as TypeParameterSpec; if (constraint_tp != null) { if (tparam_types == null) { @@ -241,7 +284,7 @@ namespace Mono.CSharp { // is valid with respect to T // if (tp.IsMethodTypeParameter) { - TypeManager.CheckTypeVariance (type, Variance.Contravariant, context); + VarianceDecl.CheckTypeVariance (type, Variance.Contravariant, context); } var tp_def = constraint_tp.MemberDefinition as TypeParameter; @@ -276,6 +319,12 @@ namespace Mono.CSharp { } } + if (constraint_tp.TypeArguments != null) { + var eb = constraint_tp.GetEffectiveBase (); + if (eb != null && !CheckConflictingInheritedConstraint (spec, eb, spec.BaseType, context, constraint.Location)) + break; + } + if (constraint_tp.HasSpecialStruct) { context.Module.Compiler.Report.Error (456, constraint.Location, "Type parameter `{0}' has the `struct' constraint, so it cannot be used as a constraint for `{1}'", @@ -318,7 +367,7 @@ namespace Mono.CSharp { if (type.IsSealed || !type.IsClass) { context.Module.Compiler.Report.Error (701, loc, "`{0}' is not a valid constraint. A constraint must be an interface, a non-sealed class or a type parameter", - TypeManager.CSharpName (type)); + type.GetSignatureForError ()); continue; } @@ -360,28 +409,30 @@ namespace Mono.CSharp { // public class TypeParameter : MemberCore, ITypeDefinition { - static readonly string[] attribute_target = new string [] { "type parameter" }; + static readonly string[] attribute_target = { "type parameter" }; Constraints constraints; GenericTypeParameterBuilder builder; - TypeParameterSpec spec; + readonly TypeParameterSpec spec; - public TypeParameter (int index, MemberName name, Constraints constraints, Attributes attrs, Variance variance) + public TypeParameter (int index, MemberName name, Constraints constraints, Attributes attrs, Variance Variance) : base (null, name, attrs) { this.constraints = constraints; - this.spec = new TypeParameterSpec (null, index, this, SpecialConstraint.None, variance, null); + this.spec = new TypeParameterSpec (null, index, this, SpecialConstraint.None, Variance, null); } // // Used by parser // - public TypeParameter (MemberName name, Attributes attrs, Variance variance) + public TypeParameter (MemberName name, Attributes attrs, VarianceDecl variance) : base (null, name, attrs) { - this.spec = new TypeParameterSpec (null, -1, this, SpecialConstraint.None, variance, null); + var var = variance == null ? Variance.None : variance.Variance; + this.spec = new TypeParameterSpec (null, -1, this, SpecialConstraint.None, var, null); + this.VarianceDecl = variance; } - + public TypeParameter (TypeParameterSpec spec, TypeSpec parentSpec, MemberName name, Attributes attrs) : base (null, name, attrs) { @@ -391,7 +442,7 @@ namespace Mono.CSharp { TypeArguments = spec.TypeArguments }; } - + #region Properties public override AttributeTargets AttributeTargets { @@ -422,6 +473,12 @@ namespace Mono.CSharp { } } + bool ITypeDefinition.IsComImport { + get { + return false; + } + } + bool ITypeDefinition.IsPartial { get { return false; @@ -434,6 +491,18 @@ namespace Mono.CSharp { } } + bool ITypeDefinition.IsTypeForwarder { + get { + return false; + } + } + + bool ITypeDefinition.IsCyclicTypeForwarder { + get { + return false; + } + } + public string Name { get { return MemberName.Name; @@ -476,6 +545,8 @@ namespace Mono.CSharp { } } + public VarianceDecl VarianceDecl { get; private set; } + #endregion // @@ -483,7 +554,7 @@ namespace Mono.CSharp { // // If partial type parameters constraints are not null and we don't // already have constraints they become our constraints. If we already - // have constraints, we must check that they're the same. + // have constraints, we must check that they're same. // public bool AddPartialConstraints (TypeDefinition part, TypeParameter tp) { @@ -539,15 +610,19 @@ namespace Mono.CSharp { // with SRE (by calling `DefineGenericParameters()' on the TypeBuilder / // MethodBuilder). // - public void Define (GenericTypeParameterBuilder type, TypeSpec declaringType, TypeContainer parent) + public void Create (TypeSpec declaringType, TypeContainer parent) { if (builder != null) throw new InternalErrorException (); // Needed to get compiler reference this.Parent = parent; - this.builder = type; spec.DeclaringType = declaringType; + } + + public void Define (GenericTypeParameterBuilder type) + { + this.builder = type; spec.SetMetaInfo (type); } @@ -573,8 +648,21 @@ namespace Mono.CSharp { if (spec.InterfacesDefined != null) builder.SetInterfaceConstraints (spec.InterfacesDefined.Select (l => l.GetMetaInfo ()).ToArray ()); - if (spec.TypeArguments != null) - builder.SetInterfaceConstraints (spec.TypeArguments.Select (l => l.GetMetaInfo ()).ToArray ()); + if (spec.TypeArguments != null) { + var meta_constraints = new List (spec.TypeArguments.Length); + foreach (var c in spec.TypeArguments) { + // + // Inflated type parameters can collide with special constraint types, don't + // emit any such type parameter. + // + if (c.BuiltinType == BuiltinTypeSpec.Type.Object || c.BuiltinType == BuiltinTypeSpec.Type.ValueType) + continue; + + meta_constraints.Add (c.GetMetaInfo ()); + } + + builder.SetInterfaceConstraints (meta_constraints.ToArray ()); + } builder.SetGenericParameterAttributes (attr); } @@ -687,6 +775,7 @@ namespace Mono.CSharp { int tp_pos; TypeSpec[] targs; TypeSpec[] ifaces_defined; + TypeSpec effective_base; // // Creates type owned type parameter @@ -754,23 +843,40 @@ namespace Mono.CSharp { get { if ((state & StateFlags.InterfacesExpanded) == 0) { if (ifaces != null) { - for (int i = 0; i < ifaces.Count; ++i ) { - var iface_type = ifaces[i]; - if (iface_type.Interfaces != null) { - if (ifaces_defined == null) - ifaces_defined = ifaces.ToArray (); + if (ifaces_defined == null) + ifaces_defined = ifaces.ToArray (); + + for (int i = 0; i < ifaces_defined.Length; ++i ) { + var iface_type = ifaces_defined[i]; + var td = iface_type.MemberDefinition as TypeDefinition; + if (td != null) + td.DoExpandBaseInterfaces (); + if (iface_type.Interfaces != null) { for (int ii = 0; ii < iface_type.Interfaces.Count; ++ii) { var ii_iface_type = iface_type.Interfaces [ii]; - AddInterface (ii_iface_type); } } } + } else if (ifaces_defined == null) { + ifaces_defined = ifaces == null ? TypeSpec.EmptyTypes : ifaces.ToArray (); } - if (ifaces_defined == null) - ifaces_defined = ifaces == null ? TypeSpec.EmptyTypes : ifaces.ToArray (); + // + // Include all base type interfaces too, see ImportTypeBase for details + // + if (BaseType != null) { + var td = BaseType.MemberDefinition as TypeDefinition; + if (td != null) + td.DoExpandBaseInterfaces (); + + if (BaseType.Interfaces != null) { + foreach (var iface in BaseType.Interfaces) { + AddInterface (iface); + } + } + } state |= StateFlags.InterfacesExpanded; } @@ -785,10 +891,7 @@ namespace Mono.CSharp { public TypeSpec[] InterfacesDefined { get { if (ifaces_defined == null) { - if (ifaces == null) - return null; - - ifaces_defined = ifaces.ToArray (); + ifaces_defined = ifaces == null ? TypeSpec.EmptyTypes : ifaces.ToArray (); } return ifaces_defined.Length == 0 ? null : ifaces_defined; @@ -796,7 +899,7 @@ namespace Mono.CSharp { set { ifaces_defined = value; if (value != null && value.Length != 0) - ifaces = value; + ifaces = new List (value); } } @@ -936,23 +1039,27 @@ namespace Mono.CSharp { return BaseType.IsStruct ? BaseType.BaseType : BaseType; } - var types = targs; - if (HasTypeConstraint) { - Array.Resize (ref types, types.Length + 1); + if (effective_base != null) + return effective_base; + + var types = new TypeSpec [HasTypeConstraint ? targs.Length + 1 : targs.Length]; - for (int i = 0; i < types.Length - 1; ++i) { - types[i] = types[i].BaseType; + for (int i = 0; i < targs.Length; ++i) { + var t = targs [i]; + + // Same issue as above, inherited constraints can be of struct type + if (t.IsStruct) { + types [i] = t.BaseType; + continue; } - types[types.Length - 1] = BaseType; - } else { - types = types.Select (l => l.BaseType).ToArray (); + types [i] = ((TypeParameterSpec)t).GetEffectiveBase (); } - if (types != null) - return Convert.FindMostEncompassedType (types); + if (HasTypeConstraint) + types [types.Length - 1] = BaseType; - return BaseType; + return effective_base = Convert.FindMostEncompassedType (types); } public override string GetSignatureForDocumentation () @@ -1156,10 +1263,22 @@ namespace Mono.CSharp { public void InflateConstraints (TypeParameterInflator inflator, TypeParameterSpec tps) { tps.BaseType = inflator.Inflate (BaseType); + + var defined = InterfacesDefined; + if (defined != null) { + tps.ifaces_defined = new TypeSpec[defined.Length]; + for (int i = 0; i < defined.Length; ++i) + tps.ifaces_defined [i] = inflator.Inflate (defined[i]); + } else if (ifaces_defined == TypeSpec.EmptyTypes) { + tps.ifaces_defined = TypeSpec.EmptyTypes; + } + + var ifaces = Interfaces; if (ifaces != null) { tps.ifaces = new List (ifaces.Count); for (int i = 0; i < ifaces.Count; ++i) tps.ifaces.Add (inflator.Inflate (ifaces[i])); + tps.state |= StateFlags.InterfacesExpanded; } if (targs != null) { @@ -1172,6 +1291,10 @@ namespace Mono.CSharp { public override MemberSpec InflateMember (TypeParameterInflator inflator) { var tps = (TypeParameterSpec) MemberwiseClone (); +#if DEBUG + tps.ID += 1000000; +#endif + InflateConstraints (inflator, tps); return tps; } @@ -1192,20 +1315,28 @@ namespace Mono.CSharp { if (BaseType.BuiltinType != BuiltinTypeSpec.Type.Object && BaseType.BuiltinType != BuiltinTypeSpec.Type.ValueType) cache.AddBaseType (BaseType); - if (ifaces != null) { - foreach (var iface_type in Interfaces) { + if (InterfacesDefined != null) { + foreach (var iface_type in InterfacesDefined) { cache.AddInterface (iface_type); } } if (targs != null) { foreach (var ta in targs) { - var b_type = ta.BaseType; - if (b_type.BuiltinType != BuiltinTypeSpec.Type.Object && b_type.BuiltinType != BuiltinTypeSpec.Type.ValueType) - cache.AddBaseType (b_type); + var tps = ta as TypeParameterSpec; + IList ifaces; + if (tps != null) { + var b_type = tps.GetEffectiveBase (); + if (b_type != null && b_type.BuiltinType != BuiltinTypeSpec.Type.Object && b_type.BuiltinType != BuiltinTypeSpec.Type.ValueType) + cache.AddBaseType (b_type); + + ifaces = tps.InterfacesDefined; + } else { + ifaces = ta.Interfaces; + } - if (ta.Interfaces != null) { - foreach (var iface_type in ta.Interfaces) { + if (ifaces != null) { + foreach (var iface_type in ifaces) { cache.AddInterface (iface_type); } } @@ -1224,7 +1355,15 @@ namespace Mono.CSharp { if (TypeArguments != null) { foreach (var t in TypeArguments) { - if (((TypeParameterSpec) t).IsConvertibleToInterface (iface)) + var tps = t as TypeParameterSpec; + if (tps != null) { + if (tps.IsConvertibleToInterface (iface)) + return true; + + continue; + } + + if (t.ImplementsInterface (iface, false)) return true; } } @@ -1256,6 +1395,22 @@ namespace Mono.CSharp { return false; } + public bool HasDependencyOn (TypeSpec type) + { + if (TypeArguments != null) { + foreach (var targ in TypeArguments) { + if (TypeSpecComparer.Override.IsEqual (targ, type)) + return true; + + var tps = targ as TypeParameterSpec; + if (tps != null && tps.HasDependencyOn (type)) + return true; + } + } + + return false; + } + public override TypeSpec Mutate (TypeParameterMutator mutator) { return mutator.Mutate (this); @@ -1316,15 +1471,23 @@ namespace Mono.CSharp { if (tp != null) return Inflate (tp); - var ac = type as ArrayContainer; - if (ac != null) { - var et = Inflate (ac.Element); - if (et != ac.Element) - return ArrayContainer.MakeType (context.Module, et, ac.Rank); + var ec = type as ElementTypeSpec; + if (ec != null) { + var et = Inflate (ec.Element); + if (et != ec.Element) { + var ac = ec as ArrayContainer; + if (ac != null) + return ArrayContainer.MakeType (context.Module, et, ac.Rank); + + throw new NotImplementedException (); + } - return ac; + return ec; } + if (type.Kind == MemberKind.MissingType) + return type; + // // When inflating a nested type, inflate its parent first // in case it's using same type parameters (was inflated within the type) @@ -1422,6 +1585,7 @@ namespace Mono.CSharp { { readonly TypeParameters mvar; readonly TypeParameters var; + readonly TypeParameterSpec[] src; Dictionary mutated_typespec; public TypeParameterMutator (TypeParameters mvar, TypeParameters var) @@ -1433,6 +1597,15 @@ namespace Mono.CSharp { this.var = var; } + public TypeParameterMutator (TypeParameterSpec[] srcVar, TypeParameters destVar) + { + if (srcVar.Length != destVar.Count) + throw new ArgumentException (); + + this.src = srcVar; + this.var = destVar; + } + #region Properties public TypeParameters MethodTypeParameters { @@ -1472,9 +1645,16 @@ namespace Mono.CSharp { public TypeParameterSpec Mutate (TypeParameterSpec tp) { - for (int i = 0; i < mvar.Count; ++i) { - if (mvar[i].Type == tp) - return var[i].Type; + if (mvar != null) { + for (int i = 0; i < mvar.Count; ++i) { + if (mvar[i].Type == tp) + return var[i].Type; + } + } else { + for (int i = 0; i < src.Length; ++i) { + if (src[i] == tp) + return var[i].Type; + } } return tp; @@ -1590,7 +1770,7 @@ namespace Mono.CSharp { } } - public override bool IsGenericIterateInterface { + public override bool IsArrayGenericInterface { get { return (open_type.state & StateFlags.GenericIterateInterface) != 0; } @@ -1619,6 +1799,16 @@ namespace Mono.CSharp { #endregion + public override bool AddInterface (TypeSpec iface) + { + var inflator = CreateLocalInflator (context); + iface = inflator.Inflate (iface); + if (iface == null) + return false; + + return base.AddInterface (iface); + } + public static bool ContainsTypeParameter (TypeSpec type) { if (type.Kind == MemberKind.TypeParameter) @@ -1637,7 +1827,7 @@ namespace Mono.CSharp { return false; } - TypeParameterInflator CreateLocalInflator (IModuleContext context) + public TypeParameterInflator CreateLocalInflator (IModuleContext context) { TypeParameterSpec[] tparams_full; TypeSpec[] targs_full = targs; @@ -1689,7 +1879,7 @@ namespace Mono.CSharp { return new TypeParameterInflator (context, this, tparams_full, targs_full); } - MetaType CreateMetaInfo (TypeParameterMutator mutator) + MetaType CreateMetaInfo () { // // Converts nested type arguments into right order @@ -1739,7 +1929,7 @@ namespace Mono.CSharp { public override MetaType GetMetaInfo () { if (info == null) - info = CreateMetaInfo (null); + info = CreateMetaInfo (); return info; } @@ -1828,7 +2018,7 @@ namespace Mono.CSharp { if (iface_inflated == null) continue; - AddInterface (iface_inflated); + base.AddInterface (iface_inflated); } } @@ -1994,13 +2184,15 @@ namespace Mono.CSharp { public virtual bool Resolve (IMemberContext ec) { if (atypes != null) - return atypes.Length != 0; + return true; int count = args.Count; bool ok = true; atypes = new TypeSpec [count]; + var errors = ec.Module.Compiler.Report.Errors; + for (int i = 0; i < count; i++){ var te = args[i].ResolveAsType (ec); if (te == null) { @@ -2024,8 +2216,8 @@ namespace Mono.CSharp { } } - if (!ok) - atypes = TypeSpec.EmptyTypes; + if (!ok || errors != ec.Module.Compiler.Report.Errors) + atypes = null; return ok; } @@ -2101,13 +2293,13 @@ namespace Mono.CSharp { names.AddRange (tparams.names); } - public void Define (GenericTypeParameterBuilder[] buiders, TypeSpec declaringType, int parentOffset, TypeContainer parent) + public void Create (TypeSpec declaringType, int parentOffset, TypeContainer parent) { types = new TypeParameterSpec[Count]; for (int i = 0; i < types.Length; ++i) { var tp = names[i]; - tp.Define (buiders[i + parentOffset], declaringType, parent); + tp.Create (declaringType, parent); types[i] = tp.Type; types[i].DeclaredPosition = i + parentOffset; @@ -2117,6 +2309,14 @@ namespace Mono.CSharp { } } + public void Define (GenericTypeParameterBuilder[] builders) + { + for (int i = 0; i < types.Length; ++i) { + var tp = names[i]; + tp.Define (builders [types [i].DeclaredPosition]); + } + } + public TypeParameter this[int index] { get { return names [index]; @@ -2156,6 +2356,44 @@ namespace Mono.CSharp { return sb.ToString (); } + + public void CheckPartialConstraints (Method part) + { + var partTypeParameters = part.CurrentTypeParameters; + + for (int i = 0; i < Count; i++) { + var tp_a = names[i]; + var tp_b = partTypeParameters [i]; + if (tp_a.Constraints == null) { + if (tp_b.Constraints == null) + continue; + } else if (tp_b.Constraints != null && tp_a.Type.HasSameConstraintsDefinition (tp_b.Type)) { + continue; + } + + part.Compiler.Report.SymbolRelatedToPreviousError (this[i].CurrentMemberDefinition.Location, ""); + part.Compiler.Report.Error (761, part.Location, + "Partial method declarations of `{0}' have inconsistent constraints for type parameter `{1}'", + part.GetSignatureForError (), partTypeParameters[i].GetSignatureForError ()); + } + } + + public void UpdateConstraints (TypeDefinition part) + { + var partTypeParameters = part.MemberName.TypeParameters; + + for (int i = 0; i < Count; i++) { + var tp = names [i]; + if (tp.AddPartialConstraints (part, partTypeParameters [i])) + continue; + + part.Compiler.Report.SymbolRelatedToPreviousError (this[i].CurrentMemberDefinition); + part.Compiler.Report.Error (265, part.Location, + "Partial declarations of `{0}' have inconsistent constraints for type parameter `{1}'", + part.GetSignatureForError (), tp.GetSignatureForError ()); + } + } + public void VerifyClsCompliance () { foreach (var tp in names) { @@ -2186,7 +2424,7 @@ namespace Mono.CSharp { public override string GetSignatureForError () { - return TypeManager.CSharpName (type); + return type.GetSignatureForError (); } public override TypeSpec ResolveAsType (IMemberContext mc) @@ -2198,6 +2436,8 @@ namespace Mono.CSharp { return null; TypeSpec[] atypes = args.Arguments; + if (atypes == null) + return null; // // Now bind the parameters @@ -2334,7 +2574,7 @@ namespace Mono.CSharp { if (mc != null) { mc.Module.Compiler.Report.Error (452, loc, "The type `{0}' must be a reference type in order to use it as type parameter `{1}' in the generic type or method `{2}'", - TypeManager.CSharpName (atype), tparam.GetSignatureForError (), context.GetSignatureForError ()); + atype.GetSignatureForError (), tparam.GetSignatureForError (), context.GetSignatureForError ()); } return false; @@ -2344,7 +2584,7 @@ namespace Mono.CSharp { if (mc != null) { mc.Module.Compiler.Report.Error (453, loc, "The type `{0}' must be a non-nullable value type in order to use it as type parameter `{1}' in the generic type or method `{2}'", - TypeManager.CSharpName (atype), tparam.GetSignatureForError (), context.GetSignatureForError ()); + atype.GetSignatureForError (), tparam.GetSignatureForError (), context.GetSignatureForError ()); } return false; @@ -2367,13 +2607,14 @@ namespace Mono.CSharp { // // Check the interfaces constraints // - if (tparam.Interfaces != null) { - foreach (TypeSpec iface in tparam.Interfaces) { + if (tparam.InterfacesDefined != null) { + foreach (TypeSpec iface in tparam.InterfacesDefined) { if (!CheckConversion (mc, context, atype, tparam, iface, loc)) { if (mc == null) return false; ok = false; + break; } } } @@ -2388,6 +2629,7 @@ namespace Mono.CSharp { return false; ok = false; + break; } } } @@ -2403,7 +2645,7 @@ namespace Mono.CSharp { mc.Module.Compiler.Report.SymbolRelatedToPreviousError (atype); mc.Module.Compiler.Report.Error (310, loc, "The type `{0}' must have a public parameterless constructor in order to use it as parameter `{1}' in the generic type or method `{2}'", - TypeManager.CSharpName (atype), tparam.GetSignatureForError (), context.GetSignatureForError ()); + atype.GetSignatureForError (), tparam.GetSignatureForError (), context.GetSignatureForError ()); } return false; } @@ -2432,12 +2674,8 @@ namespace Mono.CSharp { if (atype.IsGenericParameter) { var tps = (TypeParameterSpec) atype; - if (tps.TypeArguments != null) { - foreach (var targ in tps.TypeArguments) { - if (TypeSpecComparer.Override.IsEqual (targ, ttype)) - return true; - } - } + if (tps.HasDependencyOn (ttype)) + return true; if (Convert.ImplicitTypeParameterConversion (null, tps, ttype) != null) return true; @@ -2513,40 +2751,6 @@ namespace Mono.CSharp { } } - public partial class TypeManager - { - public static Variance CheckTypeVariance (TypeSpec t, Variance expected, IMemberContext member) - { - var tp = t as TypeParameterSpec; - if (tp != null) { - Variance v = tp.Variance; - if (expected == Variance.None && v != expected || - expected == Variance.Covariant && v == Variance.Contravariant || - expected == Variance.Contravariant && v == Variance.Covariant) { - ((TypeParameter)tp.MemberDefinition).ErrorInvalidVariance (member, expected); - } - - return expected; - } - - if (t.TypeArguments.Length > 0) { - var targs_definition = t.MemberDefinition.TypeParameters; - TypeSpec[] targs = GetTypeArguments (t); - for (int i = 0; i < targs.Length; ++i) { - Variance v = targs_definition[i].Variance; - CheckTypeVariance (targs[i], (Variance) ((int)v * (int)expected), member); - } - - return expected; - } - - if (t.IsArray) - return CheckTypeVariance (GetElementType (t), expected, member); - - return Variance.None; - } - } - // // Implements C# type inference // @@ -2627,7 +2831,7 @@ namespace Mono.CSharp { // AnonymousMethodExpression am = a.Expr as AnonymousMethodExpression; if (am != null) { - if (am.ExplicitTypeInference (ec, tic, method_parameter)) + if (am.ExplicitTypeInference (tic, method_parameter)) --score; continue; } @@ -2693,7 +2897,7 @@ namespace Mono.CSharp { var mi = Delegate.GetInvokeMethod (t_i); TypeSpec rtype = mi.ReturnType; - if (tic.IsReturnTypeNonDependent (ec, mi, rtype)) { + if (tic.IsReturnTypeNonDependent (mi, rtype)) { // It can be null for default arguments if (arguments[i] == null) continue; @@ -2716,7 +2920,7 @@ namespace Mono.CSharp { Upper = 2 } - protected class BoundInfo : IEquatable + struct BoundInfo : IEquatable { public readonly TypeSpec Type; public readonly BoundKind Kind; @@ -2732,14 +2936,14 @@ namespace Mono.CSharp { return Type.GetHashCode (); } - public virtual Expression GetTypeExpression () + public Expression GetTypeExpression () { return new TypeExpression (Type, Location.Null); } #region IEquatable Members - public virtual bool Equals (BoundInfo other) + public bool Equals (BoundInfo other) { return Type == other.Type && Kind == other.Kind; } @@ -2750,7 +2954,6 @@ namespace Mono.CSharp { readonly TypeSpec[] tp_args; readonly TypeSpec[] fixed_types; readonly List[] bounds; - bool failed; // TODO MemberCache: Could it be TypeParameterSpec[] ?? public TypeInferenceContext (TypeSpec[] typeArguments) @@ -2792,15 +2995,20 @@ namespace Mono.CSharp { public void AddCommonTypeBound (TypeSpec type) { - AddToBounds (new BoundInfo (type, BoundKind.Lower), 0); + AddToBounds (new BoundInfo (type, BoundKind.Lower), 0, false); } - protected void AddToBounds (BoundInfo bound, int index) + public void AddCommonTypeBoundAsync (TypeSpec type) + { + AddToBounds (new BoundInfo (type, BoundKind.Lower), 0, true); + } + + void AddToBounds (BoundInfo bound, int index, bool voidAllowed) { // // Some types cannot be used as type arguments // - if (bound.Type.Kind == MemberKind.Void || bound.Type.IsPointer || bound.Type.IsSpecialRuntimeType || + if ((bound.Type.Kind == MemberKind.Void && !voidAllowed) || bound.Type.IsPointer || bound.Type.IsSpecialRuntimeType || bound.Type == InternalType.MethodGroup || bound.Type == InternalType.AnonymousMethod) return; @@ -2866,7 +3074,7 @@ namespace Mono.CSharp { for (int i = 0; i < ga_u.Length; ++i) score += ExactInference (ga_u [i], ga_v [i]); - return score > 0 ? 1 : 0; + return System.Math.Min (1, score); } // If V is one of the unfixed type arguments @@ -2874,7 +3082,7 @@ namespace Mono.CSharp { if (pos == -1) return 0; - AddToBounds (new BoundInfo (u, BoundKind.Exact), pos); + AddToBounds (new BoundInfo (u, BoundKind.Exact), pos, false); return 1; } @@ -2964,9 +3172,6 @@ namespace Mono.CSharp { if (fixed_types[i] != null) throw new InternalErrorException ("Type argument has been already fixed"); - if (failed) - return false; - var candidates = bounds [i]; if (candidates == null) return false; @@ -2981,87 +3186,100 @@ namespace Mono.CSharp { } // - // Determines a unique type from which there is - // a standard implicit conversion to all the other - // candidate types. + // The set of candidate types Uj starts out as the set of + // all types in the set of bounds for Xi // - TypeSpec best_candidate = null; - int cii; - int candidates_count = candidates.Count; - for (int ci = 0; ci < candidates_count; ++ci) { - BoundInfo bound = candidates [ci]; - for (cii = 0; cii < candidates_count; ++cii) { - if (cii == ci) - continue; + var applicable = new bool [candidates.Count]; + for (int ci = 0; ci < applicable.Length; ++ci) + applicable [ci] = true; + + for (int ci = 0; ci < applicable.Length; ++ci) { + var bound = candidates [ci]; + int cii = 0; + + switch (bound.Kind) { + case BoundKind.Exact: + for (; cii != applicable.Length; ++cii) { + if (ci == cii) + continue; - BoundInfo cbound = candidates[cii]; - - // Same type parameters with different bounds - if (cbound.Type == bound.Type) { - if (bound.Kind != BoundKind.Exact) - bound = cbound; + if (!applicable[cii]) + break; - continue; + // + // For each exact bound U of Xi all types Uj which are not identical + // to U are removed from the candidate set + // + if (candidates [cii].Type != bound.Type) + applicable[cii] = false; } - if (bound.Kind == BoundKind.Exact || cbound.Kind == BoundKind.Exact) { - if (cbound.Kind == BoundKind.Lower) { - if (!Convert.ImplicitConversionExists (ec, cbound.GetTypeExpression (), bound.Type)) { - break; - } - + break; + case BoundKind.Lower: + for (; cii != applicable.Length; ++cii) { + if (ci == cii) continue; - } - if (cbound.Kind == BoundKind.Upper) { - if (!Convert.ImplicitConversionExists (ec, bound.GetTypeExpression (), cbound.Type)) { - break; - } - continue; + if (!applicable[cii]) + break; + + // + // For each lower bound U of Xi all types Uj to which there is not an implicit conversion + // from U are removed from the candidate set + // + if (!Convert.ImplicitConversionExists (ec, bound.GetTypeExpression (), candidates [cii].Type)) { + applicable[cii] = false; } - - if (bound.Kind != BoundKind.Exact) { - if (!Convert.ImplicitConversionExists (ec, bound.GetTypeExpression (), cbound.Type)) { - break; - } + } + + break; - bound = cbound; + case BoundKind.Upper: + for (; cii != applicable.Length; ++cii) { + if (ci == cii) continue; - } - - break; + + if (!applicable[cii]) + break; + + // + // For each upper bound U of Xi all types Uj from which there is not an implicit conversion + // to U are removed from the candidate set + // + if (!Convert.ImplicitConversionExists (ec, candidates[cii].GetTypeExpression (), bound.Type)) + applicable[cii] = false; } - if (bound.Kind == BoundKind.Lower) { - if (cbound.Kind == BoundKind.Lower) { - if (!Convert.ImplicitConversionExists (ec, cbound.GetTypeExpression (), bound.Type)) { - break; - } - } else { - if (!Convert.ImplicitConversionExists (ec, bound.GetTypeExpression (), cbound.Type)) { - break; - } + break; + } + } - bound = cbound; - } + TypeSpec best_candidate = null; + for (int ci = 0; ci < applicable.Length; ++ci) { + if (!applicable[ci]) + continue; + + var bound = candidates [ci]; + if (bound.Type == best_candidate) + continue; + int cii = 0; + for (; cii < applicable.Length; ++cii) { + if (ci == cii) continue; - } - if (bound.Kind == BoundKind.Upper) { - if (!Convert.ImplicitConversionExists (ec, bound.GetTypeExpression (), cbound.Type)) { - break; - } - } else { - throw new NotImplementedException ("variance conversion"); - } + if (!applicable[cii]) + continue; + + if (!Convert.ImplicitConversionExists (ec, candidates[cii].GetTypeExpression (), bound.Type)) + break; } - if (cii != candidates_count) + if (cii != applicable.Length) continue; // - // We already have the best candidate, break if thet are different + // We already have the best candidate, break if it's different (non-unique) // // Dynamic is never ambiguous as we prefer dynamic over other best candidate types // @@ -3140,8 +3358,13 @@ namespace Mono.CSharp { // Tests whether all delegate input arguments are fixed and generic output type // requires output type inference // - public bool IsReturnTypeNonDependent (ResolveContext ec, MethodSpec invoke, TypeSpec returnType) + public bool IsReturnTypeNonDependent (MethodSpec invoke, TypeSpec returnType) { + AParametersCollection d_parameters = invoke.Parameters; + + if (d_parameters.IsEmpty) + return true; + while (returnType.IsArray) returnType = ((ArrayContainer) returnType).Element; @@ -3149,11 +3372,6 @@ namespace Mono.CSharp { if (IsFixed (returnType)) return false; } else if (TypeManager.IsGenericType (returnType)) { - if (returnType.IsDelegate) { - invoke = Delegate.GetInvokeMethod (returnType); - return IsReturnTypeNonDependent (ec, invoke, invoke.ReturnType); - } - TypeSpec[] g_args = TypeManager.GetTypeArguments (returnType); // At least one unfixed return type has to exist @@ -3164,10 +3382,9 @@ namespace Mono.CSharp { } // All generic input arguments have to be fixed - AParametersCollection d_parameters = invoke.Parameters; return AllTypesAreFixed (d_parameters.Types); } - + bool IsFixed (TypeSpec type) { return IsUnfixed (type) == -1; @@ -3206,7 +3423,7 @@ namespace Mono.CSharp { // If V is one of the unfixed type arguments int pos = IsUnfixed (v); if (pos != -1) { - AddToBounds (new BoundInfo (u, inversed ? BoundKind.Upper : BoundKind.Lower), pos); + AddToBounds (new BoundInfo (u, inversed ? BoundKind.Upper : BoundKind.Lower), pos, false); return 1; } @@ -3224,7 +3441,7 @@ namespace Mono.CSharp { return LowerBoundInference (u_ac.Element, v_ac.Element, inversed); } - if (u_ac.Rank != 1 || !v.IsGenericIterateInterface) + if (u_ac.Rank != 1 || !v.IsArrayGenericInterface) return 0; var v_i = TypeManager.GetTypeArguments (v) [0]; @@ -3253,12 +3470,12 @@ namespace Mono.CSharp { // if (t.BuiltinType == BuiltinTypeSpec.Type.Dynamic) u_candidates.Add (t); + } - if (t.Interfaces != null) { - foreach (var iface in t.Interfaces) { - if (open_v == iface.MemberDefinition) - u_candidates.Add (iface); - } + if (u.Interfaces != null) { + foreach (var iface in u.Interfaces) { + if (open_v == iface.MemberDefinition) + u_candidates.Add (iface); } } @@ -3278,10 +3495,9 @@ namespace Mono.CSharp { } // - // This should always cause type inference failure + // Break when candidate arguments are ambiguous // - failed = true; - return 1; + return 0; } // @@ -3374,7 +3590,7 @@ namespace Mono.CSharp { var invoke = Delegate.GetInvokeMethod (t); TypeSpec rtype = invoke.ReturnType; - if (!rtype.IsGenericParameter && !TypeManager.IsGenericType (rtype)) + if (!IsReturnTypeNonDependent (invoke, rtype)) return 0; // LAMESPEC: Standard does not specify that all methodgroup arguments @@ -3387,14 +3603,11 @@ namespace Mono.CSharp { if (inflated == null) return 0; - if (IsUnfixed (inflated) >= 0) - return 0; - param_types[i] = inflated; } MethodGroupExpr mg = (MethodGroupExpr) e; - Arguments args = DelegateCreation.CreateDelegateMethodArguments (invoke.Parameters, param_types, e.Location); + Arguments args = DelegateCreation.CreateDelegateMethodArguments (ec, invoke.Parameters, param_types, e.Location); mg = mg.OverloadResolve (ec, ref args, null, OverloadResolver.Restrictions.CovariantDelegate | OverloadResolver.Restrictions.ProbingOnly); if (mg == null) return 0; diff --git a/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/import.cs b/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/import.cs index 605db44fb..0d7e9e5ad 100644 --- a/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/import.cs +++ b/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/import.cs @@ -6,7 +6,7 @@ // Dual licensed under the terms of the MIT X11 or GNU GPL // // Copyright 2009-2011 Novell, Inc -// Copyright 2011 Xamarin, Inc (http://www.xamarin.com) +// Copyright 2011-2012 Xamarin, Inc (http://www.xamarin.com) // using System; @@ -32,7 +32,7 @@ namespace Mono.CSharp // Dynamic types reader with additional logic to reconstruct a dynamic // type using DynamicAttribute values // - struct DynamicTypeReader + protected struct DynamicTypeReader { static readonly bool[] single_attribute = { true }; @@ -56,10 +56,10 @@ namespace Mono.CSharp // // Returns true when object at local position has dynamic attribute flag // - public bool IsDynamicObject (MetadataImporter importer) + public bool IsDynamicObject () { if (provider != null) - ReadAttribute (importer); + ReadAttribute (); return flags != null && Position < flags.Length && flags[Position]; } @@ -67,23 +67,32 @@ namespace Mono.CSharp // // Returns true when DynamicAttribute exists // - public bool HasDynamicAttribute (MetadataImporter importer) + public bool HasDynamicAttribute () { if (provider != null) - ReadAttribute (importer); + ReadAttribute (); return flags != null; } - void ReadAttribute (MetadataImporter importer) + IList GetCustomAttributes () { - IList cad; - if (provider is MemberInfo) { - cad = CustomAttributeData.GetCustomAttributes ((MemberInfo) provider); - } else if (provider is ParameterInfo) { - cad = CustomAttributeData.GetCustomAttributes ((ParameterInfo) provider); - } else { - provider = null; + var mi = provider as MemberInfo; + if (mi != null) + return CustomAttributeData.GetCustomAttributes (mi); + + var pi = provider as ParameterInfo; + if (pi != null) + return CustomAttributeData.GetCustomAttributes (pi); + + provider = null; + return null; + } + + void ReadAttribute () + { + var cad = GetCustomAttributes (); + if (cad == null) { return; } @@ -120,7 +129,7 @@ namespace Mono.CSharp protected readonly Dictionary import_cache; protected readonly Dictionary compiled_types; protected readonly Dictionary assembly_2_definition; - readonly ModuleContainer module; + protected readonly ModuleContainer module; public static readonly string CompilerServicesNamespace = "System.Runtime.CompilerServices"; @@ -152,7 +161,7 @@ namespace Mono.CSharp public FieldSpec CreateField (FieldInfo fi, TypeSpec declaringType) { - Modifiers mod = 0; + Modifiers mod; var fa = fi.Attributes; switch (fa & FieldAttributes.FieldAccessMask) { case FieldAttributes.Public: @@ -181,6 +190,12 @@ namespace Mono.CSharp try { field_type = ImportType (fi.FieldType, new DynamicTypeReader (fi)); + + // + // Private field has private type which is not fixed buffer + // + if (field_type == null) + return null; } catch (Exception e) { // TODO: I should construct fake TypeSpec based on TypeRef signature // but there is no way to do it with System.Reflection @@ -191,7 +206,9 @@ namespace Mono.CSharp var definition = new ImportedMemberDefinition (fi, field_type, this); if ((fa & FieldAttributes.Literal) != 0) { - var c = Constant.CreateConstantFromValue (field_type, fi.GetRawConstantValue (), Location.Null); + Constant c = field_type.Kind == MemberKind.MissingType ? + new NullConstant (InternalType.ErrorType, Location.Null) : + Constant.CreateConstantFromValue (field_type, fi.GetRawConstantValue (), Location.Null); return new ConstSpec (declaringType, definition, field_type, fi, mod, c); } @@ -218,7 +235,7 @@ namespace Mono.CSharp // TODO: Sanity check on field_type (only few types are allowed) var element_field = CreateField (fi.FieldType.GetField (FixedField.FixedElementName), declaringType); - return new FixedFieldSpec (declaringType, definition, fi, element_field, mod); + return new FixedFieldSpec (module, declaringType, definition, fi, element_field, mod); } } @@ -322,14 +339,16 @@ namespace Mono.CSharp // IFoo> foo; // A is definition in this case // } // - // TODO: Is full logic from CreateType needed here as well? - // if (!IsMissingType (type) && type.IsGenericTypeDefinition) { - var targs = CreateGenericArguments (0, type.GetGenericArguments (), dtype); + var start_pos = spec.DeclaringType == null ? 0 : spec.DeclaringType.MemberDefinition.TypeParametersCount; + var targs = CreateGenericArguments (start_pos, type.GetGenericArguments (), dtype); spec = spec.MakeGenericType (module, targs); } } + if (spec == null) + return null; + ++dtype.Position; tspec[index] = spec; } @@ -366,7 +385,7 @@ namespace Mono.CSharp kind = MemberKind.Method; if (tparams == null && !mb.DeclaringType.IsInterface && name.Length > 6) { if ((mod & (Modifiers.STATIC | Modifiers.PUBLIC)) == (Modifiers.STATIC | Modifiers.PUBLIC)) { - if (name[2] == '_' && name[1] == 'p' && name[0] == 'o') { + if (name[2] == '_' && name[1] == 'p' && name[0] == 'o' && (mb.Attributes & MethodAttributes.SpecialName) != 0) { var op_type = Operator.GetType (name); if (op_type.HasValue && parameters.Count > 0 && parameters.Count < 3) { kind = MemberKind.Operator; @@ -418,7 +437,7 @@ namespace Mono.CSharp } } - IMemberDefinition definition; + IMethodDefinition definition; if (tparams != null) { var gmd = new ImportedGenericMethodDefinition ((MethodInfo) mb, returnType, parameters, tparams, this); foreach (var tp in gmd.TypeParameters) { @@ -427,10 +446,10 @@ namespace Mono.CSharp definition = gmd; } else { - definition = new ImportedParameterMemberDefinition (mb, returnType, parameters, this); + definition = new ImportedMethodDefinition (mb, returnType, parameters, this); } - MethodSpec ms = new MethodSpec (kind, declaringType, definition, returnType, mb, parameters, mod); + MethodSpec ms = new MethodSpec (kind, declaringType, definition, returnType, parameters, mod); if (tparams != null) ms.IsGeneric = true; @@ -489,10 +508,10 @@ namespace Mono.CSharp // var el = p.ParameterType.GetElementType (); types[i] = ImportType (el, new DynamicTypeReader (p)); // TODO: 1-based positio to be csc compatible - } else if (i == 0 && method.IsStatic && parent.IsStatic && parent.MemberDefinition.DeclaringAssembly.HasExtensionMethod && + } else if (i == 0 && method.IsStatic && (parent.Modifiers & Modifiers.METHOD_EXTENSION) != 0 && HasAttribute (CustomAttributeData.GetCustomAttributes (method), "ExtensionAttribute", CompilerServicesNamespace)) { mod = Parameter.Modifier.This; - types[i] = ImportType (p.ParameterType); + types[i] = ImportType (p.ParameterType, new DynamicTypeReader (p)); } else { types[i] = ImportType (p.ParameterType, new DynamicTypeReader (p)); @@ -508,7 +527,7 @@ namespace Mono.CSharp var ptype = types[i]; if ((p.Attributes & ParameterAttributes.HasDefault) != 0 && ptype.Kind != MemberKind.TypeParameter && (value != null || TypeSpec.IsReferenceType (ptype))) { if (value == null) { - default_value = Constant.CreateConstant (ptype, null, Location.Null); + default_value = Constant.CreateConstantFromValue (ptype, null, Location.Null); } else { default_value = ImportParameterConstant (value); @@ -516,6 +535,21 @@ namespace Mono.CSharp default_value = new EnumConstant ((Constant) default_value, ptype); } } + + var attrs = CustomAttributeData.GetCustomAttributes (p); + for (int ii = 0; ii < attrs.Count; ++ii) { + var attr = attrs[ii]; + var dt = attr.Constructor.DeclaringType; + if (dt.Namespace != CompilerServicesNamespace) + continue; + + if (dt.Name == "CallerLineNumberAttribute" && (ptype.BuiltinType == BuiltinTypeSpec.Type.Int || Convert.ImplicitNumericConversionExists (module.Compiler.BuiltinTypes.Int, ptype))) + mod |= Parameter.Modifier.CallerLineNumber; + else if (dt.Name == "CallerFilePathAttribute" && Convert.ImplicitReferenceConversionExists (module.Compiler.BuiltinTypes.String, ptype)) + mod |= Parameter.Modifier.CallerFilePath; + else if (dt.Name == "CallerMemberNameAttribute" && Convert.ImplicitReferenceConversionExists (module.Compiler.BuiltinTypes.String, ptype)) + mod |= Parameter.Modifier.CallerMemberName; + } } else if (value == Missing.Value) { default_value = EmptyExpression.MissingValue; } else if (value == null) { @@ -618,26 +652,41 @@ namespace Mono.CSharp PropertySpec spec = null; if (!param.IsEmpty) { - var index_name = declaringType.MemberDefinition.GetAttributeDefaultMember (); - if (index_name == null) { - is_valid_property = false; - } else { - if (get != null) { - if (get.IsStatic) - is_valid_property = false; - if (get.Name.IndexOf (index_name, StringComparison.Ordinal) != 4) - is_valid_property = false; + if (is_valid_property) { + var index_name = declaringType.MemberDefinition.GetAttributeDefaultMember (); + if (index_name == null) { + is_valid_property = false; + } else { + if (get != null) { + if (get.IsStatic) + is_valid_property = false; + if (get.Name.IndexOf (index_name, StringComparison.Ordinal) != 4) + is_valid_property = false; + } + if (set != null) { + if (set.IsStatic) + is_valid_property = false; + if (set.Name.IndexOf (index_name, StringComparison.Ordinal) != 4) + is_valid_property = false; + } } - if (set != null) { - if (set.IsStatic) - is_valid_property = false; - if (set.Name.IndexOf (index_name, StringComparison.Ordinal) != 4) - is_valid_property = false; + + if (is_valid_property) { + spec = new IndexerSpec (declaringType, new ImportedParameterMemberDefinition (pi, type, param, this), type, param, pi, mod); + } else if (declaringType.MemberDefinition.IsComImport && param.FixedParameters[0].HasDefaultValue) { + // + // Enables support for properties with parameters (must have default value) of COM-imported types + // + is_valid_property = true; + + for (int i = 0; i < param.FixedParameters.Length; ++i) { + if (!param.FixedParameters[i].HasDefaultValue) { + is_valid_property = false; + break; + } + } } } - - if (is_valid_property) - spec = new IndexerSpec (declaringType, new ImportedParameterMemberDefinition (pi, type, param, this), type, param, pi, mod); } if (spec == null) @@ -677,12 +726,12 @@ namespace Mono.CSharp return CreateType (type, declaring_type, dtype, canImportBaseType); } - TypeSpec CreateType (MetaType type, TypeSpec declaringType, DynamicTypeReader dtype, bool canImportBaseType) + protected TypeSpec CreateType (MetaType type, TypeSpec declaringType, DynamicTypeReader dtype, bool canImportBaseType) { TypeSpec spec; if (import_cache.TryGetValue (type, out spec)) { if (spec.BuiltinType == BuiltinTypeSpec.Type.Object) { - if (dtype.IsDynamicObject (this)) + if (dtype.IsDynamicObject ()) return module.Compiler.BuiltinTypes.Dynamic; return spec; @@ -691,7 +740,7 @@ namespace Mono.CSharp if (!spec.IsGeneric || type.IsGenericTypeDefinition) return spec; - if (!dtype.HasDynamicAttribute (this)) + if (!dtype.HasDynamicAttribute ()) return spec; // We've found same object in the cache but this one has a dynamic custom attribute @@ -716,6 +765,8 @@ namespace Mono.CSharp return spec; var targs = CreateGenericArguments (0, type.GetGenericArguments (), dtype); + if (targs == null) + return null; if (declaringType == null) { // Simple case, no nesting spec = CreateType (type_def, null, new DynamicTypeReader (), canImportBaseType); @@ -742,24 +793,34 @@ namespace Mono.CSharp for (int i = nested_hierarchy.Count; i != 0; --i) { var t = nested_hierarchy [i - 1]; - spec = MemberCache.FindNestedType (spec, t.Name, t.Arity); + if (t.Kind == MemberKind.MissingType) + spec = t; + else + spec = MemberCache.FindNestedType (spec, t.Name, t.Arity); + if (t.Arity > 0) { spec = spec.MakeGenericType (module, targs.Skip (targs_pos).Take (spec.Arity).ToArray ()); targs_pos += t.Arity; } } - string name = type.Name; - int index = name.IndexOf ('`'); - if (index > 0) - name = name.Substring (0, index); + if (spec.Kind == MemberKind.MissingType) { + spec = new TypeSpec (MemberKind.MissingType, spec, new ImportedTypeDefinition (type_def, this), type_def, Modifiers.PUBLIC); + spec.MemberCache = MemberCache.Empty; + } else { + if ((type_def.Attributes & TypeAttributes.VisibilityMask) == TypeAttributes.NestedPrivate && IgnorePrivateMembers) + return null; - spec = MemberCache.FindNestedType (spec, name, targs.Length - targs_pos); - if (spec == null) - return null; + string name = type.Name; + int index = name.IndexOf ('`'); + if (index > 0) + name = name.Substring (0, index); - if (spec.Arity > 0) { - spec = spec.MakeGenericType (module, targs.Skip (targs_pos).ToArray ()); + spec = MemberCache.FindNestedType (spec, name, targs.Length - targs_pos); + + if (spec.Arity > 0) { + spec = spec.MakeGenericType (module, targs.Skip (targs_pos).ToArray ()); + } } } @@ -815,9 +876,10 @@ namespace Mono.CSharp if (kind == MemberKind.Class) { if ((ma & TypeAttributes.Sealed) != 0) { - mod |= Modifiers.SEALED; if ((ma & TypeAttributes.Abstract) != 0) mod |= Modifiers.STATIC; + else + mod |= Modifiers.SEALED; } else if ((ma & TypeAttributes.Abstract) != 0) { mod |= Modifiers.ABSTRACT; } @@ -974,53 +1036,6 @@ namespace Mono.CSharp spec.BaseType = base_type; } - MetaType[] ifaces; -#if STATIC - ifaces = type.__GetDeclaredInterfaces (); - if (ifaces.Length != 0) { - foreach (var iface in ifaces) { - var it = CreateType (iface); - if (it == null) - continue; - - spec.AddInterface (it); - - // Unfortunately not all languages expand inherited interfaces - var bifaces = it.Interfaces; - if (bifaces != null) { - foreach (var biface in bifaces) { - spec.AddInterface (biface); - } - } - } - } - - if (spec.BaseType != null) { - var bifaces = spec.BaseType.Interfaces; - if (bifaces != null) { - // - // Before adding base class interfaces close defined interfaces - // on type parameter - // - var tp = spec as TypeParameterSpec; - if (tp != null && tp.InterfacesDefined == null) { - tp.InterfacesDefined = TypeSpec.EmptyTypes; - } - - foreach (var iface in bifaces) - spec.AddInterface (iface); - } - } -#else - ifaces = type.GetInterfaces (); - - if (ifaces.Length > 0) { - foreach (var iface in ifaces) { - spec.AddInterface (CreateType (iface)); - } - } -#endif - if (spec.MemberDefinition.TypeParametersCount > 0) { foreach (var tp in spec.MemberDefinition.TypeParameters) { ImportTypeParameterTypeConstraints (tp, tp.GetMetaInfo ()); @@ -1028,7 +1043,7 @@ namespace Mono.CSharp } } - protected void ImportTypes (MetaType[] types, Namespace targetNamespace, bool hasExtensionTypes) + protected void ImportTypes (MetaType[] types, Namespace targetNamespace, bool importExtensionTypes) { Namespace ns = targetNamespace; string prev_namespace = null; @@ -1052,12 +1067,14 @@ namespace Mono.CSharp prev_namespace = t.Namespace; } - ns.AddType (module, it); - - if (it.IsStatic && hasExtensionTypes && + // Cannot rely on assembly level Extension attribute or static modifier because they + // are not followed by other compilers (e.g. F#). + if (it.IsClass && it.Arity == 0 && importExtensionTypes && HasAttribute (CustomAttributeData.GetCustomAttributes (t), "ExtensionAttribute", CompilerServicesNamespace)) { it.SetExtensionMethodContainer (); } + + ns.AddType (module, it); } } @@ -1074,12 +1091,13 @@ namespace Mono.CSharp continue; } - if (!IsMissingType (ct) && ct.IsClass) { - spec.BaseType = CreateType (ct); + var constraint_type = CreateType (ct); + if (constraint_type.IsClass) { + spec.BaseType = constraint_type; continue; } - spec.AddInterface (CreateType (ct)); + spec.AddInterface (constraint_type); } if (spec.BaseType == null) @@ -1152,6 +1170,14 @@ namespace Mono.CSharp throw new NotImplementedException ("Unknown element type " + type.ToString ()); } + TypeSpec compiled_type; + if (compiled_types.TryGetValue (type, out compiled_type)) { + if (compiled_type.BuiltinType == BuiltinTypeSpec.Type.Object && dtype.IsDynamicObject ()) + return module.Compiler.BuiltinTypes.Dynamic; + + return compiled_type; + } + return CreateType (type, dtype, true); } @@ -1374,7 +1400,7 @@ namespace Mono.CSharp protected AttributesBag cattrs; protected readonly MetadataImporter importer; - public ImportedDefinition (MemberInfo provider, MetadataImporter importer) + protected ImportedDefinition (MemberInfo provider, MetadataImporter importer) { this.provider = provider; this.importer = importer; @@ -1520,7 +1546,6 @@ namespace Mono.CSharp readonly Assembly assembly; readonly AssemblyName aname; bool cls_compliant; - bool contains_extension_methods; List internals_visible_to; Dictionary internals_visible_to_cache; @@ -1545,12 +1570,6 @@ namespace Mono.CSharp } } - public bool HasExtensionMethod { - get { - return contains_extension_methods; - } - } - public bool HasStrongName { get { return aname.GetPublicKey ().Length != 0; @@ -1668,13 +1687,6 @@ namespace Mono.CSharp internals_visible_to.Add (an); continue; } - - if (name == "ExtensionAttribute") { - if (dt.Namespace == MetadataImporter.CompilerServicesNamespace) - contains_extension_methods = true; - - continue; - } } } @@ -1709,7 +1721,7 @@ namespace Mono.CSharp { readonly AParametersCollection parameters; - public ImportedParameterMemberDefinition (MethodBase provider, TypeSpec type, AParametersCollection parameters, MetadataImporter importer) + protected ImportedParameterMemberDefinition (MethodBase provider, TypeSpec type, AParametersCollection parameters, MetadataImporter importer) : base (provider, type, importer) { this.parameters = parameters; @@ -1732,7 +1744,21 @@ namespace Mono.CSharp #endregion } - class ImportedGenericMethodDefinition : ImportedParameterMemberDefinition, IGenericMethodDefinition + class ImportedMethodDefinition : ImportedParameterMemberDefinition, IMethodDefinition + { + public ImportedMethodDefinition (MethodBase provider, TypeSpec type, AParametersCollection parameters, MetadataImporter importer) + : base (provider, type, parameters, importer) + { + } + + MethodBase IMethodDefinition.Metadata { + get { + return (MethodBase) provider; + } + } + } + + class ImportedGenericMethodDefinition : ImportedMethodDefinition, IGenericMethodDefinition { readonly TypeParameterSpec[] tparams; @@ -1777,12 +1803,39 @@ namespace Mono.CSharp } } + bool ITypeDefinition.IsComImport { + get { + return ((MetaType) provider).IsImport; + } + } + + bool ITypeDefinition.IsPartial { get { return false; } } + bool ITypeDefinition.IsTypeForwarder { + get { +#if STATIC + return ((MetaType) provider).__IsTypeForwarder; +#else + return false; +#endif + } + } + + bool ITypeDefinition.IsCyclicTypeForwarder { + get { +#if STATIC + return ((MetaType) provider).__IsCyclicTypeForwarder; +#else + return false; +#endif + } + } + public override string Name { get { if (name == null) { @@ -1821,7 +1874,64 @@ namespace Mono.CSharp #endregion - public static void Error_MissingDependency (IMemberContext ctx, List types, Location loc) + public void DefineInterfaces (TypeSpec spec) + { + var type = (MetaType) provider; + MetaType[] ifaces; +#if STATIC + ifaces = type.__GetDeclaredInterfaces (); + if (ifaces.Length != 0) { + foreach (var iface in ifaces) { + var it = importer.CreateType (iface); + if (it == null) + continue; + + spec.AddInterfaceDefined (it); + + // Unfortunately not all languages expand inherited interfaces + var bifaces = it.Interfaces; + if (bifaces != null) { + foreach (var biface in bifaces) { + spec.AddInterfaceDefined (biface); + } + } + } + } + + // + // It's impossible to get declared interfaces only using System.Reflection + // hence we need to mimic the behavior with ikvm-reflection too to keep + // our type look-up logic same + // + if (spec.BaseType != null) { + var bifaces = spec.BaseType.Interfaces; + if (bifaces != null) { + // + // Before adding base class interfaces close defined interfaces + // on type parameter + // + var tp = spec as TypeParameterSpec; + if (tp != null && tp.InterfacesDefined == null) { + tp.InterfacesDefined = TypeSpec.EmptyTypes; + } + + foreach (var iface in bifaces) + spec.AddInterfaceDefined (iface); + } + } +#else + ifaces = type.GetInterfaces (); + + if (ifaces.Length > 0) { + foreach (var iface in ifaces) { + spec.AddInterface (importer.CreateType (iface)); + } + } +#endif + + } + + public static void Error_MissingDependency (IMemberContext ctx, List missing, Location loc) { // // Report details about missing type and most likely cause of the problem. @@ -1829,27 +1939,44 @@ namespace Mono.CSharp // or referenced from the user core in which case compilation error has to // be reported because compiler cannot continue anyway // - for (int i = 0; i < types.Count; ++i) { - var t = types [i]; + + var report = ctx.Module.Compiler.Report; + + for (int i = 0; i < missing.Count; ++i) { + var t = missing [i].Type; // - // Report missing types only once per type + // Report missing types only once // - if (i > 0 && types.IndexOf (t) < i) + if (report.Printer.MissingTypeReported (t.MemberDefinition)) continue; string name = t.GetSignatureForError (); - if (t.MemberDefinition.DeclaringAssembly == ctx.Module.DeclaringAssembly) { - ctx.Module.Compiler.Report.Error (1683, loc, + var caller = missing[i].Caller; + if (caller.Kind != MemberKind.MissingType) + report.SymbolRelatedToPreviousError (caller); + + var definition = t.MemberDefinition; + if (definition.DeclaringAssembly == ctx.Module.DeclaringAssembly) { + report.Error (1683, loc, "Reference to type `{0}' claims it is defined in this assembly, but it is not defined in source or any added modules", name); - } else if (t.MemberDefinition.DeclaringAssembly.IsMissing) { - ctx.Module.Compiler.Report.Error (12, loc, - "The type `{0}' is defined in an assembly that is not referenced. Consider adding a reference to assembly `{1}'", - name, t.MemberDefinition.DeclaringAssembly.FullName); + } else if (definition.DeclaringAssembly.IsMissing) { + if (definition.IsTypeForwarder) { + report.Error (1070, loc, + "The type `{0}' has been forwarded to an assembly that is not referenced. Consider adding a reference to assembly `{1}'", + name, definition.DeclaringAssembly.FullName); + } else { + report.Error (12, loc, + "The type `{0}' is defined in an assembly that is not referenced. Consider adding a reference to assembly `{1}'", + name, definition.DeclaringAssembly.FullName); + } + } else if (definition.IsTypeForwarder) { + report.Error (731, loc, "The type forwarder for type `{0}' in assembly `{1}' has circular dependency", + name, definition.DeclaringAssembly.FullName); } else { - ctx.Module.Compiler.Report.Error (1684, loc, + report.Error (1684, loc, "Reference to type `{0}' claims it is defined assembly `{1}', but it could not be found", name, t.MemberDefinition.DeclaringAssembly.FullName); } @@ -1974,6 +2101,10 @@ namespace Mono.CSharp foreach (var member in all) { switch (member.MemberType) { case MemberTypes.Constructor: + if (declaringType.IsInterface) + continue; + + goto case MemberTypes.Method; case MemberTypes.Method: MethodBase mb = (MethodBase) member; var attrs = mb.Attributes; @@ -2022,7 +2153,13 @@ namespace Mono.CSharp if (get == null && set == null) continue; - imported = importer.CreateProperty (p, declaringType, get, set); + try { + imported = importer.CreateProperty (p, declaringType, get, set); + } catch (Exception ex) { + throw new InternalErrorException (ex, "Could not import property `{0}' inside `{1}'", + p.Name, declaringType.GetSignatureForError ()); + } + if (imported == null) continue; @@ -2094,6 +2231,9 @@ namespace Mono.CSharp throw new NotImplementedException (member.ToString ()); } + if (imported.IsStatic && declaringType.IsInterface) + continue; + cache.AddMemberImported (imported); } } @@ -2115,12 +2255,30 @@ namespace Mono.CSharp } } + bool ITypeDefinition.IsComImport { + get { + return false; + } + } + bool ITypeDefinition.IsPartial { get { return false; } } + bool ITypeDefinition.IsTypeForwarder { + get { + return false; + } + } + + bool ITypeDefinition.IsCyclicTypeForwarder { + get { + return false; + } + } + public string Namespace { get { return null; diff --git a/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/iterators.cs b/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/iterators.cs index 665981ca7..8b45f88a9 100644 --- a/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/iterators.cs +++ b/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/iterators.cs @@ -29,7 +29,8 @@ namespace Mono.CSharp protected bool unwind_protect; protected T machine_initializer; int resume_pc; - + ExceptionStatement inside_try_block; + protected YieldStatement (Expression expr, Location l) { this.expr = expr; @@ -51,6 +52,15 @@ namespace Mono.CSharp machine_initializer.InjectYield (ec, expr, resume_pc, unwind_protect, resume_point); } + protected override bool DoFlowAnalysis (FlowAnalysisContext fc) + { + expr.FlowAnalysis (fc); + + RegisterResumePoint (); + + return false; + } + public override bool Resolve (BlockContext bc) { expr = expr.Resolve (bc); @@ -58,12 +68,20 @@ namespace Mono.CSharp return false; machine_initializer = bc.CurrentAnonymousMethod as T; - - if (!bc.CurrentBranching.CurrentUsageVector.IsUnreachable) - unwind_protect = bc.CurrentBranching.AddResumePoint (this, out resume_pc); - + inside_try_block = bc.CurrentTryBlock; return true; } + + public void RegisterResumePoint () + { + if (inside_try_block == null) { + resume_pc = machine_initializer.AddResumePoint (this); + } else { + resume_pc = inside_try_block.AddResumePoint (this, resume_pc, machine_initializer); + unwind_protect = true; + inside_try_block = null; + } + } } public class Yield : YieldStatement @@ -73,14 +91,19 @@ namespace Mono.CSharp { } - public static bool CheckContext (ResolveContext ec, Location loc) + public static bool CheckContext (BlockContext bc, Location loc) { - if (!ec.CurrentAnonymousMethod.IsIterator) { - ec.Report.Error (1621, loc, + if (!bc.CurrentAnonymousMethod.IsIterator) { + bc.Report.Error (1621, loc, "The yield statement cannot be used inside anonymous method blocks"); return false; } + if (bc.HasSet (ResolveContext.Options.FinallyScope)) { + bc.Report.Error (1625, loc, "Cannot yield in the body of a finally clause"); + return false; + } + return true; } @@ -89,6 +112,14 @@ namespace Mono.CSharp if (!CheckContext (bc, loc)) return false; + if (bc.HasAny (ResolveContext.Options.TryWithCatchScope)) { + bc.Report.Error (1626, loc, "Cannot yield a value in the body of a try block with a catch clause"); + } + + if (bc.HasSet (ResolveContext.Options.CatchScope)) { + bc.Report.Error (1631, loc, "Cannot yield a value in the body of a catch clause"); + } + if (!base.Resolve (bc)) return false; @@ -117,9 +148,10 @@ namespace Mono.CSharp loc = l; } - public override void Error_FinallyClause (Report Report) - { - Report.Error (1625, loc, "Cannot yield in the body of a finally clause"); + protected override bool IsLocalExit { + get { + return false; + } } protected override void CloneTo (CloneContext clonectx, Statement target) @@ -127,16 +159,27 @@ namespace Mono.CSharp throw new NotSupportedException (); } - protected override bool DoResolve (BlockContext ec) + protected override bool DoResolve (BlockContext bc) { - iterator = ec.CurrentIterator; - return Yield.CheckContext (ec, loc); + iterator = bc.CurrentIterator; + return Yield.CheckContext (bc, loc); } protected override void DoEmit (EmitContext ec) { iterator.EmitYieldBreak (ec, unwind_protect); } + + protected override bool DoFlowAnalysis (FlowAnalysisContext fc) + { + return true; + } + + public override Reachability MarkReachable (Reachability rc) + { + base.MarkReachable (rc); + return Reachability.CreateUnreachable (); + } public override object Accept (StructuralVisitor visitor) { @@ -161,10 +204,13 @@ namespace Mono.CSharp protected StateMachine (ParametersBlock block, TypeDefinition parent, MemberBase host, TypeParameters tparams, string name, MemberKind kind) : base (block, parent, host, tparams, name, kind) { + OriginalTypeParameters = tparams; } #region Properties + public TypeParameters OriginalTypeParameters { get; private set; } + public StateMachineMethod StateMachineMethod { get { return method; @@ -245,7 +291,7 @@ namespace Mono.CSharp for (int i = 0; i < host.hoisted_params.Count; ++i) { HoistedParameter hp = host.hoisted_params [i]; - HoistedParameter hp_cp = host.hoisted_params_copy [i]; + HoistedParameter hp_cp = host.hoisted_params_copy [i] ?? hp; FieldExpr from = new FieldExpr (hp_cp.Field, loc); from.InstanceExpression = new CompilerGeneratedThis (ec.CurrentType, loc); @@ -265,7 +311,6 @@ namespace Mono.CSharp if (new_storey != null) new_storey = Convert.ImplicitConversionRequired (ec, new_storey, host_method.MemberType, loc); - ec.CurrentBranching.CurrentUsageVector.Goto (); return true; } @@ -293,10 +338,21 @@ namespace Mono.CSharp new_storey.Emit (ec); ec.Emit (OpCodes.Ret); } + + protected override bool DoFlowAnalysis (FlowAnalysisContext fc) + { + throw new NotImplementedException (); + } + + public override Reachability MarkReachable (Reachability rc) + { + base.MarkReachable (rc); + return Reachability.CreateUnreachable (); + } } GetEnumeratorMethod (IteratorStorey host, FullNamedExpression returnType, MemberName name) - : base (host, null, returnType, Modifiers.DEBUGGER_HIDDEN, name) + : base (host, null, returnType, Modifiers.DEBUGGER_HIDDEN, name, ToplevelBlock.Flags.CompilerGenerated | ToplevelBlock.Flags.NoFlowAnalysis) { } @@ -310,7 +366,6 @@ namespace Mono.CSharp var m = new GetEnumeratorMethod (host, returnType, name); var stmt = statement ?? new GetEnumeratorStatement (host, m); m.block.AddStatement (stmt); - m.block.IsCompilerGenerated = true; return m; } } @@ -342,16 +397,20 @@ namespace Mono.CSharp ec.CurrentAnonymousMethod = iterator; iterator.EmitDispose (ec); } + + protected override bool DoFlowAnalysis (FlowAnalysisContext fc) + { + throw new NotImplementedException (); + } } public DisposeMethod (IteratorStorey host) : base (host, null, new TypeExpression (host.Compiler.BuiltinTypes.Void, host.Location), Modifiers.PUBLIC | Modifiers.DEBUGGER_HIDDEN, - new MemberName ("Dispose", host.Location)) + new MemberName ("Dispose", host.Location), ToplevelBlock.Flags.CompilerGenerated | ToplevelBlock.Flags.NoFlowAnalysis) { host.Members.Add (this); Block.AddStatement (new DisposeMethodStatement (host.Iterator)); - Block.IsCompilerGenerated = true; } } @@ -431,6 +490,13 @@ namespace Mono.CSharp get { return hoisted_params; } } + protected override Constructor DefineDefaultConstructor (bool is_static) + { + var ctor = base.DefineDefaultConstructor (is_static); + ctor.ModFlags |= Modifiers.DEBUGGER_HIDDEN; + return ctor; + } + protected override TypeSpec[] ResolveBaseTypes (out FullNamedExpression base_class) { var mtype = Iterator.OriginalIteratorType; @@ -469,17 +535,26 @@ namespace Mono.CSharp current_field = AddCompilerGeneratedField ("$current", iterator_type_expr); disposing_field = AddCompilerGeneratedField ("$disposing", new TypeExpression (Compiler.BuiltinTypes.Bool, Location)); - if (hoisted_params != null) { + if (Iterator.IsEnumerable && hoisted_params != null) { // // Iterators are independent, each GetEnumerator call has to // create same enumerator therefore we have to keep original values // around for re-initialization // - // TODO: Do it for assigned/modified parameters only - // hoisted_params_copy = new List (hoisted_params.Count); foreach (HoistedParameter hp in hoisted_params) { - hoisted_params_copy.Add (new HoistedParameter (hp, "<$>" + hp.Field.Name)); + + // + // Don't create field copy for unmodified captured parameters + // + HoistedParameter hp_copy; + if (hp.IsAssigned) { + hp_copy = new HoistedParameter (hp, "<$>" + hp.Field.Name); + } else { + hp_copy = null; + } + + hoisted_params_copy.Add (hp_copy); } } @@ -530,9 +605,8 @@ namespace Mono.CSharp var name = new MemberName ("Current", null, explicit_iface, Location); - ToplevelBlock get_block = new ToplevelBlock (Compiler, Location) { - IsCompilerGenerated = true - }; + ToplevelBlock get_block = new ToplevelBlock (Compiler, ParametersCompiled.EmptyReadOnlyParameters, Location, + Block.Flags.CompilerGenerated | Block.Flags.NoFlowAnalysis); get_block.AddStatement (new Return (new DynamicFieldExpr (CurrentField, Location), Location)); Property current = new Property (this, type, Modifiers.DEBUGGER_HIDDEN | Modifiers.COMPILER_GENERATED, name, null); @@ -551,9 +625,8 @@ namespace Mono.CSharp ParametersCompiled.EmptyReadOnlyParameters, null); Members.Add (reset); - reset.Block = new ToplevelBlock (Compiler, Location) { - IsCompilerGenerated = true - }; + reset.Block = new ToplevelBlock (Compiler, reset.ParameterInfo, Location, + Block.Flags.CompilerGenerated | Block.Flags.NoFlowAnalysis); TypeSpec ex_type = Module.PredefinedTypes.NotSupportedException.Resolve (); if (ex_type == null) @@ -565,7 +638,8 @@ namespace Mono.CSharp protected override void EmitHoistedParameters (EmitContext ec, List hoisted) { base.EmitHoistedParameters (ec, hoisted); - base.EmitHoistedParameters (ec, hoisted_params_copy); + if (hoisted_params_copy != null) + base.EmitHoistedParameters (ec, hoisted_params_copy); } } @@ -573,12 +647,13 @@ namespace Mono.CSharp { readonly StateMachineInitializer expr; - public StateMachineMethod (StateMachine host, StateMachineInitializer expr, FullNamedExpression returnType, Modifiers mod, MemberName name) + public StateMachineMethod (StateMachine host, StateMachineInitializer expr, FullNamedExpression returnType, + Modifiers mod, MemberName name, ToplevelBlock.Flags blockFlags) : base (host, returnType, mod | Modifiers.COMPILER_GENERATED, name, ParametersCompiled.EmptyReadOnlyParameters, null) { this.expr = expr; - Block = new ToplevelBlock (host.Compiler, ParametersCompiled.EmptyReadOnlyParameters, Location.Null); + Block = new ToplevelBlock (host.Compiler, ParametersCompiled.EmptyReadOnlyParameters, Location.Null, blockFlags); } public override EmitContext CreateEmitContext (ILGenerator ig, SourceMethodBuilder sourceMethod) @@ -625,6 +700,21 @@ namespace Mono.CSharp // Don't create sequence point DoEmit (ec); } + + protected override bool DoFlowAnalysis (FlowAnalysisContext fc) + { + return state_machine.ReturnType.Kind != MemberKind.Void; + } + + public override Reachability MarkReachable (Reachability rc) + { + base.MarkReachable (rc); + + if (state_machine.ReturnType.Kind != MemberKind.Void) + rc = Reachability.CreateUnreachable (); + + return rc; + } } public readonly TypeDefinition Host; @@ -634,7 +724,6 @@ namespace Mono.CSharp // The state as we generate the machine // Label move_next_ok; - Label iterator_body_end; protected Label move_next_error; LocalBuilder skip_finally; protected LocalBuilder current_pc; @@ -648,11 +737,7 @@ namespace Mono.CSharp #region Properties - public Label BodyEnd { - get { - return iterator_body_end; - } - } + public Label BodyEnd { get; set; } public LocalBuilder CurrentPC { @@ -689,34 +774,33 @@ namespace Mono.CSharp throw new NotSupportedException ("ET"); } - protected virtual BlockContext CreateBlockContext (ResolveContext rc) + protected virtual BlockContext CreateBlockContext (BlockContext bc) { - var ctx = new BlockContext (rc, block, ((BlockContext) rc).ReturnType); + var ctx = new BlockContext (bc, block, bc.ReturnType); ctx.CurrentAnonymousMethod = this; + + ctx.AssignmentInfoOffset = bc.AssignmentInfoOffset; + ctx.EnclosingLoop = bc.EnclosingLoop; + ctx.EnclosingLoopOrSwitch = bc.EnclosingLoopOrSwitch; + ctx.Switch = bc.Switch; + return ctx; } - protected override Expression DoResolve (ResolveContext ec) + protected override Expression DoResolve (ResolveContext rc) { - var ctx = CreateBlockContext (ec); + var bc = (BlockContext) rc; + var ctx = CreateBlockContext (bc); Block.Resolve (ctx); - // - // Explicit return is required for Task state machine - // - var task_storey = storey as AsyncTaskStorey; - if (task_storey == null || (task_storey.ReturnType != null && !task_storey.ReturnType.IsGenericTask)) - ctx.CurrentBranching.CurrentUsageVector.Goto (); - - ctx.EndFlowBranching (); - - if (!ec.IsInProbingMode) { - var move_next = new StateMachineMethod (storey, this, new TypeExpression (ReturnType, loc), Modifiers.PUBLIC, new MemberName ("MoveNext", loc)); + if (!rc.IsInProbingMode) { + var move_next = new StateMachineMethod (storey, this, new TypeExpression (ReturnType, loc), Modifiers.PUBLIC, new MemberName ("MoveNext", loc), 0); move_next.Block.AddStatement (new MoveNextBodyStatement (this)); storey.AddEntryMethod (move_next); } + bc.AssignmentInfoOffset = ctx.AssignmentInfoOffset; eclass = ExprClass.Value; return this; } @@ -741,11 +825,11 @@ namespace Mono.CSharp // We only care if the PC is zero (start executing) or non-zero (don't do anything) ec.Emit (OpCodes.Brtrue, move_next_error); - iterator_body_end = ec.DefineLabel (); + BodyEnd = ec.DefineLabel (); block.EmitEmbedded (ec); - ec.MarkLabel (iterator_body_end); + ec.MarkLabel (BodyEnd); EmitMoveNextEpilogue (ec); @@ -804,11 +888,11 @@ namespace Mono.CSharp ec.MarkLabel (labels[0]); - iterator_body_end = ec.DefineLabel (); + BodyEnd = ec.DefineLabel (); block.EmitEmbedded (ec); - ec.MarkLabel (iterator_body_end); + ec.MarkLabel (BodyEnd); if (async_init != null) { var catch_value = LocalVariable.CreateCompilerGenerated (ec.Module.Compiler.BuiltinTypes.Exception, block, Location); @@ -919,6 +1003,11 @@ namespace Mono.CSharp throw new NotSupportedException (); } + protected override bool DoFlowAnalysis (FlowAnalysisContext fc) + { + throw new NotSupportedException (); + } + protected override void DoEmit (EmitContext ec) { // @@ -968,8 +1057,8 @@ namespace Mono.CSharp Modifiers.COMPILER_GENERATED, new MemberName (CompilerGeneratedContainer.MakeName (null, null, "Finally", finally_hosts_counter++), loc), ParametersCompiled.EmptyReadOnlyParameters, null); - method.Block = new ToplevelBlock (method.Compiler, method.ParameterInfo, loc); - method.Block.IsCompilerGenerated = true; + method.Block = new ToplevelBlock (method.Compiler, method.ParameterInfo, loc, + ToplevelBlock.Flags.CompilerGenerated | ToplevelBlock.Flags.NoFlowAnalysis); method.Block.AddStatement (new TryFinallyBlockProxyStatement (this, block)); // Cannot it add to storey because it'd be emitted before nested @@ -1080,13 +1169,6 @@ namespace Mono.CSharp ec.MarkLabel (resume_point); } - protected override BlockContext CreateBlockContext (ResolveContext rc) - { - var bc = base.CreateBlockContext (rc); - bc.StartFlowBranching (this, rc.CurrentBranching); - return bc; - } - public static void CreateIterator (IMethodData method, TypeDefinition parent, Modifiers modifiers) { bool is_enumerable; @@ -1101,7 +1183,7 @@ namespace Mono.CSharp "The body of `{0}' cannot be an iterator block " + "because `{1}' is not an iterator interface type", method.GetSignatureForError (), - TypeManager.CSharpName (ret)); + ret.GetSignatureForError ()); return; } diff --git a/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/lambda.cs b/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/lambda.cs index d972450fc..7868c6a2c 100644 --- a/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/lambda.cs +++ b/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/lambda.cs @@ -65,7 +65,7 @@ namespace Mono.CSharp { AParametersCollection d_params = Delegate.GetParameters (delegateType); if (HasExplicitParameters) { - if (!VerifyExplicitParameters (ec, delegateType, d_params)) + if (!VerifyExplicitParameters (ec, tic, delegateType, d_params)) return null; return Parameters; @@ -75,7 +75,7 @@ namespace Mono.CSharp { // If L has an implicitly typed parameter list we make implicit parameters explicit // Set each parameter of L is given the type of the corresponding parameter in D // - if (!VerifyParameterCompatibility (ec, delegateType, d_params, ec.IsInProbingMode)) + if (!VerifyParameterCompatibility (ec, tic, delegateType, d_params, ec.IsInProbingMode)) return null; TypeSpec [] ptypes = new TypeSpec [Parameters.Count]; @@ -182,7 +182,7 @@ namespace Mono.CSharp { ExpressionStatement statement; public ContextualReturn (Expression expr) - : base (expr, expr.Location) + : base (expr, expr.StartLocation) { } diff --git a/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/linq.cs b/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/linq.cs index 1c93d6046..11f01009d 100644 --- a/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/linq.cs +++ b/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/linq.cs @@ -135,7 +135,7 @@ namespace Mono.CSharp.Linq if (!Convert.ImplicitConversionExists (rc, a.Expr, source_type)) { rc.Report.Error (1936, loc, "An implementation of `{0}' query expression pattern for source type `{1}' could not be found", - best.Name, TypeManager.CSharpName (a.Type)); + best.Name, a.Type.GetSignatureForError ()); return true; } } @@ -836,9 +836,8 @@ namespace Mono.CSharp.Linq } public QueryBlock (Block parent, Location start) - : base (parent, ParametersCompiled.EmptyReadOnlyParameters, start) + : base (parent, ParametersCompiled.EmptyReadOnlyParameters, start, Flags.CompilerGenerated) { - flags |= Flags.CompilerGenerated; } public void AddRangeVariable (RangeVariable variable) diff --git a/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/literal.cs b/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/literal.cs index bdbd57a4f..1af2d0c9e 100644 --- a/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/literal.cs +++ b/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/literal.cs @@ -61,7 +61,7 @@ namespace Mono.CSharp if (TypeSpec.IsValueType (t)) { ec.Report.Error(37, loc, "Cannot convert null to `{0}' because it is a value type", - TypeManager.CSharpName(t)); + t.GetSignatureForError ()); return; } diff --git a/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/location.cs b/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/location.cs index e3cbf6dd1..a27ebf819 100644 --- a/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/location.cs +++ b/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/location.cs @@ -222,7 +222,7 @@ namespace Mono.CSharp // static public void Initialize (List files) { -#if NET_4_0 || MONODROID +#if NET_4_0 || MOBILE_DYNAMIC source_list.AddRange (files); #else source_list.AddRange (files.ToArray ()); @@ -414,8 +414,30 @@ if (checkpoints.Length <= CheckpointIndex) throw new Exception (String.Format (" Documentation, InactiveCode } + + public bool Suppress { + get; + set; + } + + public class SpecialVisitor + { + public virtual void Visit (Comment comment) + { + } + public virtual void Visit (NewLineToken newLineToken) + { + } + public virtual void Visit (PreProcessorDirective preProcessorDirective) + { + } + } + public abstract class SpecialBase + { + public abstract void Accept (SpecialVisitor visitor); + } - public class Comment + public class Comment : SpecialBase { public readonly CommentType CommentType; public readonly bool StartsLine; @@ -440,9 +462,64 @@ if (checkpoints.Length <= CheckpointIndex) throw new Exception (String.Format (" { return string.Format ("[Comment: CommentType={0}, Line={1}, Col={2}, EndLine={3}, EndCol={4}, Content={5}]", CommentType, Line, Col, EndLine, EndCol, Content); } + + public override void Accept (SpecialVisitor visitor) + { + visitor.Visit (this); + } } - - public class PreProcessorDirective + + public class NewLineToken : SpecialBase + { + public readonly int Line; + public readonly int Col; + public readonly NewLine NewLine; + + public NewLineToken (int line, int col, NewLine newLine) + { + this.Line = line; + this.Col = col; + this.NewLine = newLine; + } + + public override void Accept (SpecialVisitor visitor) + { + visitor.Visit (this); + } + } + + public class PragmaPreProcessorDirective : PreProcessorDirective + { + public bool Disalbe { get; set; } + + public int WarningColumn { + get; + set; + } + + public int DisableRestoreColumn { + get; + set; + } + + public List Codes = new List (); + + public PragmaPreProcessorDirective (int line, int col, int endLine, int endCol, Tokenizer.PreprocessorDirective cmd, string arg) : base (line, col, endLine, endCol, cmd, arg) + { + } + } + + public class LineProcessorDirective : PreProcessorDirective + { + public int LineNumber { get; set; } + public string FileName { get; set; } + + public LineProcessorDirective (int line, int col, int endLine, int endCol, Tokenizer.PreprocessorDirective cmd, string arg) : base (line, col, endLine, endCol, cmd, arg) + { + } + } + + public class PreProcessorDirective : SpecialBase { public readonly int Line; public readonly int Col; @@ -464,13 +541,18 @@ if (checkpoints.Length <= CheckpointIndex) throw new Exception (String.Format (" this.Arg = arg; } + public override void Accept (SpecialVisitor visitor) + { + visitor.Visit (this); + } + public override string ToString () { return string.Format ("[PreProcessorDirective: Line={0}, Col={1}, EndLine={2}, EndCol={3}, Cmd={4}, Arg={5}]", Line, Col, EndLine, EndCol, Cmd, Arg); } } - public readonly List Specials = new List (); + public readonly List Specials = new List (); CommentType curComment; bool startsLine; @@ -480,6 +562,8 @@ if (checkpoints.Length <= CheckpointIndex) throw new Exception (String.Format (" [Conditional ("FULL_AST")] public void StartComment (CommentType type, bool startsLine, int startLine, int startCol) { + if (Suppress) + return; inComment = true; curComment = type; this.startsLine = startsLine; @@ -491,6 +575,8 @@ if (checkpoints.Length <= CheckpointIndex) throw new Exception (String.Format (" [Conditional ("FULL_AST")] public void PushCommentChar (int ch) { + if (Suppress) + return; if (ch < 0) return; contentBuilder.Append ((char)ch); @@ -498,6 +584,8 @@ if (checkpoints.Length <= CheckpointIndex) throw new Exception (String.Format (" [Conditional ("FULL_AST")] public void PushCommentString (string str) { + if (Suppress) + return; contentBuilder.Append (str); } @@ -505,18 +593,79 @@ if (checkpoints.Length <= CheckpointIndex) throw new Exception (String.Format (" [Conditional ("FULL_AST")] public void EndComment (int endLine, int endColumn) { + if (Suppress) + return; if (!inComment) return; inComment = false; + // Ignore empty comments + if (startLine == endLine && startCol == endColumn) + return; Specials.Add (new Comment (curComment, startsLine, startLine, startCol, endLine, endColumn, contentBuilder.ToString ())); } [Conditional ("FULL_AST")] public void AddPreProcessorDirective (int startLine, int startCol, int endLine, int endColumn, Tokenizer.PreprocessorDirective cmd, string arg) { + if (Suppress) + return; if (inComment) EndComment (startLine, startCol); - Specials.Add (new PreProcessorDirective (startLine, startCol, endLine, endColumn, cmd, arg)); + switch (cmd) { + case Tokenizer.PreprocessorDirective.Pragma: + Specials.Add (new PragmaPreProcessorDirective (startLine, startCol, endLine, endColumn, cmd, arg)); + break; + case Tokenizer.PreprocessorDirective.Line: + Specials.Add (new LineProcessorDirective (startLine, startCol, endLine, endColumn, cmd, arg)); + break; + default: + Specials.Add (new PreProcessorDirective (startLine, startCol, endLine, endColumn, cmd, arg)); + break; + } + } + + #if FULL_AST + public PragmaPreProcessorDirective SetPragmaDisable(bool disable) + { + if (Suppress) + return null; + var pragmaDirective = Specials [Specials.Count - 1] as PragmaPreProcessorDirective; + if (pragmaDirective == null) + return null; + pragmaDirective.Disalbe = disable; + return pragmaDirective; + } + #endif + + public PragmaPreProcessorDirective GetPragmaPreProcessorDirective() + { + if (Suppress) + return null; + return Specials [Specials.Count - 1] as PragmaPreProcessorDirective; + } + + + public LineProcessorDirective GetCurrentLineProcessorDirective() + { + if (Suppress) + return null; + return Specials [Specials.Count - 1] as LineProcessorDirective; + } + + public enum NewLine { Unix, Windows } + + int lastNewLine = -1; + int lastNewCol = -1; + [Conditional ("FULL_AST")] + public void AddNewLine (int line, int col, NewLine newLine) + { + if (Suppress) + return; + if (line == lastNewLine && col == lastNewCol) + return; + lastNewLine = line; + lastNewCol = col; + Specials.Add (new NewLineToken (line, col, newLine)); } public void SkipIf () @@ -543,6 +692,31 @@ if (checkpoints.Length <= CheckpointIndex) throw new Exception (String.Format (" { Modifiers = mods; locations = locs != null ? new List (locs) : null; +/* + public readonly IList> Modifiers; + List locations; + + public MemberLocations (IList> mods) + { + Modifiers = mods; + } + + public MemberLocations (IList> mods, Location loc) + : this (mods) + { + AddLocations (loc); + } + + public MemberLocations (IList> mods, Location[] locs) + : this (mods) + { + AddLocations (locs); + } + + public MemberLocations (IList> mods, List locs) + : this (mods) + { + locations = locs;*/ } #region Properties @@ -561,6 +735,15 @@ if (checkpoints.Length <= CheckpointIndex) throw new Exception (String.Format (" #endregion + public void AddLocations (Location loc) + { + if (locations == null) { + locations = new List (); + } + + locations.Add (loc); + } + public void AddLocations (params Location[] additional) { @@ -573,7 +756,7 @@ if (checkpoints.Length <= CheckpointIndex) throw new Exception (String.Format (" if (additional == null) return; if (locations == null) { - locations = new List(additional); + locations = new List (additional); } else { locations.AddRange (additional); } @@ -585,7 +768,7 @@ if (checkpoints.Length <= CheckpointIndex) throw new Exception (String.Format (" private set; } - Dictionary> simple_locs = new Dictionary> (ReferenceEquality.Default); + Dictionary> simple_locs = new Dictionary> (ReferenceEquality.Default); Dictionary member_locs = new Dictionary (ReferenceEquality.Default); [Conditional ("FULL_AST")] @@ -599,7 +782,24 @@ if (checkpoints.Length <= CheckpointIndex) throw new Exception (String.Format (" { if (element == null || locations == null) return; - simple_locs.Add (element, new List (locations)); + List found; + if (!simple_locs.TryGetValue (element, out found)) { + simple_locs.Add (element, new List (locations)); + return; + } + found.AddRange(locations); + } + + [Conditional ("FULL_AST")] + public void InsertLocation (object element, int index, Location location) + { + List found; + if (!simple_locs.TryGetValue (element, out found)) { + found = new List (); + simple_locs.Add (element, found); + } + + found.Insert (index, location); } [Conditional ("FULL_AST")] @@ -627,6 +827,7 @@ if (checkpoints.Length <= CheckpointIndex) throw new Exception (String.Format (" } member_locs.Add (member, new MemberLocations (modLocations, locations)); } + [Conditional ("FULL_AST")] public void AddMember (MemberCore member, IList> modLocations, IEnumerable locations) { @@ -643,26 +844,6 @@ if (checkpoints.Length <= CheckpointIndex) throw new Exception (String.Format (" member_locs.Add (member, new MemberLocations (modLocations, locations)); } - [Conditional ("FULL_AST")] - public void AppendTo (object existing, params Location[] locations) - { - AppendTo (existing, (IEnumerable)locations); - - } - - [Conditional ("FULL_AST")] - public void AppendTo (object existing, IEnumerable locations) - { - if (existing == null) - return; - List locs; - if (simple_locs.TryGetValue (existing, out locs)) { - simple_locs [existing].AddRange (locations); - return; - } - AddLocation (existing, locations); - } - [Conditional ("FULL_AST")] public void AppendToMember (MemberCore existing, params Location[] locations) { @@ -687,7 +868,7 @@ if (checkpoints.Length <= CheckpointIndex) throw new Exception (String.Format (" { if (element == null) return null; - List found; + List found; simple_locs.TryGetValue (element, out found); return found; } diff --git a/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/membercache.cs b/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/membercache.cs index 9ff316886..82acb67b1 100644 --- a/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/membercache.cs +++ b/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/membercache.cs @@ -226,7 +226,7 @@ namespace Mono.CSharp { continue; if (list is MemberSpec[]) { - list = new List () { list [0] }; + list = new List { list [0] }; member_hash[entry.Key] = list; } @@ -240,6 +240,8 @@ namespace Mono.CSharp { // contain all base interface members, so the Lookup code // can use simple inheritance rules. // + // Does not work recursively because of generic interfaces + // public void AddInterface (TypeSpec iface) { var cache = iface.MemberCache; @@ -258,6 +260,13 @@ namespace Mono.CSharp { } foreach (var ce in entry.Value) { + // + // When two or more different base interfaces implemenent common + // interface + // + // I : IA, IFoo + // IA : IFoo + // if (list.Contains (ce)) continue; @@ -265,12 +274,6 @@ namespace Mono.CSharp { member_hash[entry.Key] = list; } } - - // Add also all base interfaces - if (iface.Interfaces != null) { - foreach (var base_iface in iface.Interfaces) - AddInterface (base_iface); - } } public void AddMember (InterfaceMemberBase imb, string exlicitName, MemberSpec ms) @@ -296,13 +299,14 @@ namespace Mono.CSharp { if (member.Kind == MemberKind.Operator) { var dt = member.DeclaringType; + // // Some core types have user operators but they cannot be used like normal // user operators as they are predefined and therefore having different // rules (e.g. binary operators) by not setting the flag we hide them for // user conversions // - if (!BuiltinTypeSpec.IsPrimitiveType (dt)) { + if (!BuiltinTypeSpec.IsPrimitiveType (dt) || dt.BuiltinType == BuiltinTypeSpec.Type.Char) { switch (dt.BuiltinType) { case BuiltinTypeSpec.Type.String: case BuiltinTypeSpec.Type.Delegate: @@ -331,7 +335,7 @@ namespace Mono.CSharp { member_hash[name] = list; } else { if (list.Count == 1) { - list = new List () { list[0] }; + list = new List { list[0] }; member_hash[name] = list; } @@ -386,7 +390,7 @@ namespace Mono.CSharp { } if (existing.Count == 1) { - existing = new List () { existing[0], member }; + existing = new List { existing[0], member }; return true; } @@ -460,6 +464,7 @@ namespace Mono.CSharp { IList applicable; TypeSpec best_match = null; do { +#if !FULL_AOT_RUNTIME // TODO: Don't know how to handle this yet // When resolving base type of nested type, parent type must have // base type resolved to scan full hierarchy correctly @@ -468,6 +473,7 @@ namespace Mono.CSharp { var tc = container.MemberDefinition as TypeContainer; if (tc != null) tc.DefineContainer (); +#endif if (container.MemberCacheTypes.member_hash.TryGetValue (name, out applicable)) { for (int i = applicable.Count - 1; i >= 0; i--) { @@ -498,7 +504,7 @@ namespace Mono.CSharp { // // Looks for extension methods with defined name and extension type // - public List FindExtensionMethods (IMemberContext invocationContext, TypeSpec extensionType, string name, int arity) + public List FindExtensionMethods (IMemberContext invocationContext, string name, int arity) { IList entries; if (!member_hash.TryGetValue (name, out entries)) @@ -560,11 +566,7 @@ namespace Mono.CSharp { for (int i = 0; i < applicable.Count; ++i) { var entry = applicable [i]; - if ((entry.Modifiers & Modifiers.PRIVATE) != 0) - continue; - - if ((entry.Modifiers & Modifiers.AccessibilityMask) == Modifiers.INTERNAL && - !entry.DeclaringType.MemberDefinition.IsInternalAsPublic (member.Module.DeclaringAssembly)) + if ((entry.Modifiers & Modifiers.PUBLIC) == 0 && !entry.IsAccessible (member)) continue; // @@ -695,6 +697,14 @@ namespace Mono.CSharp { if ((name_entry.Modifiers & Modifiers.STATIC) != 0) continue; + // + // Ignore user private fields for definite assignment. This is sort of unexpected but + // rationale is to have consistent results when using reference assemblies which don't + // include any private fields and full assemblies + // + if ((name_entry.Modifiers & (Modifiers.PRIVATE | Modifiers.BACKING_FIELD)) == Modifiers.PRIVATE) + continue; + // // Fixed size buffers are not subject to definite assignment checking // @@ -791,13 +801,14 @@ namespace Mono.CSharp { while (true) { foreach (var entry in abstract_type.MemberCache.member_hash) { foreach (var name_entry in entry.Value) { - if ((name_entry.Modifiers & (Modifiers.ABSTRACT | Modifiers.OVERRIDE)) != Modifiers.ABSTRACT) + if ((name_entry.Modifiers & Modifiers.ABSTRACT) == 0) continue; - if (name_entry.Kind != MemberKind.Method) + var ms = name_entry as MethodSpec; + if (ms == null) continue; - abstract_methods.Add ((MethodSpec) name_entry); + abstract_methods.Add (ms); } } @@ -905,7 +916,7 @@ namespace Mono.CSharp { public static IList GetUserOperator (TypeSpec container, Operator.OpType op, bool declaredOnly) { IList found = null; - + bool shared_list = true; IList applicable; do { var mc = container.MemberCache; @@ -935,10 +946,13 @@ namespace Mono.CSharp { found = new List (); found.Add (applicable[i]); } else { - var prev = found as List; - if (prev == null) { + List prev; + if (shared_list) { + shared_list = false; prev = new List (found.Count + 1); prev.AddRange (found); + } else { + prev = (List) found; } prev.Add (applicable[i]); @@ -947,12 +961,16 @@ namespace Mono.CSharp { } else { if (found == null) { found = applicable; + shared_list = true; } else { - var merged = found as List; - if (merged == null) { + List merged; + if (shared_list) { + shared_list = false; merged = new List (found.Count + applicable.Count); merged.AddRange (found); found = merged; + } else { + merged = (List) found; } merged.AddRange (applicable); @@ -1434,9 +1452,12 @@ namespace Mono.CSharp { "A partial method declaration and partial method implementation must be both `static' or neither"); } - Report.SymbolRelatedToPreviousError (ce); - Report.Error (764, member.Location, - "A partial method declaration and partial method implementation must be both `unsafe' or neither"); + if ((method_a.ModFlags & Modifiers.UNSAFE) != (method_b.ModFlags & Modifiers.UNSAFE)) { + Report.SymbolRelatedToPreviousError (ce); + Report.Error (764, member.Location, + "A partial method declaration and partial method implementation must be both `unsafe' or neither"); + } + return false; } diff --git a/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/method.cs b/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/method.cs index a1560a508..c74e7f3f3 100644 --- a/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/method.cs +++ b/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/method.cs @@ -47,7 +47,7 @@ namespace Mono.CSharp { protected ToplevelBlock block; protected MethodSpec spec; - public MethodCore (TypeDefinition parent, FullNamedExpression type, Modifiers mod, Modifiers allowed_mod, + protected MethodCore (TypeDefinition parent, FullNamedExpression type, Modifiers mod, Modifiers allowed_mod, MemberName name, Attributes attrs, ParametersCompiled parameters) : base (parent, type, mod, allowed_mod, name, attrs) { @@ -188,7 +188,7 @@ namespace Mono.CSharp { } } - public interface IGenericMethodDefinition : IMemberDefinition + public interface IGenericMethodDefinition : IMethodDefinition { TypeParameterSpec[] TypeParameters { get; } int TypeParametersCount { get; } @@ -198,18 +198,19 @@ namespace Mono.CSharp { public sealed class MethodSpec : MemberSpec, IParametersMember { - MethodBase metaInfo, inflatedMetaInfo; + MethodBase inflatedMetaInfo; AParametersCollection parameters; TypeSpec returnType; TypeSpec[] targs; TypeParameterSpec[] constraints; - public MethodSpec (MemberKind kind, TypeSpec declaringType, IMemberDefinition details, TypeSpec returnType, - MethodBase info, AParametersCollection parameters, Modifiers modifiers) + public static readonly MethodSpec Excluded = new MethodSpec (MemberKind.Method, InternalType.FakeInternalType, null, null, ParametersCompiled.EmptyReadOnlyParameters, 0); + + public MethodSpec (MemberKind kind, TypeSpec declaringType, IMethodDefinition details, TypeSpec returnType, + AParametersCollection parameters, Modifiers modifiers) : base (kind, declaringType, details, modifiers) { - this.metaInfo = info; this.parameters = parameters; this.returnType = returnType; } @@ -237,12 +238,24 @@ namespace Mono.CSharp { } } + public new IMethodDefinition MemberDefinition { + get { + return (IMethodDefinition) definition; + } + } + public IGenericMethodDefinition GenericDefinition { get { return (IGenericMethodDefinition) definition; } } + public bool IsAsync { + get { + return (Modifiers & Modifiers.ASYNC) != 0; + } + } + public bool IsExtensionMethod { get { return IsStatic && parameters.HasExtensionMethodType; @@ -316,21 +329,21 @@ namespace Mono.CSharp { if (DeclaringType.IsTypeBuilder) { if (IsConstructor) - inflatedMetaInfo = TypeBuilder.GetConstructor (dt_meta, (ConstructorInfo) metaInfo); + inflatedMetaInfo = TypeBuilder.GetConstructor (dt_meta, (ConstructorInfo) MemberDefinition.Metadata); else - inflatedMetaInfo = TypeBuilder.GetMethod (dt_meta, (MethodInfo) metaInfo); + inflatedMetaInfo = TypeBuilder.GetMethod (dt_meta, (MethodInfo) MemberDefinition.Metadata); } else { #if STATIC // it should not be reached throw new NotImplementedException (); #else - inflatedMetaInfo = MethodInfo.GetMethodFromHandle (metaInfo.MethodHandle, dt_meta.TypeHandle); + inflatedMetaInfo = MethodInfo.GetMethodFromHandle (MemberDefinition.Metadata.MethodHandle, dt_meta.TypeHandle); #endif } state &= ~StateFlags.PendingMetaInflate; } else { - inflatedMetaInfo = metaInfo; + inflatedMetaInfo = MemberDefinition.Metadata; } } @@ -482,29 +495,29 @@ namespace Mono.CSharp { return ms; } - public override List ResolveMissingDependencies () + public override List ResolveMissingDependencies (MemberSpec caller) { - var missing = returnType.ResolveMissingDependencies (); + var missing = returnType.ResolveMissingDependencies (this); foreach (var pt in parameters.Types) { - var m = pt.GetMissingDependencies (); + var m = pt.GetMissingDependencies (this); if (m == null) continue; if (missing == null) - missing = new List (); + missing = new List (); missing.AddRange (m); } if (Arity > 0) { foreach (var tp in GenericDefinition.TypeParameters) { - var m = tp.GetMissingDependencies (); + var m = tp.GetMissingDependencies (this); if (m == null) continue; if (missing == null) - missing = new List (); + missing = new List (); missing.AddRange (m); } @@ -512,19 +525,10 @@ namespace Mono.CSharp { return missing; } - - public void SetMetaInfo (MethodInfo info) - { - if (this.metaInfo != null) - throw new InternalErrorException ("MetaInfo reset"); - - this.metaInfo = info; - } } - public abstract class MethodOrOperator : MethodCore, IMethodData + public abstract class MethodOrOperator : MethodCore, IMethodData, IMethodDefinition { - public MethodBuilder MethodBuilder; ReturnParameter return_attributes; SecurityType declarative_security; protected MethodData MethodData; @@ -559,6 +563,12 @@ namespace Mono.CSharp { if ((ModFlags & extern_static) != extern_static) { Report.Error (601, a.Location, "The DllImport attribute must be specified on a method marked `static' and `extern'"); } + + if (MemberName.IsGeneric || Parent.IsGenericOrParentIsGeneric) { + Report.Error (7042, a.Location, + "The DllImport attribute cannot be applied to a method that is generic or contained in a generic type"); + } + is_external_implementation = true; } @@ -577,6 +587,19 @@ namespace Mono.CSharp { } } + MethodBase IMethodDefinition.Metadata { + get { + return MethodData.MethodBuilder; + } + } + + // TODO: Remove and use MethodData abstraction + public MethodBuilder MethodBuilder { + get { + return MethodData.MethodBuilder; + } + } + protected override bool CheckForDuplications () { return Parent.MemberCache.CheckExistingMembersOverloads (this, parameters); @@ -603,41 +626,34 @@ namespace Mono.CSharp { else kind = MemberKind.Method; + string explicit_name; + if (IsPartialDefinition) { caching_flags &= ~Flags.Excluded_Undetected; caching_flags |= Flags.Excluded; // Add to member cache only when a partial method implementation has not been found yet - if ((caching_flags & Flags.PartialDefinitionExists) == 0) { -// MethodBase mb = new PartialMethodDefinitionInfo (this); + if ((caching_flags & Flags.PartialDefinitionExists) != 0) + return true; - spec = new MethodSpec (kind, Parent.Definition, this, ReturnType, null, parameters, ModFlags); - if (MemberName.Arity > 0) { - spec.IsGeneric = true; + if (IsExplicitImpl) + return true; - // TODO: Have to move DefineMethod after Define (ideally to Emit) - throw new NotImplementedException ("Generic partial methods"); - } + explicit_name = null; + } else { + MethodData = new MethodData (this, ModFlags, flags, this, base_method); - Parent.MemberCache.AddMember (spec); - } + if (!MethodData.Define (Parent.PartialContainer, GetFullName (MemberName))) + return false; - return true; + explicit_name = MethodData.MetadataName; } - MethodData = new MethodData ( - this, ModFlags, flags, this, MethodBuilder, base_method); - - if (!MethodData.Define (Parent.PartialContainer, GetFullName (MemberName))) - return false; - - MethodBuilder = MethodData.MethodBuilder; - - spec = new MethodSpec (kind, Parent.Definition, this, ReturnType, MethodBuilder, parameters, ModFlags); + spec = new MethodSpec (kind, Parent.Definition, this, ReturnType, parameters, ModFlags); if (MemberName.Arity > 0) spec.IsGeneric = true; - - Parent.MemberCache.AddMember (this, MethodBuilder.Name, spec); + + Parent.MemberCache.AddMember (this, explicit_name, spec); return true; } @@ -677,6 +693,8 @@ namespace Mono.CSharp { Module.PredefinedAttributes.CompilerGenerated.EmitAttribute (MethodBuilder); if ((ModFlags & Modifiers.DEBUGGER_HIDDEN) != 0) Module.PredefinedAttributes.DebuggerHidden.EmitAttribute (MethodBuilder); + if ((ModFlags & Modifiers.DEBUGGER_STEP_THROUGH) != 0) + Module.PredefinedAttributes.DebuggerStepThrough.EmitAttribute (MethodBuilder); if (ReturnType.BuiltinType == BuiltinTypeSpec.Type.Dynamic) { return_attributes = new ReturnParameter (this, MethodBuilder, Location); @@ -707,7 +725,13 @@ namespace Mono.CSharp { if (MethodData != null) MethodData.Emit (Parent); - Block = null; + if (block != null && block.StateMachine is AsyncTaskStorey) { + var psm = Module.PredefinedAttributes.AsyncStateMachine; + psm.EmitAttribute (MethodBuilder, block.StateMachine); + } + + if ((ModFlags & Modifiers.PARTIAL) == 0) + Block = null; } protected void Error_ConditionalAttributeIsNotValid () @@ -792,9 +816,36 @@ namespace Mono.CSharp { #endregion + public virtual void PrepareEmit () + { + var mb = MethodData.DefineMethodBuilder (Parent); + + if (CurrentTypeParameters != null) { + string[] gnames = new string[CurrentTypeParameters.Count]; + for (int i = 0; i < gnames.Length; ++i) { + gnames[i] = CurrentTypeParameters[i].Name; + } + + var gen_params = MethodBuilder.DefineGenericParameters (gnames); + + for (int i = 0; i < CurrentTypeParameters.Count; ++i) { + var tp = CurrentTypeParameters[i]; + + tp.Define (gen_params[i]); + } + } + + // + // Generic method has been already defined to resolve method parameters + // correctly when they use type parameters + // + mb.SetParameters (parameters.GetMetaInfo ()); + mb.SetReturnType (ReturnType.GetMetaInfo ()); + } + public override void WriteDebugSymbol (MonoSymbolFile file) { - if (MethodData != null) + if (MethodData != null && !IsPartialDefinition) MethodData.WriteDebugSymbol (file); } } @@ -838,7 +889,7 @@ namespace Mono.CSharp { } } -#endregion + #endregion public override void Accept (StructuralVisitor visitor) { @@ -846,16 +897,10 @@ namespace Mono.CSharp { } public static Method Create (TypeDefinition parent, FullNamedExpression returnType, Modifiers mod, - MemberName name, ParametersCompiled parameters, Attributes attrs, bool hasConstraints) + MemberName name, ParametersCompiled parameters, Attributes attrs) { var m = new Method (parent, returnType, mod, name, parameters, attrs); - if (hasConstraints && ((mod & Modifiers.OVERRIDE) != 0 || m.IsExplicitImpl)) { - m.Report.Error (460, m.Location, - "`{0}': Cannot specify constraints for overrides and explicit interface implementation methods", - m.GetSignatureForError ()); - } - if ((mod & Modifiers.PARTIAL) != 0) { const Modifiers invalid_partial_mod = Modifiers.AccessibilityMask | Modifiers.ABSTRACT | Modifiers.EXTERN | Modifiers.NEW | Modifiers.OVERRIDE | Modifiers.SEALED | Modifiers.VIRTUAL; @@ -972,10 +1017,9 @@ namespace Mono.CSharp { void CreateTypeParameters () { var tparams = MemberName.TypeParameters; - string[] snames = new string[MemberName.Arity]; var parent_tparams = Parent.TypeParametersAll; - for (int i = 0; i < snames.Length; i++) { + for (int i = 0; i < MemberName.Arity; i++) { string type_argument_name = tparams[i].MemberName.Name; if (block == null) { @@ -1000,12 +1044,9 @@ namespace Mono.CSharp { tparams[i].WarningParentNameConflict (tp); } } - - snames[i] = type_argument_name; } - GenericTypeParameterBuilder[] gen_params = MethodBuilder.DefineGenericParameters (snames); - tparams.Define (gen_params, null, 0, Parent); + tparams.Create (null, 0, Parent); } protected virtual void DefineTypeParameters () @@ -1016,21 +1057,32 @@ namespace Mono.CSharp { TypeParameterSpec[] base_decl_tparams = TypeParameterSpec.EmptyTypes; TypeSpec[] base_targs = TypeSpec.EmptyTypes; if (((ModFlags & Modifiers.OVERRIDE) != 0 || IsExplicitImpl)) { - if (base_method != null) { - base_tparams = base_method.GenericDefinition.TypeParameters; - - if (base_method.DeclaringType.IsGeneric) { - base_decl_tparams = base_method.DeclaringType.MemberDefinition.TypeParameters; + MethodSpec base_override = base_method ?? MethodData.implementing; - var base_type_parent = CurrentType; - while (base_type_parent.BaseType != base_method.DeclaringType) { - base_type_parent = base_type_parent.BaseType; - } + if (base_override != null) { + base_tparams = base_override.GenericDefinition.TypeParameters; + + if (base_override.DeclaringType.IsGeneric) { + base_decl_tparams = base_override.DeclaringType.MemberDefinition.TypeParameters; - base_targs = base_type_parent.BaseType.TypeArguments; + if (base_method != null) { + var base_type_parent = CurrentType; + while (base_type_parent.BaseType != base_override.DeclaringType) { + base_type_parent = base_type_parent.BaseType; + } + + base_targs = base_type_parent.BaseType.TypeArguments; + } else { + foreach (var iface in Parent.CurrentType.Interfaces) { + if (iface == base_override.DeclaringType) { + base_targs = iface.TypeArguments; + break; + } + } + } } - if (base_method.IsGeneric) { + if (base_override.IsGeneric) { ObsoleteAttribute oa; foreach (var base_tp in base_tparams) { oa = base_tp.BaseType.GetAttributeObsolete (); @@ -1056,79 +1108,66 @@ namespace Mono.CSharp { base_targs = tparams.Types; } } - } else if (MethodData.implementing != null) { - base_tparams = MethodData.implementing.GenericDefinition.TypeParameters; - if (MethodData.implementing.DeclaringType.IsGeneric) { - base_decl_tparams = MethodData.implementing.DeclaringType.MemberDefinition.TypeParameters; - foreach (var iface in Parent.CurrentType.Interfaces) { - if (iface == MethodData.implementing.DeclaringType) { - base_targs = iface.TypeArguments; - break; - } - } - } } } for (int i = 0; i < tparams.Count; ++i) { - var tp = tparams[i]; + var tp = tparams [i]; - if (!tp.ResolveConstraints (this)) + if (base_tparams == null) { + tp.ResolveConstraints (this); continue; + } // // Copy base constraints for override/explicit methods // - if (base_tparams != null) { - var base_tparam = base_tparams[i]; - var local_tparam = tp.Type; - local_tparam.SpecialConstraint = base_tparam.SpecialConstraint; + var base_tparam = base_tparams [i]; + var local_tparam = tp.Type; + local_tparam.SpecialConstraint = base_tparam.SpecialConstraint; - var inflator = new TypeParameterInflator (this, CurrentType, base_decl_tparams, base_targs); - base_tparam.InflateConstraints (inflator, local_tparam); + var inflator = new TypeParameterInflator (this, CurrentType, base_decl_tparams, base_targs); + base_tparam.InflateConstraints (inflator, local_tparam); - // - // Check all type argument constraints for possible collision or unification - // introduced by inflating inherited constraints in this context - // - // Conflict example: - // - // class A { virtual void Foo () where U : class, T {} } - // class B : A { override void Foo {} } - // - var local_tparam_targs = local_tparam.TypeArguments; - if (local_tparam_targs != null) { - for (int ii = 0; ii < local_tparam_targs.Length; ++ii) { - var ta = local_tparam_targs [ii]; - if (!ta.IsClass && !ta.IsStruct) - continue; - - TypeSpec[] unique_tparams = null; - for (int iii = ii + 1; iii < local_tparam_targs.Length; ++iii) { - // - // Remove any identical or unified constraint types - // - var tparam_checked = local_tparam_targs[iii]; - if (TypeSpecComparer.IsEqual (ta, tparam_checked) || TypeSpec.IsBaseClass (ta, tparam_checked, false)) { - unique_tparams = new TypeSpec[local_tparam_targs.Length - 1]; - Array.Copy (local_tparam_targs, 0, unique_tparams, 0, iii); - Array.Copy (local_tparam_targs, iii + 1, unique_tparams, iii, local_tparam_targs.Length - iii - 1); - } else if (!TypeSpec.IsBaseClass (tparam_checked, ta, false)) { - Constraints.Error_ConflictingConstraints (this, local_tparam, ta, tparam_checked, Location); - } - } - - if (unique_tparams != null) { - local_tparam_targs = unique_tparams; - local_tparam.TypeArguments = local_tparam_targs; - continue; + // + // Check all type argument constraints for possible collision or unification + // introduced by inflating inherited constraints in this context + // + // Conflict example: + // + // class A { virtual void Foo () where U : class, T {} } + // class B : A { override void Foo {} } + // + var local_tparam_targs = local_tparam.TypeArguments; + if (local_tparam_targs != null) { + for (int ii = 0; ii < local_tparam_targs.Length; ++ii) { + var ta = local_tparam_targs [ii]; + if (!ta.IsClass && !ta.IsStruct) + continue; + + TypeSpec[] unique_tparams = null; + for (int iii = ii + 1; iii < local_tparam_targs.Length; ++iii) { + // + // Remove any identical or unified constraint types + // + var tparam_checked = local_tparam_targs [iii]; + if (TypeSpecComparer.IsEqual (ta, tparam_checked) || TypeSpec.IsBaseClass (ta, tparam_checked, false)) { + unique_tparams = new TypeSpec[local_tparam_targs.Length - 1]; + Array.Copy (local_tparam_targs, 0, unique_tparams, 0, iii); + Array.Copy (local_tparam_targs, iii + 1, unique_tparams, iii, local_tparam_targs.Length - iii - 1); + } else if (!TypeSpec.IsBaseClass (tparam_checked, ta, false)) { + Constraints.Error_ConflictingConstraints (this, local_tparam, ta, tparam_checked, Location); } + } - Constraints.CheckConflictingInheritedConstraint (local_tparam, ta, this, Location); + if (unique_tparams != null) { + local_tparam_targs = unique_tparams; + local_tparam.TypeArguments = local_tparam_targs; + continue; } - } - continue; + Constraints.CheckConflictingInheritedConstraint (local_tparam, ta, this, Location); + } } } @@ -1173,9 +1212,6 @@ namespace Mono.CSharp { "Introducing `Finalize' method can interfere with destructor invocation. Did you intend to declare a destructor?"); } - if (partialMethodImplementation != null && IsPartialDefinition) - MethodBuilder = partialMethodImplementation.MethodBuilder; - if (Compiler.Settings.StdLib && ReturnType.IsSpecialRuntimeType) { Error1599 (Location, ReturnType, Report); return false; @@ -1210,8 +1246,8 @@ namespace Mono.CSharp { Report.Error (1983, Location, "The return type of an async method must be void, Task, or Task"); } - block = (ToplevelBlock) block.ConvertToAsyncTask (this, Parent.PartialContainer, parameters, ReturnType, Location); - ModFlags |= Modifiers.DEBUGGER_HIDDEN; + block = (ToplevelBlock) block.ConvertToAsyncTask (this, Parent.PartialContainer, parameters, ReturnType, null, Location); + ModFlags |= Modifiers.DEBUGGER_STEP_THROUGH; } if (Compiler.Settings.WriteMetadataOnly) @@ -1274,6 +1310,22 @@ namespace Mono.CSharp { return true; } + public override void PrepareEmit () + { + if (IsPartialDefinition) { + // + // Use partial method implementation builder for partial method declaration attributes + // + if (partialMethodImplementation != null) { + MethodData = partialMethodImplementation.MethodData; + } + + return; + } + + base.PrepareEmit (); + } + // // Emits the code // @@ -1281,11 +1333,8 @@ namespace Mono.CSharp { { try { if (IsPartialDefinition) { - // - // Use partial method implementation builder for partial method declaration attributes - // - if (partialMethodImplementation != null) { - MethodBuilder = partialMethodImplementation.MethodBuilder; + if (partialMethodImplementation != null && CurrentTypeParameters != null) { + CurrentTypeParameters.CheckPartialConstraints (partialMethodImplementation); } return; @@ -1299,27 +1348,18 @@ namespace Mono.CSharp { if (CurrentTypeParameters != null) { for (int i = 0; i < CurrentTypeParameters.Count; ++i) { var tp = CurrentTypeParameters [i]; + tp.CheckGenericConstraints (false); tp.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); - throw; + } catch (Exception e) { + throw new InternalErrorException (this, e); } } @@ -1333,13 +1373,12 @@ namespace Mono.CSharp { public static void Error1599 (Location loc, TypeSpec t, Report Report) { - Report.Error (1599, loc, "Method or delegate cannot return type `{0}'", TypeManager.CSharpName (t)); + Report.Error (1599, loc, "Method or delegate cannot return type `{0}'", t.GetSignatureForError ()); } protected override bool ResolveMemberType () { if (CurrentTypeParameters != null) { - MethodBuilder = Parent.TypeBuilder.DefineMethod (GetFullName (MemberName), flags); CreateTypeParameters (); } @@ -1373,7 +1412,7 @@ namespace Mono.CSharp { Arguments argument_list; MethodSpec base_ctor; - public ConstructorInitializer (Arguments argument_list, Location loc) + protected ConstructorInitializer (Arguments argument_list, Location loc) { this.argument_list = argument_list; this.loc = loc; @@ -1432,7 +1471,7 @@ namespace Mono.CSharp { } else { // // It is legal to have "this" initializers that take no arguments - // in structs, they are just no-ops. + // in structs // // struct D { public D (int a) : this () {} // @@ -1453,9 +1492,17 @@ namespace Mono.CSharp { public override void Emit (EmitContext ec) { - // It can be null for static initializers - if (base_ctor == null) + // + // It can be null for struct initializers or System.Object + // + if (base_ctor == null) { + if (type == ec.BuiltinTypes.Object) + return; + + ec.Emit (OpCodes.Ldarg_0); + ec.Emit (OpCodes.Initobj, type); return; + } var call = new CallEmitter (); call.InstanceExpression = new CompilerGeneratedThis (type, loc); @@ -1466,6 +1513,12 @@ namespace Mono.CSharp { { Emit (ec); } + + public override void FlowAnalysis (FlowAnalysisContext fc) + { + if (argument_list != null) + argument_list.FlowAnalysis (fc); + } } public class ConstructorBaseInitializer : ConstructorInitializer { @@ -1476,8 +1529,8 @@ namespace Mono.CSharp { } class GeneratedBaseInitializer: ConstructorBaseInitializer { - public GeneratedBaseInitializer (Location loc): - base (null, loc) + public GeneratedBaseInitializer (Location loc, Arguments arguments) + : base (arguments, loc) { } } @@ -1489,7 +1542,7 @@ namespace Mono.CSharp { } } - public class Constructor : MethodCore, IMethodData + public class Constructor : MethodCore, IMethodData, IMethodDefinition { public ConstructorBuilder ConstructorBuilder; public ConstructorInitializer Initializer; @@ -1537,6 +1590,15 @@ namespace Mono.CSharp { } } + public bool IsPrimaryConstructor { get; set; } + + + MethodBase IMethodDefinition.Metadata { + get { + return ConstructorBuilder; + } + } + // // Returns true if this is a default constructor // @@ -1618,13 +1680,23 @@ namespace Mono.CSharp { if (!CheckBase ()) return false; + if (Parent.PrimaryConstructorParameters != null && !IsPrimaryConstructor) { + if (Parent.Kind == MemberKind.Struct) { + Report.Error (9009, Location, "`{0}': Structs with primary constructor cannot have explicit constructor", + GetSignatureForError ()); + } else if (Initializer == null || Initializer is ConstructorBaseInitializer) { + Report.Error (9002, Location, "`{0}': Instance constructor of type with primary constructor must specify `this' constructor initializer", + GetSignatureForError ()); + } + } + var ca = ModifiersExtensions.MethodAttr (ModFlags) | MethodAttributes.RTSpecialName | MethodAttributes.SpecialName; ConstructorBuilder = Parent.TypeBuilder.DefineConstructor ( ca, CallingConventions, parameters.GetMetaInfo ()); - spec = new MethodSpec (MemberKind.Constructor, Parent.Definition, this, Compiler.BuiltinTypes.Void, ConstructorBuilder, parameters, ModFlags); + spec = new MethodSpec (MemberKind.Constructor, Parent.Definition, this, Compiler.BuiltinTypes.Void, parameters, ModFlags); Parent.MemberCache.AddMember (spec); @@ -1689,7 +1761,7 @@ namespace Mono.CSharp { // block.AddThisVariable (bc); } else if (Parent.PartialContainer.Kind == MemberKind.Class) { - Initializer = new GeneratedBaseInitializer (Location); + Initializer = new GeneratedBaseInitializer (Location, null); } } @@ -1703,7 +1775,7 @@ namespace Mono.CSharp { } } - if (block.Resolve (null, bc, this)) { + if (block.Resolve (bc, this)) { debug_builder = Parent.CreateMethodSymbolEntry (); EmitContext ec = new EmitContext (this, ConstructorBuilder.GetILGenerator (), bc.ReturnType, debug_builder); ec.With (EmitContext.Options.ConstructorScope, true); @@ -1779,7 +1851,7 @@ namespace Mono.CSharp { var token = ConstructorBuilder.GetToken (); int t = token.Token; #if STATIC - if (token.IsPseudoToken) + if (ModuleBuilder.IsPseudoToken (t)) t = Module.Builder.ResolvePseudoToken (t); #endif @@ -1832,10 +1904,6 @@ namespace Mono.CSharp { // public class MethodData { -#if !STATIC - static FieldInfo methodbuilder_attrs_field; -#endif - public readonly IMethodData method; // @@ -1852,6 +1920,7 @@ namespace Mono.CSharp { protected TypeSpec declaring_type; protected MethodSpec parent_method; SourceMethodBuilder debug_builder; + string full_name; MethodBuilder builder; public MethodBuilder MethodBuilder { @@ -1866,6 +1935,12 @@ namespace Mono.CSharp { } } + public string MetadataName { + get { + return full_name; + } + } + public MethodData (InterfaceMemberBase member, Modifiers modifiers, MethodAttributes flags, IMethodData method) { @@ -1878,11 +1953,10 @@ namespace Mono.CSharp { public MethodData (InterfaceMemberBase member, Modifiers modifiers, MethodAttributes flags, - IMethodData method, MethodBuilder builder, + IMethodData method, MethodSpec parent_method) : this (member, modifiers, flags, method) { - this.builder = builder; this.parent_method = parent_method; } @@ -1900,13 +1974,13 @@ namespace Mono.CSharp { if (member is PropertyBase) { container.Compiler.Report.Error (550, method.Location, "`{0}' is an accessor not found in interface member `{1}{2}'", - method.GetSignatureForError (), TypeManager.CSharpName (member.InterfaceType), + method.GetSignatureForError (), member.InterfaceType.GetSignatureForError (), member.GetSignatureForError ().Substring (member.GetSignatureForError ().LastIndexOf ('.'))); } else { container.Compiler.Report.Error (539, method.Location, "`{0}.{1}' in explicit interface declaration is not a member of interface", - TypeManager.CSharpName (member.InterfaceType), member.ShortName); + member.InterfaceType.GetSignatureForError (), member.ShortName); } return false; } @@ -1914,11 +1988,11 @@ namespace Mono.CSharp { container.Compiler.Report.SymbolRelatedToPreviousError (implementing); container.Compiler.Report.Error (683, method.Location, "`{0}' explicit method implementation cannot implement `{1}' because it is an accessor", - member.GetSignatureForError (), TypeManager.CSharpSignature (implementing)); + member.GetSignatureForError (), implementing.GetSignatureForError ()); return false; } } else { - if (implementing != null) { + if (implementing != null && !optional) { if (!method.IsAccessor) { if (implementing.IsAccessor) { container.Compiler.Report.SymbolRelatedToPreviousError (implementing); @@ -2037,58 +2111,45 @@ namespace Mono.CSharp { method_full_name = implementing.MemberDefinition.Name; } - DefineMethodBuilder (container, method_full_name, method.ParameterInfo); + full_name = method_full_name; + declaring_type = container.Definition; - if (builder == null) - return false; + return true; + } -// if (container.CurrentType != null) -// declaring_type = container.CurrentType; -// else - declaring_type = container.Definition; + void DefineOverride (TypeDefinition container) + { + if (implementing == null) + return; - if (implementing != null && member.IsExplicitImpl) { - container.TypeBuilder.DefineMethodOverride (builder, (MethodInfo) implementing.GetMetaInfo ()); - } + if (!member.IsExplicitImpl) + return; - return true; + container.TypeBuilder.DefineMethodOverride (builder, (MethodInfo) implementing.GetMetaInfo ()); } - - /// - /// Create the MethodBuilder for the method - /// - void DefineMethodBuilder (TypeDefinition container, string method_name, ParametersCompiled param) + // + // Creates partial MethodBuilder for the method when has generic parameters used + // as arguments or return type + // + public MethodBuilder DefineMethodBuilder (TypeDefinition container) { - var return_type = method.ReturnType.GetMetaInfo (); - var p_types = param.GetMetaInfo (); + if (builder != null) + throw new InternalErrorException (); - if (builder == null) { - builder = container.TypeBuilder.DefineMethod ( - method_name, flags, method.CallingConventions, - return_type, p_types); - return; - } + builder = container.TypeBuilder.DefineMethod (full_name, flags, method.CallingConventions); + return builder; + } - // - // Generic method has been already defined to resolve method parameters - // correctly when they use type parameters - // - builder.SetParameters (p_types); - builder.SetReturnType (return_type); - if (builder.Attributes != flags) { -#if STATIC - builder.__SetAttributes (flags); -#else - try { - if (methodbuilder_attrs_field == null) - methodbuilder_attrs_field = typeof (MethodBuilder).GetField ("attrs", BindingFlags.NonPublic | BindingFlags.Instance); - methodbuilder_attrs_field.SetValue (builder, flags); - } catch { - container.Compiler.Report.RuntimeMissingSupport (method.Location, "Generic method MethodAttributes"); - } -#endif - } + // + // Creates full MethodBuilder for the method + // + public MethodBuilder DefineMethodBuilder (TypeDefinition container, ParametersCompiled param) + { + DefineMethodBuilder (container); + builder.SetReturnType (method.ReturnType.GetMetaInfo ()); + builder.SetParameters (param.GetMetaInfo ()); + return builder; } // @@ -2096,14 +2157,14 @@ namespace Mono.CSharp { // public void Emit (TypeDefinition parent) { - var mc = (IMemberContext) method; + DefineOverride (parent); - method.ParameterInfo.ApplyAttributes (mc, MethodBuilder); + method.ParameterInfo.ApplyAttributes (method, MethodBuilder); ToplevelBlock block = method.Block; if (block != null) { - BlockContext bc = new BlockContext (mc, block, method.ReturnType); - if (block.Resolve (null, bc, method)) { + BlockContext bc = new BlockContext (method, block, method.ReturnType); + if (block.Resolve (bc, method)) { debug_builder = member.Parent.CreateMethodSymbolEntry (); EmitContext ec = method.CreateEmitContext (MethodBuilder.GetILGenerator (), debug_builder); @@ -2120,7 +2181,7 @@ namespace Mono.CSharp { var token = builder.GetToken (); int t = token.Token; #if STATIC - if (token.IsPseudoToken) + if (ModuleBuilder.IsPseudoToken (t)) t = member.Module.Builder.ResolvePseudoToken (t); #endif @@ -2235,7 +2296,7 @@ namespace Mono.CSharp { // Ooouh Martin, templates are missing here. // When it will be possible move here a lot of child code and template method type. - public abstract class AbstractPropertyEventMethod : MemberCore, IMethodData { + public abstract class AbstractPropertyEventMethod : MemberCore, IMethodData, IMethodDefinition { protected MethodData method_data; protected ToplevelBlock block; protected SecurityType declarative_security; @@ -2244,7 +2305,7 @@ namespace Mono.CSharp { ReturnParameter return_attributes; - public AbstractPropertyEventMethod (InterfaceMemberBase member, string prefix, Attributes attrs, Location loc) + protected AbstractPropertyEventMethod (InterfaceMemberBase member, string prefix, Attributes attrs, Location loc) : base (member.Parent, SetupName (prefix, member, loc), attrs) { this.prefix = prefix; @@ -2301,6 +2362,12 @@ namespace Mono.CSharp { } } + MethodBase IMethodDefinition.Metadata { + get { + return method_data.MethodBuilder; + } + } + public abstract ParametersCompiled ParameterInfo { get ; } public abstract TypeSpec ReturnType { get; } @@ -2311,7 +2378,7 @@ namespace Mono.CSharp { if (a.Type == pa.CLSCompliant || a.Type == pa.Obsolete || a.Type == pa.Conditional) { Report.Error (1667, a.Location, "Attribute `{0}' is not valid on property or event accessors. It is valid on `{1}' declarations only", - TypeManager.CSharpName (a.Type), a.GetValidTargets ()); + a.Type.GetSignatureForError (), a.GetValidTargets ()); return; } @@ -2411,6 +2478,11 @@ namespace Mono.CSharp { return false; } + public void PrepareEmit () + { + method_data.DefineMethodBuilder (Parent.PartialContainer, ParameterInfo); + } + public override void WriteDebugSymbol (MonoSymbolFile file) { if (method_data != null) diff --git a/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/modifiers.cs b/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/modifiers.cs index 3edbed6ba..c8c6b73e6 100644 --- a/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/modifiers.cs +++ b/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/modifiers.cs @@ -46,11 +46,12 @@ namespace Mono.CSharp PROPERTY_CUSTOM = 0x10000, PARTIAL = 0x20000, - DEFAULT_ACCESS_MODIFER = 0x40000, + DEFAULT_ACCESS_MODIFIER = 0x40000, METHOD_EXTENSION = 0x80000, COMPILER_GENERATED = 0x100000, BACKING_FIELD = 0x200000, DEBUGGER_HIDDEN = 0x400000, + DEBUGGER_STEP_THROUGH = 0x800000, AccessibilityMask = PUBLIC | PROTECTED | INTERNAL | PRIVATE, AllowedExplicitImplFlags = UNSAFE | EXTERN, @@ -255,14 +256,14 @@ namespace Mono.CSharp if ((mod & Modifiers.AccessibilityMask) == 0) { mod |= def_access; if (def_access != 0) - mod |= Modifiers.DEFAULT_ACCESS_MODIFER; + mod |= Modifiers.DEFAULT_ACCESS_MODIFIER; return mod; } return mod; } - for (i = 1; i <= (int) Modifiers.TOP; i <<= 1) { + for (i = 1; i < (int) Modifiers.TOP; i <<= 1) { if ((i & invalid_flags) == 0) continue; diff --git a/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/module.cs b/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/module.cs index bf36e8f20..e7e02a0bf 100644 --- a/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/module.cs +++ b/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/module.cs @@ -113,6 +113,7 @@ namespace Mono.CSharp readonly Dictionary pointer_types; readonly Dictionary reference_types; readonly Dictionary attrs_cache; + readonly Dictionary awaiters; AssemblyDefinition assembly; readonly CompilerContext context; @@ -127,6 +128,9 @@ namespace Mono.CSharp PredefinedTypes predefined_types; PredefinedMembers predefined_members; + public Binary.PredefinedOperator[] OperatorsBinaryEqualityLifted; + public Binary.PredefinedOperator[] OperatorsBinaryLifted; + static readonly string[] attribute_targets = new string[] { "assembly", "module" }; public ModuleContainer (CompilerContext context) @@ -144,6 +148,7 @@ namespace Mono.CSharp pointer_types = new Dictionary (); reference_types = new Dictionary (); attrs_cache = new Dictionary (); + awaiters = new Dictionary (); } #region Properties @@ -182,9 +187,6 @@ namespace Mono.CSharp } public int CounterAnonymousTypes { get; set; } - public int CounterAnonymousMethods { get; set; } - public int CounterAnonymousContainers { get; set; } - public int CounterSwitchTypes { get; set; } public AssemblyDefinition DeclaringAssembly { get { @@ -309,7 +311,7 @@ namespace Mono.CSharp public override void AddTypeContainer (TypeContainer tc) { - containers.Add (tc); + AddTypeContainerMember (tc); } public override void ApplyAttributeBuilder (Attribute a, MethodSpec ctor, byte[] cdata, PredefinedAttributes pa) @@ -398,6 +400,8 @@ namespace Mono.CSharp { DefineContainer (); + ExpandBaseInterfaces (); + base.Define (); HasTypesFullyDefined = true; @@ -412,12 +416,17 @@ namespace Mono.CSharp return base.DefineContainer (); } + public void EnableRedefinition () + { + is_defined = false; + } + public override void EmitContainer () { if (OptAttributes != null) OptAttributes.Emit (); - if (Compiler.Settings.Unsafe) { + if (Compiler.Settings.Unsafe && !assembly.IsSatelliteAssembly) { var pa = PredefinedAttributes.UnverifiableCode; if (pa.IsDefined) pa.EmitAttribute (builder); @@ -465,6 +474,43 @@ namespace Mono.CSharp return null; } + // + // Return container with awaiter definition. It never returns null + // but all container member can be null for easier error reporting + // + public AwaiterDefinition GetAwaiter (TypeSpec type) + { + AwaiterDefinition awaiter; + if (awaiters.TryGetValue (type, out awaiter)) + return awaiter; + + awaiter = new AwaiterDefinition (); + + // + // Predefined: bool IsCompleted { get; } + // + awaiter.IsCompleted = MemberCache.FindMember (type, MemberFilter.Property ("IsCompleted", Compiler.BuiltinTypes.Bool), + BindingRestriction.InstanceOnly) as PropertySpec; + + // + // Predefined: GetResult () + // + // The method return type is also result type of await expression + // + awaiter.GetResult = MemberCache.FindMember (type, MemberFilter.Method ("GetResult", 0, + ParametersCompiled.EmptyReadOnlyParameters, null), + BindingRestriction.InstanceOnly) as MethodSpec; + + // + // Predefined: INotifyCompletion.OnCompleted (System.Action) + // + var nc = PredefinedTypes.INotifyCompletion; + awaiter.INotifyCompletion = !nc.Define () || type.ImplementsInterface (nc.TypeSpec, false); + + awaiters.Add (type, awaiter); + return awaiter; + } + public override void GetCompletionStartingWith (string prefix, List results) { var names = Evaluator.GetVarNames (); @@ -483,11 +529,37 @@ namespace Mono.CSharp return ""; } + public Binary.PredefinedOperator[] GetPredefinedEnumAritmeticOperators (TypeSpec enumType, bool nullable) + { + TypeSpec underlying; + Binary.Operator mask = 0; + + if (nullable) { + underlying = Nullable.NullableInfo.GetEnumUnderlyingType (this, enumType); + mask = Binary.Operator.NullableMask; + } else { + underlying = EnumSpec.GetUnderlyingType (enumType); + } + + var operators = new[] { + new Binary.PredefinedOperator (enumType, underlying, + mask | Binary.Operator.AdditionMask | Binary.Operator.SubtractionMask | Binary.Operator.DecomposedMask, enumType), + new Binary.PredefinedOperator (underlying, enumType, + mask | Binary.Operator.AdditionMask | Binary.Operator.SubtractionMask | Binary.Operator.DecomposedMask, enumType), + new Binary.PredefinedOperator (enumType, mask | Binary.Operator.SubtractionMask, underlying) + }; + + return operators; + } + public void InitializePredefinedTypes () { predefined_attributes = new PredefinedAttributes (this); predefined_types = new PredefinedTypes (this); predefined_members = new PredefinedMembers (this); + + OperatorsBinaryEqualityLifted = Binary.CreateEqualityLiftedOperatorsTable (this); + OperatorsBinaryLifted = Binary.CreateStandardLiftedOperatorsTable (this); } public override bool IsClsComplianceRequired () diff --git a/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/namespace.cs b/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/namespace.cs index 9f448842f..0989d1cd2 100644 --- a/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/namespace.cs +++ b/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/namespace.cs @@ -22,9 +22,10 @@ namespace Mono.CSharp { readonly Dictionary all_namespaces; public RootNamespace (string alias_name) - : base (null, String.Empty) + : base () { this.alias_name = alias_name; + RegisterNamespace (this); all_namespaces = new Dictionary (); all_namespaces.Add ("", this); @@ -64,12 +65,12 @@ namespace Mono.CSharp { // // For better error reporting where compiler tries to guess missing using directive // - public List FindExtensionMethodNamespaces (IMemberContext ctx, TypeSpec extensionType, string name, int arity) + public List FindExtensionMethodNamespaces (IMemberContext ctx, string name, int arity) { List res = null; foreach (var ns in all_namespaces) { - var methods = ns.Value.LookupExtensionMethod (ctx, extensionType, name, arity); + var methods = ns.Value.LookupExtensionMethod (ctx, name, arity); if (methods != null) { if (res == null) res = new List (); @@ -87,24 +88,13 @@ namespace Mono.CSharp { all_namespaces.Add (child.Name, child); } - public bool IsNamespace (string name) - { - return all_namespaces.ContainsKey (name); - } - - protected void RegisterNamespace (string dotted_name) - { - if (dotted_name != null && dotted_name.Length != 0 && ! IsNamespace (dotted_name)) - GetNamespace (dotted_name, true); - } - public override string GetSignatureForError () { return alias_name + "::"; } } - public class GlobalRootNamespace : RootNamespace + public sealed class GlobalRootNamespace : RootNamespace { public GlobalRootNamespace () : base ("global") @@ -115,67 +105,52 @@ namespace Mono.CSharp { // // Namespace cache for imported and compiled namespaces // - // This is an Expression to allow it to be referenced in the - // compiler parse/intermediate tree during name resolution. - // - public class Namespace : FullNamedExpression + public class Namespace { - Namespace parent; + readonly Namespace parent; string fullname; protected Dictionary namespaces; protected Dictionary> types; List extension_method_types; - Dictionary cached_types; - RootNamespace root; + Dictionary cached_types; bool cls_checked; - public readonly MemberName MemberName; - /// /// Constructor Takes the current namespace and the /// name. This is bootstrapped with parent == null /// and name = "" /// public Namespace (Namespace parent, string name) + : this () { - // Expression members. - this.eclass = ExprClass.Namespace; - this.Type = InternalType.Namespace; - this.loc = Location.Null; + if (name == null) + throw new ArgumentNullException ("name"); this.parent = parent; - if (parent != null) - this.root = parent.root; - else - this.root = this as RootNamespace; - - if (this.root == null) - throw new InternalErrorException ("Root namespaces must be created using RootNamespace"); - - string pname = parent != null ? parent.fullname : ""; + string pname = parent != null ? parent.fullname : null; - if (pname == "") + if (pname == null) fullname = name; else - fullname = parent.fullname + "." + name; - - if (fullname == null) - throw new InternalErrorException ("Namespace has a null fullname"); + fullname = pname + "." + name; - if (parent != null && parent.MemberName != MemberName.Null) - MemberName = new MemberName (parent.MemberName, name, Location.Null); - else if (name.Length == 0) - MemberName = MemberName.Null; - else - MemberName = new MemberName (name, Location.Null); + while (parent.parent != null) + parent = parent.parent; - namespaces = new Dictionary (); - cached_types = new Dictionary (); + var root = parent as RootNamespace; + if (root == null) + throw new InternalErrorException ("Root namespaces must be created using RootNamespace"); root.RegisterNamespace (this); } + protected Namespace () + { + namespaces = new Dictionary (); + cached_types = new Dictionary (); + } + #region Properties /// @@ -195,97 +170,9 @@ namespace Mono.CSharp { #endregion - protected override Expression DoResolve (ResolveContext ec) - { - return this; - } - - public void Error_NamespaceDoesNotExist (IMemberContext ctx, string name, int arity, Location loc) - { - var retval = LookupType (ctx, name, arity, LookupMode.IgnoreAccessibility, loc); - if (retval != null) { - ctx.Module.Compiler.Report.SymbolRelatedToPreviousError (retval.Type); - ErrorIsInaccesible (ctx, retval.GetSignatureForError (), loc); - return; - } - - retval = LookupType (ctx, name, -System.Math.Max (1, arity), LookupMode.Probing, loc); - if (retval != null) { - Error_TypeArgumentsCannotBeUsed (ctx, retval.Type, arity, loc); - return; - } - - Namespace ns; - if (arity > 0 && namespaces.TryGetValue (name, out ns)) { - ns.Error_TypeArgumentsCannotBeUsed (ctx, null, arity, loc); - 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 {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 {2} assembly reference?", - name, GetSignatureForError (), assembly); - } - } - - public override string GetSignatureForError () - { - return fullname; - } - public Namespace AddNamespace (MemberName name) { - Namespace ns_parent; - if (name.Left != null) { - if (parent != null) - ns_parent = parent.AddNamespace (name.Left); - else - ns_parent = AddNamespace (name.Left); - } else { - ns_parent = this; - } - + var ns_parent = name.Left == null ? this : AddNamespace (name.Left); return ns_parent.TryAddNamespace (name.Basename); } @@ -301,6 +188,11 @@ namespace Mono.CSharp { return ns; } + public bool TryGetNamespace (string name, out Namespace ns) + { + return namespaces.TryGetValue (name, out ns); + } + // TODO: Replace with CreateNamespace where MemberName is created for the method call public Namespace GetNamespace (string name, bool create) { @@ -336,20 +228,26 @@ namespace Mono.CSharp { return found; } - public TypeExpr LookupType (IMemberContext ctx, string name, int arity, LookupMode mode, Location loc) + public virtual string GetSignatureForError () + { + return fullname; + } + + public TypeSpec LookupType (IMemberContext ctx, string name, int arity, LookupMode mode, Location loc) { if (types == null) return null; - TypeExpr te; - if (arity == 0 && cached_types.TryGetValue (name, out te)) - return te; + TypeSpec best = null; + if (arity == 0 && cached_types.TryGetValue (name, out best)) { + if (best != null || mode != LookupMode.IgnoreAccessibility) + return best; + } IList found; if (!types.TryGetValue (name, out found)) return null; - TypeSpec best = null; foreach (var ts in found) { if (ts.Arity == arity) { if (best == null) { @@ -361,11 +259,20 @@ namespace Mono.CSharp { } if (best.MemberDefinition.IsImported && ts.MemberDefinition.IsImported) { + if (ts.Kind == MemberKind.MissingType) + continue; + + if (best.Kind == MemberKind.MissingType) { + best = ts; + continue; + } + if (mode == LookupMode.Normal) { ctx.Module.Compiler.Report.SymbolRelatedToPreviousError (best); ctx.Module.Compiler.Report.SymbolRelatedToPreviousError (ts); ctx.Module.Compiler.Report.Error (433, loc, "The imported type `{0}' is defined multiple times", ts.GetSignatureForError ()); } + break; } @@ -378,8 +285,10 @@ namespace Mono.CSharp { if (mode != LookupMode.Normal) continue; - if (ts.MemberDefinition.IsImported) + if (ts.MemberDefinition.IsImported) { + ctx.Module.Compiler.Report.SymbolRelatedToPreviousError (best); ctx.Module.Compiler.Report.SymbolRelatedToPreviousError (ts); + } ctx.Module.Compiler.Report.Warning (436, 2, loc, "The type `{0}' conflicts with the imported type of same name'. Ignoring the imported type definition", @@ -398,16 +307,11 @@ namespace Mono.CSharp { } } - if (best == null) - return null; - - te = new TypeExpression (best, Location.Null); - // TODO MemberCache: Cache more if (arity == 0 && mode == LookupMode.Normal) - cached_types.Add (name, te); + cached_types.Add (name, best); - return te; + return best; } public FullNamedExpression LookupTypeOrNamespace (IMemberContext ctx, string name, int arity, LookupMode mode, Location loc) @@ -417,21 +321,24 @@ namespace Mono.CSharp { Namespace ns; if (arity == 0 && namespaces.TryGetValue (name, out ns)) { if (texpr == null) - return ns; + return new NamespaceExpression (ns, loc); if (mode != LookupMode.Probing) { - ctx.Module.Compiler.Report.SymbolRelatedToPreviousError (texpr.Type); + //ctx.Module.Compiler.Report.SymbolRelatedToPreviousError (texpr.Type); // ctx.Module.Compiler.Report.SymbolRelatedToPreviousError (ns.loc, ""); ctx.Module.Compiler.Report.Warning (437, 2, loc, "The type `{0}' conflicts with the imported namespace `{1}'. Using the definition found in the source file", texpr.GetSignatureForError (), ns.GetSignatureForError ()); } - if (texpr.Type.MemberDefinition.IsImported) - return ns; + if (texpr.MemberDefinition.IsImported) + return new NamespaceExpression (ns, loc); } - return texpr; + if (texpr == null) + return null; + + return new TypeExpression (texpr, loc); } // @@ -455,7 +362,7 @@ namespace Mono.CSharp { // // Looks for extension method in this namespace // - public List LookupExtensionMethod (IMemberContext invocationContext, TypeSpec extensionType, string name, int arity) + public List LookupExtensionMethod (IMemberContext invocationContext, string name, int arity) { if (extension_method_types == null) return null; @@ -478,7 +385,7 @@ namespace Mono.CSharp { continue; } - var res = ts.MemberCache.FindExtensionMethods (invocationContext, extensionType, name, arity); + var res = ts.MemberCache.FindExtensionMethods (invocationContext, name, arity); if (res == null) continue; @@ -498,12 +405,14 @@ namespace Mono.CSharp { types = new Dictionary> (64); } - if ((ts.IsStatic || ts.MemberDefinition.IsPartial) && ts.Arity == 0 && - (ts.MemberDefinition.DeclaringAssembly == null || ts.MemberDefinition.DeclaringAssembly.HasExtensionMethod)) { - if (extension_method_types == null) - extension_method_types = new List (); + if (ts.IsClass && ts.Arity == 0) { + var extension_method_allowed = ts.MemberDefinition.IsImported ? (ts.Modifiers & Modifiers.METHOD_EXTENSION) != 0 : (ts.IsStatic || ts.MemberDefinition.IsPartial); + if (extension_method_allowed) { + if (extension_method_types == null) + extension_method_types = new List (); - extension_method_types.Add (ts); + extension_method_types.Add (ts); + } } var name = ts.Name; @@ -577,11 +486,6 @@ namespace Mono.CSharp { cached_types.Remove (tc.Basename); } - public override FullNamedExpression ResolveAsTypeOrNamespace (IMemberContext mc) - { - return this; - } - public void SetBuiltinType (BuiltinTypeSpec pts) { var found = types[pts.Name]; @@ -674,11 +578,9 @@ namespace Mono.CSharp { } } - public IEnumerable Conditionals { + public IDictionary Conditionals { get { - if (conditionals == null) - return Enumerable.Empty (); - return conditionals.Where (kv => kv.Value).Select (kv => kv.Key); + return conditionals ?? new Dictionary (); } } @@ -738,7 +640,7 @@ namespace Mono.CSharp { void CreateUnitSymbolInfo (MonoSymbolFile symwriter) { var si = file.CreateSymbolInfo (symwriter); - comp_unit = new CompileUnitEntry (symwriter, si);; + comp_unit = new CompileUnitEntry (symwriter, si); if (include_files != null) { foreach (SourceFile include in include_files.Values) { @@ -762,6 +664,11 @@ namespace Mono.CSharp { return Compiler.Settings.IsConditionalSymbolDefined (value); } + + public override void Accept (StructuralVisitor visitor) + { + visitor.Visit (this); + } } @@ -878,7 +785,7 @@ namespace Mono.CSharp { public override void AddPartial (TypeDefinition next_part) { var existing = ns.LookupType (this, next_part.MemberName.Name, next_part.MemberName.Arity, LookupMode.Probing, Location.Null); - var td = existing != null ? existing.Type.MemberDefinition as TypeDefinition : null; + var td = existing != null ? existing.MemberDefinition as TypeDefinition : null; AddPartial (next_part, td); } @@ -897,7 +804,7 @@ namespace Mono.CSharp { MemberCore mc; if (names_container.DefinedNames.TryGetValue (name, out mc)) { if (tc is NamespaceContainer && mc is NamespaceContainer) { - containers.Add (tc); + AddTypeContainerMember (tc); return; } @@ -910,13 +817,33 @@ namespace Mono.CSharp { } } else { names_container.DefinedNames.Add (name, tc); + + var tdef = tc.PartialContainer; + if (tdef != null) { + // + // Same name conflict in different namespace containers + // + var conflict = ns.GetAllTypes (name); + if (conflict != null) { + foreach (var e in conflict) { + if (e.Arity == mn.Arity) { + mc = (MemberCore) e.MemberDefinition; + break; + } + } + } + + if (mc != null) { + Report.SymbolRelatedToPreviousError (mc); + Report.Error (101, tc.Location, "The namespace `{0}' already contains a definition for `{1}'", + GetSignatureForError (), mn.GetSignatureForError ()); + } else { + ns.AddType (Module, tdef.Definition); + } + } } base.AddTypeContainer (tc); - - var tdef = tc.PartialContainer; - if (tdef != null) - ns.AddType (Module, tdef.Definition); } public override void ApplyAttributeBuilder (Attribute a, MethodSpec ctor, byte[] cdata, PredefinedAttributes pa) @@ -954,7 +881,7 @@ namespace Mono.CSharp { ExtensionMethodCandidates candidates; var container = this; do { - candidates = container.LookupExtensionMethodCandidates (invocationContext, extensionType, name, arity, ref position); + candidates = container.LookupExtensionMethodCandidates (invocationContext, name, arity, ref position); if (candidates != null || container.MemberName == null) return candidates; @@ -969,7 +896,7 @@ namespace Mono.CSharp { while (mn != null) { ++position; - var methods = container_ns.LookupExtensionMethod (invocationContext, extensionType, name, arity); + var methods = container_ns.LookupExtensionMethod (invocationContext, name, arity); if (methods != null) { return new ExtensionMethodCandidates (invocationContext, methods, container, position); } @@ -985,14 +912,14 @@ namespace Mono.CSharp { return null; } - ExtensionMethodCandidates LookupExtensionMethodCandidates (IMemberContext invocationContext, TypeSpec extensionType, string name, int arity, ref int position) + ExtensionMethodCandidates LookupExtensionMethodCandidates (IMemberContext invocationContext, string name, int arity, ref int position) { List candidates = null; if (position == 0) { ++position; - candidates = ns.LookupExtensionMethod (invocationContext, extensionType, name, arity); + candidates = ns.LookupExtensionMethod (invocationContext, name, arity); if (candidates != null) { return new ExtensionMethodCandidates (invocationContext, candidates, this, position); } @@ -1002,7 +929,7 @@ namespace Mono.CSharp { ++position; foreach (Namespace n in namespace_using_table) { - var a = n.LookupExtensionMethod (invocationContext, extensionType, name, arity); + var a = n.LookupExtensionMethod (invocationContext, name, arity); if (a == null) continue; @@ -1047,6 +974,9 @@ namespace Mono.CSharp { public override void GetCompletionStartingWith (string prefix, List results) { + if (Usings == null) + return; + foreach (var un in Usings) { if (un.Alias != null) continue; @@ -1122,7 +1052,7 @@ namespace Mono.CSharp { if (aliases != null && arity == 0) { UsingAliasNamespace uan; if (aliases.TryGetValue (name, out uan)) { - if (fne != null) { + if (fne != null && mode != LookupMode.Probing) { // TODO: Namespace has broken location //Report.SymbolRelatedToPreviousError (fne.Location, null); Compiler.Report.SymbolRelatedToPreviousError (uan.Location, null); @@ -1154,10 +1084,11 @@ namespace Mono.CSharp { // A using directive imports only types contained in the namespace, it // does not import any nested namespaces // - fne = using_ns.LookupType (this, name, arity, mode, loc); - if (fne == null) + var t = using_ns.LookupType (this, name, arity, mode, loc); + if (t == null) continue; + fne = new TypeExpression (t, loc); if (match == null) { match = fne; continue; @@ -1244,18 +1175,18 @@ namespace Mono.CSharp { continue; } - Namespace using_ns = entry.ResolvedExpression as Namespace; + var using_ns = entry.ResolvedExpression as NamespaceExpression; if (using_ns == null) continue; - if (list.Contains (using_ns)) { + if (list.Contains (using_ns.Namespace)) { // 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 { - list.Add (using_ns); + list.Add (using_ns.Namespace); } } @@ -1277,8 +1208,9 @@ namespace Mono.CSharp { } } - public void EnableUsingClausesRedefinition () + public void EnableRedefinition () { + is_defined = false; namespace_using_table = null; } @@ -1314,7 +1246,7 @@ namespace Mono.CSharp { return false; } - + public override void Accept (StructuralVisitor visitor) { visitor.Visit (this); @@ -1369,7 +1301,7 @@ namespace Mono.CSharp { public virtual void Define (NamespaceContainer ctx) { resolved = expr.ResolveAsTypeOrNamespace (ctx); - var ns = resolved as Namespace; + var ns = resolved as NamespaceExpression; if (ns == null) { if (resolved != null) { ctx.Module.Compiler.Report.SymbolRelatedToPreviousError (resolved.Type); @@ -1384,6 +1316,11 @@ namespace Mono.CSharp { { visitor.Visit (this); } + + public override string ToString() + { + return resolved.ToString(); + } } public class UsingExternAlias : UsingAliasNamespace @@ -1395,12 +1332,15 @@ namespace Mono.CSharp { public override void Define (NamespaceContainer ctx) { - resolved = ctx.Module.GetRootNamespace (Alias.Value); - if (resolved == null) { + var ns = ctx.Module.GetRootNamespace (Alias.Value); + if (ns == null) { ctx.Module.Compiler.Report.Error (430, Location, "The extern alias `{0}' was not specified in -reference option", Alias.Value); + return; } + + resolved = new NamespaceExpression (ns, Location); } public override void Accept (StructuralVisitor visitor) diff --git a/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/nullable.cs b/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/nullable.cs index d7a6c1638..566c62af3 100644 --- a/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/nullable.cs +++ b/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/nullable.cs @@ -13,6 +13,7 @@ // using System; +using SLE = System.Linq.Expressions; #if STATIC using IKVM.Reflection.Emit; @@ -68,6 +69,9 @@ namespace Mono.CSharp.Nullable MemberFilter.Method ("GetValueOrDefault", 0, ParametersCompiled.EmptyReadOnlyParameters, null), BindingRestriction.None); } + // + // Don't use unless really required for correctness, see Unwrap::Emit + // public static MethodSpec GetValue (TypeSpec nullableType) { return (MethodSpec) MemberCache.FindMember (nullableType, @@ -78,6 +82,12 @@ namespace Mono.CSharp.Nullable { return ((InflatedTypeSpec) nullableType).TypeArguments[0]; } + + public static TypeSpec GetEnumUnderlyingType (ModuleContainer module, TypeSpec nullableEnum) + { + return module.PredefinedTypes.Nullable.TypeSpec.MakeGenericType (module, + new[] { EnumSpec.GetUnderlyingType (GetUnderlyingType (nullableEnum)) }); + } } public class Unwrap : Expression, IMemoryLocation @@ -85,9 +95,10 @@ namespace Mono.CSharp.Nullable Expression expr; LocalTemporary temp; + Expression temp_field; readonly bool useDefaultValue; - Unwrap (Expression expr, bool useDefaultValue) + public Unwrap (Expression expr, bool useDefaultValue = true) { this.expr = expr; this.loc = expr.Location; @@ -102,6 +113,7 @@ namespace Mono.CSharp.Nullable return expr.ContainsEmitWithAwait (); } + // TODO: REMOVE public static Expression Create (Expression expr) { // @@ -114,6 +126,18 @@ namespace Mono.CSharp.Nullable return Create (expr, false); } + public static Expression CreateUnwrapped (Expression expr) + { + // + // Avoid unwraping and wraping of same type + // + Wrap wrap = expr as Wrap; + if (wrap != null) + return wrap.Child; + + return Create (expr, true); + } + public static Unwrap Create (Expression expr, bool useDefaultValue) { return new Unwrap (expr, useDefaultValue); @@ -142,6 +166,11 @@ namespace Mono.CSharp.Nullable var call = new CallEmitter (); call.InstanceExpression = this; + // + // Using GetGetValueOrDefault is prefered because JIT can possibly + // inline it whereas Value property contains a throw which is very + // unlikely to be inlined + // if (useDefaultValue) call.EmitPredefined (ec, NullableInfo.GetGetValueOrDefault (expr.Type), null); else @@ -158,12 +187,25 @@ namespace Mono.CSharp.Nullable call.EmitPredefined (ec, NullableInfo.GetHasValue (expr.Type), null); } + public override Expression EmitToField (EmitContext ec) + { + if (temp_field == null) + temp_field = this.expr.EmitToField (ec); + + return this; + } + public override bool Equals (object obj) { Unwrap uw = obj as Unwrap; return uw != null && expr.Equals (uw.expr); } + public override void FlowAnalysis (FlowAnalysisContext fc) + { + expr.FlowAnalysis (fc); + } + public Expression Original { get { return expr; @@ -181,9 +223,9 @@ namespace Mono.CSharp.Nullable } } - void Store (EmitContext ec) + public void Store (EmitContext ec) { - if (temp != null) + if (temp != null || temp_field != null) return; if (expr is VariableReference) @@ -195,20 +237,35 @@ namespace Mono.CSharp.Nullable public void Load (EmitContext ec) { - if (expr is VariableReference) + if (temp_field != null) + temp_field.Emit (ec); + else if (expr is VariableReference) expr.Emit (ec); else LocalVariable.Emit (ec); } - public override System.Linq.Expressions.Expression MakeExpression (BuilderContext ctx) + public override SLE.Expression MakeExpression (BuilderContext ctx) { return expr.MakeExpression (ctx); } public void AddressOf (EmitContext ec, AddressOp mode) { - IMemoryLocation ml = expr as VariableReference; + IMemoryLocation ml; + + if (temp_field != null) { + ml = temp_field as IMemoryLocation; + if (ml == null) { + var lt = new LocalTemporary (temp_field.Type); + temp_field.Emit (ec); + lt.Store (ec); + ml = lt; + } + } else { + ml = expr as VariableReference; + } + if (ml != null) ml.AddressOf (ec, mode); else @@ -220,7 +277,7 @@ namespace Mono.CSharp.Nullable // LocalTemporary LocalVariable { get { - if (temp == null) + if (temp == null && temp_field == null) temp = new LocalTemporary (expr.Type); return temp; } @@ -271,6 +328,12 @@ namespace Mono.CSharp.Nullable return child_cast.CreateExpressionTree (ec); } + var user_cast = child as UserCast; + if (user_cast != null) { + child.Type = type; + return user_cast.CreateExpressionTree (ec); + } + return base.CreateExpressionTree (ec); } @@ -309,10 +372,12 @@ namespace Mono.CSharp.Nullable return new LiftedNull (nullable, loc); } - public static Constant CreateFromExpression (ResolveContext ec, Expression e) + public static Constant CreateFromExpression (ResolveContext rc, Expression e) { - ec.Report.Warning (458, 2, e.Location, "The result of the expression is always `null' of type `{0}'", - TypeManager.CSharpName (e.Type)); + if (!rc.HasSet (ResolveContext.Options.ExpressionTreeConversion)) { + rc.Report.Warning (458, 2, e.Location, "The result of the expression is always `null' of type `{0}'", + e.Type.GetSignatureForError ()); + } return ReducedExpression.Create (Create (e.Type, e.Location), e); } @@ -334,19 +399,19 @@ namespace Mono.CSharp.Nullable value_target.AddressOf (ec, AddressOp.Store); ec.Emit (OpCodes.Initobj, type); - ((IMemoryLocation) value_target).AddressOf (ec, Mode); + value_target.AddressOf (ec, Mode); } } // // Generic lifting expression, supports all S/S? -> T/T? cases // - public class Lifted : Expression, IMemoryLocation + public class LiftedConversion : Expression, IMemoryLocation { Expression expr, null_value; Unwrap unwrap; - public Lifted (Expression expr, Unwrap unwrap, TypeSpec type) + public LiftedConversion (Expression expr, Unwrap unwrap, TypeSpec type) { this.expr = expr; this.unwrap = unwrap; @@ -354,7 +419,7 @@ namespace Mono.CSharp.Nullable this.type = type; } - public Lifted (Expression expr, Expression unwrap, TypeSpec type) + public LiftedConversion (Expression expr, Expression unwrap, TypeSpec type) : this (expr, unwrap as Unwrap, type) { } @@ -385,9 +450,11 @@ namespace Mono.CSharp.Nullable // Wrap target for T? if (type.IsNullableType) { - expr = Wrap.Create (expr, type); - if (expr == null) - return null; + if (!expr.Type.IsNullableType) { + expr = Wrap.Create (expr, type); + if (expr == null) + return null; + } null_value = LiftedNull.Create (type, loc); } else if (TypeSpec.IsValueType (type)) { @@ -414,9 +481,15 @@ namespace Mono.CSharp.Nullable ec.MarkLabel (is_null_label); null_value.Emit (ec); + ec.MarkLabel (end_label); } + public override void FlowAnalysis (FlowAnalysisContext fc) + { + expr.FlowAnalysis (fc); + } + public void AddressOf (EmitContext ec, AddressOp mode) { unwrap.AddressOf (ec, mode); @@ -456,6 +529,11 @@ namespace Mono.CSharp.Nullable return null; Expression res = base.ResolveOperator (ec, unwrap); + if (res == null) { + Error_OperatorCannotBeApplied (ec, loc, OperName (Oper), Expr.Type); + return null; + } + if (res != this) { if (user_operator == null) return res; @@ -532,266 +610,105 @@ namespace Mono.CSharp.Nullable } } - public class LiftedBinaryOperator : Binary + // + // Lifted version of binary operators + // + class LiftedBinaryOperator : Expression { - Unwrap left_unwrap, right_unwrap; - Expression left_orig, right_orig; - Expression user_operator; - MethodSpec wrap_ctor; - - public LiftedBinaryOperator (Binary.Operator op, Expression left, Expression right) - : base (op, left, right) + public LiftedBinaryOperator (Binary b) { + this.Binary = b; + this.loc = b.Location; } - bool IsBitwiseBoolean { - get { - return (Oper == Operator.BitwiseAnd || Oper == Operator.BitwiseOr) && - ((left_unwrap != null && left_unwrap.Type.BuiltinType == BuiltinTypeSpec.Type.Bool) || - (right_unwrap != null && right_unwrap.Type.BuiltinType == BuiltinTypeSpec.Type.Bool)); - } - } + public Binary Binary { get; private set; } - bool IsLeftNullLifted { - get { - return (state & State.LeftNullLifted) != 0; - } - } + public Expression Left { get; set; } - bool IsRightNullLifted { - get { - return (state & State.RightNullLifted) != 0; - } - } + public Expression Right { get; set; } - public override Expression CreateExpressionTree (ResolveContext ec) - { - if (user_operator != null) - return user_operator.CreateExpressionTree (ec); + public Unwrap UnwrapLeft { get; set; } - return base.CreateExpressionTree (ec); - } + public Unwrap UnwrapRight { get; set; } - // - // CSC 2 has this behavior, it allows structs to be compared - // with the null literal *outside* of a generics context and - // inlines that as true or false. - // - Constant CreateNullConstant (ResolveContext ec, Expression expr) - { - // FIXME: Handle side effect constants - Constant c = new BoolConstant (ec.BuiltinTypes, Oper == Operator.Inequality, loc); + public MethodSpec UserOperator { get; set; } - if ((Oper & Operator.EqualityMask) != 0) { - 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}'", - TypeManager.CSharpName (expr.Type), c.GetValueAsLiteral ()); + bool IsBitwiseBoolean { + get { + return (Binary.Oper == Binary.Operator.BitwiseAnd || Binary.Oper == Binary.Operator.BitwiseOr) && + ((UnwrapLeft != null && UnwrapLeft.Type.BuiltinType == BuiltinTypeSpec.Type.Bool) || + (UnwrapRight != null && UnwrapRight.Type.BuiltinType == BuiltinTypeSpec.Type.Bool)); } - - return ReducedExpression.Create (c, this); } - protected override Expression DoResolve (ResolveContext ec) + public override bool ContainsEmitWithAwait () { - if ((Oper & Operator.LogicalMask) != 0) { - Error_OperatorCannotBeApplied (ec, left, right); - return null; - } - - bool use_default_call = (Oper & (Operator.BitwiseMask | Operator.EqualityMask)) != 0; - left_orig = left; - if (left.Type.IsNullableType) { - left = left_unwrap = Unwrap.Create (left, use_default_call); - if (left == null) - return null; - } - - right_orig = right; - if (right.Type.IsNullableType) { - right = right_unwrap = Unwrap.Create (right, use_default_call); - if (right == null) - return null; - } - - // - // Some details are in 6.4.2, 7.2.7 - // Arguments can be lifted for equal operators when the return type is bool and both - // arguments are of same type - // - if (left_orig is NullLiteral) { - left = right; - state |= State.LeftNullLifted; - type = ec.BuiltinTypes.Bool; - } - - if (right_orig.IsNull) { - if ((Oper & Operator.ShiftMask) != 0) - right = new EmptyExpression (ec.BuiltinTypes.Int); - else - right = left; - - state |= State.RightNullLifted; - type = ec.BuiltinTypes.Bool; - } - - eclass = ExprClass.Value; - return DoResolveCore (ec, left_orig, right_orig); + return Left.ContainsEmitWithAwait () || Right.ContainsEmitWithAwait (); } - void EmitBitwiseBoolean (EmitContext ec) + public override Expression CreateExpressionTree (ResolveContext rc) { - Label load_left = ec.DefineLabel (); - Label load_right = ec.DefineLabel (); - Label end_label = ec.DefineLabel (); - - // null & value, null | value - if (left_unwrap == null) { - left_unwrap = right_unwrap; - right_unwrap = null; - right = left; - } + if (UserOperator != null) { + Arguments args = new Arguments (2); + args.Add (new Argument (Binary.Left)); + args.Add (new Argument (Binary.Right)); - left_unwrap.Emit (ec); - ec.Emit (OpCodes.Brtrue, load_right); - - // value & null, value | null - if (right_unwrap != null) { - right_unwrap.Emit (ec); - ec.Emit (OpCodes.Brtrue_S, load_left); + var method = new UserOperatorCall (UserOperator, args, Binary.CreateExpressionTree, loc); + return method.CreateExpressionTree (rc); } - left_unwrap.EmitCheck (ec); - ec.Emit (OpCodes.Brfalse_S, load_right); - - // load left - ec.MarkLabel (load_left); - - if (Oper == Operator.BitwiseAnd) { - left_unwrap.Load (ec); - } else { - if (right_unwrap == null) { - right.Emit (ec); - if (right is EmptyConstantCast || right is EmptyCast) - ec.Emit (OpCodes.Newobj, NullableInfo.GetConstructor (type)); - } else { - right_unwrap.Load (ec); - right_unwrap = left_unwrap; - } - } - ec.Emit (OpCodes.Br_S, end_label); - - // load right - ec.MarkLabel (load_right); - if (right_unwrap == null) { - if (Oper == Operator.BitwiseAnd) { - right.Emit (ec); - if (right is EmptyConstantCast || right is EmptyCast) - ec.Emit (OpCodes.Newobj, NullableInfo.GetConstructor (type)); - } else { - left_unwrap.Load (ec); - } - } else { - right_unwrap.Load (ec); - } - - ec.MarkLabel (end_label); + return Binary.CreateExpressionTree (rc); } - // - // Emits optimized equality or inequality operator when possible - // - void EmitEquality (EmitContext ec) + protected override Expression DoResolve (ResolveContext rc) { - // - // Either left or right is null - // - if (left_unwrap != null && (IsRightNullLifted || right.IsNull)) { - left_unwrap.EmitCheck (ec); - if (Oper == Binary.Operator.Equality) { - ec.EmitInt (0); - ec.Emit (OpCodes.Ceq); - } - return; - } - - if (right_unwrap != null && (IsLeftNullLifted || left.IsNull)) { - right_unwrap.EmitCheck (ec); - if (Oper == Binary.Operator.Equality) { - ec.EmitInt (0); - ec.Emit (OpCodes.Ceq); - } - return; - } - - Label dissimilar_label = ec.DefineLabel (); - Label end_label = ec.DefineLabel (); + if (rc.IsRuntimeBinder) { + if (UnwrapLeft == null && !Left.Type.IsNullableType) + Left = LiftOperand (rc, Left); - if (user_operator != null) { - user_operator.Emit (ec); - ec.Emit (Oper == Operator.Equality ? OpCodes.Brfalse_S : OpCodes.Brtrue_S, dissimilar_label); + if (UnwrapRight == null && !Right.Type.IsNullableType) + Right = LiftOperand (rc, Right); } else { - if (ec.HasSet (BuilderContext.Options.AsyncBody) && right.ContainsEmitWithAwait ()) { - left = left.EmitToField (ec); - right = right.EmitToField (ec); + if (UnwrapLeft == null && Left != null && Left.Type.IsNullableType) { + Left = Unwrap.CreateUnwrapped (Left); + UnwrapLeft = Left as Unwrap; } - left.Emit (ec); - right.Emit (ec); - - ec.Emit (OpCodes.Bne_Un_S, dissimilar_label); + if (UnwrapRight == null && Right != null && Right.Type.IsNullableType) { + Right = Unwrap.CreateUnwrapped (Right); + UnwrapRight = Right as Unwrap; + } } - if (left_unwrap != null) - left_unwrap.EmitCheck (ec); + type = Binary.Type; + eclass = Binary.eclass; - if (right_unwrap != null) - right_unwrap.EmitCheck (ec); + return this; + } - if (left_unwrap != null && right_unwrap != null) { - if (Oper == Operator.Inequality) - ec.Emit (OpCodes.Xor); - else - ec.Emit (OpCodes.Ceq); + Expression LiftOperand (ResolveContext rc, Expression expr) + { + TypeSpec type; + if (expr.IsNull) { + type = Left.IsNull ? Right.Type : Left.Type; } else { - if (Oper == Operator.Inequality) { - ec.EmitInt (0); - ec.Emit (OpCodes.Ceq); - } + type = expr.Type; } - ec.Emit (OpCodes.Br_S, end_label); + if (!type.IsNullableType) + type = rc.Module.PredefinedTypes.Nullable.TypeSpec.MakeGenericType (rc.Module, new[] { type }); - ec.MarkLabel (dissimilar_label); - if (Oper == Operator.Inequality) - ec.EmitInt (1); - else - ec.EmitInt (0); - - ec.MarkLabel (end_label); + return Wrap.Create (expr, type); } - - public override void EmitBranchable (EmitContext ec, Label target, bool onTrue) - { - Emit (ec); - ec.Emit (onTrue ? OpCodes.Brtrue : OpCodes.Brfalse, target); - } public override void Emit (EmitContext ec) { - // - // Optimize same expression operation - // - if (right_unwrap != null && right.Equals (left)) - right_unwrap = left_unwrap; - - if (user_operator == null && IsBitwiseBoolean) { + if (IsBitwiseBoolean && UserOperator == null) { EmitBitwiseBoolean (ec); return; } - if ((Oper & Operator.EqualityMask) != 0) { + if ((Binary.Oper & Binary.Operator.EqualityMask) != 0) { EmitEquality (ec); return; } @@ -799,28 +716,48 @@ namespace Mono.CSharp.Nullable Label is_null_label = ec.DefineLabel (); Label end_label = ec.DefineLabel (); - if (left_unwrap != null) { - left_unwrap.EmitCheck (ec); - ec.Emit (OpCodes.Brfalse, is_null_label); + if (ec.HasSet (BuilderContext.Options.AsyncBody) && Right.ContainsEmitWithAwait ()) { + Left = Left.EmitToField (ec); + Right = Right.EmitToField (ec); + } + + if (UnwrapLeft != null) { + UnwrapLeft.EmitCheck (ec); } // // Don't emit HasValue check when left and right expressions are same // - if (right_unwrap != null && !left.Equals (right)) { - right_unwrap.EmitCheck (ec); - ec.Emit (OpCodes.Brfalse, is_null_label); + if (UnwrapRight != null && !Binary.Left.Equals (Binary.Right)) { + UnwrapRight.EmitCheck (ec); + if (UnwrapLeft != null) { + ec.Emit (OpCodes.And); + } } - EmitOperator (ec, left.Type); + ec.Emit (OpCodes.Brfalse, is_null_label); + + if (UserOperator != null) { + var args = new Arguments (2); + args.Add (new Argument (Left)); + args.Add (new Argument (Right)); + + var call = new CallEmitter (); + call.EmitPredefined (ec, UserOperator, args); + } else { + Binary.EmitOperator (ec, Left, Right); + } - if (wrap_ctor != null) - ec.Emit (OpCodes.Newobj, wrap_ctor); + // + // Wrap the result when the operator return type is nullable type + // + if (type.IsNullableType) + ec.Emit (OpCodes.Newobj, NullableInfo.GetConstructor (type)); ec.Emit (OpCodes.Br_S, end_label); ec.MarkLabel (is_null_label); - if ((Oper & Operator.ComparisonMask) != 0) { + if ((Binary.Oper & Binary.Operator.ComparisonMask) != 0) { ec.EmitInt (0); } else { LiftedNull.Create (type, loc).Emit (ec); @@ -829,170 +766,289 @@ namespace Mono.CSharp.Nullable ec.MarkLabel (end_label); } - protected override void EmitOperator (EmitContext ec, TypeSpec l) + void EmitBitwiseBoolean (EmitContext ec) { - if (user_operator != null) { - user_operator.Emit (ec); - return; - } + Label load_left = ec.DefineLabel (); + Label load_right = ec.DefineLabel (); + Label end_label = ec.DefineLabel (); + Label is_null_label = ec.DefineLabel (); - if (left.Type.IsNullableType) { - l = NullableInfo.GetUnderlyingType (left.Type); - left = EmptyCast.Create (left, l); - } + bool or = Binary.Oper == Binary.Operator.BitwiseOr; - if (right.Type.IsNullableType) { - right = EmptyCast.Create (right, NullableInfo.GetUnderlyingType (right.Type)); - } + // + // Both operands are bool? types + // + if (UnwrapLeft != null && UnwrapRight != null) { + if (ec.HasSet (BuilderContext.Options.AsyncBody) && Binary.Right.ContainsEmitWithAwait ()) { + Left = Left.EmitToField (ec); + Right = Right.EmitToField (ec); + } else { + UnwrapLeft.Store (ec); + UnwrapRight.Store (ec); + } - base.EmitOperator (ec, l); - } + Left.Emit (ec); + ec.Emit (OpCodes.Brtrue_S, load_right); - Expression LiftResult (ResolveContext ec, Expression res_expr) - { - TypeSpec lifted_type; + Right.Emit (ec); + ec.Emit (OpCodes.Brtrue_S, load_left); - // - // Avoid double conversion - // - if (left_unwrap == null || IsLeftNullLifted || left_unwrap.Type != left.Type || (left_unwrap != null && IsRightNullLifted)) { - lifted_type = new NullableType (left.Type, loc).ResolveAsType (ec); - if (lifted_type == null) - return null; + UnwrapLeft.EmitCheck (ec); + ec.Emit (OpCodes.Brfalse_S, load_right); - if (left is UserCast || left is EmptyCast || left is OpcodeCast) - left.Type = lifted_type; + // load left + ec.MarkLabel (load_left); + if (or) + UnwrapRight.Load (ec); else - left = EmptyCast.Create (left, lifted_type); - } + UnwrapLeft.Load (ec); - if (left != right && (right_unwrap == null || IsRightNullLifted || right_unwrap.Type != right.Type || (right_unwrap != null && IsLeftNullLifted))) { - lifted_type = new NullableType (right.Type, loc).ResolveAsType (ec); - if (lifted_type == null) - return null; - - var r = right; - if (r is ReducedExpression) - r = ((ReducedExpression) r).OriginalExpression; + ec.Emit (OpCodes.Br_S, end_label); - if (r is UserCast || r is EmptyCast || r is OpcodeCast) - r.Type = lifted_type; + // load right + ec.MarkLabel (load_right); + if (or) + UnwrapLeft.Load (ec); else - right = EmptyCast.Create (right, lifted_type); + UnwrapRight.Load (ec); + + ec.MarkLabel (end_label); + return; } - if ((Oper & Operator.ComparisonMask) == 0) { - lifted_type = new NullableType (res_expr.Type, loc).ResolveAsType (ec); - if (lifted_type == null) - return null; + // + // Faster version when one operand is bool + // + if (UnwrapLeft == null) { + // + // (bool, bool?) + // + // Optimizes remaining (false & bool?), (true | bool?) which are not easy to handle + // in binary expression reduction + // + var c = Left as BoolConstant; + if (c != null) { + // Keep evaluation order + UnwrapRight.Store (ec); + + ec.EmitInt (or ? 1 : 0); + ec.Emit (OpCodes.Newobj, NullableInfo.GetConstructor (type)); + } else if (Left.IsNull) { + UnwrapRight.Emit (ec); + ec.Emit (or ? OpCodes.Brfalse_S : OpCodes.Brtrue_S, is_null_label); + + UnwrapRight.Load (ec); + ec.Emit (OpCodes.Br_S, end_label); + + ec.MarkLabel (is_null_label); + LiftedNull.Create (type, loc).Emit (ec); + } else { + Left.Emit (ec); + ec.Emit (or ? OpCodes.Brfalse_S : OpCodes.Brtrue_S, load_right); - wrap_ctor = NullableInfo.GetConstructor (lifted_type); - type = res_expr.Type = lifted_type; - } + ec.EmitInt (or ? 1 : 0); + ec.Emit (OpCodes.Newobj, NullableInfo.GetConstructor (type)); - if (IsLeftNullLifted) { - left = LiftedNull.Create (right.Type, left.Location); + ec.Emit (OpCodes.Br_S, end_label); + ec.MarkLabel (load_right); + UnwrapRight.Original.Emit (ec); + } + } else { // - // Special case for bool?, the result depends on both null right side and left side value + // (bool?, bool) // - if ((Oper == Operator.BitwiseAnd || Oper == Operator.BitwiseOr) && NullableInfo.GetUnderlyingType (type).BuiltinType == BuiltinTypeSpec.Type.Bool) { - return res_expr; - } - - if ((Oper & (Operator.ArithmeticMask | Operator.ShiftMask | Operator.BitwiseMask)) != 0) - return LiftedNull.CreateFromExpression (ec, res_expr); + // Keep left-right evaluation order + UnwrapLeft.Store (ec); // - // Value types and null comparison + // Optimizes remaining (bool? & false), (bool? | true) which are not easy to handle + // in binary expression reduction // - if (right_unwrap == null || (Oper & Operator.RelationalMask) != 0) - return CreateNullConstant (ec, right_orig); + var c = Right as BoolConstant; + if (c != null) { + ec.EmitInt (or ? 1 : 0); + ec.Emit (OpCodes.Newobj, NullableInfo.GetConstructor (type)); + } else if (Right.IsNull) { + UnwrapLeft.Emit (ec); + ec.Emit (or ? OpCodes.Brfalse_S : OpCodes.Brtrue_S, is_null_label); + + UnwrapLeft.Load (ec); + ec.Emit (OpCodes.Br_S, end_label); + + ec.MarkLabel (is_null_label); + LiftedNull.Create (type, loc).Emit (ec); + } else { + Right.Emit (ec); + ec.Emit (or ? OpCodes.Brfalse_S : OpCodes.Brtrue_S, load_right); + + ec.EmitInt (or ? 1 : 0); + ec.Emit (OpCodes.Newobj, NullableInfo.GetConstructor (type)); + + ec.Emit (OpCodes.Br_S, end_label); + + ec.MarkLabel (load_right); + + UnwrapLeft.Load (ec); + } } - if (IsRightNullLifted) { - right = LiftedNull.Create (left.Type, right.Location); + ec.MarkLabel (end_label); + } + // + // Emits optimized equality or inequality operator when possible + // + void EmitEquality (EmitContext ec) + { + // + // Either left or right is null + // + if (UnwrapLeft != null && Binary.Right.IsNull) { // TODO: Optimize for EmitBranchable // - // Special case for bool?, the result depends on both null right side and left side value + // left.HasValue == false // - if ((Oper == Operator.BitwiseAnd || Oper == Operator.BitwiseOr) && NullableInfo.GetUnderlyingType (type).BuiltinType == BuiltinTypeSpec.Type.Bool) { - return res_expr; + UnwrapLeft.EmitCheck (ec); + if (Binary.Oper == Binary.Operator.Equality) { + ec.EmitInt (0); + ec.Emit (OpCodes.Ceq); } + return; + } - if ((Oper & (Operator.ArithmeticMask | Operator.ShiftMask | Operator.BitwiseMask)) != 0) - return LiftedNull.CreateFromExpression (ec, res_expr); - + if (UnwrapRight != null && Binary.Left.IsNull) { // - // Value types and null comparison + // right.HasValue == false // - if (left_unwrap == null || (Oper & Operator.RelationalMask) != 0) - return CreateNullConstant (ec, left_orig); + UnwrapRight.EmitCheck (ec); + if (Binary.Oper == Binary.Operator.Equality) { + ec.EmitInt (0); + ec.Emit (OpCodes.Ceq); + } + return; } - return res_expr; - } + Label dissimilar_label = ec.DefineLabel (); + Label end_label = ec.DefineLabel (); - protected override Expression ResolveOperatorPredefined (ResolveContext ec, Binary.PredefinedOperator [] operators, bool primitives_only, TypeSpec enum_type) - { - Expression e = base.ResolveOperatorPredefined (ec, operators, primitives_only, enum_type); + if (UserOperator != null) { + var left = Left; - if (e == this || enum_type != null) - return LiftResult (ec, e); + if (UnwrapLeft != null) { + UnwrapLeft.EmitCheck (ec); + } else { + // Keep evaluation order same + if (!(Left is VariableReference)) { + Left.Emit (ec); + var lt = new LocalTemporary (Left.Type); + lt.Store (ec); + left = lt; + } + } - // - // 7.9.9 Equality operators and null - // - // The == and != operators permit one operand to be a value of a nullable type and - // the other to be the null literal, even if no predefined or user-defined operator - // (in unlifted or lifted form) exists for the operation. - // - if (e == null && (Oper & Operator.EqualityMask) != 0) { - if ((IsLeftNullLifted && right_unwrap != null) || (IsRightNullLifted && left_unwrap != null)) - return LiftResult (ec, this); - } + if (UnwrapRight != null) { + UnwrapRight.EmitCheck (ec); - return e; - } + if (UnwrapLeft != null) { + ec.Emit (OpCodes.Bne_Un, dissimilar_label); - protected override Expression ResolveUserOperator (ResolveContext ec, Expression left, Expression right) - { - // - // Try original types first for exact match without unwrapping - // - Expression expr = base.ResolveUserOperator (ec, left_orig, right_orig); - if (expr != null) - return expr; + Label compare_label = ec.DefineLabel (); + UnwrapLeft.EmitCheck (ec); + ec.Emit (OpCodes.Brtrue, compare_label); - State orig_state = state; + if (Binary.Oper == Binary.Operator.Equality) + ec.EmitInt (1); + else + ec.EmitInt (0); - // - // One side is a nullable type, try to match underlying types - // - if (left_unwrap != null || right_unwrap != null || (state & (State.RightNullLifted | State.LeftNullLifted)) != 0) { - expr = base.ResolveUserOperator (ec, left, right); + ec.Emit (OpCodes.Br, end_label); + + ec.MarkLabel (compare_label); + } else { + ec.Emit (OpCodes.Brfalse, dissimilar_label); + } + } else { + ec.Emit (OpCodes.Brfalse, dissimilar_label); + } + + var args = new Arguments (2); + args.Add (new Argument (left)); + args.Add (new Argument (Right)); + + var call = new CallEmitter (); + call.EmitPredefined (ec, UserOperator, args); + } else { + if (ec.HasSet (BuilderContext.Options.AsyncBody) && Binary.Right.ContainsEmitWithAwait ()) { + Left = Left.EmitToField (ec); + Right = Right.EmitToField (ec); + } + + // + // Emit underlying value comparison first. + // + // For this code: int? a = 1; bool b = a == 1; + // + // We emit something similar to this. Expressions with side effects have local + // variable created by Unwrap expression + // + // left.GetValueOrDefault () + // right + // bne.un.s dissimilar_label + // left.HasValue + // br.s end_label + // dissimilar_label: + // ldc.i4.0 + // end_label: + // + + Left.Emit (ec); + Right.Emit (ec); + + ec.Emit (OpCodes.Bne_Un_S, dissimilar_label); + + // + // Check both left and right expressions for Unwrap call in which + // case we need to run get_HasValue() check because the type is + // nullable and could have null value + // + if (UnwrapLeft != null) + UnwrapLeft.EmitCheck (ec); + + if (UnwrapRight != null) + UnwrapRight.EmitCheck (ec); + + if (UnwrapLeft != null && UnwrapRight != null) { + if (Binary.Oper == Binary.Operator.Inequality) + ec.Emit (OpCodes.Xor); + else + ec.Emit (OpCodes.Ceq); + } else { + if (Binary.Oper == Binary.Operator.Inequality) { + ec.EmitInt (0); + ec.Emit (OpCodes.Ceq); + } + } } - if (expr == null) - return null; + ec.Emit (OpCodes.Br_S, end_label); - // - // Lift the result in the case it can be null and predefined or user operator - // result type is of a value type - // - if (!TypeSpec.IsValueType (expr.Type)) - return null; + ec.MarkLabel (dissimilar_label); + if (Binary.Oper == Binary.Operator.Inequality) + ec.EmitInt (1); + else + ec.EmitInt (0); - if (state != orig_state) - return expr; + ec.MarkLabel (end_label); + } - expr = LiftResult (ec, expr); - if (expr is Constant) - return expr; + public override void FlowAnalysis (FlowAnalysisContext fc) + { + Binary.FlowAnalysis (fc); + } - type = expr.Type; - user_operator = expr; - return this; + public override SLE.Expression MakeExpression (BuilderContext ctx) + { + return Binary.MakeExpression (ctx, Left, Right); } } @@ -1102,41 +1158,40 @@ namespace Mono.CSharp.Nullable // Constant lc = left as Constant; if (lc != null && !lc.IsDefaultValue) - return ReducedExpression.Create (lc, this); + return ReducedExpression.Create (lc, this, false); // // Reduce (left ?? null) to left OR (null-constant ?? right) to right // - if (right.IsNull || lc != null) - return ReducedExpression.Create (lc != null ? right : left, this); + if (right.IsNull || lc != null) { + // + // Special case null ?? null + // + if (right.IsNull && ltype == right.Type) + return null; + + return ReducedExpression.Create (lc != null ? right : left, this, false); + } right = Convert.ImplicitConversion (ec, right, ltype, loc); type = ltype; return this; } - - // - // Special case null ?? null - // - if (ltype == right.Type) { - type = ltype; - return this; - } } else { return null; } TypeSpec rtype = right.Type; - if (!Convert.ImplicitConversionExists (ec, unwrap != null ? unwrap : left, rtype) || right.eclass == ExprClass.MethodGroup) + if (!Convert.ImplicitConversionExists (ec, unwrap ?? left, rtype) || right.eclass == ExprClass.MethodGroup) return null; // // Reduce (null ?? right) to right // if (left.IsNull) - return ReducedExpression.Create (right, this).Resolve (ec); + return ReducedExpression.Create (right, this, false).Resolve (ec); - left = Convert.ImplicitConversion (ec, unwrap != null ? unwrap : left, rtype, loc); + left = Convert.ImplicitConversion (ec, unwrap ?? left, rtype, loc); type = rtype; return this; } @@ -1178,7 +1233,15 @@ namespace Mono.CSharp.Nullable unwrap.EmitCheck (ec); ec.Emit (OpCodes.Brfalse, is_null_label); - left.Emit (ec); + // + // When both expressions are nullable the unwrap + // is needed only for null check not for value uwrap + // + if (type.IsNullableType && TypeSpecComparer.IsEqual (NullableInfo.GetUnderlyingType (type), unwrap.Type)) + unwrap.Load (ec); + else + left.Emit (ec); + ec.Emit (OpCodes.Br, end_label); ec.MarkLabel (is_null_label); @@ -1203,6 +1266,14 @@ namespace Mono.CSharp.Nullable ec.MarkLabel (end_label); } + public override void FlowAnalysis (FlowAnalysisContext fc) + { + left.FlowAnalysis (fc); + var left_da = fc.BranchDefiniteAssignment (); + right.FlowAnalysis (fc); + fc.DefiniteAssignment = left_da; + } + protected override void CloneTo (CloneContext clonectx, Expression t) { NullCoalescingOperator target = (NullCoalescingOperator) t; @@ -1256,7 +1327,7 @@ namespace Mono.CSharp.Nullable call = new CallEmitter (); call.InstanceExpression = lt; - call.EmitPredefined (ec, NullableInfo.GetValue (expr.Type), null); + call.EmitPredefined (ec, NullableInfo.GetGetValueOrDefault (expr.Type), null); lt.Release (ec); diff --git a/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/outline.cs b/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/outline.cs index 7f21b8c4d..1104b1c11 100644 --- a/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/outline.cs +++ b/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/outline.cs @@ -29,8 +29,6 @@ // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // -#if !NET_2_1 - using System; using System.Reflection; using System.Collections; @@ -90,7 +88,9 @@ 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 { if (underlyingType != typeof (int)) o.Write (" : {0}", FormatType (underlyingType)); } - +#if NET_2_0 WriteGenericConstraints (t.GetGenericArguments ()); - +#endif o.WriteLine (" {"); o.Indent++; @@ -396,11 +396,15 @@ 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 (";"); } @@ -559,6 +563,7 @@ public class Outline { } } +#if NET_2_0 string FormatGenericParams (Type [] args) { StringBuilder sb = new StringBuilder (); @@ -574,6 +579,7 @@ 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. @@ -673,7 +679,9 @@ 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) @@ -685,10 +693,12 @@ 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); @@ -706,6 +716,7 @@ public class Outline { GetTypeName (sb, t); } +#if NET_2_0 void WriteGenericConstraints (Type [] args) { @@ -761,6 +772,7 @@ public class Outline { } } } +#endif string OperatorFromName (string name) { @@ -1024,5 +1036,3 @@ public class Comparer : IComparer { } } } - -#endif \ No newline at end of file diff --git a/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/parameter.cs b/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/parameter.cs index 365f876f0..f1215173c 100644 --- a/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/parameter.cs +++ b/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/parameter.cs @@ -223,6 +223,7 @@ namespace Mono.CSharp { } static readonly string[] attribute_targets = new string[] { "param" }; + static readonly string[] attribute_targets_primary = new string[] { "param", "field" }; FullNamedExpression texpr; Modifier modFlags; @@ -233,6 +234,7 @@ namespace Mono.CSharp { protected int idx; public bool HasAddressTaken; + Constructor primary_constructor; TemporaryVariableReference expr_tree_variable; HoistedParameter hoisted_variant; @@ -307,7 +309,7 @@ namespace Mono.CSharp { public override string[] ValidAttributeTargets { get { - return attribute_targets; + return primary_constructor != null ? attribute_targets_primary : attribute_targets; } } @@ -315,6 +317,12 @@ namespace Mono.CSharp { public override void ApplyAttributeBuilder (Attribute a, MethodSpec ctor, byte[] cdata, PredefinedAttributes pa) { + if (a.Target == AttributeTargets.Field) { + var field = MemberCache.FindMember (primary_constructor.Spec.DeclaringType, MemberFilter.Field (name, parameter_type), BindingRestriction.DeclaredOnly); + ((Field)field.MemberDefinition).ApplyAttributeBuilder (a, ctor, cdata, pa); + return; + } + if (a.Type == pa.In && ModFlags == Modifier.OUT) { a.Report.Error (36, a.Location, "An out parameter cannot have the `In' attribute"); return; @@ -338,7 +346,7 @@ namespace Mono.CSharp { if (HasOptionalExpression) { a.Report.Error (1745, a.Location, "Cannot specify `{0}' attribute on optional parameter `{1}'", - TypeManager.CSharpName (a.Type).Replace ("Attribute", ""), Name); + a.Type.GetSignatureForError ().Replace ("Attribute", ""), Name); } if (a.Type == pa.DefaultParameterValue) @@ -371,6 +379,15 @@ namespace Mono.CSharp { return member.IsAccessibleAs (parameter_type); } + bool IsValidCallerContext (MemberCore memberContext) + { + var m = memberContext as Method; + if (m != null) + return !m.IsPartialImplementation; + + return true; + } + // // Resolve is used in method definitions // @@ -382,6 +399,10 @@ namespace Mono.CSharp { if (attributes != null) attributes.AttachTo (this, rc); + var ctor = rc.CurrentMemberDefinition as Constructor; + if (ctor != null && ctor.IsPrimaryConstructor) + primary_constructor = ctor; + parameter_type = texpr.ResolveAsType (rc); if (parameter_type == null) return null; @@ -394,7 +415,7 @@ namespace Mono.CSharp { return null; } - TypeManager.CheckTypeVariance (parameter_type, + VarianceDecl.CheckTypeVariance (parameter_type, (modFlags & Parameter.Modifier.RefOutMask) != 0 ? Variance.None : Variance.Contravariant, rc); @@ -406,7 +427,7 @@ namespace Mono.CSharp { if ((modFlags & Modifier.This) != 0 && (parameter_type.IsPointer || parameter_type.BuiltinType == BuiltinTypeSpec.Type.Dynamic)) { rc.Module.Compiler.Report.Error (1103, Location, "The extension method cannot be of type `{0}'", - TypeManager.CSharpName (parameter_type)); + parameter_type.GetSignatureForError ()); } return parameter_type; @@ -416,9 +437,10 @@ namespace Mono.CSharp { { var pa = rc.Module.PredefinedAttributes; TypeSpec caller_type; + Attribute callerMemberName = null, callerFilePath = null; foreach (var attr in attributes.Attrs) { - var atype = attr.ResolveType (); + var atype = attr.ResolveTypeForComparison (); if (atype == null) continue; @@ -430,7 +452,14 @@ namespace Mono.CSharp { caller_type.GetSignatureForError (), parameter_type.GetSignatureForError ()); } + if (!IsValidCallerContext (rc.CurrentMemberDefinition)) { + rc.Report.Warning (4026, 1, attr.Location, + "The CallerMemberName applied to parameter `{0}' will have no effect because it applies to a member that is used in context that do not allow optional arguments", + name); + } + modFlags |= Modifier.CallerMemberName; + callerMemberName = attr; continue; } @@ -438,10 +467,16 @@ namespace Mono.CSharp { caller_type = rc.BuiltinTypes.Int; if (caller_type != parameter_type && !Convert.ImplicitNumericConversionExists (caller_type, parameter_type)) { rc.Report.Error (4017, attr.Location, - "The CallerMemberName attribute cannot be applied because there is no standard conversion from `{0}' to `{1}'", + "The CallerLineNumberAttribute attribute cannot be applied because there is no standard conversion from `{0}' to `{1}'", caller_type.GetSignatureForError (), parameter_type.GetSignatureForError ()); } + if (!IsValidCallerContext (rc.CurrentMemberDefinition)) { + rc.Report.Warning (4024, 1, attr.Location, + "The CallerLineNumberAttribute applied to parameter `{0}' will have no effect because it applies to a member that is used in context that do not allow optional arguments", + name); + } + modFlags |= Modifier.CallerLineNumber; continue; } @@ -454,10 +489,40 @@ namespace Mono.CSharp { caller_type.GetSignatureForError (), parameter_type.GetSignatureForError ()); } + if (!IsValidCallerContext (rc.CurrentMemberDefinition)) { + rc.Report.Warning (4025, 1, attr.Location, + "The CallerFilePath applied to parameter `{0}' will have no effect because it applies to a member that is used in context that do not allow optional arguments", + name); + } + modFlags |= Modifier.CallerFilePath; + callerFilePath = attr; continue; } } + + if ((modFlags & Modifier.CallerLineNumber) != 0) { + if (callerMemberName != null) { + rc.Report.Warning (7081, 1, callerMemberName.Location, + "The CallerMemberNameAttribute applied to parameter `{0}' will have no effect. It is overridden by the CallerLineNumberAttribute", + Name); + } + + if (callerFilePath != null) { + rc.Report.Warning (7082, 1, callerFilePath.Location, + "The CallerFilePathAttribute applied to parameter `{0}' will have no effect. It is overridden by the CallerLineNumberAttribute", + name); + } + } + + if ((modFlags & Modifier.CallerMemberName) != 0) { + if (callerFilePath != null) { + rc.Report.Warning (7080, 1, callerFilePath.Location, + "The CallerMemberNameAttribute applied to parameter `{0}' will have no effect. It is overridden by the CallerFilePathAttribute", + name); + } + + } } public void ResolveDefaultValue (ResolveContext rc) @@ -501,7 +566,7 @@ namespace Mono.CSharp { } else { rc.Report.Error (1909, default_expr.Location, "The DefaultParameterValue attribute is not applicable on parameters of type `{0}'", - default_expr.Type.GetSignatureForError ()); ; + default_expr.Type.GetSignatureForError ()); } default_expr = null; @@ -582,7 +647,7 @@ namespace Mono.CSharp { { string type_name; if (parameter_type != null) - type_name = TypeManager.CSharpName (parameter_type); + type_name = parameter_type.GetSignatureForError (); else type_name = texpr.GetSignatureForError (); @@ -635,7 +700,7 @@ namespace Mono.CSharp { if (OptAttributes != null) OptAttributes.Emit (); - if (HasDefaultValue) { + if (HasDefaultValue && default_expr.Type != null) { // // Emit constant values for true constants only, the other // constant-like expressions will rely on default value expression @@ -648,9 +713,9 @@ namespace Mono.CSharp { } else { builder.SetConstant (c.GetValue ()); } - } else if (default_expr.Type.IsStruct) { + } else if (default_expr.Type.IsStruct || default_expr.Type.IsGenericParameter) { // - // Handles special case where default expression is used with value-type + // Handles special case where default expression is used with value-type or type parameter // // void Foo (S s = default (S)) {} // @@ -932,9 +997,14 @@ namespace Mono.CSharp { if (inflated_param == types[i]) continue; - default_value |= FixedParameters[i] is DefaultValueExpression; + default_value |= FixedParameters[i].HasDefaultValue; inflated_types = new TypeSpec[types.Length]; - Array.Copy (types, inflated_types, types.Length); + Array.Copy (types, inflated_types, types.Length); + } else { + if (inflated_param == types[i]) + continue; + + default_value |= FixedParameters[i].HasDefaultValue; } inflated_types[i] = inflated_param; @@ -945,13 +1015,42 @@ namespace Mono.CSharp { var clone = (AParametersCollection) MemberwiseClone (); clone.types = inflated_types; + + // + // Default expression is original expression from the parameter + // declaration context which can be of nested enum in generic class type. + // In such case we end up with expression type of G.E and e.g. parameter + // type of G.E and conversion would fail without inflate in this + // context. + // if (default_value) { + clone.parameters = new IParameterData[Count]; for (int i = 0; i < Count; ++i) { - var dve = clone.FixedParameters[i] as DefaultValueExpression; - if (dve != null) { - throw new NotImplementedException ("net"); - // clone.FixedParameters [i].DefaultValue = new DefaultValueExpression (); - } + var fp = FixedParameters[i]; + clone.FixedParameters[i] = fp; + + if (!fp.HasDefaultValue) + continue; + + var expr = fp.DefaultValue; + + if (inflated_types[i] == expr.Type) + continue; + + var c = expr as Constant; + if (c != null) { + // + // It may fail we are inflating before type validation is done + // + c = Constant.ExtractConstantFromValue (inflated_types[i], c.GetValue (), expr.Location); + if (c == null) + expr = new DefaultValueExpression (new TypeExpression (inflated_types[i], expr.Location), expr.Location); + else + expr = c; + } else if (expr is DefaultValueExpression) + expr = new DefaultValueExpression (new TypeExpression (inflated_types[i], expr.Location), expr.Location); + + clone.FixedParameters[i] = new ParameterData (fp.Name, fp.ModFlags, expr); } } @@ -963,11 +1062,11 @@ namespace Mono.CSharp { if (types == null || types [pos] == null) return ((Parameter)FixedParameters [pos]).GetSignatureForError (); - string type = TypeManager.CSharpName (types [pos]); + string type = types [pos].GetSignatureForError (); if (FixedParameters [pos].HasExtensionMethodModifier) return "this " + type; - Parameter.Modifier mod = FixedParameters [pos].ModFlags; + var mod = FixedParameters[pos].ModFlags & Parameter.Modifier.ModifierMask; if (mod == 0) return type; @@ -1299,16 +1398,13 @@ namespace Mono.CSharp { { } - protected override Expression DoResolve (ResolveContext rc) - { - return base.DoResolve (rc); - } - public void Resolve (ResolveContext rc, Parameter p) { var expr = Resolve (rc); - if (expr == null) + if (expr == null) { + this.expr = ErrorExpression.Instance; return; + } expr = Child; @@ -1352,6 +1448,8 @@ namespace Mono.CSharp { rc.Report.Error (1750, Location, "Optional parameter expression of type `{0}' cannot be converted to parameter type `{1}'", type.GetSignatureForError (), parameter_type.GetSignatureForError ()); + + this.expr = ErrorExpression.Instance; } public override object Accept (StructuralVisitor visitor) diff --git a/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/pending.cs b/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/pending.cs index b33128629..0f863a7bc 100644 --- a/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/pending.cs +++ b/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/pending.cs @@ -192,17 +192,17 @@ namespace Mono.CSharp { static MissingInterfacesInfo [] GetMissingInterfaces (TypeDefinition container) { // - // Notice that Interfaces will only return the interfaces that the Type - // is supposed to implement, not all the interfaces that the type implements. + // Interfaces will return all interfaces that the container + // implements including any inherited interfaces // var impl = container.Definition.Interfaces; if (impl == null || impl.Count == 0) return EmptyMissingInterfacesInfo; - MissingInterfacesInfo[] ret = new MissingInterfacesInfo[impl.Count]; + var ret = new MissingInterfacesInfo[impl.Count]; - for (int i = 0; i < impl.Count; i++) + for (int i = 0; i < ret.Length; i++) ret [i] = new MissingInterfacesInfo (impl [i]); // we really should not get here because Object doesnt implement any @@ -534,10 +534,14 @@ namespace Mono.CSharp { // about mismatch at return type when the check bellow rejects them // var parameters = mi.Parameters; + MethodSpec close_match = null; + while (true) { var candidates = MemberCache.FindMembers (base_type, mi.Name, false); - if (candidates == null) + if (candidates == null) { + base_method = close_match; return false; + } MethodSpec similar_candidate = null; foreach (var candidate in candidates) { @@ -548,7 +552,7 @@ namespace Mono.CSharp { continue; var candidate_param = ((MethodSpec) candidate).Parameters; - if (!TypeSpecComparer.Override.IsSame (parameters.Types, candidate_param.Types)) + if (!TypeSpecComparer.Override.IsEqual (parameters.Types, candidate_param.Types)) continue; bool modifiers_match = true; @@ -587,22 +591,32 @@ namespace Mono.CSharp { continue; // - // From this point on the candidate is used for detailed error reporting + // From this point the candidate is used for detailed error reporting // because it's very close match to what we are looking for // - base_method = (MethodSpec) candidate; + var m = (MethodSpec) candidate; + + if (!m.IsPublic) { + if (close_match == null) + close_match = m; - if (!candidate.IsPublic) - return false; + continue; + } - if (!TypeSpecComparer.Override.IsEqual (mi.ReturnType, base_method.ReturnType)) - return false; + if (!TypeSpecComparer.Override.IsEqual (mi.ReturnType, m.ReturnType)) { + if (close_match == null) + close_match = m; - if (mi.IsGeneric && !Method.CheckImplementingMethodConstraints (container, base_method, mi)) { + continue; + } + + base_method = m; + + if (mi.IsGeneric && !Method.CheckImplementingMethodConstraints (container, m, mi)) { return true; } } - + if (base_method != null) { if (similar_candidate != null) { Report.SymbolRelatedToPreviousError (similar_candidate); @@ -617,8 +631,10 @@ namespace Mono.CSharp { } base_type = candidates[0].DeclaringType.BaseType; - if (base_type == null) + if (base_type == null) { + base_method = close_match; return false; + } } if (!base_method.IsVirtual) { @@ -673,7 +689,7 @@ namespace Mono.CSharp { if (pending_implementations [i].optional) continue; - MethodSpec candidate = null; + MethodSpec candidate; if (base_implements_type || BaseImplements (type, mi, out candidate)) continue; @@ -692,7 +708,7 @@ namespace Mono.CSharp { container.GetSignatureForError (), mi.GetSignatureForError (), candidate.GetSignatureForError ()); } else if ((candidate.Modifiers & Modifiers.PUBLIC) == 0) { Report.Error (737, container.Location, - "`{0}' does not implement interface member `{1}' and the best implementing candidate `{2}' in not public", + "`{0}' does not implement interface member `{1}' and the best implementing candidate `{2}' is not public", container.GetSignatureForError (), mi.GetSignatureForError (), candidate.GetSignatureForError ()); } else { Report.Error (738, container.Location, diff --git a/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/property.cs b/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/property.cs index 067c0c5f2..b27566e02 100644 --- a/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/property.cs +++ b/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/property.cs @@ -35,7 +35,7 @@ namespace Mono.CSharp // This includes properties, indexers, and events public abstract class PropertyBasedMember : InterfaceMemberBase { - public PropertyBasedMember (TypeDefinition parent, FullNamedExpression type, Modifiers mod, Modifiers allowed_mod, MemberName name, Attributes attrs) + protected PropertyBasedMember (TypeDefinition parent, FullNamedExpression type, Modifiers mod, Modifiers allowed_mod, MemberName name, Attributes attrs) : base (parent, type, mod, allowed_mod, name, attrs) { } @@ -82,6 +82,8 @@ namespace Mono.CSharp } } + public abstract void PrepareEmit (); + protected override bool VerifyClsCompliance () { if (!base.VerifyClsCompliance ()) @@ -174,9 +176,9 @@ namespace Mono.CSharp return ps; } - public override List ResolveMissingDependencies () + public override List ResolveMissingDependencies (MemberSpec caller) { - return memberType.ResolveMissingDependencies (); + return memberType.ResolveMissingDependencies (this); } } @@ -197,20 +199,15 @@ namespace Mono.CSharp { } - public override MethodBuilder Define (TypeContainer parent) + public override void Define (TypeContainer parent) { base.Define (parent); - Spec = new MethodSpec (MemberKind.Method, parent.PartialContainer.Definition, this, ReturnType, null, ParameterInfo, ModFlags); + Spec = new MethodSpec (MemberKind.Method, parent.PartialContainer.Definition, this, ReturnType, ParameterInfo, ModFlags); method_data = new MethodData (method, ModFlags, flags, this); - if (!method_data.Define (parent.PartialContainer, method.GetFullName (MemberName))) - return null; - - Spec.SetMetaInfo (method_data.MethodBuilder); - - return method_data.MethodBuilder; + method_data.Define (parent.PartialContainer, method.GetFullName (MemberName)); } public override TypeSpec ReturnType { @@ -253,7 +250,7 @@ namespace Mono.CSharp return; } - base.ApplyAttributeBuilder (a, ctor, cdata, pa); + base.ApplyToExtraTarget (a, ctor, cdata, pa); } public override ParametersCompiled ParameterInfo { @@ -262,22 +259,17 @@ namespace Mono.CSharp } } - public override MethodBuilder Define (TypeContainer parent) + public override void Define (TypeContainer parent) { parameters.Resolve (this); base.Define (parent); - Spec = new MethodSpec (MemberKind.Method, parent.PartialContainer.Definition, this, ReturnType, null, ParameterInfo, ModFlags); + Spec = new MethodSpec (MemberKind.Method, parent.PartialContainer.Definition, this, ReturnType, ParameterInfo, ModFlags); method_data = new MethodData (method, ModFlags, flags, this); - if (!method_data.Define (parent.PartialContainer, method.GetFullName (MemberName))) - return null; - - Spec.SetMetaInfo (method_data.MethodBuilder); - - return method_data.MethodBuilder; + method_data.Define (parent.PartialContainer, method.GetFullName (MemberName)); } public override TypeSpec ReturnType { @@ -334,7 +326,7 @@ namespace Mono.CSharp return method.IsClsComplianceRequired (); } - public virtual MethodBuilder Define (TypeContainer parent) + public virtual void Define (TypeContainer parent) { var container = parent.PartialContainer; @@ -369,8 +361,6 @@ namespace Mono.CSharp if (Compiler.Settings.WriteMetadataOnly) block = null; } - - return null; } public bool HasCustomAccessModifier { @@ -408,7 +398,7 @@ namespace Mono.CSharp PropertyMethod get, set, first; PropertyBuilder PropertyBuilder; - public PropertyBase (TypeDefinition parent, FullNamedExpression type, Modifiers mod_flags, Modifiers allowed_mod, MemberName name, Attributes attrs) + protected PropertyBase (TypeDefinition parent, FullNamedExpression type, Modifiers mod_flags, Modifiers allowed_mod, MemberName name, Attributes attrs) : base (parent, type, mod_flags, allowed_mod, name, attrs) { } @@ -522,7 +512,16 @@ namespace Mono.CSharp // Check base property accessors conflict // var base_prop = (PropertySpec) base_member; - if (Get != null) { + if (Get == null) { + if ((ModFlags & Modifiers.SEALED) != 0 && base_prop.HasGet && !base_prop.Get.IsAccessible (this)) { + // TODO: Should be different error code but csc uses for some reason same + Report.SymbolRelatedToPreviousError (base_prop); + Report.Error (545, Location, + "`{0}': cannot override because `{1}' does not have accessible get accessor", + GetSignatureForError (), base_prop.GetSignatureForError ()); + ok = false; + } + } else { if (!base_prop.HasGet) { if (ok) { Report.SymbolRelatedToPreviousError (base_prop); @@ -539,7 +538,16 @@ namespace Mono.CSharp } } - if (Set != null) { + if (Set == null) { + if ((ModFlags & Modifiers.SEALED) != 0 && base_prop.HasSet && !base_prop.Set.IsAccessible (this)) { + // TODO: Should be different error code but csc uses for some reason same + Report.SymbolRelatedToPreviousError (base_prop); + Report.Error (546, Location, + "`{0}': cannot override because `{1}' does not have accessible set accessor", + GetSignatureForError (), base_prop.GetSignatureForError ()); + ok = false; + } + } else { if (!base_prop.HasSet) { if (ok) { Report.SymbolRelatedToPreviousError (base_prop); @@ -624,24 +632,14 @@ namespace Mono.CSharp if (Get != null) { spec.Get = Get.Spec; - - var method = Get.Spec.GetMetaInfo () as MethodBuilder; - if (method != null) { - PropertyBuilder.SetGetMethod (method); - Parent.MemberCache.AddMember (this, method.Name, Get.Spec); - } + Parent.MemberCache.AddMember (this, Get.Spec.Name, Get.Spec); } else { CheckMissingAccessor (kind, parameters, true); } if (Set != null) { spec.Set = Set.Spec; - - var method = Set.Spec.GetMetaInfo () as MethodBuilder; - if (method != null) { - PropertyBuilder.SetSetMethod (method); - Parent.MemberCache.AddMember (this, method.Name, Set.Spec); - } + Parent.MemberCache.AddMember (this, Set.Spec.Name, Set.Spec); } else { CheckMissingAccessor (kind, parameters, false); } @@ -681,6 +679,25 @@ namespace Mono.CSharp } } + public override void PrepareEmit () + { + AccessorFirst.PrepareEmit (); + if (AccessorSecond != null) + AccessorSecond.PrepareEmit (); + + if (get != null) { + var method = Get.Spec.GetMetaInfo () as MethodBuilder; + if (method != null) + PropertyBuilder.SetGetMethod (method); + } + + if (set != null) { + var method = Set.Spec.GetMetaInfo () as MethodBuilder; + if (method != null) + PropertyBuilder.SetSetMethod (method); + } + } + protected override void SetMemberName (MemberName new_name) { base.SetMemberName (new_name); @@ -735,6 +752,10 @@ namespace Mono.CSharp } } + static readonly string[] attribute_target_auto = new string[] { "property", "field" }; + + Field backing_field; + public Property (TypeDefinition parent, FullNamedExpression type, Modifiers mod, MemberName name, Attributes attrs) : base (parent, type, mod, @@ -749,19 +770,28 @@ namespace Mono.CSharp { visitor.Visit (this); } - + + public override void ApplyAttributeBuilder (Attribute a, MethodSpec ctor, byte[] cdata, PredefinedAttributes pa) + { + if (a.Target == AttributeTargets.Field) { + backing_field.ApplyAttributeBuilder (a, ctor, cdata, pa); + return; + } + + base.ApplyAttributeBuilder (a, ctor, cdata, pa); + } void CreateAutomaticProperty () { // Create backing field - Field field = new BackingField (this); - if (!field.Define ()) + backing_field = new BackingField (this); + if (!backing_field.Define ()) return; - Parent.PartialContainer.Members.Add (field); + Parent.PartialContainer.Members.Add (backing_field); - FieldExpr fe = new FieldExpr (field, Location); - if ((field.ModFlags & Modifiers.STATIC) == 0) + FieldExpr fe = new FieldExpr (backing_field, Location); + if ((backing_field.ModFlags & Modifiers.STATIC) == 0) fe.InstanceExpression = new CompilerGeneratedThis (Parent.CurrentType, Location); // @@ -826,6 +856,13 @@ namespace Mono.CSharp base.Emit (); } + + public override string[] ValidAttributeTargets { + get { + return Get != null && ((Get.ModFlags & Modifiers.COMPILER_GENERATED) != 0) ? + attribute_target_auto : base.ValidAttributeTargets; + } + } } /// @@ -839,10 +876,10 @@ namespace Mono.CSharp { } - public override MethodBuilder Define (TypeContainer ds) + public override void Define (TypeContainer ds) { CheckAbstractAndExtern (block != null); - return base.Define (ds); + base.Define (ds); } public override string GetSignatureForError () @@ -1089,8 +1126,8 @@ namespace Mono.CSharp return false; if (declarators != null) { - if ((mod_flags_src & Modifiers.DEFAULT_ACCESS_MODIFER) != 0) - mod_flags_src &= ~(Modifiers.AccessibilityMask | Modifiers.DEFAULT_ACCESS_MODIFER); + if ((mod_flags_src & Modifiers.DEFAULT_ACCESS_MODIFIER) != 0) + mod_flags_src &= ~(Modifiers.AccessibilityMask | Modifiers.DEFAULT_ACCESS_MODIFIER); var t = new TypeExpression (MemberType, TypeExpression.Location); foreach (var d in declarators) { @@ -1109,9 +1146,6 @@ namespace Mono.CSharp return true; } - if (Add.IsInterfaceImplementation) - SetIsUsed (); - backing_field = new Field (Parent, new TypeExpression (MemberType, Location), Modifiers.BACKING_FIELD | Modifiers.COMPILER_GENERATED | Modifiers.PRIVATE | (ModFlags & (Modifiers.STATIC | Modifiers.UNSAFE)), @@ -1171,7 +1205,7 @@ namespace Mono.CSharp return; } - base.ApplyAttributeBuilder (a, ctor, cdata, pa); + base.ApplyToExtraTarget (a, ctor, cdata, pa); } public override AttributeTargets AttributeTargets { @@ -1185,7 +1219,7 @@ namespace Mono.CSharp return method.IsClsComplianceRequired (); } - public virtual MethodBuilder Define (TypeContainer parent) + public virtual void Define (TypeContainer parent) { // Fill in already resolved event type to speed things up and // avoid confusing duplicate errors @@ -1196,17 +1230,13 @@ namespace Mono.CSharp method.flags | MethodAttributes.HideBySig | MethodAttributes.SpecialName, this); if (!method_data.Define (parent.PartialContainer, method.GetFullName (MemberName))) - return null; + return; 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); + Spec = new MethodSpec (MemberKind.Method, parent.PartialContainer.Definition, this, ReturnType, ParameterInfo, method.ModFlags); Spec.IsAccessor = true; - - return mb; } public override TypeSpec ReturnType { @@ -1220,6 +1250,12 @@ namespace Mono.CSharp return method.GetAttributeObsolete (); } + public MethodData MethodData { + get { + return method_data; + } + } + public override string[] ValidAttributeTargets { get { return attribute_targets; @@ -1318,23 +1354,16 @@ namespace Mono.CSharp // // Now define the accessors // - var AddBuilder = Add.Define (Parent); - if (AddBuilder == null) - return false; - - var RemoveBuilder = remove.Define (Parent); - if (RemoveBuilder == null) - return false; + add.Define (Parent); + remove.Define (Parent); EventBuilder = Parent.TypeBuilder.DefineEvent (GetFullName (MemberName), EventAttributes.None, MemberType.GetMetaInfo ()); - EventBuilder.SetAddOnMethod (AddBuilder); - EventBuilder.SetRemoveOnMethod (RemoveBuilder); spec = new EventSpec (Parent.Definition, this, MemberType, ModFlags, Add.Spec, remove.Spec); Parent.MemberCache.AddMember (this, GetFullName (MemberName), spec); - Parent.MemberCache.AddMember (this, AddBuilder.Name, Add.Spec); - Parent.MemberCache.AddMember (this, RemoveBuilder.Name, remove.Spec); + Parent.MemberCache.AddMember (this, Add.Spec.Name, Add.Spec); + Parent.MemberCache.AddMember (this, Remove.Spec.Name, remove.Spec); return true; } @@ -1356,6 +1385,15 @@ namespace Mono.CSharp base.Emit (); } + public override void PrepareEmit () + { + add.PrepareEmit (); + remove.PrepareEmit (); + + EventBuilder.SetAddOnMethod (add.MethodData.MethodBuilder); + EventBuilder.SetRemoveOnMethod (remove.MethodData.MethodBuilder); + } + public override void WriteDebugSymbol (MonoSymbolFile file) { add.WriteDebugSymbol (file); @@ -1427,9 +1465,9 @@ namespace Mono.CSharp return es; } - public override List ResolveMissingDependencies () + public override List ResolveMissingDependencies (MemberSpec caller) { - return MemberType.ResolveMissingDependencies (); + return MemberType.ResolveMissingDependencies (this); } } @@ -1445,7 +1483,7 @@ namespace Mono.CSharp this.parameters = parameters; } - public override MethodBuilder Define (TypeContainer parent) + public override void Define (TypeContainer parent) { // Disable reporting, parameters are resolved twice Report.DisableReporting (); @@ -1455,7 +1493,7 @@ namespace Mono.CSharp Report.EnableReporting (); } - return base.Define (parent); + base.Define (parent); } public override ParametersCompiled ParameterInfo { @@ -1701,16 +1739,17 @@ namespace Mono.CSharp return spec; } - public override List ResolveMissingDependencies () + public override List ResolveMissingDependencies (MemberSpec caller) { - var missing = base.ResolveMissingDependencies (); + var missing = base.ResolveMissingDependencies (caller); + foreach (var pt in parameters.Types) { - var m = pt.GetMissingDependencies (); + var m = pt.GetMissingDependencies (caller); if (m == null) continue; if (missing == null) - missing = new List (); + missing = new List (); missing.AddRange (m); } diff --git a/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/reflection.cs b/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/reflection.cs index 2de023c18..b233b9439 100644 --- a/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/reflection.cs +++ b/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/reflection.cs @@ -83,7 +83,7 @@ namespace Mono.CSharp { // It can be used more than once when importing same assembly // into 2 or more global aliases - var definition = GetAssemblyDefinition (assembly); + GetAssemblyDefinition (assembly); // // This part tries to simulate loading of top-level @@ -98,7 +98,7 @@ namespace Mono.CSharp all_types = e.Types; } - ImportTypes (all_types, targetNamespace, definition.HasExtensionMethod); + ImportTypes (all_types, targetNamespace, true); } public ImportedModuleDefinition ImportModule (Module module, RootNamespace targetNamespace) @@ -219,7 +219,7 @@ namespace Mono.CSharp // public bool Create (AppDomain domain, AssemblyBuilderAccess access) { -#if STATIC +#if STATIC || FULL_AOT_RUNTIME throw new NotSupportedException (); #else ResolveAssemblySecurityAttributes (); @@ -547,4 +547,4 @@ namespace Mono.CSharp } } } -} \ No newline at end of file +} diff --git a/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/report.cs b/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/report.cs index b27b9c8a0..5ae47d8a0 100644 --- a/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/report.cs +++ b/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/report.cs @@ -56,7 +56,9 @@ namespace Mono.CSharp { 3000, 3001, 3002, 3003, 3005, 3006, 3007, 3008, 3009, 3010, 3011, 3012, 3013, 3014, 3015, 3016, 3017, 3018, 3019, 3021, 3022, 3023, 3024, 3026, 3027, - 4014 + 4014, 4024, 4025, 4026, + 7035, 7080, 7081, 7082, 7095, + 8009, }; static HashSet AllWarningsHashSet; @@ -550,6 +552,8 @@ namespace Mono.CSharp { // public abstract class ReportPrinter { + protected HashSet reported_missing_definitions; + #region Properties public int ErrorsCount { get; protected set; } @@ -605,6 +609,22 @@ namespace Mono.CSharp { } } + // + // Tracks reported missing types. It needs to be session specific + // because we can run in probing mode + // + public bool MissingTypeReported (ITypeDefinition typeDefinition) + { + if (reported_missing_definitions == null) + reported_missing_definitions = new HashSet (); + + if (reported_missing_definitions.Contains (typeDefinition)) + return true; + + reported_missing_definitions.Add (typeDefinition); + return false; + } + public void Reset () { // HACK: Temporary hack for broken repl flow @@ -649,7 +669,7 @@ namespace Mono.CSharp { // // This line is useful when debugging recorded messages // - // Console.WriteLine ("RECORDING: {0}", msg.ToString ()); + // Console.WriteLine ("RECORDING: {0}", msg.Text); if (session_messages == null) session_messages = new List (); @@ -735,6 +755,11 @@ namespace Mono.CSharp { error_msg |= !msg.IsWarning; } + if (reported_missing_definitions != null) { + foreach (var missing in reported_missing_definitions) + dest.MissingTypeReported (missing); + } + return error_msg; } } @@ -931,7 +956,7 @@ namespace Mono.CSharp { if (timers == null) return; - Dictionary timer_names = new Dictionary () { + Dictionary timer_names = new Dictionary { { TimerType.ParseTotal, "Parsing source files" }, { TimerType.AssemblyBuilderSetup, "Assembly builder setup" }, { TimerType.CreateTypeTotal, "Compiled types created" }, @@ -1030,7 +1055,7 @@ namespace Mono.CSharp { public override bool IsEnabled (int code, bool previous) { - return this.code == code ? false : previous; + return this.code != code && previous; } } @@ -1056,7 +1081,7 @@ namespace Mono.CSharp { public override bool IsEnabled(int code, bool previous) { - return this.code == code ? true : previous; + return this.code == code || previous; } } diff --git a/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/settings.cs b/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/settings.cs index 1556b5ca5..3c7f13bdb 100644 --- a/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/settings.cs +++ b/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/settings.cs @@ -28,9 +28,10 @@ namespace Mono.CSharp { V_3 = 3, V_4 = 4, V_5 = 5, + V_6 = 6, Future = 100, - Default = LanguageVersion.V_5, + Default = LanguageVersion.Future, } public enum RuntimeVersion @@ -146,6 +147,7 @@ namespace Mono.CSharp { public int VerboseParserFlag; public int FatalCounter; public bool Stacktrace; + public bool BreakOnInternalError; #endregion public bool ShowFullPaths; @@ -159,6 +161,8 @@ namespace Mono.CSharp { public RuntimeVersion StdLibRuntimeVersion; + public string RuntimeMetadataVersion; + public bool WriteMetadataOnly; readonly List conditional_symbols; @@ -301,8 +305,8 @@ namespace Mono.CSharp { UnknownOption } - static readonly char[] argument_value_separator = new char[] { ';', ',' }; - static readonly char[] numeric_value_separator = new char[] { ';', ',', ' ' }; + static readonly char[] argument_value_separator = { ';', ',' }; + static readonly char[] numeric_value_separator = { ';', ',', ' ' }; readonly TextWriter output; readonly Report report; @@ -350,6 +354,17 @@ namespace Mono.CSharp { public CompilerSettings ParseArguments (string[] args) { CompilerSettings settings = new CompilerSettings (); + if (!ParseArguments (settings, args)) + return null; + + return settings; + } + + public bool ParseArguments (CompilerSettings settings, string[] args) + { + if (settings == null) + throw new ArgumentNullException ("settings"); + List response_file_list = null; bool parsing_options = true; stop_argument = false; @@ -369,7 +384,7 @@ namespace Mono.CSharp { if (response_file_list.Contains (response_file)) { report.Error (1515, "Response file `{0}' specified multiple times", response_file); - return null; + return false; } response_file_list.Add (response_file); @@ -377,7 +392,7 @@ namespace Mono.CSharp { extra_args = LoadArgs (response_file); if (extra_args == null) { report.Error (2011, "Unable to open response file: " + response_file); - return null; + return false; } args = AddArgs (args, extra_args); @@ -399,7 +414,7 @@ namespace Mono.CSharp { continue; case ParseResult.Stop: stop_argument = true; - return settings; + return true; case ParseResult.UnknownOption: if (UnknownOptionHandler != null) { var ret = UnknownOptionHandler (args, i); @@ -433,11 +448,11 @@ namespace Mono.CSharp { } Error_WrongOption (arg); - return null; + return false; case ParseResult.Stop: stop_argument = true; - return settings; + return true; } } } @@ -445,10 +460,7 @@ namespace Mono.CSharp { ProcessSourceFiles (arg, false, settings.SourceFiles); } - if (report.Errors > 0) - return null; - - return settings; + return report.Errors == 0; } void ProcessSourceFiles (string spec, bool recurse, List sourceFiles) @@ -461,7 +473,7 @@ namespace Mono.CSharp { return; } - string[] files = null; + string[] files; try { files = Directory.GetFiles (path, pattern); } catch (System.IO.DirectoryNotFoundException) { @@ -568,7 +580,7 @@ namespace Mono.CSharp { public bool ProcessWarningsList (string text, Action action) { bool valid = true; - foreach (string wid in text.Split (numeric_value_separator)) { + foreach (string wid in text.Split (numeric_value_separator, StringSplitOptions.RemoveEmptyEntries)) { int id; if (!int.TryParse (wid, NumberStyles.AllowLeadingWhite, CultureInfo.InvariantCulture, out id)) { report.Error (1904, "`{0}' is not a valid warning number", wid); @@ -600,24 +612,7 @@ namespace Mono.CSharp { static bool IsExternAliasValid (string identifier) { - if (identifier.Length == 0) - return false; - if (identifier[0] != '_' && !char.IsLetter (identifier[0])) - return false; - - for (int i = 1; i < identifier.Length; i++) { - char c = identifier[i]; - if (char.IsLetter (c) || char.IsDigit (c)) - continue; - - UnicodeCategory category = char.GetUnicodeCategory (c); - if (category != UnicodeCategory.Format || category != UnicodeCategory.NonSpacingMark || - category != UnicodeCategory.SpacingCombiningMark || - category != UnicodeCategory.ConnectorPunctuation) - return false; - } - - return true; + return Tokenizer.IsValidIdentifier (identifier); } static string[] LoadArgs (string file) @@ -678,7 +673,8 @@ namespace Mono.CSharp { " --stacktrace Shows stack trace at error location\n" + " --timestamp Displays time stamps of various compiler events\n" + " -v Verbose parsing (for debugging the parser)\n" + - " --mcs-debug X Sets MCS debugging level to X\n"); + " --mcs-debug X Sets MCS debugging level to X\n" + + " --break-on-ice Breaks compilation on internal compiler error"); } // @@ -984,7 +980,7 @@ namespace Mono.CSharp { settings.WarningsAreErrors = true; parser_settings.WarningsAreErrors = true; } else { - if (!ProcessWarningsList (value, v => settings.AddWarningAsError (v))) + if (!ProcessWarningsList (value, settings.AddWarningAsError)) return ParseResult.Error; } return ParseResult.Success; @@ -993,7 +989,7 @@ namespace Mono.CSharp { if (value.Length == 0) { settings.WarningsAreErrors = false; } else { - if (!ProcessWarningsList (value, v => settings.AddWarningOnly (v))) + if (!ProcessWarningsList (value, settings.AddWarningOnly)) return ParseResult.Error; } return ParseResult.Success; @@ -1014,7 +1010,7 @@ namespace Mono.CSharp { return ParseResult.Error; } - if (!ProcessWarningsList (value, v => settings.SetIgnoreWarning (v))) + if (!ProcessWarningsList (value, settings.SetIgnoreWarning)) return ParseResult.Error; return ParseResult.Success; @@ -1141,11 +1137,13 @@ namespace Mono.CSharp { switch (value.ToLowerInvariant ()) { case "iso-1": + case "1": settings.Version = LanguageVersion.ISO_1; return ParseResult.Success; case "default": settings.Version = LanguageVersion.Default; return ParseResult.Success; + case "2": case "iso-2": settings.Version = LanguageVersion.ISO_2; return ParseResult.Success; @@ -1158,12 +1156,15 @@ namespace Mono.CSharp { case "5": settings.Version = LanguageVersion.V_5; return ParseResult.Success; + case "6": + settings.Version = LanguageVersion.V_6; + return ParseResult.Success; case "future": settings.Version = LanguageVersion.Future; return ParseResult.Success; } - report.Error (1617, "Invalid -langversion option `{0}'. It must be `ISO-1', `ISO-2', `3', `4', `5', `Default' or `Future'", value); + report.Error (1617, "Invalid -langversion option `{0}'. It must be `ISO-1', `ISO-2', Default or value in range 1 to 6", value); return ParseResult.Error; case "/codepage": @@ -1189,6 +1190,15 @@ namespace Mono.CSharp { } return ParseResult.Success; + case "runtimemetadataversion": + if (value.Length == 0) { + Error_RequiresArgument (option); + return ParseResult.Error; + } + + settings.RuntimeMetadataVersion = value; + return ParseResult.Success; + default: return ParseResult.UnknownOption; } @@ -1430,6 +1440,10 @@ namespace Mono.CSharp { settings.WriteMetadataOnly = true; return ParseResult.Success; + case "--break-on-ice": + settings.BreakOnInternalError = true; + return ParseResult.Success; + default: if (arg.StartsWith ("--fatal", StringComparison.Ordinal)){ int fatal = 1; diff --git a/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/statement.cs b/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/statement.cs index 46aff2b96..e7a360db6 100644 --- a/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/statement.cs +++ b/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/statement.cs @@ -24,41 +24,23 @@ namespace Mono.CSharp { public abstract class Statement { public Location loc; + protected bool reachable; + + public bool IsUnreachable { + get { + return !reachable; + } + } /// /// Resolves the statement, true means that all sub-statements /// did resolve ok. - // + /// public virtual bool Resolve (BlockContext bc) { return true; } - /// - /// We already know that the statement is unreachable, but we still - /// need to resolve it to catch errors. - /// - public virtual bool ResolveUnreachable (BlockContext ec, bool warn) - { - // - // This conflicts with csc's way of doing this, but IMHO it's - // the right thing to do. - // - // If something is unreachable, we still check whether it's - // correct. This means that you cannot use unassigned variables - // in unreachable code, for instance. - // - - if (warn) - ec.Report.Warning (162, 2, loc, "Unreachable code detected"); - - ec.StartFlowBranching (FlowBranching.BranchingType.Block, loc); - bool ok = Resolve (ec); - ec.KillFlowBranching (); - - return ok; - } - /// /// Return value indicates whether all code paths emitted return. /// @@ -97,6 +79,66 @@ namespace Mono.CSharp { { return visitor.Visit (this); } + + // + // Return value indicates whether statement has unreachable end + // + protected abstract bool DoFlowAnalysis (FlowAnalysisContext fc); + + public bool FlowAnalysis (FlowAnalysisContext fc) + { + if (reachable) { + fc.UnreachableReported = false; + var res = DoFlowAnalysis (fc); + fc.DefiniteAssignmentOnTrue = fc.DefiniteAssignmentOnFalse = null; + return res; + } + + // + // Special handling cases + // + if (this is Block) { + return DoFlowAnalysis (fc); + } + + if (this is EmptyStatement || loc.IsNull) + return true; + + if (fc.UnreachableReported) + return true; + + fc.Report.Warning (162, 2, loc, "Unreachable code detected"); + fc.UnreachableReported = true; + return true; + } + + public virtual Reachability MarkReachable (Reachability rc) + { + if (!rc.IsUnreachable) + reachable = true; + + return rc; + } + + protected void CheckExitBoundaries (BlockContext bc, Block scope) + { + if (bc.CurrentBlock.ParametersBlock.Original != scope.ParametersBlock.Original) { + bc.Report.Error (1632, loc, "Control cannot leave the body of an anonymous method"); + return; + } + + for (var b = bc.CurrentBlock; b != null && b != scope; b = b.Parent) { + if (b.IsFinallyBlock) { + Error_FinallyClauseExit (bc); + break; + } + } + } + + protected void Error_FinallyClauseExit (BlockContext bc) + { + bc.Report.Error (157, loc, "Control cannot leave the body of a finally clause"); + } } public sealed class EmptyStatement : Statement @@ -105,13 +147,8 @@ namespace Mono.CSharp { { this.loc = loc; } - - public override bool Resolve (BlockContext ec) - { - return true; - } - public override bool ResolveUnreachable (BlockContext ec, bool warn) + public override bool Resolve (BlockContext ec) { return true; } @@ -125,6 +162,11 @@ namespace Mono.CSharp { throw new NotSupportedException (); } + protected override bool DoFlowAnalysis (FlowAnalysisContext fc) + { + return false; + } + protected override void CloneTo (CloneContext clonectx, Statement target) { // nothing needed. @@ -135,13 +177,13 @@ namespace Mono.CSharp { return visitor.Visit (this); } } - + public class If : Statement { Expression expr; public Statement TrueStatement; public Statement FalseStatement; - bool is_true_ret; + bool true_returns, false_returns; public If (Expression bool_expr, Statement true_statement, Location l) : this (bool_expr, true_statement, null, l) @@ -167,52 +209,13 @@ namespace Mono.CSharp { public override bool Resolve (BlockContext ec) { - bool ok = true; - expr = expr.Resolve (ec); - if (expr == null) { - ok = false; - } else { - // - // Dead code elimination - // - if (expr is Constant) { - bool take = !((Constant) expr).IsDefaultValue; - - if (take) { - if (!TrueStatement.Resolve (ec)) - return false; - if ((FalseStatement != null) && - !FalseStatement.ResolveUnreachable (ec, true)) - return false; - FalseStatement = null; - } else { - if (!TrueStatement.ResolveUnreachable (ec, true)) - return false; - TrueStatement = null; + var ok = TrueStatement.Resolve (ec); - if ((FalseStatement != null) && - !FalseStatement.Resolve (ec)) - return false; - } - - return true; - } - } - - ec.StartFlowBranching (FlowBranching.BranchingType.Conditional, loc); - - ok &= TrueStatement.Resolve (ec); - - is_true_ret = ec.CurrentBranching.CurrentUsageVector.IsUnreachable; - - ec.CurrentBranching.CreateSibling (); - - if (FalseStatement != null) + if (FalseStatement != null) { ok &= FalseStatement.Resolve (ec); - - ec.EndFlowBranching (); + } return ok; } @@ -246,7 +249,7 @@ namespace Mono.CSharp { bool branch_emitted = false; end = ec.DefineLabel (); - if (!is_true_ret){ + if (!true_returns){ ec.Emit (OpCodes.Br, end); branch_emitted = true; } @@ -261,6 +264,80 @@ namespace Mono.CSharp { } } + protected override bool DoFlowAnalysis (FlowAnalysisContext fc) + { + fc.DefiniteAssignmentOnTrue = fc.DefiniteAssignmentOnFalse = fc.DefiniteAssignment; + + expr.FlowAnalysis (fc); + + var da_false = new DefiniteAssignmentBitSet (fc.DefiniteAssignmentOnFalse); + + fc.DefiniteAssignment = fc.DefiniteAssignmentOnTrue; + fc.DefiniteAssignmentOnTrue = fc.DefiniteAssignmentOnFalse = null; + + var res = TrueStatement.FlowAnalysis (fc); + + if (FalseStatement == null) { + if (true_returns) + fc.DefiniteAssignment = da_false; + else + fc.DefiniteAssignment &= da_false; + + return false; + } + + if (true_returns) { + fc.DefiniteAssignment = da_false; + return FalseStatement.FlowAnalysis (fc); + } + + var da_true = fc.DefiniteAssignment; + + fc.DefiniteAssignment = da_false; + res &= FalseStatement.FlowAnalysis (fc); + + if (!TrueStatement.IsUnreachable) { + if (false_returns || FalseStatement.IsUnreachable) + fc.DefiniteAssignment = da_true; + else + fc.DefiniteAssignment &= da_true; + } + + return res; + } + + public override Reachability MarkReachable (Reachability rc) + { + if (rc.IsUnreachable) + return rc; + + base.MarkReachable (rc); + + var c = expr as Constant; + if (c != null) { + bool take = !c.IsDefaultValue; + if (take) { + rc = TrueStatement.MarkReachable (rc); + } else { + if (FalseStatement != null) + rc = FalseStatement.MarkReachable (rc); + } + + return rc; + } + + var true_rc = TrueStatement.MarkReachable (rc); + true_returns = true_rc.IsUnreachable; + + if (FalseStatement == null) + return rc; + + var false_rc = FalseStatement.MarkReachable (rc); + false_returns = false_rc.IsUnreachable; + + return true_rc & false_rc; + } + protected override void CloneTo (CloneContext clonectx, Statement t) { If target = (If) t; @@ -277,14 +354,15 @@ namespace Mono.CSharp { } } - public class Do : Statement { + public class Do : LoopStatement + { public Expression expr; - public Statement EmbeddedStatement; + bool iterator_reachable, end_reachable; public Do (Statement statement, BooleanExpression bool_expr, Location doLocation, Location whileLocation) + : base (statement) { expr = bool_expr; - EmbeddedStatement = statement; loc = doLocation; WhileLocation = whileLocation; } @@ -293,32 +371,11 @@ namespace Mono.CSharp { get; private set; } - public override bool Resolve (BlockContext ec) + public override bool Resolve (BlockContext bc) { - bool ok = true; + var ok = base.Resolve (bc); - ec.StartFlowBranching (FlowBranching.BranchingType.Loop, loc); - - bool was_unreachable = ec.CurrentBranching.CurrentUsageVector.IsUnreachable; - - ec.StartFlowBranching (FlowBranching.BranchingType.Embedded, loc); - if (!EmbeddedStatement.Resolve (ec)) - ok = false; - ec.EndFlowBranching (); - - if (ec.CurrentBranching.CurrentUsageVector.IsUnreachable && !was_unreachable) - ec.Report.Warning (162, 2, expr.Location, "Unreachable code detected"); - - expr = expr.Resolve (ec); - if (expr == null) - ok = false; - else if (expr is Constant){ - bool infinite = !((Constant) expr).IsDefaultValue; - if (infinite) - ec.CurrentBranching.CurrentUsageVector.Goto (); - } - - ec.EndFlowBranching (); + expr = expr.Resolve (bc); return ok; } @@ -333,7 +390,7 @@ namespace Mono.CSharp { ec.LoopEnd = ec.DefineLabel (); ec.MarkLabel (loop); - EmbeddedStatement.Emit (ec); + Statement.Emit (ec); ec.MarkLabel (ec.LoopBegin); // Mark start of while condition @@ -358,11 +415,52 @@ namespace Mono.CSharp { ec.LoopEnd = old_end; } + protected override bool DoFlowAnalysis (FlowAnalysisContext fc) + { + var res = Statement.FlowAnalysis (fc); + + fc.DefiniteAssignmentOnTrue = fc.DefiniteAssignmentOnFalse = fc.DefiniteAssignment; + expr.FlowAnalysis (fc); + + fc.DefiniteAssignment = fc.DefiniteAssignmentOnFalse; + + if (res && !iterator_reachable) + return !end_reachable; + + if (!end_reachable) { + var c = expr as Constant; + if (c != null && !c.IsDefaultValue) + return true; + } + + return false; + } + + public override Reachability MarkReachable (Reachability rc) + { + base.MarkReachable (rc); + + var body_rc = Statement.MarkReachable (rc); + + if (body_rc.IsUnreachable && !iterator_reachable) { + expr = new UnreachableExpression (expr); + return end_reachable ? rc : Reachability.CreateUnreachable (); + } + + if (!end_reachable) { + var c = expr as Constant; + if (c != null && !c.IsDefaultValue) + return Reachability.CreateUnreachable (); + } + + return rc; + } + protected override void CloneTo (CloneContext clonectx, Statement t) { Do target = (Do) t; - target.EmbeddedStatement = EmbeddedStatement.Clone (clonectx); + target.Statement = Statement.Clone (clonectx); target.expr = expr.Clone (clonectx); } @@ -370,57 +468,46 @@ namespace Mono.CSharp { { return visitor.Visit (this); } + + public override void SetEndReachable () + { + end_reachable = true; + } + + public override void SetIteratorReachable () + { + iterator_reachable = true; + } } - public class While : Statement { + public class While : LoopStatement + { public Expression expr; - public Statement Statement; - bool infinite, empty; + bool empty, infinite, end_reachable; + List end_reachable_das; public While (BooleanExpression bool_expr, Statement statement, Location l) + : base (statement) { this.expr = bool_expr; - Statement = statement; loc = l; } - public override bool Resolve (BlockContext ec) + public override bool Resolve (BlockContext bc) { bool ok = true; - expr = expr.Resolve (ec); + expr = expr.Resolve (bc); if (expr == null) ok = false; - // - // Inform whether we are infinite or not - // - if (expr is Constant){ - bool value = !((Constant) expr).IsDefaultValue; - - if (value == false){ - if (!Statement.ResolveUnreachable (ec, true)) - return false; - empty = true; - return true; - } else - infinite = true; + var c = expr as Constant; + if (c != null) { + empty = c.IsDefaultValue; + infinite = !empty; } - ec.StartFlowBranching (FlowBranching.BranchingType.Loop, loc); - if (!infinite) - ec.CurrentBranching.CreateSibling (); - - ec.StartFlowBranching (FlowBranching.BranchingType.Embedded, loc); - if (!Statement.Resolve (ec)) - ok = false; - ec.EndFlowBranching (); - - // There's no direct control flow from the end of the embedded statement to the end of the loop - ec.CurrentBranching.CurrentUsageVector.Goto (); - - ec.EndFlowBranching (); - + ok &= base.Resolve (bc); return ok; } @@ -476,6 +563,60 @@ namespace Mono.CSharp { ec.LoopEnd = old_end; } + protected override bool DoFlowAnalysis (FlowAnalysisContext fc) + { + fc.DefiniteAssignmentOnTrue = fc.DefiniteAssignmentOnFalse = fc.DefiniteAssignment; + + expr.FlowAnalysis (fc); + + fc.DefiniteAssignment = fc.DefiniteAssignmentOnTrue; + var da_false = new DefiniteAssignmentBitSet (fc.DefiniteAssignmentOnFalse); + fc.DefiniteAssignmentOnTrue = fc.DefiniteAssignmentOnFalse = null; + + Statement.FlowAnalysis (fc); + + // + // Special case infinite while with breaks + // + if (end_reachable_das != null) { + da_false = DefiniteAssignmentBitSet.And (end_reachable_das); + end_reachable_das = null; + } + + fc.DefiniteAssignment = da_false; + + if (infinite && !end_reachable) + return true; + + return false; + } + + public override Reachability MarkReachable (Reachability rc) + { + if (rc.IsUnreachable) + return rc; + + base.MarkReachable (rc); + + // + // Special case unreachable while body + // + if (empty) { + Statement.MarkReachable (Reachability.CreateUnreachable ()); + return rc; + } + + Statement.MarkReachable (rc); + + // + // When infinite while end is unreachable via break anything what follows is unreachable too + // + if (infinite && !end_reachable) + return Reachability.CreateUnreachable (); + + return rc; + } + protected override void CloneTo (CloneContext clonectx, Statement t) { While target = (While) t; @@ -488,13 +629,31 @@ namespace Mono.CSharp { { return visitor.Visit (this); } + + public override void AddEndDefiniteAssignment (FlowAnalysisContext fc) + { + if (!infinite) + return; + + if (end_reachable_das == null) + end_reachable_das = new List (); + + end_reachable_das.Add (fc.DefiniteAssignment); + } + + public override void SetEndReachable () + { + end_reachable = true; + } } - public class For : Statement + public class For : LoopStatement { - bool infinite, empty; + bool infinite, empty, iterator_reachable, end_reachable; + List end_reachable_das; public For (Location l) + : base (null) { loc = l; } @@ -511,67 +670,82 @@ namespace Mono.CSharp { get; set; } - public Statement Statement { - get; set; - } - - public override bool Resolve (BlockContext ec) + public override bool Resolve (BlockContext bc) { - bool ok = true; - - if (Initializer != null) { - if (!Initializer.Resolve (ec)) - ok = false; - } + Initializer.Resolve (bc); if (Condition != null) { - Condition = Condition.Resolve (ec); - if (Condition == null) - ok = false; - else if (Condition is Constant) { - bool value = !((Constant) Condition).IsDefaultValue; - - if (value == false){ - if (!Statement.ResolveUnreachable (ec, true)) - return false; - if ((Iterator != null) && - !Iterator.ResolveUnreachable (ec, false)) - return false; + Condition = Condition.Resolve (bc); + var condition_constant = Condition as Constant; + if (condition_constant != null) { + if (condition_constant.IsDefaultValue) { empty = true; - return true; - } else + } else { infinite = true; + } } - } else + } else { infinite = true; + } - ec.StartFlowBranching (FlowBranching.BranchingType.Loop, loc); - if (!infinite) - ec.CurrentBranching.CreateSibling (); + return base.Resolve (bc) && Iterator.Resolve (bc); + } - bool was_unreachable = ec.CurrentBranching.CurrentUsageVector.IsUnreachable; + protected override bool DoFlowAnalysis (FlowAnalysisContext fc) + { + Initializer.FlowAnalysis (fc); - ec.StartFlowBranching (FlowBranching.BranchingType.Embedded, loc); - if (!Statement.Resolve (ec)) - ok = false; - ec.EndFlowBranching (); + DefiniteAssignmentBitSet da_false; + if (Condition != null) { + fc.DefiniteAssignmentOnTrue = fc.DefiniteAssignmentOnFalse = fc.DefiniteAssignment; - if (Iterator != null){ - if (ec.CurrentBranching.CurrentUsageVector.IsUnreachable) { - if (!Iterator.ResolveUnreachable (ec, !was_unreachable)) - ok = false; - } else { - if (!Iterator.Resolve (ec)) - ok = false; - } + Condition.FlowAnalysis (fc); + fc.DefiniteAssignment = fc.DefiniteAssignmentOnTrue; + da_false = new DefiniteAssignmentBitSet (fc.DefiniteAssignmentOnFalse); + fc.DefiniteAssignmentOnTrue = fc.DefiniteAssignmentOnFalse = null; + } else { + da_false = fc.BranchDefiniteAssignment (); } - // There's no direct control flow from the end of the embedded statement to the end of the loop - ec.CurrentBranching.CurrentUsageVector.Goto (); + Statement.FlowAnalysis (fc); - ec.EndFlowBranching (); + Iterator.FlowAnalysis (fc); - return ok; + // + // Special case infinite for with breaks + // + if (end_reachable_das != null) { + da_false = DefiniteAssignmentBitSet.And (end_reachable_das); + end_reachable_das = null; + } + + fc.DefiniteAssignment = da_false; + + if (infinite && !end_reachable) + return true; + + return false; + } + + public override Reachability MarkReachable (Reachability rc) + { + base.MarkReachable (rc); + + Initializer.MarkReachable (rc); + + var body_rc = Statement.MarkReachable (rc); + if (!body_rc.IsUnreachable || iterator_reachable) { + Iterator.MarkReachable (rc); + } + + // + // When infinite for end is unreachable via break anything what follows is unreachable too + // + if (infinite && !end_reachable) { + return Reachability.CreateUnreachable (); + } + + return rc; } protected override void DoEmit (EmitContext ec) @@ -644,6 +818,64 @@ namespace Mono.CSharp { { return visitor.Visit (this); } + + public override void AddEndDefiniteAssignment (FlowAnalysisContext fc) + { + if (!infinite) + return; + + if (end_reachable_das == null) + end_reachable_das = new List (); + + end_reachable_das.Add (fc.DefiniteAssignment); + } + + public override void SetEndReachable () + { + end_reachable = true; + } + + public override void SetIteratorReachable () + { + iterator_reachable = true; + } + } + + public abstract class LoopStatement : Statement + { + protected LoopStatement (Statement statement) + { + Statement = statement; + } + + public Statement Statement { get; set; } + + public override bool Resolve (BlockContext bc) + { + var prev_loop = bc.EnclosingLoop; + var prev_los = bc.EnclosingLoopOrSwitch; + bc.EnclosingLoopOrSwitch = bc.EnclosingLoop = this; + var ok = Statement.Resolve (bc); + bc.EnclosingLoopOrSwitch = prev_los; + bc.EnclosingLoop = prev_loop; + + return ok; + } + + // + // Needed by possibly infinite loops statements (for, while) and switch statment + // + public virtual void AddEndDefiniteAssignment (FlowAnalysisContext fc) + { + } + + public virtual void SetEndReachable () + { + } + + public virtual void SetIteratorReachable () + { + } } public class StatementExpression : Statement @@ -653,7 +885,7 @@ namespace Mono.CSharp { public StatementExpression (ExpressionStatement expr) { this.expr = expr; - loc = expr.Location; + loc = expr.StartLocation; } public StatementExpression (ExpressionStatement expr, Location loc) @@ -679,6 +911,19 @@ namespace Mono.CSharp { expr.EmitStatement (ec); } + protected override bool DoFlowAnalysis (FlowAnalysisContext fc) + { + expr.FlowAnalysis (fc); + return false; + } + + public override Reachability MarkReachable (Reachability rc) + { + base.MarkReachable (rc); + expr.MarkReachable (rc); + return rc; + } + public override bool Resolve (BlockContext ec) { expr = expr.ResolveStatement (ec); @@ -693,11 +938,12 @@ namespace Mono.CSharp { public class StatementErrorExpression : Statement { - readonly Expression expr; + Expression expr; public StatementErrorExpression (Expression expr) { this.expr = expr; + this.loc = expr.StartLocation; } public Expression Expr { @@ -706,14 +952,27 @@ namespace Mono.CSharp { } } + public override bool Resolve (BlockContext bc) + { + expr.Error_InvalidExpressionStatement (bc); + return true; + } + protected override void DoEmit (EmitContext ec) { throw new NotSupportedException (); } + protected override bool DoFlowAnalysis (FlowAnalysisContext fc) + { + return false; + } + protected override void CloneTo (CloneContext clonectx, Statement target) { - throw new NotImplementedException (); + var t = (StatementErrorExpression) target; + + t.expr = expr.Clone (clonectx); } public override object Accept (StructuralVisitor visitor) @@ -731,7 +990,7 @@ namespace Mono.CSharp { public StatementList (Statement first, Statement second) { - statements = new List () { first, second }; + statements = new List { first, second }; } #region Properties @@ -761,6 +1020,25 @@ namespace Mono.CSharp { s.Emit (ec); } + protected override bool DoFlowAnalysis (FlowAnalysisContext fc) + { + foreach (var s in statements) + s.FlowAnalysis (fc); + + return false; + } + + public override Reachability MarkReachable (Reachability rc) + { + base.MarkReachable (rc); + + Reachability res = rc; + foreach (var s in statements) + res = s.MarkReachable (rc); + + return res; + } + protected override void CloneTo (CloneContext clonectx, Statement target) { StatementList t = (StatementList) target; @@ -776,23 +1054,54 @@ namespace Mono.CSharp { } } - // A 'return' or a 'yield break' + // + // For statements which require special handling when inside try or catch block + // public abstract class ExitStatement : Statement { protected bool unwind_protect; - protected abstract bool DoResolve (BlockContext ec); - public virtual void Error_FinallyClause (Report Report) + protected abstract bool DoResolve (BlockContext bc); + protected abstract bool IsLocalExit { get; } + + public override bool Resolve (BlockContext bc) { - Report.Error (157, loc, "Control cannot leave the body of a finally clause"); + var res = DoResolve (bc); + + if (!IsLocalExit) { + // + // We are inside finally scope but is it the scope we are exiting + // + if (bc.HasSet (ResolveContext.Options.FinallyScope)) { + + for (var b = bc.CurrentBlock; b != null; b = b.Parent) { + if (b.IsFinallyBlock) { + Error_FinallyClauseExit (bc); + break; + } + + if (b is ParametersBlock) + break; + } + } + } + + unwind_protect = bc.HasAny (ResolveContext.Options.TryScope | ResolveContext.Options.CatchScope); + return res; } - public sealed override bool Resolve (BlockContext ec) + protected override bool DoFlowAnalysis (FlowAnalysisContext fc) { - var res = DoResolve (ec); - unwind_protect = ec.CurrentBranching.AddReturnOrigin (ec.CurrentBranching.CurrentUsageVector, this); - ec.CurrentBranching.CurrentUsageVector.Goto (); - return res; + if (IsLocalExit) + return true; + + if (fc.TryFinally != null) { + fc.TryFinally.RegisterForControlExitCheck (new DefiniteAssignmentBitSet (fc.DefiniteAssignment)); + } else { + fc.ParametersBlock.CheckControlExit (fc); + } + + return true; } } @@ -820,12 +1129,20 @@ namespace Mono.CSharp { } } + protected override bool IsLocalExit { + get { + return false; + } + } + #endregion protected override bool DoResolve (BlockContext ec) { + var block_return_type = ec.ReturnType; + if (expr == null) { - if (ec.ReturnType.Kind == MemberKind.Void) + if (block_return_type.Kind == MemberKind.Void) return true; // @@ -841,21 +1158,23 @@ namespace Mono.CSharp { expr = EmptyExpression.Null; return true; } + + if (storey.ReturnType.IsGenericTask) + block_return_type = storey.ReturnType.TypeArguments[0]; } if (ec.CurrentIterator != null) { Error_ReturnFromIterator (ec); - } else { + } else if (block_return_type != InternalType.ErrorType) { ec.Report.Error (126, loc, "An object of a type convertible to `{0}' is required for the return statement", - ec.ReturnType.GetSignatureForError ()); + block_return_type.GetSignatureForError ()); } return false; } expr = expr.Resolve (ec); - TypeSpec block_return_type = ec.ReturnType; AnonymousExpression am = ec.CurrentAnonymousMethod; if (am == null) { @@ -879,15 +1198,16 @@ namespace Mono.CSharp { var async_type = storey.ReturnType; if (async_type == null && async_block.ReturnTypeInference != null) { - async_block.ReturnTypeInference.AddCommonTypeBound (expr.Type); + if (expr.Type.Kind == MemberKind.Void && !(this is ContextualReturn)) + ec.Report.Error (4029, loc, "Cannot return an expression of type `void'"); + else + async_block.ReturnTypeInference.AddCommonTypeBoundAsync (expr.Type); return true; } 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", - ec.GetSignatureForError ()); - + ec.Report.Error (8030, loc, + "Anonymous function or lambda expression converted to a void returning delegate cannot return a value"); return false; } @@ -895,9 +1215,14 @@ namespace Mono.CSharp { if (this is ContextualReturn) return true; - ec.Report.Error (1997, loc, - "`{0}': A return keyword must not be followed by an expression when async method returns `Task'. Consider using `Task' return type", - ec.GetSignatureForError ()); + if (async_block.DelegateType != null) { + ec.Report.Error (8031, loc, + "Async lambda expression or anonymous method converted to a `Task' cannot return a value. Consider returning `Task'"); + } else { + ec.Report.Error (1997, loc, + "`{0}': A return keyword must not be followed by an expression when async method returns `Task'. Consider using `Task' return type", + ec.GetSignatureForError ()); + } return false; } @@ -913,19 +1238,26 @@ 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 ()); - + ec.Report.Error (8030, loc, + "Anonymous function or lambda expression converted to a void returning delegate cannot return a value"); return false; } var l = am as AnonymousMethodBody; - if (l != null && l.ReturnTypeInference != null && expr != null) { - l.ReturnTypeInference.AddCommonTypeBound (expr.Type); - return true; + if (l != null && expr != null) { + if (l.ReturnTypeInference != null) { + l.ReturnTypeInference.AddCommonTypeBound (expr.Type); + return true; + } + + // + // Try to optimize simple lambda. Only when optimizations are enabled not to cause + // unexpected debugging experience + // + if (this is ContextualReturn && !ec.IsInProbingMode && ec.Module.Compiler.Settings.Optimize) { + l.DirectMethodGroupConversion = expr.CanReduceLambda (l); + } } } } @@ -952,23 +1284,42 @@ namespace Mono.CSharp { protected override void DoEmit (EmitContext ec) { if (expr != null) { - expr.Emit (ec); var async_body = ec.CurrentAnonymousMethod as AsyncInitializer; if (async_body != null) { - var async_return = ((AsyncTaskStorey) async_body.Storey).HoistedReturn; + var storey = (AsyncTaskStorey)async_body.Storey; + Label exit_label = async_body.BodyEnd; + // // It's null for await without async - if (async_return != null) { - async_return.EmitAssign (ec); + // + if (storey.HoistedReturnValue != null) { + // + // Special case hoisted return value (happens in try/finally scenario) + // + if (ec.TryFinallyUnwind != null) { + if (storey.HoistedReturnValue is VariableReference) { + storey.HoistedReturnValue = ec.GetTemporaryField (storey.HoistedReturnValue.Type); + } + exit_label = TryFinally.EmitRedirectedReturn (ec, async_body); + } + + var async_return = (IAssignMethod)storey.HoistedReturnValue; + async_return.EmitAssign (ec, expr, false, false); ec.EmitEpilogue (); + } else { + expr.Emit (ec); + + if (ec.TryFinallyUnwind != null) + exit_label = TryFinally.EmitRedirectedReturn (ec, async_body); } - ec.Emit (unwind_protect ? OpCodes.Leave : OpCodes.Br, async_body.BodyEnd); + ec.Emit (OpCodes.Leave, exit_label); return; } + expr.Emit (ec); ec.EmitEpilogue (); if (unwind_protect || ec.EmitAccurateDebugInfo) @@ -984,12 +1335,27 @@ namespace Mono.CSharp { } } + protected override bool DoFlowAnalysis (FlowAnalysisContext fc) + { + if (expr != null) + expr.FlowAnalysis (fc); + + base.DoFlowAnalysis (fc); + return true; + } + void Error_ReturnFromIterator (ResolveContext rc) { rc.Report.Error (1622, loc, "Cannot return a value from iterators. Use the yield return statement to return a value, or yield break to end the iteration"); } + public override Reachability MarkReachable (Reachability rc) + { + base.MarkReachable (rc); + return Reachability.CreateUnreachable (); + } + protected override void CloneTo (CloneContext clonectx, Statement t) { Return target = (Return) t; @@ -1004,18 +1370,12 @@ namespace Mono.CSharp { } } - public class Goto : Statement { + public class Goto : ExitStatement + { string target; LabeledStatement label; - bool unwind_protect; + TryFinally try_finally; - public override bool Resolve (BlockContext ec) - { - unwind_protect = ec.CurrentBranching.AddGotoOrigin (ec.CurrentBranching.CurrentUsageVector, this); - ec.CurrentBranching.CurrentUsageVector.Goto (); - return true; - } - public Goto (string label, Location l) { loc = l; @@ -1026,10 +1386,65 @@ namespace Mono.CSharp { get { return target; } } - public void SetResolvedTarget (LabeledStatement label) + protected override bool IsLocalExit { + get { + return true; + } + } + + protected override bool DoResolve (BlockContext bc) { - this.label = label; - label.AddReference (); + label = bc.CurrentBlock.LookupLabel (target); + if (label == null) { + Error_UnknownLabel (bc, target, loc); + return false; + } + + try_finally = bc.CurrentTryBlock as TryFinally; + + CheckExitBoundaries (bc, label.Block); + + return true; + } + + public static void Error_UnknownLabel (BlockContext bc, string label, Location loc) + { + bc.Report.Error (159, loc, "The label `{0}:' could not be found within the scope of the goto statement", + label); + } + + protected override bool DoFlowAnalysis (FlowAnalysisContext fc) + { + if (fc.LabelStack == null) { + fc.LabelStack = new List (); + } else if (fc.LabelStack.Contains (label)) { + return true; + } + + fc.LabelStack.Add (label); + label.Block.ScanGotoJump (label, fc); + fc.LabelStack.Remove (label); + return true; + } + + public override Reachability MarkReachable (Reachability rc) + { + if (rc.IsUnreachable) + return rc; + + base.MarkReachable (rc); + + if (try_finally != null) { + if (try_finally.FinallyBlock.HasReachableClosingBrace) { + label.AddGotoReference (rc, false); + } else { + label.AddGotoReference (rc, true); + } + } else { + label.AddGotoReference (rc, false); + } + + return Reachability.CreateUnreachable (); } protected override void CloneTo (CloneContext clonectx, Statement target) @@ -1041,9 +1456,29 @@ namespace Mono.CSharp { { if (label == null) throw new InternalErrorException ("goto emitted before target resolved"); + Label l = label.LabelTarget (ec); + + if (ec.TryFinallyUnwind != null && IsLeavingFinally (label.Block)) { + var async_body = (AsyncInitializer) ec.CurrentAnonymousMethod; + l = TryFinally.EmitRedirectedJump (ec, async_body, l, label.Block); + } + ec.Emit (unwind_protect ? OpCodes.Leave : OpCodes.Br, l); } + + bool IsLeavingFinally (Block labelBlock) + { + var b = try_finally.Statement as Block; + while (b != null) { + if (b == labelBlock) + return true; + + b = b.Parent; + } + + return false; + } public override object Accept (StructuralVisitor visitor) { @@ -1055,10 +1490,9 @@ namespace Mono.CSharp { string name; bool defined; bool referenced; + bool finalTarget; Label label; Block block; - - FlowBranching.UsageVector vectors; public LabeledStatement (string name, Block block, Location l) { @@ -1087,51 +1521,68 @@ namespace Mono.CSharp { get { return name; } } - public bool IsDefined { - get { return defined; } - } - - public bool HasBeenReferenced { - get { return referenced; } - } + protected override void CloneTo (CloneContext clonectx, Statement target) + { + var t = (LabeledStatement) target; - public FlowBranching.UsageVector JumpOrigins { - get { return vectors; } + t.block = clonectx.RemapBlockCopy (block); } - public void AddUsageVector (FlowBranching.UsageVector vector) + public override bool Resolve (BlockContext bc) { - vector = vector.Clone (); - vector.Next = vectors; - vectors = vector; + return true; } - protected override void CloneTo (CloneContext clonectx, Statement target) + protected override void DoEmit (EmitContext ec) { - // nothing to clone + LabelTarget (ec); + ec.MarkLabel (label); + + if (finalTarget) + ec.Emit (OpCodes.Br_S, label); } - public override bool Resolve (BlockContext ec) + protected override bool DoFlowAnalysis (FlowAnalysisContext fc) { - // this flow-branching will be terminated when the surrounding block ends - ec.StartFlowBranching (this); - return true; + if (!referenced) { + fc.Report.Warning (164, 2, loc, "This label has not been referenced"); + } + + return false; } - protected override void DoEmit (EmitContext ec) + public override Reachability MarkReachable (Reachability rc) { - if (!HasBeenReferenced) - ec.Report.Warning (164, 2, loc, "This label has not been referenced"); + base.MarkReachable (rc); - LabelTarget (ec); - ec.MarkLabel (label); + if (referenced) + rc = new Reachability (); + + return rc; } - public void AddReference () + public void AddGotoReference (Reachability rc, bool finalTarget) { + if (referenced) + return; + referenced = true; + MarkReachable (rc); + + // + // Label is final target when goto jumps out of try block with + // finally clause. In that case we need leave with target but in C# + // terms the label is unreachable. Using finalTarget we emit + // explicit label not just marker + // + if (finalTarget) { + this.finalTarget = true; + return; + } + + block.ScanGotoJump (this); } - + public override object Accept (StructuralVisitor visitor) { return visitor.Visit (this); @@ -1142,40 +1593,44 @@ namespace Mono.CSharp { /// /// `goto default' statement /// - public class GotoDefault : Statement { - + public class GotoDefault : SwitchGoto + { public GotoDefault (Location l) + : base (l) { - loc = l; - } - - protected override void CloneTo (CloneContext clonectx, Statement target) - { - // nothing to clone } - public override bool Resolve (BlockContext ec) + public override bool Resolve (BlockContext bc) { - ec.CurrentBranching.CurrentUsageVector.Goto (); - - if (ec.Switch == null) { - ec.Report.Error (153, loc, "A goto case is only valid inside a switch statement"); + if (bc.Switch == null) { + Error_GotoCaseRequiresSwitchBlock (bc); return false; } - if (!ec.Switch.GotDefault) { - FlowBranchingBlock.Error_UnknownLabel (loc, "default", ec.Report); - return false; - } + bc.Switch.RegisterGotoCase (null, null); + base.Resolve (bc); return true; } protected override void DoEmit (EmitContext ec) { - ec.Emit (OpCodes.Br, ec.Switch.DefaultLabel); + ec.Emit (unwind_protect ? OpCodes.Leave : OpCodes.Br, ec.Switch.DefaultLabel.GetILLabel (ec)); } - + + public override Reachability MarkReachable (Reachability rc) + { + if (!rc.IsUnreachable) { + var label = switch_statement.DefaultLabel; + if (label.IsUnreachable) { + label.MarkReachable (rc); + switch_statement.Block.ScanGotoJump (label); + } + } + + return base.MarkReachable (rc); + } + public override object Accept (StructuralVisitor visitor) { return visitor.Visit (this); @@ -1185,38 +1640,33 @@ namespace Mono.CSharp { /// /// `goto case' statement /// - public class GotoCase : Statement { + public class GotoCase : SwitchGoto + { Expression expr; - SwitchLabel sl; public GotoCase (Expression e, Location l) + : base (l) { expr = e; - loc = l; } public Expression Expr { get { - return this.expr; + return expr; } } - + + public SwitchLabel Label { get; set; } + public override bool Resolve (BlockContext ec) { - if (ec.Switch == null){ - ec.Report.Error (153, loc, "A goto case is only valid inside a switch statement"); + if (ec.Switch == null) { + Error_GotoCaseRequiresSwitchBlock (ec); return false; } - ec.CurrentBranching.CurrentUsageVector.Goto (); - - expr = expr.Resolve (ec); - if (expr == null) - return false; - - Constant c = expr as Constant; + Constant c = expr.ResolveLabelConstant (ec); if (c == null) { - ec.Report.Error (150, expr.Location, "A constant value is expected"); return false; } @@ -1225,7 +1675,7 @@ namespace Mono.CSharp { res = c; } else { TypeSpec type = ec.Switch.SwitchType; - res = c.TryReduce (ec, type); + res = c.Reduce (ec, type); if (res == null) { c.Error_ValueCannotBeConverted (ec, type, true); return false; @@ -1234,17 +1684,20 @@ namespace Mono.CSharp { if (!Convert.ImplicitStandardConversionExists (c, type)) ec.Report.Warning (469, 2, loc, "The `goto case' value is not implicitly convertible to type `{0}'", - TypeManager.CSharpName (type)); + type.GetSignatureForError ()); } - sl = ec.Switch.ResolveGotoCase (ec, res); + ec.Switch.RegisterGotoCase (this, res); + base.Resolve (ec); + expr = res; + return true; } protected override void DoEmit (EmitContext ec) { - ec.Emit (OpCodes.Br, sl.GetILLabel (ec)); + ec.Emit (unwind_protect ? OpCodes.Leave : OpCodes.Br, Label.GetILLabel (ec)); } protected override void CloneTo (CloneContext clonectx, Statement t) @@ -1253,12 +1706,67 @@ namespace Mono.CSharp { target.expr = expr.Clone (clonectx); } + + public override Reachability MarkReachable (Reachability rc) + { + if (!rc.IsUnreachable) { + var label = switch_statement.FindLabel ((Constant) expr); + if (label.IsUnreachable) { + label.MarkReachable (rc); + switch_statement.Block.ScanGotoJump (label); + } + } + + return base.MarkReachable (rc); + } public override object Accept (StructuralVisitor visitor) { return visitor.Visit (this); } } + + public abstract class SwitchGoto : Statement + { + protected bool unwind_protect; + protected Switch switch_statement; + + protected SwitchGoto (Location loc) + { + this.loc = loc; + } + + protected override void CloneTo (CloneContext clonectx, Statement target) + { + // Nothing to clone + } + + public override bool Resolve (BlockContext bc) + { + CheckExitBoundaries (bc, bc.Switch.Block); + + unwind_protect = bc.HasAny (ResolveContext.Options.TryScope | ResolveContext.Options.CatchScope); + switch_statement = bc.Switch; + + return true; + } + + protected override bool DoFlowAnalysis (FlowAnalysisContext fc) + { + return true; + } + + public override Reachability MarkReachable (Reachability rc) + { + base.MarkReachable (rc); + return Reachability.CreateUnreachable (); + } + + protected void Error_GotoCaseRequiresSwitchBlock (BlockContext bc) + { + bc.Report.Error (153, loc, "A goto case is only valid inside a switch statement"); + } + } public class Throw : Statement { Expression expr; @@ -1278,12 +1786,22 @@ namespace Mono.CSharp { public override bool Resolve (BlockContext ec) { if (expr == null) { - ec.CurrentBranching.CurrentUsageVector.Goto (); - return ec.CurrentBranching.CheckRethrow (loc); + if (!ec.HasSet (ResolveContext.Options.CatchScope)) { + ec.Report.Error (156, loc, "A throw statement with no arguments is not allowed outside of a catch clause"); + } else if (ec.HasSet (ResolveContext.Options.FinallyScope)) { + for (var b = ec.CurrentBlock; b != null && !b.IsCatchBlock; b = b.Parent) { + if (b.IsFinallyBlock) { + ec.Report.Error (724, loc, + "A throw statement with no arguments is not allowed inside of a finally clause nested inside of the innermost catch clause"); + break; + } + } + } + + return true; } expr = expr.Resolve (ec, ResolveFlags.Type | ResolveFlags.VariableOrValue); - ec.CurrentBranching.CurrentUsageVector.Goto (); if (expr == null) return false; @@ -1299,15 +1817,40 @@ namespace Mono.CSharp { protected override void DoEmit (EmitContext ec) { - if (expr == null) - ec.Emit (OpCodes.Rethrow); - else { + if (expr == null) { + var atv = ec.AsyncThrowVariable; + if (atv != null) { + if (atv.HoistedVariant != null) { + atv.HoistedVariant.Emit (ec); + } else { + atv.Emit (ec); + } + + ec.Emit (OpCodes.Throw); + } else { + ec.Emit (OpCodes.Rethrow); + } + } else { expr.Emit (ec); ec.Emit (OpCodes.Throw); } } + protected override bool DoFlowAnalysis (FlowAnalysisContext fc) + { + if (expr != null) + expr.FlowAnalysis (fc); + + return true; + } + + public override Reachability MarkReachable (Reachability rc) + { + base.MarkReachable (rc); + return Reachability.CreateUnreachable (); + } + protected override void CloneTo (CloneContext clonectx, Statement t) { Throw target = (Throw) t; @@ -1322,67 +1865,130 @@ namespace Mono.CSharp { } } - public class Break : Statement { - + public class Break : LocalExitStatement + { public Break (Location l) + : base (l) { - loc = l; + } + + public override object Accept (StructuralVisitor visitor) + { + return visitor.Visit (this); } - bool unwind_protect; + protected override void DoEmit (EmitContext ec) + { + var l = ec.LoopEnd; - public override bool Resolve (BlockContext ec) + if (ec.TryFinallyUnwind != null) { + var async_body = (AsyncInitializer) ec.CurrentAnonymousMethod; + l = TryFinally.EmitRedirectedJump (ec, async_body, l, enclosing_loop.Statement as Block); + } + + ec.Emit (unwind_protect ? OpCodes.Leave : OpCodes.Br, l); + } + + protected override bool DoFlowAnalysis (FlowAnalysisContext fc) { - unwind_protect = ec.CurrentBranching.AddBreakOrigin (ec.CurrentBranching.CurrentUsageVector, loc); - ec.CurrentBranching.CurrentUsageVector.Goto (); + enclosing_loop.AddEndDefiniteAssignment (fc); return true; } - protected override void DoEmit (EmitContext ec) + protected override bool DoResolve (BlockContext bc) { - ec.Emit (unwind_protect ? OpCodes.Leave : OpCodes.Br, ec.LoopEnd); + enclosing_loop = bc.EnclosingLoopOrSwitch; + return base.DoResolve (bc); } - protected override void CloneTo (CloneContext clonectx, Statement t) + public override Reachability MarkReachable (Reachability rc) + { + base.MarkReachable (rc); + + if (!rc.IsUnreachable) + enclosing_loop.SetEndReachable (); + + return Reachability.CreateUnreachable (); + } + } + + public class Continue : LocalExitStatement + { + public Continue (Location l) + : base (l) { - // nothing needed } - + public override object Accept (StructuralVisitor visitor) { return visitor.Visit (this); } - } - public class Continue : Statement { - - public Continue (Location l) + + protected override void DoEmit (EmitContext ec) { - loc = l; + var l = ec.LoopBegin; + + if (ec.TryFinallyUnwind != null) { + var async_body = (AsyncInitializer) ec.CurrentAnonymousMethod; + l = TryFinally.EmitRedirectedJump (ec, async_body, l, enclosing_loop.Statement as Block); + } + + ec.Emit (unwind_protect ? OpCodes.Leave : OpCodes.Br, l); } - bool unwind_protect; + protected override bool DoResolve (BlockContext bc) + { + enclosing_loop = bc.EnclosingLoop; + return base.DoResolve (bc); + } - public override bool Resolve (BlockContext ec) + public override Reachability MarkReachable (Reachability rc) { - unwind_protect = ec.CurrentBranching.AddContinueOrigin (ec.CurrentBranching.CurrentUsageVector, loc); - ec.CurrentBranching.CurrentUsageVector.Goto (); - return true; + base.MarkReachable (rc); + + if (!rc.IsUnreachable) + enclosing_loop.SetIteratorReachable (); + + return Reachability.CreateUnreachable (); } + } - protected override void DoEmit (EmitContext ec) + public abstract class LocalExitStatement : ExitStatement + { + protected LoopStatement enclosing_loop; + + protected LocalExitStatement (Location loc) { - ec.Emit (unwind_protect ? OpCodes.Leave : OpCodes.Br, ec.LoopBegin); + this.loc = loc; + } + + protected override bool IsLocalExit { + get { + return true; + } } protected override void CloneTo (CloneContext clonectx, Statement t) { // nothing needed. } - - public override object Accept (StructuralVisitor visitor) + + protected override bool DoResolve (BlockContext bc) { - return visitor.Visit (this); + if (enclosing_loop == null) { + bc.Report.Error (139, loc, "No enclosing loop out of which to break or continue"); + return false; + } + + var block = enclosing_loop.Statement as Block; + + // Don't need to do extra checks for simple statements loops + if (block != null) { + CheckExitBoundaries (bc, block); + } + + return true; } } @@ -1402,69 +2008,72 @@ namespace Mono.CSharp { Location Location { get; } } - public class BlockVariableDeclaration : Statement + public class BlockVariableDeclarator { - public class Declarator + LocalVariable li; + Expression initializer; + + public BlockVariableDeclarator (LocalVariable li, Expression initializer) { - LocalVariable li; - Expression initializer; + if (li.Type != null) + throw new ArgumentException ("Expected null variable type"); - public Declarator (LocalVariable li, Expression initializer) - { - if (li.Type != null) - throw new ArgumentException ("Expected null variable type"); + this.li = li; + this.initializer = initializer; + } - this.li = li; - this.initializer = initializer; - } + #region Properties - public Declarator (Declarator clone, Expression initializer) - { - this.li = clone.li; - this.initializer = initializer; + public LocalVariable Variable { + get { + return li; } + } - #region Properties - - public LocalVariable Variable { - get { - return li; - } + public Expression Initializer { + get { + return initializer; } - - public Expression Initializer { - get { - return initializer; - } - set { - initializer = value; - } + set { + initializer = value; } + } - #endregion + #endregion + + public virtual BlockVariableDeclarator Clone (CloneContext cloneCtx) + { + var t = (BlockVariableDeclarator) MemberwiseClone (); + if (initializer != null) + t.initializer = initializer.Clone (cloneCtx); + + return t; } + } + public class BlockVariable : Statement + { Expression initializer; protected FullNamedExpression type_expr; protected LocalVariable li; - protected List declarators; + protected List declarators; TypeSpec type; - public BlockVariableDeclaration (FullNamedExpression type, LocalVariable li) + public BlockVariable (FullNamedExpression type, LocalVariable li) { this.type_expr = type; this.li = li; this.loc = type_expr.Location; } - protected BlockVariableDeclaration (LocalVariable li) + protected BlockVariable (LocalVariable li) { this.li = li; } #region Properties - public List Declarators { + public List Declarators { get { return declarators; } @@ -1493,10 +2102,10 @@ namespace Mono.CSharp { #endregion - public void AddDeclarator (Declarator decl) + public void AddDeclarator (BlockVariableDeclarator decl) { if (declarators == null) - declarators = new List (); + declarators = new List (); declarators.Add (decl); } @@ -1589,8 +2198,8 @@ namespace Mono.CSharp { bool eval_global = bc.Module.Compiler.Settings.StatementMode && bc.CurrentBlock is ToplevelBlock; if (eval_global) { CreateEvaluatorVariable (bc, li); - } else { - li.PrepareForFlowAnalysis (bc); + } else if (type != InternalType.ErrorType) { + li.PrepareAssignmentAnalysis (bc); } if (initializer != null) { @@ -1603,8 +2212,8 @@ namespace Mono.CSharp { d.Variable.Type = li.Type; if (eval_global) { CreateEvaluatorVariable (bc, d.Variable); - } else { - d.Variable.PrepareForFlowAnalysis (bc); + } else if (type != InternalType.ErrorType) { + d.Variable.PrepareAssignmentAnalysis (bc); } if (d.Initializer != null && resolveDeclaratorInitializers) { @@ -1627,13 +2236,13 @@ namespace Mono.CSharp { { li.CreateBuilder (ec); - if (Initializer != null) + if (Initializer != null && !IsUnreachable) ((ExpressionStatement) Initializer).EmitStatement (ec); if (declarators != null) { foreach (var d in declarators) { d.Variable.CreateBuilder (ec); - if (d.Initializer != null) { + if (d.Initializer != null && !IsUnreachable) { ec.Mark (d.Variable.Location); ((ExpressionStatement) d.Initializer).EmitStatement (ec); } @@ -1641,9 +2250,33 @@ namespace Mono.CSharp { } } + protected override bool DoFlowAnalysis (FlowAnalysisContext fc) + { + if (Initializer != null) + Initializer.FlowAnalysis (fc); + + if (declarators != null) { + foreach (var d in declarators) { + if (d.Initializer != null) + d.Initializer.FlowAnalysis (fc); + } + } + + return false; + } + + public override Reachability MarkReachable (Reachability rc) + { + var init = initializer as ExpressionStatement; + if (init != null) + init.MarkReachable (rc); + + return base.MarkReachable (rc); + } + protected override void CloneTo (CloneContext clonectx, Statement target) { - BlockVariableDeclaration t = (BlockVariableDeclaration) target; + BlockVariable t = (BlockVariable) target; if (type_expr != null) t.type_expr = (FullNamedExpression) type_expr.Clone (clonectx); @@ -1654,7 +2287,7 @@ namespace Mono.CSharp { if (declarators != null) { t.declarators = null; foreach (var d in declarators) - t.AddDeclarator (new Declarator (d, d.Initializer == null ? null : d.Initializer.Clone (clonectx))); + t.AddDeclarator (d.Clone (clonectx)); } } @@ -1664,9 +2297,9 @@ namespace Mono.CSharp { } } - public class BlockConstantDeclaration : BlockVariableDeclaration + public class BlockConstant : BlockVariable { - public BlockConstantDeclaration (FullNamedExpression type, LocalVariable li) + public BlockConstant (FullNamedExpression type, LocalVariable li) : base (type, li) { } @@ -1711,7 +2344,7 @@ namespace Mono.CSharp { // // The information about a user-perceived local variable // - public class LocalVariable : INamedBlockVariable, ILocalVariable + public sealed class LocalVariable : INamedBlockVariable, ILocalVariable { [Flags] public enum Flags @@ -1724,8 +2357,7 @@ namespace Mono.CSharp { ForeachVariable = 1 << 5, FixedVariable = 1 << 6, UsingVariable = 1 << 7, -// DefinitelyAssigned = 1 << 8, - IsLocked = 1 << 9, + IsLocked = 1 << 8, ReadonlyMask = ForeachVariable | FixedVariable | UsingVariable } @@ -1940,6 +2572,10 @@ namespace Mono.CSharp { public void EmitAddressOf (EmitContext ec) { + // TODO: Need something better for temporary variables + if ((flags & Flags.CompilerGenerated) != 0) + CreateBuilder (ec); + ec.Emit (OpCodes.Ldloca, builder); } @@ -1963,35 +2599,31 @@ namespace Mono.CSharp { throw new InternalErrorException ("Variable is not readonly"); } - public bool IsThisAssigned (BlockContext ec, Block block) + public bool IsThisAssigned (FlowAnalysisContext fc, Block block) { if (VariableInfo == null) throw new Exception (); - if (!ec.DoFlowAnalysis || ec.CurrentBranching.IsAssigned (VariableInfo)) + if (IsAssigned (fc)) return true; - return VariableInfo.IsFullyInitialized (ec, block.StartLocation); + return VariableInfo.IsFullyInitialized (fc, block.StartLocation); } - public bool IsAssigned (BlockContext ec) + public bool IsAssigned (FlowAnalysisContext fc) { - if (VariableInfo == null) - throw new Exception (); - - return !ec.DoFlowAnalysis || ec.CurrentBranching.IsAssigned (VariableInfo); + return fc.IsDefinitelyAssigned (VariableInfo); } - public void PrepareForFlowAnalysis (BlockContext bc) + public void PrepareAssignmentAnalysis (BlockContext bc) { // - // No need for definitely assigned check for these guys + // No need to run assignment analysis for these guys // if ((flags & (Flags.Constant | Flags.ReadonlyMask | Flags.CompilerGenerated)) != 0) return; - VariableInfo = new VariableInfo (this, bc.FlowOffset); - bc.FlowOffset += VariableInfo.Length; + VariableInfo = VariableInfo.Create (bc, this); } // @@ -2032,7 +2664,7 @@ namespace Mono.CSharp { public enum Flags { Unchecked = 1, - HasRet = 8, + ReachableEnd = 8, Unsafe = 16, HasCapturedVariable = 64, HasCapturedThis = 1 << 7, @@ -2041,7 +2673,12 @@ namespace Mono.CSharp { HasAsyncModifier = 1 << 10, Resolved = 1 << 11, YieldBlock = 1 << 12, - AwaitBlock = 1 << 13 + AwaitBlock = 1 << 13, + FinallyBlock = 1 << 14, + CatchBlock = 1 << 15, + Iterator = 1 << 20, + NoFlowAnalysis = 1 << 21, + InitializationEmitted = 1 << 22 } public Block Parent; @@ -2073,9 +2710,7 @@ namespace Mono.CSharp { #endif // int assignable_slots; - bool unreachable_shown; - bool unreachable; - + public Block (Block parent, Location start, Location end) : this (parent, 0, start, end) { @@ -2101,15 +2736,6 @@ namespace Mono.CSharp { #region Properties - public bool HasUnreachableClosingBrace { - get { - return (flags & Flags.HasRet) != 0; - } - set { - flags = value ? flags | Flags.HasRet : flags & ~Flags.HasRet; - } - } - public Block Original { get { return original; @@ -2124,6 +2750,19 @@ namespace Mono.CSharp { set { flags = value ? flags | Flags.CompilerGenerated : flags & ~Flags.CompilerGenerated; } } + + public bool IsCatchBlock { + get { + return (flags & Flags.CatchBlock) != 0; + } + } + + public bool IsFinallyBlock { + get { + return (flags & Flags.FinallyBlock) != 0; + } + } + public bool Unchecked { get { return (flags & Flags.Unchecked) != 0; } set { flags = value ? flags | Flags.Unchecked : flags & ~Flags.Unchecked; } @@ -2140,14 +2779,6 @@ namespace Mono.CSharp { #endregion - public Block CreateSwitchBlock (Location start) - { - // FIXME: Only explicit block should be created - var new_block = new Block (this, start, start); - new_block.IsCompilerGenerated = true; - return new_block; - } - public void SetEndLocation (Location loc) { EndLocation = loc; @@ -2221,134 +2852,93 @@ namespace Mono.CSharp { scope_initializers.Add (s); } } + + public void InsertStatement (int index, Statement s) + { + statements.Insert (index, s); + } public void AddStatement (Statement s) { statements.Add (s); } - public int AssignableSlots { - get { - // FIXME: HACK, we don't know the block available variables count now, so set this high enough - return 4096; -// return assignable_slots; + public LabeledStatement LookupLabel (string name) + { + return ParametersBlock.GetLabel (name, this); + } + + public override Reachability MarkReachable (Reachability rc) + { + if (rc.IsUnreachable) + return rc; + + MarkReachableScope (rc); + + foreach (var s in statements) { + rc = s.MarkReachable (rc); + if (rc.IsUnreachable) { + if ((flags & Flags.ReachableEnd) != 0) + return new Reachability (); + + return rc; + } } + + flags |= Flags.ReachableEnd; + + return rc; } - public LabeledStatement LookupLabel (string name) + public void MarkReachableScope (Reachability rc) { - return ParametersBlock.TopBlock.GetLabel (name, this); + base.MarkReachable (rc); + + if (scope_initializers != null) { + foreach (var si in scope_initializers) + si.MarkReachable (rc); + } } - public override bool Resolve (BlockContext ec) + public override bool Resolve (BlockContext bc) { if ((flags & Flags.Resolved) != 0) return true; - Block prev_block = ec.CurrentBlock; - bool ok = true; - - ec.CurrentBlock = this; - ec.StartFlowBranching (this); + Block prev_block = bc.CurrentBlock; + bc.CurrentBlock = this; // // Compiler generated scope statements // if (scope_initializers != null) { for (resolving_init_idx = 0; resolving_init_idx < scope_initializers.Count; ++resolving_init_idx) { - scope_initializers[resolving_init_idx.Value].Resolve (ec); + scope_initializers[resolving_init_idx.Value].Resolve (bc); } resolving_init_idx = null; } - // - // This flag is used to notate nested statements as unreachable from the beginning of this block. - // For the purposes of this resolution, it doesn't matter that the whole block is unreachable - // from the beginning of the function. The outer Resolve() that detected the unreachability is - // responsible for handling the situation. - // + bool ok = true; int statement_count = statements.Count; for (int ix = 0; ix < statement_count; ix++){ Statement s = statements [ix]; - // - // Warn if we detect unreachable code. - // - if (unreachable) { - if (s is EmptyStatement) - continue; - - if (!unreachable_shown && !(s is LabeledStatement)) { - ec.Report.Warning (162, 2, s.loc, "Unreachable code detected"); - unreachable_shown = true; - } - - Block c_block = s as Block; - if (c_block != null) - c_block.unreachable = c_block.unreachable_shown = true; - } - - // - // Note that we're not using ResolveUnreachable() for unreachable - // statements here. ResolveUnreachable() creates a temporary - // flow branching and kills it afterwards. This leads to problems - // if you have two unreachable statements where the first one - // assigns a variable and the second one tries to access it. - // - - if (!s.Resolve (ec)) { + if (!s.Resolve (bc)) { ok = false; - if (ec.IsInProbingMode) - break; + if (!bc.IsInProbingMode) + statements [ix] = new EmptyStatement (s.loc); - statements [ix] = new EmptyStatement (s.loc); continue; } - - if (unreachable && !(s is LabeledStatement) && !(s is Block)) - statements [ix] = new EmptyStatement (s.loc); - - unreachable = ec.CurrentBranching.CurrentUsageVector.IsUnreachable; - if (unreachable && s is LabeledStatement) - throw new InternalErrorException ("should not happen"); } - while (ec.CurrentBranching is FlowBranchingLabeled) - ec.EndFlowBranching (); - - bool flow_unreachable = ec.EndFlowBranching (); - - ec.CurrentBlock = prev_block; - - if (flow_unreachable) - flags |= Flags.HasRet; - - // If we're a non-static `struct' constructor which doesn't have an - // initializer, then we must initialize all of the struct's fields. - if (this == ParametersBlock.TopBlock && !ParametersBlock.TopBlock.IsThisAssigned (ec) && !flow_unreachable) - ok = false; + bc.CurrentBlock = prev_block; flags |= Flags.Resolved; return ok; } - public override bool ResolveUnreachable (BlockContext ec, bool warn) - { - unreachable_shown = true; - unreachable = true; - - if (warn) - ec.Report.Warning (162, 2, loc, "Unreachable code detected"); - - var fb = ec.StartFlowBranching (FlowBranching.BranchingType.Block, loc); - fb.CurrentUsageVector.IsUnreachable = true; - bool ok = Resolve (ec); - ec.KillFlowBranching (); - - return ok; - } - protected override void DoEmit (EmitContext ec) { for (int ix = 0; ix < statements.Count; ix++){ @@ -2370,10 +2960,118 @@ namespace Mono.CSharp { s.Emit (ec); } + protected override bool DoFlowAnalysis (FlowAnalysisContext fc) + { + if (scope_initializers != null) { + foreach (var si in scope_initializers) + si.FlowAnalysis (fc); + } + + return DoFlowAnalysis (fc, 0); + } + + bool DoFlowAnalysis (FlowAnalysisContext fc, int startIndex) + { + bool end_unreachable = !reachable; + for (; startIndex < statements.Count; ++startIndex) { + var s = statements[startIndex]; + + end_unreachable = s.FlowAnalysis (fc); + if (s.IsUnreachable) { + statements [startIndex] = RewriteUnreachableStatement (s); + continue; + } + + // + // Statement end reachability is needed mostly due to goto support. Consider + // + // if (cond) { + // goto X; + // } else { + // goto Y; + // } + // X: + // + // X label is reachable only via goto not as another statement after if. We need + // this for flow-analysis only to carry variable info correctly. + // + if (end_unreachable) { + for (++startIndex; startIndex < statements.Count; ++startIndex) { + s = statements[startIndex]; + if (s is SwitchLabel) { + s.FlowAnalysis (fc); + break; + } + + if (s.IsUnreachable) { + s.FlowAnalysis (fc); + statements [startIndex] = RewriteUnreachableStatement (s); + } + } + } + } + + // + // The condition should be true unless there is forward jumping goto + // + // if (this is ExplicitBlock && end_unreachable != Explicit.HasReachableClosingBrace) + // Debug.Fail (); + + return !Explicit.HasReachableClosingBrace; + } + + static Statement RewriteUnreachableStatement (Statement s) + { + // LAMESPEC: It's not clear whether declararion statement should be part of reachability + // analysis. Even csc report unreachable warning for it but it's actually used hence + // we try to emulate this behaviour + // + // Consider: + // goto L; + // int v; + // L: + // v = 1; + + if (s is BlockVariable) + return s; + + return new EmptyStatement (s.loc); + } + + public void ScanGotoJump (Statement label) + { + int i; + for (i = 0; i < statements.Count; ++i) { + if (statements[i] == label) + break; + } + + var rc = new Reachability (); + for (++i; i < statements.Count; ++i) { + var s = statements[i]; + rc = s.MarkReachable (rc); + if (rc.IsUnreachable) + return; + } + + flags |= Flags.ReachableEnd; + } + + public void ScanGotoJump (Statement label, FlowAnalysisContext fc) + { + int i; + for (i = 0; i < statements.Count; ++i) { + if (statements[i] == label) + break; + } + + DoFlowAnalysis (fc, ++i); + } + #if DEBUG public override string ToString () { - return String.Format ("{0} ({1}:{2})", GetType (), ID, StartLocation); + return String.Format ("{0}: ID={1} Clone={2} Location={3}", GetType (), ID, clone_id != 0, StartLocation); } #endif @@ -2381,7 +3079,7 @@ namespace Mono.CSharp { { Block target = (Block) t; #if DEBUG - target.clone_id = clone_id_counter++; + target.clone_id = ++clone_id_counter; #endif clonectx.AddBlockMap (this, target); @@ -2456,6 +3154,15 @@ namespace Mono.CSharp { } } + public bool HasReachableClosingBrace { + get { + return (flags & Flags.ReachableEnd) != 0; + } + set { + flags = value ? flags | Flags.ReachableEnd : flags & ~Flags.ReachableEnd; + } + } + public bool HasYield { get { return (flags & Flags.YieldBlock) != 0; @@ -2488,8 +3195,11 @@ namespace Mono.CSharp { return am_storey; } - public override void Emit (EmitContext ec) + public void EmitScopeInitialization (EmitContext ec) { + if ((flags & Flags.InitializationEmitted) != 0) + return; + if (am_storey != null) { DefineStoreyContainer (ec, am_storey); am_storey.EmitStoreyInstantiation (ec, this); @@ -2498,6 +3208,13 @@ namespace Mono.CSharp { if (scope_initializers != null) EmitScopeInitializers (ec); + flags |= Flags.InitializationEmitted; + } + + public override void Emit (EmitContext ec) + { + EmitScopeInitialization (ec); + if (ec.EmitAccurateDebugInfo && !IsCompilerGenerated && ec.Mark (StartLocation)) { ec.Emit (OpCodes.Nop); } @@ -2510,7 +3227,8 @@ namespace Mono.CSharp { if (Parent != null) ec.EndScope (); - if (ec.EmitAccurateDebugInfo && !HasUnreachableClosingBrace && !IsCompilerGenerated && ec.Mark (EndLocation)) { + if (ec.EmitAccurateDebugInfo && HasReachableClosingBrace && !(this is ParametersBlock) && + !IsCompilerGenerated && ec.Mark (EndLocation)) { ec.Emit (OpCodes.Nop); } } @@ -2534,16 +3252,26 @@ namespace Mono.CSharp { // Only first storey in path will hold this reference. All children blocks will // reference it indirectly using $ref field // - for (Block b = Original.Explicit.Parent; b != null; b = b.Parent) { - var s = b.Explicit.AnonymousMethodStorey; - if (s != null) { - storey.HoistedThis = s.HoistedThis; - break; + for (Block b = Original.Explicit; b != null; b = b.Parent) { + if (b.Parent != null) { + var s = b.Parent.Explicit.AnonymousMethodStorey; + if (s != null) { + storey.HoistedThis = s.HoistedThis; + break; + } } - } + if (b.Explicit == b.Explicit.ParametersBlock && b.Explicit.ParametersBlock.StateMachine != null) { + if (storey.HoistedThis == null) + storey.HoistedThis = b.Explicit.ParametersBlock.StateMachine.HoistedThis; + + if (storey.HoistedThis != null) + break; + } + } + // - // We are the first storey on path and this has to be hoisted + // We are the first storey on path and 'this' has to be hoisted // if (storey.HoistedThis == null) { foreach (ExplicitBlock ref_block in Original.ParametersBlock.TopBlock.ThisReferencesFromChildrenBlock) { @@ -2559,32 +3287,82 @@ namespace Mono.CSharp { if (block_on_path == null) continue; - if (storey.HoistedThis == null) - storey.AddCapturedThisField (ec); + if (storey.HoistedThis == null) { + storey.AddCapturedThisField (ec, null); + } for (ExplicitBlock b = ref_block; b.AnonymousMethodStorey != storey; b = b.Parent.Explicit) { - if (b.AnonymousMethodStorey != null) { - b.AnonymousMethodStorey.AddParentStoreyReference (ec, storey); - b.AnonymousMethodStorey.HoistedThis = storey.HoistedThis; + ParametersBlock pb; + AnonymousMethodStorey b_storey = b.AnonymousMethodStorey; + + if (b_storey != null) { + // + // Don't add storey cross reference for `this' when the storey ends up not + // beeing attached to any parent + // + if (b.ParametersBlock.StateMachine == null) { + AnonymousMethodStorey s = null; + for (Block ab = b.AnonymousMethodStorey.OriginalSourceBlock.Parent; ab != null; ab = ab.Parent) { + s = ab.Explicit.AnonymousMethodStorey; + if (s != null) + break; + } + + // Needs to be in sync with AnonymousMethodBody::DoCreateMethodHost + if (s == null) { + var parent = storey == null || storey.Kind == MemberKind.Struct ? null : storey; + b.AnonymousMethodStorey.AddCapturedThisField (ec, parent); + break; + } + + } // // Stop propagation inside same top block // - if (b.ParametersBlock == ParametersBlock.Original) + if (b.ParametersBlock == ParametersBlock.Original) { + b_storey.AddParentStoreyReference (ec, storey); +// b_storey.HoistedThis = storey.HoistedThis; break; + } - b = b.ParametersBlock; + b = pb = b.ParametersBlock; + } else { + pb = b as ParametersBlock; } - var pb = b as ParametersBlock; if (pb != null && pb.StateMachine != null) { if (pb.StateMachine == storey) break; + // + // If we are state machine with no parent. We can hook into parent without additional + // reference and capture this directly + // + ExplicitBlock parent_storey_block = pb; + while (parent_storey_block.Parent != null) { + parent_storey_block = parent_storey_block.Parent.Explicit; + if (parent_storey_block.AnonymousMethodStorey != null) { + break; + } + } + + if (parent_storey_block.AnonymousMethodStorey == null) { + pb.StateMachine.AddCapturedThisField (ec, null); + b.HasCapturedThis = true; + continue; + } + pb.StateMachine.AddParentStoreyReference (ec, storey); } - b.HasCapturedVariable = true; + // + // Add parent storey reference only when this is not captured directly + // + if (b_storey != null) { + b_storey.AddParentStoreyReference (ec, storey); + b_storey.HoistedThis = storey.HoistedThis; + } } } } @@ -2620,6 +3398,7 @@ namespace Mono.CSharp { } storey.Define (); + storey.PrepareEmit (); storey.Parent.PartialContainer.AddCompilerGeneratedClass (storey); } @@ -2638,6 +3417,8 @@ namespace Mono.CSharp { public void RegisterIteratorYield () { + ParametersBlock.TopBlock.IsIterator = true; + var block = this; while ((block.flags & Flags.YieldBlock) == 0) { block.flags |= Flags.YieldBlock; @@ -2649,6 +3430,16 @@ namespace Mono.CSharp { } } + public void SetCatchBlock () + { + flags |= Flags.CatchBlock; + } + + public void SetFinallyBlock () + { + flags |= Flags.FinallyBlock; + } + public void WrapIntoDestructor (TryFinally tf, ExplicitBlock tryBlock) { tryBlock.statements = statements; @@ -2784,12 +3575,12 @@ namespace Mono.CSharp { protected ParametersCompiled parameters; protected ParameterInfo[] parameter_info; - bool resolved; - protected bool unreachable; + protected bool resolved; protected ToplevelBlock top_block; protected StateMachine state_machine; + protected Dictionary labels; - public ParametersBlock (Block parent, ParametersCompiled parameters, Location start) + public ParametersBlock (Block parent, ParametersCompiled parameters, Location start, Flags flags = 0) : base (parent, 0, start, start) { if (parameters == null) @@ -2798,7 +3589,7 @@ namespace Mono.CSharp { this.parameters = parameters; ParametersBlock = this; - flags |= (parent.ParametersBlock.flags & (Flags.YieldBlock | Flags.AwaitBlock)); + this.flags |= flags | (parent.ParametersBlock.flags & (Flags.YieldBlock | Flags.AwaitBlock)); this.top_block = parent.ParametersBlock.top_block; ProcessParameters (); @@ -2825,9 +3616,10 @@ namespace Mono.CSharp { this.scope_initializers = source.scope_initializers; this.resolved = true; - this.unreachable = source.unreachable; + this.reachable = source.reachable; this.am_storey = source.am_storey; this.state_machine = source.state_machine; + this.flags = source.flags & Flags.ReachableEnd; ParametersBlock = this; @@ -2835,7 +3627,7 @@ namespace Mono.CSharp { // Overwrite original for comparison purposes when linking cross references // between anonymous methods // - Original = source; + Original = source.Original; } #region Properties @@ -2889,36 +3681,76 @@ namespace Mono.CSharp { #endregion - // - // Check whether all `out' parameters have been assigned. - // - public void CheckOutParameters (FlowBranching.UsageVector vector) + // + // Checks whether all `out' parameters have been assigned. + // + public void CheckControlExit (FlowAnalysisContext fc) { - if (vector.IsUnreachable) - return; - - int n = parameter_info == null ? 0 : parameter_info.Length; + CheckControlExit (fc, fc.DefiniteAssignment); + } - for (int i = 0; i < n; i++) { - VariableInfo var = parameter_info[i].VariableInfo; + public virtual void CheckControlExit (FlowAnalysisContext fc, DefiniteAssignmentBitSet dat) + { + if (parameter_info == null) + return; - if (var == null) + foreach (var p in parameter_info) { + if (p.VariableInfo == null) continue; - if (vector.IsAssigned (var, false)) + if (p.VariableInfo.IsAssigned (dat)) continue; - var p = parameter_info[i].Parameter; - TopBlock.Report.Error (177, p.Location, + fc.Report.Error (177, p.Location, "The out parameter `{0}' must be assigned to before control leaves the current method", - p.Name); + p.Parameter.Name); + } + } + + protected override void CloneTo (CloneContext clonectx, Statement t) + { + base.CloneTo (clonectx, t); + + var target = (ParametersBlock) t; + + // + // Clone label statements as well as they contain block reference + // + var pb = this; + while (true) { + if (pb.labels != null) { + target.labels = new Dictionary (); + + foreach (var entry in pb.labels) { + var list = entry.Value as List; + + if (list != null) { + var list_clone = new List (); + foreach (var lentry in list) { + list_clone.Add (RemapLabeledStatement (lentry, lentry.Block, clonectx.RemapBlockCopy (lentry.Block))); + } + + target.labels.Add (entry.Key, list_clone); + } else { + var labeled = (LabeledStatement) entry.Value; + target.labels.Add (entry.Key, RemapLabeledStatement (labeled, labeled.Block, clonectx.RemapBlockCopy (labeled.Block))); + } + } + + break; + } + + if (pb.Parent == null) + break; + + pb = pb.Parent.ParametersBlock; } } public override Expression CreateExpressionTree (ResolveContext ec) { if (statements.Count == 1) { - Expression expr = ((Statement) statements[0]).CreateExpressionTree (ec); + Expression expr = statements[0].CreateExpressionTree (ec); if (scope_initializers != null) expr = new BlockScopeExpression (expr, this); @@ -2948,6 +3780,62 @@ namespace Mono.CSharp { base.Emit (ec); } + protected override bool DoFlowAnalysis (FlowAnalysisContext fc) + { + var res = base.DoFlowAnalysis (fc); + + if (HasReachableClosingBrace) + CheckControlExit (fc); + + return res; + } + + public LabeledStatement GetLabel (string name, Block block) + { + // + // Cloned parameters blocks can have their own cloned version of top-level labels + // + if (labels == null) { + if (Parent != null) + return Parent.ParametersBlock.GetLabel (name, block); + + return null; + } + + object value; + if (!labels.TryGetValue (name, out value)) { + return null; + } + + var label = value as LabeledStatement; + Block b = block; + if (label != null) { + if (IsLabelVisible (label, b)) + return label; + + } else { + List list = (List) value; + for (int i = 0; i < list.Count; ++i) { + label = list[i]; + if (IsLabelVisible (label, b)) + return label; + } + } + + return null; + } + + static bool IsLabelVisible (LabeledStatement label, Block b) + { + do { + if (label.Block == b) + return true; + b = b.Parent; + } while (b != null); + + return false; + } + public ParameterInfo GetParameterInfo (Parameter p) { for (int i = 0; i < parameters.Count; ++i) { @@ -2987,86 +3875,71 @@ namespace Mono.CSharp { } } - public bool Resolve (FlowBranching parent, BlockContext rc, IMethodData md) + static LabeledStatement RemapLabeledStatement (LabeledStatement stmt, Block src, Block dst) + { + var src_stmts = src.Statements; + for (int i = 0; i < src_stmts.Count; ++i) { + if (src_stmts[i] == stmt) + return (LabeledStatement) dst.Statements[i]; + } + + throw new InternalErrorException ("Should never be reached"); + } + + public override bool Resolve (BlockContext bc) { + // TODO: if ((flags & Flags.Resolved) != 0) + if (resolved) return true; resolved = true; - if (rc.HasSet (ResolveContext.Options.ExpressionTreeConversion)) + if (bc.HasSet (ResolveContext.Options.ExpressionTreeConversion)) flags |= Flags.IsExpressionTree; - try { - ResolveMeta (rc); - - using (rc.With (ResolveContext.Options.DoFlowAnalysis, true)) { - FlowBranchingToplevel top_level = rc.StartFlowBranching (this, parent); - - if (!Resolve (rc)) - return false; - - unreachable = top_level.End (); - } - } catch (Exception e) { - if (e is CompletionResult || rc.Report.IsDisabled || e is FatalException) - throw; - - if (rc.CurrentBlock != null) { - rc.Report.Error (584, rc.CurrentBlock.StartLocation, "Internal compiler error: {0}", e.Message); - } else { - rc.Report.Error (587, "Internal compiler error: {0}", e.Message); - } - - if (rc.Module.Compiler.Settings.DebugFlags > 0) - throw; - } - - if (rc.ReturnType.Kind != MemberKind.Void && !unreachable) { - if (rc.CurrentAnonymousMethod == null) { - // FIXME: Missing FlowAnalysis for generated iterator MoveNext method - if (md is StateMachineMethod) { - unreachable = true; - } else { - rc.Report.Error (161, md.Location, "`{0}': not all code paths return a value", md.GetSignatureForError ()); - return false; - } - } else { - // - // If an asynchronous body of F is either an expression classified as nothing, or a - // statement block where no return statements have expressions, the inferred return type is Task - // - if (IsAsync) { - var am = rc.CurrentAnonymousMethod as AnonymousMethodBody; - if (am != null && am.ReturnTypeInference != null && !am.ReturnTypeInference.HasBounds (0)) { - am.ReturnTypeInference = null; - am.ReturnType = rc.Module.PredefinedTypes.Task.TypeSpec; - return true; - } - } + try { + PrepareAssignmentAnalysis (bc); - rc.Report.Error (1643, rc.CurrentAnonymousMethod.Location, "Not all code paths return a value in anonymous method of type `{0}'", - rc.CurrentAnonymousMethod.GetSignatureForError ()); + if (!base.Resolve (bc)) return false; + + } catch (Exception e) { + if (e is CompletionResult || bc.Report.IsDisabled || e is FatalException || bc.Report.Printer is NullReportPrinter || bc.Module.Compiler.Settings.BreakOnInternalError) + throw; + + if (bc.CurrentBlock != null) { + bc.Report.Error (584, bc.CurrentBlock.StartLocation, "Internal compiler error: {0}", e.Message); + } else { + bc.Report.Error (587, "Internal compiler error: {0}", e.Message); + } + } + + // + // If an asynchronous body of F is either an expression classified as nothing, or a + // statement block where no return statements have expressions, the inferred return type is Task + // + if (IsAsync) { + var am = bc.CurrentAnonymousMethod as AnonymousMethodBody; + if (am != null && am.ReturnTypeInference != null && !am.ReturnTypeInference.HasBounds (0)) { + am.ReturnTypeInference = null; + am.ReturnType = bc.Module.PredefinedTypes.Task.TypeSpec; + return true; } } return true; } - void ResolveMeta (BlockContext ec) + void PrepareAssignmentAnalysis (BlockContext bc) { - int orig_count = parameters.Count; - - for (int i = 0; i < orig_count; ++i) { - Parameter.Modifier mod = parameters.FixedParameters[i].ModFlags; + for (int i = 0; i < parameters.Count; ++i) { + var par = parameters.FixedParameters[i]; - if ((mod & Parameter.Modifier.OUT) == 0) + if ((par.ModFlags & Parameter.Modifier.OUT) == 0) continue; - VariableInfo vi = new VariableInfo (parameters, i, ec.FlowOffset); - parameter_info[i].VariableInfo = vi; - ec.FlowOffset += vi.Length; + parameter_info [i].VariableInfo = VariableInfo.Create (bc, (Parameter) par); } } @@ -3078,15 +3951,14 @@ namespace Mono.CSharp { state_machine = stateMachine; iterator.SetStateMachine (stateMachine); - var tlb = new ToplevelBlock (host.Compiler, Parameters, Location.Null); + var tlb = new ToplevelBlock (host.Compiler, Parameters, Location.Null, Flags.CompilerGenerated); tlb.Original = this; - tlb.IsCompilerGenerated = true; tlb.state_machine = stateMachine; tlb.AddStatement (new Return (iterator, iterator.Location)); return tlb; } - public ParametersBlock ConvertToAsyncTask (IMemberContext context, TypeDefinition host, ParametersCompiled parameters, TypeSpec returnType, Location loc) + public ParametersBlock ConvertToAsyncTask (IMemberContext context, TypeDefinition host, ParametersCompiled parameters, TypeSpec returnType, TypeSpec delegateType, Location loc) { for (int i = 0; i < parameters.Count; i++) { Parameter p = parameters[i]; @@ -3118,22 +3990,22 @@ namespace Mono.CSharp { var block_type = host.Module.Compiler.BuiltinTypes.Void; var initializer = new AsyncInitializer (this, host, block_type); initializer.Type = block_type; + initializer.DelegateType = delegateType; var stateMachine = new AsyncTaskStorey (this, context, initializer, returnType); state_machine = stateMachine; initializer.SetStateMachine (stateMachine); + const Flags flags = Flags.CompilerGenerated; + var b = this is ToplevelBlock ? - new ToplevelBlock (host.Compiler, Parameters, Location.Null) : - new ParametersBlock (Parent, parameters, Location.Null) { - IsAsync = true, - }; + new ToplevelBlock (host.Compiler, Parameters, Location.Null, flags) : + new ParametersBlock (Parent, parameters, Location.Null, flags | Flags.HasAsyncModifier); b.Original = this; - b.IsCompilerGenerated = true; b.state_machine = stateMachine; - b.AddStatement (new StatementExpression (initializer)); + b.AddStatement (new AsyncInitializerStatement (initializer)); return b; } } @@ -3146,7 +4018,6 @@ namespace Mono.CSharp { LocalVariable this_variable; CompilerContext compiler; Dictionary names; - Dictionary labels; List this_references; @@ -3155,12 +4026,12 @@ namespace Mono.CSharp { { } - public ToplevelBlock (CompilerContext ctx, ParametersCompiled parameters, Location start) + public ToplevelBlock (CompilerContext ctx, ParametersCompiled parameters, Location start, Flags flags = 0) : base (parameters, start) { this.compiler = ctx; + this.flags = flags; top_block = this; - flags |= Flags.HasRet; ProcessParameters (); } @@ -3176,12 +4047,14 @@ namespace Mono.CSharp { { this.compiler = source.TopBlock.compiler; top_block = this; - flags |= Flags.HasRet; } public bool IsIterator { get { - return HasYield; + return (flags & Flags.Iterator) != 0; + } + set { + flags = value ? flags | Flags.Iterator : flags & ~Flags.Iterator; } } @@ -3234,18 +4107,19 @@ namespace Mono.CSharp { // // A collision checking between local names // + var variable_block = li.Block.Explicit; for (int i = 0; i < existing_list.Count; ++i) { existing = existing_list[i]; Block b = existing.Block.Explicit; // Collision at same level - if (li.Block.Explicit == b) { + if (variable_block == b) { li.Block.Error_AlreadyDeclared (name, li); break; } // Collision with parent - Block parent = li.Block.Explicit; + Block parent = variable_block; while ((parent = parent.Parent) != null) { if (parent == b) { li.Block.Error_AlreadyDeclared (name, li, "parent or current"); @@ -3254,10 +4128,10 @@ namespace Mono.CSharp { } } - if (!ignoreChildrenBlocks) { + if (!ignoreChildrenBlocks && variable_block.Parent != b.Parent) { // Collision with children while ((b = b.Parent) != null) { - if (li.Block.Explicit == b) { + if (variable_block == b) { li.Block.Error_AlreadyDeclared (name, li, "child"); i = existing_list.Count; break; @@ -3352,8 +4226,23 @@ namespace Mono.CSharp { int count = parameters.Count; Arguments args = new Arguments (count); for (int i = 0; i < count; ++i) { - var arg_expr = GetParameterReference (i, parameter_info[i].Location); - args.Add (new Argument (arg_expr)); + var pi = parameter_info[i]; + var arg_expr = GetParameterReference (i, pi.Location); + + Argument.AType atype_modifier; + switch (pi.Parameter.ParameterModifier & Parameter.Modifier.RefOutMask) { + case Parameter.Modifier.REF: + atype_modifier = Argument.AType.Ref; + break; + case Parameter.Modifier.OUT: + atype_modifier = Argument.AType.Out; + break; + default: + atype_modifier = 0; + break; + } + + args.Add (new Argument (arg_expr, atype_modifier)); } return args; @@ -3419,41 +4308,6 @@ namespace Mono.CSharp { return false; } - public LabeledStatement GetLabel (string name, Block block) - { - if (labels == null) - return null; - - object value; - if (!labels.TryGetValue (name, out value)) { - return null; - } - - var label = value as LabeledStatement; - Block b = block; - if (label != null) { - if (label.Block == b.Original) - return label; - - // TODO: Temporary workaround for the switch block implicit label block - if (label.Block.IsCompilerGenerated && label.Block.Parent == b.Original) - return label; - } else { - List list = (List) value; - for (int i = 0; i < list.Count; ++i) { - label = list[i]; - if (label.Block == b.Original) - return label; - - // TODO: Temporary workaround for the switch block implicit label block - if (label.Block.IsCompilerGenerated && label.Block.Parent == b.Original) - return label; - } - } - - return null; - } - // // This is used by non-static `struct' constructors which do not have an // initializer - in this case, the constructor must initialize all of the @@ -3468,12 +4322,19 @@ namespace Mono.CSharp { this_variable = new LocalVariable (this, "this", LocalVariable.Flags.IsThis | LocalVariable.Flags.Used, StartLocation); this_variable.Type = bc.CurrentType; - this_variable.PrepareForFlowAnalysis (bc); + this_variable.PrepareAssignmentAnalysis (bc); } - public bool IsThisAssigned (BlockContext ec) + public override void CheckControlExit (FlowAnalysisContext fc, DefiniteAssignmentBitSet dat) { - return this_variable == null || this_variable.IsThisAssigned (ec, this); + // + // If we're a non-static struct constructor which doesn't have an + // initializer, then we must initialize all of the struct's fields. + // + if (this_variable != null) + this_variable.IsThisAssigned (fc, this); + + base.CheckControlExit (fc, dat); } public override void Emit (EmitContext ec) @@ -3481,9 +4342,7 @@ namespace Mono.CSharp { if (Report.Errors > 0) return; -#if PRODUCTION try { -#endif if (IsCompilerGenerated) { using (ec.With (BuilderContext.Options.OmitDebugInfo, true)) { base.Emit (ec); @@ -3504,7 +4363,7 @@ namespace Mono.CSharp { // As a workaround, we're always creating a return label in // this case. // - if (ec.HasReturnLabel || !unreachable) { + if (ec.HasReturnLabel || HasReachableClosingBrace) { if (ec.HasReturnLabel) ec.MarkLabel (ec.ReturnLabel); @@ -3517,22 +4376,48 @@ namespace Mono.CSharp { ec.Emit (OpCodes.Ret); } -#if PRODUCTION - } catch (Exception e){ - Console.WriteLine ("Exception caught by the compiler while emitting:"); - Console.WriteLine (" Block that caused the problem begin at: " + block.loc); - - Console.WriteLine (e.GetType ().FullName + ": " + e.Message); - throw; + } catch (Exception e) { + throw new InternalErrorException (e, StartLocation); } -#endif + } + + public bool Resolve (BlockContext bc, IMethodData md) + { + if (resolved) + return true; + + var errors = bc.Report.Errors; + + base.Resolve (bc); + + if (bc.Report.Errors > errors) + return false; + + MarkReachable (new Reachability ()); + + if (HasReachableClosingBrace && bc.ReturnType.Kind != MemberKind.Void) { + // TODO: var md = bc.CurrentMemberDefinition; + bc.Report.Error (161, md.Location, "`{0}': not all code paths return a value", md.GetSignatureForError ()); + } + + if ((flags & Flags.NoFlowAnalysis) != 0) + return true; + + var fc = new FlowAnalysisContext (bc.Module.Compiler, this, bc.AssignmentInfoOffset); + try { + FlowAnalysis (fc); + } catch (Exception e) { + throw new InternalErrorException (e, StartLocation); + } + + return true; } } - public class SwitchLabel { - Expression label; + public class SwitchLabel : Statement + { Constant converted; - readonly Location loc; + Expression label; Label? il_label; @@ -3568,10 +4453,12 @@ namespace Mono.CSharp { return converted; } set { - converted = value; + converted = value; } } + public bool SectionStart { get; set; } + public Label GetILLabel (EmitContext ec) { if (il_label == null){ @@ -3581,75 +4468,81 @@ namespace Mono.CSharp { return il_label.Value; } + protected override void DoEmit (EmitContext ec) + { + ec.MarkLabel (GetILLabel (ec)); + } + + protected override bool DoFlowAnalysis (FlowAnalysisContext fc) + { + if (!SectionStart) + return false; + + fc.DefiniteAssignment = new DefiniteAssignmentBitSet (fc.SwitchInitialDefinitiveAssignment); + return false; + } + + public override bool Resolve (BlockContext bc) + { + if (ResolveAndReduce (bc)) + bc.Switch.RegisterLabel (bc, this); + + return true; + } + // // Resolves the expression, reduces it to a literal if possible // and then converts it to the requested type. // - public bool ResolveAndReduce (ResolveContext ec, TypeSpec required_type, bool allow_nullable) - { - Expression e = label.Resolve (ec); - - if (e == null) - return false; + bool ResolveAndReduce (BlockContext rc) + { + if (IsDefault) + return true; - Constant c = e as Constant; - if (c == null){ - ec.Report.Error (150, loc, "A constant value is expected"); + var c = label.ResolveLabelConstant (rc); + if (c == null) return false; - } - if (allow_nullable && c is NullLiteral) { + if (rc.Switch.IsNullable && c is NullLiteral) { converted = c; return true; } - converted = c.ImplicitConversionRequired (ec, required_type, loc); + converted = c.ImplicitConversionRequired (rc, rc.Switch.SwitchType); return converted != null; } - public void Error_AlreadyOccurs (ResolveContext ec, TypeSpec switch_type, SwitchLabel collision_with) + public void Error_AlreadyOccurs (ResolveContext ec, SwitchLabel collision_with) { - string label; - if (converted == null) - label = "default"; - else - label = converted.GetValueAsLiteral (); - ec.Report.SymbolRelatedToPreviousError (collision_with.loc, null); - ec.Report.Error (152, loc, "The label `case {0}:' already occurs in this switch statement", label); + ec.Report.Error (152, loc, "The label `{0}' already occurs in this switch statement", GetSignatureForError ()); } - public SwitchLabel Clone (CloneContext clonectx) + protected override void CloneTo (CloneContext clonectx, Statement target) { - if (label == null) - return this; - - return new SwitchLabel (label.Clone (clonectx), loc); + var t = (SwitchLabel) target; + if (label != null) + t.label = label.Clone (clonectx); } - } - public class SwitchSection { - public readonly List Labels; - public readonly Block Block; - - public SwitchSection (List labels, Block block) + public override object Accept (StructuralVisitor visitor) { - Labels = labels; - Block = block; + return visitor.Visit (this); } - public SwitchSection Clone (CloneContext clonectx) + public string GetSignatureForError () { - var cloned_labels = new List (); + string label; + if (converted == null) + label = "default"; + else + label = converted.GetValueAsLiteral (); - foreach (SwitchLabel sl in Labels) - cloned_labels.Add (sl.Clone (clonectx)); - - return new SwitchSection (cloned_labels, clonectx.LookupBlock (Block)); + return string.Format ("case {0}:", label); } } - - public class Switch : Statement + + public class Switch : LoopStatement { // structure used to hold blocks of keys while calculating table switch sealed class LabelsRange : IComparable @@ -3701,33 +4594,58 @@ namespace Mono.CSharp { } } - sealed class LabelMarker : Statement + sealed class DispatchStatement : Statement { - readonly Switch s; - readonly List labels; + readonly Switch body; - public LabelMarker (Switch s, List labels) + public DispatchStatement (Switch body) { - this.s = s; - this.labels = labels; + this.body = body; } protected override void CloneTo (CloneContext clonectx, Statement target) { + throw new NotImplementedException (); + } + + protected override bool DoFlowAnalysis (FlowAnalysisContext fc) + { + return false; } protected override void DoEmit (EmitContext ec) { - foreach (var l in labels) { - if (l.IsDefault) - ec.MarkLabel (s.DefaultLabel); - else - ec.MarkLabel (l.GetILLabel (ec)); - } + body.EmitDispatch (ec); + } + } + + class MissingBreak : Statement + { + SwitchLabel label; + + public MissingBreak (SwitchLabel sl) + { + this.label = sl; + this.loc = sl.loc; + } + + protected override void DoEmit (EmitContext ec) + { + } + + protected override void CloneTo (CloneContext clonectx, Statement target) + { + } + + protected override bool DoFlowAnalysis (FlowAnalysisContext fc) + { + fc.Report.Error (163, loc, "Control cannot fall through from one case label `{0}' to another", + label.GetSignatureForError ()); + + return true; } } - public List Sections; public Expression Expr; // @@ -3735,64 +4653,64 @@ namespace Mono.CSharp { // Dictionary labels; Dictionary string_labels; + List case_labels; + + List> goto_cases; + List end_reachable_das; /// /// The governing switch type /// public TypeSpec SwitchType; - // - // Computed - // - Label default_target; - Label null_target; Expression new_expr; - bool is_constant; - SwitchSection constant_section; - SwitchSection default_section; - SwitchLabel null_section; + SwitchLabel case_null; + SwitchLabel case_default; - Statement simple_stmt; + Label defaultLabel, nullLabel; VariableReference value; ExpressionStatement string_dictionary; FieldExpr switch_cache_field; ExplicitBlock block; + bool end_reachable; // // Nullable Types support // Nullable.Unwrap unwrap; - public Switch (Expression e, ExplicitBlock block, List sects, Location l) + public Switch (Expression e, ExplicitBlock block, Location l) + : base (block) { Expr = e; this.block = block; - Sections = sects; loc = l; } + public SwitchLabel ActiveLabel { get; set; } + public ExplicitBlock Block { get { return block; } } - public Label DefaultLabel { + public SwitchLabel DefaultLabel { get { - return default_target; + return case_default; } } - public bool GotDefault { + public bool IsNullable { get { - return default_section != null; + return unwrap != null; } } - public bool IsNullable { + public List RegisteredLabels { get { - return unwrap != null; + return case_labels; } } @@ -3869,62 +4787,40 @@ namespace Mono.CSharp { }; } - // - // Performs the basic sanity checks on the switch statement - // (looks for duplicate keys and non-constant expressions). - // - // It also returns a hashtable with the keys that we will later - // use to compute the switch tables - // - bool CheckSwitch (ResolveContext ec) + public void RegisterLabel (BlockContext rc, SwitchLabel sl) { - bool error = false; - if (SwitchType.BuiltinType == BuiltinTypeSpec.Type.String) - string_labels = new Dictionary (Sections.Count + 1); - else - labels = new Dictionary (Sections.Count + 1); - - foreach (SwitchSection ss in Sections){ - foreach (SwitchLabel sl in ss.Labels){ - if (sl.IsDefault){ - if (default_section != null){ - sl.Error_AlreadyOccurs (ec, SwitchType, default_section.Labels [0]); - error = true; - } - default_section = ss; - continue; - } + case_labels.Add (sl); - if (!sl.ResolveAndReduce (ec, SwitchType, IsNullable)) { - error = true; - continue; - } - - try { - if (string_labels != null) { - string s = sl.Converted.GetValue () as string; - if (s == null) - null_section = sl; - else - string_labels.Add (s, sl); - } else { - if (sl.Converted is NullLiteral) { - null_section = sl; - } else { - labels.Add (sl.Converted.GetValueAsLong (), sl); - } - } - } catch (ArgumentException) { - if (string_labels != null) - sl.Error_AlreadyOccurs (ec, SwitchType, string_labels[(string) sl.Converted.GetValue ()]); - else - sl.Error_AlreadyOccurs (ec, SwitchType, labels[sl.Converted.GetValueAsLong ()]); + if (sl.IsDefault) { + if (case_default != null) { + sl.Error_AlreadyOccurs (rc, case_default); + } else { + case_default = sl; + } + + return; + } - error = true; + try { + if (string_labels != null) { + string string_value = sl.Converted.GetValue () as string; + if (string_value == null) + case_null = sl; + else + string_labels.Add (string_value, sl); + } else { + if (sl.Converted is NullLiteral) { + case_null = sl; + } else { + labels.Add (sl.Converted.GetValueAsLong (), sl); } } + } catch (ArgumentException) { + if (string_labels != null) + sl.Error_AlreadyOccurs (rc, string_labels[(string) sl.Converted.GetValue ()]); + else + sl.Error_AlreadyOccurs (rc, labels[sl.Converted.GetValueAsLong ()]); } - return !error; } // @@ -3936,8 +4832,6 @@ namespace Mono.CSharp { // void EmitTableSwitch (EmitContext ec, Expression val) { - Label lbl_default = default_target; - if (labels != null && labels.Count > 0) { List ranges; if (string_labels != null) { @@ -3970,17 +4864,21 @@ namespace Mono.CSharp { ranges.Sort (); } + Label lbl_default = defaultLabel; TypeSpec compare_type = SwitchType.IsEnum ? EnumSpec.GetUnderlyingType (SwitchType) : SwitchType; for (int range_index = ranges.Count - 1; range_index >= 0; --range_index) { LabelsRange kb = ranges[range_index]; - lbl_default = (range_index == 0) ? default_target : ec.DefineLabel (); + lbl_default = (range_index == 0) ? defaultLabel : ec.DefineLabel (); // Optimize small ranges using simple equality check if (kb.Range <= 2) { foreach (var key in kb.label_values) { SwitchLabel sl = labels[key]; - if (sl.Converted.IsDefaultValue) { + if (sl == case_default || sl == case_null) + continue; + + if (sl.Converted.IsZeroInteger) { val.EmitBranchable (ec, sl.GetILLabel (ec), false); } else { val.Emit (ec); @@ -4051,52 +4949,25 @@ namespace Mono.CSharp { if (ranges.Count > 0) ec.Emit (OpCodes.Br, lbl_default); } - - // now emit the code for the sections - bool found_default = false; - - foreach (SwitchSection ss in Sections) { - foreach (SwitchLabel sl in ss.Labels) { - if (sl.IsDefault) { - ec.MarkLabel (lbl_default); - found_default = true; - if (null_section == null) - ec.MarkLabel (null_target); - } else if (sl.Converted.IsNull) { - ec.MarkLabel (null_target); - } - - ec.MarkLabel (sl.GetILLabel (ec)); - } - - ss.Block.Emit (ec); - } - - if (!found_default) { - ec.MarkLabel (lbl_default); - if (null_section == null) { - ec.MarkLabel (null_target); - } - } } - - SwitchLabel FindLabel (Constant value) + + public SwitchLabel FindLabel (Constant value) { SwitchLabel sl = null; if (string_labels != null) { string s = value.GetValue () as string; if (s == null) { - if (null_section != null) - sl = null_section; - else if (default_section != null) - sl = default_section.Labels[0]; + if (case_null != null) + sl = case_null; + else if (case_default != null) + sl = case_default; } else { string_labels.TryGetValue (s, out sl); } } else { if (value is NullLiteral) { - sl = null_section; + sl = case_null; } else { labels.TryGetValue (value.GetValueAsLong (), out sl); } @@ -4105,16 +4976,27 @@ namespace Mono.CSharp { return sl; } - SwitchSection FindSection (SwitchLabel label) + protected override bool DoFlowAnalysis (FlowAnalysisContext fc) { - foreach (SwitchSection ss in Sections){ - foreach (SwitchLabel sl in ss.Labels){ - if (label == sl) - return ss; - } + Expr.FlowAnalysis (fc); + + var prev_switch = fc.SwitchInitialDefinitiveAssignment; + var InitialDefinitiveAssignment = fc.DefiniteAssignment; + fc.SwitchInitialDefinitiveAssignment = InitialDefinitiveAssignment; + + block.FlowAnalysis (fc); + + fc.SwitchInitialDefinitiveAssignment = prev_switch; + + if (end_reachable_das != null) { + var sections_das = DefiniteAssignmentBitSet.And (end_reachable_das); + InitialDefinitiveAssignment |= sections_das; + end_reachable_das = null; } - return null; + fc.DefiniteAssignment = InitialDefinitiveAssignment; + + return case_default != null && !end_reachable; } public override bool Resolve (BlockContext ec) @@ -4133,10 +5015,13 @@ namespace Mono.CSharp { new_expr = SwitchGoverningType (ec, unwrap); } - if (new_expr == null){ - ec.Report.Error (151, loc, - "A switch expression of type `{0}' cannot be converted to an integral type, bool, char, string, enum or nullable type", - TypeManager.CSharpName (Expr.Type)); + if (new_expr == null) { + if (Expr.Type != InternalType.ErrorType) { + ec.Report.Error (151, loc, + "A switch expression of type `{0}' cannot be converted to an integral type, bool, char, string, enum or nullable type", + Expr.Type.GetSignatureForError ()); + } + return false; } @@ -4148,127 +5033,190 @@ namespace Mono.CSharp { return false; } - if (!CheckSwitch (ec)) - return false; + if (block.Statements.Count == 0) + return true; - Switch old_switch = ec.Switch; - ec.Switch = this; - ec.Switch.SwitchType = SwitchType; + if (SwitchType.BuiltinType == BuiltinTypeSpec.Type.String) { + string_labels = new Dictionary (); + } else { + labels = new Dictionary (); + } - ec.StartFlowBranching (FlowBranching.BranchingType.Switch, loc); + case_labels = new List (); var constant = new_expr as Constant; - if (constant != null) { - is_constant = true; - SwitchLabel label = FindLabel (constant); - if (label != null) - constant_section = FindSection (label); - if (constant_section == null) - constant_section = default_section; - } else { + // + // Don't need extra variable for constant switch or switch with + // only default case + // + if (constant == null) { // - // Store switch expression for comparission purposes + // Store switch expression for comparison purposes // value = new_expr as VariableReference; - if (value == null) + if (value == null && !HasOnlyDefaultSection ()) { + var current_block = ec.CurrentBlock; + ec.CurrentBlock = Block; + // Create temporary variable inside switch scope value = TemporaryVariableReference.Create (SwitchType, ec.CurrentBlock, loc); + value.Resolve (ec); + ec.CurrentBlock = current_block; + } } - bool first = true; - bool ok = true; - foreach (SwitchSection ss in Sections){ - if (!first) - ec.CurrentBranching.CreateSibling ( - null, FlowBranching.SiblingType.SwitchSection); - else - first = false; - - if (is_constant && (ss != constant_section)) { - // If we're a constant switch, we're only emitting - // one single section - mark all the others as - // unreachable. - ec.CurrentBranching.CurrentUsageVector.Goto (); - if (!ss.Block.ResolveUnreachable (ec, true)) { - ok = false; + Switch old_switch = ec.Switch; + ec.Switch = this; + var parent_los = ec.EnclosingLoopOrSwitch; + ec.EnclosingLoopOrSwitch = this; + + var ok = Statement.Resolve (ec); + + ec.EnclosingLoopOrSwitch = parent_los; + ec.Switch = old_switch; + + // + // Check if all goto cases are valid. Needs to be done after switch + // is resolved because goto can jump forward in the scope. + // + if (goto_cases != null) { + foreach (var gc in goto_cases) { + if (gc.Item1 == null) { + if (DefaultLabel == null) { + Goto.Error_UnknownLabel (ec, "default", loc); + } + + continue; + } + + var sl = FindLabel (gc.Item2); + if (sl == null) { + Goto.Error_UnknownLabel (ec, "case " + gc.Item2.GetValueAsLiteral (), loc); + } else { + gc.Item1.Label = sl; } - } else { - if (!ss.Block.Resolve (ec)) - ok = false; } } - if (default_section == null) - ec.CurrentBranching.CreateSibling (null, FlowBranching.SiblingType.SwitchSection); + if (!ok) + return false; + + if (constant == null && SwitchType.BuiltinType == BuiltinTypeSpec.Type.String && string_labels.Count > 6) { + ResolveStringSwitchMap (ec); + } + + // + // Anonymous storey initialization has to happen before + // any generated switch dispatch + // + block.InsertStatement (0, new DispatchStatement (this)); + + return true; + } + + bool HasOnlyDefaultSection () + { + for (int i = 0; i < block.Statements.Count; ++i) { + var s = block.Statements[i] as SwitchLabel; - ec.EndFlowBranching (); - ec.Switch = old_switch; + if (s == null || s.IsDefault) + continue; - if (!ok) return false; - - if (!is_constant) { - if (SwitchType.BuiltinType == BuiltinTypeSpec.Type.String) { - if (string_labels.Count < 7) - ResolveSimpleSwitch (ec); - else - ResolveStringSwitchMap (ec); - } else if (labels.Count < 3 && !IsNullable) { - ResolveSimpleSwitch (ec); - } } return true; } - public SwitchLabel ResolveGotoCase (ResolveContext rc, Constant value) + public override Reachability MarkReachable (Reachability rc) { - var sl = FindLabel (value); + if (rc.IsUnreachable) + return rc; - if (sl == null) { - FlowBranchingBlock.Error_UnknownLabel (loc, "case " + value.GetValueAsLiteral (), rc.Report); - } + base.MarkReachable (rc); - return sl; - } + block.MarkReachableScope (rc); - // - // Prepares switch using simple if/else comparison for small label count (4 + optional default) - // - void ResolveSimpleSwitch (BlockContext bc) - { - simple_stmt = default_section != null ? default_section.Block : null; + if (block.Statements.Count == 0) + return rc; - for (int i = Sections.Count - 1; i >= 0; --i) { - var s = Sections[i]; + SwitchLabel constant_label = null; + var constant = new_expr as Constant; - if (s == default_section) { - s.Block.AddScopeStatement (new LabelMarker (this, s.Labels)); - continue; + if (constant != null) { + constant_label = FindLabel (constant) ?? case_default; + if (constant_label == null) { + block.Statements.RemoveAt (0); + return rc; } + } - s.Block.AddScopeStatement (new LabelMarker (this, s.Labels)); + var section_rc = new Reachability (); + SwitchLabel prev_label = null; - Expression cond = null; - for (int ci = 0; ci < s.Labels.Count; ++ci) { - var e = new Binary (Binary.Operator.Equality, value, s.Labels[ci].Converted); + for (int i = 0; i < block.Statements.Count; ++i) { + var s = block.Statements[i]; + var sl = s as SwitchLabel; + + if (sl != null && sl.SectionStart) { + // + // Section is marked already via constant switch or goto case + // + if (!sl.IsUnreachable) { + section_rc = new Reachability (); + continue; + } - if (ci > 0) { - cond = new Binary (Binary.Operator.LogicalOr, cond, e); + if (section_rc.IsUnreachable) { + section_rc = new Reachability (); } else { - cond = e; + if (prev_label != null) { + sl.SectionStart = false; + s = new MissingBreak (prev_label); + s.MarkReachable (rc); + block.Statements.Insert (i - 1, s); + ++i; + } } + + prev_label = sl; + + if (constant_label != null && constant_label != sl) + section_rc = Reachability.CreateUnreachable (); } - // - // Compiler generated, hide from symbol file - // - simple_stmt = new If (cond, s.Block, simple_stmt, Location.Null); + section_rc = s.MarkReachable (section_rc); } - // It's null for empty switch - if (simple_stmt != null) - simple_stmt.Resolve (bc); + if (!section_rc.IsUnreachable && prev_label != null) { + prev_label.SectionStart = false; + var s = new MissingBreak (prev_label); + s.MarkReachable (rc); + block.Statements.Add (s); + } + + // + // Reachability can affect parent only when all possible paths are handled but + // we still need to run reachability check on switch body to check for fall-through + // + if (case_default == null && constant_label == null) + return rc; + + // + // We have at least one local exit from the switch + // + if (end_reachable) + return rc; + + return Reachability.CreateUnreachable (); + } + + public void RegisterGotoCase (GotoCase gotoCase, Constant value) + { + if (goto_cases == null) + goto_cases = new List> (); + + goto_cases.Add (Tuple.Create (gotoCase, value)); } // @@ -4298,37 +5246,28 @@ namespace Mono.CSharp { ctype.AddField (field); var init = new List (); - int counter = 0; + int counter = -1; labels = new Dictionary (string_labels.Count); string value = null; - foreach (SwitchSection section in Sections) { - bool contains_label = false; - foreach (SwitchLabel sl in section.Labels) { - if (sl.IsDefault || sl.Converted.IsNull) - continue; - if (!contains_label) { - labels.Add (counter, sl); - contains_label = true; - } + foreach (SwitchLabel sl in case_labels) { - value = (string) sl.Converted.GetValue (); - var init_args = new List (2); - init_args.Add (new StringLiteral (ec.BuiltinTypes, value, sl.Location)); + if (sl.SectionStart) + labels.Add (++counter, sl); - sl.Converted = new IntConstant (ec.BuiltinTypes, counter, loc); - init_args.Add (sl.Converted); + if (sl == case_default || sl == case_null) + continue; - init.Add (new CollectionElementInitializer (init_args, loc)); - } + value = (string) sl.Converted.GetValue (); + var init_args = new List (2); + init_args.Add (new StringLiteral (ec.BuiltinTypes, value, sl.Location)); - // - // Don't add empty sections - // - if (contains_label) - ++counter; - } + sl.Converted = new IntConstant (ec.BuiltinTypes, counter, loc); + init_args.Add (sl.Converted); + init.Add (new CollectionElementInitializer (init_args, loc)); + } + Arguments args = new Arguments (1); args.Add (new Argument (new IntConstant (ec.BuiltinTypes, init.Count, loc))); Expression initializer = new NewInitialize (string_dictionary_type, args, @@ -4345,7 +5284,7 @@ namespace Mono.CSharp { // // Skip initialization when value is null // - value.EmitBranchable (ec, null_target, false); + value.EmitBranchable (ec, nullLabel, false); // // Check if string dictionary is initialized and initialize @@ -4371,7 +5310,7 @@ namespace Mono.CSharp { // // A value was not found, go to default case // - get_item.EmitBranchable (ec, default_target, false); + get_item.EmitBranchable (ec, defaultLabel, false); } else { Arguments get_value_args = new Arguments (1); get_value_args.Add (new Argument (value)); @@ -4382,7 +5321,7 @@ namespace Mono.CSharp { LocalTemporary get_item_object = new LocalTemporary (ec.BuiltinTypes.Object); get_item_object.EmitAssign (ec, get_item, true, false); - ec.Emit (OpCodes.Brfalse, default_target); + ec.Emit (OpCodes.Brfalse, defaultLabel); ExpressionStatement get_item_int = (ExpressionStatement) new SimpleAssign (string_switch_variable, new Cast (new TypeExpression (ec.BuiltinTypes.Int, loc), get_item_object, loc)).Resolve (rc); @@ -4395,49 +5334,118 @@ namespace Mono.CSharp { string_switch_variable.Release (ec); } - protected override void DoEmit (EmitContext ec) + // + // Emits switch using simple if/else comparison for small label count (4 + optional default) + // + void EmitShortSwitch (EmitContext ec) { - // Workaround broken flow-analysis - block.HasUnreachableClosingBrace = true; + MethodSpec equal_method = null; + if (SwitchType.BuiltinType == BuiltinTypeSpec.Type.String) { + equal_method = ec.Module.PredefinedMembers.StringEqual.Resolve (loc); + } - // - // Needed to emit anonymous storey initialization - // Otherwise it does not contain any statements for now - // - block.Emit (ec); + if (equal_method != null) { + value.EmitBranchable (ec, nullLabel, false); + } + + for (int i = 0; i < case_labels.Count; ++i) { + var label = case_labels [i]; + if (label == case_default || label == case_null) + continue; + + var constant = label.Converted; + + if (equal_method != null) { + value.Emit (ec); + constant.Emit (ec); + + var call = new CallEmitter (); + call.EmitPredefined (ec, equal_method, new Arguments (0)); + ec.Emit (OpCodes.Brtrue, label.GetILLabel (ec)); + continue; + } - default_target = ec.DefineLabel (); - null_target = ec.DefineLabel (); + if (constant.IsZeroInteger && constant.Type.BuiltinType != BuiltinTypeSpec.Type.Long && constant.Type.BuiltinType != BuiltinTypeSpec.Type.ULong) { + value.EmitBranchable (ec, label.GetILLabel (ec), false); + continue; + } + + value.Emit (ec); + constant.Emit (ec); + ec.Emit (OpCodes.Beq, label.GetILLabel (ec)); + } + + ec.Emit (OpCodes.Br, defaultLabel); + } + + void EmitDispatch (EmitContext ec) + { + if (value == null) { + // + // Constant switch, we've already done the work if there is only 1 label + // referenced + // + int reachable = 0; + foreach (var sl in case_labels) { + if (sl.IsUnreachable) + continue; + + if (reachable++ > 0) { + var constant = (Constant) new_expr; + var constant_label = FindLabel (constant) ?? case_default; + + ec.Emit (OpCodes.Br, constant_label.GetILLabel (ec)); + break; + } + } - if (IsNullable) { - unwrap.EmitCheck (ec); - ec.Emit (OpCodes.Brfalse, null_target); - value.EmitAssign (ec, new_expr, false, false); - } else if (new_expr != value && !is_constant) { - value.EmitAssign (ec, new_expr, false, false); + return; + } + + if (string_dictionary != null) { + DoEmitStringSwitch (ec); + } else if (case_labels.Count < 4 || string_labels != null) { + EmitShortSwitch (ec); + } else { + EmitTableSwitch (ec, value); } + } + protected override void DoEmit (EmitContext ec) + { // // Setup the codegen context // Label old_end = ec.LoopEnd; Switch old_switch = ec.Switch; - + ec.LoopEnd = ec.DefineLabel (); ec.Switch = this; - // Emit Code. - if (is_constant) { - if (constant_section != null) - constant_section.Block.Emit (ec); - } else if (string_dictionary != null) { - DoEmitStringSwitch (ec); - } else if (simple_stmt != null) { - simple_stmt.Emit (ec); - } else { - EmitTableSwitch (ec, value); + defaultLabel = case_default == null ? ec.LoopEnd : case_default.GetILLabel (ec); + nullLabel = case_null == null ? defaultLabel : case_null.GetILLabel (ec); + + if (value != null) { + ec.Mark (loc); + if (IsNullable) { + unwrap.EmitCheck (ec); + ec.Emit (OpCodes.Brfalse, nullLabel); + value.EmitAssign (ec, new_expr, false, false); + } else if (new_expr != value) { + value.EmitAssign (ec, new_expr, false, false); + } + + + // + // Next statement is compiler generated we don't need extra + // nop when we can use the statement for sequence point + // + ec.Mark (block.StartLocation); + block.IsCompilerGenerated = true; } + block.Emit (ec); + // Restore context state. ec.MarkLabel (ec.LoopEnd); @@ -4453,19 +5461,32 @@ namespace Mono.CSharp { Switch target = (Switch) t; target.Expr = Expr.Clone (clonectx); - target.Sections = new List (); - foreach (SwitchSection ss in Sections){ - target.Sections.Add (ss.Clone (clonectx)); - } + target.Statement = target.block = (ExplicitBlock) block.Clone (clonectx); } public override object Accept (StructuralVisitor visitor) { return visitor.Visit (this); } + + public override void AddEndDefiniteAssignment (FlowAnalysisContext fc) + { + if (case_default == null) + return; + + if (end_reachable_das == null) + end_reachable_das = new List (); + + end_reachable_das.Add (fc.DefiniteAssignment); + } + + public override void SetEndReachable () + { + end_reachable = true; + } } - // A place where execution can restart in an iterator + // A place where execution can restart in a state machine public abstract class ResumableStatement : Statement { bool prepared; @@ -4530,10 +5551,10 @@ namespace Mono.CSharp { EmitTryBodyPrepare (ec); EmitTryBody (ec); - ec.BeginFinallyBlock (); + bool beginFinally = EmitBeginFinallyBlock (ec); Label start_finally = ec.DefineLabel (); - if (resume_points != null) { + if (resume_points != null && beginFinally) { var state_machine = (StateMachineInitializer) ec.CurrentAnonymousMethod; ec.Emit (OpCodes.Ldloc, state_machine.SkipFinally); @@ -4545,6 +5566,7 @@ namespace Mono.CSharp { if (finally_host != null) { finally_host.Define (); + finally_host.PrepareEmit (); finally_host.Emit (); // Now it's safe to add, to close it properly and emit sequence points @@ -4557,7 +5579,8 @@ namespace Mono.CSharp { EmitFinallyBody (ec); } - ec.EndExceptionBlock (); + if (beginFinally) + ec.EndExceptionBlock (); } public override void EmitForDispose (EmitContext ec, LocalBuilder pc, Label end, bool have_dispatcher) @@ -4624,8 +5647,38 @@ namespace Mono.CSharp { ec.EndExceptionBlock (); } + protected override bool DoFlowAnalysis (FlowAnalysisContext fc) + { + var res = stmt.FlowAnalysis (fc); + parent = null; + return res; + } + + protected virtual bool EmitBeginFinallyBlock (EmitContext ec) + { + ec.BeginFinallyBlock (); + return true; + } + + public override Reachability MarkReachable (Reachability rc) + { + base.MarkReachable (rc); + return Statement.MarkReachable (rc); + } + public override bool Resolve (BlockContext bc) { + bool ok; + + parent = bc.CurrentTryBlock; + bc.CurrentTryBlock = this; + + using (bc.Set (ResolveContext.Options.TryScope)) { + ok = stmt.Resolve (bc); + } + + bc.CurrentTryBlock = parent; + // // Finally block inside iterator is called from MoveNext and // Dispose methods that means we need to lift the block into @@ -4639,7 +5692,7 @@ namespace Mono.CSharp { } } - return base.Resolve (bc); + return base.Resolve (bc) && ok; } } @@ -4648,11 +5701,9 @@ namespace Mono.CSharp { // public abstract class ExceptionStatement : ResumableStatement { -#if !STATIC - bool code_follows; -#endif protected List resume_points; protected int first_resume_pc; + protected ExceptionStatement parent; protected ExceptionStatement (Location loc) { @@ -4687,26 +5738,18 @@ namespace Mono.CSharp { } } - public void SomeCodeFollows () + public virtual int AddResumePoint (ResumableStatement stmt, int pc, StateMachineInitializer stateMachine) { -#if !STATIC - code_follows = true; -#endif - } + if (parent != null) { + // TODO: MOVE to virtual TryCatch + var tc = this as TryCatch; + var s = tc != null && tc.IsTryCatchFinally ? stmt : this; - public override bool Resolve (BlockContext ec) - { -#if !STATIC - // System.Reflection.Emit automatically emits a 'leave' at the end of a try clause - // So, ensure there's some IL code after this statement. - if (!code_follows && resume_points == null && ec.CurrentBranching.CurrentUsageVector.IsUnreachable) - ec.NeedReturnLabel (); -#endif - return true; - } + pc = parent.AddResumePoint (s, pc, stateMachine); + } else { + pc = stateMachine.AddResumePoint (this); + } - public void AddResumePoint (ResumableStatement stmt, int pc) - { if (resume_points == null) { resume_points = new List (); first_resume_pc = pc; @@ -4716,8 +5759,8 @@ namespace Mono.CSharp { throw new InternalErrorException ("missed an intervening AddResumePoint?"); resume_points.Add (stmt); + return pc; } - } public class Lock : TryFinallyBlock @@ -4780,17 +5823,13 @@ namespace Mono.CSharp { } using (ec.Set (ResolveContext.Options.LockScope)) { - ec.StartFlowBranching (this); - Statement.Resolve (ec); - ec.EndFlowBranching (); + base.Resolve (ec); } if (lv != null) { lv.IsLockedByStatement = locked; } - base.Resolve (ec); - return true; } @@ -4901,6 +5940,17 @@ namespace Mono.CSharp { Block.Emit (ec); } + protected override bool DoFlowAnalysis (FlowAnalysisContext fc) + { + return Block.FlowAnalysis (fc); + } + + public override Reachability MarkReachable (Reachability rc) + { + base.MarkReachable (rc); + return Block.MarkReachable (rc); + } + protected override void CloneTo (CloneContext clonectx, Statement t) { Unchecked target = (Unchecked) t; @@ -4936,6 +5986,17 @@ namespace Mono.CSharp { Block.Emit (ec); } + protected override bool DoFlowAnalysis (FlowAnalysisContext fc) + { + return Block.FlowAnalysis (fc); + } + + public override Reachability MarkReachable (Reachability rc) + { + base.MarkReachable (rc); + return Block.MarkReachable (rc); + } + protected override void CloneTo (CloneContext clonectx, Statement t) { Checked target = (Checked) t; @@ -4973,6 +6034,17 @@ namespace Mono.CSharp { Block.Emit (ec); } + protected override bool DoFlowAnalysis (FlowAnalysisContext fc) + { + return Block.FlowAnalysis (fc); + } + + public override Reachability MarkReachable (Reachability rc) + { + base.MarkReachable (rc); + return Block.MarkReachable (rc); + } + protected override void CloneTo (CloneContext clonectx, Statement t) { Unsafe target = (Unsafe) t; @@ -5002,6 +6074,11 @@ namespace Mono.CSharp { } public abstract void EmitExit (EmitContext ec); + + public override void FlowAnalysis (FlowAnalysisContext fc) + { + expr.FlowAnalysis (fc); + } } class ExpressionEmitter : Emitter { @@ -5035,7 +6112,7 @@ namespace Mono.CSharp { { LocalVariable pinned_string; - public StringEmitter (Expression expr, LocalVariable li, Location loc) + public StringEmitter (Expression expr, LocalVariable li) : base (expr, li) { } @@ -5082,8 +6159,7 @@ namespace Mono.CSharp { } } - - public class VariableDeclaration : BlockVariableDeclaration + public class VariableDeclaration : BlockVariable { public VariableDeclaration (FullNamedExpression type, LocalVariable li) : base (type, li) @@ -5159,7 +6235,7 @@ namespace Mono.CSharp { // Case 2: string // if (initializer.Type.BuiltinType == BuiltinTypeSpec.Type.String) { - return new StringEmitter (initializer, li, loc).Resolve (bc); + return new StringEmitter (initializer, li).Resolve (bc); } // Case 3: fixed buffer @@ -5208,7 +6284,7 @@ namespace Mono.CSharp { } } - public BlockVariableDeclaration Variables { + public BlockVariable Variables { get { return decl; } @@ -5216,19 +6292,20 @@ namespace Mono.CSharp { #endregion - public override bool Resolve (BlockContext ec) + public override bool Resolve (BlockContext bc) { - using (ec.Set (ResolveContext.Options.FixedInitializerScope)) { - if (!decl.Resolve (ec)) + using (bc.Set (ResolveContext.Options.FixedInitializerScope)) { + if (!decl.Resolve (bc)) return false; } - ec.StartFlowBranching (FlowBranching.BranchingType.Conditional, loc); - bool ok = statement.Resolve (ec); - bool flow_unreachable = ec.EndFlowBranching (); - has_ret = flow_unreachable; + return statement.Resolve (bc); + } - return ok; + protected override bool DoFlowAnalysis (FlowAnalysisContext fc) + { + decl.FlowAnalysis (fc); + return statement.FlowAnalysis (fc); } protected override void DoEmit (EmitContext ec) @@ -5258,6 +6335,19 @@ namespace Mono.CSharp { } } + public override Reachability MarkReachable (Reachability rc) + { + base.MarkReachable (rc); + + decl.MarkReachable (rc); + + rc = statement.MarkReachable (rc); + + // TODO: What if there is local exit? + has_ret = rc.IsUnreachable; + return rc; + } + protected override void CloneTo (CloneContext clonectx, Statement t) { Fixed target = (Fixed) t; @@ -5274,13 +6364,77 @@ namespace Mono.CSharp { public class Catch : Statement { - Block block; + class FilterStatement : Statement + { + readonly Catch ctch; + + public FilterStatement (Catch ctch) + { + this.ctch = ctch; + } + + protected override void CloneTo (CloneContext clonectx, Statement target) + { + } + + protected override void DoEmit (EmitContext ec) + { + if (ctch.li != null) { + if (ctch.hoisted_temp != null) + ctch.hoisted_temp.Emit (ec); + else + ctch.li.Emit (ec); + } + + var expr_start = ec.DefineLabel (); + var end = ec.DefineLabel (); + + ec.Emit (OpCodes.Brtrue_S, expr_start); + ec.EmitInt (0); + ec.Emit (OpCodes.Br, end); + ec.MarkLabel (expr_start); + + ctch.Filter.Emit (ec); + + ec.MarkLabel (end); + ec.Emit (OpCodes.Endfilter); + ec.BeginFilterHandler (); + ec.Emit (OpCodes.Pop); + } + + protected override bool DoFlowAnalysis (FlowAnalysisContext fc) + { + ctch.Filter.FlowAnalysis (fc); + return true; + } + + public override bool Resolve (BlockContext bc) + { + ctch.Filter = ctch.Filter.Resolve (bc); + + if (ctch.Filter != null) { + if (ctch.Filter.ContainsEmitWithAwait ()) { + bc.Report.Error (7094, ctch.Filter.Location, "The `await' operator cannot be used in the filter expression of a catch clause"); + } + + var c = ctch.Filter as Constant; + if (c != null && !c.IsDefaultValue) { + bc.Report.Warning (7095, 1, ctch.Filter.Location, "Exception filter expression is a constant"); + } + } + + return true; + } + } + + ExplicitBlock block; LocalVariable li; FullNamedExpression type_expr; CompilerAssign assign; TypeSpec type; + LocalTemporary hoisted_temp; - public Catch (Block block, Location loc) + public Catch (ExplicitBlock block, Location loc) { this.block = block; this.loc = loc; @@ -5288,7 +6442,7 @@ namespace Mono.CSharp { #region Properties - public Block Block { + public ExplicitBlock Block { get { return block; } @@ -5300,6 +6454,10 @@ namespace Mono.CSharp { } } + public Expression Filter { + get; set; + } + public bool IsGeneral { get { return type_expr == null; @@ -5328,46 +6486,77 @@ namespace Mono.CSharp { protected override void DoEmit (EmitContext ec) { + if (Filter != null) { + ec.BeginExceptionFilterBlock (); + ec.Emit (OpCodes.Isinst, IsGeneral ? ec.BuiltinTypes.Object : CatchType); + + if (li != null) + EmitCatchVariableStore (ec); + + if (Block.HasAwait) { + Block.EmitScopeInitialization (ec); + } else { + Block.Emit (ec); + } + + return; + } + if (IsGeneral) ec.BeginCatchBlock (ec.BuiltinTypes.Object); else ec.BeginCatchBlock (CatchType); if (li != null) { - li.CreateBuilder (ec); - - // - // Special case hoisted catch variable, we have to use a temporary variable - // to pass via anonymous storey initialization with the value still on top - // of the stack - // - if (li.HoistedVariant != null) { - LocalTemporary lt = new LocalTemporary (li.Type); - lt.Store (ec); - - // switch to assigning from the temporary variable and not from top of the stack - assign.UpdateSource (lt); - } + EmitCatchVariableStore (ec); } else { ec.Emit (OpCodes.Pop); } - Block.Emit (ec); + if (!Block.HasAwait) + Block.Emit (ec); } - public override bool Resolve (BlockContext ec) + void EmitCatchVariableStore (EmitContext ec) + { + li.CreateBuilder (ec); + + // + // Special case hoisted catch variable, we have to use a temporary variable + // to pass via anonymous storey initialization with the value still on top + // of the stack + // + if (li.HoistedVariant != null) { + hoisted_temp = new LocalTemporary (li.Type); + hoisted_temp.Store (ec); + + // switch to assignment from temporary variable and not from top of the stack + assign.UpdateSource (hoisted_temp); + } + } + + public override bool Resolve (BlockContext bc) { - using (ec.With (ResolveContext.Options.CatchScope, true)) { - if (type_expr != null) { - type = type_expr.ResolveAsType (ec); + using (bc.Set (ResolveContext.Options.CatchScope)) { + if (type_expr == null) { + if (CreateExceptionVariable (bc.Module.Compiler.BuiltinTypes.Object)) { + Expression source = new EmptyExpression (li.Type); + assign = new CompilerAssign (new LocalVariableReference (li, Location.Null), source, Location.Null); + Block.AddScopeStatement (new StatementExpression (assign, Location.Null)); + } + } else { + type = type_expr.ResolveAsType (bc); if (type == null) return false; - if (type.BuiltinType != BuiltinTypeSpec.Type.Exception && !TypeSpec.IsBaseClass (type, ec.BuiltinTypes.Exception, false)) { - ec.Report.Error (155, loc, "The type caught or thrown must be derived from System.Exception"); + if (li == null) + CreateExceptionVariable (type); + + if (type.BuiltinType != BuiltinTypeSpec.Type.Exception && !TypeSpec.IsBaseClass (type, bc.BuiltinTypes.Exception, false)) { + bc.Report.Error (155, loc, "The type caught or thrown must be derived from System.Exception"); } else if (li != null) { li.Type = type; - li.PrepareForFlowAnalysis (ec); + li.PrepareAssignmentAnalysis (bc); // source variable is at the top of the stack Expression source = new EmptyExpression (li.Type); @@ -5382,8 +6571,46 @@ namespace Mono.CSharp { } } - return Block.Resolve (ec); + if (Filter != null) { + Block.AddScopeStatement (new FilterStatement (this)); + } + + Block.SetCatchBlock (); + return Block.Resolve (bc); + } + } + + bool CreateExceptionVariable (TypeSpec type) + { + if (!Block.HasAwait) + return false; + + // TODO: Scan the block for rethrow expression + //if (!Block.HasRethrow) + // return; + + li = LocalVariable.CreateCompilerGenerated (type, block, Location.Null); + return true; + } + + protected override bool DoFlowAnalysis (FlowAnalysisContext fc) + { + if (li != null && !li.IsCompilerGenerated) { + fc.SetVariableAssigned (li.VariableInfo, true); } + + return block.FlowAnalysis (fc); + } + + public override Reachability MarkReachable (Reachability rc) + { + base.MarkReachable (rc); + + var c = Filter as Constant; + if (c != null && c.IsDefaultValue) + return Reachability.CreateUnreachable (); + + return block.MarkReachable (rc); } protected override void CloneTo (CloneContext clonectx, Statement t) @@ -5393,75 +6620,276 @@ namespace Mono.CSharp { if (type_expr != null) target.type_expr = (FullNamedExpression) type_expr.Clone (clonectx); - target.block = clonectx.LookupBlock (block); + if (Filter != null) + target.Filter = Filter.Clone (clonectx); + + target.block = (ExplicitBlock) clonectx.LookupBlock (block); } } public class TryFinally : TryFinallyBlock { - Block fini; - + ExplicitBlock fini; + List try_exit_dat; + List /// + /// A sequence of names to use for transparent identifiers. Once the sequence is over, a fallback name generator is used /// - public QueryExpressionExpansionResult ExpandQueryExpressions(AstNode node) { + public QueryExpressionExpansionResult ExpandQueryExpressions(AstNode node, IEnumerable transparentIdentifierNamePicker) { var visitor = new Visitor(); + visitor.TransparentIdentifierNamePicker = transparentIdentifierNamePicker.GetEnumerator(); var astNode = node.AcceptVisitor(visitor); if (astNode != null) { astNode.Freeze(); @@ -353,5 +415,16 @@ namespace ICSharpCode.NRefactory.CSharp { return null; } } + + + /// + /// 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. + /// + /// + /// + public QueryExpressionExpansionResult ExpandQueryExpressions(AstNode node) + { + return ExpandQueryExpressions(node, Enumerable.Empty()); + } } } diff --git a/NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/BaseRefactoringContext.cs b/NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/BaseRefactoringContext.cs index 32a84ba23..3f8055871 100644 --- a/NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/BaseRefactoringContext.cs +++ b/NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/BaseRefactoringContext.cs @@ -36,6 +36,8 @@ using ICSharpCode.NRefactory.Editor; using System.ComponentModel.Design; using ICSharpCode.NRefactory.CSharp.Analysis; using ICSharpCode.NRefactory.Utils; +using System.Collections.Generic; +using ICSharpCode.NRefactory.Analysis; namespace ICSharpCode.NRefactory.CSharp.Refactoring { @@ -49,6 +51,13 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring return true; } + /// + /// Gets the default namespace which should be defined in this file. + /// + public abstract string DefaultNamespace { + get; + } + /// /// Gets a value indicating if 'var' keyword should be used or explicit types. /// @@ -83,10 +92,18 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring get { return resolver.Compilation; } } + /// + /// Gets the type graph for the current compilation. + /// + public virtual TypeGraph TypeGraph { + get { return new TypeGraph(Compilation.Assemblies); } + } + public BaseRefactoringContext (ICSharpCode.NRefactory.CSharp.Resolver.CSharpAstResolver resolver, System.Threading.CancellationToken cancellationToken) { this.resolver = resolver; this.cancellationToken = cancellationToken; + this.referenceFinder = new LocalReferenceFinder(resolver); } @@ -120,6 +137,12 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring { return resolver.GetConversion(expression, cancellationToken); } + + public TypeSystemAstBuilder CreateTypeSystemAstBuilder(AstNode node) + { + var csResolver = resolver.GetResolverStateBefore(node); + return new TypeSystemAstBuilder(csResolver); + } #endregion #region Code Analyzation @@ -143,12 +166,15 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring /// /// The statement to start the analysis. /// + /// + /// TODO. + /// /// /// The reachability analysis object. /// - public ReachabilityAnalysis CreateReachabilityAnalysis (Statement statement) + public ReachabilityAnalysis CreateReachabilityAnalysis (Statement statement, ReachabilityAnalysis.RecursiveDetectorVisitor recursiveDetectorVisitor = null) { - return ReachabilityAnalysis.Create (statement, resolver, CancellationToken); + return ReachabilityAnalysis.Create (statement, resolver, recursiveDetectorVisitor, CancellationToken); } /// @@ -161,8 +187,102 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring { return new CompositeFormatStringParser().Parse(source); } + + LocalReferenceFinder referenceFinder; + + public IList FindReferences(AstNode rootNode, IVariable variable) + { + return referenceFinder.FindReferences(rootNode, variable); + } + #endregion + + #region Naming + public virtual string GetNameProposal (string name, TextLocation loc, bool camelCase = true) + { + string baseName = (camelCase ? char.ToLower (name [0]) : char.ToUpper (name [0])) + name.Substring (1); + + var type = RootNode.GetNodeAt(loc); + if (type == null) + return baseName; + + int number = -1; + string proposedName; + do { + proposedName = AppendNumberToName (baseName, number++); + } while (type.Members.Select (m => m.GetChildByRole (Roles.Identifier)).Any (n => n.Name == proposedName)); + return proposedName; + } + + public virtual string GetLocalNameProposal (string name, TextLocation loc, bool camelCase = true) + { + string baseName = (camelCase ? char.ToLower (name [0]) : char.ToUpper (name [0])) + name.Substring (1); + var node = RootNode.GetNodeAt(loc); + if (node == null) + return baseName; + + var context = GetResolverStateBefore (node); + int number = -1; + string proposedName; + do { + proposedName = AppendNumberToName (baseName, number++); + } while (!(context.ResolveSimpleName (proposedName, EmptyList.Instance) is UnknownIdentifierResolveResult)); + return proposedName; + } + + static string AppendNumberToName (string baseName, int number) + { + return baseName + (number > 0 ? (number + 1).ToString () : ""); + } + #endregion + + #region Text stuff + public virtual TextEditorOptions TextEditorOptions { + get { + return TextEditorOptions.Default; + } + } + + public virtual bool IsSomethingSelected { + get { + return SelectionStart != TextLocation.Empty; + } + } + + public virtual string SelectedText { + get { return string.Empty; } + } + + public virtual TextLocation SelectionStart { + get { + return TextLocation.Empty; + } + } + + public virtual TextLocation SelectionEnd { + get { + return TextLocation.Empty; + } + } + + public abstract int GetOffset (TextLocation location); + + public abstract IDocumentLine GetLineByOffset (int offset); + + public int GetOffset (int line, int col) + { + return GetOffset (new TextLocation (line, col)); + } + + public abstract TextLocation GetLocation (int offset); + + public abstract string GetText (int offset, int length); + + public abstract string GetText (ISegment segment); + #endregion + + /// /// Translates the english input string to the context language. /// @@ -175,13 +295,14 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring } #region IServiceProvider implementation - readonly ServiceContainer services = new ServiceContainer(); + IServiceContainer services = new ServiceContainer(); /// /// Gets a service container used to associate services with this context. /// - public ServiceContainer Services { + public IServiceContainer Services { get { return services; } + protected set { services = value; } } /// diff --git a/NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/CodeAction.cs b/NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/CodeAction.cs index 3bc59be60..3acd74698 100644 --- a/NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/CodeAction.cs +++ b/NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/CodeAction.cs @@ -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.Refactoring; namespace ICSharpCode.NRefactory.CSharp.Refactoring { @@ -48,6 +49,75 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring private set; } + /// + /// Gets the action start location. + /// + public TextLocation Start { + get; + private set; + } + + /// + /// Gets the action end location. + /// + public TextLocation End { + get; + private set; + } + + /// + /// This property is used to identify which actions are "siblings", ie which actions + /// are the same kind of fix. This is used to group issues when batch fixing them. + /// + /// + /// Although the type is , there is a restriction: The instance + /// used must behave well as a key (for instance in a hash table). Additionaly, this + /// value must be independent of the specific instance + /// which created it. In other words two different instances of the same issue provider + /// implementation should use the same sibling keys for the same kinds of issues. + /// + /// The non-null sibling key if this type of action is batchable, null otherwise. + public object SiblingKey { + get; + private set; + } + + Severity severity = Severity.Suggestion; + + /// + /// Gets or sets the severity of the code action. + /// Actions are sorted according to their Severity. + /// + /// The severity. + public Severity Severity { + get { + return severity; + } + set { + severity = value; + } + } + + const string defaultSiblingKey = "default"; + + /// + /// Initializes a new instance of the class, + /// using a non-null default value for . + /// + /// + /// The description. + /// + /// + /// The code transformation. + /// + /// + /// A node that specifies the start/end positions for the code action. + /// + public CodeAction (string description, Action