in flex/src/com/intellij/lang/javascript/inspections/actionscript/ActionScriptAnnotatingVisitor.java [306:466]
public void visitJSFunctionDeclaration(final @NotNull JSFunction node) {
super.visitJSFunctionDeclaration(node);
checkPackageElement(node);
final ASTNode nameIdentifier = node.findNameIdentifier();
if (nameIdentifier == null) return;
PsiElement parent = node.getParent();
if (parent instanceof JSFile) {
parent = JSResolveUtil.getClassReferenceForXmlFromContext(parent);
final String name = node.getName();
if (parent instanceof JSClass &&
name != null &&
name.equals(((JSClass)parent).getName()) &&
!isNative(node) &&
FlexSupportLoader.isFlexMxmFile(parent.getContainingFile())) {
myHolder.newAnnotation(HighlightSeverity.ERROR,
FlexBundle.message("javascript.validation.message.constructor.in.mxml.is.not.allowed")
).range(nameIdentifier)
.withFix(new RemoveASTNodeFix("javascript.fix.remove.constructor", node)).create();
}
}
if (parent instanceof JSClass clazz && !node.isConstructor()) {
final JSAttributeList attributeList = node.getAttributeList();
if (attributeList == null ||
!attributeList.hasModifier(JSAttributeList.ModifierType.STATIC) &&
(attributeList.getAccessType() != JSAttributeList.AccessType.PRIVATE ||
attributeList.hasModifier(JSAttributeList.ModifierType.OVERRIDE)
)) {
final String qName = clazz.getQualifiedName();
final boolean hasOverride = attributeList != null && attributeList.hasModifier(JSAttributeList.ModifierType.OVERRIDE);
final Ref<JSFunction> set = new Ref<>();
boolean b = JSResolveUtil.iterateOverrides(node, null, new JSOverrideHandler() {
@Override
public boolean process(final @NotNull List<? extends JSPsiElementBase> elements, final PsiElement scope, final @Nullable String className) {
if (Objects.equals(qName, className)) return true;
JSFunction value = (JSFunction)elements.iterator().next();
set.set(value);
DialectOptionHolder holder= myHighlighter.getDialectOptionsHolder();
if ("Object".equals(className)) {
if (hasOverride && !attributeList.hasModifier(JSAttributeList.ModifierType.NATIVE)) { /*native modifier is written always*/
final ASTNode astNode = attributeList.getNode().findChildByType(JSTokenTypes.OVERRIDE_KEYWORD);
myHolder.newAnnotation(HighlightSeverity.ERROR,
JavaScriptBundle.message("javascript.validation.message.function.override.for.object.method"))
.range(astNode)
.withFix(new RemoveASTNodeFix("javascript.fix.remove.override.modifier", astNode.getPsi()))
.create();
}
return false;
}
else if (!hasOverride && holder.isECMA4) {
myHolder.newAnnotation(HighlightSeverity.ERROR, JavaScriptBundle.message(
"javascript.validation.message.function.override.without.override.modifier", className))
.range(nameIdentifier)
.withFix(new AddOverrideIntentionAction(node))
.create();
}
else {
JSAttributeList attrList = value.getAttributeList();
JSAttributeList parentAttrList = ((JSAttributeListOwner)scope).getAttributeList();
if (attrList != null && attrList.hasModifier(JSAttributeList.ModifierType.FINAL) ||
parentAttrList != null && parentAttrList.hasModifier(JSAttributeList.ModifierType.FINAL)
) {
myHolder.newAnnotation(HighlightSeverity.ERROR,
JavaScriptBundle.message("javascript.validation.message.can.not.override.final.method", className))
.range(attributeList.getNode().findChildByType(JSTokenTypes.OVERRIDE_KEYWORD))
.create();
}
}
if (clazz.isInterface()) {
myHolder.newAnnotation(HighlightSeverity.ERROR, JavaScriptBundle.message(
"javascript.validation.message.function.override.for.interface", className)).range(nameIdentifier).create();
}
return false;
}
}, true);
if (b && hasOverride) {
final ASTNode astNode = attributeList.getNode().findChildByType(JSTokenTypes.OVERRIDE_KEYWORD);
myHolder.newAnnotation(HighlightSeverity.ERROR,
JavaScriptBundle.message("javascript.validation.message.function.override.without.parent.method"))
.range(astNode)
.withFix(new RemoveASTNodeFix("javascript.fix.remove.override.modifier", astNode.getPsi()))
.create();
}
if (!b && hasOverride) {
final JSFunction override = set.get();
final JSAttributeList overrideAttrList = override.getAttributeList();
String overrideNs = null;
if (attributeList.getAccessType() != overrideAttrList.getAccessType() ||
(overrideNs = ActionScriptPsiImplUtil.getNamespaceValue(overrideAttrList)) != null &&
!overrideNs.equals(ActionScriptPsiImplUtil.getNamespaceValue(attributeList))) {
String newVisibility;
ModCommandAction fix;
if (overrideNs != null) {
newVisibility = overrideNs;
fix = JSFixFactory.getInstance().createChangeVisibilityFix(node, null ,overrideNs);
}
else {
newVisibility = JSFormatUtil.formatVisibility(overrideAttrList.getAccessType());
fix = JSFixFactory.getInstance().createChangeVisibilityFix(node, overrideAttrList.getAccessType() ,null);
}
myHolder.newAnnotation(HighlightSeverity.ERROR, JavaScriptBundle
.message("javascript.validation.message.function.override.incompatible.access.modifier", newVisibility))
.range(findElementForAccessModifierError(node, attributeList))
.withFix(fix)
.create();
}
final SignatureMatchResult incompatibleSignature = checkCompatibleSignature(node, override);
if (incompatibleSignature == SignatureMatchResult.PARAMETERS_DIFFERS) {
final JSParameterList nodeParameterList = node.getParameterList();
final JSParameterList overrideParameterList = override.getParameterList();
myHolder.newAnnotation(HighlightSeverity.ERROR,
JavaScriptBundle.message("javascript.validation.message.function.override.incompatible.signature",
overrideParameterList != null ? overrideParameterList.getText() : "()"
))
.range(nodeParameterList != null ? nodeParameterList.getNode() : node.findNameIdentifier())
.withFix(new JSChangeSignatureFix(node, overrideParameterList, false) {
@Override
public @NotNull String getText() {
return JavaScriptBundle.message("javascript.fix.message.change.parameters.to.expected");
}
})
.withFix(new JSChangeSignatureFix(override, nodeParameterList))
.create();
}
else if (incompatibleSignature == SignatureMatchResult.RETURN_TYPE_DIFFERS) {
PsiElement returnTypeExpr = node.getReturnTypeElement();
JSType type = override.getReturnType();
final String baseReturnType = type != null ? type.getResolvedTypeText() : null;
String msg = JavaScriptBundle
.message("javascript.validation.message.function.override.incompatible.signature2", StringUtil.notNullize(baseReturnType));
myHolder.newAnnotation(HighlightSeverity.ERROR, msg)
.range(returnTypeExpr != null ? returnTypeExpr.getNode() : node.findNameIdentifier())
.withFix(new JSChangeTypeFix(node, baseReturnType, "javascript.fix.message.change.return.type.to.expected"))
.withFix(createChangeBaseMethodSignatureFix(override, node))
.create();
}
else if (incompatibleSignature == SignatureMatchResult.FUNCTION_KIND_DIFFERS) {
String msg = JavaScriptBundle
.message("javascript.validation.message.function.override.incompatible.signature3", override.getKind().toString());
myHolder.newAnnotation(HighlightSeverity.ERROR, msg).range(node.findNameIdentifier())
.create();
}
}
}
}
}