primitive type parameters are not allowed in Groovy

This commit is contained in:
Maxim.Medvedev
2012-01-26 13:40:20 +04:00
parent 540f59614e
commit f534949f19
5 changed files with 125 additions and 0 deletions
@@ -299,3 +299,5 @@ add.parentheses=Add parentheses
add.parentheses.to.command.method.call=Add parentheses to command method call
dollar.slash.strings.are.not.allowed.in.0=Dollar slashy strings are not allowed in Groovy {0}
method.with.type.parameters.should.have.return.type=Method with type parameters should have return type
primitive.type.parameters.are.not.allowed=Primitive type parameters are not allowed
primitive.bound.types.are.not.allowed=Primitive bound types are not allowed
@@ -657,6 +657,35 @@ public class GroovyAnnotator extends GroovyElementVisitor implements Annotator {
checkNamedArgs(listOrMap.getNamedArguments(), false);
}
@Override
public void visitClassTypeElement(GrClassTypeElement typeElement) {
super.visitClassTypeElement(typeElement);
final GrCodeReferenceElement ref = typeElement.getReferenceElement();
final GrTypeArgumentList argList = ref.getTypeArgumentList();
if (argList == null) return;
final GrTypeElement[] elements = argList.getTypeArgumentElements();
for (GrTypeElement element : elements) {
checkTypeArgForPrimitive(element, GroovyBundle.message("primitive.type.parameters.are.not.allowed"));
}
}
private void checkTypeArgForPrimitive(@Nullable GrTypeElement element, String message) {
if (element == null || !(element.getType() instanceof PsiPrimitiveType)) return;
myHolder.
createErrorAnnotation(element, message).
registerFix(new GrReplacePrimitiveTypeWithWrapperFix(element));
}
@Override
public void visitWildcardTypeArgument(GrWildcardTypeArgument wildcardTypeArgument) {
super.visitWildcardTypeArgument(wildcardTypeArgument);
checkTypeArgForPrimitive(wildcardTypeArgument.getBoundTypeElement(), GroovyBundle.message("primitive.bound.types.are.not.allowed"));
}
private void highlightNamedArgs(GrNamedArgument[] namedArguments) {
for (GrNamedArgument namedArgument : namedArguments) {
final GrArgumentLabel label = namedArgument.getLabel();
@@ -0,0 +1,82 @@
/*
* Copyright 2000-2012 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.plugins.groovy.annotator.intentions;
import com.intellij.codeInsight.intention.IntentionAction;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.project.Project;
import com.intellij.psi.*;
import com.intellij.util.IncorrectOperationException;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.plugins.groovy.intentions.GroovyIntentionsBundle;
import org.jetbrains.plugins.groovy.lang.GrReferenceAdjuster;
import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElementFactory;
import org.jetbrains.plugins.groovy.lang.psi.api.types.GrTypeElement;
/**
* @author Max Medvedev
*/
public class GrReplacePrimitiveTypeWithWrapperFix implements IntentionAction {
private static final Logger LOG = Logger.getInstance(GrReplacePrimitiveTypeWithWrapperFix.class);
private final GrTypeElement myTypeElement;
private final String myBoxedName;
public GrReplacePrimitiveTypeWithWrapperFix(GrTypeElement typeElement) {
LOG.assertTrue(typeElement.isValid());
myTypeElement = typeElement;
final PsiType type = typeElement.getType();
LOG.assertTrue(type instanceof PsiPrimitiveType);
myBoxedName = ((PsiPrimitiveType)type).getBoxedType(typeElement).getClassName();
}
@NotNull
@Override
public String getText() {
return GroovyIntentionsBundle.message("replace.with.wrapper", myBoxedName);
}
@NotNull
@Override
public String getFamilyName() {
return GroovyIntentionsBundle.message("replace.primitive.type.with.wrapper");
}
@Override
public boolean isAvailable(@NotNull Project project, Editor editor, PsiFile file) {
return myTypeElement.isValid() && myTypeElement.getType() instanceof PsiPrimitiveType;
}
@Override
public void invoke(@NotNull Project project, Editor editor, PsiFile file) throws IncorrectOperationException {
final PsiType type = myTypeElement.getType();
if (!(type instanceof PsiPrimitiveType)) return;
final PsiClassType boxed = ((PsiPrimitiveType)type).getBoxedType(myTypeElement);
final GrTypeElement newTypeElement = GroovyPsiElementFactory.getInstance(project).createTypeElement(boxed);
final PsiElement replaced = myTypeElement.replace(newTypeElement);
GrReferenceAdjuster.shortenReferences(replaced);
}
@Override
public boolean startInWriteAction() {
return true;
}
}
@@ -143,3 +143,5 @@ remove.unnecessary.semicolons.family.name=Remove unnecessary semicolons from sel
no.unnecessary.semicolons.found=No unnecessary semicolons found
add.return.type=Add return type
add.return.type.to.method.declaration=Add return type to method declaration
replace.with.wrapper=Replace with {0}
replace.primitive.type.with.wrapper=Replace primitive type with wrapper
@@ -645,4 +645,14 @@ def result = new Foo().x''')
myFixture.enableInspections(new ClashingGettersInspection())
myFixture.testHighlighting(true, false, false)
}
void testPrimitiveTypeParams() {
myFixture.configureByText('a.groovy', '''
List<<error descr="Primitive type parameters are not allowed">int</error>> list = new ArrayList<int><EOLError descr="'(' expected"></EOLError>
List<? extends <error descr="Primitive bound types are not allowed">double</error>> l = new ArrayList<double>()
List<?> list2
''')
myFixture.testHighlighting(true, false, false)
}
}