Skip to content

Commit df01599

Browse files
committed
GROOVY-4020, GROOVY-5760, GROOVY-7670, GROOVY-9194
1 parent 550abd0 commit df01599

26 files changed

Lines changed: 644 additions & 112 deletions

File tree

base/org.codehaus.groovy25/.checkstyle

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
<file-match-pattern match-pattern="groovy/classgen/AsmClassGenerator.java" include-pattern="false" />
3939
<file-match-pattern match-pattern="groovy/classgen/EnumVisitor.java" include-pattern="false" />
4040
<file-match-pattern match-pattern="groovy/classgen/ExtendedVerifier.java" include-pattern="false" />
41+
<file-match-pattern match-pattern="groovy/classgen/GeneratorContext.java" include-pattern="false" />
4142
<file-match-pattern match-pattern="groovy/classgen/Verifier.java" include-pattern="false" />
4243
<file-match-pattern match-pattern="groovy/classgen/asm/CompileStack.java" include-pattern="false" />
4344
<file-match-pattern match-pattern="groovy/classgen/asm/InvocationWriter.java" include-pattern="false" />
Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one
3+
* or more contributor license agreements. See the NOTICE file
4+
* distributed with this work for additional information
5+
* regarding copyright ownership. The ASF licenses this file
6+
* to you under the Apache License, Version 2.0 (the
7+
* "License"); you may not use this file except in compliance
8+
* with the License. You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
package org.codehaus.groovy.classgen;
20+
21+
import org.codehaus.groovy.GroovyBugError;
22+
import org.codehaus.groovy.ast.ClassHelper;
23+
import org.codehaus.groovy.ast.ClassNode;
24+
import org.codehaus.groovy.ast.CompileUnit;
25+
import org.codehaus.groovy.ast.MethodNode;
26+
27+
28+
/**
29+
* A context shared across generations of a class and its inner classes
30+
*/
31+
public class GeneratorContext {
32+
33+
private int innerClassIdx = 1;
34+
private int closureClassIdx = 1;
35+
private final CompileUnit compileUnit;
36+
37+
public GeneratorContext(CompileUnit compileUnit) {
38+
this.compileUnit = compileUnit;
39+
}
40+
41+
public GeneratorContext(CompileUnit compileUnit, int innerClassOffset) {
42+
this.compileUnit = compileUnit;
43+
this.innerClassIdx = innerClassOffset;
44+
}
45+
46+
public int getNextInnerClassIdx() {
47+
return innerClassIdx++;
48+
}
49+
50+
public CompileUnit getCompileUnit() {
51+
return compileUnit;
52+
}
53+
54+
public String getNextClosureInnerName(ClassNode owner, ClassNode enclosingClass, MethodNode enclosingMethod) {
55+
String methodName = "";
56+
if (enclosingMethod != null) {
57+
methodName = enclosingMethod.getName();
58+
59+
if (enclosingClass.isDerivedFrom(ClassHelper.CLOSURE_TYPE)) {
60+
methodName = "";
61+
} else {
62+
methodName = "_"+encodeAsValidClassName(methodName);
63+
}
64+
}
65+
return methodName + "_closure" + closureClassIdx++;
66+
}
67+
68+
/* GRECLIPSE edit -- GROOVY-4020, et al.
69+
private static final int MIN_ENCODING = ' ';
70+
private static final int MAX_ENCODING = ']';
71+
private static final boolean[] CHARACTERS_TO_ENCODE = new boolean[MAX_ENCODING-MIN_ENCODING+1];
72+
static {
73+
CHARACTERS_TO_ENCODE[' '-MIN_ENCODING] = true;
74+
CHARACTERS_TO_ENCODE['!'-MIN_ENCODING] = true;
75+
CHARACTERS_TO_ENCODE['/'-MIN_ENCODING] = true;
76+
CHARACTERS_TO_ENCODE['.'-MIN_ENCODING] = true;
77+
CHARACTERS_TO_ENCODE[';'-MIN_ENCODING] = true;
78+
CHARACTERS_TO_ENCODE['$'-MIN_ENCODING] = true;
79+
CHARACTERS_TO_ENCODE['<'-MIN_ENCODING] = true;
80+
CHARACTERS_TO_ENCODE['>'-MIN_ENCODING] = true;
81+
CHARACTERS_TO_ENCODE['['-MIN_ENCODING] = true;
82+
CHARACTERS_TO_ENCODE[']'-MIN_ENCODING] = true;
83+
CHARACTERS_TO_ENCODE[':'-MIN_ENCODING] = true;
84+
CHARACTERS_TO_ENCODE['\\'-MIN_ENCODING] = true;
85+
}
86+
*/
87+
private static final boolean[] CHARACTERS_TO_ENCODE;
88+
private static final int MIN_ENCODING, MAX_ENCODING;
89+
static {
90+
char[] chars = {' ', '!', '"', '#', '$', '&', '\'', '(', ')', '*', '+', ',', '-', '.', '/', ':', ';', '<', '=', '>', '@', '[', '\\', ']', '^', '{', '}', '~'};
91+
92+
MIN_ENCODING = chars[0];
93+
MAX_ENCODING = chars[chars.length - 1];
94+
CHARACTERS_TO_ENCODE = new boolean[MAX_ENCODING - MIN_ENCODING + 1];
95+
96+
for (char c : chars) {
97+
CHARACTERS_TO_ENCODE[c - MIN_ENCODING] = true;
98+
}
99+
}
100+
// GRECLIPSE end
101+
102+
public static String encodeAsValidClassName(String name) {
103+
// GRECLIPSE add -- GROOVY-4020, et al.
104+
if (name.equals("module-info") || name.equals("package-info")) return name;
105+
// GRECLIPSE end
106+
final int l = name.length();
107+
StringBuilder b = null;
108+
int lastEscape = -1;
109+
for(int i = 0; i < l; ++i) {
110+
final int encodeIndex = name.charAt(i) - MIN_ENCODING;
111+
if (encodeIndex >= 0 && encodeIndex < CHARACTERS_TO_ENCODE.length) {
112+
if (CHARACTERS_TO_ENCODE[encodeIndex]) {
113+
if(b == null) {
114+
b = new StringBuilder(name.length() + 3);
115+
b.append(name, 0, i);
116+
} else {
117+
b.append(name, lastEscape + 1, i);
118+
}
119+
b.append('_');
120+
lastEscape = i;
121+
}
122+
}
123+
}
124+
if(b == null) return name;
125+
if (lastEscape == -1) throw new GroovyBugError("unexpected escape char control flow in "+name);
126+
b.append(name, lastEscape + 1, l);
127+
return b.toString();
128+
}
129+
}

base/org.codehaus.groovy30/.checkstyle

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
<file-match-pattern match-pattern="groovy/classgen/(Annotation|Enum)Visitor.java" include-pattern="false" />
4242
<file-match-pattern match-pattern="groovy/classgen/AsmClassGenerator.java" include-pattern="false" />
4343
<file-match-pattern match-pattern="groovy/classgen/(Extended)?Verifier.java" include-pattern="false" />
44+
<file-match-pattern match-pattern="groovy/classgen/GeneratorContext.java" include-pattern="false" />
4445
<file-match-pattern match-pattern="groovy/classgen/asm/(Invocation|Statement)Writer.java" include-pattern="false" />
4546
<file-match-pattern match-pattern="groovy/classgen/asm/CompileStack.java" include-pattern="false" />
4647
<file-match-pattern match-pattern="groovy/classgen/asm/sc/StaticInvocationWriter.java" include-pattern="false" />
Lines changed: 147 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,147 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one
3+
* or more contributor license agreements. See the NOTICE file
4+
* distributed with this work for additional information
5+
* regarding copyright ownership. The ASF licenses this file
6+
* to you under the Apache License, Version 2.0 (the
7+
* "License"); you may not use this file except in compliance
8+
* with the License. You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
package org.codehaus.groovy.classgen;
20+
21+
import org.codehaus.groovy.GroovyBugError;
22+
import org.codehaus.groovy.ast.ClassHelper;
23+
import org.codehaus.groovy.ast.ClassNode;
24+
import org.codehaus.groovy.ast.CompileUnit;
25+
import org.codehaus.groovy.ast.MethodNode;
26+
27+
28+
/**
29+
* A context shared across generations of a class and its inner classes
30+
*/
31+
public class GeneratorContext {
32+
33+
private int innerClassIdx = 1;
34+
private int closureClassIdx = 1;
35+
private int syntheticMethodIdx = 0;
36+
private final CompileUnit compileUnit;
37+
38+
public GeneratorContext(CompileUnit compileUnit) {
39+
this.compileUnit = compileUnit;
40+
}
41+
42+
public GeneratorContext(CompileUnit compileUnit, int innerClassOffset) {
43+
this.compileUnit = compileUnit;
44+
this.innerClassIdx = innerClassOffset;
45+
}
46+
47+
public int getNextInnerClassIdx() {
48+
return innerClassIdx++;
49+
}
50+
51+
public CompileUnit getCompileUnit() {
52+
return compileUnit;
53+
}
54+
55+
public String getNextClosureInnerName(ClassNode owner, ClassNode enclosingClass, MethodNode enclosingMethod) {
56+
return getNextInnerName(owner, enclosingClass, enclosingMethod, "closure");
57+
}
58+
59+
public String getNextLambdaInnerName(ClassNode owner, ClassNode enclosingClass, MethodNode enclosingMethod) {
60+
return getNextInnerName(owner, enclosingClass, enclosingMethod, "lambda");
61+
}
62+
63+
private String getNextInnerName(ClassNode owner, ClassNode enclosingClass, MethodNode enclosingMethod, String classifier) {
64+
String methodName = "";
65+
if (enclosingMethod != null) {
66+
methodName = enclosingMethod.getName();
67+
68+
if (enclosingClass.isDerivedFrom(ClassHelper.CLOSURE_TYPE)) {
69+
methodName = "";
70+
} else {
71+
methodName = "_" + encodeAsValidClassName(methodName);
72+
}
73+
}
74+
75+
return methodName + "_" + classifier + closureClassIdx++;
76+
}
77+
78+
public String getNextConstructorReferenceSyntheticMethodName(MethodNode enclosingMethodNode) {
79+
return "ctorRef$"
80+
+ (null == enclosingMethodNode
81+
? ""
82+
: enclosingMethodNode.getName().replace("<", "").replace(">", "") + "$" )
83+
+ syntheticMethodIdx++;
84+
}
85+
86+
/* GRECLIPSE edit -- GROOVY-4020, et al.
87+
private static final int MIN_ENCODING = ' ';
88+
private static final int MAX_ENCODING = ']';
89+
private static final boolean[] CHARACTERS_TO_ENCODE = new boolean[MAX_ENCODING-MIN_ENCODING+1];
90+
static {
91+
CHARACTERS_TO_ENCODE[' '-MIN_ENCODING] = true;
92+
CHARACTERS_TO_ENCODE['!'-MIN_ENCODING] = true;
93+
CHARACTERS_TO_ENCODE['/'-MIN_ENCODING] = true;
94+
CHARACTERS_TO_ENCODE['.'-MIN_ENCODING] = true;
95+
CHARACTERS_TO_ENCODE[';'-MIN_ENCODING] = true;
96+
CHARACTERS_TO_ENCODE['$'-MIN_ENCODING] = true;
97+
CHARACTERS_TO_ENCODE['<'-MIN_ENCODING] = true;
98+
CHARACTERS_TO_ENCODE['>'-MIN_ENCODING] = true;
99+
CHARACTERS_TO_ENCODE['['-MIN_ENCODING] = true;
100+
CHARACTERS_TO_ENCODE[']'-MIN_ENCODING] = true;
101+
CHARACTERS_TO_ENCODE[':'-MIN_ENCODING] = true;
102+
CHARACTERS_TO_ENCODE['\\'-MIN_ENCODING] = true;
103+
}
104+
*/
105+
private static final boolean[] CHARACTERS_TO_ENCODE;
106+
private static final int MIN_ENCODING, MAX_ENCODING;
107+
static {
108+
char[] chars = {' ', '!', '"', '#', '$', '&', '\'', '(', ')', '*', '+', ',', '-', '.', '/', ':', ';', '<', '=', '>', '@', '[', '\\', ']', '^', '{', '}', '~'};
109+
110+
MIN_ENCODING = chars[0];
111+
MAX_ENCODING = chars[chars.length - 1];
112+
CHARACTERS_TO_ENCODE = new boolean[MAX_ENCODING - MIN_ENCODING + 1];
113+
114+
for (char c : chars) {
115+
CHARACTERS_TO_ENCODE[c - MIN_ENCODING] = true;
116+
}
117+
}
118+
// GRECLIPSE end
119+
120+
public static String encodeAsValidClassName(String name) {
121+
// GRECLIPSE add -- GROOVY-4020, et al.
122+
if (name.equals("module-info") || name.equals("package-info")) return name;
123+
// GRECLIPSE end
124+
final int l = name.length();
125+
StringBuilder b = null;
126+
int lastEscape = -1;
127+
for(int i = 0; i < l; ++i) {
128+
final int encodeIndex = name.charAt(i) - MIN_ENCODING;
129+
if (encodeIndex >= 0 && encodeIndex < CHARACTERS_TO_ENCODE.length) {
130+
if (CHARACTERS_TO_ENCODE[encodeIndex]) {
131+
if(b == null) {
132+
b = new StringBuilder(name.length() + 3);
133+
b.append(name, 0, i);
134+
} else {
135+
b.append(name, lastEscape + 1, i);
136+
}
137+
b.append('_');
138+
lastEscape = i;
139+
}
140+
}
141+
}
142+
if(b == null) return name;
143+
if (lastEscape == -1) throw new GroovyBugError("unexpected escape char control flow in "+name);
144+
b.append(name, lastEscape + 1, l);
145+
return b.toString();
146+
}
147+
}

base/org.codehaus.groovy40/.checkstyle

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
<file-match-pattern match-pattern="groovy/ast/tools/(Expression|Generics)Utils.java" include-pattern="false" />
3838
<file-match-pattern match-pattern="groovy/classgen/(Annotation|Enum)Visitor.java" include-pattern="false" />
3939
<file-match-pattern match-pattern="groovy/classgen/(Extended)?Verifier.java" include-pattern="false" />
40+
<file-match-pattern match-pattern="groovy/classgen/GeneratorContext.java" include-pattern="false" />
4041
<file-match-pattern match-pattern="groovy/classgen/asm/WriterController.java" include-pattern="false" />
4142
<file-match-pattern match-pattern="groovy/classgen/asm/sc/StaticInvocationWriter.java" include-pattern="false" />
4243
<file-match-pattern match-pattern="groovy/classgen/asm/sc/StaticPropertyAccessHelper.java" include-pattern="false" />

0 commit comments

Comments
 (0)