support for constructor functions that return itself if the constructor function is not called with "new"
diff --git a/plugins/org.eclipse.dltk.javascript.core/src/org/eclipse/dltk/internal/javascript/validation/FlowValidation.java b/plugins/org.eclipse.dltk.javascript.core/src/org/eclipse/dltk/internal/javascript/validation/FlowValidation.java index 0a14be7..ac2b361 100644 --- a/plugins/org.eclipse.dltk.javascript.core/src/org/eclipse/dltk/internal/javascript/validation/FlowValidation.java +++ b/plugins/org.eclipse.dltk.javascript.core/src/org/eclipse/dltk/internal/javascript/validation/FlowValidation.java
@@ -18,6 +18,7 @@ import org.eclipse.core.runtime.CoreException; import org.eclipse.dltk.core.builder.IBuildContext; import org.eclipse.dltk.core.builder.IBuildParticipant; +import org.eclipse.dltk.internal.javascript.ti.JSDocSupport; import org.eclipse.dltk.javascript.ast.AbstractNavigationVisitor; import org.eclipse.dltk.javascript.ast.BreakStatement; import org.eclipse.dltk.javascript.ast.CaseClause; @@ -44,6 +45,8 @@ import org.eclipse.dltk.javascript.ast.WhileStatement; import org.eclipse.dltk.javascript.core.JavaScriptProblems; import org.eclipse.dltk.javascript.parser.Reporter; +import org.eclipse.dltk.javascript.parser.jsdoc.JSDocTag; +import org.eclipse.dltk.javascript.parser.jsdoc.JSDocTags; import org.eclipse.osgi.util.NLS; public class FlowValidation extends AbstractNavigationVisitor<FlowStatus> @@ -204,6 +207,17 @@ final FlowStatus result = super.visitFunctionStatement(node); if (scope.contains(FlowEndKind.RETURNS_VALUE) && (scope.contains(FlowEndKind.RETURNS) || result.noReturn)) { + if (result.noReturn && result.returnValue + && node.getDocumentation() != null) { + JSDocTags parse = JSDocSupport.parse(node + .getDocumentation()); + // if it does return a value and it has a no return and it + // is a constructor function then don't report it. Very + // likely a construct to support a constructor function + // without the new keyword. + if (parse.count(JSDocTag.CONSTRUCTOR) == 1) + return result; + } reportInconsistentReturn(node); } return result;
diff --git a/tests/org.eclipse.dltk.javascript.core.tests/src/org/eclipse/dltk/javascript/core/tests/validation/FlowValidationTests.java b/tests/org.eclipse.dltk.javascript.core.tests/src/org/eclipse/dltk/javascript/core/tests/validation/FlowValidationTests.java index f5c66d1..c8bfa1a 100644 --- a/tests/org.eclipse.dltk.javascript.core.tests/src/org/eclipse/dltk/javascript/core/tests/validation/FlowValidationTests.java +++ b/tests/org.eclipse.dltk.javascript.core.tests/src/org/eclipse/dltk/javascript/core/tests/validation/FlowValidationTests.java
@@ -454,5 +454,30 @@ final List<IProblem> problems = validate(sCode); assertEquals(problems.toString(), 0, problems.size()); } + + + public void testConstructorFunctionReturningItself() { + final StringList code = new StringList(); + code.add("/**"); + code.add(" * @constructor"); + code.add(" */"); + code.add("function MyConstructor(){"); + code.add(" if (!(this instanceof MyConstructor))"); + code.add(" { return new MyConstructor() }"); + code.add("}"); + final String sCode = code.toString(); + final List<IProblem> problems = validate(sCode); + assertEquals(problems.toString(), 0, problems.size()); + } + public void testFunctionReturningItself() { + final StringList code = new StringList(); + code.add("function MyConstructor(){"); + code.add(" if (!(this instanceof MyConstructor))"); + code.add(" { return new MyConstructor() }"); + code.add("}"); + final String sCode = code.toString(); + final List<IProblem> problems = validate(sCode); + assertEquals(problems.toString(), 1, problems.size()); + } }