/* * Copyright 2009-2017 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. * 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.eclipse.jdt.core.groovy.tests.locations; import static org.junit.Assert.assertEquals; import java.util.LinkedList; import java.util.List; import groovy.lang.GroovyClassLoader; import org.codehaus.groovy.antlr.LocationSupport; import org.codehaus.groovy.ast.ASTNode; import org.codehaus.groovy.ast.ModuleNode; import org.codehaus.groovy.ast.expr.DeclarationExpression; import org.codehaus.groovy.ast.stmt.ExpressionStatement; import org.codehaus.groovy.control.CompilerConfiguration; import org.codehaus.groovy.control.ErrorCollector; import org.codehaus.groovy.control.SourceUnit; import org.codehaus.jdt.groovy.internal.compiler.ast.GroovyCompilationUnitDeclaration; import org.eclipse.jdt.groovy.core.util.ReflectionUtils; import org.junit.Test; public final class LocationSupportTests { @Test public void testLocationSupport() throws Exception { List<StringBuffer> sbuffers = new LinkedList<StringBuffer>(); sbuffers.add(new StringBuffer("123\n")); sbuffers.add(new StringBuffer("567\n")); sbuffers.add(new StringBuffer("90\n")); LocationSupport locations = new LocationSupport(sbuffers); assertEquals("Wrong offset found", 0, locations.findOffset(1, 1)); assertEquals("Wrong offset found", 1, locations.findOffset(1, 2)); assertEquals("Wrong offset found", 2, locations.findOffset(1, 3)); assertEquals("Wrong offset found", 3, locations.findOffset(1, 4)); assertEquals("Wrong offset found", 4, locations.findOffset(2, 1)); assertEquals("Wrong offset found", 5, locations.findOffset(2, 2)); assertEquals("Wrong offset found", 6, locations.findOffset(2, 3)); assertEquals("Wrong offset found", 7, locations.findOffset(2, 4)); assertEquals("Wrong offset found", 8, locations.findOffset(3, 1)); assertEquals("Wrong offset found", 9, locations.findOffset(3, 2)); assertEquals("Wrong offset found", 10, locations.findOffset(3, 3)); } @Test public void testParserSourceLocationsBlock() throws Exception { String content = "def x = 7\n x++\n def y = []"; SourceUnit sourceUnit = new SourceUnit("Foo", content, new CompilerConfiguration(), new GroovyClassLoader(), new ErrorCollector(new CompilerConfiguration())); sourceUnit.parse(); sourceUnit.completePhase(); sourceUnit.convert(); ModuleNode module = sourceUnit.getAST(); // now check locations assertEquals(0, module.getStart()); assertEquals(content.length(), module.getEnd()); assertEquals(0, module.getStatementBlock().getStart()); assertEquals(content.length(), module.getStatementBlock().getEnd()); assertEquals("".length(), ((ASTNode) module.getStatementBlock().getStatements().get(0)).getStart()); assertEquals("def x = 7".length(), ((ASTNode) module.getStatementBlock().getStatements().get(0)).getEnd()); assertEquals("def x = 7\n ".length(), ((ASTNode) module.getStatementBlock().getStatements().get(1)).getStart()); assertEquals("def x = 7\n x++".length(), ((ASTNode) module.getStatementBlock().getStatements().get(1)).getEnd()); assertEquals("def x = 7\n x++\n ".length(), ((ASTNode) module.getStatementBlock().getStatements().get(2)).getStart()); assertEquals("def x = 7\n x++\n def y = []".length(), ((ASTNode) module.getStatementBlock().getStatements().get(2)).getEnd()); } @Test public void testParserSourceLocationsEmpty() throws Exception { String content = ""; SourceUnit sourceUnit = new SourceUnit("Foo", content, new CompilerConfiguration(), new GroovyClassLoader(), new ErrorCollector(new CompilerConfiguration())); sourceUnit.parse(); sourceUnit.completePhase(); sourceUnit.convert(); ModuleNode module = sourceUnit.getAST(); // now check locations assertEquals(0, module.getStart()); assertEquals(content.length(), module.getEnd()); } @Test public void testParserSourceLocationsOneLine() throws Exception { String content = "def x = 7"; SourceUnit sourceUnit = new SourceUnit("Foo", content, new CompilerConfiguration(), new GroovyClassLoader(), new ErrorCollector(new CompilerConfiguration())); sourceUnit.parse(); sourceUnit.completePhase(); sourceUnit.convert(); ModuleNode module = sourceUnit.getAST(); // now check locations assertEquals(0, module.getStart()); assertEquals(content.length(), module.getEnd()); assertEquals(0, module.getStatementBlock().getStart()); assertEquals(content.length(), module.getStatementBlock().getEnd()); assertEquals("".length(), ((ASTNode) module.getStatementBlock().getStatements().get(0)).getStart()); assertEquals("def x = 7".length(), ((ASTNode) module.getStatementBlock().getStatements().get(0)).getEnd()); } @Test public void testParserSourceLocationsNewLine() throws Exception { String content = "def x = 7\n"; SourceUnit sourceUnit = new SourceUnit("Foo", content, new CompilerConfiguration(), new GroovyClassLoader(), new ErrorCollector(new CompilerConfiguration())); sourceUnit.parse(); sourceUnit.completePhase(); sourceUnit.convert(); ModuleNode module = sourceUnit.getAST(); // now check locations assertEquals(0, module.getStart()); assertEquals(content.length(), module.getEnd()); assertEquals("".length(), module.getStatementBlock().getStart()); assertEquals("def x = 7".length(), module.getStatementBlock().getEnd()); assertEquals("".length(), ((ASTNode) module.getStatementBlock().getStatements().get(0)).getStart()); assertEquals("def x = 7".length(), ((ASTNode) module.getStatementBlock().getStatements().get(0)).getEnd()); } @Test public void testParserSourceLocationsClass() throws Exception { String content = "class X {\n }"; SourceUnit sourceUnit = new SourceUnit("Foo", content, new CompilerConfiguration(), new GroovyClassLoader(), new ErrorCollector(new CompilerConfiguration())); sourceUnit.parse(); sourceUnit.completePhase(); sourceUnit.convert(); ModuleNode module = sourceUnit.getAST(); // now check locations assertEquals(0, module.getStart()); assertEquals(content.length(), module.getEnd()); assertEquals(0, ((ASTNode) module.getClasses().get(0)).getStart()); assertEquals(content.length(), ((ASTNode) module.getClasses().get(0)).getEnd()); } @Test public void testParserSourceLocationsMethod() throws Exception { String content = "def x() { \n\n\n\n\n\n\n}"; SourceUnit sourceUnit = new SourceUnit("Foo", content, new CompilerConfiguration(), new GroovyClassLoader(), new ErrorCollector(new CompilerConfiguration())); sourceUnit.parse(); sourceUnit.completePhase(); sourceUnit.convert(); ModuleNode module = sourceUnit.getAST(); // now check locations assertEquals(0, module.getStart()); assertEquals(content.length(), module.getEnd()); assertEquals(0, ((ASTNode) module.getMethods().get(0)).getStart()); assertEquals(content.indexOf('x'), module.getMethods().get(0).getNameStart()); assertEquals(content.indexOf('x') + "x".length() - 1, module.getMethods().get(0).getNameEnd()); assertEquals(content.length(), ((ASTNode) module.getMethods().get(0)).getEnd()); } @Test public void testParserSourceLocationsMethod2() throws Exception { String content = "def \"x \" () { \n\n\n\n\n\n\n}"; SourceUnit sourceUnit = new SourceUnit("Foo", content, new CompilerConfiguration(), new GroovyClassLoader(), new ErrorCollector(new CompilerConfiguration())); sourceUnit.parse(); sourceUnit.completePhase(); sourceUnit.convert(); ModuleNode module = sourceUnit.getAST(); // now check locations assertEquals(0, module.getStart()); assertEquals(content.length(), module.getEnd()); assertEquals(0, ((ASTNode) module.getMethods().get(0)).getStart()); assertEquals(content.indexOf("\"x \""), (module.getMethods().get(0)).getNameStart()); assertEquals(content.indexOf("\"x \"")+"\"x \"".length() - 1, (module.getMethods().get(0)).getNameEnd()); assertEquals(content.length(), ((ASTNode) module.getMethods().get(0)).getEnd()); } @Test public void testParserSourceLocationsClassMethodStatement() throws Exception { String content = "def x = 7\n x++\n def y = []\ndef z() { \n\n\n\n\n\n\n}\nclass X {\n }"; SourceUnit sourceUnit = new SourceUnit("Foo", content, new CompilerConfiguration(), new GroovyClassLoader(), new ErrorCollector(new CompilerConfiguration())); sourceUnit.parse(); sourceUnit.completePhase(); sourceUnit.convert(); ModuleNode module = sourceUnit.getAST(); // now check locations assertEquals(0, module.getStart()); assertEquals(content.length(), module.getEnd()); assertEquals(0, module.getStatementBlock().getStart()); assertEquals("def x = 7\n x++\n def y = []\ndef z() { \n\n\n\n\n\n\n}".length(), module.getStatementBlock().getEnd()); assertEquals("".length(), ((ASTNode) module.getStatementBlock().getStatements().get(0)).getStart()); assertEquals("def x = 7".length(), ((ASTNode) module.getStatementBlock().getStatements().get(0)).getEnd()); assertEquals("def x = 7\n ".length(), ((ASTNode) module.getStatementBlock().getStatements().get(1)).getStart()); assertEquals("def x = 7\n x++".length(), ((ASTNode) module.getStatementBlock().getStatements().get(1)).getEnd()); assertEquals("def x = 7\n x++\n ".length(), ((ASTNode) module.getStatementBlock().getStatements().get(2)).getStart()); assertEquals("def x = 7\n x++\n def y = []".length(), ((ASTNode) module.getStatementBlock().getStatements().get(2)).getEnd()); assertEquals("def x = 7\n x++\n def y = []\n".length(), ((ASTNode) module.getMethods().get(0)).getStart()); assertEquals("def x = 7\n x++\n def y = []\ndef z() { \n\n\n\n\n\n\n}".length(), ((ASTNode) module.getMethods().get(0)).getEnd()); // use index of 1 because zero index is of Foo assertEquals("def x = 7\n x++\n def y = []\ndef z() { \n\n\n\n\n\n\n}\n".length(), ((ASTNode) module.getClasses().get(1)).getStart()); assertEquals("def x = 7\n x++\n def y = []\ndef z() { \n\n\n\n\n\n\n}\nclass X {\n }".length(), ((ASTNode) module.getClasses().get(1)).getEnd()); } @Test public void testGRECLIPSE887_ImportStatements() throws Exception { String content = "import java.util.List\nimport java.lang.*\nimport javax.swing.text.html.HTML.A\nimport javax.swing.text.html.HTML.*"; SourceUnit sourceUnit = new SourceUnit("Foo", content, new CompilerConfiguration(), new GroovyClassLoader(), new ErrorCollector(new CompilerConfiguration())); sourceUnit.parse(); sourceUnit.completePhase(); sourceUnit.convert(); final ModuleNode module = sourceUnit.getAST(); // now check locations assertEquals(0, module.getStart()); assertEquals(content.length(), module.getEnd()); assertEquals(0, module.getImport("List").getStart()); assertEquals("import java.util.List".length(), module.getImport("List").getEnd()); assertEquals("import java.util.List\n".length(), module.getStarImports().get(0).getStart()); assertEquals("import java.util.List\nimport java.lang.*".length(), module.getStarImports().get(0).getEnd()); assertEquals("import java.util.List\nimport java.lang.*\n".length(), module.getImport("A").getStart()); assertEquals("import java.util.List\nimport java.lang.*\nimport javax.swing.text.html.HTML.A".length(), module.getImport("A").getEnd()); assertEquals("import java.util.List\nimport java.lang.*\nimport javax.swing.text.html.HTML.A\n".length(), module.getStarImports().get(1).getStart()); assertEquals("import java.util.List\nimport java.lang.*\nimport javax.swing.text.html.HTML.A\nimport javax.swing.text.html.HTML.*".length(), module.getStarImports().get(1).getEnd()); // now test against the compilation unit declaration GroovyCompilationUnitDeclaration cud = new GroovyCompilationUnitDeclaration(null, null, -1, null, null, null) {{ GroovyCompilationUnitDeclaration.UnitPopulator cup = new GroovyCompilationUnitDeclaration.UnitPopulator(); ReflectionUtils.setPrivateField(cup.getClass(), "unitDeclaration", cup, this); ReflectionUtils.executePrivateMethod(cup.getClass(), "createImportDeclarations", new Class[] {ModuleNode.class}, cup, new Object[] {module}); }}; assertEquals(module.getImport("List").getStart(), cud.imports[0].declarationSourceStart); assertEquals(module.getImport("List").getEnd() - 1, cud.imports[0].declarationSourceEnd); assertEquals(module.getStarImports().get(0).getStart(), cud.imports[1].declarationSourceStart); assertEquals(module.getStarImports().get(0).getEnd() - 1, cud.imports[1].declarationSourceEnd); assertEquals(module.getImport("A").getStart(), cud.imports[2].declarationSourceStart); assertEquals(module.getImport("A").getEnd() - 1, cud.imports[2].declarationSourceEnd); assertEquals(module.getStarImports().get(1).getStart(), cud.imports[3].declarationSourceStart); assertEquals(module.getStarImports().get(1).getEnd() - 1, cud.imports[3].declarationSourceEnd); } @Test public void testUnicodeEscapes1() throws Exception { String escapeSequence = "/*\\u00E9*/ "; String content = escapeSequence + "def x = 7"; SourceUnit sourceUnit = new SourceUnit("Foo", content, new CompilerConfiguration(), new GroovyClassLoader(), new ErrorCollector(new CompilerConfiguration())); sourceUnit.parse(); sourceUnit.completePhase(); sourceUnit.convert(); ModuleNode module = sourceUnit.getAST(); // now check locations assertEquals(0, module.getStart()); assertEquals(content.length(), module.getEnd()); assertEquals(escapeSequence.length(), ((ASTNode) module.getStatementBlock().getStatements().get(0)).getStart()); assertEquals(content.length(), ((ASTNode) module.getStatementBlock().getStatements().get(0)).getEnd()); } @Test public void testUnicodeEscapes2() throws Exception { String escapeSequence = "/*\\u00E9*/ "; String content = escapeSequence + "\n\n\ndef x = 7"; SourceUnit sourceUnit = new SourceUnit("Foo", content, new CompilerConfiguration(), new GroovyClassLoader(), new ErrorCollector(new CompilerConfiguration())); sourceUnit.parse(); sourceUnit.completePhase(); sourceUnit.convert(); ModuleNode module = sourceUnit.getAST(); // now check locations assertEquals(0, module.getStart()); assertEquals(content.length(), module.getEnd()); assertEquals(content.indexOf("def"), ((ASTNode) module.getStatementBlock().getStatements().get(0)).getStart()); assertEquals(content.length(), ((ASTNode) module.getStatementBlock().getStatements().get(0)).getEnd()); } @Test public void testUnicodeEscapes3() throws Exception { String escapeSequence = "/*\\u00E9\\u00E9\\u00E9\\u00E9\\u00E9\\u00E9\\u00E9\\u00E9\\u00E9*/"; String content = escapeSequence + "\n\n\ndef /*\\u00E9*/x = /*\\u00E9*/7"; SourceUnit sourceUnit = new SourceUnit("Foo", content, new CompilerConfiguration(), new GroovyClassLoader(), new ErrorCollector(new CompilerConfiguration())); sourceUnit.parse(); sourceUnit.completePhase(); sourceUnit.convert(); ModuleNode module = sourceUnit.getAST(); // now check locations assertEquals(0, module.getStart()); assertEquals(content.length(), module.getEnd()); assertEquals(content.indexOf("def"), ((ASTNode) module.getStatementBlock().getStatements().get(0)).getStart()); assertEquals(content.length(), ((ASTNode) module.getStatementBlock().getStatements().get(0)).getEnd()); // inside the assignment DeclarationExpression decl = (DeclarationExpression) ((ExpressionStatement) module.getStatementBlock().getStatements().get(0)).getExpression(); assertEquals(content.indexOf('x'), decl.getLeftExpression().getStart()); assertEquals(content.indexOf('x')+1, decl.getLeftExpression().getEnd()); assertEquals(content.indexOf('7'), decl.getRightExpression().getStart()); assertEquals(content.indexOf('7')+1, decl.getRightExpression().getEnd()); } }