/* * 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.codehaus.jdt.groovy.integration.internal; import static org.eclipse.jdt.groovy.core.util.ContentTypeUtils.isGroovyLikeFileName; import static org.eclipse.jdt.groovy.core.util.ContentTypeUtils.isJavaLikeButNotGroovyLikeFileName; import java.util.regex.Pattern; import org.codehaus.jdt.groovy.internal.compiler.ast.GroovyParser; import org.eclipse.jdt.groovy.core.util.CharArraySequence; import org.eclipse.jdt.internal.compiler.CompilationResult; import org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration; import org.eclipse.jdt.internal.compiler.env.ICompilationUnit; import org.eclipse.jdt.internal.compiler.impl.CompilerOptions; import org.eclipse.jdt.internal.compiler.problem.ProblemReporter; import org.eclipse.jdt.internal.core.util.CommentRecorderParser; import org.eclipse.jdt.internal.core.util.Util; /** * The multiplexing parser can delegate file parsing to multiple parsers. In this scenario it subtypes 'Parser' (which is the Java * parser) but is also aware of a groovy parser. Depending on what kind of file is to be parsed, it will invoke the relevant parser. */ public class MultiplexingCommentRecorderParser extends CommentRecorderParser { // FIXASC How often is the LanguageSupport impl looked up? Should be once then we remember what happened. private final GroovyParser groovyParser; public MultiplexingCommentRecorderParser(Object requestor, CompilerOptions compilerOptions, ProblemReporter problemReporter, boolean optimizeStringLiterals) { this(requestor, compilerOptions, problemReporter, optimizeStringLiterals, true); } public MultiplexingCommentRecorderParser(Object requestor, CompilerOptions compilerOptions, ProblemReporter problemReporter, boolean optimizeStringLiterals, boolean allowTransforms) { super(problemReporter, optimizeStringLiterals); groovyParser = new GroovyParser(requestor, compilerOptions, problemReporter, allowTransforms, true); } @Override public CompilationUnitDeclaration dietParse(ICompilationUnit sourceUnit, CompilationResult compilationResult) { if (isGroovyLikeFileName(sourceUnit.getFileName()) || isGroovyLikeSourceUnit(sourceUnit)) { if (this.scanner != null) { this.scanner.setSource(sourceUnit.getContents()); } return groovyParser.dietParse(sourceUnit, compilationResult); } return super.dietParse(sourceUnit, compilationResult); } private static boolean isGroovyLikeSourceUnit(ICompilationUnit sourceUnit) { if (sourceUnit.getFileName() == null || !isJavaLikeButNotGroovyLikeFileName(String.valueOf(sourceUnit.getFileName()))) { if (GROOVY_SOURCE_DISCRIMINATOR.matcher(new CharArraySequence(sourceUnit.getContents())).find()) { Util.log(1, "Identified a Groovy source unit through inspection of its contents: " + String.valueOf(sourceUnit.getContents(), 0, Math.min(250, sourceUnit.getContents().length))); return true; } } return false; } private static final Pattern GROOVY_SOURCE_DISCRIMINATOR = Pattern.compile("\\Apackage\\s+\\w+(?:\\s*\\.\\s*\\w+)*\\s++(?!;)"); @Override public void reset() { groovyParser.reset(); } }