improved PHP parser
[phpeclipse.git] / net.sourceforge.phpeclipse / src / net / sourceforge / phpdt / internal / compiler / problem / ProblemReporter.java
index 0be0218..3d5be38 100644 (file)
@@ -13,10 +13,12 @@ import net.sourceforge.phpdt.core.compiler.InvalidInputException;
 import net.sourceforge.phpdt.internal.compiler.CompilationResult;
 import net.sourceforge.phpdt.internal.compiler.IErrorHandlingPolicy;
 import net.sourceforge.phpdt.internal.compiler.IProblemFactory;
+import net.sourceforge.phpdt.internal.compiler.env.IConstants;
 import net.sourceforge.phpdt.internal.compiler.impl.CompilerOptions;
 import net.sourceforge.phpdt.internal.compiler.impl.Constant;
 import net.sourceforge.phpdt.internal.compiler.impl.ReferenceContext;
 import net.sourceforge.phpdt.internal.compiler.lookup.Binding;
+import net.sourceforge.phpdt.internal.compiler.lookup.CompilerModifiers;
 import net.sourceforge.phpdt.internal.compiler.lookup.FieldBinding;
 import net.sourceforge.phpdt.internal.compiler.lookup.LocalVariableBinding;
 import net.sourceforge.phpdt.internal.compiler.lookup.MethodBinding;
@@ -30,6 +32,7 @@ import net.sourceforge.phpdt.internal.compiler.lookup.TypeConstants;
 import net.sourceforge.phpdt.internal.compiler.parser.Parser;
 import net.sourceforge.phpdt.internal.compiler.parser.Scanner;
 import net.sourceforge.phpdt.internal.compiler.util.Util;
+import net.sourceforge.phpeclipse.internal.compiler.ast.ASTNode;
 import net.sourceforge.phpeclipse.internal.compiler.ast.AbstractMethodDeclaration;
 import net.sourceforge.phpeclipse.internal.compiler.ast.AbstractVariableDeclaration;
 import net.sourceforge.phpeclipse.internal.compiler.ast.AllocationExpression;
@@ -37,10 +40,9 @@ import net.sourceforge.phpeclipse.internal.compiler.ast.Argument;
 import net.sourceforge.phpeclipse.internal.compiler.ast.ArrayAllocationExpression;
 import net.sourceforge.phpeclipse.internal.compiler.ast.ArrayReference;
 import net.sourceforge.phpeclipse.internal.compiler.ast.Assignment;
-import net.sourceforge.phpeclipse.internal.compiler.ast.ASTNode;
 import net.sourceforge.phpeclipse.internal.compiler.ast.BinaryExpression;
 import net.sourceforge.phpeclipse.internal.compiler.ast.BranchStatement;
-import net.sourceforge.phpeclipse.internal.compiler.ast.Case;
+import net.sourceforge.phpeclipse.internal.compiler.ast.CaseStatement;
 import net.sourceforge.phpeclipse.internal.compiler.ast.CastExpression;
 import net.sourceforge.phpeclipse.internal.compiler.ast.CompilationUnitDeclaration;
 import net.sourceforge.phpeclipse.internal.compiler.ast.CompoundAssignment;
@@ -596,7 +598,7 @@ public class ProblemReporter extends ProblemHandler implements ProblemReasons {
         .shortReadableName()) }, location.sourceStart, location.sourceEnd);
   }
 
-  public void duplicateCase(Case statement, Constant constant) {
+  public void duplicateCase(CaseStatement statement, Constant constant) {
     String[] arguments = new String[] { String.valueOf(constant.intValue()) };
     this.handle(IProblem.DuplicateCase, arguments, arguments, statement.sourceStart, statement.sourceEnd);
   }
@@ -1592,9 +1594,402 @@ public class ProblemReporter extends ProblemHandler implements ProblemReasons {
         : compUnitDecl.sourceStart, compUnitDecl == null ? 1 : compUnitDecl.sourceEnd);
   }
 
-  public void maskedExceptionHandler(ReferenceBinding exceptionType, ASTNode location) {
-    this.handle(IProblem.MaskedCatch, NoArgument, NoArgument, location.sourceStart, location.sourceEnd);
-  }
+  public void javadocDuplicatedReturnTag(int sourceStart, int sourceEnd){
+       this.handle(IProblem.JavadocDuplicateReturnTag, NoArgument, NoArgument, sourceStart, sourceEnd);
+}
+public void javadocDeprecatedField(FieldBinding field, ASTNode location, int modifiers) {
+       if (javadocVisibility(this.options.reportInvalidJavadocTagsVisibility, modifiers)) {
+               this.handle(
+                       IProblem.JavadocUsingDeprecatedField,
+                       new String[] {new String(field.declaringClass.readableName()), new String(field.name)},
+                       new String[] {new String(field.declaringClass.shortReadableName()), new String(field.name)},
+                       location.sourceStart,
+                       location.sourceEnd);
+       }
+}
+public void javadocDeprecatedMethod(MethodBinding method, ASTNode location, int modifiers) {
+       if (javadocVisibility(this.options.reportInvalidJavadocTagsVisibility, modifiers)) {
+               if (method.isConstructor()) {
+                       this.handle(
+                               IProblem.JavadocUsingDeprecatedConstructor,
+                               new String[] {new String(method.declaringClass.readableName()), parametersAsString(method)},
+                               new String[] {new String(method.declaringClass.shortReadableName()), parametersAsShortString(method)},
+                               location.sourceStart,
+                               location.sourceEnd);
+               } else {
+                       this.handle(
+                               IProblem.JavadocUsingDeprecatedMethod,
+                               new String[] {new String(method.declaringClass.readableName()), new String(method.selector), parametersAsString(method)},
+                               new String[] {new String(method.declaringClass.shortReadableName()), new String(method.selector), parametersAsShortString(method)},
+                               location.sourceStart,
+                               location.sourceEnd);
+               }
+       }
+}
+public void javadocDeprecatedType(TypeBinding type, ASTNode location, int modifiers) {
+       if (location == null) return; // 1G828DN - no type ref for synthetic arguments
+       if (javadocVisibility(this.options.reportInvalidJavadocTagsVisibility, modifiers)) {
+               this.handle(
+                       IProblem.JavadocUsingDeprecatedType,
+                       new String[] {new String(type.readableName())},
+                       new String[] {new String(type.shortReadableName())},
+                       location.sourceStart,
+                       location.sourceEnd);
+       }
+}
+//public void javadocDuplicatedParamTag(JavadocSingleNameReference param, int modifiers) {
+//     if (javadocVisibility(this.options.reportInvalidJavadocTagsVisibility, modifiers)) {
+//             String[] arguments = new String[] {String.valueOf(param.token)};
+//             this.handle(IProblem.JavadocDuplicateParamName, arguments, arguments, param.sourceStart, param.sourceEnd);
+//     }
+//}
+public void javadocDuplicatedThrowsClassName(TypeReference typeReference, int modifiers) {
+       if (javadocVisibility(this.options.reportInvalidJavadocTagsVisibility, modifiers)) {
+               String[] arguments = new String[] {String.valueOf(typeReference.resolvedType.sourceName())};
+               this.handle(IProblem.JavadocDuplicateThrowsClassName, arguments, arguments, typeReference.sourceStart, typeReference.sourceEnd);
+       }
+}
+public void javadocErrorNoMethodFor(MessageSend messageSend, TypeBinding recType, TypeBinding[] params, int modifiers) {
+       StringBuffer buffer = new StringBuffer();
+       StringBuffer shortBuffer = new StringBuffer();
+       for (int i = 0, length = params.length; i < length; i++) {
+               if (i != 0){
+                       buffer.append(", "); //$NON-NLS-1$
+                       shortBuffer.append(", "); //$NON-NLS-1$
+               }
+               buffer.append(new String(params[i].readableName()));
+               shortBuffer.append(new String(params[i].shortReadableName()));
+       }
+
+       int id = recType.isArrayType() ? IProblem.JavadocNoMessageSendOnArrayType : IProblem.JavadocNoMessageSendOnBaseType;
+       if (javadocVisibility(this.options.reportInvalidJavadocTagsVisibility, modifiers)) {
+               this.handle(
+                       id,
+                       new String[] {new String(recType.readableName()), new String(messageSend.selector), buffer.toString()},
+                       new String[] {new String(recType.shortReadableName()), new String(messageSend.selector), shortBuffer.toString()},
+                       messageSend.sourceStart,
+                       messageSend.sourceEnd);
+       }
+}
+public void javadocInvalidConstructor(Statement statement, MethodBinding targetConstructor, int modifiers) {
+
+       if (!javadocVisibility(this.options.reportInvalidJavadocTagsVisibility, modifiers)) {
+               return;
+       }
+//     boolean insideDefaultConstructor = 
+//             (this.referenceContext instanceof ConstructorDeclaration)
+//                     && ((ConstructorDeclaration)this.referenceContext).isDefaultConstructor();
+//     boolean insideImplicitConstructorCall =
+//             (statement instanceof ExplicitConstructorCall)
+//                     && (((ExplicitConstructorCall) statement).accessMode == ExplicitConstructorCall.ImplicitSuper);
+
+       int id = IProblem.JavadocUndefinedConstructor; //default...
+       switch (targetConstructor.problemId()) {
+               case NotFound :
+//                     if (insideDefaultConstructor){
+//                             id = IProblem.JavadocUndefinedConstructorInDefaultConstructor;
+//                     } else if (insideImplicitConstructorCall){
+//                             id = IProblem.JavadocUndefinedConstructorInImplicitConstructorCall;
+//                     } else {
+                               id = IProblem.JavadocUndefinedConstructor;
+//                     }
+                       break;
+               case NotVisible :
+//                     if (insideDefaultConstructor){
+//                             id = IProblem.JavadocNotVisibleConstructorInDefaultConstructor;
+//                     } else if (insideImplicitConstructorCall){
+//                             id = IProblem.JavadocNotVisibleConstructorInImplicitConstructorCall;
+//                     } else {
+                               id = IProblem.JavadocNotVisibleConstructor;
+//                     }
+                       break;
+               case Ambiguous :
+//                     if (insideDefaultConstructor){
+//                             id = IProblem.AmbiguousConstructorInDefaultConstructor;
+//                     } else if (insideImplicitConstructorCall){
+//                             id = IProblem.AmbiguousConstructorInImplicitConstructorCall;
+//                     } else {
+                               id = IProblem.JavadocAmbiguousConstructor;
+//                     }
+                       break;
+               case NoError : // 0
+               default :
+                       needImplementation(); // want to fail to see why we were here...
+                       break;
+       }
+
+       this.handle(
+               id,
+               new String[] {new String(targetConstructor.declaringClass.readableName()), parametersAsString(targetConstructor)},
+               new String[] {new String(targetConstructor.declaringClass.shortReadableName()), parametersAsShortString(targetConstructor)},
+               statement.sourceStart,
+               statement.sourceEnd);
+}
+public void javadocAmbiguousMethodReference(int sourceStart, int sourceEnd, Binding fieldBinding, int modifiers) {
+       int id = IProblem.JavadocAmbiguousMethodReference;
+       if (javadocVisibility(this.options.reportInvalidJavadocTagsVisibility, modifiers)) {
+               String[] arguments = new String[] {new String(fieldBinding.readableName())};
+               handle(id, arguments, arguments, sourceStart, sourceEnd);
+       }
+}
+/*
+ * Similar implementation than invalidField(FieldReference...)
+ * Note that following problem id cannot occur for Javadoc:
+ *     - NonStaticReferenceInStaticContext :
+ *     - NonStaticReferenceInConstructorInvocation :
+ *     - ReceiverTypeNotVisible :
+ */
+public void javadocInvalidField(int sourceStart, int sourceEnd, Binding fieldBinding, TypeBinding searchedType, int modifiers) {
+       int id = IProblem.JavadocUndefinedField;
+       switch (fieldBinding.problemId()) {
+               case NotFound :
+                       id = IProblem.JavadocUndefinedField;
+                       break;
+               case NotVisible :
+                       id = IProblem.JavadocNotVisibleField;
+                       break;
+               case Ambiguous :
+                       id = IProblem.JavadocAmbiguousField;
+                       break;
+               case InheritedNameHidesEnclosingName :
+                       id = IProblem.JavadocInheritedFieldHidesEnclosingName;
+                       break;
+               case NoError : // 0
+               default :
+                       needImplementation(); // want to fail to see why we were here...
+                       break;
+       }
+
+       if (javadocVisibility(this.options.reportInvalidJavadocTagsVisibility, modifiers)) {
+               String[] arguments = new String[] {new String(fieldBinding.readableName())};
+               handle(id, arguments, arguments, sourceStart, sourceEnd);
+       }
+}
+/*
+ * Similar implementation than invalidMethod(MessageSend...)
+ * Note that following problem id cannot occur for Javadoc:
+ *     - NonStaticReferenceInStaticContext :
+ *     - NonStaticReferenceInConstructorInvocation :
+ *     - ReceiverTypeNotVisible :
+ */
+public void javadocInvalidMethod(MessageSend messageSend, MethodBinding method, int modifiers) {
+       if (!javadocVisibility(this.options.reportInvalidJavadocTagsVisibility, modifiers)) {
+               return;
+       }
+       int id = IProblem.JavadocUndefinedMethod; //default...
+       switch (method.problemId()) {
+               case NotFound :
+                       id = IProblem.JavadocUndefinedMethod;
+                       break;
+               case NotVisible :
+                       id = IProblem.JavadocNotVisibleMethod;
+                       break;
+               case Ambiguous :
+                       id = IProblem.JavadocAmbiguousMethod;
+                       break;
+               case InheritedNameHidesEnclosingName :
+                       id = IProblem.JavadocInheritedMethodHidesEnclosingName;
+                       break;
+               case NoError : // 0
+               default :
+                       needImplementation(); // want to fail to see why we were here...
+                       break;
+       }
+
+       if (id == IProblem.JavadocUndefinedMethod) {
+               ProblemMethodBinding problemMethod = (ProblemMethodBinding) method;
+               if (problemMethod.closestMatch != null) {
+                               String closestParameterTypeNames = parametersAsString(problemMethod.closestMatch);
+                               String parameterTypeNames = parametersAsString(method);
+                               String closestParameterTypeShortNames = parametersAsShortString(problemMethod.closestMatch);
+                               String parameterTypeShortNames = parametersAsShortString(method);
+                               if (closestParameterTypeShortNames.equals(parameterTypeShortNames)){
+                                       closestParameterTypeShortNames = closestParameterTypeNames;
+                                       parameterTypeShortNames = parameterTypeNames;
+                               }
+                               this.handle(
+                                       IProblem.JavadocParameterMismatch,
+                                       new String[] {
+                                               new String(problemMethod.closestMatch.declaringClass.readableName()),
+                                               new String(problemMethod.closestMatch.selector),
+                                               closestParameterTypeNames,
+                                               parameterTypeNames 
+                                       },
+                                       new String[] {
+                                               new String(problemMethod.closestMatch.declaringClass.shortReadableName()),
+                                               new String(problemMethod.closestMatch.selector),
+                                               closestParameterTypeShortNames,
+                                               parameterTypeShortNames
+                                       },
+                                       (int) (messageSend.nameSourcePosition >>> 32),
+                                       (int) messageSend.nameSourcePosition);
+                               return;
+               }
+       }
+
+       this.handle(
+               id,
+               new String[] {
+                       new String(method.declaringClass.readableName()),
+                       new String(method.selector), parametersAsString(method)},
+               new String[] {
+                       new String(method.declaringClass.shortReadableName()),
+                       new String(method.selector), parametersAsShortString(method)},
+               (int) (messageSend.nameSourcePosition >>> 32),
+               (int) messageSend.nameSourcePosition);
+}
+//public void javadocInvalidParamName(JavadocSingleNameReference param, int modifiers) {
+//     if (javadocVisibility(this.options.reportInvalidJavadocTagsVisibility, modifiers)) {
+//             String[] arguments = new String[] {String.valueOf(param.token)};
+//             this.handle(IProblem.JavadocInvalidParamName, arguments, arguments, param.sourceStart, param.sourceEnd);
+//     }
+//}
+public void javadocInvalidSeeReference(int sourceStart, int sourceEnd) {
+       this.handle(IProblem.JavadocInvalidSeeReference, NoArgument, NoArgument, sourceStart, sourceEnd);
+}
+public void javadocInvalidSeeReferenceArgs(int sourceStart, int sourceEnd) {
+       this.handle(IProblem.JavadocInvalidSeeArgs, NoArgument, NoArgument, sourceStart, sourceEnd);
+}
+public void javadocInvalidSeeUrlReference(int sourceStart, int sourceEnd) {
+       this.handle(IProblem.JavadocInvalidSeeHref, NoArgument, NoArgument, sourceStart, sourceEnd);
+}
+public void javadocInvalidTag(int sourceStart, int sourceEnd) {
+       this.handle(IProblem.JavadocInvalidTag, NoArgument, NoArgument, sourceStart, sourceEnd);
+}
+public void javadocInvalidThrowsClass(int sourceStart, int sourceEnd) {
+       this.handle(IProblem.JavadocInvalidThrowsClass, NoArgument, NoArgument, sourceStart, sourceEnd);
+}
+public void javadocInvalidThrowsClassName(TypeReference typeReference, int modifiers) {
+       if (javadocVisibility(this.options.reportInvalidJavadocTagsVisibility, modifiers)) {
+               String[] arguments = new String[] {String.valueOf(typeReference.resolvedType.sourceName())};
+               this.handle(IProblem.JavadocInvalidThrowsClassName, arguments, arguments, typeReference.sourceStart, typeReference.sourceEnd);
+       }
+}
+public void javadocInvalidType(ASTNode location, TypeBinding type, int modifiers) {
+       if (javadocVisibility(this.options.reportInvalidJavadocTagsVisibility, modifiers)) {
+               int id = IProblem.JavadocUndefinedType; // default
+               switch (type.problemId()) {
+                       case NotFound :
+                               id = IProblem.JavadocUndefinedType;
+                               break;
+                       case NotVisible :
+                               id = IProblem.JavadocNotVisibleType;
+                               break;
+                       case Ambiguous :
+                               id = IProblem.JavadocAmbiguousType;
+                               break;
+                       case InternalNameProvided :
+                               id = IProblem.JavadocInternalTypeNameProvided;
+                               break;
+                       case InheritedNameHidesEnclosingName :
+                               id = IProblem.JavadocInheritedNameHidesEnclosingTypeName;
+                               break;
+                       case NoError : // 0
+                       default :
+                               needImplementation(); // want to fail to see why we were here...
+                               break;
+               }
+               this.handle(
+                       id,
+                       new String[] {new String(type.readableName())},
+                       new String[] {new String(type.shortReadableName())},
+                       location.sourceStart,
+                       location.sourceEnd);
+       }
+}
+public void javadocMalformedSeeReference(int sourceStart, int sourceEnd) {
+       this.handle(IProblem.JavadocMalformedSeeReference, NoArgument, NoArgument, sourceStart, sourceEnd);
+}
+public void javadocMissing(int sourceStart, int sourceEnd, int modifiers){
+       boolean overriding = (modifiers & (CompilerModifiers.AccImplementing+CompilerModifiers.AccOverriding)) != 0;
+       boolean report = (this.options.getSeverity(CompilerOptions.MissingJavadocComments) != ProblemSeverities.Ignore)
+                                       && (!overriding || this.options.reportMissingJavadocCommentsOverriding);
+       if (report) {
+               String arg = javadocVisibilityArgument(this.options.reportMissingJavadocCommentsVisibility, modifiers);
+               if (arg != null) {
+                       String[] arguments = new String[] { arg };
+                       this.handle(IProblem.JavadocMissing, arguments, arguments, sourceStart, sourceEnd);
+               }
+       }
+}
+public void javadocMissingParamName(int sourceStart, int sourceEnd){
+       this.handle(IProblem.JavadocMissingParamName, NoArgument, NoArgument, sourceStart, sourceEnd);
+}
+public void javadocMissingParamTag(Argument param, int modifiers) {
+       boolean overriding = (modifiers & (CompilerModifiers.AccImplementing+CompilerModifiers.AccOverriding)) != 0;
+       boolean report = (this.options.getSeverity(CompilerOptions.MissingJavadocTags) != ProblemSeverities.Ignore)
+                                       && (!overriding || this.options.reportMissingJavadocTagsOverriding);
+       if (report && javadocVisibility(this.options.reportMissingJavadocTagsVisibility, modifiers)) {
+               String[] arguments = new String[] { String.valueOf(param.name) };
+               this.handle(IProblem.JavadocMissingParamTag, arguments, arguments, param.sourceStart, param.sourceEnd);
+       }
+}
+public void javadocMissingReturnTag(int sourceStart, int sourceEnd, int modifiers){
+       boolean overriding = (modifiers & (CompilerModifiers.AccImplementing+CompilerModifiers.AccOverriding)) != 0;
+       boolean report = (this.options.getSeverity(CompilerOptions.MissingJavadocTags) != ProblemSeverities.Ignore)
+                                       && (!overriding || this.options.reportMissingJavadocTagsOverriding);
+       if (report && javadocVisibility(this.options.reportMissingJavadocTagsVisibility, modifiers)) {
+               this.handle(IProblem.JavadocMissingReturnTag, NoArgument, NoArgument, sourceStart, sourceEnd);
+       }
+}
+public void javadocMissingSeeReference(int sourceStart, int sourceEnd){
+       this.handle(IProblem.JavadocMissingSeeReference, NoArgument, NoArgument, sourceStart, sourceEnd);
+}
+public void javadocMissingThrowsClassName(int sourceStart, int sourceEnd){
+       this.handle(IProblem.JavadocMissingThrowsClassName, NoArgument, NoArgument, sourceStart, sourceEnd);
+}
+public void javadocMissingThrowsTag(TypeReference typeRef, int modifiers){
+       boolean overriding = (modifiers & (CompilerModifiers.AccImplementing+CompilerModifiers.AccOverriding)) != 0;
+       boolean report = (this.options.getSeverity(CompilerOptions.MissingJavadocTags) != ProblemSeverities.Ignore)
+                                       && (!overriding || this.options.reportMissingJavadocTagsOverriding);
+       if (report && javadocVisibility(this.options.reportMissingJavadocTagsVisibility, modifiers)) {
+               String[] arguments = new String[] { String.valueOf(typeRef.resolvedType.sourceName()) };
+               this.handle(IProblem.JavadocMissingThrowsTag, arguments, arguments, typeRef.sourceStart, typeRef.sourceEnd);
+       }
+}
+public void javadocUnexpectedTag(int sourceStart, int sourceEnd) {
+       this.handle(IProblem.JavadocUnexpectedTag, NoArgument, NoArgument, sourceStart, sourceEnd);
+}
+public void javadocUnterminatedInlineTag(int sourceStart, int sourceEnd) {
+       this.handle(IProblem.JavadocUnterminatedInlineTag, NoArgument, NoArgument, sourceStart, sourceEnd);
+}
+private boolean javadocVisibility(int visibility, int modifiers) {
+       switch (modifiers & CompilerModifiers.AccVisibilityMASK) {
+               case IConstants.AccPublic :
+                       return true;
+               case IConstants.AccProtected:
+                       return (visibility != IConstants.AccPublic);
+//             case IConstants.AccDefault:
+//                     return (visibility == IConstants.AccDefault || visibility == IConstants.AccPrivate);
+               case IConstants.AccPrivate:
+                       return (visibility == IConstants.AccPrivate);
+       }
+       return true;
+}
+private String javadocVisibilityArgument(int visibility, int modifiers) {
+       String argument = null;
+       switch (modifiers & CompilerModifiers.AccVisibilityMASK) {
+               case IConstants.AccPublic :
+                       argument = CompilerOptions.PUBLIC;
+                       break;
+               case IConstants.AccProtected:
+                       if (visibility != IConstants.AccPublic) {
+                               argument = CompilerOptions.PROTECTED;
+                       }
+                       break;
+//             case IConstants.AccDefault:
+//                     if (visibility == IConstants.AccDefault || visibility == IConstants.AccPrivate) {
+//                             argument = CompilerOptions.DEFAULT;
+//                     }
+//                     break;
+               case IConstants.AccPrivate:
+                       if (visibility == IConstants.AccPrivate) {
+                               argument = CompilerOptions.PRIVATE;
+                       }
+                       break;
+       }
+       return argument;
+}
 
   public void methodNeedingAbstractModifier(MethodDeclaration methodDecl) {
     this.handle(IProblem.MethodRequiresBody, NoArgument, NoArgument, methodDecl.sourceStart, methodDecl.sourceEnd);