Skip to content

Commit dc40d40

Browse files
authored
Prevent duplicate function declarations in Python (microsoft#5744)
* Show errors for duplicate function declarations in python * lf
1 parent 4fa0997 commit dc40d40

2 files changed

Lines changed: 19 additions & 6 deletions

File tree

pxtpy/ast.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ namespace pxt.py {
1414
pyAST?: AST;
1515
isProtected?: boolean;
1616
moduleTypeMarker?: {};
17+
18+
declared?: number; // A reference to the current iteration; used for detecting duplicate functions
1719
}
1820

1921
export interface TypeOptions {
@@ -408,7 +410,7 @@ namespace pxt.py {
408410
}
409411
export interface Constant extends Expr {
410412
kind: "Constant";
411-
value: any; // ???
413+
value: any; // ???
412414
}
413415

414416
// the following expression can appear in assignment context

pxtpy/converter.ts

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,7 @@ namespace pxt.py {
9696
delete r.pyRetType
9797
delete r.pySymbolType
9898
delete r.moduleTypeMarker
99+
delete r.declared
99100
if (r.parameters)
100101
r.parameters = r.parameters.map(p => {
101102
p = U.flatClone(p)
@@ -391,7 +392,7 @@ namespace pxt.py {
391392
}
392393
}
393394

394-
// next free error 9520; 9550-9599 reserved for parser
395+
// next free error 9521; 9550-9599 reserved for parser
395396
function error(astNode: py.AST, code: number, msg: string) {
396397
diagnostics.push(mkDiag(astNode, pxtc.DiagnosticCategory.Error, code, msg))
397398
//const pos = position(astNode ? astNode.startPos || 0 : 0, mod.source)
@@ -924,10 +925,20 @@ namespace pxt.py {
924925
const topLev = isTopLevel()
925926

926927
setupScope(n)
928+
const existing = lookupSymbol(getFullName(n));
927929
const sym = addSymbolFor(isMethod ? SK.Method : SK.Function, n)
928930

929-
if (shouldInlineFunction(sym) && !inline)
930-
return B.mkText("")
931+
if (!inline) {
932+
if (existing && existing.declared === currIteration) {
933+
error(n, 9520, lf("Duplicate function declaration"));
934+
}
935+
936+
sym.declared = currIteration;
937+
938+
if (shouldInlineFunction(sym)) {
939+
return B.mkText("")
940+
}
941+
}
931942

932943
if (isMethod) sym.isInstance = true
933944
ctx.currFun = n
@@ -1327,7 +1338,7 @@ namespace pxt.py {
13271338
fd.isGetSet = true
13281339
fdBack.isGetSet = true
13291340
return B.mkGroup(res)
1330-
} else
1341+
} else
13311342
*/
13321343
if (currIteration == 0) {
13331344
return B.mkText("/* skip for now */")
@@ -1733,7 +1744,7 @@ namespace pxt.py {
17331744
syntaxInfo.auxResult = i
17341745
let arg = orderedArgs[i]
17351746
if (!arg) {
1736-
// if we can't parse this next argument, but the cursor is beyond the
1747+
// if we can't parse this next argument, but the cursor is beyond the
17371748
// previous arguments, assume it's here
17381749
break
17391750
}

0 commit comments

Comments
 (0)