diff --git a/python/ql/lib/semmle/python/Files.qll b/python/ql/lib/semmle/python/Files.qll
index 4fa94f46ac6e..2fa1a733fc6f 100644
--- a/python/ql/lib/semmle/python/Files.qll
+++ b/python/ql/lib/semmle/python/Files.qll
@@ -1,9 +1,7 @@
import python
/** A file */
-class File extends Container {
- File() { files(this, _, _, _, _) }
-
+class File extends Container, @file {
/** DEPRECATED: Use `getAbsolutePath` instead. */
deprecated override string getName() { result = this.getAbsolutePath() }
@@ -34,9 +32,7 @@ class File extends Container {
}
/** Gets a short name for this file (just the file name) */
- string getShortName() {
- exists(string simple, string ext | files(this, _, simple, ext, _) | result = simple + ext)
- }
+ string getShortName() { result = this.getBaseName() }
private int lastLine() {
result = max(int i | exists(Location l | l.getFile() = this and l.getEndLine() = i))
@@ -55,7 +51,7 @@ class File extends Container {
)
}
- override string getAbsolutePath() { files(this, result, _, _, _) }
+ override string getAbsolutePath() { files(this, result) }
/** Gets the URL of this file. */
override string getURL() { result = "file://" + this.getAbsolutePath() + ":0:0:0:0" }
@@ -118,15 +114,10 @@ private predicate occupied_line(File f, int n) {
}
/** A folder (directory) */
-class Folder extends Container {
- Folder() { folders(this, _, _) }
-
+class Folder extends Container, @folder {
/** DEPRECATED: Use `getAbsolutePath` instead. */
deprecated override string getName() { result = this.getAbsolutePath() }
- /** DEPRECATED: Use `getBaseName` instead. */
- deprecated string getSimple() { folders(this, _, result) }
-
/**
* Holds if this element is at the specified location.
* The location spans column `startcolumn` of line `startline` to
@@ -144,7 +135,7 @@ class Folder extends Container {
endcolumn = 0
}
- override string getAbsolutePath() { folders(this, result, _) }
+ override string getAbsolutePath() { folders(this, result) }
/** Gets the URL of this folder. */
override string getURL() { result = "folder://" + this.getAbsolutePath() }
diff --git a/python/ql/lib/semmlecode.python.dbscheme b/python/ql/lib/semmlecode.python.dbscheme
index 4f1806347d7f..ff5327c074ca 100644
--- a/python/ql/lib/semmlecode.python.dbscheme
+++ b/python/ql/lib/semmlecode.python.dbscheme
@@ -120,16 +120,11 @@ svnchurn(
Python dbscheme
****************************/
-/* fromSource is ignored */
files(unique int id: @file,
- varchar(900) name: string ref,
- varchar(900) simple: string ref,
- varchar(900) ext: string ref,
- int fromSource: int ref);
+ varchar(900) name: string ref);
folders(unique int id: @folder,
- varchar(900) name: string ref,
- varchar(900) simple: string ref);
+ varchar(900) name: string ref);
@container = @folder | @file;
diff --git a/python/ql/lib/semmlecode.python.dbscheme.stats b/python/ql/lib/semmlecode.python.dbscheme.stats
index 99fa25b38175..31653bf41a9c 100644
--- a/python/ql/lib/semmlecode.python.dbscheme.stats
+++ b/python/ql/lib/semmlecode.python.dbscheme.stats
@@ -4331,18 +4331,6 @@
name
3066
-
-simple
-1294
-
-
-ext
-1
-
-
-fromSource
-1
-
@@ -4362,54 +4350,6 @@
-id
-simple
-
-
-12
-
-
-1
-2
-3066
-
-
-
-
-
-
-id
-ext
-
-
-12
-
-
-1
-2
-3066
-
-
-
-
-
-
-id
-fromSource
-
-
-12
-
-
-1
-2
-3066
-
-
-
-
-
-
name
id
@@ -4425,276 +4365,6 @@
-
-name
-simple
-
-
-12
-
-
-1
-2
-3066
-
-
-
-
-
-
-name
-ext
-
-
-12
-
-
-1
-2
-3066
-
-
-
-
-
-
-name
-fromSource
-
-
-12
-
-
-1
-2
-3066
-
-
-
-
-
-
-simple
-id
-
-
-12
-
-
-1
-2
-1058
-
-
-2
-3
-132
-
-
-3
-38
-98
-
-
-47
-646
-6
-
-
-
-
-
-
-simple
-name
-
-
-12
-
-
-1
-2
-1058
-
-
-2
-3
-132
-
-
-3
-38
-98
-
-
-47
-646
-6
-
-
-
-
-
-
-simple
-ext
-
-
-12
-
-
-1
-2
-1294
-
-
-
-
-
-
-simple
-fromSource
-
-
-12
-
-
-1
-2
-1294
-
-
-
-
-
-
-ext
-id
-
-
-12
-
-
-3066
-3067
-1
-
-
-
-
-
-
-ext
-name
-
-
-12
-
-
-3066
-3067
-1
-
-
-
-
-
-
-ext
-simple
-
-
-12
-
-
-1294
-1295
-1
-
-
-
-
-
-
-ext
-fromSource
-
-
-12
-
-
-1
-2
-1
-
-
-
-
-
-
-fromSource
-id
-
-
-12
-
-
-3066
-3067
-1
-
-
-
-
-
-
-fromSource
-name
-
-
-12
-
-
-3066
-3067
-1
-
-
-
-
-
-
-fromSource
-simple
-
-
-12
-
-
-1294
-1295
-1
-
-
-
-
-
-
-fromSource
-ext
-
-
-12
-
-
-1
-2
-1
-
-
-
-
-
@@ -4709,10 +4379,6 @@
name
686
-
-simple
-538
-
@@ -4732,22 +4398,6 @@
-id
-simple
-
-
-12
-
-
-1
-2
-686
-
-
-
-
-
-
name
id
@@ -4763,74 +4413,6 @@
-
-name
-simple
-
-
-12
-
-
-1
-2
-686
-
-
-
-
-
-
-simple
-id
-
-
-12
-
-
-1
-2
-481
-
-
-2
-4
-45
-
-
-4
-27
-12
-
-
-
-
-
-
-simple
-name
-
-
-12
-
-
-1
-2
-481
-
-
-2
-4
-45
-
-
-4
-27
-12
-
-
-
-
-
diff --git a/python/upgrades/4f1806347d7fafe2f78508da01c01e5aff5f7cbb/old.dbscheme b/python/upgrades/4f1806347d7fafe2f78508da01c01e5aff5f7cbb/old.dbscheme
new file mode 100644
index 000000000000..4f1806347d7f
--- /dev/null
+++ b/python/upgrades/4f1806347d7fafe2f78508da01c01e5aff5f7cbb/old.dbscheme
@@ -0,0 +1,999 @@
+/*
+ * This dbscheme is auto-generated by 'semmle/dbscheme_gen.py'.
+ * WARNING: Any modifications to this file will be lost.
+ * Relations can be changed by modifying master.py or
+ * by adding rules to dbscheme.template
+ */
+
+/* This is a dummy line to alter the dbscheme, so we can make a database upgrade
+ * without actually changing any of the dbscheme predicates. It contains a date
+ * to allow for such updates in the future as well.
+ *
+ * 2020-07-02
+ *
+ * DO NOT remove this comment carelessly, since it can revert the dbscheme back to a
+ * previously seen state (matching a previously seen SHA), which would make the upgrade
+ * mechanism not work properly.
+ */
+
+ /*
+ * External artifacts
+ */
+
+externalDefects(
+ unique int id : @externalDefect,
+ varchar(900) queryPath : string ref,
+ int location : @location ref,
+ varchar(900) message : string ref,
+ float severity : float ref
+);
+
+externalMetrics(
+ unique int id : @externalMetric,
+ varchar(900) queryPath : string ref,
+ int location : @location ref,
+ float value : float ref
+);
+
+externalData(
+ int id : @externalDataElement,
+ varchar(900) queryPath : string ref,
+ int column: int ref,
+ varchar(900) data : string ref
+);
+
+snapshotDate(unique date snapshotDate : date ref);
+
+sourceLocationPrefix(varchar(900) prefix : string ref);
+
+
+/*
+ * Duplicate code
+ */
+
+duplicateCode(
+ unique int id : @duplication,
+ varchar(900) relativePath : string ref,
+ int equivClass : int ref);
+
+similarCode(
+ unique int id : @similarity,
+ varchar(900) relativePath : string ref,
+ int equivClass : int ref);
+
+@duplication_or_similarity = @duplication | @similarity
+
+tokens(
+ int id : @duplication_or_similarity ref,
+ int offset : int ref,
+ int beginLine : int ref,
+ int beginColumn : int ref,
+ int endLine : int ref,
+ int endColumn : int ref);
+
+/*
+ * Line metrics
+ */
+py_codelines(int id : @py_scope ref,
+ int count : int ref);
+
+py_commentlines(int id : @py_scope ref,
+ int count : int ref);
+
+py_docstringlines(int id : @py_scope ref,
+ int count : int ref);
+
+py_alllines(int id : @py_scope ref,
+ int count : int ref);
+
+/*
+ * Version history
+ */
+
+svnentries(
+ int id : @svnentry,
+ varchar(500) revision : string ref,
+ varchar(500) author : string ref,
+ date revisionDate : date ref,
+ int changeSize : int ref
+)
+
+svnaffectedfiles(
+ int id : @svnentry ref,
+ int file : @file ref,
+ varchar(500) action : string ref
+)
+
+svnentrymsg(
+ int id : @svnentry ref,
+ varchar(500) message : string ref
+)
+
+svnchurn(
+ int commit : @svnentry ref,
+ int file : @file ref,
+ int addedLines : int ref,
+ int deletedLines : int ref
+)
+
+/****************************
+ Python dbscheme
+****************************/
+
+/* fromSource is ignored */
+files(unique int id: @file,
+ varchar(900) name: string ref,
+ varchar(900) simple: string ref,
+ varchar(900) ext: string ref,
+ int fromSource: int ref);
+
+folders(unique int id: @folder,
+ varchar(900) name: string ref,
+ varchar(900) simple: string ref);
+
+@container = @folder | @file;
+
+containerparent(int parent: @container ref,
+ unique int child: @container ref);
+
+@sourceline = @file | @py_Module | @xmllocatable;
+
+numlines(int element_id: @sourceline ref,
+ int num_lines: int ref,
+ int num_code: int ref,
+ int num_comment: int ref
+ );
+
+@location = @location_ast | @location_default ;
+
+locations_default(unique int id: @location_default,
+ int file: @file ref,
+ int beginLine: int ref,
+ int beginColumn: int ref,
+ int endLine: int ref,
+ int endColumn: int ref);
+
+locations_ast(unique int id: @location_ast,
+ int module: @py_Module ref,
+ int beginLine: int ref,
+ int beginColumn: int ref,
+ int endLine: int ref,
+ int endColumn: int ref);
+
+file_contents(unique int file: @file ref, string contents: string ref);
+
+py_module_path(int module: @py_Module ref, int file: @container ref);
+
+variable(unique int id : @py_variable,
+ int scope : @py_scope ref,
+ varchar(1) name : string ref);
+
+py_line_lengths(unique int id : @py_line,
+ int file: @py_Module ref,
+ int line : int ref,
+ int length : int ref);
+
+py_extracted_version(int module : @py_Module ref,
+ varchar(1) version : string ref);
+
+/* AUTO GENERATED PART STARTS HERE */
+
+
+/* AnnAssign.location = 0, location */
+/* AnnAssign.value = 1, expr */
+/* AnnAssign.annotation = 2, expr */
+/* AnnAssign.target = 3, expr */
+
+/* Assert.location = 0, location */
+/* Assert.test = 1, expr */
+/* Assert.msg = 2, expr */
+
+/* Assign.location = 0, location */
+/* Assign.value = 1, expr */
+/* Assign.targets = 2, expr_list */
+
+/* AssignExpr.location = 0, location */
+/* AssignExpr.parenthesised = 1, bool */
+/* AssignExpr.value = 2, expr */
+/* AssignExpr.target = 3, expr */
+
+/* Attribute.location = 0, location */
+/* Attribute.parenthesised = 1, bool */
+/* Attribute.value = 2, expr */
+/* Attribute.attr = 3, str */
+/* Attribute.ctx = 4, expr_context */
+
+/* AugAssign.location = 0, location */
+/* AugAssign.operation = 1, BinOp */
+
+/* Await.location = 0, location */
+/* Await.parenthesised = 1, bool */
+/* Await.value = 2, expr */
+
+/* BinaryExpr.location = 0, location */
+/* BinaryExpr.parenthesised = 1, bool */
+/* BinaryExpr.left = 2, expr */
+/* BinaryExpr.op = 3, operator */
+/* BinaryExpr.right = 4, expr */
+/* BinaryExpr = AugAssign */
+
+/* BoolExpr.location = 0, location */
+/* BoolExpr.parenthesised = 1, bool */
+/* BoolExpr.op = 2, boolop */
+/* BoolExpr.values = 3, expr_list */
+
+/* Break.location = 0, location */
+
+/* Bytes.location = 0, location */
+/* Bytes.parenthesised = 1, bool */
+/* Bytes.s = 2, bytes */
+/* Bytes.prefix = 3, bytes */
+/* Bytes.implicitly_concatenated_parts = 4, StringPart_list */
+
+/* Call.location = 0, location */
+/* Call.parenthesised = 1, bool */
+/* Call.func = 2, expr */
+/* Call.positional_args = 3, expr_list */
+/* Call.named_args = 4, dict_item_list */
+
+/* Class.name = 0, str */
+/* Class.body = 1, stmt_list */
+/* Class = ClassExpr */
+
+/* ClassExpr.location = 0, location */
+/* ClassExpr.parenthesised = 1, bool */
+/* ClassExpr.name = 2, str */
+/* ClassExpr.bases = 3, expr_list */
+/* ClassExpr.keywords = 4, dict_item_list */
+/* ClassExpr.inner_scope = 5, Class */
+
+/* Compare.location = 0, location */
+/* Compare.parenthesised = 1, bool */
+/* Compare.left = 2, expr */
+/* Compare.ops = 3, cmpop_list */
+/* Compare.comparators = 4, expr_list */
+
+/* Continue.location = 0, location */
+
+/* Delete.location = 0, location */
+/* Delete.targets = 1, expr_list */
+
+/* Dict.location = 0, location */
+/* Dict.parenthesised = 1, bool */
+/* Dict.items = 2, dict_item_list */
+
+/* DictComp.location = 0, location */
+/* DictComp.parenthesised = 1, bool */
+/* DictComp.function = 2, Function */
+/* DictComp.iterable = 3, expr */
+
+/* DictUnpacking.location = 0, location */
+/* DictUnpacking.value = 1, expr */
+
+/* Ellipsis.location = 0, location */
+/* Ellipsis.parenthesised = 1, bool */
+
+/* ExceptStmt.location = 0, location */
+/* ExceptStmt.type = 1, expr */
+/* ExceptStmt.name = 2, expr */
+/* ExceptStmt.body = 3, stmt_list */
+
+/* Exec.location = 0, location */
+/* Exec.body = 1, expr */
+/* Exec.globals = 2, expr */
+/* Exec.locals = 3, expr */
+
+/* ExprStmt.location = 0, location */
+/* ExprStmt.value = 1, expr */
+
+/* Filter.location = 0, location */
+/* Filter.parenthesised = 1, bool */
+/* Filter.value = 2, expr */
+/* Filter.filter = 3, expr */
+
+/* For.location = 0, location */
+/* For.target = 1, expr */
+/* For.iter = 2, expr */
+/* For.body = 3, stmt_list */
+/* For.orelse = 4, stmt_list */
+/* For.is_async = 5, bool */
+
+/* FormattedValue.location = 0, location */
+/* FormattedValue.parenthesised = 1, bool */
+/* FormattedValue.value = 2, expr */
+/* FormattedValue.conversion = 3, str */
+/* FormattedValue.format_spec = 4, JoinedStr */
+
+/* Function.name = 0, str */
+/* Function.args = 1, parameter_list */
+/* Function.vararg = 2, expr */
+/* Function.kwonlyargs = 3, expr_list */
+/* Function.kwarg = 4, expr */
+/* Function.body = 5, stmt_list */
+/* Function.is_async = 6, bool */
+/* Function = FunctionParent */
+
+/* FunctionExpr.location = 0, location */
+/* FunctionExpr.parenthesised = 1, bool */
+/* FunctionExpr.name = 2, str */
+/* FunctionExpr.args = 3, arguments */
+/* FunctionExpr.returns = 4, expr */
+/* FunctionExpr.inner_scope = 5, Function */
+
+/* GeneratorExp.location = 0, location */
+/* GeneratorExp.parenthesised = 1, bool */
+/* GeneratorExp.function = 2, Function */
+/* GeneratorExp.iterable = 3, expr */
+
+/* Global.location = 0, location */
+/* Global.names = 1, str_list */
+
+/* If.location = 0, location */
+/* If.test = 1, expr */
+/* If.body = 2, stmt_list */
+/* If.orelse = 3, stmt_list */
+
+/* IfExp.location = 0, location */
+/* IfExp.parenthesised = 1, bool */
+/* IfExp.test = 2, expr */
+/* IfExp.body = 3, expr */
+/* IfExp.orelse = 4, expr */
+
+/* Import.location = 0, location */
+/* Import.names = 1, alias_list */
+
+/* ImportExpr.location = 0, location */
+/* ImportExpr.parenthesised = 1, bool */
+/* ImportExpr.level = 2, int */
+/* ImportExpr.name = 3, str */
+/* ImportExpr.top = 4, bool */
+
+/* ImportStar.location = 0, location */
+/* ImportStar.module = 1, expr */
+
+/* ImportMember.location = 0, location */
+/* ImportMember.parenthesised = 1, bool */
+/* ImportMember.module = 2, expr */
+/* ImportMember.name = 3, str */
+
+/* Fstring.location = 0, location */
+/* Fstring.parenthesised = 1, bool */
+/* Fstring.values = 2, expr_list */
+/* Fstring = FormattedValue */
+
+/* KeyValuePair.location = 0, location */
+/* KeyValuePair.value = 1, expr */
+/* KeyValuePair.key = 2, expr */
+
+/* Lambda.location = 0, location */
+/* Lambda.parenthesised = 1, bool */
+/* Lambda.args = 2, arguments */
+/* Lambda.inner_scope = 3, Function */
+
+/* List.location = 0, location */
+/* List.parenthesised = 1, bool */
+/* List.elts = 2, expr_list */
+/* List.ctx = 3, expr_context */
+
+/* ListComp.location = 0, location */
+/* ListComp.parenthesised = 1, bool */
+/* ListComp.function = 2, Function */
+/* ListComp.iterable = 3, expr */
+/* ListComp.generators = 4, comprehension_list */
+/* ListComp.elt = 5, expr */
+
+/* Module.name = 0, str */
+/* Module.hash = 1, str */
+/* Module.body = 2, stmt_list */
+/* Module.kind = 3, str */
+
+/* Name.location = 0, location */
+/* Name.parenthesised = 1, bool */
+/* Name.variable = 2, variable */
+/* Name.ctx = 3, expr_context */
+/* Name = ParameterList */
+
+/* Nonlocal.location = 0, location */
+/* Nonlocal.names = 1, str_list */
+
+/* Num.location = 0, location */
+/* Num.parenthesised = 1, bool */
+/* Num.n = 2, number */
+/* Num.text = 3, number */
+
+/* Pass.location = 0, location */
+
+/* PlaceHolder.location = 0, location */
+/* PlaceHolder.parenthesised = 1, bool */
+/* PlaceHolder.variable = 2, variable */
+/* PlaceHolder.ctx = 3, expr_context */
+
+/* Print.location = 0, location */
+/* Print.dest = 1, expr */
+/* Print.values = 2, expr_list */
+/* Print.nl = 3, bool */
+
+/* Raise.location = 0, location */
+/* Raise.exc = 1, expr */
+/* Raise.cause = 2, expr */
+/* Raise.type = 3, expr */
+/* Raise.inst = 4, expr */
+/* Raise.tback = 5, expr */
+
+/* Repr.location = 0, location */
+/* Repr.parenthesised = 1, bool */
+/* Repr.value = 2, expr */
+
+/* Return.location = 0, location */
+/* Return.value = 1, expr */
+
+/* Set.location = 0, location */
+/* Set.parenthesised = 1, bool */
+/* Set.elts = 2, expr_list */
+
+/* SetComp.location = 0, location */
+/* SetComp.parenthesised = 1, bool */
+/* SetComp.function = 2, Function */
+/* SetComp.iterable = 3, expr */
+
+/* Slice.location = 0, location */
+/* Slice.parenthesised = 1, bool */
+/* Slice.start = 2, expr */
+/* Slice.stop = 3, expr */
+/* Slice.step = 4, expr */
+
+/* SpecialOperation.location = 0, location */
+/* SpecialOperation.parenthesised = 1, bool */
+/* SpecialOperation.name = 2, str */
+/* SpecialOperation.arguments = 3, expr_list */
+
+/* Starred.location = 0, location */
+/* Starred.parenthesised = 1, bool */
+/* Starred.value = 2, expr */
+/* Starred.ctx = 3, expr_context */
+
+/* Str.location = 0, location */
+/* Str.parenthesised = 1, bool */
+/* Str.s = 2, str */
+/* Str.prefix = 3, str */
+/* Str.implicitly_concatenated_parts = 4, StringPart_list */
+
+/* StringPart.text = 0, str */
+/* StringPart.location = 1, location */
+/* StringPart = StringPartList */
+/* StringPartList = BytesOrStr */
+
+/* Subscript.location = 0, location */
+/* Subscript.parenthesised = 1, bool */
+/* Subscript.value = 2, expr */
+/* Subscript.index = 3, expr */
+/* Subscript.ctx = 4, expr_context */
+
+/* TemplateDottedNotation.location = 0, location */
+/* TemplateDottedNotation.parenthesised = 1, bool */
+/* TemplateDottedNotation.value = 2, expr */
+/* TemplateDottedNotation.attr = 3, str */
+/* TemplateDottedNotation.ctx = 4, expr_context */
+
+/* TemplateWrite.location = 0, location */
+/* TemplateWrite.value = 1, expr */
+
+/* Try.location = 0, location */
+/* Try.body = 1, stmt_list */
+/* Try.orelse = 2, stmt_list */
+/* Try.handlers = 3, stmt_list */
+/* Try.finalbody = 4, stmt_list */
+
+/* Tuple.location = 0, location */
+/* Tuple.parenthesised = 1, bool */
+/* Tuple.elts = 2, expr_list */
+/* Tuple.ctx = 3, expr_context */
+/* Tuple = ParameterList */
+
+/* UnaryExpr.location = 0, location */
+/* UnaryExpr.parenthesised = 1, bool */
+/* UnaryExpr.op = 2, unaryop */
+/* UnaryExpr.operand = 3, expr */
+
+/* While.location = 0, location */
+/* While.test = 1, expr */
+/*