Skip to content

Commit

Permalink
fix end offset of type parameters and primitives (incl. arrays of)
Browse files Browse the repository at this point in the history
  • Loading branch information
eric-milles committed Mar 17, 2022
1 parent ec2e886 commit ec804d5
Show file tree
Hide file tree
Showing 3 changed files with 72 additions and 34 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2009-2021 the original author or authors.
* Copyright 2009-2022 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -410,6 +410,43 @@ public void testGenericsArityErrors() {
"----------\n");
}

@Test
public void testGenericsBoundsError() {
//@formatter:off
String[] sources = {
"T.groovy",
"class T<X extends Y> {}\n",
};
//@formatter:on

runNegativeTest(sources,
"----------\n" +
"1. ERROR in T.groovy (at line 1)\n" +
"\tclass T<X extends Y> {}\n" +
"\t ^\n" +
"Groovy:unable to resolve class Y\n" +
"----------\n");
}

@Test
public void testGenericsHidingError() {
//@formatter:off
String[] sources = {
"T.groovy",
"class T {}\n" +
"class U<T> {}\n",
};
//@formatter:on

runNegativeTest(sources,
"----------\n" +
"1. WARNING in T.groovy (at line 2)\n" +
"\tclass U<T> {}\n" +
"\t ^\n" +
"The type parameter T is hiding the type T\n" +
"----------\n");
}

@Test
public void testCallingGenericConstructors() {
//@formatter:off
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4811,7 +4811,7 @@ public void testTypeChecked10322() {
"----------\n" +
"1. WARNING in Main.groovy (at line 2)\n" +
"\tdef <T> T m(T t) {\n" +
"\t ^^\n" +
"\t ^\n" +
"The type parameter T is hiding the type T\n" +
"----------\n");
}
Expand All @@ -4836,7 +4836,7 @@ public void testTypeChecked10323() {
"----------\n" +
"1. ERROR in Main.groovy (at line 3)\n" +
"\tdef <T,T> T m(C<T> c) {\n" +
"\t ^^\n" +
"\t ^\n" +
"Duplicate type parameter T\n" +
"----------\n");
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2013,12 +2013,12 @@ private TypeReference createTypeReferenceForArrayNameTrailingBrackets(ClassNode
throw new IllegalStateException("node " + node + " reported it had a primitive component type, but it does not!");
} else {
TypeReference baseTypeReference = TypeReference.baseTypeReference(typeId, dim);
if (sourceEnd > 0) sourceEnd = sourceStart + componentType.getName().length();
baseTypeReference.sourceStart = sourceStart;
baseTypeReference.sourceEnd = sourceStart + componentType.getName().length();
baseTypeReference.sourceEnd = sourceEnd - 1;
return baseTypeReference;
}
}
assert dim > 0 : "array ClassNode with no dimensions: " + name;

char[] typeName = name.substring(0, pos + 2).toCharArray();

Expand Down Expand Up @@ -2057,52 +2057,53 @@ private TypeReference createTypeReferenceForArrayNameLeadingBrackets(ClassNode n
throw new IllegalStateException("node " + node + " reported it had a primitive component type, but it does not!");
} else {
TypeReference baseTypeReference = TypeReference.baseTypeReference(typeId, dim);
if (sourceEnd > 0) sourceEnd = sourceStart + componentType.getName().length();
baseTypeReference.sourceStart = sourceStart;
baseTypeReference.sourceEnd = sourceStart + componentType.getName().length();
baseTypeReference.sourceEnd = sourceEnd - 1;
return baseTypeReference;
}
} else {
name = name.substring(dim);
if (name.charAt(name.length() - 1) == ';') {
name = name.substring(1, name.length() - 1); // chop off 'L' and ';'
}
}

char[] typeName = name.toCharArray();
name = name.substring(dim);
if (name.charAt(name.length() - 1) == ';') {
name = name.substring(1, name.length() - 1); // chop off 'L' and ';'
}

if (unitDeclaration.imports.length > 0) {
char[][] compoundName = CharOperation.splitOn('.', typeName);
for (ImportReference importReference : unitDeclaration.imports) {
if (isAliasForType(importReference, compoundName[0])) {
typeName = CharOperation.concatWith(importReference.getImportName(), '.');
if (compoundName.length > 1) {
typeName = CharOperation.concatWith(typeName, CharOperation.subarray(compoundName, 1, -1), '.');
}
break;
char[] typeName = name.toCharArray();

if (unitDeclaration.imports.length > 0) {
char[][] compoundName = CharOperation.splitOn('.', typeName);
for (ImportReference importReference : unitDeclaration.imports) {
if (isAliasForType(importReference, compoundName[0])) {
typeName = CharOperation.concatWith(importReference.getImportName(), '.');
if (compoundName.length > 1) {
typeName = CharOperation.concatWith(typeName, CharOperation.subarray(compoundName, 1, -1), '.');
}
break;
}
}

return createTypeReferenceForArrayName(typeName, componentType, dim, sourceStart, sourceEnd);
}

return createTypeReferenceForArrayName(typeName, componentType, dim, sourceStart, sourceEnd);
}

private TypeReference createTypeReferenceForArrayName(char[] typeName, ClassNode typeNode, int dim, int sourceStart, int sourceEnd) {
int nameEnd = (sourceEnd == -2 ? -1 : typeNode.getEnd());
int nameEnd = (sourceEnd < 0 ? -1 : typeNode.getEnd());
if (!typeNode.isUsingGenerics()) {
if (CharOperation.indexOf('.', typeName) < 0) {
// For a single array reference, for example 'String[]' start will be 'S' and end will be the char after ']'. When the
// ArrayTypeReference is built we need these positions for the result: sourceStart - the 'S'; sourceEnd - the last ']';
// originalSourceEnd - the 'g'
ArrayTypeReference tr = new ArrayTypeReference(typeName, dim, toPos(sourceStart, nameEnd - 1));
tr.sourceEnd = sourceEnd == -2 ? -2 : sourceEnd - 1;
tr.sourceEnd = sourceEnd - 1;
return tr;
} else {
// For a qualified array reference, for example 'java.lang.Number[][]' start will be 'j' and end will be the char after ']'.
// When the ArrayQualifiedTypeReference is built we need these positions for the result: sourceStart - the 'j'; sourceEnd - the
// last ']'; the positions computed for the reference components would be j..a l..g and N..r
char[][] compoundName = CharOperation.splitOn('.', typeName);
ArrayQualifiedTypeReference tr = new ArrayQualifiedTypeReference(compoundName, dim, positionsFor(compoundName, sourceStart, nameEnd - 1));
tr.sourceEnd = sourceEnd == -2 ? -2 : sourceEnd - 1;
tr.sourceEnd = sourceEnd - 1;
return tr;
}
} else {
Expand All @@ -2114,14 +2115,14 @@ private TypeReference createTypeReferenceForArrayName(char[] typeName, ClassNode

if (CharOperation.indexOf('.', typeName) < 0) {
ParameterizedSingleTypeReference tr = new ParameterizedSingleTypeReference(typeName, typeArgs, dim, toPos(sourceStart, nameEnd - 1));
tr.sourceEnd = sourceEnd == -2 ? -2 : sourceEnd - 1;
tr.sourceEnd = sourceEnd - 1;
return tr;
} else {
char[][] compoundName = CharOperation.splitOn('.', typeName);
TypeReference[][] compoundArgs = new TypeReference[compoundName.length][];
compoundArgs[compoundName.length - 1] = typeArgs;
ParameterizedQualifiedTypeReference tr = new ParameterizedQualifiedTypeReference(compoundName, compoundArgs, dim, positionsFor(compoundName, sourceStart, nameEnd - 1));
tr.sourceEnd = sourceEnd == -2 ? -2 : sourceEnd - 1;
tr.sourceEnd = sourceEnd - 1;
return tr;
}
}
Expand Down Expand Up @@ -2183,7 +2184,7 @@ private TypeReference[] createTypeReferencesForClassNodes(ClassNode[] classNodes
}

private TypeReference createTypeReferenceForClassNode(ClassNode classNode) {
return createTypeReferenceForClassNode(classNode, startOffset(classNode), endOffset(classNode));
return createTypeReferenceForClassNode(classNode, startOffset(classNode), Math.max(endOffset(classNode), -1));
}

private TypeReference createTypeReferenceForClassNode(ClassNode classNode, int sourceStart, int sourceEnd) {
Expand All @@ -2210,7 +2211,7 @@ private TypeReference createTypeReferenceForClassNode(ClassNode classNode, int s
if (name.length() == 1 && name.charAt(0) == '?') {
TypeReference tr = new Wildcard(Wildcard.UNBOUND);
tr.sourceStart = sourceStart;
tr.sourceEnd = sourceEnd;
tr.sourceEnd = sourceEnd - 1;
return tr;
}

Expand All @@ -2224,7 +2225,7 @@ private TypeReference createTypeReferenceForClassNode(ClassNode classNode, int s
if (nameToPrimitiveTypeId.containsKey(name)) {
TypeReference tr = TypeReference.baseTypeReference(nameToPrimitiveTypeId.get(name), 0);
tr.sourceStart = sourceStart;
tr.sourceEnd = sourceEnd;
tr.sourceEnd = sourceEnd - 1;
return tr;
}

Expand Down Expand Up @@ -2329,7 +2330,7 @@ private TypeParameter[] createTypeParametersForGenerics(GenericsType[] generics)
int offset = generics[i].getStart(),
length = typeParameter.name.length;
typeParameter.sourceStart = offset;
typeParameter.sourceEnd = offset + length;
typeParameter.sourceEnd = offset + length - 1;

ClassNode[] upperBounds = generics[i].getUpperBounds();
if (upperBounds != null && upperBounds.length > 0) {
Expand Down Expand Up @@ -2451,9 +2452,9 @@ private long[] positionsFor(char[][] reference, long start, long end) {
result[i] = ((offset << 32) | offset + length);
offset += length + 2; // advance past the next '.'
}
} else if (start == -1 && end == -2) {
} else if (start == -1) {
Arrays.fill(result, (-1L << 32) | -2L);
} else { // FIXASC: This case shouldn't happen
} else { // length is 0 or ...
Arrays.fill(result, (start << 32) | start);
}
return result;
Expand Down

0 comments on commit ec804d5

Please sign in to comment.