public void Generate(CodeGenerator generator) { generator.EnterElement(this); if (ArrayElementType != null) { ArrayElementType.Generate(generator); generator.Write(TokenType.Punctuation, ArraySuffix); generator.ExitElement(); return; } var name = RawName; if (SimplifiedBuiltinTypeNames.TryGetValue(name, out var simplifiedBuiltinTypeName)) { generator.Write(TokenType.Keyword, simplifiedBuiltinTypeName); generator.ExitElement(); return; } if (name == "var") { generator.Write(TokenType.Keyword, name); generator.ExitElement(); return; } if (Global) { generator.Write(TokenType.Keyword, "global"); generator.Write(TokenType.Punctuation, "::"); } var nameBuilder = new StringBuilder(); var namespaceNameLength = 0; { var previousIndex = 0; for (var i = 0; i < name.Length; i++) { var c = name[i]; if (c == '.') { nameBuilder.Append(name.Substring(previousIndex, i - previousIndex).EscapeIdentifier()); namespaceNameLength = nameBuilder.Length; nameBuilder.Append('.'); previousIndex = i + 1; } else if (c == '+') { nameBuilder.Append(name.Substring(previousIndex, i - previousIndex).EscapeIdentifier()).Append('.'); previousIndex = i + 1; } } nameBuilder.Append(previousIndex > 0 ? name.Substring(previousIndex).EscapeIdentifier() : name.EscapeUnqualifiedTypeIdentifier()); } if (namespaceNameLength > 0) { var namespaceRef = new CodeUsingImport(nameBuilder.ToString(0, namespaceNameLength)); var usingSets = generator.UsingSets; foreach (var usingSet in usingSets) { if (usingSet.Contains(namespaceRef)) { var ambiguityDetected = false; var unqualifiedTypeName = nameBuilder.ToString(namespaceNameLength + 1, nameBuilder.Length - namespaceNameLength - 1); var unqualifiedTypeNameWithArity = unqualifiedTypeName + (TypeArguments != null && TypeArguments.Count != 0 ? "`" + TypeArguments.Count : ""); if (TypesByNames.TryGetValue(unqualifiedTypeNameWithArity, out var types)) { foreach (var type in types) { var otherNamespaceRef = new CodeUsingImport(type.NamespaceName); if (namespaceRef != otherNamespaceRef) { foreach (var otherUsingSet in usingSets) { if (otherUsingSet.Contains(otherNamespaceRef)) { ambiguityDetected = true; break; } } } if (ambiguityDetected) { break; } } } ambiguityDetected = ambiguityDetected || generator.Options.PredeclaredTypes.Where(type => type.NamespaceName != namespaceRef.Name && type.TypeName == unqualifiedTypeNameWithArity).Any(); if (!ambiguityDetected) { nameBuilder.Length = 0; nameBuilder.Append(unqualifiedTypeName); } break; } } } { var previousIndex = 0; var typeArgumentStart = 0; for (var characterIndex = 0; characterIndex < nameBuilder.Length;) { if (nameBuilder[characterIndex] == '`') { generator.OutputQualifiedName(TokenType.TypeIdentifier, nameBuilder, previousIndex, characterIndex); characterIndex++; var arity = 0; while (characterIndex < nameBuilder.Length && '0' <= nameBuilder[characterIndex] && nameBuilder[characterIndex] <= '9') { arity = arity * 10 + (nameBuilder[characterIndex] - '0'); characterIndex++; } previousIndex = characterIndex; generator.Write(TokenType.Punctuation, '<'); var first = true; for (var typeArgumentIndex = typeArgumentStart; typeArgumentIndex < typeArgumentStart + arity; typeArgumentIndex++) { var typeArgument = TypeArguments[typeArgumentIndex]; if (first) { first = false; } else { generator.Write(TokenType.Punctuation, ','); if (typeArgument != null) { generator.Write(TokenType.Space, ' '); } } if (typeArgument != null) { typeArgument.Generate(generator); } } typeArgumentStart += arity; generator.Write(TokenType.Punctuation, '>'); } else { characterIndex++; } } if (previousIndex < nameBuilder.Length) { generator.OutputQualifiedName(TokenType.TypeIdentifier, nameBuilder, previousIndex); } } generator.ExitElement(); }