Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 6c48eb8

Browse files
committed
C#: Add type mentions to AST
1 parent ffc2a64 commit 6c48eb8

36 files changed

Lines changed: 2402 additions & 76 deletions

File tree

csharp/ql/src/semmle/code/csharp/PrintAst.qll

Lines changed: 99 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,16 @@ private predicate isInterestingBaseType(ValueOrRefType base) {
120120
*/
121121
private newtype TPrintAstNode =
122122
TElementNode(Element element) { shouldPrint(element, _) } or
123+
TTopLevelTypeMentionNode(TypeMention typeMention) {
124+
shouldPrint(typeMention.getTarget(), _) and
125+
not isNotNeeded(typeMention.getTarget().getParent*()) and
126+
not typeMention.getTarget().getParent*() instanceof TypeParameter
127+
} or
128+
TNestedTypeMentionNode(TypeMention typeMention) {
129+
shouldPrint(typeMention.getParent+().getTarget(), _) and
130+
not isNotNeeded(typeMention.getParent+().getTarget().getParent*()) and
131+
not typeMention.getParent+().getTarget().getParent*() instanceof TypeParameter
132+
} or
123133
TParametersNode(Parameterizable parameterizable) {
124134
shouldPrint(parameterizable, _) and
125135
parameterizable.getNumberOfParameters() > 0 and
@@ -139,11 +149,6 @@ private newtype TPrintAstNode =
139149
shouldPrint(type, _) and
140150
hasInterestingBaseTypes(type) and
141151
not isNotNeeded(type)
142-
} or
143-
TBaseTypeNode(ValueOrRefType derived, ValueOrRefType base) {
144-
shouldPrint(derived, _) and
145-
base = getAnInterestingBaseType(derived) and
146-
not isNotNeeded(derived)
147152
}
148153

149154
/**
@@ -238,6 +243,46 @@ abstract class ElementNode extends PrintAstNode, TElementNode {
238243
final Element getElement() { result = element }
239244
}
240245

246+
/**
247+
* A node representing an AST node with an underlying `TypeMention`.
248+
*/
249+
abstract class TypeMentionNode extends PrintAstNode {
250+
TypeMention typeMention;
251+
252+
override string toString() { result = "[TypeMention] " + typeMention.getType().toString() }
253+
254+
override Location getLocation() { result = typeMention.getLocation() }
255+
256+
/**
257+
* Gets the `TypeMention` represented by this node.
258+
*/
259+
final TypeMention getTypeMention() { result = typeMention }
260+
261+
override NestedTypeMentionNode getChild(int childIndex) {
262+
result.getTypeMention() =
263+
rank[childIndex](TypeMention t, Location l |
264+
t = any(TypeMention tm | tm.getParent() = typeMention) and
265+
l = t.getLocation()
266+
|
267+
t order by l.getFile().toString(), l.getStartLine(), l.getStartColumn()
268+
)
269+
}
270+
}
271+
272+
/**
273+
* A node representing a top-level `TypeMention`, which has a target `Element`.
274+
*/
275+
class TopLevelTypeMentionNode extends TypeMentionNode, TTopLevelTypeMentionNode {
276+
TopLevelTypeMentionNode() { this = TTopLevelTypeMentionNode(typeMention) }
277+
}
278+
279+
/**
280+
* A node representing a nested `TypeMention`, whose parent is also a `TypeMention`.
281+
*/
282+
class NestedTypeMentionNode extends TypeMentionNode, TNestedTypeMentionNode {
283+
NestedTypeMentionNode() { this = TNestedTypeMentionNode(typeMention) }
284+
}
285+
241286
/**
242287
* A node representing a `ControlFlowElement` (`Expr` or `Stmt`).
243288
*/
@@ -263,8 +308,15 @@ class ControlFlowElementNode extends ElementNode {
263308
not isNotNeeded(element.getParent+())
264309
}
265310

266-
override ElementNode getChild(int childIndex) {
267-
result.getElement() = controlFlowElement.getChild(childIndex)
311+
override PrintAstNode getChild(int childIndex) {
312+
(
313+
childIndex = min(int i | exists(controlFlowElement.getChild(i))) - 1
314+
or
315+
not exists(controlFlowElement.getAChild()) and childIndex = 0
316+
) and
317+
result.(TopLevelTypeMentionNode).getTypeMention().getTarget() = controlFlowElement
318+
or
319+
result.(ElementNode).getElement() = controlFlowElement.getChild(childIndex)
268320
}
269321
}
270322

@@ -292,12 +344,15 @@ final class AssignmentNode extends ControlFlowElementNode {
292344

293345
AssignmentNode() { assignment = element }
294346

295-
override ElementNode getChild(int childIndex) {
347+
override PrintAstNode getChild(int childIndex) {
348+
childIndex = -1 and
349+
result.(TopLevelTypeMentionNode).getTypeMention().getTarget() = controlFlowElement
350+
or
296351
childIndex = 0 and
297-
result.getElement() = assignment.getLValue()
352+
result.(ElementNode).getElement() = assignment.getLValue()
298353
or
299354
childIndex = 1 and
300-
result.getElement() = assignment.getRValue()
355+
result.(ElementNode).getElement() = assignment.getRValue()
301356
}
302357
}
303358

@@ -313,6 +368,9 @@ final class CallableNode extends ElementNode {
313368
}
314369

315370
override PrintAstNode getChild(int childIndex) {
371+
childIndex = -1 and
372+
result.(TopLevelTypeMentionNode).getTypeMention().getTarget() = callable
373+
or
316374
childIndex = 0 and
317375
result.(AttributesNode).getAttributable() = callable
318376
or
@@ -342,6 +400,9 @@ final class DeclarationWithAccessorsNode extends ElementNode {
342400
}
343401

344402
override PrintAstNode getChild(int childIndex) {
403+
childIndex = -1 and
404+
result.(TopLevelTypeMentionNode).getTypeMention().getTarget() = declaration
405+
or
345406
childIndex = 0 and
346407
result.(AttributesNode).getAttributable() = declaration
347408
or
@@ -375,6 +436,9 @@ final class FieldNode extends ElementNode {
375436
}
376437

377438
override PrintAstNode getChild(int childIndex) {
439+
childIndex = -1 and
440+
result.(TopLevelTypeMentionNode).getTypeMention().getTarget() = field
441+
or
378442
childIndex = 0 and
379443
result.(AttributesNode).getAttributable() = field
380444
or
@@ -414,6 +478,9 @@ final class ParameterNode extends ElementNode {
414478
}
415479

416480
override PrintAstNode getChild(int childIndex) {
481+
childIndex = -1 and
482+
result.(TopLevelTypeMentionNode).getTypeMention().getTarget() = param
483+
or
417484
childIndex = 0 and
418485
result.(AttributesNode).getAttributable() = param
419486
or
@@ -433,7 +500,16 @@ final class AttributeNode extends ElementNode {
433500
not isNotNeeded(attr.getTarget())
434501
}
435502

436-
override ElementNode getChild(int childIndex) { result.getElement() = attr.getChild(childIndex) }
503+
override PrintAstNode getChild(int childIndex) {
504+
(
505+
childIndex = min(int i | exists(attr.getChild(i))) - 1
506+
or
507+
not exists(attr.getAChild()) and childIndex = 0
508+
) and
509+
result.(TopLevelTypeMentionNode).getTypeMention().getTarget() = attr
510+
or
511+
result.(ElementNode).getElement() = attr.getChild(childIndex)
512+
}
437513
}
438514

439515
/**
@@ -594,19 +670,21 @@ final class BaseTypesNode extends PrintAstNode, TBaseTypesNode {
594670

595671
override Location getLocation() { none() }
596672

597-
override BaseTypeNode getChild(int childIndex) {
673+
override TopLevelTypeMentionNode getChild(int childIndex) {
598674
childIndex = 0 and
599-
result.getBaseType() = valueOrRefType.getBaseClass() and
600-
result.getDerivedType() = valueOrRefType
675+
result.getTypeMention().getType() = valueOrRefType.getBaseClass() and
676+
result.getTypeMention().getTarget() = valueOrRefType
601677
or
602-
result.getBaseType() =
603-
rank[childIndex](ValueOrRefType base, string name |
604-
base = valueOrRefType.getABaseInterface() and
605-
name = base.toString()
678+
result.getTypeMention() =
679+
rank[childIndex](TypeMention t, Location l |
680+
t =
681+
any(TypeMention tm |
682+
tm.getType() = valueOrRefType.getABaseInterface() and tm.getTarget() = valueOrRefType
683+
) and
684+
l = t.getLocation()
606685
|
607-
base order by name
608-
) and
609-
result.getDerivedType() = valueOrRefType
686+
t order by l.getFile().toString(), l.getStartLine(), l.getStartColumn()
687+
)
610688
}
611689

612690
/**
@@ -615,32 +693,6 @@ final class BaseTypesNode extends PrintAstNode, TBaseTypesNode {
615693
ValueOrRefType getValueOrRefType() { result = valueOrRefType }
616694
}
617695

618-
/**
619-
* A node representing a base type reference of a `ValueOrRefType` declaration.
620-
*/
621-
final class BaseTypeNode extends PrintAstNode, TBaseTypeNode {
622-
ValueOrRefType derived;
623-
ValueOrRefType base;
624-
625-
BaseTypeNode() { this = TBaseTypeNode(derived, base) }
626-
627-
override string toString() { result = getQlClass(base) + base.toString() }
628-
629-
override Location getLocation() { none() }
630-
631-
override BaseTypeNode getChild(int childIndex) { none() }
632-
633-
/**
634-
* Gets the underlying derived `ValueOrRefType`
635-
*/
636-
ValueOrRefType getDerivedType() { result = derived }
637-
638-
/**
639-
* Gets the underlying base `ValueOrRefType`
640-
*/
641-
ValueOrRefType getBaseType() { result = base }
642-
}
643-
644696
/** Holds if `node` belongs to the output tree, and its property `key` has the given `value`. */
645697
query predicate nodes(PrintAstNode node, string key, string value) { value = node.getProperty(key) }
646698

0 commit comments

Comments
 (0)