/// <summary> /// Compares the order of two using directives. /// </summary> /// <param name="firstUsing"> /// The first using directive. /// </param> /// <param name="secondUsing"> /// The second using directive. /// </param> /// <returns> /// Returns false if the elements are out of order. /// </returns> private bool CompareOrderOfUsingDirectives(UsingDirective firstUsing, UsingDirective secondUsing) { Param.AssertNotNull(firstUsing, "firstUsing"); Param.AssertNotNull(secondUsing, "secondUsing"); if (string.IsNullOrEmpty(firstUsing.Alias)) { if (string.IsNullOrEmpty(secondUsing.Alias)) { bool isFirstSystem = firstUsing.NamespaceType.StartsWith("System", StringComparison.Ordinal) || firstUsing.NamespaceType.StartsWith("global::System", StringComparison.Ordinal); bool isSecondSystem = secondUsing.NamespaceType.StartsWith("System", StringComparison.Ordinal) || secondUsing.NamespaceType.StartsWith("global::System", StringComparison.Ordinal); // Neither of the usings is an alias. First, ensure that System namespaces are placed above all // non-System namespaces. if (isSecondSystem && !isFirstSystem) { this.AddViolation(secondUsing, Rules.SystemUsingDirectivesMustBePlacedBeforeOtherUsingDirectives); return(false); } else if ((isFirstSystem && isSecondSystem) || (!isFirstSystem && !isSecondSystem)) { if (!CheckNamespaceOrdering(firstUsing.NamespaceType, secondUsing.NamespaceType)) { // The usings are not in alphabetical order by namespace. this.AddViolation(firstUsing, Rules.UsingDirectivesMustBeOrderedAlphabeticallyByNamespace); return(false); } } } } else { if (string.IsNullOrEmpty(secondUsing.Alias)) { // The first using is an alias, but the second is not. They are in the wrong order. this.AddViolation(firstUsing, Rules.UsingAliasDirectivesMustBePlacedAfterOtherUsingDirectives); return(false); } else { // Both of the usings are aliases. Verify that they are sorted alphabetically by the alias name. if (string.Compare(firstUsing.Alias, secondUsing.Alias, StringComparison.OrdinalIgnoreCase) > 0) { // The usings are not sorted alphabetically by the alias. this.AddViolation(firstUsing, Rules.UsingAliasDirectivesMustBeOrderedAlphabeticallyByAliasName); return(false); } } } return(true); }
/// <summary> /// Checks the order of the using directives in the given list. /// </summary> /// <param name="usings"> /// The list of using directives. /// </param> private void CheckOrderOfUsingDirectivesInList(List <UsingDirective> usings) { Param.AssertNotNull(usings, "usings"); for (int i = 0; i < usings.Count; ++i) { UsingDirective firstUsing = usings[i]; for (int j = i + 1; j < usings.Count; ++j) { UsingDirective secondUsing = usings[j]; if (!this.CompareOrderOfUsingDirectives(firstUsing, secondUsing)) { break; } } } }
/// <summary> /// Parses and returns a using directive. /// </summary> /// <param name="parent"> /// The parent of the namespace. /// </param> /// <param name="elementReference"> /// A reference to the element being created. /// </param> /// <param name="unsafeCode"> /// Indicates whether the code is marked as unsafe. /// </param> /// <param name="generated"> /// Indicates whether the code is marked as generated code. /// </param> /// <returns> /// Returns the element. /// </returns> private UsingDirective ParseUsingDirective(CsElement parent, Reference<ICodePart> elementReference, bool unsafeCode, bool generated) { Param.AssertNotNull(parent, "parent"); Param.AssertNotNull(elementReference, "elementReference"); Param.Ignore(unsafeCode); Param.Ignore(generated); // Add the using token. Node<CsToken> firstToken = this.tokens.InsertLast(this.GetToken(CsTokenType.Using, SymbolType.Using, elementReference)); int index = this.GetNextCodeSymbolIndex(2); if (index == -1) { throw this.CreateSyntaxException(); } // Check static word introduce in C# 6 Symbol staticSymbol = this.symbols.Peek(index); if (staticSymbol != null && staticSymbol.SymbolType == SymbolType.Static) { CsToken staticToken = this.GetToken(CsTokenType.Static, SymbolType.Static, elementReference); this.tokens.Add(staticToken); } // The next symbol will either be the namespace, or an alias. To determine this, look past this to see if there is an equals sign. Symbol peekAhead = this.GetNextSymbol(SymbolType.Other, elementReference); index = this.GetNextCodeSymbolIndex(2); if (index == -1) { throw this.CreateSyntaxException(); } CsToken alias = null; peekAhead = this.symbols.Peek(index); if (peekAhead.SymbolType == SymbolType.Equals) { // There is an alias. First collect the alias. alias = this.GetToken(CsTokenType.Other, SymbolType.Other, elementReference); this.tokens.Add(alias); // Next collect the equals sign. this.tokens.Add(this.GetOperatorToken(OperatorType.Equals, elementReference)); } // Collect and add the namespace token. TypeToken @namespace = this.GetTypeToken(elementReference, unsafeCode, false); this.tokens.Add(@namespace); // Create the declaration. CsTokenList declarationTokens = new CsTokenList(this.tokens, firstToken, this.tokens.Last); Declaration declaration = new Declaration( declarationTokens, alias == null ? @namespace.Text : alias.Text, ElementType.UsingDirective, AccessModifierType.Public); // Get the closing semicolon. this.tokens.Add(this.GetToken(CsTokenType.Semicolon, SymbolType.Semicolon, elementReference)); // Create the using directive. UsingDirective element = new UsingDirective(this.document, parent, declaration, generated, @namespace.Text, alias == null ? null : alias.Text); elementReference.Target = element; return element; }
/// <summary> /// Compares the order of two using directives. /// </summary> /// <param name="firstUsing"> /// The first using directive. /// </param> /// <param name="secondUsing"> /// The second using directive. /// </param> /// <returns> /// Returns false if the elements are out of order. /// </returns> private bool CompareOrderOfUsingDirectives(UsingDirective firstUsing, UsingDirective secondUsing) { Param.AssertNotNull(firstUsing, "firstUsing"); Param.AssertNotNull(secondUsing, "secondUsing"); if (string.IsNullOrEmpty(firstUsing.Alias)) { if (string.IsNullOrEmpty(secondUsing.Alias)) { bool isFirstSystem = firstUsing.NamespaceType.StartsWith("System", StringComparison.Ordinal) || firstUsing.NamespaceType.StartsWith("global::System", StringComparison.Ordinal); bool isSecondSystem = secondUsing.NamespaceType.StartsWith("System", StringComparison.Ordinal) || secondUsing.NamespaceType.StartsWith("global::System", StringComparison.Ordinal); // Neither of the usings is an alias. First, ensure that System namespaces are placed above all // non-System namespaces. if (isSecondSystem && !isFirstSystem) { this.AddViolation(secondUsing, Rules.SystemUsingDirectivesMustBePlacedBeforeOtherUsingDirectives); return false; } else if ((isFirstSystem && isSecondSystem) || (!isFirstSystem && !isSecondSystem)) { if (!CheckNamespaceOrdering(firstUsing.NamespaceType, secondUsing.NamespaceType)) { // The usings are not in alphabetical order by namespace. this.AddViolation(firstUsing, Rules.UsingDirectivesMustBeOrderedAlphabeticallyByNamespace); return false; } } } } else { if (string.IsNullOrEmpty(secondUsing.Alias)) { // The first using is an alias, but the second is not. They are in the wrong order. this.AddViolation(firstUsing, Rules.UsingAliasDirectivesMustBePlacedAfterOtherUsingDirectives); return false; } else { // Both of the usings are aliases. Verify that they are sorted alphabetically by the alias name. if (string.Compare(firstUsing.Alias, secondUsing.Alias, StringComparison.OrdinalIgnoreCase) > 0) { // The usings are not sorted alphabetically by the alias. this.AddViolation(firstUsing, Rules.UsingAliasDirectivesMustBeOrderedAlphabeticallyByAliasName); return false; } } } return true; }
private int GetUsingGroupIndex(UsingDirective usingDirective) { int result = -1; int index = 0; int wildcardGroup = -1; foreach (IList<string> groupPrefix in this.GroupPrefixes) { foreach (string prefix in groupPrefix) { if (prefix == UsingSettings.UsingWildcard) wildcardGroup = index; if (usingDirective.NamespaceType.StartsWith(prefix, StringComparison.OrdinalIgnoreCase)) { result = index; } } index++; } if ((result == -1) && (wildcardGroup != -1)) result = wildcardGroup; return result; }
/// <summary> /// The save. /// </summary> /// <param name="usingDirective"> /// The using directive. /// </param> private void Save(UsingDirective usingDirective) { var realNamespace = usingDirective.NamespaceType; if (!string.IsNullOrEmpty(usingDirective.Alias)) { var pos = realNamespace.LastIndexOf('.'); if (pos >= 0) { realNamespace = realNamespace.Substring(0, pos); } } this.usingDirectives.Add(realNamespace); if ("Platform".Equals(realNamespace)) { this.IsPlatformUsedInUsingDirectives = true; } this.cppWriter.Write("using namespace "); this.cppWriter.Write(realNamespace.Replace(".", "::")); this.cppWriter.WriteLine(";"); }