44using System . Collections . Generic ;
55using System . IO ;
66using System . Linq ;
7- using System . Security . Cryptography ;
8- using System . Text ;
97
108namespace Semmle . Extraction . CSharp
119{
@@ -135,34 +133,15 @@ public static bool ContainsTypeParameters(this ITypeSymbol type, Context cx, ISy
135133 /// <param name="subTermAction">The action to apply to syntactic sub terms of this type.</param>
136134 public static void BuildTypeId ( this ITypeSymbol type , Context cx , TextWriter trapFile , Action < Context , TextWriter , ITypeSymbol > subTermAction )
137135 {
138- switch ( type . SpecialType )
136+ if ( type . SpecialType != SpecialType . None )
139137 {
140- case SpecialType . System_Object :
141- case SpecialType . System_Void :
142- case SpecialType . System_Boolean :
143- case SpecialType . System_Char :
144- case SpecialType . System_SByte :
145- case SpecialType . System_Byte :
146- case SpecialType . System_Int16 :
147- case SpecialType . System_UInt16 :
148- case SpecialType . System_Int32 :
149- case SpecialType . System_UInt32 :
150- case SpecialType . System_Int64 :
151- case SpecialType . System_UInt64 :
152- case SpecialType . System_Decimal :
153- case SpecialType . System_Single :
154- case SpecialType . System_Double :
155- case SpecialType . System_String :
156- case SpecialType . System_IntPtr :
157- case SpecialType . System_UIntPtr :
158-
159- /*
160- * Use the keyword ("int" etc) for the built-in types.
161- * This makes the IDs shorter and means that all built-in types map to
162- * the same entities (even when using multiple versions of mscorlib).
163- */
164- trapFile . Write ( type . ToDisplayString ( ) ) ;
165- return ;
138+ /*
139+ * Use the keyword ("int" etc) for the built-in types.
140+ * This makes the IDs shorter and means that all built-in types map to
141+ * the same entities (even when using multiple versions of mscorlib).
142+ */
143+ trapFile . Write ( type . ToDisplayString ( ) ) ;
144+ return ;
166145 }
167146
168147 using ( cx . StackGuard )
@@ -186,7 +165,7 @@ public static void BuildTypeId(this ITypeSymbol type, Context cx, TextWriter tra
186165 case TypeKind . Pointer :
187166 var ptr = ( IPointerTypeSymbol ) type ;
188167 subTermAction ( cx , trapFile , ptr . PointedAtType ) ;
189- trapFile . Write ( "*" ) ;
168+ trapFile . Write ( '*' ) ;
190169 return ;
191170 case TypeKind . TypeParameter :
192171 var tp = ( ITypeParameterSymbol ) type ;
@@ -214,28 +193,8 @@ public static void BuildArraySuffix(this IArrayTypeSymbol array, TextWriter trap
214193 trapFile . Write ( ']' ) ;
215194 }
216195
217- private static void BuildAssembly ( IAssemblySymbol asm , TextWriter trapFile , bool extraPrecise = false )
196+ static void BuildNamedTypeId ( this INamedTypeSymbol named , Context cx , TextWriter trapFile , Action < Context , TextWriter , ITypeSymbol > subTermAction )
218197 {
219- var assembly = asm . Identity ;
220- trapFile . Write ( assembly . Name ) ;
221- trapFile . Write ( '_' ) ;
222- trapFile . Write ( assembly . Version . Major ) ;
223- trapFile . Write ( '.' ) ;
224- trapFile . Write ( assembly . Version . Minor ) ;
225- trapFile . Write ( '.' ) ;
226- trapFile . Write ( assembly . Version . Build ) ;
227- if ( extraPrecise )
228- {
229- trapFile . Write ( '.' ) ;
230- trapFile . Write ( assembly . Version . Revision ) ;
231- }
232- trapFile . Write ( "::" ) ;
233- }
234-
235- public static void BuildNamedTypeId ( this INamedTypeSymbol named , Context cx , TextWriter trapFile , Action < Context , TextWriter , ITypeSymbol > subTermAction )
236- {
237- bool prefixAssembly = ! ( named . ContainingAssembly is null ) ;
238-
239198 if ( named . IsTupleType )
240199 {
241200 trapFile . Write ( '(' ) ;
@@ -258,8 +217,6 @@ public static void BuildNamedTypeId(this INamedTypeSymbol named, Context cx, Tex
258217 }
259218 else if ( named . ContainingNamespace != null )
260219 {
261- if ( prefixAssembly )
262- BuildAssembly ( named . ContainingAssembly , trapFile ) ;
263220 named . ContainingNamespace . BuildNamespace ( cx , trapFile ) ;
264221 }
265222
@@ -290,6 +247,26 @@ public static void BuildNamedTypeId(this INamedTypeSymbol named, Context cx, Tex
290247
291248 static void BuildNamespace ( this INamespaceSymbol ns , Context cx , TextWriter trapFile )
292249 {
250+ // Only include the assembly information in each type ID
251+ // for normal extractions. This is because standalone extractions
252+ // lack assembly information or may be ambiguous.
253+ bool prependAssemblyToTypeId = ! cx . Extractor . Standalone && ns . ContainingAssembly != null ;
254+
255+ if ( prependAssemblyToTypeId )
256+ {
257+ // Note that we exclude the revision number as this has
258+ // been observed to be unstable.
259+ var assembly = ns . ContainingAssembly . Identity ;
260+ trapFile . Write ( assembly . Name ) ;
261+ trapFile . Write ( '_' ) ;
262+ trapFile . Write ( assembly . Version . Major ) ;
263+ trapFile . Write ( '.' ) ;
264+ trapFile . Write ( assembly . Version . Minor ) ;
265+ trapFile . Write ( '.' ) ;
266+ trapFile . Write ( assembly . Version . Build ) ;
267+ trapFile . Write ( "::" ) ;
268+ }
269+
293270 trapFile . WriteSubId ( Namespace . Create ( cx , ns ) ) ;
294271 trapFile . Write ( '.' ) ;
295272 }
@@ -379,7 +356,7 @@ public static void BuildNamedTypeDisplayName(this INamedTypeSymbol namedType, Co
379356 }
380357
381358 trapFile . Write ( namedType . Name ) ;
382- if ( namedType . IsGenericType && namedType . TypeArguments . Any ( ) )
359+ if ( namedType . IsGenericType && namedType . TypeKind != TypeKind . Error && namedType . TypeArguments . Any ( ) )
383360 {
384361 trapFile . Write ( '<' ) ;
385362 trapFile . BuildList ( "," , namedType . TypeArguments , ( p , tb0 ) =>
@@ -478,30 +455,6 @@ public static TypeInfo GetTypeInfo(this Context cx, Microsoft.CodeAnalysis.CShar
478455 public static SymbolInfo GetSymbolInfo ( this Context cx , Microsoft . CodeAnalysis . CSharp . CSharpSyntaxNode node ) =>
479456 cx . GetModel ( node ) . GetSymbolInfo ( node ) ;
480457
481- /// <summary>
482- /// Gets the symbol for a particular syntax node.
483- /// Throws an exception if the symbol is not found.
484- /// </summary>
485- ///
486- /// <remarks>
487- /// This gives a nicer message than a "null pointer exception",
488- /// and should be used where we require a symbol to be resolved.
489- /// </remarks>
490- ///
491- /// <param name="cx">The extraction context.</param>
492- /// <param name="node">The syntax node.</param>
493- /// <returns>The resolved symbol.</returns>
494- public static ISymbol GetSymbol ( this Context cx , Microsoft . CodeAnalysis . CSharp . CSharpSyntaxNode node )
495- {
496- var info = GetSymbolInfo ( cx , node ) ;
497- if ( info . Symbol == null )
498- {
499- throw new InternalError ( node , "Could not resolve symbol" ) ;
500- }
501-
502- return info . Symbol ;
503- }
504-
505458 /// <summary>
506459 /// Determines the type of a node, or default
507460 /// if the type could not be determined.
@@ -515,84 +468,11 @@ public static AnnotatedTypeSymbol GetType(this Context cx, Microsoft.CodeAnalysi
515468 return new AnnotatedTypeSymbol ( info . Type . DisambiguateType ( ) , info . Nullability . Annotation ) ;
516469 }
517470
518- /// <summary>
519- /// Gets the annotated type of an IPropertySymbol.
520- /// This has not yet been exposed on the public API.
521- /// </summary>
522- public static AnnotatedTypeSymbol GetAnnotatedType ( this IPropertySymbol symbol ) => new AnnotatedTypeSymbol ( symbol . Type , symbol . NullableAnnotation ) ;
523-
524- /// <summary>
525- /// Gets the annotated type of an IFieldSymbol.
526- /// This has not yet been exposed on the public API.
527- /// </summary>
528- public static AnnotatedTypeSymbol GetAnnotatedType ( this IFieldSymbol symbol ) => new AnnotatedTypeSymbol ( symbol . Type , symbol . NullableAnnotation ) ;
529- private static bool IsSpecialized ( this IMethodSymbol method ) =>
530- method . IsGenericMethod &&
531- ! ReferenceEquals ( method , method . OriginalDefinition ) &&
532- method . TypeParameters . Zip ( method . TypeArguments , ( a , b ) => ! ReferenceEquals ( a , b ) ) . Any ( b => b ) ;
533-
534- /// <summary>
535- /// Gets the annotated return type of an IMethodSymbol.
536- /// This has not yet been exposed on the public API.
537- /// </summary>
538- public static AnnotatedTypeSymbol GetAnnotatedReturnType ( this IMethodSymbol symbol ) => new AnnotatedTypeSymbol ( symbol . ReturnType , symbol . ReturnNullableAnnotation ) ;
539-
540- /// <summary>
541- /// Gets the type annotation for a NullableAnnotation.
542- /// </summary>
543- public static Kinds . TypeAnnotation GetTypeAnnotation ( this NullableAnnotation na )
544- {
545- switch ( na )
546- {
547- case NullableAnnotation . Annotated :
548- return Kinds . TypeAnnotation . Annotated ;
549- case NullableAnnotation . NotAnnotated :
550- return Kinds . TypeAnnotation . NotAnnotated ;
551- default :
552- return Kinds . TypeAnnotation . None ;
553- }
554- }
555-
556- /// <summary>
557- /// Gets the annotated element type of an IArrayTypeSymbol.
558- /// This has not yet been exposed on the public API.
559- /// </summary>
560- public static AnnotatedTypeSymbol GetAnnotatedElementType ( this IArrayTypeSymbol symbol ) =>
561- new AnnotatedTypeSymbol ( symbol . ElementType , symbol . ElementNullableAnnotation ) ;
562-
563471 /// <summary>
564472 /// Gets the annotated type arguments of an INamedTypeSymbol.
565473 /// This has not yet been exposed on the public API.
566474 /// </summary>
567475 public static IEnumerable < AnnotatedTypeSymbol > GetAnnotatedTypeArguments ( this INamedTypeSymbol symbol ) =>
568476 symbol . TypeArguments . Zip ( symbol . TypeArgumentsNullableAnnotations , ( t , a ) => new AnnotatedTypeSymbol ( t , a ) ) ;
569-
570- /// <summary>
571- /// Gets the annotated type arguments of an IMethodSymbol.
572- /// This has not yet been exposed on the public API.
573- /// </summary>
574- public static IEnumerable < AnnotatedTypeSymbol > GetAnnotatedTypeArguments ( this IMethodSymbol symbol ) =>
575- symbol . TypeArguments . Zip ( symbol . TypeArgumentsNullableAnnotations , ( t , a ) => new AnnotatedTypeSymbol ( t , a ) ) ;
576-
577- /// <summary>
578- /// Gets the annotated type constraints of an ITypeParameterSymbol.
579- /// This has not yet been exposed on the public API.
580- /// </summary>
581- public static IEnumerable < AnnotatedTypeSymbol > GetAnnotatedTypeConstraints ( this ITypeParameterSymbol symbol ) =>
582- symbol . ConstraintTypes . Zip ( symbol . ConstraintNullableAnnotations , ( t , a ) => new AnnotatedTypeSymbol ( t , a ) ) ;
583-
584- /// <summary>
585- /// Creates an AnnotatedTypeSymbol from an ITypeSymbol.
586- /// Note: not currently used but might be useful.
587- /// </summary>
588- public static AnnotatedTypeSymbol WithAnnotation ( this ITypeSymbol symbol , NullableAnnotation annotation ) =>
589- new AnnotatedTypeSymbol ( symbol , annotation ) ;
590-
591- /// <summary>
592- /// Holds if this type looks like an "anonymous" type. Names of anonymous types
593- /// sometimes collide so they need to be handled separately.
594- /// </summary>
595- public static bool IsAnonymous ( this INamedTypeSymbol type ) =>
596- type . IsAnonymousType || type . Name . StartsWith ( "<>" ) ;
597477 }
598478}
0 commit comments