From 4bc7defcfa1632ef1f1bef3d861818a2dc6f5786 Mon Sep 17 00:00:00 2001 From: "Kirill.Safonov" Date: Wed, 23 Dec 2009 12:18:10 +0300 Subject: [PATCH 01/67] hide upload panel if there's no providers for stored before-launch task configs --- .../impl/ConfigurationSettingsEditorWrapper.java | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/execution/impl/ConfigurationSettingsEditorWrapper.java b/platform/lang-impl/src/com/intellij/execution/impl/ConfigurationSettingsEditorWrapper.java index c433a70df571..290eacfa1518 100644 --- a/platform/lang-impl/src/com/intellij/execution/impl/ConfigurationSettingsEditorWrapper.java +++ b/platform/lang-impl/src/com/intellij/execution/impl/ConfigurationSettingsEditorWrapper.java @@ -88,9 +88,15 @@ public class ConfigurationSettingsEditorWrapper extends SettingsEditor Date: Wed, 23 Dec 2009 14:04:56 +0300 Subject: [PATCH 02/67] Maven: test fix --- .../ide/impl/SelectInTargetPsiWrapper.java | 166 +++++++++--------- .../project/MavenArtifactDownloader.java | 2 +- 2 files changed, 84 insertions(+), 84 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/ide/impl/SelectInTargetPsiWrapper.java b/platform/lang-impl/src/com/intellij/ide/impl/SelectInTargetPsiWrapper.java index 1f6fe4393a0c..a71d9e5c52b7 100644 --- a/platform/lang-impl/src/com/intellij/ide/impl/SelectInTargetPsiWrapper.java +++ b/platform/lang-impl/src/com/intellij/ide/impl/SelectInTargetPsiWrapper.java @@ -1,83 +1,83 @@ -/* - * Copyright 2000-2009 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 com.intellij.ide.impl; - -import com.intellij.ide.SelectInContext; -import com.intellij.ide.SelectInTarget; -import com.intellij.openapi.editor.Document; -import com.intellij.openapi.fileEditor.FileDocumentManager; -import com.intellij.openapi.project.Project; -import com.intellij.openapi.vfs.VirtualFile; -import com.intellij.psi.*; -import org.jetbrains.annotations.NotNull; - - -public abstract class SelectInTargetPsiWrapper implements SelectInTarget { - protected final Project myProject; - - protected SelectInTargetPsiWrapper(@NotNull final Project project) { - myProject = project; - } - - public abstract String toString(); - - protected abstract boolean canSelect(PsiFileSystemItem file); - - public final boolean canSelect(SelectInContext context) { - if (myProject.isDisposed()) return false; - - VirtualFile virtualFile = context.getVirtualFile(); - if (!virtualFile.isValid()) return false; - - final Document document = FileDocumentManager.getInstance().getDocument(virtualFile); - final PsiFileSystemItem psiFile; - if (document != null) { - psiFile = PsiDocumentManager.getInstance(myProject).getPsiFile(document); - } - else if (context.getSelectorInFile() instanceof PsiFile) { - psiFile = (PsiFile)context.getSelectorInFile(); - } - else if (virtualFile.isDirectory()) { - psiFile = PsiManager.getInstance(myProject).findDirectory(virtualFile); - } - else { - psiFile = PsiManager.getInstance(myProject).findFile(virtualFile); - } - return psiFile != null && canSelect(psiFile) || canWorkWithCustomObjects(); - } - - public final void selectIn(SelectInContext context, final boolean requestFocus) { - VirtualFile file = context.getVirtualFile(); - Object selector = context.getSelectorInFile(); - if (selector == null) { - PsiManager psiManager = PsiManager.getInstance(myProject); - selector = file.isDirectory() ? psiManager.findDirectory(file) : psiManager.findFile(file); - } - - if (selector instanceof PsiElement) { - select(((PsiElement)selector).getOriginalElement(), requestFocus); - } else { - select(selector, file, requestFocus); - } - } - - protected abstract void select(final Object selector, VirtualFile virtualFile, final boolean requestFocus); - - protected abstract boolean canWorkWithCustomObjects(); - - protected abstract void select(PsiElement element, boolean requestFocus); -} +/* + * Copyright 2000-2009 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 com.intellij.ide.impl; + +import com.intellij.ide.SelectInContext; +import com.intellij.ide.SelectInTarget; +import com.intellij.openapi.editor.Document; +import com.intellij.openapi.fileEditor.FileDocumentManager; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.psi.*; +import org.jetbrains.annotations.NotNull; + + +public abstract class SelectInTargetPsiWrapper implements SelectInTarget { + protected final Project myProject; + + protected SelectInTargetPsiWrapper(@NotNull final Project project) { + myProject = project; + } + + public abstract String toString(); + + protected abstract boolean canSelect(PsiFileSystemItem file); + + public final boolean canSelect(SelectInContext context) { + if (myProject.isDisposed()) return false; + + VirtualFile virtualFile = context.getVirtualFile(); + if (!virtualFile.isValid()) return false; + + final Document document = FileDocumentManager.getInstance().getDocument(virtualFile); + final PsiFileSystemItem psiFile; + if (document != null) { + psiFile = PsiDocumentManager.getInstance(myProject).getPsiFile(document); + } + else if (context.getSelectorInFile() instanceof PsiFile) { + psiFile = (PsiFile)context.getSelectorInFile(); + } + else if (virtualFile.isDirectory()) { + psiFile = PsiManager.getInstance(myProject).findDirectory(virtualFile); + } + else { + psiFile = PsiManager.getInstance(myProject).findFile(virtualFile); + } + return psiFile != null && canSelect(psiFile) || canWorkWithCustomObjects(); + } + + public final void selectIn(SelectInContext context, final boolean requestFocus) { + VirtualFile file = context.getVirtualFile(); + Object selector = context.getSelectorInFile(); + if (selector == null) { + PsiManager psiManager = PsiManager.getInstance(myProject); + selector = file.isDirectory() ? psiManager.findDirectory(file) : psiManager.findFile(file); + } + + if (selector instanceof PsiElement) { + select(((PsiElement)selector).getOriginalElement(), requestFocus); + } else { + select(selector, file, requestFocus); + } + } + + protected abstract void select(final Object selector, VirtualFile virtualFile, final boolean requestFocus); + + protected abstract boolean canWorkWithCustomObjects(); + + protected abstract void select(PsiElement element, boolean requestFocus); +} diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/MavenArtifactDownloader.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/MavenArtifactDownloader.java index d0dfd3e7c8c6..cb8ffc48db82 100644 --- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/MavenArtifactDownloader.java +++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/MavenArtifactDownloader.java @@ -31,7 +31,7 @@ import java.util.concurrent.*; import java.util.concurrent.atomic.AtomicInteger; public class MavenArtifactDownloader { - private final static ExecutorService EXECUTOR = new ThreadPoolExecutor(0, 5, 60, TimeUnit.SECONDS, new ArrayBlockingQueue(5)); + private final static ThreadPoolExecutor EXECUTOR = new ThreadPoolExecutor(5, Integer.MAX_VALUE, 60, TimeUnit.SECONDS, new LinkedBlockingQueue()); private final MavenEmbedderWrapper myEmbedder; private final MavenProgressIndicator myProgress; From 2bb7839fc4845e0bcfbdc2c86fd59c0c11098bef Mon Sep 17 00:00:00 2001 From: "Anton.Makeev" Date: Wed, 23 Dec 2009 15:20:38 +0300 Subject: [PATCH 03/67] Maven: correctly set sources/javadoc urls for artifacts with classifiers --- .../intellij/openapi/util/io/FileUtil.java | 18 ++-- .../importing/MavenRootModelAdapter.java | 24 +++--- .../idea/maven/project/MavenArtifact.java | 47 ++++++----- .../idea/maven/project/MavenProject.java | 8 +- .../idea/maven/utils/MavenConstants.java | 1 + .../importing/DependenciesImportingTest.java | 84 ++++++++++--------- 6 files changed, 98 insertions(+), 84 deletions(-) diff --git a/platform/util/src/com/intellij/openapi/util/io/FileUtil.java b/platform/util/src/com/intellij/openapi/util/io/FileUtil.java index 0ff6f7cd3952..aa58b0a89bd7 100644 --- a/platform/util/src/com/intellij/openapi/util/io/FileUtil.java +++ b/platform/util/src/com/intellij/openapi/util/io/FileUtil.java @@ -659,24 +659,24 @@ public class FileUtil { delete(source); } - public static boolean startsWith(@NonNls String path1, @NonNls String path2) { - return startsWith(path1, path2, SystemInfo.isFileSystemCaseSensitive); + public static boolean startsWith(@NonNls String path, @NonNls String start) { + return startsWith(path, start, SystemInfo.isFileSystemCaseSensitive); } - public static boolean startsWith(final String path1, final String path2, final boolean caseSensitive) { - final int length1 = path1.length(); - final int length2 = path2.length(); + public static boolean startsWith(final String path, final String start, final boolean caseSensitive) { + final int length1 = path.length(); + final int length2 = start.length(); if (length2 == 0) return true; if (length2 > length1) return false; - if (!path1.regionMatches(!caseSensitive, 0, path2, 0, length2)) return false; + if (!path.regionMatches(!caseSensitive, 0, start, 0, length2)) return false; if (length1 == length2) return true; - char last2 = path2.charAt(length2 - 1); + char last2 = start.charAt(length2 - 1); char next1; if (last2 == '/' || last2 == File.separatorChar) { - next1 = path1.charAt(length2 -1); + next1 = path.charAt(length2 -1); } else { - next1 = path1.charAt(length2); + next1 = path.charAt(length2); } return next1 == '/' || next1 == File.separatorChar; } diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/importing/MavenRootModelAdapter.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/importing/MavenRootModelAdapter.java index 6b2db908180b..97d321bef7f1 100644 --- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/importing/MavenRootModelAdapter.java +++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/importing/MavenRootModelAdapter.java @@ -240,7 +240,7 @@ public class MavenRootModelAdapter { OrderRootType type, MavenArtifact artifact, String classifier) { - String newUrl = artifact.getUrlForClassifier(classifier); + String newUrl = artifact.getUrlForExtraArtifact(classifier); for (String url : libraryModel.getUrls(type)) { if (newUrl.equals(url)) return; if (MavenConstants.SCOPE_SYSTEM.equals(artifact.getScope()) || isRepositoryUrl(artifact, url, classifier)) { @@ -251,7 +251,7 @@ public class MavenRootModelAdapter { } private boolean isRepositoryUrl(MavenArtifact artifact, String url, String classifier) { - return url.endsWith(artifact.getRelativePathForClassifier(classifier) + JarFileSystem.JAR_SEPARATOR); + return url.endsWith(artifact.getRelativePathForExtraArtifact(classifier) + JarFileSystem.JAR_SEPARATOR); } public static boolean isChangedByUser(Library library) { @@ -260,20 +260,18 @@ public class MavenRootModelAdapter { String classes = classRoots[0]; - int dotPos = classes.lastIndexOf("."); + if (!classes.endsWith("!/")) return true; + + int dotPos = classes.lastIndexOf("/", classes.length() - 2 /* trim ending !/ */); if (dotPos == -1) return true; - String path = classes.substring(0, dotPos); + String pathToJar = classes.substring(0, dotPos); - String jarSuffix = ".jar" + JarFileSystem.JAR_SEPARATOR; - String sourcesPath = path + "-" + MavenConstants.CLASSIFIER_SOURCES + jarSuffix; - String javadocPath = path + "-" + MavenConstants.CLASSIFIER_JAVADOC + jarSuffix; + String[] sources = library.getUrls(OrderRootType.SOURCES); + if (sources.length != 1 || !FileUtil.startsWith(sources[0], pathToJar)) return true; + + String[] javadoc = library.getUrls(JavadocOrderRootType.getInstance()); + if (javadoc.length != 1 || !FileUtil.startsWith(javadoc[0], pathToJar)) return true; - for (String each : library.getUrls(OrderRootType.SOURCES)) { - if (!FileUtil.pathsEqual(each, sourcesPath)) return true; - } - for (String each : library.getUrls(JavadocOrderRootType.getInstance())) { - if (!FileUtil.pathsEqual(each, javadocPath)) return true; - } return false; } diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/MavenArtifact.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/MavenArtifact.java index 0c047302dd7c..6e0c06a45d73 100644 --- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/MavenArtifact.java +++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/MavenArtifact.java @@ -19,15 +19,11 @@ package org.jetbrains.idea.maven.project; import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.vfs.JarFileSystem; -import com.intellij.openapi.vfs.LocalFileSystem; -import com.intellij.openapi.vfs.VirtualFile; import com.intellij.openapi.vfs.VirtualFileManager; import org.apache.maven.artifact.Artifact; import org.apache.maven.artifact.handler.ArtifactHandler; import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; import org.jetbrains.idea.maven.embedder.CustomArtifact; -import static org.jetbrains.idea.maven.project.MavenId.append; import org.jetbrains.idea.maven.utils.MavenConstants; import java.io.File; @@ -36,6 +32,8 @@ import java.text.MessageFormat; import java.util.ArrayList; import java.util.List; +import static org.jetbrains.idea.maven.project.MavenId.append; + public class MavenArtifact implements Serializable { private String myGroupId; private String myArtifactId; @@ -148,10 +146,10 @@ public class MavenArtifact implements Serializable { } public String getRelativePath() { - return getRelativePathForClassifier(null); + return getRelativePathForExtraArtifact(null); } - public String getRelativePathForClassifier(String extraClassifier) { + public String getRelativePathForExtraArtifact(String extraArtifactClassifier) { StringBuilder result = new StringBuilder(); result.append(myGroupId.replace('.', '/')); result.append('/'); @@ -162,17 +160,20 @@ public class MavenArtifact implements Serializable { result.append(myArtifactId); result.append('-'); result.append(myVersion); - if (!StringUtil.isEmptyOrSpaces(myClassifier)) { - result.append('-'); - result.append(myClassifier); - } - if (!StringUtil.isEmptyOrSpaces(extraClassifier)) { + if (!StringUtil.isEmptyOrSpaces(extraArtifactClassifier)) { + if (MavenConstants.TYPE_TEST_JAR.equals(myType)) { + result.append("-test"); + } result.append('-'); - result.append(extraClassifier); + result.append(extraArtifactClassifier); result.append(".jar"); } else { + if (!StringUtil.isEmptyOrSpaces(myClassifier)) { + result.append('-'); + result.append(myClassifier); + } result.append("."); result.append(myExtension); } @@ -180,17 +181,25 @@ public class MavenArtifact implements Serializable { } public String getUrl() { - return getUrlForClassifier(null); + return getUrlForExtraArtifact(null); } - public String getUrlForClassifier(String extraClassifier) { + public String getUrlForExtraArtifact(String extraArtifactClassifier) { String path = getPath(); - if (!StringUtil.isEmptyOrSpaces(extraClassifier)) { - int dotPos = path.lastIndexOf("."); - if (dotPos != -1) {// sometimes path doesn't contain '.'; but i can't find any reason. - String withoutExtension = path.substring(0, dotPos); - path = MessageFormat.format("{0}-{1}.jar", withoutExtension, extraClassifier); + if (!StringUtil.isEmptyOrSpaces(extraArtifactClassifier)) { + int repoEnd = path.lastIndexOf(getRelativePath()); + + if (repoEnd == -1) { + // unknown path format: try to add a classified at the end of the filename + int dotPos = path.lastIndexOf("."); + if (dotPos != -1) {// sometimes path doesn't contain '.'; but i can't find any reason why. + String withoutExtension = path.substring(0, dotPos); + path = MessageFormat.format("{0}-{1}.jar", withoutExtension, extraArtifactClassifier); + } + } else { + String repoPath = path.substring(0, repoEnd); + path = repoPath + getRelativePathForExtraArtifact(extraArtifactClassifier); } } return VirtualFileManager.constructUrl(JarFileSystem.PROTOCOL, path) + JarFileSystem.JAR_SEPARATOR; diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/MavenProject.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/MavenProject.java index a6d37c007e87..c5bcb1a3e88a 100644 --- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/MavenProject.java +++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/MavenProject.java @@ -671,10 +671,10 @@ public class MavenProject { public boolean isSupportedDependency(MavenArtifact artifact) { String t = artifact.getType(); - if (t.equalsIgnoreCase(MavenConstants.TYPE_JAR) - || t.equalsIgnoreCase("test-jar") - || t.equalsIgnoreCase("ejb") - || t.equalsIgnoreCase("ejb-client")) { + if (MavenConstants.TYPE_JAR.equalsIgnoreCase(t) + || MavenConstants.TYPE_TEST_JAR.equalsIgnoreCase(t) + || "ejb".equalsIgnoreCase(t) + || "ejb-client".equalsIgnoreCase(t)) { return true; } diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/utils/MavenConstants.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/utils/MavenConstants.java index f031e6b6c8f6..c1be345b500f 100644 --- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/utils/MavenConstants.java +++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/utils/MavenConstants.java @@ -23,6 +23,7 @@ public class MavenConstants { public static final String SETTINGS_XML = "settings.xml"; public static final String TYPE_JAR = "jar"; + public static final String TYPE_TEST_JAR = "test-jar"; public static final String TYPE_WAR = "war"; public static final String CLASSIFIER_JAVADOC = "javadoc"; diff --git a/plugins/maven/src/test/java/org/jetbrains/idea/maven/importing/DependenciesImportingTest.java b/plugins/maven/src/test/java/org/jetbrains/idea/maven/importing/DependenciesImportingTest.java index 40c8ae8a07c8..a64e540a805b 100644 --- a/plugins/maven/src/test/java/org/jetbrains/idea/maven/importing/DependenciesImportingTest.java +++ b/plugins/maven/src/test/java/org/jetbrains/idea/maven/importing/DependenciesImportingTest.java @@ -74,6 +74,47 @@ public class DependenciesImportingTest extends MavenImportingTestCase { "jar://" + getRepositoryPath() + "/junit/junit/4.0/junit-4.0-javadoc.jar!/"); } + public void testTestJarDependencies() throws Exception { + importProject("test" + + "project" + + "1" + + + "" + + " " + + " junit" + + " junit" + + " 4.0" + + " test-jar" + + " " + + ""); + + assertModules("project"); + assertModuleLibDep("project", "Maven: junit:junit:test-jar:tests:4.0", + "jar://" + getRepositoryPath() + "/junit/junit/4.0/junit-4.0-tests.jar!/", + "jar://" + getRepositoryPath() + "/junit/junit/4.0/junit-4.0-test-sources.jar!/", + "jar://" + getRepositoryPath() + "/junit/junit/4.0/junit-4.0-test-javadoc.jar!/"); + } + + public void testDependencyWithClassifier() throws Exception { + importProject("test" + + "project" + + "1" + + + "" + + " " + + " junit" + + " junit" + + " 4.0" + + " bar" + + " " + + ""); + assertModules("project"); + assertModuleLibDep("project", "Maven: junit:junit:bar:4.0", + "jar://" + getRepositoryPath() + "/junit/junit/4.0/junit-4.0-bar.jar!/", + "jar://" + getRepositoryPath() + "/junit/junit/4.0/junit-4.0-sources.jar!/", + "jar://" + getRepositoryPath() + "/junit/junit/4.0/junit-4.0-javadoc.jar!/"); + } + public void testSystemDependencyWithoutPath() throws Exception { importProject("test" + "project" + @@ -718,41 +759,6 @@ public class DependenciesImportingTest extends MavenImportingTestCase { "jar://" + envDir + "/lib/tools.jar!/"); } - public void testTestJarDependencies() throws Exception { - importProject("test" + - "project" + - "1" + - - "" + - " " + - " group" + - " artifact" + - " test-jar" + - " 1" + - " " + - ""); - - assertModules("project"); - assertModuleLibDeps("project", "Maven: group:artifact:test-jar:tests:1"); - } - - public void testDependencyWithClassifier() throws Exception { - importProject("test" + - "project" + - "1" + - - "" + - " " + - " group" + - " artifact" + - " bar" + - " 1" + - " " + - ""); - assertModules("project"); - assertModuleLibDeps("project", "Maven: group:artifact:bar:1"); - } - public void testDependencyWithVersionRangeOnModule() throws Exception { createProjectPom("test" + "project" + @@ -1385,8 +1391,8 @@ public class DependenciesImportingTest extends MavenImportingTestCase { assertModuleLibDeps("project", "Maven: org.testng:testng:jdk15:5.8", "Maven: junit:junit:3.8.1"); assertModuleLibDep("project", "Maven: org.testng:testng:jdk15:5.8", "jar://" + getRepositoryPath() + "/org/testng/testng/5.8/testng-5.8-jdk15.jar!/", - "jar://" + getRepositoryPath() + "/org/testng/testng/5.8/testng-5.8-jdk15-sources.jar!/", - "jar://" + getRepositoryPath() + "/org/testng/testng/5.8/testng-5.8-jdk15-javadoc.jar!/"); + "jar://" + getRepositoryPath() + "/org/testng/testng/5.8/testng-5.8-sources.jar!/", + "jar://" + getRepositoryPath() + "/org/testng/testng/5.8/testng-5.8-javadoc.jar!/"); setRepositoryPath(new File(myDir, "__repo").getPath()); myProjectsManager.getEmbeddersManagerInTests().reset(); // to recognize repository change @@ -1397,8 +1403,8 @@ public class DependenciesImportingTest extends MavenImportingTestCase { assertModuleLibDep("project", "Maven: org.testng:testng:jdk15:5.8", "jar://" + getRepositoryPath() + "/org/testng/testng/5.8/testng-5.8-jdk15.jar!/", - "jar://" + getRepositoryPath() + "/org/testng/testng/5.8/testng-5.8-jdk15-sources.jar!/", - "jar://" + getRepositoryPath() + "/org/testng/testng/5.8/testng-5.8-jdk15-javadoc.jar!/"); + "jar://" + getRepositoryPath() + "/org/testng/testng/5.8/testng-5.8-sources.jar!/", + "jar://" + getRepositoryPath() + "/org/testng/testng/5.8/testng-5.8-javadoc.jar!/"); } public void testDoNotPopulateSameRootEntriesOnEveryImport() throws Exception { From 5f866d8dc777b96c38800158b3f0c2545261ecda Mon Sep 17 00:00:00 2001 From: Bas Leijdekkers Date: Wed, 23 Dec 2009 14:45:43 +0100 Subject: [PATCH 04/67] =?UTF-8?q?IDEADEV-42089=20(false=20positive=20with?= =?UTF-8?q?=20"=E2=80=8BConstant=20array=20creation=20expression=20can=20b?= =?UTF-8?q?e=20replaced=20with=20array=20initializer"=20inspection)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...tantArrayCreationExpressionInspection.java | 33 ++++++++++++++++--- ...essaryConstantArrayCreationExpression.java | 6 ++++ .../expected.xml | 9 +++++ ...ArrayCreationExpressionInspectionTest.java | 11 +++++++ 4 files changed, 54 insertions(+), 5 deletions(-) create mode 100644 plugins/InspectionGadgets/test/com/siyeh/igtest/style/unnecessary_constant_array_creation_expression/UnnecessaryConstantArrayCreationExpression.java create mode 100644 plugins/InspectionGadgets/test/com/siyeh/igtest/style/unnecessary_constant_array_creation_expression/expected.xml create mode 100644 plugins/InspectionGadgets/testsrc/com/siyeh/ig/style/UnnecessaryConstantArrayCreationExpressionInspectionTest.java diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/style/UnnecessaryConstantArrayCreationExpressionInspection.java b/plugins/InspectionGadgets/src/com/siyeh/ig/style/UnnecessaryConstantArrayCreationExpressionInspection.java index cc8c4b04a23a..1eb58482211e 100644 --- a/plugins/InspectionGadgets/src/com/siyeh/ig/style/UnnecessaryConstantArrayCreationExpressionInspection.java +++ b/plugins/InspectionGadgets/src/com/siyeh/ig/style/UnnecessaryConstantArrayCreationExpressionInspection.java @@ -1,5 +1,5 @@ /* - * Copyright 2008 Bas Leijdekkers + * Copyright 2008-2009 Bas Leijdekkers * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,14 +15,11 @@ */ package com.siyeh.ig.style; +import com.intellij.psi.*; import com.siyeh.ig.BaseInspection; import com.siyeh.ig.BaseInspectionVisitor; import com.siyeh.ig.InspectionGadgetsFix; import com.siyeh.InspectionGadgetsBundle; -import com.intellij.psi.PsiArrayInitializerExpression; -import com.intellij.psi.PsiElement; -import com.intellij.psi.PsiNewExpression; -import com.intellij.psi.PsiVariable; import com.intellij.openapi.project.Project; import com.intellij.codeInspection.ProblemDescriptor; import com.intellij.util.IncorrectOperationException; @@ -32,18 +29,21 @@ import org.jetbrains.annotations.Nullable; public class UnnecessaryConstantArrayCreationExpressionInspection extends BaseInspection { + @Override @NotNull public String getDisplayName() { return InspectionGadgetsBundle.message( "unnecessary.constant.array.creation.expression.display.name"); } + @Override @NotNull protected String buildErrorString(Object... infos) { return InspectionGadgetsBundle.message( "unnecessary.constant.array.creation.expression.problem.descriptor"); } + @Override @Nullable protected InspectionGadgetsFix buildFix(Object... infos) { return new UnnecessaryConstantArrayCreationExpressionFix(); @@ -58,6 +58,7 @@ public class UnnecessaryConstantArrayCreationExpressionInspection "unnecessary.constant.array.creation.expression.quickfix"); } + @Override protected void doFix(Project project, ProblemDescriptor descriptor) throws IncorrectOperationException { final PsiElement element = descriptor.getPsiElement(); @@ -74,6 +75,7 @@ public class UnnecessaryConstantArrayCreationExpressionInspection } } + @Override public BaseInspectionVisitor buildVisitor() { return new UnnecessaryConstantArrayCreationExpressionVisitor(); } @@ -81,6 +83,7 @@ public class UnnecessaryConstantArrayCreationExpressionInspection private static class UnnecessaryConstantArrayCreationExpressionVisitor extends BaseInspectionVisitor { + @Override public void visitArrayInitializerExpression( PsiArrayInitializerExpression expression) { super.visitArrayInitializerExpression(expression); @@ -92,7 +95,27 @@ public class UnnecessaryConstantArrayCreationExpressionInspection if (!(grandParent instanceof PsiVariable)) { return; } + final PsiVariable variable = (PsiVariable)grandParent; + if (hasGenericTypeParameters(variable)) { + return; + } registerError(parent); } + + private static boolean hasGenericTypeParameters(PsiVariable variable) { + final PsiType type = variable.getType(); + final PsiType componentType = type.getDeepComponentType(); + if (!(componentType instanceof PsiClassType)) { + return false; + } + final PsiClassType classType = (PsiClassType)componentType; + final PsiType[] parameterTypes = classType.getParameters(); + for (PsiType parameterType : parameterTypes) { + if (parameterType != null) { + return true; + } + } + return false; + } } } \ No newline at end of file diff --git a/plugins/InspectionGadgets/test/com/siyeh/igtest/style/unnecessary_constant_array_creation_expression/UnnecessaryConstantArrayCreationExpression.java b/plugins/InspectionGadgets/test/com/siyeh/igtest/style/unnecessary_constant_array_creation_expression/UnnecessaryConstantArrayCreationExpression.java new file mode 100644 index 000000000000..1b5d28275bf3 --- /dev/null +++ b/plugins/InspectionGadgets/test/com/siyeh/igtest/style/unnecessary_constant_array_creation_expression/UnnecessaryConstantArrayCreationExpression.java @@ -0,0 +1,6 @@ +package com.siyeh.igtest.style.unnecessary_constant_array_creation_expression; + +public class UnnecessaryConstantArrayCreationExpression { + private Class[] classes1 = new Class[]{}; + private Class[] classes2 = new Class[]{}; +} diff --git a/plugins/InspectionGadgets/test/com/siyeh/igtest/style/unnecessary_constant_array_creation_expression/expected.xml b/plugins/InspectionGadgets/test/com/siyeh/igtest/style/unnecessary_constant_array_creation_expression/expected.xml new file mode 100644 index 000000000000..31b176d1eca5 --- /dev/null +++ b/plugins/InspectionGadgets/test/com/siyeh/igtest/style/unnecessary_constant_array_creation_expression/expected.xml @@ -0,0 +1,9 @@ + + + + UnnecessaryConstantArrayCreationExpression.java + 4 + Constant array creation expression can be replaced with array initializer + <code>new Class[]{}</code> can be replaced with array initializer expression #loc + + \ No newline at end of file diff --git a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/style/UnnecessaryConstantArrayCreationExpressionInspectionTest.java b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/style/UnnecessaryConstantArrayCreationExpressionInspectionTest.java new file mode 100644 index 000000000000..741ed64c24f3 --- /dev/null +++ b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/style/UnnecessaryConstantArrayCreationExpressionInspectionTest.java @@ -0,0 +1,11 @@ +package com.siyeh.ig.style; + +import com.IGInspectionTestCase; + +public class UnnecessaryConstantArrayCreationExpressionInspectionTest extends IGInspectionTestCase { + + public void test() throws Exception { + doTest("com/siyeh/igtest/style/unnecessary_constant_array_creation_expression", + new UnnecessaryConstantArrayCreationExpressionInspection()); + } +} \ No newline at end of file From 98d931ecb0d057d84a656e83edf47ee24ed8939d Mon Sep 17 00:00:00 2001 From: Alexey Gopachenko Date: Wed, 23 Dec 2009 17:50:36 +0300 Subject: [PATCH 05/67] Fix updater by removing non-working channel switching ability and always resorting to AppplictionInfo.xml default channel. --- .../intellij/openapi/updateSettings/impl/UpdateChecker.java | 2 +- .../intellij/openapi/updateSettings/impl/UpdateSettings.java | 3 --- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/UpdateChecker.java b/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/UpdateChecker.java index b5791d5a3d3b..e3f39d7b317b 100644 --- a/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/UpdateChecker.java +++ b/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/UpdateChecker.java @@ -308,7 +308,7 @@ public final class UpdateChecker { Product product = findProduct(root, productCode); if (product == null) return null; - UpdateChannel channel = product.findUpdateChannelById(UpdateSettings.getInstance().CURRENT_UPDATE_CHANNEL); + UpdateChannel channel = product.findUpdateChannelById(ApplicationInfo.getInstance().getDefaultUpdateChannel()); if (channel != null) return channel; for (UpdateChannel c : product.getChannels()) { diff --git a/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/UpdateSettings.java b/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/UpdateSettings.java index 89e7df47beec..06d96d2d9f3b 100644 --- a/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/UpdateSettings.java +++ b/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/UpdateSettings.java @@ -15,7 +15,6 @@ */ package com.intellij.openapi.updateSettings.impl; -import com.intellij.openapi.application.ApplicationInfo; import com.intellij.openapi.components.PersistentStateComponent; import com.intellij.openapi.components.ServiceManager; import com.intellij.openapi.components.State; @@ -51,8 +50,6 @@ public class UpdateSettings implements PersistentStateComponent { public String CHECK_PERIOD = UpdateSettingsConfigurable.WEEKLY; public long LAST_TIME_CHECKED = 0; - public String CURRENT_UPDATE_CHANNEL = ApplicationInfo.getInstance().getDefaultUpdateChannel(); - public static UpdateSettings getInstance() { return ServiceManager.getService(UpdateSettings.class); } From 6c83e38c91fbf6795a3f200918c44e5b974df204 Mon Sep 17 00:00:00 2001 From: Bas Leijdekkers Date: Wed, 23 Dec 2009 16:52:08 +0100 Subject: [PATCH 06/67] =?UTF-8?q?IDEADEV-42093=20("=E2=80=8BChecked=20exce?= =?UTF-8?q?ption=20instance=20not=20thrown"=20reported=20erroneously)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ThrowableInstanceNeverThrownInspection.java | 3 ++- .../ThrowableInstanceNeverThrown.java | 13 +++++++++++++ .../throwable_instance_never_thrown/expected.xml | 9 ++++++++- 3 files changed, 23 insertions(+), 2 deletions(-) diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/bugs/ThrowableInstanceNeverThrownInspection.java b/plugins/InspectionGadgets/src/com/siyeh/ig/bugs/ThrowableInstanceNeverThrownInspection.java index c8466c4debe3..043ea018f324 100644 --- a/plugins/InspectionGadgets/src/com/siyeh/ig/bugs/ThrowableInstanceNeverThrownInspection.java +++ b/plugins/InspectionGadgets/src/com/siyeh/ig/bugs/ThrowableInstanceNeverThrownInspection.java @@ -137,7 +137,8 @@ public class ThrowableInstanceNeverThrownInspection extends BaseInspection { public static PsiElement getParent(PsiElement element) { PsiElement parent = element; while (parent instanceof PsiParenthesizedExpression || - parent instanceof PsiConditionalExpression) { + parent instanceof PsiConditionalExpression || + parent instanceof PsiTypeCastExpression) { parent = parent.getParent(); } final PsiElement skipped = skipInitCause(parent); diff --git a/plugins/InspectionGadgets/test/com/siyeh/igtest/bugs/throwable_instance_never_thrown/ThrowableInstanceNeverThrown.java b/plugins/InspectionGadgets/test/com/siyeh/igtest/bugs/throwable_instance_never_thrown/ThrowableInstanceNeverThrown.java index c6f26c09545c..b6445f7bf1da 100644 --- a/plugins/InspectionGadgets/test/com/siyeh/igtest/bugs/throwable_instance_never_thrown/ThrowableInstanceNeverThrown.java +++ b/plugins/InspectionGadgets/test/com/siyeh/igtest/bugs/throwable_instance_never_thrown/ThrowableInstanceNeverThrown.java @@ -17,4 +17,17 @@ public class ThrowableInstanceNeverThrown { void throwing() throws Throwable { throw new RuntimeException("asdf").initCause(null); } + + void alsoThrowing() throws IllegalArgumentException { + throw (IllegalArgumentException) new IllegalArgumentException("asdf").initCause(null); + } + + void throwingTheThird() throws Throwable { + final RuntimeException e = new RuntimeException("throw me"); + throw e; + } + + void leftBehind() throws Throwable { + final RuntimeException e = new RuntimeException("throw me"); + } } diff --git a/plugins/InspectionGadgets/test/com/siyeh/igtest/bugs/throwable_instance_never_thrown/expected.xml b/plugins/InspectionGadgets/test/com/siyeh/igtest/bugs/throwable_instance_never_thrown/expected.xml index c7321b7c81b9..0c197b2f6208 100644 --- a/plugins/InspectionGadgets/test/com/siyeh/igtest/bugs/throwable_instance_never_thrown/expected.xml +++ b/plugins/InspectionGadgets/test/com/siyeh/igtest/bugs/throwable_instance_never_thrown/expected.xml @@ -1,6 +1,6 @@ - + ThrowableInstanceNeverThrown.java 14 @@ -8,4 +8,11 @@ Runtime exception instance <code>new RuntimeException()</code> is not thrown + + ThrowableInstanceNeverThrown.java + 31 + Throwable instance not thrown + Runtime exception instance <code>new RuntimeException("throw me")</code> is not thrown + + \ No newline at end of file From 50200fc373525ecb659457aeb4c8523a71400fd8 Mon Sep 17 00:00:00 2001 From: Maxim Shafirov Date: Wed, 23 Dec 2009 19:04:22 +0300 Subject: [PATCH 07/67] CIDR build, initial --- build/lib/gant/lib/jps.jar | Bin 1554352 -> 1554511 bytes .../src/META-INF/PlatformLangPlugin.xml | 4 +++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/build/lib/gant/lib/jps.jar b/build/lib/gant/lib/jps.jar index 18b2cfe654451946cff2998c0321aa0ddef1798a..493e6b120b894931c277949ea5a98c629968e3b1 100644 GIT binary patch delta 21172 zcmb7scU%7VhRD&_u$Nd+ z)Wv8NO^m&zd^L$JQKKf-^u)xx=ia%??y7(MUOu18o%@{UoO{l>WoCC~r{dAT^N$C5 zrgsu06G#3g%`RK)+0gUN*<~%VA{TcYgwUYHZ8DAVO$NurHi?aiUA#3=L=qf}mP6^m zooKlsJ+Q^dk@O%fMvkQi<74F4=)uP^ay&iwB}Q&W51PcvE$KmCtlXR)Y>Jf=>A{Uy zIhh^=$1%(87#?(xGX@p2qh`7@q*(lkNycJbo?Sd<|9Qt8G7*2Q-Tn&+hh`2bkCMDc*k z6kq*wMv+txZd~#;z|^M9$N5d=Bx1>_mwL-jKl|sVG8Q8i6BZ9FW-OjqELgm-Sh09x zv0+iL_+at1|J>B?-76lBft-i~d7_?3s>ji!0_-lJv?U)(8rWr1T9@$&q^>;6KjrDc zX|axt9z5}_6zIXGTK|*j!L;xuCVEiOxPy@%{FAUrLpG)qdQ!x{OSq06wCb@^L#__` zQ?qkc>_)Us&Tc~M5!s2fUY8w5>&w~AyvaoL+}-);Xm5@qCAoB0 zwr{CrRc-iM(Ro!4%^BlOxRu{duv_WDlG!mtgr+(sD zW35?SLM&Xr?Gp&`BHsZjHt9^2(y>1!Vt0R|O8(S9FKTYVYwu*f?$2?g)FI~J-5}Mw zvh3>>PE#?l@%HNv4Qu(z>sKD>y@+S8nK>J$7&(DkQF>%uc;&O3zgwuEfBd}7LYHT| zW22gkvT)p}QvR2Eu%$|8ElvETHdICHyH{@cWd{$-%wk&Q(%)hv`$U<)Vj$Y~-d6sZ z7d`3|#^3a%N39b1LYg~!MO(g}A5GpDO7!dYtNr<2HBKfbCB@rY4dgRSG;^``<-_?h zPfEU7m4C>dG=YD=hTJSBHrA2qcX|8dN&K5Ss`iTgkEwi?C++u*1^je{9$jC}i=GxT zXs_qbzcJ0sansDe2Z*&GeLG(V3ft(s?8)2t>1N74w7-VEqh1)9q0FZkEJsIPTL^^dhb{hkjMOl(>-i;ICli-fLVF0;t?$+!8d20Dh4 zz5fG#gqE0-|MHErWc_9n{?gok5++>JoSreK*SkB>jh*H)MToI`Mhn$iw-;In7tJ)T z1uK1GT`1SvBZZFQHuLP_$*4OSVowO6klIqPL3t;^WWUo(n5XGxZT;b51yU-gd6*Vz zu-Xp~7ItaU_eM3iHx;E*X%0d(3xzp?2Xw86IXGM(%+Z|b__okR%R%QGYKVRHd|{v9 zSQ^dZa0X^B627E^yWi8Ev`pxr(u6JDeEkpmyb3{al4D{MVU5Wv5KeazyW4##g?-xK zwzr?J62dJs;P*mG+C0Gx`UwZSc)k{7rs+MPyuK~mo)%rEUaF({@UD*( zqV=??j+CuQEiqD{hDD}G&9#|2th1CtcS-w}0aAgDX8Xf!ZSF;O;W$$2!{`z*2r7Ie z19UEwyvUNXi}j%Se4Rhs*lh^0R~1UzU6Pa(YcCutJ@y%3do`ypCqFwUf5@b;Q3cuK z^K!yueksp23>%&`At%4VxUfk%rU;Ym*^Qs6Iw_fS5)Hva|xrHTKX|BC0# z$nBCdE{pLmah-|aGNdihO%kwvQlAfp!c&GQ`3isCgX_iLfL&Agu}1!T{uXK82Je32 z1o;kskF_(TX70uPl^oJg>l`MN&BL z2j0a}5bqCB#n=jh^kONP4~2ZvstqN@QUksoR2570`G#=4SPJ1A!?R*3KwitQ!@&}w zAgn|Rl-KhcNGle;^ORMikigZ!912Z=x5$b0ge0LkX(pS61dIufTJoH(VaE;_rH~-B zCP)hKXY_$ap^c{b3as(ghZ}{qTC*K=JEM;>3Y~ZxA$Nvn=fnWH8#j!!(jn};SYLi! z=t)|=U~yeJ)F|}TG&A79VktEI4K4QmJg1DvnvfMWeq3%|RN9y^S(7^BRFH*%5N_n- zj6$Z6MdBC?Yc7cXf!Uf?4$pZywYp>#%EGYH>BS9=Las&_0gIbS;ewC{k1nEL`5IaP z-k*yKKN?1VE{4lvHEF?v%%`1)F z78E8d(7=Vb4xEv+&l)?tXAVYR4ByQX0*u09jrAUMujCa$cpnz`;4#WF4F(8aBGu-X zLFy8zR={!%T!HI>TFfnoYMYyvBMYlwbP8YBD3oi2HE_hp2MfYFIJ88nBX7{qjZo4? z4D=H=uU@U4JZGXSZtU2sVaVErlS!x$ zcEhece1IG->@f*DguSKV)9p6l09o^eIJwAXmn{p2AZ-+{6baQlr=O6OH$G>qEF8ry zwXG5xpW_T7CytH-29;hvTy>A#^z4OP)?zxA$d7jV`Sls%nijBI+BJ7J1=w9 zGPfOpvE$GwS@;5V@-YZm_)6xDGWV;@DJU%*PwB!p@Ha>SMb|M|L&lFCS1_vE_;Dzc zh3{m37ta~Ve%hm;U>tgM3*E~d``W0&ag$`>2bq5Z&5RnEor^x)llcJ{NcNaXJ;vwD z!hPJfXq-7?Q17A4;~WvQvN7x@GGB_stg+hU{#E8Dk!FwV?6kZ*S@;7LhZN+G%gW71 z#lNusyquxqdJfMWiXJ_c`Ss|+#H=y-c!rRLXEMJQ`MKkA#$=5v7$b{3nxY%%SXmTH zy=O$)!bP1)I4J7Pf?cS>Ek=|f>%I``BbrR22VdVT>=!=5RV8|26S9^`DY8}cHll_N zq7Mr#?YEXmSA`-U96GX1**H(mgX2Z5ZNawJb8V|j+Z*M!=h_NKbZwk3=SOX-T&)^= z{#Fwgzy)%gbp{v21!HX_dnw03>PpF@2=@tuOaiWaTH^wzH7;pd<0_^#u3K8;BBeDh zM_S|JqcyHKTH}hMH7+4qe7RD(i@Wp3tE77V zDhe@!xP|+2M=>ga8_Er%tf#A_LkbDgjH(>BmCNRGI8IdI%xWo=_l5hbrF0j0%NlvN zaw;zTXu})?{4Ksi{tT9nbk6lY#8rrJnj?jqZwbG}Um$Pf7XkLYX*Gi4C z*GB99&$hawtsj`JIqO_)O<7NEZCNk9f*m|qF9rIN#A_~O;R#seexoh~Z;;x##28=W zc|1qv9*J@K21!A`mTZvTMq9Rxc$K3<=Zz%i_PmYKJs#2Co24#@uHP)RK~TbWiZjBFY|ooc=Jp;U@m^|wh$^@x^*6S)X(2iKO{ z$@S%SF^vH1X92&E=3*97QRC1yw`_fcj1tCp=wyUDeLjS}mTJR*S2dxy4#*YINyy$V z)#VFe?sln7Ql!GKh>K{vpF1RSeXy}IE@BVY3fuEUu8KQW#WkzuN;10k*~Ez`U8PC! zXf<5fF8L2HccE8o`tLuqFNkEqg<(`2_gT%bea2nouHi%r=C<%_xEq`(599`>>~-1DYX{v28W!({i+3GmDZPaS`}`Cq(VUYq|>PvQr8!axTU_H6iTL zazh>W!!eS$o4A4A;`(#9xjgPJx176&W4(*tP38}dqz(hoV;~z?AeC`d{J#C%1cB?y zCrj9+o%lUf;F5Lzy8ZmeJhzO?Cr8!1nWKawB*>%iV5j6C|4CdEe@TmG6G!k*NdWy1 za0@e}k2xtr^p|Sl|BS|e0+K4EFd9k(&FI>iP}cG%$(aC`LJ5Bgk3`%}XYi-F?>Wh3 zz#pLeA=i|9#J$cv#?AC+EWdET{lO-GpjF~Jah=(?)x+I{>~sFR`LmrHALqOx_VE|0 zc>n)pbgtyjHr~g7U4c^0%JcX+flihu6;edeH~hEEfQ=c@M>O8crSD?oEBsX^_s1Z} zZ1qIL*CHB6?&rUgIET&e`J0SJq9J~mHQIju2eF2Ahrj!ru_C9npCpcU%E|nFt`6gM zpqb;iRtNZp89w|YJO4{YHUF@Z|E-UP{9c3n)u)R8r;7iNEJlIPz=Gde_Sv;dTW=ia zEl7e+n;V=rCZ8+@T@emq3mODVY7p}DFY?H8ccld*&G1rM%JVe&rL;7S)?C|JL(rV@ zrMy>M%@LYOAlD?maACJp%U~8fY2y)TSOhP+by_MVzrLE?P>vU@f;WrWZG=10WV5Kl zth`{;&a0S}n(Rc_1s~c!ihXhOCH=0bq^IkHl~SNiI}cvbkbf%i!csdgp$(V5>_Q!f zk-9uySkP_82M3mHGcwMkV7pM?!DxW{zs4YIob1G=h{i#<_Uu9<2PeX@Tf6rXS-}+{ zAAN12ZHL%Ua5j=jYrt;oLbSs|OwD%Z=4YHk9$zy7U2~Dh7KPAEXwIB;72`Z&{m1i9 znB2zt*GGifg;oyzc%e0uD=ZC$h)~Qzs)LaB(*9p{h+liDxcx3i{~fs47yaWeIHK#w z+iKj?HVs_!cA?8QOcY69*O$(O?hf@HLeCei3%!YU5mE2+Qt$d{&YO7ra)qgf(v1QK zX}2&S<2YyOqX>hlgdrJ~!T_x=6J8*^gglgyhil}a4l>67681>O9;LBII@qti%yc0m zkI~454s!RGk;gOgM2$S2jlT&`(=YL3GGo83u_rUrc4uqkO^m!nBX82kGWiCE zg;<}R(rgh`!nTUe2ZS9NjrR$ac46OP?JUCS1k}P$Yeo10Q&SSh<3$_(iMa=agBiO8 zQ4u~Smq)fdML66u!!}A0j$k!W5kA4{O+`3{)eJ>Aj@5icIEmFFML3PsGDSFx)dyO& zT&q@S)hb0ehq85=-e&xQfi$;h&7GRCLJ=+?_>m%9#Oi<|e2&#o4Lqp`Ut;T&BK!}l z^NMf@s|$*78LNwm@HJN7D#Eu|T~UN9Slv>Dt61IEtlZJ8+|{hyQ-mU7=Dud;fg)VP z)|!VQ%Dp(Wv|!l(4iPJW(uE3+R2LW6RF!P!UIxwpb1p? zj*9Szw9{F;yTYfDb}!cMO@~e42hltzd}a|l$YLGjusT-}9uq|z^`A+duL!@8x`1Xy z;R_YvH`2!G@H?q-KHw-R{A8y8mLmK~+HW&Qr!YHHnH}tx>KEY*`kN4ED#Aacp2a+U zN8yu58|M`5xR`aYSP}ju_(#}Bda$tLz|hQEzHn1I*}B9J2S9DGr;d;dfKd2_)3-myCMptqa%taks2p3 zt{;W}gk|DW(vQ8DXmIQd_3;zGb|H~~%a>g2HQX&4KjXad|31-NjjOWLan4pHS~?vN zJu)KfqF1G8jMyV8)B;{Ig``O)b1>; z|4EwQN$;sFJ$vi3S^*qKN&>mnYft@4TJF3l8rw9{?%iL1nz!%zM~ar|J)SS^wCP+DbYLAE!Usw>fMwVew4X6rz7l9XtAPr9(DPPP9%Pv`1wLQ_C* z^Y%M9rzS8AsE+*X3-O_>z{6p7S zyJ2kn(Wkz>K+=E6*W84Sjk7O3s$a+3j~n#2wbbmj@3QKrX_ga0^m{bRKSk+T$ZcEd zdu!P0&iW5D%bia@+F?)Yr$6RmIni$Ium4x3x7EKjb5_n9za->Vz%(3eu5X zQGGA1x9XbS7D4QOF#^0c>n--Cr}eLD9ld=?e^Sd~`ycgZv{=-q`Zuj~I*t1F+`LeQ z<4Ea-qZ9zsEQUDyeGfyl=3PjrVTd=q+gehzZ~7Gc_&de7w0w50vbBcVW$g?`m>tGj z>^EWzMZVPF&0iNx46Ma*q;z%|RG~c4P|Lo*t)X!(I?wJ5G_+IcQS1c6H=0wH*@iRP z9nh<545KyoVlq5m@0rYTq(o6`g+J=Oq5M_6>s+$iFw-R|iAjKuH{{vp?J*2c>9qgO ze*d(A52wz5*ey9^IezwE?uYwMEtn?BCV2d+>I;veWZ9nl!0>^KsiY+Gq(nV>i@xeV zyYY9!Ic?}#d`|(3Rd(7fp z;EV9aSvS1#Vo&sx-_e%zh1~oep7-Ph{6?Bw9FS+M;2oRV-2EvlIAv3tHhuo#Ch}=X`?GQn(hlO`kb+Us z>7CrIHSVAWhFxRA-28Dld3m`bUSO59RRaYh58*Mg?{n^)C!*#&q{qks(5k&^3V+^_ z2<8S}@t`AlJO{DuRP9-=k?l}<4-Z*KOhP3 zs+po4+ao$efV6i_p)VLp?}EZrs4~PO7|uIXt`U_>)KCCei#-ew)PY%}N%6tYfh1!i zh7}ZK=jM!kAt}~QXdp#|BXP1XEOqG8&I%cNZqKaY#>@UlHUlNNc-u1w4s>L$(~S0%G^eJ;%ZBHMi#k15f;I87`kbgc ziRU8;7XRku|3VIFwjOCh2uqMn&neSkiPTYLsP1Yry}r2UY7Nw^vWAzjr7;deb)64C8UY>3(394zdrwiK@gad4)qnkGzaNLGyk zZ;h8N5YtVK5t=p8kX8NVTCk8HgQMU`uIvw&yQy(PlNhZra1bu2lyvN2OEN)1VIFBT z9tf$cyDC3Z_;%H#?5H=8bMO#Ye?N5YO;{9fHdkt;Q=`iR`)>h ztc3*W0B?LO2SH3vbfm+31nCCbN>nqX_E2#i^;83dM1Ut&BW}h289m^`o~j=-dmZ7g zzawzE3%jb8(TYzLX@Bdd@3=?I#Y5NLs8Xw!8X&e0#P!_K_$qP03Udi`IEX@ZU{z0( zA6)OH#)xx67!=*Y=nv)nQ9HXgQhPVzVR~=1Q2a5P5^BSsRt~~zeUPBW^N=>hh_(hB z{b04xqzA9Q*wOkCMysdOuMb*KT3s0aRK~Lyu^-wO)%SFwczr0jC>vp9Uv#BmR|=(Q zb{J#g2P7KQyzBucg~t6#e}pG| z#^{+XjUj{{Bj%i8Q2A5L6HYQK1P(x|?i|BY|3%Bx#5)A9`#Hl0@us>O{wKljUuO7) z5vE{R)&mncVj$w}zG3*5fod0Vzzx<49He#-bMCNKxu2=FX6wKp)LHqE;q#LmQ8ms) zoHyeh-O*SZ7Pi1XoMXC@2;2EH;f40502iS-3x%zNnXuqDj}XYs!oUkd9Q+1G9aMBN z$#6Og*X`+WS3GpE8YiYSbcKrgAoWC3$FdloVRD^NBO_e7mj+``U$&=EAcU?pdcz-c zRGYS-IuAk58uekqifWS;_GV+=wh}yP7{g;$8f{QihV%FDA?V($DGaZkZ}Nc#Z#j(R zWuwwRTOCT@m{d5BjePws26@djS>TtI4t|3i>7;fbNMN zK~OSGZ7WW`%vw7Q9s%Gr9J^g}l|jpwdw9XJQJ9%2!_n#Fy9_T-J?g=ZNoe{fg1`3< z!;89OCO4KiBJG%q!YTh!A)fTtc_!F8%`Dpsb zk!bo-Boh|*^Dse^JWS_5Q4H$V&%+4Dap>^!Jfw!iIH-d>EYQ!-5#^smI3$hcFBs*v0%p)H^$uK^^ydnBf6|b}eF1^dS#VNFR+*tHlgDT#Yf(#GDW@P1ZD!D*acY{_eH&{n{MG}vPU6mzYi<)|{!Yg5yzYph?|3vl zbvMJyAIM&spC1!^_I{Sg3$L3@AWR_1I>?|7_i^ZGNK+>u^}izwugH--UFOFXBE0$q z6LuBNCI}Jn#}3X((rh9!ru>gFu9xGqdut;0bo>f~Qd?r@ncikI{5k}Oe}vWSx}Gz? zbEUO<6E#Qt#GplQ;`mDsS*t~`*%LB0IVNY{P&YeWA2V8}gdQvkMIXCN!U?lgFKPQl z`e@k(i&PvFT>BAXxq;z@Ph_jMf`cbxB+b1LZ*5M{ru9?;h5Jb4{NYco@x9^LWOT7^ zs1q{4s;*`)vZuy~Tx|*XpFMpbGv6$OS1+>yTi?c@SHFdJ;!~LL!dq&4QR?BOS|DY* z*#_O-M#p{`$ncW4)sA9==}wjm{VU9V;57wVl?xf3J_YxTJ8M}Be~97(ho_(?zB`+Cp5I!diukJ*{wJh8im#Pjy265Hk}E7Ia~dwG793A%SMiV^GBs+?H<>sC6lW z%0Kb+gw$DREAM?Lq(XaNoVvSbsUc$NDkpA+zh|L#>0S!eho0}C;{JWC)%pid3mkX{ z30VgiRQ{u9Er@&<$LH=*3ME1@X?=Q}5vqrH8sOf$sN;Wwzo4_=GdilqXZgs^w<8U5lp7Crnl6CIm45BoTs z#e~+mW(g_@|NamMztrLhmiZXgvuq72d()yo?tCPr7uFy;I7ko$KdOa4wD?2n35zcT zFF>f>A_iFxBQ$jZx?EiBgzCa0!g{OJ3Hd_$LR`Tsmog~qkj01C@`Gy&(c2!C3}5}w z;sK$HP+LAsp(c<{J{Qejgp=U(DLt(D#}WYPYb|C?`|cvt&O1Z#I?%8fJ(+Wsw$dPf zAtqycF%sVYoIHe7l>4CxsT8jU(pTbVHFYuCzx@wmqz|_mAv6*hZ!AX5V+Mm}tbDPWEZ+5@tq2I& zj1E-4huS}N@p9eSzYC#^V6aA^i9YXP8m3QUP)s8{>+c}Ypjig^?me}qIO#KHzFVo9 zAWk~LS~vdiGQ-wVWd45A3F%;9m6yKkeS~u^Gx+)#s}7(1MQD{IQ%}nhtOgjq&=FnL z`xxDFy(Ys6fIIz#rdB<4Sni16RBNki1l3-QTODoE;Y03ddQ1?53KgRsZgj#9DmtN! z)k`o#O{1McPwi5YCdN>P9iMECP=7spXX7(4^KpomFht+S)O&5*wo%^&G& zgf&amO!3chBY0o%ehoaCmM#!OObJl?=G1vmYRO+x(N`$>1FyVy{)I@RWzpPc<#O4b{Q8pdCvK-x6!J9}#VLrqD{7$40IgS|-WyRA$`bREP4L}pTL|=8 zjP6=DVwQ}n(4!N5Dc%seuEL<6jW@v){52(%tim&6&nc``Ehq-KwF>R6oynjJyKSEE z<0@Qz9af{6b@Lb=_KnRC+W0#9Xnw-xIucRKTxpM1tIb8-Rwv{Et-rSEA-$Xo@+pP~ zjJK&!@)zPe2`-&u_=Q|w8+dHM?Ztl$dhqrghId+{wh?VlSSvM5@r2WpaTI9G2O<<# ze|9}(wCe9{GW@d!BRm}9p`{?KD}Hs^X)QvL0~qw!s2E`dfhG@SP=2yvfj?H0^Z7dT zVnm(??Aoma!Q=ThGjv&p)RR*gbYTakYzu*w&ZJN@i3q!0`jTRX3IcW5?*XwJ z(LiRLqJw7yT6mB`{lsrRXXdupB-peOMa{2zKzFlGH2kz3o%P>@eLnk(*_`%Jk)h`% zWX(=CYiT3jGM0_-vB8C0A3Y4(iaKYA&f&H$1QfEvmoRtk8*DA#{z82TWV-@LY+Z)6}yC ztd+VIzdTv6!VHTq;5VUO7csl%Pov_&tvK7>Tto53q-BM=AEKEKo6V5+p_(D~-%Bmv z*Ofn@&Z=9eQ}`jWt`Jt8Y9`D)h%+e1m zt+$(mdh@J#$rIl|SarllfvD}synN9NS=-fKV*Q^qQU4%cZ@5iFdwQ`mEpLh(6azt7#=&3=s!}E73HF=%TBa7eXJ)O`Pmoe^IBiL zCfkhzc8D;y1H;R|@wLF?&wTaZQGxj?U+M|`F10okf92~3g%xPx(HaIlO7SzoIRZ`J zK%pLDH#;-)@ejTpQ2Ya$dE*VoS}om$9ko5c7=w&{7FbOjcuerkpHMuitP(TcX*VJU zye6csKHQBKN_ML$;>TW2sHIpt#{y6G`PG5+O8k!G)L3WB0G{joe96TG+a@|}@pIiK zQYJgOdWhPCAzYqqfvi31a4~HWl|{h$kNvzrw-;sC-=|O`((;3ed(pY1wG;}4R$uv< z;qYGkf=IW~3HdA6axNTTE&L6-6)Zpb;bjeBg`Q#f4MFvQzEAyZ z(9Vvy@uDmK{XW$ej=v*!yUC&5?IK^;lA9cpZ(1NsQC0Hma3Hr4#I-jq__Vh#j8gC} z0YS<4_~Mro4Tb%PzF^Y*E`jwHHBeg7NAGs0fY>58XvFpo0)9={-iO(%Gqq_O{1pyI zN{Hj@WUSXuFVg5R&qwv6T_-lHYW}S^$C1*+jXLEA9Bdz);iRu;q_1^<5@#aen~|)a z|I~X0^JR`BCB{uT<0+wrmWCM2P>yFW+Skoni_hP}pJR{`T1!IOqyL$S(2L3#r{Sl37 zrUBs!j_>nan}bTN-*4*${NJLF>pd>i0CEFL3~J{ESyj3qc-tRyPGEA^P3(nm+5|%_ zx4B59QOyB2vp5fpS%E;cP#HNw4?Dt*oY{t80p`rdMtos4I)&cP^? ze{sr!XgsS4Y!t07=B@;*3hh5F-R{uV!0~Y*kSIyu0>GM*kRzsRZ@}30XLotaz^tD1(xatGNlkmqj1rvBZ zbP8po*e?`&^DLl*x=_3TWsh4j*)AemJcG(2;c*O0f_E6gP|V;PYw?O6-Z^y8cE0GaX5DL)(tCJ1$E%ZmTZ=H4yg5bJMJo^#JXv3`i*iUp`kpI&cH72470m)FHE>%Yd_!IwA~oWt`sk=5(L zWR90NXe-M&`meJ*=ARVz^!zi>8>ZJ&ThlSVSr^|yfyMo#);XWr^@qReu`H5T zIyA%wZfJ4Kc(YQ*wd(XbxWMal(5*hxa=y{w`DMFdi&M)0ck#X!bt#t%-Y8;HNO4ch z*IT_|bVIcc^gDqM{M5|S&<2=>1Ur*uHc;zOJ1tYU8bffclG4=8-8r8yZvUGCem=w* zMN@r`*!k-VChPjU-~+82GN&f~@4EfvP7S_66|~Vh&=5_0e4ip=kdIfja4Mde4{U_8 z&Hp%Meo)YenScLo!MP7`q)2f+cdehk9lu+~n8UylC;GuM7P zjEF~81I5V-b1v%ZM3z&}DQgG?ZFDYs^ne5;OpRlN%x=19dY+_)za_GqSDng@pfF44 zMOQM-=1hK*^zx{xyK7oy({y1lFPL4f(Pwy{#No>K$*PezBG2+_TdUgxylz>t<~zNR zVWmUCbWV_F;@l$TH8+I=b9~6PY^rmH^leg-um)!bDP7&TYnD@PH|Hhinr0aJj?ENq z|J;lSZjLhF{hExPWEV77wM(!M)YcVm;mjh%y^C3=m@W6A3rRv-BfnuXd_j^C7A7%c z)gk&A8ZwnlO-5M@{92UCrbX+M zoYx#r!h0^dfqs(mhMW1aP^Uuk=YlV3ffgS{yAs^i1bI-o3I5EN6!(+kf>ur!Yr%NO zNo`(BH0a&S7cP$0w|CC`{|MZ4IEC9lMYP^XJ*QDkX@xRwhN~=WEfUD50y-^ydsS~Z zg<+90*e$dhr7vhrU8gtJENSxSb1%GvASK#OGh#i}jDRbx**^TFHM();BVY2_C=#rf z^#OFEQx`|1pls<`S6O;0z9gziIJ>mHPYA=VJx2(n%K51%`~D%7MZ*n0L!k2-;3p!> z7yL-4OlE0>k3?4t#%s5lD~{1=$of*Dtk!TgjpfDdL20+>b~mEjcF?X3i>`kgG|{XL zh120w8|L>70#DDNa38l%)8qpKzVs-ie*nJs2#fpfI&cJ4=?0@_;}znyM(mWnKeup; z4X=MlaX&vad50=Ah3YK^6W!0~wF7xN8wS3LJIIS`a5lifq=&_eXW9(Ss zYBY-R7fXySrfCv`(O6<)NwLKCohh)piO>J}e4g34^PcydIdi7md*=>bc-XJ#LBGJx z?PQHXApd4=Oj;6HHE_npr22+#uP^pPsNa&N19Ua24~$Q!UN?Tp_E35H#w3_^!xTv` zcHc0?(TnRhOm)dcVVE`qp5HJ9fa@Jq7f@=LD0RPSN+cBb{F|odBE6b>%T&=uuZo_U z_DS?=@N?5QI(pSuW3FzXS2-qg8$G=`teUqNOlYP4$%+G`A_D~>G7v^SH&uf8IjRkc zOlG}%cLj6hK+66u&K%)KuU;gY*D`EPQ}a_+6SOc}MHw3l+gqB$>BYI0<|umctfjd+ zy@+aMu5Bd&p#kDQDu}5T2Rt0+^n` zN9^2Ok$%xVf1){E45(EzDL$!ALY>+*Yr3CLGFLJCRs8MCTPf};^URxrsoI52<~Wg7 z|6=p<6W=-nfutB#{k1J-#a-tEv*NLoRJSfPxoiw|=Wa2#^CRYNzvV98VeV(9Mi$l! zt=uhG5J;-XjBH=1THW1`nAdoW)UHzpa@tD4`_(z3d)+bf1Ff0(HQ6ZG1Vt}M!W!7P z(h&huGc1Ab&rh1~ny9Y_zBcbL(XrF&v#jb_CPB!8;;+q-Fngxc0)KyPt^mQ)Eh$hO zj6WqB>s*L`PuT~Lzcss{*8^*^yXSZ2c#XUEJ@XI#CK9Q?ubymu)GP=`&2ao{b0yfd zNcD%}H5R?Q+n?rRW?HFJw%l;gs~16*To&t`C`+W1#(Lheut@is#+L40jjL7L{i2B_ z)j(rC)ZM$CWqBYa9|~PP!2PtBFf^e_NihCKbunYwT)? z)%u)OxhTwf$w(VFf33a7Zgh3G5sv+BiFdDyu@*Bq2Hx-{0DSHMIJsgU8+dvaJWa z8k&^&#)gg|TVD#0FgDIHfUL zH-|P+a%^*c^&@%~&{Z*u6(DYvEz;ejt8&v5pE`;0?zkSx zLwg+{v=)}#h>9~1KU{LP4N~f-G&Pn zEae-Bzxtt{^dB~;YTKwDMj=AHZxHW^4~&9K2*7xxpMU3SkWTTNJ9nqflog zSfUhvgHe3KqW2V%@0r8(;yJy{^Jep(=)k}?; zW)nEN)*7Lgnz3SYc(}(ItCw1fHbQO#dm7t<^-_Cb2q|`eg1_yNdMQQfOp0AVY+?&H zO5K@m4^aq#b0d_{3Q{i`GAUIQlwoOO(_+Vr&Kwb&JZeUHfez<%Tm9$E?Yt z#wyB&w8?gtUdm;Zkr4NnGgy-HAmz3LgD{4{VZGU#c?_WS-WtUNjs(8 zaNQ+^=pv*&25Gyr7alD(yKT}zvVLUYxFc&|x=uO_$uAsAzVwMGXve0F7?Y8wla67X zY@x%#ah$&yX@iF9q!W0RnLRj1Cw+!jd6^TjQK!(-pb;5qqjb_4oiG?n=t(jL?+cw! ztP^%3kT)8=(n%LlCmUO#lfKl6dY$l>PEb&a(}vKcZ$X@-gyjE#VH-3iZ*)!;n^HRI znois$3i{DF%ev&`j7E>HqkEZoEwXY)PtZv>bmCiRCTnq}=WlXkC zx{FI7ZD+r{ZdxmX6K7uM-QAn3l%|;v=0nffW0urzejXp_BeX#X&jQqti08 zQSmX>KO$rB=&nOE2cxe~bvVxjzl>3%a& zv{Bia*+X=)1O=JaYPJY`HIfd=enx4(^bsyyvOkDln8Tg2-XI&q%0}scv2YFx6|fn0xHwh0BRb$vff9);_fG|iD%#;mfpS#AS0HS# zh`-x}bRk0!WG9@ShK;bpooPyEFL{G9dAsRUK76`TFUF%^xm1p}FxrAfsE%QaMcZ41 zAZ6wOeGF&J)5b-V2dK(`Tw?+g0^mPTQlDAwl!fEwY7Pc(hMuO zJ4*?5cw9)s8>cM%OY|ga=a8_vht5&% ziimcZr*uGc!#oU%9e$XHr~^*U$6B3WSfEs~($Oiaf+&s=$Kvp|L(>IHLnKXIphTAU z`1Bqd$8r!dCy4zh^V0=N9x`h$RN|rt(}v;G2pObq0mOy#`Ucw%(5sdZB7Z=bLPDLtee7wjf1|K71F=zbhVMKU* zK8m##vhZU)_i$vBr=N{5V6jq3Yz;FPD^0Ci1i6|bu1SdAFEot7tF_CQD8YT!vGO5d zt}GO7dHovIB$&nK@I^jp*8jhRtLV>tmC=p~jl2{-ZAcQ#FdXx~p3Ns@9W5VjHuB zirW*S@plIdU#f(OJ7MlprF_0;3T-L#dJ78y^_BFcM)*nSkD*v7T*n^TCGIA@j!%?+ z=(84m-pqY2N;oL)J0y&igpOi84OX?ExHv@;>iGrx9TGnlg_S}!xx#xOl^;!rL)Ni` zgTg<-nnPkMS)lZTqJ5=cM@ex)b;L=RVOvPkk3-)=CB**(ZRuw)rBHF7O!ov39`GR=V$lfg zg!a5kB5|&hwIz73_<8%7Q-V4AfOzhpcsaHGKJoLI1L8MDC=@KBh!63COeSvaca`Y; zZ^iGp0UI}iWL{$(uRW9^Pcpp^Z=d)_Plo(i zhCJ?hP<(b!d~r~yQ!Kth)~kJz&~wioHhl!aDv1(?h>l+?2A_;`zos~D>r?l5P(zU? z|CdLmr#Gz}(lm?)8219$3qx9&ul;KXxAxfg%xrPjl?Xfy#F5U9ybma5$BB zOBGAaRKlg2)#Jn^lPsEs=$LXiyWCRcQcjh!h1IJ`ZYio%9?e!e)Kzdql7Z`wwYa5f zMfrG*6G5t8ww(D`h%2=aUp5N8gHe;u3@K5n^`D+{OG#zg;{CE%vHG>q;cltk9)Z-4 z)yGTqIYHrJ@Q)71C^RgspwS!aPc9WVeWSQVsko(3W@AFFRA+RFT6D+le$ zwmW!q+P!fobS!ONC#my)%}ZTNwY$C1xt`Rye2YQE-4CuFPFD-;rM*(`)Kh|~ry}(^ zC=E#6C-r7^8Sq~I2J#?I&S2z0rQ|nS9?HqX2swYBG_;i6{7t5_I6H@#&MGCRyoo%D zlSec1s8aHYH<8B?ay~Y30%MQkY_gy6-*~*uO;2Iuw@XcDzlmJH$hwS%{|#Pm;_MF?dlO^p$X*9;Vr70`vqc}2widNN zENxGXIUp6erG3ZPtwivXcH+!3kQX(kBlpGoIR2AU4oinp_ez2yeT+{(`Kh)MigcuF zsx3>Aj$$@Wk%}=JuSlO_HcgTKhuJ(uI*HjrMLLbyN=5n{vsElx&9XHtTc=28QT9I5 z`;e8kveIr=DpI6#NcmWi&Ua1Cw;fib3t0S=p=T875|%z!q|2CHP^7OgyQoNCV|GcA zzQOE!Mfwi29~9{dW;Ye-DrUbhE4P`IJIu;mX5}|#<#$E;9+~%7y7)APp;bes1+X{Dhts=c7WgLJwx)gB}&o^_u54heIuD6Zp z<%`?7;tsB`ljk^0aX#RaxFWqK`B6m{Nq&su#k|GG6 z)xEOrq+rG019Cty&c1f11lvJ5u-#$VP(C%8Fdf8MiLha(ieG}rr^w`E$|vkY zhIm04%f2L5o!>jjo&SS!$nzyJDWSGIyRqY}=r)xoaXK6MGHWvm7QsqBs2;#q4oEwx z)N{|dqx525O>RC`QkdZ+t^FDMYLckf>$C47-3u;v+-?*Ek~(w86nkYTX=&HFzlgLS zVG8pS>^H5nB|+!ZyEl)Bhs*Hs$XvTo~ivp z@bd_!IHqrTqL|?60!^ShJ=?y}tF1K>0o$73j?1-AGmvk`x3y*8jt@b~DXY`{%|!bH z_SNU~Z2Jux?SNgY?FNP&{?MLoq1D>|xVZHniy)BHlT;h-?sUk`KNBta+~+_k?ix>sy*?9lxd*x%t85YdV=Nw;H=-2qKD|G!`kKxn9?sJZA zFnKS2j-?&`^EHQowei7y#~k(@dy?cF#N4>9IKO8fhmS=$rv=d-YTne@N~Ko|Q=M0t z?(kvGFW9HYdNZ9PS+9kyui)%jPY_6oEjugWbl+a)oa5=2q?&c$G!CH#Cy&uT)XU?&JH{@au2@ZJkPqU z$Bj6PyTNVe58he{WmDttesvCE`c2%O9y-r3{e(YtNp9CG=MiuHM6SQv zkB;r8Wn+63EWTlhfW-%FcK4rtYAEXyt4-C4WhY_C5t}pNGG>JlvSX>J&`YOSjpi-H z8Z@6EwxIcOu_n!*h;?XQLux?tTq%j>+ojqxzbVzDd4yb*=I!NJnopLQ{D7QD%ej&R zzPsXQh7Dh6427W@14XN9YSH{SZdXug@gl9C@3El5u<9t00h6z06BN*i>*-79e?+S`j|Eg=emQYoHpb!k^!zb;-i_b&_Iy6mB}GLK3TO z7S^^Zi1_P*4R=jOxYdCBca@0pBA6&!W42WLS7Ym6tL}2Y(g^}d@ji9DAH&q9)-f9) zf3|9Kkw$zMwCu@S7+I2P`0yVjGXC>&=0LcHeA))j0k41CU)fjy>m0QqZ9~c&bkx{^ zSfJt6LjU?^0|dsKb+Bd*59@Y9itqAo(tSKLM(e5`5_NqK#)_nBKE7S-PrHa7ZiBva zvD3~DqX^9WWxiN3_Ls0rd0KP!~Dj z8^SS~_?(sKO%+R7a2HROpX z&Viz{RK!*~h@a1$Z9E@Eei=l|4!QHyMC#M2JGG||#M=c)xO|uW+f;CVETcAApjLpN zQq9`s3%Dio0<<)HR++dVwM0(38KTK%j({84o`0JP4ntX`Iykfdha7SBJh38w%B_6m z420L4%vzsuM}p>a63$~4Cqu0hOqU#tgN%i$jUN6Xhu$E6q3V>nUtw}Q^H!eLcy=My z`0F1G4G*>$LAOYyH$n(ogq^ig6k*9?H5}e5g+~&&jfKN_B29@PKDh$ZM!t``)g(pw z_|(=#xh|Nv8OIvoCUjOSE)-T2S_Z;H&UtFqIqaFB~!0wYA#)EUUXcfCYyfx4tAK6Lrb!+Km&MiKG=knIa zShX;9GcKB>W5{{B<@k6@Qn*iJ?*3fnnEc_7dKed+cs{L(;DRUi71mm+MmS}THn z5qE$1yXfZ~n?&Fka4qG7>~jL&baA)@&&WZ!WvW7l?X=n5-+@=l@UHV&EF~ns!==18 zmMlZP6ZI)v4T`r~bddfbxA~07ptS@eldRSL)xsUdS&JrOSCQm9x0iLN3iaXTN4$>W zMl%*pctQP~F_~0lZdav{{@y!Kct5tRuxyfpT z?*?;t%4)SLZRJ)1-;eUZ4tQn}`NFgK zfIw13pQcZ0L%CtFa}5vEcU9b3H}JqUNl`xBSz~0jaNwaqt0x}8Ythp^)46QJV4I81 zHQI^^MAl=mM^6uUD$z;qDAcj-ha%3d!HP)oZN$(G-bw?e+njV>u%?$CV*K|E?z+pP zMb9;|wb;<*>VhDg3?%t>{mo~k3U4X+5%0Rq2>;CI9d>UWI^R{R;f;PvsRT{d^C%fc zeR}ICo_!{%g-?_w*u535J+bK_<3p}>YEISOdh~&$CO%rLDtff=tNR8ulD4!YYR=}< zSOrN*J_=$yS9oYsDtiLHW&`>h-q<4xhw2p+e^`ub3blAV{g>On;Vp?IUyHrlbFGUt z6c;Qnoi^PYj+}16rxuc$`?#>CucsOd6t_{z!DkzJOMMP>`e>PQJz6FRevbz`_C0jG zh5E##(ApH$+OnRypMKyhms$o~-a_RXcTXsFt@bPAl8G}CcVkmNfB`fc`uji1|_c)F2Br|nj(qxnH9YfXEM zHnyVqWXf|~#7OGs)7X^HICuR{9!Z~lA|LL-uQ`{TqlY!rq5sf~&zp<$AIjaRu% z6*_qy4EF2|n0yt77)d>SjGLbLLE3gToth+DPx<%+MpAVjT3?Npw7V+2zKyXZHzlfY z@!jfsTj6vgsf&+7l`t(N?@;?wTJBp^$u?JY6`O#`_aPy!H#S3b)PidbaTada#mD^a zU0Ct{kyg~Rrd5RZGg`fn2!tJ&G2Z^Eiuny;;4jI+DshgB>&y}!<*lmx>| zUmv21(2eOu-m>C%9eVoUO~*RfPJ^RGIA+fkdsrrz9?b{tH*>yQJqQOaN$q^9%=uOe zj}&J$7_f&wc`n+6wblQX!yCSKRD>6M_yS?wi!#G=E-Sj`h@umY#v<$c^K--T`#(vY zeCn7P;17HDs(ol@TK1s{YdA&P!fS(54>>LHVYO_zUYviRU@|_!lhn+|&bWAg;%jqH zkKXue{)q;yNod$ZVrQ!0~N%X0$ z`Ch6J1@7|vMUU(j!cPaVe{cNe4-q!CJiNHuLO6HoD~!?iXpHvILpOT8C6>x!Ali+S0XOy74#2@UoiHdT%V!6G z2)8;(T;p`uKWYf2o9u}A#p|G&T@9m12ZAIbvL{Sc;gEydT|(fY432@Tb`IYqa8bOj z@RI2L=1(dkZ~pQvDhe)iNm>};zzr!PNy9BH*;PYVm@HL-!-z&8>isH)C&^0xkMI{Q-bs%Exe3Ka=69?tDM|T(r}k0fkkE5kerIQj7xD&#AzSIUoekn|Rm1fq2jRRE&6qllOBjx}_ga6Y25*z6r6T*gQQTHDP z=@_YMA~6~ai(?Ij|1ikzqdX*02Wfe#vzpiT| z!%bSc8%+ZdSc_})kHw*L%txaIkxfy{fi9FAA{(Fblu{M4h5K*MsnL&-Q4p%OkpIAo zGofl@c|a2#1e8-7$XDCxplvxdS&nj0ar)r=^1vI)Xh{zLQ zY6Uf3Zr)apv$6ur3dKX;Sd9hzDehyuniKmIF!Piw#d%#(WH)iH1RYmg;f6#+msZod@|BW`gu&7A!a&pE=pQexco067Cs~zRE=XywqRtL)BO9EDePIw}e zMO2PKgD%kk$zO^sS>6A9=VR!OKNUto{uMCp?DbdUn&Jc%>;~7)f$M`T5f=i zlW~3&x0M1QAO-*An<~vF!l^r`uoi4@U25!Cfxfj}5M4$`5 zaHu3ftt}6}%}YgxBqKDdsn(E3-tj;cz+DrE-jUxuPyhrbqM56Ia;RUTnkXNA!AmdC zNj9jPfMNMM5ncKOYmK-smjhERwWU1PpO@y1!E?HnuW-R#Pz%kkHFA9Y2-ys3eT>5M zTBu!H<#_QODI6-dLOioJ;tOLuxCS<~l#Ng|tu#dQUP|5z#)N8|JM5L@snY^6bm%S@*-QL6Xu6%zI z8d};j04^n|z2xn^=tX(Rjgs{64Qc++x=6VE7RQTP$$Hpc7o+~PFNgZIz$d##aWZZa zG{Rs9*F%0te=h75k51t?G7F3)c>lCgJN49ha*IK{bSzO0gvE(yqI`YqgfSV^*YXhi zN-}#jX?}e)QEdnnhQWsW*hA=IygVe6Lsc56_2qxEO9?$iJPM~44CE9d}23aPXLT;s1A}1`vX91jGz8G&XgUbxzX~OgA}R+ z0~%r7J3pbNNGN`c!|i+{th;V8h0^6spK|5cck$1O)-*<0-e(+|@&^w2R|HBr8vr$$ zsQu+*=eVr*6O@_Pm&W(ICK!Yz7r8JfS#2c0{F0Xf|HNALjj-3&CL?Ryw;ca58SnBP zzQ@Kk#W&Yk*EqbpDZ&%4^U{OIqM0ezZ-&a#@9@~XI3ycjYBTih%smcu_yn6z>v=(_ z&mS_p@b%y9VB~DQ%8R=@o1N&b=@Q`U;^Z6)?o}zVQk11V7Gr*j%kEp9tWk zfI!I!16p9+eeg>WHL?0SnkcS^CdS|MF)=uVGmI_OI zZ)T*=;e}038=zThG~?<>5xPW1%P%^kau-cGm{>uhko_Acly8H2aoH5F07Z>828O>) zaG`+WiDU=E0zVSy!2)igT7M0GGir;2uwoI11{7$VjJmchQgRbi_UoWJdwjo7p*uEc6CO=@V6<{Tb_D|D#t)( z3RzA*4TO{~Y8Ch-1@(rW;H9E>{Q{s@U2IHz7kp%0bdKUZP27TB-u^7yPua z`;1>8m}d;l{6m{rxu%7*H!O@H~u?Ic`3ga&i{W3Jtf>*9g3~L-3tx2U(fON zd0IcHmx_>ikBPl$=1kW*px-p~dU2Ifue&ewsj}H8jJq7PPIyVQ=N;wRuJ^T-Ageb* z<324TIpBP6wY9wRR2gFbcMW~s!Z>#PnOphkvL*o5zJ*pa_c_$)nAQ&G`<8kX*a!Ki zo>5^4+#jnoLgzlnANrg^6<~889DOrh@KWpre1|SMhmHEJH-<2#FKREwl^)-%t3qyH z94J9LS_+0mSF|=b-4|`$Q_PSSW(b1LjdWJ_L{pN66R}=D)UJXXJXAQ~HU{B~L1=Xu z!LP?~{6STJJzVaGc8=HPQ2bpjE^GY}y4j3D%P#u+6$Y;GhkSzm*ntyEYT}a_F3wK4 z*B@<8-pz5>0DNP8YhRge0IZ+kuO+n`VKH%S#Q>y_`J2-(T6G$@GypA+d4jD=!CT)v4LnayB#ML*G0E1gK!Ae=*J;ED-{SigOK%Ex`$SMBVK5o!$=5hhR-z@PAgJkgFcPk9Hf1(8OvS+8`N1;5dO+#Fw%p+%mZ@ z8nh6XiGd#5oa1k2;w_^|2U@B}UY&Ti>xW^r^Ey&Ih-}~}kTMM4CeEgML#_yeKZM1g zRl0RR$8u(@!MjO4`+5|@*?4G@hvRBuJs;Z8OdH$Q+29JGgB%x5LYp-l{rKN3k1!BU z4#$T5vx!6TV+{ciJObO)X$Oajrl422@^KU6N1%yyd%4iE0EI(ll?qQ0;rc@!p%ctm zXg~TihX$-PRDuO0F4UiSS;!Z!c=!Qun($jaqmUEATN<3uw_>UNhS|s$UQ%IoSTqXz zeC}=OxcxC2ET(D}9G z4`&Eebv}ohT*F|9!<~WIBqhA z!nfnF8EwZPet3)r$BzuHjaDYyL4=D6yoI^>fd(e@AB)0Ir+W(c{@aiM<;Ldo`u<^(rebHNZZ9NW}`Qy>O7T@uN zb+gp|1Po*N1CMqftek*~6&`vZf9QW4+x5=`RCGM{#`Dh@bg5^u2g?^1>vovH9wy8phH)Fu>*jYLE&?GtH$Y>J? zZBL{(?f1vVAT~5ZU;5Oiuf}POUmEGV0Jm|kR-m_ASJFAnTszR|<^7zuu`0(ZF8nDe z5TC8z#&%DB4cF%3GPqE?pZk*71x}ictt2#5f}<{CSx~irXYUr zBE{d5Cx1mRa5rglpcaOXK!TeP+TG#?A5Os`)AUzfn)*GOFFzH{XXhhp(;pnae>%_z z;|YF-;Bo^ebFN9CDFXWCqt&x!lXr6uHR24*V*}NUm&4vgh-}aoPgT3gC*Sjw9C(k! zbEcgOu-)~ydT=}JAkbF_Jdg>@%T4}JGzXu9)oCbf_{qP7PMA*c?@xH+;mh#g@0@Aq zXRG&o{H%3}({MvSoUKcJreh1muRXXEI(%T#!H(%TOieePWP3jpHXJeGljTPyEtqB? z{>85z+yDb+pa-GPITZhu$q)K`VY0!v;pl;S$;SgfL1h*Rtz7IN^1oPhZs$k-u3z{V R|7O3^W - + + + From 20c2cf49ed0a20d3509c0062da02ac0455d186ab Mon Sep 17 00:00:00 2001 From: Maxim Shafirov Date: Wed, 23 Dec 2009 21:43:56 +0300 Subject: [PATCH 08/67] Some dependencies normalized. CIDR build continues --- build/lib/gant/lib/jps.jar | Bin 1554511 -> 1563342 bytes .../psi/UpdateJspxFileCopyright.java | 6 +++--- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/build/lib/gant/lib/jps.jar b/build/lib/gant/lib/jps.jar index 493e6b120b894931c277949ea5a98c629968e3b1..2aed07e9be5973af30b55428422603eeccec54b8 100644 GIT binary patch delta 33775 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 delta 30197 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 PVOnZ44$!E4GvEIQ%L@3j diff --git a/plugins/copyright/src/com/maddyhome/idea/copyright/psi/UpdateJspxFileCopyright.java b/plugins/copyright/src/com/maddyhome/idea/copyright/psi/UpdateJspxFileCopyright.java index a5d2a4fcbdd9..77e0976f41e2 100644 --- a/plugins/copyright/src/com/maddyhome/idea/copyright/psi/UpdateJspxFileCopyright.java +++ b/plugins/copyright/src/com/maddyhome/idea/copyright/psi/UpdateJspxFileCopyright.java @@ -22,9 +22,9 @@ import com.intellij.openapi.project.Project; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.PsiComment; import com.intellij.psi.PsiElement; -import com.intellij.psi.jsp.JspFile; import com.intellij.psi.xml.XmlDoctype; import com.intellij.psi.xml.XmlDocument; +import com.intellij.psi.xml.XmlFile; import com.intellij.psi.xml.XmlProlog; import com.maddyhome.idea.copyright.CopyrightProfile; import com.maddyhome.idea.copyright.options.XmlOptions; @@ -39,7 +39,7 @@ public class UpdateJspxFileCopyright extends UpdateJspFileCopyright { protected void scanFile() { logger.debug("updating " + getFile().getVirtualFile()); - XmlDocument doc = ((JspFile)getFile()).getDocument(); + XmlDocument doc = ((XmlFile)getFile()).getDocument(); XmlProlog xmlProlog = doc.getProlog(); if (xmlProlog == null) { return; @@ -77,4 +77,4 @@ public class UpdateJspxFileCopyright extends UpdateJspFileCopyright { } private static final Logger logger = Logger.getInstance(UpdateJspxFileCopyright.class.getName()); -} \ No newline at end of file +} From 242a6a014c7e7e0647e824238396af12e0fb3ee8 Mon Sep 17 00:00:00 2001 From: Dmitry Jemerov Date: Thu, 24 Dec 2009 13:55:47 +0300 Subject: [PATCH 09/67] report plugin name as well as version --- .../platform-impl/src/com/intellij/diagnostic/ITNReporter.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/platform-impl/src/com/intellij/diagnostic/ITNReporter.java b/platform/platform-impl/src/com/intellij/diagnostic/ITNReporter.java index 5e34a23317bf..7a88fb799950 100644 --- a/platform/platform-impl/src/com/intellij/diagnostic/ITNReporter.java +++ b/platform/platform-impl/src/com/intellij/diagnostic/ITNReporter.java @@ -110,7 +110,7 @@ public class ITNReporter extends ErrorReportSubmitter { if (pluginId != null) { final IdeaPluginDescriptor ideaPluginDescriptor = ApplicationManager.getApplication().getPlugin(pluginId); if (ideaPluginDescriptor != null && !ideaPluginDescriptor.isBundled()) { - descBuilder.append("Plugin version: ").append(ideaPluginDescriptor.getVersion()).append("\n"); + descBuilder.append("Plugin ").append(ideaPluginDescriptor.getName()).append(" version: ").append(ideaPluginDescriptor.getVersion()).append("\n"); } } } From fa0fd10068644af860392db905d276b152a6f03c Mon Sep 17 00:00:00 2001 From: Alexey Kudravtsev Date: Thu, 24 Dec 2009 19:35:50 +0300 Subject: [PATCH 10/67] project leak --- .../util/src/com/intellij/CommonBundle.java | 1 + .../src/org/jetbrains/idea/svn/SvnBundle.java | 4 ++ .../idea/svn/SvnFileSystemListener.java | 72 ++++++++----------- .../svn/SvnFileSystemListenerWrapper.java | 28 +++++--- 4 files changed, 52 insertions(+), 53 deletions(-) diff --git a/platform/util/src/com/intellij/CommonBundle.java b/platform/util/src/com/intellij/CommonBundle.java index e64c62028df4..237517c32866 100644 --- a/platform/util/src/com/intellij/CommonBundle.java +++ b/platform/util/src/com/intellij/CommonBundle.java @@ -142,4 +142,5 @@ public class CommonBundle { public static String getApplyButtonText() { return CommonBundle.message("button.apply"); } + } diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnBundle.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnBundle.java index fe11edb9d933..d74e63803a51 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnBundle.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnBundle.java @@ -35,6 +35,10 @@ public class SvnBundle { return CommonBundle.message(getBundle(), key, params); } + public static String getString(@PropertyKey(resourceBundle = BUNDLE)String key) { + return getBundle().getString(key); + } + private static ResourceBundle getBundle() { ResourceBundle bundle = null; if (ourBundle != null) bundle = ourBundle.get(); diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnFileSystemListener.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnFileSystemListener.java index 0badc99b2125..ccd5b6e1575d 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnFileSystemListener.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnFileSystemListener.java @@ -17,8 +17,8 @@ package org.jetbrains.idea.svn; +import com.intellij.openapi.command.CommandAdapter; import com.intellij.openapi.command.CommandEvent; -import com.intellij.openapi.command.CommandListener; import com.intellij.openapi.command.undo.UndoManager; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.progress.ProgressManager; @@ -52,9 +52,9 @@ import java.io.File; import java.io.IOException; import java.util.*; -public class SvnFileSystemListener implements LocalFileOperationsHandler, CommandListener { +public class SvnFileSystemListener extends CommandAdapter implements LocalFileOperationsHandler { private static final Logger LOG = Logger.getInstance("#org.jetbrains.idea.svn.SvnFileSystemListener"); - private LocalFileSystem myLfs; + private final LocalFileSystem myLfs; private static class AddedFileInfo { private final Project myProject; @@ -138,7 +138,7 @@ public class SvnFileSystemListener implements LocalFileOperationsHandler, Comman File srcFile = new File(file.getPath()); File destFile = new File(new File(toDir.getPath()), copyName); final boolean dstDirUnderControl = SVNWCUtil.isVersionedDirectory(destFile.getParentFile()); - if ((! dstDirUnderControl) && !isPendingAdd(toDir)) { + if (! dstDirUnderControl && !isPendingAdd(toDir)) { return null; } @@ -167,7 +167,7 @@ public class SvnFileSystemListener implements LocalFileOperationsHandler, Comman final String srcUUID = helper.getRepositoryUUID(srcDir); final String dstUUID = helper.getRepositoryUUID(dstDir); - return (srcUUID != null) && (dstUUID != null) && (srcUUID.equals(dstUUID)); + return srcUUID != null && dstUUID != null && srcUUID.equals(dstUUID); } private class UUIDHelper { @@ -184,7 +184,7 @@ public class SvnFileSystemListener implements LocalFileOperationsHandler, Comman public String getRepositoryUUID(final VirtualFile dir) { try { final SVNInfo info1 = myWcClient.doInfo(new File(dir.getPath()), SVNRevision.WORKING); - if ((info1 == null) || (info1.getRepositoryUUID() == null)) { + if (info1 == null || info1.getRepositoryUUID() == null) { // go deeper if current parent was added (if parent was added, it theoretically could NOT know its repo UUID) final VirtualFile parent = dir.getParent(); if (parent == null) { @@ -333,14 +333,12 @@ public class SvnFileSystemListener implements LocalFileOperationsHandler, Comman if (!SVNWCUtil.isVersionedDirectory(ioFile.getParentFile())) { return false; } - else { - try { - if (SVNWCUtil.isWorkingCopyRoot(ioFile)) { - return false; - } - } catch (SVNException e) { - // - } + try { + if (SVNWCUtil.isWorkingCopyRoot(ioFile)) { + return false; + } + } catch (SVNException e) { + // } SVNStatus status = getFileStatus(ioFile); @@ -352,7 +350,7 @@ public class SvnFileSystemListener implements LocalFileOperationsHandler, Comman status.getContentsStatus() == SVNStatusType.STATUS_EXTERNAL) { return false; } else if (status.getContentsStatus() == SVNStatusType.STATUS_IGNORED) { - if (vcs != null && (file.getParent() != null)) { + if (vcs != null && file.getParent() != null) { if (! isUndoOrRedo(vcs.getProject())) { putIgnoreInfo(file, vcs, ioFile); } @@ -437,7 +435,7 @@ public class SvnFileSystemListener implements LocalFileOperationsHandler, Comman * deleted: 'undo' mode: try to revert non-recursively, if kind is the same, otherwise do nothing, return false. * anything else: return false. */ - private boolean createItem(VirtualFile dir, String name, boolean directory, final boolean recursive) throws IOException { + private boolean createItem(VirtualFile dir, String name, boolean directory, final boolean recursive) { SvnVcs vcs = getVCS(dir); if (vcs == null) { return false; @@ -464,7 +462,7 @@ public class SvnFileSystemListener implements LocalFileOperationsHandler, Comman else if (status.getContentsStatus() == SVNStatusType.STATUS_DELETED) { SVNNodeKind kind = status.getKind(); // kind differs. - if ((directory && kind != SVNNodeKind.DIR) || (!directory && kind != SVNNodeKind.FILE)) { + if (directory && kind != SVNNodeKind.DIR || !directory && kind != SVNNodeKind.FILE) { return false; } try { @@ -505,9 +503,6 @@ public class SvnFileSystemListener implements LocalFileOperationsHandler, Comman myIgnoredInfo.remove(project); } - public void beforeCommandFinished(CommandEvent event) { - } - public void commandFinished(CommandEvent event) { final Project project = event.getProject(); if (project == null) return; @@ -515,22 +510,22 @@ public class SvnFileSystemListener implements LocalFileOperationsHandler, Comman } void commandFinished(final Project project) { - if (myAddedFiles.size() > 0) { + if (!myAddedFiles.isEmpty()) { processAddedFiles(project); } - if (myDeletedFiles.size() > 0) { + if (!myDeletedFiles.isEmpty()) { processDeletedFiles(project); } processMovedFiles(project); final List exceptionList = myMoveExceptions.get(project); - if ((exceptionList != null) && (! exceptionList.isEmpty())) { + if (exceptionList != null && ! exceptionList.isEmpty()) { AbstractVcsHelper.getInstance(project).showErrors(exceptionList, SvnBundle.message("move.files.errors.title")); } dealWithIgnorePatterns(project); - if (myFilesToRefresh.size() > 0) { + if (!myFilesToRefresh.isEmpty()) { refreshFiles(project); } } @@ -558,7 +553,7 @@ public class SvnFileSystemListener implements LocalFileOperationsHandler, Comman final SelectIgnorePatternsToRemoveOnDeleteDialog dialog = new SelectIgnorePatternsToRemoveOnDeleteDialog(project, map); dialog.show(); final Collection result = dialog.getResult(); - if ((dialog.getExitCode() == DialogWrapper.OK_EXIT_CODE) && (! result.isEmpty())) { + if (dialog.getExitCode() == DialogWrapper.OK_EXIT_CODE && ! result.isEmpty()) { final List exceptions = new ArrayList(0); final Runnable deletePatterns = new Runnable() { @@ -611,10 +606,10 @@ public class SvnFileSystemListener implements LocalFileOperationsHandler, Comman myFilesToRefresh.clear(); } - private void filterOutInvalid(final Collection files) { + private static void filterOutInvalid(final Collection files) { for (Iterator iterator = files.iterator(); iterator.hasNext();) { final VirtualFile file = iterator.next(); - if ((! file.isValid()) || (! file.exists())) { + if (! file.isValid() || ! file.exists()) { LOG.info("Refresh root is not valid: " + file.getPath()); iterator.remove(); } @@ -650,7 +645,7 @@ public class SvnFileSystemListener implements LocalFileOperationsHandler, Comman } } } - if (addedVFiles.size() == 0) return; + if (addedVFiles.isEmpty()) return; final VcsShowConfirmationOption.Value value = vcs.getAddConfirmation().getValue(); if (value != VcsShowConfirmationOption.Value.DO_NOTHING_SILENTLY) { final AbstractVcsHelper vcsHelper = AbstractVcsHelper.getInstance(project); @@ -661,10 +656,10 @@ public class SvnFileSystemListener implements LocalFileOperationsHandler, Comman else { final String singleFilePrompt; if (addedVFiles.size() == 1 && addedVFiles.get(0).isDirectory()) { - singleFilePrompt = SvnBundle.message("confirmation.text.add.dir"); + singleFilePrompt = SvnBundle.getString("confirmation.text.add.dir"); } else { - singleFilePrompt = SvnBundle.message("confirmation.text.add.file"); + singleFilePrompt = SvnBundle.getString("confirmation.text.add.file"); } filesToProcess = vcsHelper.selectFilesToProcess(addedVFiles, SvnBundle.message("confirmation.title.add.multiple.files"), null, @@ -685,8 +680,7 @@ public class SvnFileSystemListener implements LocalFileOperationsHandler, Comman protected void executeInternal() throws VcsException { try { // not recursive - final SVNCopySource[] copySource = new SVNCopySource[] - {new SVNCopySource(SVNRevision.WORKING, SVNRevision.WORKING, copyFrom)}; + final SVNCopySource[] copySource = {new SVNCopySource(SVNRevision.WORKING, SVNRevision.WORKING, copyFrom)}; copyClient.doCopy(copySource, ioFile, false, true, true); } catch (SVNException e) { @@ -725,7 +719,7 @@ public class SvnFileSystemListener implements LocalFileOperationsHandler, Comman deletedFiles.add(filePath); } } - if (deletedFiles.size() == 0 || myUndoingMove) return; + if (deletedFiles.isEmpty() || myUndoingMove) return; SvnVcs vcs = SvnVcs.getInstance(project); final VcsShowConfirmationOption.Value value = vcs.getDeleteConfirmation().getValue(); if (value != VcsShowConfirmationOption.Value.DO_NOTHING_SILENTLY) { @@ -738,15 +732,15 @@ public class SvnFileSystemListener implements LocalFileOperationsHandler, Comman final String singleFilePrompt; if (deletedFiles.size() == 1 && deletedFiles.get(0).isDirectory()) { - singleFilePrompt = SvnBundle.message("confirmation.text.delete.dir"); + singleFilePrompt = SvnBundle.getString("confirmation.text.delete.dir"); } else { - singleFilePrompt = SvnBundle.message("confirmation.text.delete.file"); + singleFilePrompt = SvnBundle.getString("confirmation.text.delete.file"); } final Collection files = vcsHelper .selectFilePathsToProcess(deletedFiles, SvnBundle.message("confirmation.title.delete.multiple.files"), null, SvnBundle.message("confirmation.title.delete.file"), singleFilePrompt, vcs.getDeleteConfirmation()); - filesToProcess = (files == null) ? null : new ArrayList(files); + filesToProcess = files == null ? null : new ArrayList(files); } if (filesToProcess != null) { List exceptions = new ArrayList(); @@ -797,12 +791,6 @@ public class SvnFileSystemListener implements LocalFileOperationsHandler, Comman } } - public void undoTransparentActionStarted() { - } - - public void undoTransparentActionFinished() { - } - @Nullable private static SvnVcs getVCS(VirtualFile file) { Project[] projects = ProjectManager.getInstance().getOpenProjects(); diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnFileSystemListenerWrapper.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnFileSystemListenerWrapper.java index 1e640efc183a..6bf4014d442d 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnFileSystemListenerWrapper.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnFileSystemListenerWrapper.java @@ -15,11 +15,13 @@ */ package org.jetbrains.idea.svn; +import com.intellij.openapi.Disposable; import com.intellij.openapi.command.CommandEvent; import com.intellij.openapi.command.CommandListener; import com.intellij.openapi.command.CommandProcessor; import com.intellij.openapi.project.Project; import com.intellij.openapi.project.ProjectLocator; +import com.intellij.openapi.util.Disposer; import com.intellij.openapi.util.Pair; import com.intellij.openapi.vfs.LocalFileOperationsHandler; import com.intellij.openapi.vfs.LocalFileSystem; @@ -66,13 +68,13 @@ public class SvnFileSystemListenerWrapper { } public void start(final Project project) { - if ((! myInCommand) && (project != null)) { + if (!myInCommand && project != null) { myDelegate.commandStarted(project); } } public void finish(final Project project) { - if ((! myInCommand) && (project != null)) { + if (! myInCommand && project != null) { myDelegate.commandFinished(project); } } @@ -115,7 +117,7 @@ public class SvnFileSystemListenerWrapper { } @Nullable - private Project getProject(Object[] args) { + private static Project getProject(Object[] args) { for (Object arg : args) { if (arg instanceof VirtualFile) { return ProjectLocator.getInstance().guessProjectForFile((VirtualFile) arg); @@ -128,7 +130,7 @@ public class SvnFileSystemListenerWrapper { final Project project = getProject(args); if (project != null) { final Pair pair = myStarted.get(project); - if ((pair != null) && method.getName().equals(pair.getFirst()) && Arrays.equals(args, pair.getSecond())) { + if (pair != null && method.getName().equals(pair.getFirst()) && Arrays.equals(args, pair.getSecond())) { myMarker.finish(project); } } @@ -136,13 +138,18 @@ public class SvnFileSystemListenerWrapper { return "boolean".equals(method.getReturnType().getName()) ? Boolean.TRUE : null; } - public void register(final Method method, final Object[] args) { + private void register(final Method method, final Object[] args) { final Object[] newArr = new Object[args.length]; System.arraycopy(args, 0, newArr, 0, args.length); final Project project = getProject(args); if (project != null) { myMarker.start(project); myStarted.put(project, new Pair(method.getName(), newArr)); + Disposer.register(project, new Disposable() { + public void dispose() { + myStarted.remove(project); + } + }); } } } @@ -160,11 +167,9 @@ public class SvnFileSystemListenerWrapper { } public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { - if ("afterDone".equals(method.getName())) { - if (args.length == 1) { - ((ThrowableConsumer) args[0]).consume(myParentProxy); - return null; - } + if ("afterDone".equals(method.getName()) && args.length == 1) { + ((ThrowableConsumer)args[0]).consume(myParentProxy); + return null; } if (LocalFileOperationsHandler.class.equals(method.getDeclaringClass())) { @@ -172,7 +177,8 @@ public class SvnFileSystemListenerWrapper { } if ("equals".equals(method.getName())) { return args[0].equals(this); - } else if ("hashCode".equals(method.getName())) { + } + else if ("hashCode".equals(method.getName())) { return 1; } return method.invoke(myDelegate, args); From 20f27d546802088f1671b982422d7eb58be7e59c Mon Sep 17 00:00:00 2001 From: Dmitry Jemerov Date: Thu, 24 Dec 2009 19:44:33 +0300 Subject: [PATCH 11/67] convert test to PyLightFixtureTestCase --- .../fixtures/impl/CodeInsightTestFixtureImpl.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/platform/testFramework/src/com/intellij/testFramework/fixtures/impl/CodeInsightTestFixtureImpl.java b/platform/testFramework/src/com/intellij/testFramework/fixtures/impl/CodeInsightTestFixtureImpl.java index 6e0b84b903a1..2ea7bf964393 100644 --- a/platform/testFramework/src/com/intellij/testFramework/fixtures/impl/CodeInsightTestFixtureImpl.java +++ b/platform/testFramework/src/com/intellij/testFramework/fixtures/impl/CodeInsightTestFixtureImpl.java @@ -409,7 +409,8 @@ public class CodeInsightTestFixtureImpl extends BaseFixture implements CodeInsig } public List filterAvailableIntentions(@NotNull final String hint) throws Exception { - return ContainerUtil.findAll(getAvailableIntentions(),new Condition() { + final List availableIntentions = getAvailableIntentions(); + return ContainerUtil.findAll(availableIntentions, new Condition() { public boolean value(final IntentionAction intentionAction) { return intentionAction.getText().startsWith(hint); } From e3e0dec80adb67044ea1f25e3a58ce87e9ca187a Mon Sep 17 00:00:00 2001 From: Maxim Shafirov Date: Thu, 24 Dec 2009 22:15:42 +0300 Subject: [PATCH 12/67] JPS: Module's testRuntimeClasspath() now includes its test compile output. --- build/lib/gant/lib/jps.jar | Bin 1563342 -> 1563414 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/build/lib/gant/lib/jps.jar b/build/lib/gant/lib/jps.jar index 2aed07e9be5973af30b55428422603eeccec54b8..5a618983c6364840b3eae55cbcd2281eced3b1e4 100644 GIT binary patch delta 19564 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 Date: Fri, 25 Dec 2009 09:57:07 +0300 Subject: [PATCH 13/67] namespace vs location --- .../codeInsight/daemon/impl/quickfix/BaseExtResourceAction.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/xml/impl/src/com/intellij/codeInsight/daemon/impl/quickfix/BaseExtResourceAction.java b/xml/impl/src/com/intellij/codeInsight/daemon/impl/quickfix/BaseExtResourceAction.java index e695f9f07c7d..18215cba6ba1 100644 --- a/xml/impl/src/com/intellij/codeInsight/daemon/impl/quickfix/BaseExtResourceAction.java +++ b/xml/impl/src/com/intellij/codeInsight/daemon/impl/quickfix/BaseExtResourceAction.java @@ -43,7 +43,7 @@ abstract class BaseExtResourceAction extends BaseIntentionAction { if (uri == null) return false; - XmlFile xmlFile = XmlUtil.findNamespace(file, uri); + XmlFile xmlFile = XmlUtil.findNamespaceByLocation(file, uri); if (xmlFile != null) return false; if (!isAcceptableUri(uri)) return false; setText(XmlBundle.message(getQuickFixKeyId())); From 63385baeb23e42e215ff2b346ac4d933b96f790b Mon Sep 17 00:00:00 2001 From: Dmitry Avdeev Date: Fri, 25 Dec 2009 09:57:21 +0300 Subject: [PATCH 14/67] namespace vs location --- .../impl/source/xml/XmlEntityDeclImpl.java | 4 +-- .../com/intellij/xml/DefaultXmlExtension.java | 5 ++-- .../xml/impl/schema/XmlNSDescriptorImpl.java | 12 ++++----- .../xml/index/IndexedRelevantResource.java | 19 +++++++++++--- .../intellij/xml/index/ResourceRelevance.java | 19 ++++++++------ .../intellij/xml/index/XmlNamespaceIndex.java | 17 ++++++------ .../src/com/intellij/xml/util/XmlUtil.java | 26 ++++++++++++------- .../com/intellij/xml/XmlSchemaProvider.java | 8 +++--- 8 files changed, 66 insertions(+), 44 deletions(-) diff --git a/xml/impl/src/com/intellij/psi/impl/source/xml/XmlEntityDeclImpl.java b/xml/impl/src/com/intellij/psi/impl/source/xml/XmlEntityDeclImpl.java index 9fdf0b8b9fb6..1b3df38dd743 100644 --- a/xml/impl/src/com/intellij/psi/impl/source/xml/XmlEntityDeclImpl.java +++ b/xml/impl/src/com/intellij/psi/impl/source/xml/XmlEntityDeclImpl.java @@ -254,14 +254,14 @@ public class XmlEntityDeclImpl extends XmlElementImpl implements XmlEntityDecl, if (attributeValue != null) { final String value = attributeValue.getValue(); if (value != null) { - XmlFile xmlFile = XmlUtil.findNamespace(baseFile, value); + XmlFile xmlFile = XmlUtil.findNamespaceByLocation(baseFile, value); if (xmlFile != null) { return xmlFile; } final int i = URIReferenceProvider.getPrefixLength(value); if (i > 0) { - return XmlUtil.findNamespace(baseFile, value.substring(i)); + return XmlUtil.findNamespaceByLocation(baseFile, value.substring(i)); } } } diff --git a/xml/impl/src/com/intellij/xml/DefaultXmlExtension.java b/xml/impl/src/com/intellij/xml/DefaultXmlExtension.java index 364472a70e56..6ff7f6e00816 100644 --- a/xml/impl/src/com/intellij/xml/DefaultXmlExtension.java +++ b/xml/impl/src/com/intellij/xml/DefaultXmlExtension.java @@ -16,6 +16,7 @@ package com.intellij.xml; import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.module.ModuleUtil; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Pair; import com.intellij.openapi.util.text.StringUtil; @@ -115,7 +116,7 @@ public class DefaultXmlExtension extends XmlExtension { } @NotNull - public Set guessUnboundNamespaces(@NotNull final PsiElement element, final XmlFile file) { + public Set guessUnboundNamespaces(@NotNull final PsiElement element, @NotNull XmlFile file) { if (!(element instanceof XmlTag)) { return Collections.emptySet(); } @@ -132,7 +133,7 @@ public class DefaultXmlExtension extends XmlExtension { final XmlTag parentTag = tag.getParentTag(); ns: for (Iterator i = set.iterator(); i.hasNext();) { final String s = i.next(); - final Collection namespaces = XmlUtil.findNSFilesByURI(s, element.getProject()); + final Collection namespaces = XmlUtil.findNSFilesByURI(s, element.getProject(), ModuleUtil.findModuleForPsiElement(file)); for (XmlFile namespace : namespaces) { final XmlDocument document = namespace.getDocument(); assert document != null; diff --git a/xml/impl/src/com/intellij/xml/impl/schema/XmlNSDescriptorImpl.java b/xml/impl/src/com/intellij/xml/impl/schema/XmlNSDescriptorImpl.java index 0e2b4ecaca2c..d1a88adfbb01 100644 --- a/xml/impl/src/com/intellij/xml/impl/schema/XmlNSDescriptorImpl.java +++ b/xml/impl/src/com/intellij/xml/impl/schema/XmlNSDescriptorImpl.java @@ -90,7 +90,7 @@ public class XmlNSDescriptorImpl implements XmlNSDescriptor,Validator implements Comparable> { - public static List> getResources(ID indexId, final K key, @NotNull final Module module) { + public static final Function,VirtualFile> MAPPING = new Function, VirtualFile>() { + public VirtualFile fun(IndexedRelevantResource resource) { + return resource.getFile(); + } + }; + + public static List> getResources(ID indexId, + final K key, + @Nullable final Module module, + @NotNull Project project) { final ArrayList> resources = new ArrayList>(); - final ProjectFileIndex fileIndex = ProjectRootManager.getInstance(module.getProject()).getFileIndex(); + final ProjectFileIndex fileIndex = ProjectRootManager.getInstance(project).getFileIndex(); FileBasedIndex.getInstance().processValues(indexId, key, null, new FileBasedIndex.ValueProcessor() { public boolean process(VirtualFile file, V value) { ResourceRelevance relevance = ResourceRelevance.getRelevance(file, module, fileIndex); @@ -48,7 +59,7 @@ public class IndexedRelevantResource implements Compara } return true; } - }, new AdditionalIndexedRootsScope(GlobalSearchScope.allScope(module.getProject()))); + }, new AdditionalIndexedRootsScope(GlobalSearchScope.allScope(project))); return resources; } @@ -58,7 +69,7 @@ public class IndexedRelevantResource implements Compara ArrayList> all = new ArrayList>(); Collection allKeys = FileBasedIndex.getInstance().getAllKeys(indexId, module.getProject()); for (K key : allKeys) { - List> resources = getResources(indexId, key, module); + List> resources = getResources(indexId, key, module, module.getProject()); if (!resources.isEmpty()) { if (chooser == null) { all.add(resources.get(0)); diff --git a/xml/impl/src/com/intellij/xml/index/ResourceRelevance.java b/xml/impl/src/com/intellij/xml/index/ResourceRelevance.java index f1833e5ab1d2..1c787d3f1516 100644 --- a/xml/impl/src/com/intellij/xml/index/ResourceRelevance.java +++ b/xml/impl/src/com/intellij/xml/index/ResourceRelevance.java @@ -22,6 +22,7 @@ import com.intellij.openapi.module.ModuleManager; import com.intellij.openapi.roots.OrderEntry; import com.intellij.openapi.roots.ProjectFileIndex; import com.intellij.openapi.vfs.VirtualFile; +import org.jetbrains.annotations.Nullable; import java.util.List; @@ -36,19 +37,21 @@ public enum ResourceRelevance { SOURCE, MAPPED; - public static ResourceRelevance getRelevance(VirtualFile file, Module module, ProjectFileIndex fileIndex) { - Module moduleForFile = fileIndex.getModuleForFile(file); - if (moduleForFile != null) { // in module content - return module.equals(moduleForFile) || ModuleManager.getInstance(module.getProject()).isModuleDependent(module, moduleForFile) ? SOURCE : NONE; + public static ResourceRelevance getRelevance(VirtualFile file, @Nullable Module module, ProjectFileIndex fileIndex) { + if (module != null) { + Module moduleForFile = fileIndex.getModuleForFile(file); + if (moduleForFile != null) { // in module content + return module.equals(moduleForFile) || ModuleManager.getInstance(module.getProject()).isModuleDependent(module, moduleForFile) ? SOURCE : NONE; + } } if (fileIndex.isInLibraryClasses(file)) { List orderEntries = fileIndex.getOrderEntriesForFile(file); if (orderEntries.isEmpty()) { return NONE; } - for (OrderEntry orderEntry : orderEntries) { - Module ownerModule = orderEntry.getOwnerModule(); - if (ownerModule != null) { + if (module != null) { + for (OrderEntry orderEntry : orderEntries) { + Module ownerModule = orderEntry.getOwnerModule(); if (ownerModule.equals(module)) { return LIBRARY; } @@ -59,7 +62,7 @@ public enum ResourceRelevance { if (resourceManager.isUserResource(file)) { return MAPPED; } - if (resourceManager.isStandardResource(file)) { + if (ExternalResourceManagerImpl.isStandardResource(file)) { return STANDARD; } return NONE; diff --git a/xml/impl/src/com/intellij/xml/index/XmlNamespaceIndex.java b/xml/impl/src/com/intellij/xml/index/XmlNamespaceIndex.java index a3a66f1b4063..acc93470cc5d 100644 --- a/xml/impl/src/com/intellij/xml/index/XmlNamespaceIndex.java +++ b/xml/impl/src/com/intellij/xml/index/XmlNamespaceIndex.java @@ -15,6 +15,7 @@ */ package com.intellij.xml.index; +import com.intellij.openapi.module.Module; import com.intellij.openapi.project.Project; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.util.indexing.DataIndexer; @@ -22,11 +23,11 @@ import com.intellij.util.indexing.FileBasedIndex; import com.intellij.util.indexing.FileContent; import com.intellij.util.indexing.ID; import com.intellij.util.io.DataExternalizer; -import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.io.ByteArrayInputStream; -import java.util.Collection; +import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -34,7 +35,7 @@ import java.util.Map; /** * @author Dmitry Avdeev */ -public class XmlNamespaceIndex extends XmlIndex{ +public class XmlNamespaceIndex extends XmlIndex { @Nullable public static String getNamespace(VirtualFile file, final Project project) { @@ -42,14 +43,12 @@ public class XmlNamespaceIndex extends XmlIndex{ return list.size() == 0 ? null : list.get(0); } - public static Collection getFilesByNamespace(String namespace, final Project project) { - return FileBasedIndex.getInstance().getContainingFiles(NAME, namespace, createFilter(project)); + public static List> getResourcesByNamespace(String namespace, final Project project, Module module) { + List> resources = IndexedRelevantResource.getResources(NAME, namespace, module, project); + Collections.sort(resources); + return resources; } - static void requestRebuild() { - FileBasedIndex.getInstance().requestRebuild(NAME); - } - private static final ID NAME = ID.create("XmlNamespaces"); public ID getName() { diff --git a/xml/impl/src/com/intellij/xml/util/XmlUtil.java b/xml/impl/src/com/intellij/xml/util/XmlUtil.java index 3c44af23d7f2..e7297e1ec1ba 100644 --- a/xml/impl/src/com/intellij/xml/util/XmlUtil.java +++ b/xml/impl/src/com/intellij/xml/util/XmlUtil.java @@ -31,6 +31,8 @@ import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.extensions.Extensions; import com.intellij.openapi.fileTypes.FileType; import com.intellij.openapi.fileTypes.StdFileTypes; +import com.intellij.openapi.module.Module; +import com.intellij.openapi.module.ModuleUtil; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Key; import com.intellij.openapi.util.Pair; @@ -63,6 +65,7 @@ import com.intellij.xml.impl.schema.ComplexTypeDescriptor; import com.intellij.xml.impl.schema.TypeDescriptor; import com.intellij.xml.impl.schema.XmlElementDescriptorImpl; import com.intellij.xml.impl.schema.XmlNSDescriptorImpl; +import com.intellij.xml.index.IndexedRelevantResource; import com.intellij.xml.index.XmlNamespaceIndex; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; @@ -239,16 +242,21 @@ public class XmlUtil { return xmlFile == null ? findXmlFile(base, location) : xmlFile; } - public static Collection findNSFilesByURI(String namespace, final Project project) { - final Collection files = XmlNamespaceIndex.getFilesByNamespace(namespace, project); - final ArrayList list = new ArrayList(files.size()); - for (VirtualFile file : files) { - final PsiFile psiFile = PsiManager.getInstance(project).findFile(file); - if (psiFile instanceof XmlFile) { - list.add((XmlFile)psiFile); + @Nullable + public static XmlFile findNamespaceByLocation(PsiFile base, @NotNull String nsLocation) { + final String location = ExternalResourceManager.getInstance().getResourceLocation(nsLocation, base.getProject()); + return findXmlFile(base, location); + } + + public static Collection findNSFilesByURI(String namespace, final Project project, Module module) { + final List> resources = XmlNamespaceIndex.getResourcesByNamespace(namespace, project, module); + final PsiManager psiManager = PsiManager.getInstance(project); + return ContainerUtil.mapNotNull(resources, new NullableFunction, XmlFile>() { + public XmlFile fun(IndexedRelevantResource stringStringIndexedRelevantResource) { + PsiFile file = psiManager.findFile(stringStringIndexedRelevantResource.getFile()); + return file instanceof XmlFile ? (XmlFile)file : null; } - } - return list; + }); } @Nullable diff --git a/xml/openapi/src/com/intellij/xml/XmlSchemaProvider.java b/xml/openapi/src/com/intellij/xml/XmlSchemaProvider.java index 8f5704584595..c6b6322f5913 100644 --- a/xml/openapi/src/com/intellij/xml/XmlSchemaProvider.java +++ b/xml/openapi/src/com/intellij/xml/XmlSchemaProvider.java @@ -43,7 +43,7 @@ public abstract class XmlSchemaProvider { public final static ExtensionPointName EP_NAME = new ExtensionPointName("com.intellij.xml.schemaProvider"); @Nullable - public static XmlFile findSchema(@NotNull @NonNls String url, @Nullable Module module, @NotNull PsiFile file) { + public static XmlFile findSchema(@NotNull @NonNls String namespace, @Nullable Module module, @NotNull PsiFile file) { final boolean dumb = DumbService.getInstance(file.getProject()).isDumb(); for (XmlSchemaProvider provider: Extensions.getExtensions(EP_NAME)) { @@ -54,7 +54,7 @@ public abstract class XmlSchemaProvider { if (file instanceof XmlFile && !provider.isAvailable((XmlFile)file)) { continue; } - final XmlFile schema = provider.getSchema(url, module, file); + final XmlFile schema = provider.getSchema(namespace, module, file); if (schema != null) { return schema; } @@ -63,10 +63,10 @@ public abstract class XmlSchemaProvider { } @Nullable - public static XmlFile findSchema(@NotNull @NonNls String url, @NotNull PsiFile baseFile) { + public static XmlFile findSchema(@NotNull @NonNls String namespace, @NotNull PsiFile baseFile) { final PsiDirectory directory = baseFile.getParent(); final Module module = ModuleUtil.findModuleForPsiElement(directory == null ? baseFile : directory); - return findSchema(url, module, baseFile); + return findSchema(namespace, module, baseFile); } /** From 25264585ee9d8f0be45afd7ac88452e7db0d79b1 Mon Sep 17 00:00:00 2001 From: Maxim Shafirov Date: Fri, 25 Dec 2009 13:50:14 +0300 Subject: [PATCH 15/67] Correct PsiAnchor for cls elements --- .../psi/impl/compiled/ClsRepositoryPsiElement.java | 12 +++++++----- .../lang-impl/src/com/intellij/psi/PsiAnchor.java | 14 ++++++++++---- 2 files changed, 17 insertions(+), 9 deletions(-) diff --git a/java/java-impl/src/com/intellij/psi/impl/compiled/ClsRepositoryPsiElement.java b/java/java-impl/src/com/intellij/psi/impl/compiled/ClsRepositoryPsiElement.java index 6d48380dedd0..ef1ac2797bcd 100644 --- a/java/java-impl/src/com/intellij/psi/impl/compiled/ClsRepositoryPsiElement.java +++ b/java/java-impl/src/com/intellij/psi/impl/compiled/ClsRepositoryPsiElement.java @@ -15,10 +15,8 @@ */ package com.intellij.psi.impl.compiled; -import com.intellij.psi.PsiElement; -import com.intellij.psi.PsiFile; -import com.intellij.psi.PsiInvalidElementAccessException; -import com.intellij.psi.PsiManager; +import com.intellij.psi.*; +import com.intellij.psi.stubs.IStubElementType; import com.intellij.psi.stubs.PsiFileStub; import com.intellij.psi.stubs.StubElement; import com.intellij.util.ArrayUtil; @@ -26,13 +24,17 @@ import org.jetbrains.annotations.NotNull; import java.util.List; -public abstract class ClsRepositoryPsiElement extends ClsElementImpl { +public abstract class ClsRepositoryPsiElement extends ClsElementImpl implements StubBasedPsiElement { private final T myStub; protected ClsRepositoryPsiElement(final T stub) { myStub = stub; } + public IStubElementType getElementType() { + return myStub.getStubType(); + } + public PsiElement getParent() { return myStub.getParentStub().getPsi(); } diff --git a/platform/lang-impl/src/com/intellij/psi/PsiAnchor.java b/platform/lang-impl/src/com/intellij/psi/PsiAnchor.java index 81ee7d95cd51..24121c111b39 100644 --- a/platform/lang-impl/src/com/intellij/psi/PsiAnchor.java +++ b/platform/lang-impl/src/com/intellij/psi/PsiAnchor.java @@ -26,6 +26,7 @@ import com.intellij.openapi.util.NullableComputable; import com.intellij.openapi.util.TextRange; import com.intellij.psi.impl.light.LightElement; import com.intellij.psi.impl.source.PsiFileImpl; +import com.intellij.psi.impl.source.PsiFileWithStubSupport; import com.intellij.psi.stubs.StubBase; import com.intellij.psi.stubs.StubElement; import com.intellij.psi.stubs.StubTree; @@ -46,7 +47,7 @@ public abstract class PsiAnchor { public abstract int getEndOffset(); public static PsiAnchor create(final PsiElement element) { - if (element instanceof PsiCompiledElement || element instanceof PsiFile) { + if (element instanceof PsiFile) { return new HardReference(element); } @@ -55,7 +56,7 @@ public abstract class PsiAnchor { return new HardReference(element); } - if (element instanceof StubBasedPsiElement && element.isPhysical() && ((PsiFileImpl)file).getContentElementType() instanceof IStubFileElementType) { + if (element instanceof StubBasedPsiElement && element.isPhysical() && (element instanceof PsiCompiledElement || ((PsiFileImpl)file).getContentElementType() instanceof IStubFileElementType)) { final StubBasedPsiElement elt = (StubBasedPsiElement)element; if (elt.getStub() != null || elt.getElementType().shouldCreateStub(element.getNode())) { return new StubIndexReference(file, calcStubIndex((StubBasedPsiElement)element)); @@ -225,12 +226,17 @@ public abstract class PsiAnchor { public PsiElement retrieve() { return ApplicationManager.getApplication().runReadAction(new NullableComputable() { public PsiElement compute() { - PsiFileImpl fileImpl = (PsiFileImpl)myFile; + PsiFileWithStubSupport fileImpl = (PsiFileWithStubSupport)myFile; StubTree tree = fileImpl.getStubTree(); boolean foreign = (tree == null); if (foreign) { - tree = fileImpl.calcStubTree(); + if (fileImpl instanceof PsiFileImpl) { + tree = ((PsiFileImpl)fileImpl).calcStubTree(); + } + else { + return null; + } } StubElement stub = tree.getPlainList().get(myIndex); From bf02213df7fa022a9b9ff7d31d365e1f698f8796 Mon Sep 17 00:00:00 2001 From: Alexey Kudravtsev Date: Fri, 25 Dec 2009 16:43:44 +0300 Subject: [PATCH 16/67] additional assertion in tests --- .../daemon/LightDaemonAnalyzerTestCase.java | 4 ++- .../daemon/impl/DaemonCodeAnalyzerImpl.java | 6 ++++- .../daemon/impl/PassExecutorService.java | 27 ++++++++++--------- .../impl/CodeInsightTestFixtureImpl.java | 4 ++- 4 files changed, 25 insertions(+), 16 deletions(-) diff --git a/java/testFramework/src/com/intellij/codeInsight/daemon/LightDaemonAnalyzerTestCase.java b/java/testFramework/src/com/intellij/codeInsight/daemon/LightDaemonAnalyzerTestCase.java index d0bd554bf1c5..40cf8c048143 100644 --- a/java/testFramework/src/com/intellij/codeInsight/daemon/LightDaemonAnalyzerTestCase.java +++ b/java/testFramework/src/com/intellij/codeInsight/daemon/LightDaemonAnalyzerTestCase.java @@ -16,6 +16,7 @@ package com.intellij.codeInsight.daemon; import com.intellij.codeHighlighting.Pass; +import com.intellij.codeInsight.daemon.impl.DaemonCodeAnalyzerImpl; import com.intellij.codeInsight.daemon.impl.HighlightInfo; import com.intellij.injected.editor.EditorWindow; import com.intellij.openapi.editor.Editor; @@ -46,7 +47,8 @@ public abstract class LightDaemonAnalyzerTestCase extends LightCodeInsightTestCa @Override protected void tearDown() throws Exception { - DaemonCodeAnalyzer.getInstance(getProject()).projectClosed(); + DaemonCodeAnalyzerImpl codeAnalyzer = (DaemonCodeAnalyzerImpl)DaemonCodeAnalyzer.getInstance(getProject()); + codeAnalyzer.projectClosed(); super.tearDown(); } diff --git a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/DaemonCodeAnalyzerImpl.java b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/DaemonCodeAnalyzerImpl.java index c0d7fd498f5b..57353aafea0c 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/DaemonCodeAnalyzerImpl.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/DaemonCodeAnalyzerImpl.java @@ -361,7 +361,7 @@ public class DaemonCodeAnalyzerImpl extends DaemonCodeAnalyzer implements JDOMEx if (myUpdateProgress != null) { myUpdateProgress.cancel(); - myPassExecutorService.cancelAll(); + myPassExecutorService.cancelAll(false); cancelVisibleProgress(); myUpdateProgress = null; } @@ -626,4 +626,8 @@ public class DaemonCodeAnalyzerImpl extends DaemonCodeAnalyzer implements JDOMEx return UpdateHighlightersUtil.getFileLeveleHighlights(project, file); } + @TestOnly + public void clearPasses() { + myPassExecutorService.cancelAll(true); + } } diff --git a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/PassExecutorService.java b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/PassExecutorService.java index f3d4a3b4983f..525c97024724 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/PassExecutorService.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/PassExecutorService.java @@ -61,7 +61,7 @@ public abstract class PassExecutorService implements Disposable { private final Map> mySubmittedPasses = new ConcurrentHashMap>(); private final Project myProject; - private boolean isDisposed; + private volatile boolean isDisposed; private final AtomicInteger nextPassId = new AtomicInteger(100); public PassExecutorService(Project project) { @@ -70,28 +70,29 @@ public abstract class PassExecutorService implements Disposable { } public void dispose() { - for (Job submittedPass : mySubmittedPasses.values()) { - submittedPass.cancel(); - } - for (Job job : mySubmittedPasses.values()) { - try { - if (!job.isDone()) ((JobImpl)job).waitForTermination(); - } - catch (Throwable throwable) { - LOG.error(throwable); - } - } + cancelAll(true); isDisposed = true; } - public void cancelAll() { + public void cancelAll(boolean waitForTermination) { for (Job submittedPass : mySubmittedPasses.values()) { submittedPass.cancel(); } + if (waitForTermination) { + for (Job job : mySubmittedPasses.values()) { + try { + if (!job.isDone()) ((JobImpl)job).waitForTermination(); + } + catch (Throwable throwable) { + LOG.error(throwable); + } + } + } mySubmittedPasses.clear(); } public void submitPasses(Map passesMap, DaemonProgressIndicator updateProgress, final int jobPriority) { + if (isDisposed()) return; int id = 1; // (doc, passId) -> created pass diff --git a/platform/testFramework/src/com/intellij/testFramework/fixtures/impl/CodeInsightTestFixtureImpl.java b/platform/testFramework/src/com/intellij/testFramework/fixtures/impl/CodeInsightTestFixtureImpl.java index 2ea7bf964393..3205bf938fe1 100644 --- a/platform/testFramework/src/com/intellij/testFramework/fixtures/impl/CodeInsightTestFixtureImpl.java +++ b/platform/testFramework/src/com/intellij/testFramework/fixtures/impl/CodeInsightTestFixtureImpl.java @@ -1086,7 +1086,8 @@ public class CodeInsightTestFixtureImpl extends BaseFixture implements CodeInsig public static List instantiateAndRun(PsiFile file, Editor editor, int[] toIgnore, boolean allowDirt) { Project project = file.getProject(); ensureIndexesUpToDate(project); - FileStatusMap fileStatusMap = ((DaemonCodeAnalyzerImpl)DaemonCodeAnalyzer.getInstance(project)).getFileStatusMap(); + DaemonCodeAnalyzerImpl codeAnalyzer = (DaemonCodeAnalyzerImpl)DaemonCodeAnalyzer.getInstance(project); + FileStatusMap fileStatusMap = codeAnalyzer.getFileStatusMap(); for (int ignoreId : toIgnore) { fileStatusMap.markFileUpToDate(editor.getDocument(), file, ignoreId); } @@ -1108,6 +1109,7 @@ public class CodeInsightTestFixtureImpl extends BaseFixture implements CodeInsig } finally { fileStatusMap.allowDirt(true); + codeAnalyzer.clearPasses(); } } From 2ab8927200f71362fa50f8674ffcf6c66b3642fe Mon Sep 17 00:00:00 2001 From: Dmitry Jemerov Date: Fri, 25 Dec 2009 16:49:56 +0300 Subject: [PATCH 17/67] allow to pass test patterns via command line rather than testGroups.properties --- .../src/com/intellij/TestCaseLoader.java | 12 ++++++-- .../src/com/intellij/TestClassesFilter.java | 28 ++++++++++++------- 2 files changed, 28 insertions(+), 12 deletions(-) diff --git a/platform/testFramework/src/com/intellij/TestCaseLoader.java b/platform/testFramework/src/com/intellij/TestCaseLoader.java index 9de887ee6a78..46932e197c9a 100644 --- a/platform/testFramework/src/com/intellij/TestCaseLoader.java +++ b/platform/testFramework/src/com/intellij/TestCaseLoader.java @@ -25,6 +25,7 @@ package com.intellij; import com.intellij.idea.Bombed; +import com.intellij.openapi.util.text.StringUtil; import com.intellij.testFramework.PlatformTestUtil; import com.intellij.testFramework.TestRunnerUtil; import junit.framework.Test; @@ -57,12 +58,19 @@ public class TestCaseLoader { } } + myTestGroupName = System.getProperty("idea.test.group"); } else { - myTestClassesFilter = TestClassesFilter.EMPTY_CLASSES_FILTER; + String patterns = System.getProperty("idea.test.patterns"); + if (patterns != null) { + myTestClassesFilter = new TestClassesFilter(StringUtil.split(patterns, ";")); + } + else { + myTestClassesFilter = TestClassesFilter.EMPTY_CLASSES_FILTER; + } + myTestGroupName = ""; } - myTestGroupName = System.getProperty("idea.test.group"); System.out.println("Using test group: [" + (myTestGroupName == null ? "" : myTestGroupName) + "]"); } diff --git a/platform/testFramework/src/com/intellij/TestClassesFilter.java b/platform/testFramework/src/com/intellij/TestClassesFilter.java index c494d2f70bdc..dca60cb054bd 100644 --- a/platform/testFramework/src/com/intellij/TestClassesFilter.java +++ b/platform/testFramework/src/com/intellij/TestClassesFilter.java @@ -33,16 +33,24 @@ public class TestClassesFilter { for (String groupName : filters.keySet()) { List filterList = filters.get(groupName); - ArrayList patterns = new ArrayList(); - myPatterns.put(groupName, patterns); - for (String aFilter : filterList) { - String filter = aFilter.trim(); - if (filter.length() == 0) continue; - filter = filter.replaceAll("\\*", ".\\*"); - Pattern pattern = Pattern.compile(filter); - myAllPatterns.add(pattern); - patterns.add(pattern); - } + addPatterns(groupName, filterList); + } + } + + TestClassesFilter(List filterList) { + addPatterns("", filterList); + } + + private void addPatterns(String groupName, List filterList) { + ArrayList patterns = new ArrayList(); + myPatterns.put(groupName, patterns); + for (String aFilter : filterList) { + String filter = aFilter.trim(); + if (filter.length() == 0) continue; + filter = filter.replaceAll("\\*", ".\\*"); + Pattern pattern = Pattern.compile(filter); + myAllPatterns.add(pattern); + patterns.add(pattern); } } From 1e6361b781889764ec1865afb73f4fecf29a92f2 Mon Sep 17 00:00:00 2001 From: Dmitry Jemerov Date: Fri, 25 Dec 2009 17:32:33 +0300 Subject: [PATCH 18/67] move JFlex to CE source --- tools/lexer/idea-flex.skeleton | 263 ++ tools/lexer/jflex-1.4/.classpath | 9 + tools/lexer/jflex-1.4/.project | 17 + tools/lexer/jflex-1.4/COPYRIGHT | 303 ++ tools/lexer/jflex-1.4/JFlex-Changes.txt | 12 + tools/lexer/jflex-1.4/bin/jflex | 51 + tools/lexer/jflex-1.4/bin/jflex.bat | 19 + tools/lexer/jflex-1.4/doc/COPYRIGHT | 303 ++ tools/lexer/jflex-1.4/doc/crossref.png | Bin 0 -> 147 bytes tools/lexer/jflex-1.4/doc/footnote.png | Bin 0 -> 190 bytes tools/lexer/jflex-1.4/doc/jflex_anttask.html | 165 + tools/lexer/jflex-1.4/doc/logo.gif | Bin 0 -> 31753 bytes tools/lexer/jflex-1.4/doc/manual.css | 19 + tools/lexer/jflex-1.4/doc/manual.html | 3920 +++++++++++++++++ tools/lexer/jflex-1.4/doc/manual.pdf | Bin 0 -> 392211 bytes tools/lexer/jflex-1.4/doc/manual.ps.gz | Bin 0 -> 195352 bytes .../lexer/jflex-1.4/examples/binary/Makefile | 22 + tools/lexer/jflex-1.4/examples/binary/README | 18 + .../examples/binary/StraightStreamReader.java | 287 ++ .../jflex-1.4/examples/binary/binary.flex | 52 + .../lexer/jflex-1.4/examples/byaccj/Makefile | 27 + tools/lexer/jflex-1.4/examples/byaccj/README | 22 + .../lexer/jflex-1.4/examples/byaccj/calc.flex | 62 + tools/lexer/jflex-1.4/examples/byaccj/calc.y | 112 + tools/lexer/jflex-1.4/examples/cup/Main.java | 39 + tools/lexer/jflex-1.4/examples/cup/Makefile | 26 + tools/lexer/jflex-1.4/examples/cup/README | 30 + tools/lexer/jflex-1.4/examples/cup/lcalc.flex | 142 + .../lexer/jflex-1.4/examples/cup/output.good | 4 + tools/lexer/jflex-1.4/examples/cup/test.txt | 4 + tools/lexer/jflex-1.4/examples/cup/ycalc.cup | 234 + .../jflex-1.4/examples/interpreter/AST.java | 30 + .../jflex-1.4/examples/interpreter/Main.java | 88 + .../jflex-1.4/examples/interpreter/Makefile | 42 + .../jflex-1.4/examples/interpreter/README | 31 + .../examples/interpreter/STEfun.java | 54 + .../examples/interpreter/STEvar.java | 57 + .../examples/interpreter/SymTab.java | 79 + .../examples/interpreter/SymtabEntry.java | 48 + .../examples/interpreter/Tboolexp.java | 64 + .../jflex-1.4/examples/interpreter/Tdekl.java | 75 + .../examples/interpreter/Tdekllist.java | 69 + .../jflex-1.4/examples/interpreter/Texp.java | 43 + .../examples/interpreter/Texpinfix.java | 64 + .../examples/interpreter/Texplist.java | 73 + .../jflex-1.4/examples/interpreter/Tfun.java | 66 + .../examples/interpreter/Tident.java | 62 + .../examples/interpreter/Tifthenelse.java | 59 + .../examples/interpreter/Tnumber.java | 47 + .../examples/interpreter/Tparlist.java | 54 + .../examples/interpreter/Tprogram.java | 99 + .../examples/interpreter/Tuminus.java | 49 + .../jflex-1.4/examples/interpreter/build.xml | 38 + .../jflex-1.4/examples/interpreter/example.as | 16 + .../jflex-1.4/examples/interpreter/parser.cup | 112 + .../examples/interpreter/scanner.flex | 71 + .../jflex-1.4/examples/java/JavaParser.java | 47 + .../jflex-1.4/examples/java/JavaSymbol.java | 31 + tools/lexer/jflex-1.4/examples/java/Makefile | 48 + tools/lexer/jflex-1.4/examples/java/README | 41 + .../jflex-1.4/examples/java/TestLexer.java | 62 + tools/lexer/jflex-1.4/examples/java/java.flex | 312 ++ .../lexer/jflex-1.4/examples/java/java12.cup | 885 ++++ .../jflex-1.4/examples/java/lexer-output.good | 376 ++ .../jflex-1.4/examples/java/unicode.flex | 149 + .../lexer/jflex-1.4/examples/simple/Makefile | 23 + tools/lexer/jflex-1.4/examples/simple/README | 29 + .../jflex-1.4/examples/simple/Utility.java | 19 + .../jflex-1.4/examples/simple/Yytoken.java | 24 + .../jflex-1.4/examples/simple/output.good | 660 +++ .../jflex-1.4/examples/simple/simple.flex | 86 + .../lexer/jflex-1.4/examples/simple/test.txt | 19 + .../jflex-1.4/examples/standalone/Makefile | 13 + .../jflex-1.4/examples/standalone/README | 20 + .../jflex-1.4/examples/standalone/build.xml | 23 + .../jflex-1.4/examples/standalone/sample.inp | 8 + .../examples/standalone/standalone.flex | 44 + tools/lexer/jflex-1.4/lib/JFlex.jar | Bin 0 -> 169541 bytes tools/lexer/jflex-1.4/lib/jflex-mode.el | 114 + tools/lexer/jflex-1.4/lib/jflex.vim | 149 + tools/lexer/jflex-1.4/src/JFlex/Action.java | 149 + .../src/JFlex/CharClassException.java | 49 + .../src/JFlex/CharClassInterval.java | 73 + .../jflex-1.4/src/JFlex/CharClasses.java | 388 ++ tools/lexer/jflex-1.4/src/JFlex/CharSet.java | 112 + .../src/JFlex/CharSetEnumerator.java | 88 + .../jflex-1.4/src/JFlex/CountEmitter.java | 115 + tools/lexer/jflex-1.4/src/JFlex/DFA.java | 940 ++++ .../lexer/jflex-1.4/src/JFlex/EOFActions.java | 96 + tools/lexer/jflex-1.4/src/JFlex/Emitter.java | 1616 +++++++ .../jflex-1.4/src/JFlex/ErrorMessages.java | 140 + .../src/JFlex/GeneratorException.java | 36 + .../jflex-1.4/src/JFlex/HiLowEmitter.java | 88 + .../lexer/jflex-1.4/src/JFlex/IntCharSet.java | 411 ++ tools/lexer/jflex-1.4/src/JFlex/IntPair.java | 57 + tools/lexer/jflex-1.4/src/JFlex/Interval.java | 163 + tools/lexer/jflex-1.4/src/JFlex/LexParse.cup | 632 +++ tools/lexer/jflex-1.4/src/JFlex/LexParse.java | 1711 +++++++ tools/lexer/jflex-1.4/src/JFlex/LexScan.flex | 569 +++ tools/lexer/jflex-1.4/src/JFlex/LexScan.java | 2849 ++++++++++++ .../jflex-1.4/src/JFlex/LexicalStates.java | 99 + .../jflex-1.4/src/JFlex/MacroException.java | 49 + tools/lexer/jflex-1.4/src/JFlex/Macros.java | 219 + tools/lexer/jflex-1.4/src/JFlex/Main.java | 344 ++ .../jflex-1.4/src/JFlex/Messages.properties | 70 + tools/lexer/jflex-1.4/src/JFlex/NFA.java | 996 +++++ tools/lexer/jflex-1.4/src/JFlex/Options.java | 131 + tools/lexer/jflex-1.4/src/JFlex/Out.java | 461 ++ .../jflex-1.4/src/JFlex/PackEmitter.java | 230 + tools/lexer/jflex-1.4/src/JFlex/RegExp.java | 172 + tools/lexer/jflex-1.4/src/JFlex/RegExp1.java | 80 + tools/lexer/jflex-1.4/src/JFlex/RegExp2.java | 50 + tools/lexer/jflex-1.4/src/JFlex/RegExps.java | 159 + .../jflex-1.4/src/JFlex/ScannerException.java | 104 + tools/lexer/jflex-1.4/src/JFlex/SemCheck.java | 145 + .../lexer/jflex-1.4/src/JFlex/SilentExit.java | 31 + tools/lexer/jflex-1.4/src/JFlex/Skeleton.java | 207 + .../jflex-1.4/src/JFlex/StatePairList.java | 83 + tools/lexer/jflex-1.4/src/JFlex/StateSet.java | 329 ++ .../src/JFlex/StateSetEnumerator.java | 127 + .../jflex-1.4/src/JFlex/StdOutWriter.java | 114 + tools/lexer/jflex-1.4/src/JFlex/Timer.java | 110 + .../src/JFlex/anttask/JFlexTask.java | 268 ++ .../src/JFlex/gui/GeneratorThread.java | 93 + .../jflex-1.4/src/JFlex/gui/GridPanel.java | 161 + .../src/JFlex/gui/GridPanelConstraint.java | 44 + .../jflex-1.4/src/JFlex/gui/Handles.java | 49 + .../jflex-1.4/src/JFlex/gui/MainFrame.java | 275 ++ .../src/JFlex/gui/OptionsDialog.java | 258 ++ .../jflex-1.4/src/JFlex/skeleton.default | 317 ++ tools/lexer/jflex-1.4/src/JFlex/sym.java | 60 + .../jflex-1.4/src/JFlex/tests/AllTests.java | 50 + .../src/JFlex/tests/AntTaskTests.java | 166 + .../src/JFlex/tests/CharClassesTest.java | 103 + .../src/JFlex/tests/EmitterTest.java | 50 + .../src/JFlex/tests/PackEmitterTest.java | 80 + .../src/JFlex/tests/RegExpTests.java | 58 + .../src/JFlex/tests/SkeletonTest.java | 63 + tools/lexer/jflex-1.4/src/README | 63 + tools/lexer/jflex-1.4/src/build.xml | 108 + tools/lexer/jflex-1.4/src/changelog | 255 ++ .../src/java_cup/runtime/Scanner.java | 25 + .../src/java_cup/runtime/Symbol.java | 105 + .../src/java_cup/runtime/lr_parser.java | 1238 ++++++ .../java_cup/runtime/virtual_parse_stack.java | 145 + tools/lexer/jflex-1.4/src/manifest | 1 + tools/lexer/jflex-1.4/src/skeleton.default | 317 ++ tools/lexer/jflex-1.4/src/skeleton.nested | 419 ++ 148 files changed, 30197 insertions(+) create mode 100644 tools/lexer/idea-flex.skeleton create mode 100644 tools/lexer/jflex-1.4/.classpath create mode 100644 tools/lexer/jflex-1.4/.project create mode 100644 tools/lexer/jflex-1.4/COPYRIGHT create mode 100644 tools/lexer/jflex-1.4/JFlex-Changes.txt create mode 100644 tools/lexer/jflex-1.4/bin/jflex create mode 100644 tools/lexer/jflex-1.4/bin/jflex.bat create mode 100644 tools/lexer/jflex-1.4/doc/COPYRIGHT create mode 100644 tools/lexer/jflex-1.4/doc/crossref.png create mode 100644 tools/lexer/jflex-1.4/doc/footnote.png create mode 100644 tools/lexer/jflex-1.4/doc/jflex_anttask.html create mode 100644 tools/lexer/jflex-1.4/doc/logo.gif create mode 100644 tools/lexer/jflex-1.4/doc/manual.css create mode 100644 tools/lexer/jflex-1.4/doc/manual.html create mode 100644 tools/lexer/jflex-1.4/doc/manual.pdf create mode 100644 tools/lexer/jflex-1.4/doc/manual.ps.gz create mode 100644 tools/lexer/jflex-1.4/examples/binary/Makefile create mode 100644 tools/lexer/jflex-1.4/examples/binary/README create mode 100644 tools/lexer/jflex-1.4/examples/binary/StraightStreamReader.java create mode 100644 tools/lexer/jflex-1.4/examples/binary/binary.flex create mode 100644 tools/lexer/jflex-1.4/examples/byaccj/Makefile create mode 100644 tools/lexer/jflex-1.4/examples/byaccj/README create mode 100644 tools/lexer/jflex-1.4/examples/byaccj/calc.flex create mode 100644 tools/lexer/jflex-1.4/examples/byaccj/calc.y create mode 100644 tools/lexer/jflex-1.4/examples/cup/Main.java create mode 100644 tools/lexer/jflex-1.4/examples/cup/Makefile create mode 100644 tools/lexer/jflex-1.4/examples/cup/README create mode 100644 tools/lexer/jflex-1.4/examples/cup/lcalc.flex create mode 100644 tools/lexer/jflex-1.4/examples/cup/output.good create mode 100644 tools/lexer/jflex-1.4/examples/cup/test.txt create mode 100644 tools/lexer/jflex-1.4/examples/cup/ycalc.cup create mode 100644 tools/lexer/jflex-1.4/examples/interpreter/AST.java create mode 100644 tools/lexer/jflex-1.4/examples/interpreter/Main.java create mode 100644 tools/lexer/jflex-1.4/examples/interpreter/Makefile create mode 100644 tools/lexer/jflex-1.4/examples/interpreter/README create mode 100644 tools/lexer/jflex-1.4/examples/interpreter/STEfun.java create mode 100644 tools/lexer/jflex-1.4/examples/interpreter/STEvar.java create mode 100644 tools/lexer/jflex-1.4/examples/interpreter/SymTab.java create mode 100644 tools/lexer/jflex-1.4/examples/interpreter/SymtabEntry.java create mode 100644 tools/lexer/jflex-1.4/examples/interpreter/Tboolexp.java create mode 100644 tools/lexer/jflex-1.4/examples/interpreter/Tdekl.java create mode 100644 tools/lexer/jflex-1.4/examples/interpreter/Tdekllist.java create mode 100644 tools/lexer/jflex-1.4/examples/interpreter/Texp.java create mode 100644 tools/lexer/jflex-1.4/examples/interpreter/Texpinfix.java create mode 100644 tools/lexer/jflex-1.4/examples/interpreter/Texplist.java create mode 100644 tools/lexer/jflex-1.4/examples/interpreter/Tfun.java create mode 100644 tools/lexer/jflex-1.4/examples/interpreter/Tident.java create mode 100644 tools/lexer/jflex-1.4/examples/interpreter/Tifthenelse.java create mode 100644 tools/lexer/jflex-1.4/examples/interpreter/Tnumber.java create mode 100644 tools/lexer/jflex-1.4/examples/interpreter/Tparlist.java create mode 100644 tools/lexer/jflex-1.4/examples/interpreter/Tprogram.java create mode 100644 tools/lexer/jflex-1.4/examples/interpreter/Tuminus.java create mode 100644 tools/lexer/jflex-1.4/examples/interpreter/build.xml create mode 100644 tools/lexer/jflex-1.4/examples/interpreter/example.as create mode 100644 tools/lexer/jflex-1.4/examples/interpreter/parser.cup create mode 100644 tools/lexer/jflex-1.4/examples/interpreter/scanner.flex create mode 100644 tools/lexer/jflex-1.4/examples/java/JavaParser.java create mode 100644 tools/lexer/jflex-1.4/examples/java/JavaSymbol.java create mode 100644 tools/lexer/jflex-1.4/examples/java/Makefile create mode 100644 tools/lexer/jflex-1.4/examples/java/README create mode 100644 tools/lexer/jflex-1.4/examples/java/TestLexer.java create mode 100644 tools/lexer/jflex-1.4/examples/java/java.flex create mode 100644 tools/lexer/jflex-1.4/examples/java/java12.cup create mode 100644 tools/lexer/jflex-1.4/examples/java/lexer-output.good create mode 100644 tools/lexer/jflex-1.4/examples/java/unicode.flex create mode 100644 tools/lexer/jflex-1.4/examples/simple/Makefile create mode 100644 tools/lexer/jflex-1.4/examples/simple/README create mode 100644 tools/lexer/jflex-1.4/examples/simple/Utility.java create mode 100644 tools/lexer/jflex-1.4/examples/simple/Yytoken.java create mode 100644 tools/lexer/jflex-1.4/examples/simple/output.good create mode 100644 tools/lexer/jflex-1.4/examples/simple/simple.flex create mode 100644 tools/lexer/jflex-1.4/examples/simple/test.txt create mode 100644 tools/lexer/jflex-1.4/examples/standalone/Makefile create mode 100644 tools/lexer/jflex-1.4/examples/standalone/README create mode 100644 tools/lexer/jflex-1.4/examples/standalone/build.xml create mode 100644 tools/lexer/jflex-1.4/examples/standalone/sample.inp create mode 100644 tools/lexer/jflex-1.4/examples/standalone/standalone.flex create mode 100644 tools/lexer/jflex-1.4/lib/JFlex.jar create mode 100644 tools/lexer/jflex-1.4/lib/jflex-mode.el create mode 100644 tools/lexer/jflex-1.4/lib/jflex.vim create mode 100644 tools/lexer/jflex-1.4/src/JFlex/Action.java create mode 100644 tools/lexer/jflex-1.4/src/JFlex/CharClassException.java create mode 100644 tools/lexer/jflex-1.4/src/JFlex/CharClassInterval.java create mode 100644 tools/lexer/jflex-1.4/src/JFlex/CharClasses.java create mode 100644 tools/lexer/jflex-1.4/src/JFlex/CharSet.java create mode 100644 tools/lexer/jflex-1.4/src/JFlex/CharSetEnumerator.java create mode 100644 tools/lexer/jflex-1.4/src/JFlex/CountEmitter.java create mode 100644 tools/lexer/jflex-1.4/src/JFlex/DFA.java create mode 100644 tools/lexer/jflex-1.4/src/JFlex/EOFActions.java create mode 100644 tools/lexer/jflex-1.4/src/JFlex/Emitter.java create mode 100644 tools/lexer/jflex-1.4/src/JFlex/ErrorMessages.java create mode 100644 tools/lexer/jflex-1.4/src/JFlex/GeneratorException.java create mode 100644 tools/lexer/jflex-1.4/src/JFlex/HiLowEmitter.java create mode 100644 tools/lexer/jflex-1.4/src/JFlex/IntCharSet.java create mode 100644 tools/lexer/jflex-1.4/src/JFlex/IntPair.java create mode 100644 tools/lexer/jflex-1.4/src/JFlex/Interval.java create mode 100644 tools/lexer/jflex-1.4/src/JFlex/LexParse.cup create mode 100644 tools/lexer/jflex-1.4/src/JFlex/LexParse.java create mode 100644 tools/lexer/jflex-1.4/src/JFlex/LexScan.flex create mode 100644 tools/lexer/jflex-1.4/src/JFlex/LexScan.java create mode 100644 tools/lexer/jflex-1.4/src/JFlex/LexicalStates.java create mode 100644 tools/lexer/jflex-1.4/src/JFlex/MacroException.java create mode 100644 tools/lexer/jflex-1.4/src/JFlex/Macros.java create mode 100644 tools/lexer/jflex-1.4/src/JFlex/Main.java create mode 100644 tools/lexer/jflex-1.4/src/JFlex/Messages.properties create mode 100644 tools/lexer/jflex-1.4/src/JFlex/NFA.java create mode 100644 tools/lexer/jflex-1.4/src/JFlex/Options.java create mode 100644 tools/lexer/jflex-1.4/src/JFlex/Out.java create mode 100644 tools/lexer/jflex-1.4/src/JFlex/PackEmitter.java create mode 100644 tools/lexer/jflex-1.4/src/JFlex/RegExp.java create mode 100644 tools/lexer/jflex-1.4/src/JFlex/RegExp1.java create mode 100644 tools/lexer/jflex-1.4/src/JFlex/RegExp2.java create mode 100644 tools/lexer/jflex-1.4/src/JFlex/RegExps.java create mode 100644 tools/lexer/jflex-1.4/src/JFlex/ScannerException.java create mode 100644 tools/lexer/jflex-1.4/src/JFlex/SemCheck.java create mode 100644 tools/lexer/jflex-1.4/src/JFlex/SilentExit.java create mode 100644 tools/lexer/jflex-1.4/src/JFlex/Skeleton.java create mode 100644 tools/lexer/jflex-1.4/src/JFlex/StatePairList.java create mode 100644 tools/lexer/jflex-1.4/src/JFlex/StateSet.java create mode 100644 tools/lexer/jflex-1.4/src/JFlex/StateSetEnumerator.java create mode 100644 tools/lexer/jflex-1.4/src/JFlex/StdOutWriter.java create mode 100644 tools/lexer/jflex-1.4/src/JFlex/Timer.java create mode 100644 tools/lexer/jflex-1.4/src/JFlex/anttask/JFlexTask.java create mode 100644 tools/lexer/jflex-1.4/src/JFlex/gui/GeneratorThread.java create mode 100644 tools/lexer/jflex-1.4/src/JFlex/gui/GridPanel.java create mode 100644 tools/lexer/jflex-1.4/src/JFlex/gui/GridPanelConstraint.java create mode 100644 tools/lexer/jflex-1.4/src/JFlex/gui/Handles.java create mode 100644 tools/lexer/jflex-1.4/src/JFlex/gui/MainFrame.java create mode 100644 tools/lexer/jflex-1.4/src/JFlex/gui/OptionsDialog.java create mode 100644 tools/lexer/jflex-1.4/src/JFlex/skeleton.default create mode 100644 tools/lexer/jflex-1.4/src/JFlex/sym.java create mode 100644 tools/lexer/jflex-1.4/src/JFlex/tests/AllTests.java create mode 100644 tools/lexer/jflex-1.4/src/JFlex/tests/AntTaskTests.java create mode 100644 tools/lexer/jflex-1.4/src/JFlex/tests/CharClassesTest.java create mode 100644 tools/lexer/jflex-1.4/src/JFlex/tests/EmitterTest.java create mode 100644 tools/lexer/jflex-1.4/src/JFlex/tests/PackEmitterTest.java create mode 100644 tools/lexer/jflex-1.4/src/JFlex/tests/RegExpTests.java create mode 100644 tools/lexer/jflex-1.4/src/JFlex/tests/SkeletonTest.java create mode 100644 tools/lexer/jflex-1.4/src/README create mode 100644 tools/lexer/jflex-1.4/src/build.xml create mode 100644 tools/lexer/jflex-1.4/src/changelog create mode 100644 tools/lexer/jflex-1.4/src/java_cup/runtime/Scanner.java create mode 100644 tools/lexer/jflex-1.4/src/java_cup/runtime/Symbol.java create mode 100644 tools/lexer/jflex-1.4/src/java_cup/runtime/lr_parser.java create mode 100644 tools/lexer/jflex-1.4/src/java_cup/runtime/virtual_parse_stack.java create mode 100644 tools/lexer/jflex-1.4/src/manifest create mode 100644 tools/lexer/jflex-1.4/src/skeleton.default create mode 100644 tools/lexer/jflex-1.4/src/skeleton.nested diff --git a/tools/lexer/idea-flex.skeleton b/tools/lexer/idea-flex.skeleton new file mode 100644 index 000000000000..a91ec0c86859 --- /dev/null +++ b/tools/lexer/idea-flex.skeleton @@ -0,0 +1,263 @@ + /** initial size of the lookahead buffer */ +--- private static final int ZZ_BUFFERSIZE = ...; + + /** lexical states */ +--- lexical states, charmap + + /* error codes */ + private static final int ZZ_UNKNOWN_ERROR = 0; + private static final int ZZ_NO_MATCH = 1; + private static final int ZZ_PUSHBACK_2BIG = 2; + private static final char[] EMPTY_BUFFER = new char[0]; + private static final int YYEOF = -1; + private static java.io.Reader zzReader = null; // Fake + + /* error messages for the codes above */ + private static final String ZZ_ERROR_MSG[] = { + "Unkown internal scanner error", + "Error: could not match input", + "Error: pushback value was too large" + }; + +--- isFinal list + /** the current state of the DFA */ + private int zzState; + + /** the current lexical state */ + private int zzLexicalState = YYINITIAL; + + /** this buffer contains the current text to be matched and is + the source of the yytext() string */ + private CharSequence zzBuffer = ""; + + /** this buffer may contains the current text array to be matched when it is cheap to acquire it */ + private char[] zzBufferArray; + + /** the textposition at the last accepting state */ + private int zzMarkedPos; + + /** the textposition at the last state to be included in yytext */ + private int zzPushbackPos; + + /** the current text position in the buffer */ + private int zzCurrentPos; + + /** startRead marks the beginning of the yytext() string in the buffer */ + private int zzStartRead; + + /** endRead marks the last character in the buffer, that has been read + from input */ + private int zzEndRead; + + /** + * zzAtBOL == true <=> the scanner is currently at the beginning of a line + */ + private boolean zzAtBOL = true; + + /** zzAtEOF == true <=> the scanner is at the EOF */ + private boolean zzAtEOF; + +--- user class code + +--- constructor declaration + + public final int getTokenStart(){ + return zzStartRead; + } + + public final int getTokenEnd(){ + return getTokenStart() + yylength(); + } + + public void reset(CharSequence buffer, int start, int end,int initialState){ + zzBuffer = buffer; + zzBufferArray = com.intellij.util.text.CharArrayUtil.fromSequenceWithoutCopying(buffer); + zzCurrentPos = zzMarkedPos = zzStartRead = start; + zzPushbackPos = 0; + zzAtEOF = false; + zzAtBOL = true; + zzEndRead = end; + yybegin(initialState); + } + + // For Demetra compatibility + public void reset(CharSequence buffer, int initialState){ + zzBuffer = buffer; + zzBufferArray = null; + zzCurrentPos = zzMarkedPos = zzStartRead = 0; + zzPushbackPos = 0; + zzAtEOF = false; + zzAtBOL = true; + zzEndRead = buffer.length(); + yybegin(initialState); + } + + /** + * Refills the input buffer. + * + * @return false, iff there was new input. + * + * @exception java.io.IOException if any I/O-Error occurs + */ + private boolean zzRefill() throws java.io.IOException { + return true; + } + + + /** + * Returns the current lexical state. + */ + public final int yystate() { + return zzLexicalState; + } + + + /** + * Enters a new lexical state + * + * @param newState the new lexical state + */ + public final void yybegin(int newState) { + zzLexicalState = newState; + } + + + /** + * Returns the text matched by the current regular expression. + */ + public final CharSequence yytext() { + return zzBuffer.subSequence(zzStartRead, zzMarkedPos); + } + + + /** + * Returns the character at position pos from the + * matched text. + * + * It is equivalent to yytext().charAt(pos), but faster + * + * @param pos the position of the character to fetch. + * A value from 0 to yylength()-1. + * + * @return the character at position pos + */ + public final char yycharat(int pos) { + return zzBufferArray != null ? zzBufferArray[zzStartRead+pos]:zzBuffer.charAt(zzStartRead+pos); + } + + + /** + * Returns the length of the matched text region. + */ + public final int yylength() { + return zzMarkedPos-zzStartRead; + } + + + /** + * Reports an error that occured while scanning. + * + * In a wellformed scanner (no or only correct usage of + * yypushback(int) and a match-all fallback rule) this method + * will only be called with things that "Can't Possibly Happen". + * If this method is called, something is seriously wrong + * (e.g. a JFlex bug producing a faulty scanner etc.). + * + * Usual syntax/scanner level error handling should be done + * in error fallback rules. + * + * @param errorCode the code of the errormessage to display + */ +--- zzScanError declaration + String message; + try { + message = ZZ_ERROR_MSG[errorCode]; + } + catch (ArrayIndexOutOfBoundsException e) { + message = ZZ_ERROR_MSG[ZZ_UNKNOWN_ERROR]; + } + +--- throws clause + } + + + /** + * Pushes the specified amount of characters back into the input stream. + * + * They will be read again by then next call of the scanning method + * + * @param number the number of characters to be read again. + * This number must not be greater than yylength()! + */ +--- yypushback decl (contains zzScanError exception) + if ( number > yylength() ) + zzScanError(ZZ_PUSHBACK_2BIG); + + zzMarkedPos -= number; + } + + +--- zzDoEOF + /** + * Resumes scanning until the next regular expression is matched, + * the end of input is encountered or an I/O-Error occurs. + * + * @return the next token + * @exception java.io.IOException if any I/O-Error occurs + */ +--- yylex declaration + int zzInput; + int zzAction; + + // cached fields: + int zzCurrentPosL; + int zzMarkedPosL; + int zzEndReadL = zzEndRead; + CharSequence zzBufferL = zzBuffer; + char[] zzBufferArrayL = zzBufferArray; + char [] zzCMapL = ZZ_CMAP; + +--- local declarations + + while (true) { + zzMarkedPosL = zzMarkedPos; + +--- start admin (line, char, col count) + zzAction = -1; + + zzCurrentPosL = zzCurrentPos = zzStartRead = zzMarkedPosL; + +--- start admin (lexstate etc) + + zzForAction: { + while (true) { + +--- next input, line, col, char count, next transition, isFinal action + zzAction = zzState; + zzMarkedPosL = zzCurrentPosL; +--- line count update + } + + } + } + + // store back cached position + zzMarkedPos = zzMarkedPosL; +--- char count update + +--- actions + default: + if (zzInput == YYEOF && zzStartRead == zzCurrentPos) { + zzAtEOF = true; +--- eofvalue + } + else { +--- no match + } + } + } + } + +--- main + +} diff --git a/tools/lexer/jflex-1.4/.classpath b/tools/lexer/jflex-1.4/.classpath new file mode 100644 index 000000000000..c7ff90e6b35c --- /dev/null +++ b/tools/lexer/jflex-1.4/.classpath @@ -0,0 +1,9 @@ + + + + + + + + diff --git a/tools/lexer/jflex-1.4/.project b/tools/lexer/jflex-1.4/.project new file mode 100644 index 000000000000..3160ec94a23d --- /dev/null +++ b/tools/lexer/jflex-1.4/.project @@ -0,0 +1,17 @@ + + + jflex + + + + + + org.eclipse.jdt.core.javabuilder + + + + + + org.eclipse.jdt.core.javanature + + diff --git a/tools/lexer/jflex-1.4/COPYRIGHT b/tools/lexer/jflex-1.4/COPYRIGHT new file mode 100644 index 000000000000..0109c544d770 --- /dev/null +++ b/tools/lexer/jflex-1.4/COPYRIGHT @@ -0,0 +1,303 @@ +JFlex - Copying, Warranty & License + + + +JFlex is free software, published under the terms of the GNU General Public License. + +There is absolutely NO WARRANTY for JFlex, its code and its documentation. + +The code generated by JFlex inherits the copyright of the specification it +was produced from. If it was your specification, you may use the generated +code without restriction. + + + +TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + + +0. + This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + + +1. + You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + +2. + You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + + + a) + You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + + b) + You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + + c) + If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + + +3. + You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + + + a) + Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + + b) + Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + + c) + Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + +4. + You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + + +5. + You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + + +6. + Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + + +7. + If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + + +8. + If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + + +9. + The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + + + +10. + If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + + +NO WARRANTY + + + +11. + BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + + +12. + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + + + +END OF TERMS AND CONDITIONS diff --git a/tools/lexer/jflex-1.4/JFlex-Changes.txt b/tools/lexer/jflex-1.4/JFlex-Changes.txt new file mode 100644 index 000000000000..9048b81f42dd --- /dev/null +++ b/tools/lexer/jflex-1.4/JFlex-Changes.txt @@ -0,0 +1,12 @@ +The following changes to JFlex 1.4.1 have been done by JetBrains developers: + +July 26, 2005: + + * JFlexTask.java: Added setCharAt() method for setting the -charat option from Ant + builds. + +July 8, 2005: + + * Main.java, Options.java, Emitter.java: Added new command line option -charat. + The option replaces array index access when accessing the zzBufferL array with + calls to the .charAt() method. diff --git a/tools/lexer/jflex-1.4/bin/jflex b/tools/lexer/jflex-1.4/bin/jflex new file mode 100644 index 000000000000..80f7b76bf1d6 --- /dev/null +++ b/tools/lexer/jflex-1.4/bin/jflex @@ -0,0 +1,51 @@ +#! /bin/bash +# +# JFlex start script $Revision: 2.0 $ +# +# if Java is not in your binary path, you need to supply its +# location in this script. The script automatically finds +# JFLEX_HOME when called directly, via binary path, or symbolic +# link. +# +# Site wide installation: simply make a symlink from e.g. +# /usr/bin/jflex to this script at its original position +# +#=================================================================== +# +# configurables: + +# path to the java interpreter +JAVA=java + +# end configurables +# +#=================================================================== +# + +# calculate true location + +PRG=`type $0` +PRG=${PRG##* } + +# If PRG is a symlink, trace it to the real home directory + +while [ -L "$PRG" ] +do + newprg=$(ls -l ${PRG}) + newprg=${newprg##*-> } + [ ${newprg} = ${newprg#/} ] && newprg=${PRG%/*}/${newprg} + PRG="$newprg" +done + +PRG=${PRG%/*} +JFLEX_HOME=${PRG}/.. + +# -------------------------------------------------------------------- + +export CLASSPATH +CLASSPATH=$JFLEX_HOME/lib/JFlex.jar + +$JAVA JFlex.Main $@ + +#for more memory: +#$JAVA -Xmx128m JFlex.Main $@ diff --git a/tools/lexer/jflex-1.4/bin/jflex.bat b/tools/lexer/jflex-1.4/bin/jflex.bat new file mode 100644 index 000000000000..6ac3ccd53845 --- /dev/null +++ b/tools/lexer/jflex-1.4/bin/jflex.bat @@ -0,0 +1,19 @@ +@echo off +REM Please adjust the paths JFLEX_HOME and JAVA_HOME to suit your needs +REM (please do not add a trailing backslash) + +set JFLEX_HOME=.. + +REM only needed for JDK 1.1.x: +set JAVA_HOME=C:\JAVA + + +REM ------------------------------------------------------------------- + +set CLPATH=%JAVA_HOME%\lib\classes.zip;%JFLEX_HOME%\lib\JFlex.jar + +REM for JDK 1.1.x +REM %JAVA_HOME%\bin\java -classpath %CLPATH% JFlex.Main %1 %2 %3 %4 %5 %6 %7 %8 %9 + +REM for JDK 1.2 +java -Xmx128m -jar %JFLEX_HOME%\lib\JFlex.jar %1 %2 %3 %4 %5 %6 %7 %8 %9 diff --git a/tools/lexer/jflex-1.4/doc/COPYRIGHT b/tools/lexer/jflex-1.4/doc/COPYRIGHT new file mode 100644 index 000000000000..0109c544d770 --- /dev/null +++ b/tools/lexer/jflex-1.4/doc/COPYRIGHT @@ -0,0 +1,303 @@ +JFlex - Copying, Warranty & License + + + +JFlex is free software, published under the terms of the GNU General Public License. + +There is absolutely NO WARRANTY for JFlex, its code and its documentation. + +The code generated by JFlex inherits the copyright of the specification it +was produced from. If it was your specification, you may use the generated +code without restriction. + + + +TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + + +0. + This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + + +1. + You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + +2. + You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + + + a) + You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + + b) + You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + + c) + If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + + +3. + You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + + + a) + Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + + b) + Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + + c) + Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + +4. + You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + + +5. + You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + + +6. + Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + + +7. + If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + + +8. + If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + + +9. + The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + + + +10. + If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + + +NO WARRANTY + + + +11. + BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + + +12. + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + + + +END OF TERMS AND CONDITIONS diff --git a/tools/lexer/jflex-1.4/doc/crossref.png b/tools/lexer/jflex-1.4/doc/crossref.png new file mode 100644 index 0000000000000000000000000000000000000000..7dd2dddf5ac24cb1297a9d565c41057cb7090e02 GIT binary patch literal 147 zcmeAS@N?(olHy`uVBq!ia0vp@Aj|@a!R<*>X0K7&N_)1@@}28%Z6=9 t-O~MHw|5t0`TuI#<-T9Me##YR_J!+(UN4n;@(5@ygQu&X%Q~loCIFb&G|K=0 literal 0 HcmV?d00001 diff --git a/tools/lexer/jflex-1.4/doc/footnote.png b/tools/lexer/jflex-1.4/doc/footnote.png new file mode 100644 index 0000000000000000000000000000000000000000..4591c0eca1231a8dd51f936b46363bcb9c35cefd GIT binary patch literal 190 zcmeAS@N?(olHy`uVBq!ia0vp^{2FS zrsoVLnH6~&F0zL+P8GD|SkqyVU@2Hw;H_Hnf}ux6|G)cetK3(c&T7OiHM_`p-Fn|I zk6S7tu`7hSPeski&6e)S+V5Vl<++E- m`l!8MrB+YxvAz2@`46M@GoAfWMa#rMF7kBsb6Mw<&;$UT-9{4t literal 0 HcmV?d00001 diff --git a/tools/lexer/jflex-1.4/doc/jflex_anttask.html b/tools/lexer/jflex-1.4/doc/jflex_anttask.html new file mode 100644 index 000000000000..942acf2b391d --- /dev/null +++ b/tools/lexer/jflex-1.4/doc/jflex_anttask.html @@ -0,0 +1,165 @@ + + + + +JFlex Ant Task + + + + +

JFlex Ant Task

+

+ JFlex can be easily integrated with Ant build tool. + To use JFlex with Ant, simply copy JFlex.jar to $ANT_HOME/lib/ directory. +

+

Description

+

+ The JFlex Ant Task invokes the JFlex lexical + analyzer generator on a grammar file. +

+

+ To use the JFlex task, the following line must be placed in the Ant build file: +

+
<taskdef classname="JFlex.anttask.JFlexTask" name="jflex" />
+ +

+ The JFlex task requires the file attribute to be set to the source grammar file (*.flex). + Unless the target directory is specified with the destdir option, + the generated class will be saved to the same directory where grammar file resides. + Like javac, the JFlex task creates subdirectories in destdir according to the + generated class package. +

+

+ This task only invokes JFlex if the grammar file is newer than the generated + files. +

+ +

Parameters

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
AttributeDescriptionRequiredDefault
file="file"The grammar file to process.Yes
destdir="dir" + The directory to write the generated files to. If not set, the files + are written to the directory containing the grammar file. Note that unlike + JFlex's "-d" command line option, destdir causes the generated file to be written to + {destdir}/{package name}. This behaviour is similar to javac -d dir. + No
outdir="dir" + The directory to write the generated files to. If not set, the files + are written to the directory containing the grammar file. This options works + exactly like JFlex's "-d" command line option, it causes the output file to + be written to dir regardless of the package name. + No
verboseDisplay generation process messages.No"off"
dumpDump character classes, NFA and DFA tables.No"off"
time or

timeStatistics

Display generation time statistics.No"off"
nomin or

skipMinimization

Skip minimization step.No"off"
skel="file" or

skeleton="file"

Use external skeleton file.No"off"
dot or

generateDot

Write graphviz .dot files for the generated automata (alpha).No"off"
nobakDo not make a backup if the generated file exists.No"off"
switchUse code generation method switch.No"off"
tableUse code generation method table.No"off"
packUse code generation method pack.No"on"
+

Example

+
+<jflex
+    file="src/parser/Parser.flex"
+    destdir="build/generated/"
+/>
+
+

+ JFlex generates the lexical analyzer for src/parser/Parser.flex and saves the result + to build/generated/parser/, providing Parser.flex declares to be in package parser. +

+ +
+<jflex
+    file="src/parser/Parser.flex"
+    destdir="build/generated/"
+/>
+<javac
+    srcdir="build/generated/"
+    destdir="build/classes/"
+/>
+
+

+ The same as above plus compile generated classes to build/classes +

+
+ + + + diff --git a/tools/lexer/jflex-1.4/doc/logo.gif b/tools/lexer/jflex-1.4/doc/logo.gif new file mode 100644 index 0000000000000000000000000000000000000000..dcd04fb57dc96af7e3d03e58af4bff7a73dce2a8 GIT binary patch literal 31753 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 wGXLuP{A=hdk<6 + + + + +JFlex User's Manual + + + + + + + + + + + + + + + +

+ +

+ + +
+ +

+

+The Fast Lexical Analyser Generator +
+

+
+

+
Copyright ©1998-2004 by Gerwin Klein +
+


+

JFlex User's Manual +
+


+

Version 1.4, April 12, 2004 + +
+ +

+
+ +

+Contents +

+ + + + + +


+Introduction +

+JFlex is a lexical analyzer generator for Java[*]written in Java. It is also a rewrite of the very useful tool JLex [3] which +was developed by Elliot Berk at Princeton University. As Vern Paxon states +for his C/C++ tool flex [11]: They do not share any code though. + +

+ +

+Design goals +

+The main design goals of JFlex are: + +
    +
  • Full unicode support +
  • +
  • Fast generated scanners +
  • +
  • Fast scanner generation +
  • +
  • Convenient specification syntax +
  • +
  • Platform independence +
  • +
  • JLex compatibility +
  • +
+ +

+ +

+About this manual +

+This manual gives a brief but complete description of the tool JFlex. It +assumes that you are familiar with the issue of lexical analysis. The references [1], +[2], and [13] provide a good introduction to this topic. + +

+The next section of this manual describes installation procedures +for JFlex. If you never worked with JLex or +just want to compare a JLex and a JFlex scanner specification you +should also read Working with JFlex - an example +(section [*]). All options and the complete +specification syntax are presented in +Lexical specifications (section [*]); +Encodings, Platforms, and Unicode (section [*]) +provides information about scannig text vs. binary files. +If you are interested in performance +considerations and comparing JLex with JFlex speed, +a few words on performance (section [*]) +might be just right for you. Those who want to +use their old JLex specifications may want to check out section [*] +Porting from JLex to avoid possible problems +with not portable or non standard JLex behavior that has been fixed in +JFlex. Section [*] talks about porting scanners from the +Unix tools lex and flex. Interfacing JFlex scanners with the LALR +parser generators CUP and BYacc/J is explained in working + together (section [*]). Section [*] +Bugs gives a list of currently known active bugs. +The manual concludes with notes about +Copying and License (section [*]) and +references. + +

+ +


+Installing and Running JFlex +

+ +

+ +

+Installing JFlex +

+ +

+ +


+Windows +

+To install JFlex on Windows 95/98/NT/XP, follow these three steps: + +
    +
  1. Unzip the file you downloaded into the directory you want JFlex in (using +something like +WinZip). +If you unzipped it to say C:\, the following directory structure +should be generated: + +
    +C:\JFlex\                          
    +      +--bin\                   (start scripts) 
    +      +--doc\                   (FAQ and manual)
    +      +--examples\ 
    +               +--binary\       (scanning binary files)
    +               +--byaccj\       (calculator example for BYacc/J)
    +               +--cup\          (calculator example for cup)
    +               +--interpreter\  (interpreter example for cup)
    +               +--java\         (Java lexer specification) 
    +               +--simple\       (example scanner)
    +               +--standalone\   (a simple standalone scanner) 
    +      +--lib\                   (the precompiled classes) 
    +      +--src\ 
    +          +--JFlex\             (source code of JFlex) 
    +          +--JFlex\gui          (source code of JFlex UI classes)
    +          +--java_cup\runtime\  (source code of cup runtime classes)
    +
    + +

    +

  2. +
  3. Edit the file bin\jflex.bat +(in the example it's C:\JFlex\bin\jflex.bat) +such that + +

    + +

      +
    • JAVA_HOME contains the directory where your Java JDK is installed + (for instance C:\java) and +
    • +
    • JFLEX_HOME the directory that contains JFlex (in the example: + C:\JFlex) +
    • +
    + +

    +

  4. +
  5. Include the bin\ directory of JFlex in your path. +(the one that contains the start script, in the example: C:\JFlex\bin). +
  6. +
+ +

+ +

+Unix with tar archive +

+ +

+To install JFlex on a Unix system, follow these two steps: + +

    +
  • Uncompress the archive into a directory of your choice + with GNU tar, for instance to /usr/share: + +

    +tar -C /usr/share -xvzf jflex-1.4.tar.gz + +

    +(The example is for site wide installation. You need to + be root for that. User installation works exactly the + same way--just choose a directory where you have write + permission) + +

    +

  • +
  • Make a symbolic link from somewhere in your binary + path to bin/jflex, for instance: + +

    +ln -s /usr/share/JFlex/bin/jflex /usr/bin/jflex + +

    +If the java interpreter is not in your binary path, you + need to supply its location in the script bin/jflex. +

  • +
+ +

+You can verify the integrity of the downloaded file with +the MD5 checksum available on the JFlex download page. +If you put the checksum file in the same directory +as the archive, you run: + +

+md5sum --check jflex-1.4.tar.gz.md5 + +

+It should tell you + +

+jflex-1.4.tar.gz: OK + +

+ +

+Linux with RPM +

+ +

+ +

    +
  • become root +
  • +
  • issue +
    rpm -U jflex-1.4-0.rpm +
  • +
+ +

+You can verify the integrity of the downloaded rpm file with + +

+rpm --checksig jflex-1.4-0.rpm + +

+This requires my pgp public key. If you don't have it, you can use + +

+rpm --checksig --nopgp jflex-1.4-0.rpm + +

+or you can get it from http://www.jflex.de/public-key.asc. + +

+ +

+Running JFlex +

+You run JFlex with: + +

+jflex <options> <inputfiles> + +

+It is also possible to skip the start script in bin\ +and include the file lib\JFlex.jar +in your CLASSPATH environment variable instead. + +

+Then you run JFlex with: + +

+java JFlex.Main <options> <inputfiles> + +

+The input files and options are in both cases optional. If you don't provide a file name on +the command line, JFlex will pop up a window to ask you for one. + +

+JFlex knows about the following options: + +

+

+
+
-d <directory> +
writes the generated file to the directory <directory> + +

+

+
+
--skel <file> +
uses external skeleton <file>. This is mainly for JFlex + maintenance and special low level customizations. Use only when you + know what you are doing! JFlex comes with a skeleton file in the + src directory that reflects exactly the internal, precompiled + skeleton and can be used with the -skel option. + +

+

+
+
--nomin +
skip the DFA minimization step during scanner generation. + +

+

+
+
--jlex +
tries even harder to comply to JLex interpretation of specs. + +

+

+
+
--dot +
generate graphviz dot files for the NFA, DFA and minimized + DFA. This feature is still in alpha status, and not + fully implemented yet. + +

+

+
+
--dump +
display transition tables of NFA, initial DFA, and minimized DFA + +

+

+
+
--verbose or -v +
display generation progress messages (enabled by default) + +

+

+
+
--quiet or -q +
display error messages only (no chatter about what JFlex is + currently doing) + +

+

+
+
--time +
display time statistics about the code generation process + (not very accurate) + +

+

+
+
--version +
print version number + +

+

+
+
--info +
print system and JDK information (useful if you'd like + to report a problem) + +

+

+
+
--pack +
use the %pack code generation method by default + +

+

+
+
--table +
use the %table code generation method by default + +

+

+
+
--switch +
use the %switch code generation method by default + +

+

+
+
--help or -h +
print a help message explaining options and usage of JFlex. +
+
+ +

+ +


+A simple Example: How to work with JFlex +

+To demonstrate what a lexical specification with JFlex looks like, this +section presents a part of the specification for the Java language. +The example does not describe the whole lexical structure of Java programs, +but only a small and simplified part of it (some keywords, some operators, +comments and only two kinds of literals). It also shows how to interface +with the LALR parser generator CUP [8] and therefore +uses a class sym (generated by CUP), where integer constants for +the terminal tokens of the CUP grammar are declared. JFlex comes with a +directory examples, where you can find a small standalone scanner +that doesn't need other tools like CUP to give you a running example. +The "examples" directory also contains a complete JFlex +specification of the lexical structure of Java programs together with the +CUP parser specification for Java by +C. Scott Ananian, obtained +from the CUP [8] website (it was modified to interface with the JFlex scanner). +Both specifications adhere to the Java Language Specification [7]. + +

+

+/* JFlex example: part of Java language lexer specification */
+import java_cup.runtime.*;
+
+/**
+ * This class is a simple example lexer.
+ */
+%%
+
+
+%class Lexer
+%unicode
+%cup
+%line
+%column
+
+
+%{
+  StringBuffer string = new StringBuffer();
+
+  private Symbol symbol(int type) {
+    return new Symbol(type, yyline, yycolumn);
+  }
+  private Symbol symbol(int type, Object value) {
+    return new Symbol(type, yyline, yycolumn, value);
+  }
+%}
+
+
+LineTerminator = \r|\n|\r\n
+InputCharacter = [^\r\n]
+WhiteSpace     = {LineTerminator} | [ \t\f]
+
+/* comments */
+Comment = {TraditionalComment} | {EndOfLineComment} | {DocumentationComment}
+
+TraditionalComment   = "/*" [^*] ~"*/" | "/*" "*"+ "/"
+EndOfLineComment     = "//" {InputCharacter}* {LineTerminator}
+DocumentationComment = "/**" {CommentContent} "*"+ "/"
+CommentContent       = ( [^*] | \*+ [^/*] )*
+
+Identifier = [:jletter:] [:jletterdigit:]*
+
+DecIntegerLiteral = 0 | [1-9][0-9]*
+
+
+%state STRING
+
+%%
+
+
+/* keywords */
+<YYINITIAL> "abstract"           { return symbol(sym.ABSTRACT); }
+<YYINITIAL> "boolean"            { return symbol(sym.BOOLEAN); }
+<YYINITIAL> "break"              { return symbol(sym.BREAK); }
+
+
+<YYINITIAL> {
+  /* identifiers */ 
+  {Identifier}                   { return symbol(sym.IDENTIFIER); }
+ 
+  /* literals */
+  {DecIntegerLiteral}            { return symbol(sym.INTEGER_LITERAL); }
+  \"                             { string.setLength(0); yybegin(STRING); }
+
+  /* operators */
+  "="                            { return symbol(sym.EQ); }
+  "=="                           { return symbol(sym.EQEQ); }
+  "+"                            { return symbol(sym.PLUS); }
+
+  /* comments */
+  {Comment}                      { /* ignore */ }
+ 
+  /* whitespace */
+  {WhiteSpace}                   { /* ignore */ }
+}
+
+
+<STRING> {
+  \"                             { yybegin(YYINITIAL); 
+                                   return symbol(sym.STRING_LITERAL, 
+                                   string.toString()); }
+  [^\n\r\"\\]+                   { string.append( yytext() ); }
+  \\t                            { string.append('\t'); }
+  \\n                            { string.append('\n'); }
+
+  \\r                            { string.append('\r'); }
+  \\\"                           { string.append('\"'); }
+  \\                             { string.append('\\'); }
+}
+
+
+/* error fallback */
+.|\n                             { throw new Error("Illegal character <"+
+                                                    yytext()+">"); }
+
+ +

+From this specification JFlex generates a .java file with one +class that contains code for the scanner. The class will have a +constructor taking a java.io.Reader from which the input is +read. The class will also have a function yylex() that runs the +scanner and that can be used to get the next token from the input (in this +example the function actually has the name next_token() because +the specification uses the %cup switch). + +

+As with JLex, the specification consists of three parts, divided by %%: + +

+ +

+ +


+Code to include +

+Let's take a look at the first section, ``user code'': The text up to the +first line starting with %% is copied verbatim to the top +of the generated lexer class (before the actual class declaration). +Beside package and import statements there is usually not much +to do here. If the code ends with a javadoc class comment, the generated class +will get this comment, if not, JFlex will generate one automatically. + +

+ +


+Options and Macros +

+The second section ``options and declarations'' is more interesting. It consists +of a set of options, code that is included inside the generated scanner +class, lexical states and macro declarations. Each JFlex option must begin +a line of the specification and starts with a %. In our example +the following options are used: + +

+ +

    +
  • %class Lexer tells JFlex to give the + generated class the name ``Lexer'' and to write the code to a file ``Lexer.java''. + +

    +

  • +
  • %unicode defines the set of characters the scanner will + work on. For scanning text files, %unicode should always be used. See also + section [*] for more information on character sets, encodings, and + scanning text vs. binary files. + +

    +

  • +
  • %cup switches to CUP compatibility + mode to interface with a CUP generated parser. + +

    +

  • +
  • %line switches line counting on (the + current line number can be accessed via the variable yyline) + +

    +

  • +
  • %column switches column counting on + (current column is accessed via yycolumn) + +

    +

  • +
+ +

+The code included in %{...%} +is copied verbatim into the generated lexer class source. +Here you can declare member variables and functions that are used +inside scanner actions. In our example we declare a StringBuffer ``string'' +in which we will store parts of string literals and two helper functions +``symbol'' that create java_cup.runtime.Symbol objects +with position information of the current token (see section [*] +JFlex and CUP +for how to interface with the parser generator CUP). As JFlex options, both +%{ and \%} must begin a line. + +

+The specification continues with macro declarations. Macros are +abbreviations for regular expressions, used to make lexical specifications +easier to read and understand. A macro declaration +consists of a macro identifier followed by =, then followed by +the regular expression it represents. This regular expression may +itself contain macro usages. Although this allows a grammar like specification +style, macros are still just abbreviations and not non terminals - they +cannot be recursive or mutually recursive. Cycles in macro definitions +are detected and reported at generation time by JFlex. + +

+Here some of the example macros in more detail: + +

    +
  • LineTerminator stands for the regular + expression that matches an ASCII CR, an ASCII LF or an CR followed by LF. + +

    +

  • +
  • InputCharacter stands for all characters + that are not a CR or LF. + +

    +

  • +
  • TraditionalComment is the expression + that matches the string "/*" followed by a character that is not + a * followed by anything that matches the macro + CommentContent + followed by any number of * followed by /. + +

    +

  • +
  • CommentContent matches zero or more + occurrences of any character except a * or any number of + * followed by a character that is not a / + +

    +

  • +
  • Identifier matches each string that + starts with a character of class jletter followed by zero or more characters + of class jletterdigit. jletter and jletterdigit + are predefined character classes. jletter includes all characters for which + the Java function Character.isJavaIdentifierStart returns true and + jletterdigit all characters for that Character.isJavaIdentifierPart + returns true. +
  • +
+ +

+The last part of the second section in our +lexical specification is a lexical state declaration: +%state STRING +declares a lexical state STRING that can be +used in the ``lexical rules'' part of the specification. A state declaration +is a line starting with %state followed by a space or comma +separated list of state identifiers. There can be more than one line starting +with %state. + +

+ +


+Rules and Actions +

+The "lexical rules" section of a JFlex specification contains regular expressions +and actions (Java code) that are executed when the scanner matches the +associated regular expression. As the scanner reads its input, it keeps +track of all regular expressions and activates the action of the expression +that has the longest match. Our specification above for instance would with input +"breaker" match the regular expression for Identifier +and not the keyword "break" +followed by the Identifier "er", because rule {Identifier} +matches more of this input at once (i.e. it matches all of it) +than any other rule in the specification. If two regular expressions both +have the longest match for a certain input, the scanner chooses the action +of the expression that appears first in the specification. In that way, we +get for input "break" the keyword "break" and not an +Identifier "break". + +

+Additional to regular expression matches, one can use lexical states to +refine a specification. A lexical state acts like a start condition. +If the scanner is in lexical state STRING, only expressions that +are preceded by the start condition <STRING> can be matched. +A start condition of a regular expression can contain more than one lexical +state. It is then matched when the lexer is in any of these lexical states. +The lexical state YYINITIAL is predefined and is also the state +in which the lexer begins scanning. If a regular expression has no start +conditions it is matched in all lexical states. + +

+Since you often have a bunch of expressions with the same start conditions, +JFlex allows the same abbreviation as the Unix tool flex: +

+<STRING> {
+  expr1   { action1 }
+  expr2   { action2 }
+}
+
+means that both expr1 and expr2 have start condition <STRING>. + +

+The first three rules in our example demonstrate the syntax of a regular +expression preceded by the start condition <YYINITIAL>. + +

+<YYINITIAL> "abstract" { return symbol(sym.ABSTRACT); } + +

+matches the input "abstract" only if the scanner is in its +start state "YYINITIAL". When the string "abstract" is +matched, the scanner function returns the CUP symbol sym.ABSTRACT. +If an action does not return a value, the scanning process is resumed immediately +after executing the action. + +

+The rules enclosed in + +

+<YYINITIAL> { +
... +
}
+ +

+demonstrate the abbreviated syntax and are also only matched in state YYINITIAL. + +

+Of these rules, one may be of special interest: + +

+\" { string.setLength(0); yybegin(STRING); } + +

+If the scanner matches a double quote in state YYINITIAL we +have recognized the start of a string literal. Therefore we clear our StringBuffer +that will hold the content of this string literal and tell the scanner +with yybegin(STRING) to switch into the lexical state STRING. +Because we do not yet return a value to the parser, our scanner proceeds +immediately. + +

+In lexical state STRING another +rule demonstrates how to refer to the input that has been matched: + +

+[^\n\r\"]+ { string.append( yytext() ); } + +

+The expression [^\n\r\"]+ matches +all characters in the input up to the next backslash (indicating an +escape sequence such as \n), double quote (indicating the end +of the string), or line terminator (which must not occur in a string literal). +The matched region of the input is referred to with yytext() +and appended to the content of the string literal parsed so far. + +

+The last lexical rule in the example specification +is used as an error fallback. It matches any character in any state that +has not been matched by another rule. It doesn't conflict with any other +rule because it has the least priority (because it's the last rule) and +because it matches only one character (so it can't have longest match +precedence over any other rule). + +

+ +

+How to get it going +

+ +
    +
  • Install JFlex (see section [*] Installing JFlex) + +

    +

  • +
  • If you have written your specification file (or chosen one from the examples +directory), save it (say under the name java-lang.flex). + +

    +

  • +
  • Run JFlex with + +

    +jflex java-lang.flex + +

    +

  • +
  • JFlex should then report some progress messages about generating the scanner +and write the generated code to the directory of your specification file. + +

    +

  • +
  • Compile the generated .java file and your own classes. (If you +use CUP, generate your parser classes first) + +

    +

  • +
  • That's it. +
  • +
+ +

+ +


+Lexical Specifications +

+As shown above, a lexical specification file for JFlex consists of three +parts divided by a single line starting with %%: + +

+UserCode +
%% +
Options and declarations +
%% +
Lexical rules + +

+In all parts of the specification comments of the form +/* comment text */ and the Java style end of line comments starting with // +are permitted. JFlex comments do nest - so the number of /* and */ +should be balanced. + +

+ +


+User code +

+The first part contains user code that is copied verbatim into the beginning +of the source file of the generated lexer before the scanner class is declared. +As shown in the example above, this is the place to put package +declarations and import +statements. It is possible, but not considered as good Java programming +style to put own helper class (such as token classes) in this section. +They should get their own .java file instead. + +

+ +


+Options and declarations +

+The second part of the lexical specification contains options +to customize your generated lexer (JFlex directives and Java code to include in +different parts of the lexer), declarations of lexical states and +macro definitions for use in the third section +``Lexical rules'' of the lexical specification file. + +

+Each JFlex directive must be situated at the beginning of a line +and starts with the % character. Directives that have one or +more parameters are described as follows: + +

+%class "classname" + +

+means that you start a line with %class followed by a space followed +by the name of the class for the generated scanner (the double quotes are +not to be entered, see the example specification in +section [*]). + +

+ +


+Class options and user class code +

+These options regard name, constructor, API, and related parts of the +generated scanner class. + +
    +
  • %class "classname" + +

    +Tells JFlex to give the generated class the name "classname" and to +write the generated code to a file "classname.java". If the +-d <directory> command line option is not used, the code +will be written to the directory where the specification file resides. If +no %class directive is present in the specification, the generated +class will get the name "Yylex" and will be written to a file +"Yylex.java". There should be only one %class directive +in a specification. + +

    +

  • +
  • %implements "interface 1"[, "interface 2", ..] + +

    +Makes the generated class implement the specified interfaces. If more than +one %implements directive is present, all the specified interfaces +will be implemented. + +

    +

  • +
  • %extends "classname" + +

    +Makes the generated class a subclass of the class ``classname''. +There should be only one %extends directive in a specification. + +

    +

  • +
  • %public + +

    +Makes the generated class public (the class is only accessible in its +own package by default). + +

    +

  • +
  • %final + +

    +Makes the generated class final. + +

    +

  • +
  • %abstract + +

    +Makes the generated class abstract. + +

    +

  • +
  • %apiprivate + +

    +Makes all generated methods and fields of the class +private. Exceptions are the constructor, user code in the +specification, and, if %cup is present, the method +next_token. All occurences of +" public " (one space character before and after public) +in the skeleton file are replaced by +" private " (even if a user-specified skeleton is used). +Access to the genarated class is expected to be mediated by user class +code (see next switch). + +

    +

  • +
  • %{ +
    ... +
    %} + +

    +The code enclosed in %{ and %} is copied verbatim +into the generated class. Here you can define your own member variables +and functions in the generated scanner. Like all options, both %{ +and %} must start a line in the specification. If more than one +class code directive %{...%} is present, the code is concatenated +in order of appearance in the specification. + +

    +

  • +
  • %init{ +
    ... +
    %init} + +

    +The code enclosed in %init{ and %init} is copied +verbatim into the constructor of the generated class. Here, member +variables declared in the %{...%} directive can be initialized. +If more than one initializer option is present, the code is concatenated +in order of appearance in the specification. + +

    +

  • +
  • %initthrow{ +
    "exception1"[, "exception2", ...] +
    %initthrow} + +

    +or (on a single line) just + +

    +%initthrow "exception1" [, "exception2", ...] + +

    +Causes the specified exceptions to be declared in the throws +clause of the constructor. If more than one %initthrow{ ... %initthrow} +directive is present in the specification, all specified exceptions will +be declared. + +

    +

  • +
  • %scanerror "exception" + +

    +Causes the generated scanner to throw an instance of the specified +exception in case of an internal error (default is +java.lang.Error). Note that this exception is only for +internal scanner errors. With usual specifications it should never +occur (i.e. if there is an error fallback rule in the specification +and only the documented scanner API is used). + +

    +

  • +
  • %buffer "size" + +

    +Set the initial size of the scan buffer to the specified value +(decimal, in bytes). The default value is 16384. + +

    +

  • +
  • %include "filename" + +

    +Replaces the %include verbatim by the specified file. This +feature is still experimental. It works, but error reporting can be +strange if a syntax error occurs on the last token in the included +file. + +

    +

  • +
+ +

+ +


+Scanning method +

+This section shows how the scanning method can be customized. You can redefine +the name and return type of the method and it is possible to declare +exceptions that may be thrown in one of the actions of the specification. +If no return type is specified, the scanning method will be declared as +returning values of class Yytoken. + +
    +
  • %function "name" + +

    +Causes the scanning method to get the specified name. If no %function +directive is present in the specification, the scanning method gets the +name ``yylex''. This directive overrides settings of the +%cup switch. Please note that the default name +of the scanning method with the %cup switch is +next_token. Overriding this name might lead to the generated scanner +being implicitly declared as abstract, because it does not provide +the method next_token of the interface java_cup.runtime.Scanner. +It is of course possible to provide a dummy implemention of that method +in the class code section, if you still want to override the function name. + +

    +

  • +
  • %integer +
    %int + +

    +Both cause the scanning method to be declared as of Java type int. +Actions in the specification can then return int values as tokens. +The default end of file value under this setting is YYEOF, which is a public +static final int member of the generated class. + +

    +

  • +
  • %intwrap + +

    +Causes the scanning method to be declared as of the Java wrapper type +Integer. Actions in the specification can then return Integer +values as tokens. The default end of file value under this setting is null. + +

    +

  • +
  • %type "typename" + +

    +Causes the scanning method to be declared as returning values of the specified type. +Actions in the specification can then return values of typename +as tokens. The default end of file value under this setting is null. +If typename is not a subclass of java.lang.Object, +you should specify another end of file value using the +%eofval{ ... %eofval} +directive or the <<EOF>> rule. +The %type directive overrides settings of the +%cup switch. + +

    +

  • +
  • %yylexthrow{ +
    "exception1"[, "exception2", ... ] +
    %yylexthrow} + +

    +or (on a single line) just + +

    +%yylexthrow "exception1" [, "exception2", ...] + +

    +The exceptions listed inside %yylexthrow{ ... %yylexthrow} +will be declared in the throws clause of the scanning method. If there is +more than one %yylexthrow{ ... %yylexthrow} clause in +the specification, all specified exceptions will be declared. +

  • +
+ +

+ +


+The end of file +

+There is always a default value that the scanning method will return when +the end of file has been reached. You may however define a specific value +to return and a specific piece of code that should be executed when the +end of file is reached. + +

+The default end of file values depends on the return type of the scanning method: + +

    +
  • For %integer, the scanning method will return the value +YYEOF, which is a public static final int member +of the generated class. + +

    +

  • +
  • For %intwrap, +
  • +
  • no specified type at all, or a +
  • +
  • user defined type, declared using %type, the value is null. + +

    +

  • +
  • In CUP compatibility mode, using %cup, the value is + +

    +new java_cup.runtime.Symbol(sym.EOF) +

  • +
+ +

+User values and code to be executed at the end of file can be defined using these directives: + +

    +
  • %eofval{ +
    ... +
    %eofval} + +

    +The code included in %eofval{ ... %eofval} will +be copied verbatim into the scanning method and will be executed each time +when the end of file is reached (this is possible when +the scanning method is called again after the end of file has been +reached). The code should return the value that indicates the end of +file to the parser. There should be only one %eofval{ +... %eofval} clause in the specification. +The %eofval{ ... %eofval} directive overrides settings of the +%cup switch and %byaccj switch. +As of version 1.2 JFlex provides +a more readable way to specify the end of file value using the +<<EOF>> rule (see also section [*]). + +

    +

  • +
  • %eof{ +
    ... +
    %eof} + +

    +The code included in %{eof ... %eof} will be executed + exactly once, when the end of file is reached. The code is included + inside a method void yy_do_eof() and should not return any + value (use %eofval{...%eofval} or + <<EOF>> for this purpose). If more than one + end of file code directive is present, the code will be concatenated + in order of appearance in the specification. + +

    +

  • +
  • %eofthrow{ +
    "exception1"[,"exception2", ... ] +
    %eofthrow} + +

    +or (on a single line) just + +

    +%eofthrow "exception1" [, "exception2", ...] + +

    +The exceptions listed inside %eofthrow{...%eofthrow} will + be declared in the throws clause of the method yy_do_eof() + (see %eof for more on that method). + If there is more than one %eofthrow{...%eofthrow} clause + in the specification, all specified exceptions will be declared. + +

    +

  • +
  • %eofclose + +

    +Causes JFlex to close the input stream at the end of file. The code + yyclose() is appended to the method yy_do_eof() + (together with the code specified in %eof{...%eof}) and + the exception java.io.IOException is declared in the throws + clause of this method (together with those of + %eofthrow{...%eofthrow}) + +

    +

  • +
  • %eofclose false + +

    +Turns the effect of %eofclose off again (e.g. in case closing of + input stream is not wanted after %cup). + +

    +

  • +
+ +

+ +


+Standalone scanners +

+ +
    +
  • %debug + +

    +Creates a main function in the generated class that expects the name +of an input file on the command line and then runs the scanner on this +input file by printing information about each returned token to the Java +console until the end of file is reached. The information includes: +line number (if line counting is enabled), column (if column counting is enabled), +the matched text, and the executed action (with line number in the specification). + +

    +

  • +
  • %standalone + +

    +Creates a main function in the generated class that expects the name +of an input file on the command line and then runs the scanner on this +input file. The values returned by the scanner are ignored, but any unmatched +text is printed to the Java console instead (as the C/C++ tool flex does, if +run as standalone program). To avoid having to use an extra token class, the +scanning method will be declared as having default type int, not YYtoken +(if there isn't any other type explicitly specified). +This is in most cases irrelevant, but could be useful to know when making +another scanner standalone for some purpose. You should also consider using +the %debug directive, if you just want to be able to run the scanner +without a parser attached for testing etc. + +

    +

  • +
+ +

+ +


+CUP compatibility +

+You may also want to read section [*] JFlex and CUP +if you are interested in how to interface your generated +scanner with CUP. + +
    +
  • %cup + +

    +The %cup directive enables the CUP compatibility mode and is equivalent +to the following set of directives: + +

    +

    +%implements java_cup.runtime.Scanner
    +%function next_token
    +%type java_cup.runtime.Symbol
    +%eofval{
    +  return new java_cup.runtime.Symbol(<CUPSYM>.EOF);
    +%eofval}
    +%eofclose
    +
    + +

    +The value of <CUPSYM> defaults to sym and can be +changed with the %cupsym directive. In JLex compatibility +mode (-jlex switch on the command line), %eofclose +will not be turned on. + +

    +

  • +
  • %cupsym "classname" + +

    +Customizes the name of the CUP generated class/interface +containing the names of terminal tokens. Default is sym. +The directive should not be used after %cup, but before. + +

    +

  • +
  • %cupdebug + +

    +Creates a main function in the generated class that expects the name +of an input file on the command line and then runs the scanner on this +input file. Prints line, column, matched text, and CUP symbol name for +each returned token to standard out. + +

    +

  • +
+ +

+ +


+BYacc/J compatibility +

+You may also want to read section [*] JFlex and BYacc/J +if you are interested in how to interface your generated +scanner with Byacc/J. + +
    +
  • %byacc + +

    +The %byacc directive enables the BYacc/J compatibility mode and is equivalent +to the following set of directives: + +

    +

    +%integer
    +%eofval{
    +  return 0;
    +%eofval}
    +%eofclose
    +
    + +

    +

  • +
+ +

+ +


+Code generation +

+The following options define what kind of lexical analyzer code JFlex +will produce. %pack is the default setting and will be used, +when no code generation method is specified. + +

+ +

    +
  • %switch + +

    +With %switch JFlex will generate a scanner that has + the DFA hard coded into a nested switch statement. This method gives + a good deal of compression in terms of the size of the compiled + .class file while still providing very good performance. If your + scanner gets to big though (say more than about 200 states) + performance may vastly degenerate and you should consider using one + of the %table or %pack directives. If your scanner + gets even bigger (about 300 states), the Java compiler javac + could produce corrupted code, that will crash when executed or will + give you an java.lang.VerifyError when checked by the virtual + machine. This is due to the size limitation of 64 KB of Java + methods as described in the Java Virtual Machine Specification + [10]. In this case you will be forced to use the + %pack directive, since %switch + usually provides more compression of the DFA table than the + %table directive. + +

    +

  • +
  • %table + +

    +The %table direction causes JFlex to produce a classical + table driven scanner that encodes its DFA table in an array. In + this mode, JFlex only does a small amount of table compression (see + [6], [12], [1] and [13] + for more details on the matter of table compression) and uses the + same method that JLex did up to version 1.2.1. See section [*] + performance of this manual to compare + these methods. The same reason as above (64 KB size limitation of + methods) causes the same problem, when the scanner gets too big. + This is, because the virtual machine treats static initializers of + arrays as normal methods. You will in this case again be forced to + use the %pack directive to avoid the problem. + +

    +

  • +
  • %pack + +

    +%pack causes JFlex to compress the generated DFA table and to + store it in one or more string literals. JFlex takes care that the + strings are not longer than permitted by the class file format. + The strings have to be unpacked when + the first scanner object is created and initialized. + After unpacking the internal access to the DFA table is exactly the + same as with option %table -- the only extra work to be done + at runtime is the unpacking process which is quite fast (not noticeable + in normal cases). It is in time complexity proportional to the + size of the expanded DFA table, and it is static, + i.e. it is done only once for a certain scanner class -- no matter + how often it is instantiated. Again, see section + [*] performance + on the performance of these scanners + With %pack, there should be practically no + limitation to the size of the scanner. %pack is the default + setting and will be used when no code generation method is specified. +

  • +
+ +

+ +


+Character sets +

+ +
    +
  • %7bit + +

    +Causes the generated scanner to use an 7 bit input character set (character +codes 0-127). Because this is the default value in JLex, JFlex also defaults +to 7 bit scanners. If an input character with a code greater than 127 is +encountered in an input at runtime, the scanner will throw an ArrayIndexOutofBoundsException. +Not only because of this, you should consider using the %unicode directive. +See also section [*] for information about character encodings. + +

    +

  • +
  • %full +
    %8bit + +

    +Both options cause the generated scanner to use an 8 bit input character +set (character codes 0-255). If an input character with a code greater +than 255 is encountered in an input at runtime, the scanner will throw +an ArrayIndexOutofBoundsException. Note that even if your platform +uses only one byte per character, the Unicode value of a character may +still be greater than 255. If you are scanning text files, you should +consider using the %unicode directive. See also section [*] +for more information about character encodings. + +

    +

  • +
  • %unicode +
    %16bit + +

    +Both options cause the generated scanner to use the full 16 bit Unicode input +character set (character codes 0-65535). There will be no runtime overflow when +using this set of input characters. %unicode does not mean that the +scanner will read two bytes at a time. What is read and what constitutes a +character depends on the runtime platform. See also section [*] +for more information about character encodings. + +

    +

  • +
  • %caseless +
    %ignorecase + +

    +This option causes JFlex to handle all characters and strings in the +specification as if they were specified in both uppercase and lowercase form. +This enables an easy way to specify a scanner for a language with +case insensitive keywords. The string "break" in a specification is for instance +handled like the expression ([bB][rR][eE][aA][kK]). The %caseless +option does not change the matched text and does not effect character classes. So +[a] still only matches the character a and not A, too. +Which letters are uppercase and which lowercase letters, is defined by the Unicode standard +and determined by JFlex with the Java methods Character.toUpperCase and +Character.toLowerCase. In JLex compatibility +mode (-jlex switch on the command line), %caseless +and %ignorecase also affect character classes. + +

    +

  • +
+


+Line, character and column counting +

+ +
    +
  • %char + +

    +Turns character counting on. The int member variable yychar +contains the number of characters (starting with 0) from the beginning +of input to the beginning of the current token. + +

    +

  • +
  • %line + +

    +Turns line counting on. The int member variable yyline +contains the number of lines (starting with 0) from the beginning of input +to the beginning of the current token. + +

    +

  • +
  • %column + +

    +Turns column counting on. The int member variable yycolumn +contains the number of characters (starting with 0) from the beginning +of the current line to the beginning of the current token. + +

    +

  • +
+ +

+ +


+Obsolete JLex options +

+ +
    +
  • %notunix + +

    +This JLex option is obsolete in JFlex but still recognized as valid directive. +It used to switch between Windows and Unix kind of line terminators (\r\n +and \n) for the $ operator in regular expressions. JFlex +always recognizes both styles of platform dependent line terminators. + +

    +

  • +
  • %yyeof + +

    +This JLex option is obsolete in JFlex but still recognized as valid directive. +In JLex it declares a public member constant YYEOF. JFlex declares it in any case. +

  • +
+ +

+ +


+State declarations +

+State declarations have the following from: + +

+%s[tate] "state identifier" [, "state identifier", ... ] for inclusive or +
%x[state] "state identifier" [, "state identifier", ... ] for exlusive states + +

+There may be more than one line of state declarations, each starting with +%state or %xstate (the first character is sufficient, +%s and %x works, too). State identifiers are letters followed +by a sequence of letters, digits or underscores. State identifiers can be separated +by whitespace or comma. + +

+The sequence + +

+%state STATE1 +
%xstate STATE3, XYZ, STATE_10 +
%state ABC STATE5 + +

+declares the set of identifiers STATE1, STATE3, XYZ, + STATE_10, ABC, STATE5 as lexical states, STATE1, ABC, STATE5 +as inclusive, and STATE3, XYZ, STATE_10 as exclusive. +See also section +[*] on the way lexical states influence how the input is +matched. + +

+ +


+Macro definitions +

+A macro definition has the form + +

+macroidentifier = regular expression + +

+That means, a macro definition is a macro identifier (letter followed +by a sequence of letters, digits or underscores), that can later be +used to reference the macro, followed by optional whitespace, followed +by an "=", followed by optional whitespace, followed by a +regular expression (see section [*] lexical + rules for more information about regular expressions). + +

+The regular expression on the right hand side must be well formed and +must not contain the ^, / or $ operators. Differently +to JLex, macros are not just pieces of text that are expanded by copying +- they are parsed and must be well formed. + +

+This is a feature. It eliminates some very hard to find bugs in +lexical specifications (such like not having parentheses around more +complicated macros - which is not necessary with JFlex). See section +[*] Porting from JLex for more +details on the problems of JLex style macros. + +

+Since it is allowed to have macro usages in macro definitions, it is +possible to use a grammar like notation to specify the desired lexical +structure. Macros however remain just abbreviations of the regular expressions +they represent. They are not non terminals of a grammar and cannot be used +recursively in any way. JFlex detects cycles in macro definitions and reports +them at generation time. JFlex also warns you about macros that have been +defined but never used in the ``lexical rules'' section of the specification. + +

+ +


+Lexical rules +

+The ``lexical rules'' section of an JFlex specification contains a set of +regular expressions and actions (Java code) that are executed when the +scanner matches the associated regular expression. + +

+ +


+Syntax +

+The syntax of the "lexical rules" section is described by the following +BNF grammar (terminal symbols are enclosed in 'quotes'): + +

+

+LexicalRules ::= Rule+ 
+Rule         ::= [StateList] ['^'] RegExp [LookAhead] Action 
+               | [StateList] '<<EOF>>' Action
+               | StateGroup 
+StateGroup   ::= StateList '{' Rule+ '}' 
+StateList    ::= '<' Identifier (',' Identifier)* '>' 
+LookAhead    ::= '$' | '/' RegExp
+Action       ::= '{' JavaCode '}' | '|'
+
+RegExp       ::= RegExp '|' RegExp 
+               | RegExp RegExp 
+               | '(' RegExp ')'
+               | ('!'|'~') RegExp
+               | RegExp ('*'|'+'|'?')
+               | RegExp "{" Number ["," Number] "}" 
+               | '[' ['^'] (Character|Character'-'Character)* ']' 
+               | PredefinedClass 
+               | '{' Identifier '}' 
+               | '"' StringCharacter+ '"' 
+               | Character 
+
+PredefinedClass ::= '[:jletter:]' 
+                  | '[:jletterdigit:]' 
+                  | '[:letter:]' 
+                  | '[:digit:]' 
+                  | '[:uppercase:]' 
+                  | '[:lowercase:]' 
+                  | '.'
+
+ +

+The grammar uses the following terminal symbols: + +

    +
  • JavaCode +
    a sequence of BlockStatements as described in the Java + Language Specification [7], section 14.2. + +

    +

  • +
  • Number +
    a non negative decimal integer. + +

    +

  • +
  • Identifier +
    a letter [a-zA-Z] followed by a sequence of zero or more + letters, digits or underscores [a-zA-Z0-9_] + +

    +

  • +
  • Character +
    an escape sequence or any unicode character that is not one of these + meta characters: + | ( ) { } [ ] < > \ . * + ? ^ $ / . " ~ ! + +

    +

  • +
  • StringCharacter +
    an escape sequence or any unicode character that is not one of these + meta characters: + \ " + +

    +

  • +
  • An escape sequence + +

    + +

      +
    • \n \r \t \f \b +
    • +
    • a \x followed by two hexadecimal digits [a-fA-F0-9] (denoting + a standard ASCII escape sequence), + +

      +

    • +
    • a \u followed by four hexadecimal digits [a-fA-F0-9] + (denoting an unicode escape sequence), + +

      +

    • +
    • a backslash followed by a three digit octal number from 000 to 377 (denoting + a standard ASCII escape sequence), or + +

      +

    • +
    • a backslash followed by any other unicode character that stands for this + character. + +

      +

    • +
    + +

    +

  • +
+ +

+Please note that the \n escape sequence stands for the ASCII +LF character - not for the end of line. If you would like to match the +line terminator, you should use the expression \r|\n|\r\n if you want +the Java conventions, or \r|\n|\r\n|\u2028|\u2029|\u000B|\u000C|\u0085 +if you want to be fully Unicode compliant (see also [5]). + +

+As of version 1.1 of JFlex the whitespace characters " " +(space) and "\t" (tab) can be used to improve the readability of +regular expressions. They will be ignored by JFlex. In character +classes and strings however, whitespace characters keep standing for +themselves (so the string " " still matches exactly one space +character and [ \n] still matches an ASCII LF or a space +character). + +

+JFlex applies the following standard operator precedences in regular +expression (from highest to lowest): + +

+ +

    +
  • unary postfix operators ('*', '+', '?', {n}, {n,m}) + +

    +

  • +
  • unary prefix operators ('!', '~') + +

    +

  • +
  • concatenation (RegExp::= RegExp Regexp) + +

    +

  • +
  • union (RegExp::= RegExp '|' RegExp) +
  • +
+ +

+So the expression a | abc | !cd* for instance is parsed as +(a|(abc)) | ((!c)(d*)). + +

+ +


+Semantics +

+This section gives an informal description of which text is matched by +a regular expression (i.e. an expression described by the RegExp +production of the grammar presented above). + +

+A regular expression that consists solely of + +

    +
  • a Character matches this character. + +

    +

  • +
  • a character class '[' (Character|Character'-'Character)* ']' matches + any character in that class. A Character is to be considered an + element of a class, if it is listed in the class or if its code lies within + a listed character range Character'-'Character. So [a0-3\n] + for instance matches the characters + +

    +a 0 1 2 3 \n + +

    +If the list of characters is empty (i.e. just []), the expression + matches nothing at all (the empty set), not even the empty string. This + may be useful in combination with the negation operator '!'. + +

    +

  • +
  • a negated character class '[^' (Character|Character'-'Character)* ']' + matches all characters not listed in the class. If the list of characters + is empty (i.e. [^]), the expression matches any character of the + input character set. + +

    +

  • +
  • a string '"' StringCharacter+ '" ' matches the exact + text enclosed in double quotes. All meta characters but \ and + " loose their special meaning inside a string. See also the + %ignorecase switch. + +

    +

  • +
  • a macro usage '{' Identifier '}' matches the input that is matched + by the right hand side of the macro with name "Identifier". + +

    +

  • +
  • a predefined character class matches any of + the characters in that class. There are the following predefined character + classes: + +

    +. contains all characters but \n. + +

    +All other predefined character classes are defined in the Unicode + specification or the Java Language Specification and determined by + Java functions of class + java.lang.Character. + +

    +

    +[:jletter:]      isJavaIdentifierStart()
    +[:jletterdigit:] isJavaIdentifierPart()
    +[:letter:]       isLetter()
    +[:digit:]        isDigit()
    +[:uppercase:]    isUpperCase()
    +[:lowercase:]    isLowerCase()
    +
    + +

    +They are especially useful when working with the unicode character set. + +

    +

  • +
+ +

+If a and b are regular expressions, then + +

+

+
a | b
+
(union) + +

+is the regular expression, that matches + all input that is matched by a or by b. + +

+

+
a b
+
(concatenation) + +

+is the regular expression, + that matches the input matched by a followed by the + input matched by b. + +

+

+
a*
+
(kleene closure) + +

+matches zero or more repetitions + of the input matched by a + +

+

+
a+
+
(iteration) + +

+is equivalent to aa* + +

+

+
a?
+
(option) + +

+matches the empty input or the input matched + by a + +

+

+
!a
+
(negation) + +

+matches everything but the strings matched by a. + Use with care: the construction of !a involves + an additional, possibly exponential NFA to DFA transformation + on the NFA for a. Note that + with negation and union you also have (by applying DeMorgan) + intersection and set difference: the intersection of + a and b is !(!a|!b), the expression + that matches everything of a not matched by b is + !(!a|b) + +

+

+
~a
+
(upto) + +

+matches everything up to (and including) the first occurrence of a text + matched by a. The expression ~a is equivalent + to !([^]* a [^]* | "") a. A traditional C-style comment + is matched by "/*" ~"*/" + +

+

+
a{n}
+
(repeat) + +

+is equivalent to n times the concatenation of a. + So a{4} for instance is equivalent to the expression a a a a. + The decimal integer n must be positive. + +

+

+
a{n,m}
+
is equivalent to at least n times and at most m times the + concatenation of a. So a{2,4} for instance is equivalent + to the expression a a a? a?. Both n and m are non + negative decimal integers and m must not be smaller than n. + +

+

+
( a )
+
matches the same input as a. + +

+

+
+ +

+In a lexical rule, a regular expression r may be preceded by a +'^' (the beginning of line operator). r is then +only matched at the beginning of a line in the input. A line begins +after each occurrence of \r|\n|\r\n|\u2028|\u2029|\u000B|\u000C|\u0085 +(see also [5]) and at the beginning of input. +The preceding line terminator in the input is not consumed and can +be matched by another rule. + +

+In a lexical rule, a regular expression r may be followed by a +lookahead expression. A lookahead expression is either a '$' +(the end of line operator) or a '/' followed by an arbitrary +regular expression. In both cases the lookahead is not consumed and +not included in the matched text region, but it is considered +while determining which rule has the longest match (see also +[*] How the input is matched). + +

+In the '$' case r is only matched at the end of a line in +the input. The end of a line is denoted by the regular expression +\r|\n|\r\n|\u2028|\u2029|\u000B|\u000C|\u0085. +So a$ is equivalent to a / \r|\n|\r\n|\u2028|\u2029|\u000B|\u000C|\u0085.This is a bit different to the situation described in [5]: +since in JFlex $ is a true trailing context, the end of file +does not count as end of line. + +

+ +

+For arbitrary lookahead (also called trailing context) the +expression is matched only when followed by input that matches the +trailing context. Unfortunately the lookahead expression is not +really arbitrary: In a rule r1 / r2, either the text matched +by r1 must have a fixed length (e.g. if r1 is a string) +or the beginning of the trailing context r2 must not match the +end of r1. So for example "abc" / "a"|"b" is ok because +"abc" has a fixed length, "a"|"ab" / "x"* is ok because +no prefix of "x"* matches a postfix of "a"|"ab", but +"x"|"xy" / "yx" is not possible, because the postfix "y" +of "x"|"xy" is also a prefix of "yx". JFlex will report +such cases at generation time. The algorithm JFlex currently uses for matching +trailing context expressions is the one described in [1] (leading +to the deficiencies mentioned above). + +

+As of version 1.2, JFlex allows lex/flex style «EOF» rules in +lexical specifications. A rule +

+[StateList]  <<EOF>>    { some action code }
+
+is very similar to the %eofval directive (section [*]). +The difference lies in the optional StateList that may precede the «EOF» rule. The +action code will only be executed when the end of file is read and the +scanner is currently in one of the lexical states listed in StateList. +The same StateGroup (see section [*] +How the input is matched) and precedence +rules as in the ``normal'' rule case apply +(i.e. if there is more than one «EOF» +rule for a certain lexical state, the action of the one appearing +earlier in the specification will be executed). «EOF» rules +override settings of the %cup and %byaccj options and +should not be mixed with the %eofval directive. + +

+An Action consists either of a piece of Java code enclosed in +curly braces or is the special | action. The | action is +an abbreviation for the action of the following expression. + +

+Example: +

+expression1   |
+expression2   |
+expression3   { some action }
+
+is equivalent to the expanded form +
+expression1   { some action }
+expression2   { some action }
+expression3   { some action }
+
+ +

+They are useful when you work with trailing context expressions. The +expression a | (c / d) | b is not syntactically legal, but can +easily be expressed using the | action: +

+a       |
+c / d   |
+b       { some action }
+
+ +

+ +


+How the input is matched +

+When consuming its input, the scanner determines the regular expression +that matches the longest portion of the input (longest match rule). If +there is more than one regular expression that matches the longest portion +of input (i.e. they all match the same input), the generated scanner chooses +the expression that appears first in the specification. After determining +the active regular expression, the associated action is executed. If there +is no matching regular expression, the scanner terminates the program with +an error message (if the %standalone directive has been used, the +scanner prints the unmatched input to java.lang.System.out instead +and resumes scanning). + +

+Lexical states can be used to further restrict the set of regular expressions +that match the current input. + +

+ +

    +
  • A regular expression can only be matched when its associated set of lexical +states includes the currently active lexical state of the scanner or if +the set of associated lexical states is empty and the currently active lexical +state is inclusive. Exclusive and inclusive states only differ at this point: +rules with an empty set of associated states. + +

    +

  • +
  • The currently active lexical state of the scanner can be changed from within +an action of a regular expression using the method yybegin(). + +

    +

  • +
  • The scanner starts in the inclusive lexical state +YYINITIAL, which is always declared by default. + +

    +

  • +
  • The set of lexical states associated with a regular expression is +the StateList that precedes the expression. If a rule is +contained in one or more StateGroups, then the states of +these are also associated with the rule, i.e. they accumulate over +StateGroups. + +

    +Example: +

    +%states A, B
    +%xstates C
    +%%
    +expr1                   { yybegin(A); action }
    +<YYINITIAL, A> expr2    { action }
    +<A> {
    +  expr3                 { action }
    +  <B,C> expr4           { action }
    +}
    +
    +The first line declares two (inclusive) lexical states A and B, +the second line an exclusive lexical state C. +The default (inclusive) state YYINITIAL is always implicitly there and +doesn't need to be declared. The rule with expr1 has no +states listed, and is thus matched in all states but the exclusive +ones, i.e. A, B, and YYINITIAL. In its +action, the scanner is switched to state A. The second rule +expr2 can only match when the scanner is in state +YYINITIAL or A. The rule expr3 can only be +matched in state A and expr4 in states A, B, +and C. + +

    +

  • +
  • Lexical states are declared and used as Java int constants in +the generated class under the same name as they are used in the specification. +There is no guarantee that the values of these integer constants are +distinct. They are pointers into the generated DFA table, and if JFlex +recognizes two states as lexically equivalent (if they are used with the +exact same set of regular expressions), then the two constants will get +the same value. + +

    +

  • +
+ +

+ +

+The generated class +

+JFlex generates exactly one file containing one class from the specification +(unless you have declared another class in the first specification section). + +

+The generated class contains (among other things) the DFA tables, an input buffer, +the lexical states of the specification, a constructor, and the scanning method +with the user supplied actions. + +

+The name of the class is by default Yylex, it is customizable +with the %class directive (see also section +[*]). The input buffer of the lexer is connected with an +input stream over the java.io.Reader object which is passed +to the lexer in the generated constructor. If you want to provide your +own constructor for the lexer, you should always call the generated +one in it to initialize the input buffer. The input buffer should not +be accessed directly, but only over the advertised API (see also +section [*]). Its internal implementation may change +between releases or skeleton files without notice. + +

+The main interface to the outside world is the generated scanning +method (default name yylex, default return type +Yytoken). Most of its aspects are customizable (name, return +type, declared exceptions etc., see also section +[*]). If it is called, it will consume input until +one of the expressions in the specification is matched or an error +occurs. If an expression is matched, the corresponding action is +executed. It may return a value of the specified return type (in which +case the scanning method return with this value), or if it doesn't +return a value, the scanner resumes consuming input until the next +expression is matched. If the end of file is reached, the scanner +executes the EOF action, and (also upon each further call to the scanning +method) returns the specified EOF value (see also section [*]). + +

+ +


+Scanner methods and fields accessible in actions (API) +

+Generated methods and member fields in JFlex scanners are prefixed +with yy to indicate that they are generated and to avoid name +conflicts with user code copied into the class. Since user code is +part of the same class, JFlex has no language means like the +private modifier to indicate which members and methods are +internal and which ones belong to the API. Instead, JFlex follows a +naming convention: everything starting with a zz prefix like +zzStartRead is to be considered internal and subject to +change without notice between JFlex releases. Methods and members of +the generated class that do not have a zz prefix like +yycharat belong to the API that the scanner class provides to +users in action code of the specification. They will be remain stable +and supported between JFlex releases as long as possible. + +

+Currently, the API consists of the following methods and member fields: + +

    +
  • String yytext() +
    returns the matched input text region + +

    +

  • +
  • int yylength() +
    returns the length of the matched input text region (does not require + a String object to be created) + +

    +

  • +
  • char yycharat(int pos) +
    returns the character at position pos from the matched text. + It is equivalent to yytext().charAt(pos), but faster. pos must be a value from 0 to yylength()-1. + +

    +

  • +
  • void yyclose() +
    closes the input stream. All subsequent calls to the scanning method will + return the end of file value + +

    +

  • +
  • void yyreset(java.io.Reader reader) +
    closes the current input stream, and resets the scanner to read from + a new input stream. All internal variables are reset, the old input + stream cannot be reused (content of the internal buffer is + discarded and lost). The lexical state is set to YY_INITIAL. + +

    +

  • +
  • void yypushStream(java.io.Reader reader) +
    Stores the current input stream on a stack, and + reads from a new stream. Lexical state, line, + char, and column counting remain untouched. + The current input stream can be restored with + yypopstream (usually in an «EOF» action). + +

    +A typical example for this are include files in + style of the C preprocessor. The corresponding + JFlex specification could look somewhat like this: +

    +"#include" {FILE}  { yypushStream(new FileReader(getFile(yytext()))); }
    +..
    +<<EOF>>        { if (yymoreStreams()) yypopStream(); else return EOF; }
    +
    + +

    +This method is only available in the skeleton file + skeleton.nested. You can find it in the + src directory of the JFlex distribution. + +

    +

  • +
  • void yypopStream() +
    Closes the current input stream and continues to + read from the one on top of the stream stack. + +

    +This method is only available in the skeleton file + skeleton.nested. You can find it in the + src directory of the JFlex distribution. + +

    +

  • +
  • boolean yymoreStreams() +
    Returns true iff there are still streams for yypopStream + left to read from on the stream stack. + +

    +This method is only available in the skeleton file + skeleton.nested. You can find it in the + src directory of the JFlex distribution. + +

    +

  • +
  • int yystate() +
    returns the current lexical state of the scanner. + +

    +

  • +
  • void yybegin(int lexicalState) +
    enters the lexical state lexicalState + +

    +

  • +
  • void yypushback(int number) +
    pushes number characters of the matched text back into the inputstream. + They will be read again in the next call of the scanning method. + The number of characters to be read again must not be greater than the length + of the matched text. The pushed back characters will after the call of + yypushback not be included in yylength and yytext(). + Please note that in Java strings are unchangeable, i.e. an action code like +
    +    String matched = yytext();
    +    yypushback(1);
    +    return matched;
    +
    + will return the whole matched text, while +
    +    yypushback(1);
    +    return yytext();
    +
    + will return the matched text minus the last character. + +

    +

  • +
  • int yyline +
    contains the current line of input (starting with 0, only active with + the %line directive) + +

    +

  • +
  • int yychar +
    contains the current character count in the input (starting with 0, + only active with the %char directive) + +

    +

  • +
  • int yycolumn +
    contains the current column of the current line (starting with 0, only + active with the %column directive) + +

    +

  • +
+ +

+ +


+Encodings, Platforms, and Unicode +

+ +

+This section tries to shed some light on the issues of Unicode and +encodings, cross platform scanning, and how to deal with binary data. +My thanks go to Stephen Ostermiller for his input on this topic. + +

+ +


+The Problem +

+ +

+Before we dive straight into details, let's take a look at what the +problem is. The problem is Java's platform independence when you want +to use it. For scanners the interesting part about platform +independence is character encodings and how they are handled. + +

+If a program reads a file from disk, it gets a stream of bytes. In +earlier times, when the grass was green, and the world was much +simpler, everybody knew that the byte value 65 is, of course, an A. +It was no problem to see which bytes meant which characters (actually +these times never existed, but anyway). The normal Latin alphabet +only has 26 characters, so 7 bits or 128 distinct values should surely +be enough to map them, even if you allow yourself the luxury of upper +and lower case. Nowadays, things are different. The world suddenly +grew much larger, and all kinds of people wanted all kinds of special +characters, just because they use them in their language and writing. +This is were the mess starts. Since the 128 distinct values were +already filled up with other stuff, people began to use all 8 bits of +the byte, and extended the byte/character mappings to fit their need, +and of course everybody did it differently. Some people for instance +may have said ``let's use the value 213 for the German character ä''. Others +may have found that 213 should much rather mean é, because they didn't need +German and wrote French instead. As long as you use your program and +data files only on one platform, this is no problem, as all know what +means what, and everything gets used consistently. + +

+Now Java comes into play, and wants to run everywhere (once written, +that is) and now there suddenly is a problem: how do I get the same +program to say ä to a certain byte when it runs in Germany and maybe é +when it runs in France? And also the other way around: when I want to +say é on the screen, which byte value should I send to the operating +system? + +

+Java's solution to this is to use Unicode internally. Unicode aims to +be a superset of all known character sets and is therefore a perfect base +for encoding things that might get used all over the world. To make +things work correctly, you still have to know where you are and how to +map byte values to Unicode characters and vice versa, but the +important thing is, that this mapping is at least possible (you can +map Kanji characters to Unicode, but you cannot map them to ASCII or +iso-latin-1). + +

+ +


+Scanning text files +

+ +

+Scanning text files is the standard application for scanners like +JFlex. Therefore it should also be the most convenient one. Most times +it is. + +

+The following scenario works like a breeze: +You work on a platform X, write your lexer specification there, can +use any obscure Unicode character in it as you like, and compile the +program. Your users work on any platform Y (possibly but not +necessarily something different from X), they write their input files +on Y and they run your program on Y. No problems. + +

+Java does this as follows: +If you want to read anything in Java that is supposed to contain text, +you use a FileReader or some InputStream together with +an InputStreamReader. InputStreams return the raw bytes, the +InputStreamReader converts the bytes into Unicode characters with +the platform's default encoding. If a text file is produced on the +same platform, the platform's default encoding should do the mapping +correctly. Since JFlex also uses readers and Unicode internally, this +mechanism also works for the scanner specifications. If you write an +A in your text editor and the editor uses the platform's encoding (say A is 65), +then Java translates this into the logical Unicode A internally. +If a user writes an A on a completely different platform (say A is 237 there), +then Java also translates this into the logical Unicode A internally. Scanning +is performed after that translation and both match. + +

+Note that because of this mapping from bytes to characters, you should always +use the %unicode switch in you lexer specification if you want to scan +text files. %8bit may not be enough, even if +you know that your platform only uses one byte per character. The encoding +Cp1252 used on many Windows machines for instance knows 256 characters, but +the character ´ with Cp1252 code \x92 has the Unicode value \u2019, which +is larger than 255 and which would make your scanner throw an +ArrayIndexOutOfBoundsException if it is encountered. + +

+So for the usual case you don't have to do anything but use the +%unicode switch in your lexer specification. + +

+Things may break when you produce a text file on platform X and +consume it on a different platform Y. Let's say you have a file +written on a Windows PC using the encoding Cp1252. Then you move +this file to a Linux PC with encoding ISO 8859-1 and there you want +to run your scanner on it. Java now thinks the file is encoded +in ISO 8859-1 (the platform's default encoding) while it really is +encoded in Cp1252. For most characters +Cp1252 and ISO 8859-1 are the same, but for the byte values \x80 +to \x9f they disagree: ISO 8859-1 is undefined there. You can fix +the problem by telling Java explicitly which encoding to use. When +constructing the InputStreamReader, you can give the encoding +as argument. The line +

+Reader r = new InputStreamReader(input, "Cp1252"); + +
+will do the trick. + +

+Of course the encoding to use can also come from the data itself: +for instance, when you scan a HTML page, it may have embedded +information about its character encoding in the headers. + +

+More information about encodings, which ones are supported, how +they are called, and how to set them may be found in the +official Java documentation in the chapter about +internationalization. +The link +http://java.sun.com/j2se/1.3/docs/guide/intl/ +leads to an online version of this for Sun's JDK 1.3. + +

+ +


+Scanning binaries +

+ +

+Scanning binaries is both easier and more difficult +than scanning text files. It's easier because you want +the raw bytes and not their meaning, i.e. you don't want +any translation. +It's more difficult because it's not so easy to get +``no translation'' when you use Java readers. + +

+The problem (for binaries) is that JFlex scanners are +designed to work on text. Therefore the interface is +the Reader class (there is a constructor +for InputStream instances, but it's just there +for convenience and wraps an InputStreamReader +around it to get characters, not bytes). +You can still get a binary scanner when you write +your own custom InputStreamReader class that +does explicitly no translation, but just copies +byte values to character codes instead. It sounds +quite easy, and actually it is no big deal, but there +are a few little pitfalls on the way. In the scanner +specification you can only enter positive character +codes (for bytes that is \x00 +to \xFF). Java's byte type on the other hand +is a signed 8 bit integer (-128 to 127), so you have to convert +them properly in your custom Reader. Also, you should +take care when you write your lexer spec: if you +use text in there, it gets interpreted by an encoding +first, and what scanner you get as result might depend +on which platform you run JFlex on when you generate +the scanner (this is what you want for text, but for binaries it +gets in the way). If you are not sure, or if the development +platform might change, it's probably best to use character +code escapes in all places, since they don't change their +meaning. + +

+To illustrate these points, the example in examples/binary +contains a very small binary scanner that tries to +detect if a file is a Java class file. For that +purpose it looks if the file begins with the magic number \xCAFEBABE. + +

+ +


+A few words on performance +

+This section gives some empirical results about the speed of JFlex generated +scanners in comparison to those generated by JLex, +compares a JFlex scanner with a handwritten +one, and presents some tips on how to make +your specification produce a faster scanner. + +

+ +


+Comparison of JLex and JFlex +

+Scanners generated by the tool JLex are quite fast. It was however +possible to further improve the performance of generated scanners +using JFlex. The following table shows the results that were produced +by the scanner specification of a small toy programming language (in +fact the example from the JLex website). The scanner was generated +using JLex and all three different JFlex code generation methods. Then +it was run on a W98 system using Sun's JDK 1.3 with different sample inputs +of that toy programming language. All test runs were made under the +same conditions on an otherwise idle machine. + +

+The values presented in the table denote the time from the first call +to the scanning method to returning the EOF value and the speedup in +percent. The tests were run both int the mixed (HotSpot) JVM mode and +the pure interpreted mode. The mixed mode JVM brings +about a factor of 10 performance improvement, the difference between +JLex and JFlex only decreases slightly. + +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
 KBJVMJLex%switchspeedup%tablespeedup%packspeedup
 496hotspot325 ms261 ms24.5 %261 ms24.5 %261 ms24.5 %
 187hotspot127 ms98 ms29.6 %94 ms35.1 %96 ms32.3 %
 93hotspot66 ms50 ms32.0 %50 ms32.0 %48 ms37.5 %
 496interpr.4009 ms3025 ms32.5 %3258 ms23.1 %3231 ms24.1 %
 187interpr.1641 ms1155 ms42.1 %1245 ms31.8 %1234 ms33.0 %
 93interpr.817 ms573 ms42.6 %617 ms32.4 %613 ms33.3 %
+ +


+ +

+Since the scanning time of the lexical analyzer examined in the table +above includes lexical actions that often need to create new object instances, +another table shows the execution time for the same specification with empty +lexical actions to compare the pure scanning engines. + +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
 KBJVMJLex%switchspeedup%tablespeedup%packspeedup
 496hotspot204 ms140 ms45.7 %138 ms47.8 %140 ms45.7 %
 187hotspot83 ms55 ms50.9 %52 ms59.6 %52 ms59.6 %
 93hotspot41 ms28 ms46.4 %26 ms57.7 %26 ms57.7 %
 496interpr.2983 ms2036 ms46.5 %2230 ms33.8 %2232 ms33.6 %
 187interpr.1260 ms793 ms58.9 %865 ms45.7 %867 ms45.3 %
 93interpr.628 ms395 ms59.0 %432 ms45.4 %432 ms45.4 %
+ +


+ +

+Execution time of single instructions depends on the platform and +the implementation of the Java Virtual Machine the program is executed +on. Therefore the tables above cannot be used as a reference to which +code generation method of JFlex is the right one to choose in general. +The following table was produced by the same lexical specification and +the same input on a Linux system also using Sun's JDK 1.3. + +

+With actions: + +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
 KBJVMJLex%switchspeedup%tablespeedup%packspeedup
 496hotspot246 ms203 ms21.2 %193 ms27.5 %190 ms29.5 %
 187hotspot99 ms76 ms30.3 %69 ms43.5 %70 ms41.4 %
 93hotspot48 ms36 ms33.3 %34 ms41.2 %35 ms37.1 %
 496interpr.3251 ms2247 ms44.7 %2430 ms33.8 %2444 ms33.0 %
 187interpr.1320 ms848 ms55.7 %958 ms37.8 %920 ms43.5 %
 93interpr.658 ms423 ms55.6 %456 ms44.3 %452 ms45.6 %
+ +


+ +

+Without actions: + +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
 KBJVMJLex%switchspeedup%tablespeedup%packspeedup
 496hotspot136 ms78 ms74.4 %76 ms78.9 %77 ms76.6 %
 187hotspot59 ms31 ms90.3 %48 ms22.9 %32 ms84.4 %
 93hotspot28 ms15 ms86.7 %15 ms86.7 %15 ms86.7 %
 496interpr.1992 ms1047 ms90.3 %1246 ms59.9 %1215 ms64.0 %
 187interpr.859 ms408 ms110.5 %479 ms79.3 %487 ms76.4 %
 93interpr.435 ms200 ms117.5 %237 ms83.5 %242 ms79.8 %
+ +


+ +

+Although all JFlex scanners were faster than those generated by JLex, +slight differences between JFlex code generation methods show up when compared +to the run on the W98 system. + +

+The following table compares a handwritten scanner for the Java language +obtained from the website of CUP with the JFlex generated scanner for Java +that comes with JFlex in the examples directory. They were tested +on different .java files on a Linux machine with Sun's JDK 1.3. + +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
 linesKBJVMhandwritten scannerJFlex generated scanner
 19050496hotspot824 ms248 ms235 % faster
 6350165hotspot272 ms84 ms232 % faster
 127033hotspot53 ms18 ms194 % faster
 19050496interpreted5.83 s3.85 s51 % faster
 6350165interpreted1.95 s1.29 s51 % faster
 127033interpreted0.38 s0.25 s52 % faster
+ +


+ +

+Although JDK 1.3 seems to speed up the handwritten scanner if compared +to JDK 1.1 or 1.2 more than the generated one, the generated scanner is +still up to 3.3 times as fast as the handwritten one. One example of +a handwritten scanner that is +considerably slower than the equivalent generated one is surely no +proof for all generated scanners being faster than handwritten. It is +clearly impossible to prove something like that, since you could +always write the generated scanner by hand. From a software +engineering point of view however, there is no excuse for writing a +scanner by hand since this task takes more time, is more difficult and +therefore more error prone than writing a compact, readable and easy +to change lexical specification. (I'd like to add, that I do not +think, that the handwritten scanner from the CUP website used here in +the test is stupid or badly written or anything like that. I actually +think, Scott did a great job with it, and that for learning about +lexers it is quite valuable to study it or even to write a similar one +for oneself.) + +

+ +


+How to write a faster specification +

+Although JFlex generated scanners show good performance without +special optimizations, there are some heuristics that can make a +lexical specification produce an even faster scanner. Those are +(roughly in order of performance gain): + +

+ +

    +
  • Avoid rules that require backtracking + +

    +From the C/C++ flex [11] manpage: ``Getting rid +of backtracking is messy and often may be an enormous amount of work for +a complicated scanner.'' Backtracking is introduced by the longest match +rule and occurs for instance on this set of expressions: + +

    + "averylongkeyword" +
    . + +

    +With input "averylongjoke" the scanner has to read all charcters +up to 'j' to decide that rule . should be matched. All +characters of "verylong" have to be read again for the next +matching process. Backtracking can be avoided in general by adding +error rules that match those error conditions + +

    + "av"|"ave"|"avery"|"averyl"|.. + +

    +While this is impractical in most scanners, there is still the +possibility to add a ``catch all'' rule for a lengthy list of keywords +

    +"keyword1"  { return symbol(KEYWORD1); } 
    +.. 
    +"keywordn"  { return symbol(KEYWORDn); }
    +[a-z]+      { error("not a keyword"); }
    +
    +Most programming language scanners already have a rule like this for +some kind of variable length identifiers. + +

    +

  • +
  • Avoid line and column counting + +

    +It costs multiple additional comparisons per input character and the + matched text has to be rescanned for counting. In most scanners it + is possible to do the line counting in the specification by + incrementing yyline each time a line terminator has been + matched. Column counting could also be included in actions. This + will be faster, but can in some cases become quite messy. + +

    +

  • +
  • Avoid lookahead expressions and the end of line operator '$' + +

    +The trailing context will first have to be read and then (because + it is not to be consumed) read again. + +

    +

  • +
  • Avoid the beginning of line operator '^' + +

    +It costs multiple additional comparisons per match. In some + cases one extra lookahead character is needed (when the last character read is + \r the scanner has to read one character ahead to check if + the next one is an \n or not). + +

    +

  • +
  • Match as much text as possible in a rule. + +

    +One rule is matched in the innermost loop of the scanner. After + each action some overhead for setting up the internal state of the + scanner is necessary. +

  • +
+ +

+Note that writing more rules in a specification does not make the generated +scanner slower (except when you have to switch to another code generation +method because of the larger size). + +

+The two main rules of optimization apply also for lexical specifications: + +

    +
  1. don't do it +
  2. +
  3. (for experts only) don't do it yet +
  4. +
+ +

+Some of the performance tips above contradict a readable and compact +specification style. When in doubt or when requirements are not or not +yet fixed: don't use them - the specification can always be optimized +in a later state of the development process. + +

+ +

+Porting Issues +

+ +

+ +


+Porting from JLex +

+JFlex was designed to read old JLex specifications unchanged and to +generate a scanner which behaves exactly the same as the one generated +by JLex with the only difference of being faster. + +

+This works as expected on all well formed JLex specifications. + +

+Since the statement above is somewhat absolute, let's take a look at +what ``well formed'' means here. A JLex specification is well formed, when +it + +

    +
  • generates a working scanner with JLex + +

    +

  • +
  • doesn't contain the unescaped characters ! and ~ + +

    +They are operators in JFlex while JLex treats them as normal + input characters. You can easily port such a JLex specification + to JFlex by replacing every ! with \! and every + ~ with \~ in all regular expressions. + +

    +

  • +
  • has only complete regular expressions surrounded by parentheses in + macro definitions + +

    +This may sound a bit harsh, but could otherwise be a major problem + - it can also help you find some disgusting bugs in your + specification that didn't show up in the first place. In JLex, a + right hand side of a macro is just a piece of text, that is copied + to the point where the macro is used. With this, some weird kind of + stuff like +

    +  macro1 = ("hello"
    +  macro2 = {macro1})*
    +
    + was possible (with macro2 expanding to ("hello")*). This + is not allowed in JFlex and you will have to transform such + definitions. There are however some more subtle kinds of errors that + can be introduced by JLex macros. Let's consider a definition like + macro = a|b and a usage like {macro}*. + This expands in JLex to a|b* and not to the probably intended + (a|b)*. + +

    +JFlex uses always the second form of expansion, since this is the natural + form of thinking about abbreviations for regular expressions. + +

    +Most specifications shouldn't suffer from this problem, because + macros often only contain (harmless) character classes like + alpha = [a-zA-Z] and more dangerous definitions like + +

    + ident = {alpha}({alpha}|{digit})* + +

    +are only used to write rules like + +

    + {ident} { .. action .. } + +

    +and not more complex expressions like + +

    + {ident}* { .. action .. } + +

    +where the kind of error presented above would show up. +

  • +
+ +

+ +


+Porting from lex/flex +

+This section tries to give an overview of activities and possible +problems when porting a lexical specification from the C/C++ tools lex +and flex [11] available on most Unix systems to JFlex. + +

+Most of the C/C++ specific features are naturally not present in JFlex, +but most ``clean'' lex/flex lexical specifications can be ported to +JFlex without very much work. + +

+This section is by far not complete and is based mainly on a survey of +the flex man page and very little personal experience. If you do +engage in any porting activity from lex/flex to JFlex and encounter +problems, have better solutions for points presented here or have just +some tips you would like to share, please do contact me. I will +incorporate your experiences in this manual (with all due credit to you, +of course). + +

+ +

+Basic structure +

+A lexical specification for flex has the following basic structure: +
+definitions
+%%
+rules
+%%
+user code
+
+ +

+The user code section usually contains some C code that is used +in actions of the rules part of the specification. For JFlex most +of this code will have to be included in the class code %{..%} +directive in the options and declarations section (after +translating the C code to Java, of course). + +

+ +

+Macros and Regular Expression Syntax +

+The definitions section of a flex specification is quite similar +to the options and declarations part of JFlex specs. + +

+Macro definitions in flex have the form: +

+<identifier>  <expression>
+
+To port them to JFlex macros, just insert a = between <identifier> +and <expression>. + +

+The syntax and semantics of regular expressions in flex are pretty much the +same as in JFlex. A little attention is needed for some escape sequences +present in flex (such as \a) that are not supported in JFlex. These +escape sequences should be transformed into their octal or hexadecimal +equivalent. + +

+Another point are predefined character classes. Flex offers the ones directly +supported by C, JFlex offers the ones supported by Java. These classes will +sometimes have to be listed manually (if there is need for this feature, it +may be implemented in a future JFlex version). + +

+ +

+Lexical Rules +

+Since flex is mostly Unix based, the '^' (beginning of line) and +'$' (end of line) operators, consider the \n character as only line terminator. This should usually cause not much problems, but you +should be prepared for occurrences of \r or \r\n or one of +the characters \u2028, \u2029, \u000B, \u000C, +or \u0085. They are considered to be line terminators in Unicode and +therefore may not be consumed when +^ or $ is present in a rule. +

+The trailing context algorithm of flex is better than the one used in +JFlex. Therefore lookahead expressions could cause major headaches. JFlex +will issue an error message at generation time, if it cannot generate +a scanner for a certain lookahead expression. (sorry, I have no more tips here +on that yet. If anyone knows how the flex lookahead algorithm works (or any better one) +and can be efficiently implemented, again: please contact me). + +

+ +


+Working together +

+ +

+ +


+JFlex and CUP +

+One of the main design goals of JFlex was to make interfacing with the free +Java parser generator CUP [8] as easy as possibly. +This has been done by giving +the %cup directive a special meaning. An +interface however always has two sides. This section concentrates on the +CUP side of the story. + +

+ +

+CUP version 0.10j +

+Since CUP version 0.10j, this has been simplified greatly by the new +CUP scanner interface java_cup.runtime.Scanner. JFlex lexers now implement +this interface automatically when then %cup +switch is used. There are no special parser code, init + code or scan with options any more that you have to provide +in your CUP parser specification. You can just concentrate on your grammar. + +

+If your generated Lexer has the class name Scanner, the parser +is started from the a main program like this: + +

+

+...
+  try {
+    parser p = new parser(new Scanner(new FileReader(fileName)));
+    Object result = p.parse().value;
+  }
+  catch (Exception e) {
+...
+
+ +

+ +

+Using existing JFlex/CUP specifications with CUP 0.10j +

+If you already have an existing specification and you would like to upgrade +both JFlex and CUP to their newest version, you will probably have to adjust +your specification. + +

+The main difference between the %cup switch in +JFlex 1.2.1 and lower, and the current JFlex version is, that JFlex scanners +now automatically implement the java_cup.runtime.Scanner interface. +This means, that the scanning function now changes its name from yylex() +to next_token(). + +

+The main difference from older CUP versions to 0.10j is, that CUP now +has a default constructor that accepts a java_cup.runtime.Scanner +as argument and that uses this scanner as +default (so no scan with code is necessary any more). + +

+If you have an existing CUP specification, it will probably look somewhat like this: +

+parser code {:
+  Lexer lexer;
+
+  public parser (java.io.Reader input) {
+    lexer = new Lexer(input);
+  }
+:};
+
+scan with {: return lexer.yylex(); :};
+
+ +

+To upgrade to CUP 0.10j, you could change it to look like this: +

+parser code {:
+  public parser (java.io.Reader input) {
+    super(new Lexer(input));
+  }
+:};
+
+ +

+If you do not mind to change the method that is calling the parser, +you could remove the constructor entirely (and if there is nothing else +in it, the whole parser code section as well, of course). The calling +main procedure would then construct the parser as shown in the section above. + +

+The JFlex specification does not need to be changed. + +

+ +

+Using older versions of CUP +

+For people, who like or have to use older versions of CUP, the following section +explains ``the old way''. Please note, that the standard name of the scanning +function with the %cup switch is not +yylex(), but next_token(). + +

+If you have a scanner specification that begins like this: + +

+

+package PACKAGE;
+import java_cup.runtime.*;   /* this is convenience, but not necessary */
+ 
+%%
+ 
+%class Lexer
+%cup
+..
+
+ +

+then it matches a CUP specification starting like + +

+

+package PACKAGE;
+
+parser code {:
+  Lexer lexer;
+
+  public parser (java.io.Reader input) {
+    lexer = new Lexer(input);
+  }
+:};
+
+scan with {: return lexer.next_token(); :};
+
+..
+
+ +

+This assumes that the generated parser will get the name parser. +If it doesn't, you have to adjust the constructor name. + +

+The parser can then be started in a main routine like this: + +

+

+..
+  try {
+    parser p = new parser(new FileReader(fileName));
+    Object result = p.parse().value; 
+  }
+  catch (Exception e) {
+..
+
+ +

+If you want the parser specification to be independent of the name of the generated +scanner, you can instead write an interface Lexer + +

+

+public interface Lexer {
+  public java_cup.runtime.Symbol next_token() throws java.io.IOException;
+}
+
+ +

+change the parser code to: + +

+

+package PACKAGE;
+
+parser code {:
+  Lexer lexer;
+
+  public parser (Lexer lexer) {
+    this.lexer = lexer;
+  }
+:};
+
+scan with {: return lexer.next_token(); :};
+
+..
+
+ +

+tell JFlex about the Lexer +interface using the %implements +directive: + +

+

+..
+%class Scanner     /* not Lexer now since that is our interface! */
+%implements Lexer
+%cup
+..
+
+ +

+and finally change the main routine to look like + +

+

+...
+  try {
+    parser p = new parser(new Scanner(new FileReader(fileName)));
+    Object result = p.parse().value;
+  }
+  catch (Exception e) {
+...
+
+ +

+If you want to improve the error messages that CUP generated parsers +produce, you can also override the methods report_error and report_fatal_error +in the ``parser code'' section of the CUP specification. The new methods +could for instance use yyline and yycolumn (stored in +the left and right members of class java_cup.runtime.Symbol) +to report error positions more conveniently for the user. The lexer and +parser for the Java language in the examples/java directory of the +JFlex distribution use this style of error reporting. These specifications +also demonstrate the techniques above in action. + +

+ +


+JFlex and BYacc/J +

+ +

+JFlex has builtin support for the Java extension +BYacc/J +[9] by Bob Jamison +to the classical Berkeley Yacc parser generator. +This section describes how to interface BYacc/J with JFlex. It +builds on many helpful suggestions and comments from Larry Bell. + +

+Since Yacc's architecture is a bit different from CUP's, the +interface setup also works in a slightly different manner. +BYacc/J expects a function int yylex() in the parser +class that returns each next token. Semantic values are expected +in a field yylval of type parserval where ``parser'' +is the name of the generated parser class. + +

+For a small calculator example, one could use a setup like the +following on the JFlex side: + +

+

+%%
+
+%byaccj
+
+%{
+  /* store a reference to the parser object */
+  private parser yyparser;
+
+  /* constructor taking an additional parser object */
+  public Yylex(java.io.Reader r, parser yyparser) {
+    this(r);
+    this.yyparser = yyparser;
+  }
+%}
+
+NUM = [0-9]+ ("." [0-9]+)?
+NL  = \n | \r | \r\n
+
+%%
+
+/* operators */
+"+" | 
+..
+"(" | 
+")"    { return (int) yycharat(0); }
+
+/* newline */
+{NL}   { return parser.NL; }
+
+/* float */
+{NUM}  { yyparser.yylval = new parserval(Double.parseDouble(yytext()));
+         return parser.NUM; }
+
+ +

+The lexer expects a reference to the parser in its constructor. +Since Yacc allows direct use of terminal characters like '+' +in its specifications, we just return the character code for +single char matches (e.g. the operators in the example). Symbolic +token names are stored as public static int constants in +the generated parser class. They are used as in the NL token +above. Finally, for some tokens, a semantic value may have to be +communicated to the parser. The NUM rule demonstrates that +bit. + +

+A matching BYacc/J parser specification could look like this: +

+%{
+  import java.io.*;
+%}
+      
+%token NL          /* newline  */
+%token <dval> NUM  /* a number */
+
+%type <dval> exp
+
+%left '-' '+'
+..
+%right '^'         /* exponentiation */
+      
+%%
+
+..
+      
+exp:     NUM          { $$ = $1; }
+       | exp '+' exp  { $$ = $1 + $3; }
+       ..
+       | exp '^' exp  { $$ = Math.pow($1, $3); }
+       | '(' exp ')'  { $$ = $2; }
+       ;
+
+%%
+  /* a reference to the lexer object */
+  private Yylex lexer;
+
+  /* interface to the lexer */
+  private int yylex () {
+    int yyl_return = -1;
+    try {
+      yyl_return = lexer.yylex();
+    }
+    catch (IOException e) {
+      System.err.println("IO error :"+e);
+    }
+    return yyl_return;
+  }
+
+  /* error reporting */
+  public void yyerror (String error) {
+    System.err.println ("Error: " + error);
+  }
+
+  /* lexer is created in the constructor */
+  public parser(Reader r) {
+    lexer = new Yylex(r, this);
+  }
+
+  /* that's how you use the parser */
+  public static void main(String args[]) throws IOException {
+    parser yyparser = new parser(new FileReader(args[0]));
+    yyparser.yyparse();    
+  }
+
+ +

+Here, the customized part is mostly in the user code section: +We create the lexer in the constructor of the parser and store +a reference to it for later use in the parser's int yylex() +method. This yylex in the parser only calls int yylex() +of the generated lexer and passes the result on. If something goes +wrong, it returns -1 to indicate an error. + +

+Runnable versions of the specifications above +are located in the examples/byaccj directory of the JFlex +distribution. + +

+ +


+Bugs and Deficiencies +

+ +

+ +

+Deficiencies +

+The trailing context algorithm described in [1] and used in +JFlex is incorrect. It does not work, when a postfix of the regular +expression matches a prefix of the trailing context and the length +of the text matched by the expression does not have a fixed size. +JFlex will report these cases as errors at generation time. + +

+ +

+Bugs +

+ +

+As of April 12, 2004 the following bugs are known in JFlex: + +

    +
  • The check if a lookahead expression is legal fails on some expressions. + The lookahead algorithm itself works as advertised, but JFlex will not + report all lookahead expressions that the algorithm can't handle at generation + time. Some cases are caught by the check, but not all. + +

    +Workaround: Check lookahead expressions manually. A lookahead expression + r1/r2 is ok, if no postfix of r1 can match a prefix of r2. +

  • +
+ +

+If you find new ones, please use the bugs section of the +JFlex website +to report them. + +

+ +


+Copying and License +

+JFlex is free software, published under the terms of the +GNU General Public License. + +

+There is absolutely NO WARRANTY for JFlex, its code and its documentation. + +

+The code generated by JFlex inherits the copyright of the specification it +was produced from. If it was your specification, you may use the generated +code without restriction. + +

+See the file COPYRIGHT +for more information. + +

+ +


+Bibliography +

+ +

+

1 +
+ A. Aho, R. Sethi, J. Ullman, Compilers: Principles, Techniques, and Tools, 1986 + +

+

2 +
+ A. W. Appel, Modern Compiler Implementation in Java: basic techniques, 1997 + +

+

3 +
+ E. Berk, JLex: A lexical analyser generator for Java, +
http://www.cs.princeton.edu/~appel/modern/java/JLex/ +

+

4 +
+ K. Brouwer, W. Gellerich,E. Ploedereder, + Myths and Facts about the Efficient Implementation of Finite Automata and Lexical Analysis, + in: Proceedings of the 7th International Conference on Compiler Construction (CC '98), 1998 + +

+

5 +
+ M. Davis, Unicode Regular Expression Guidelines, Unicode Technical Report #18, 2000 +
http://www.unicode.org/unicode/reports/tr18/tr18-5.1.html +

+

6 +
+ P. Dencker, K. Dürre, J. Henft, Optimization of Parser Tables for portable Compilers, + in: ACM Transactions on Programming Languages and Systems 6(4), 1984 + +

+

7 +
+ J. Gosling, B. Joy, G. Steele, The Java Language Specifcation, 1996, +
http://www.javasoft.com/docs/books/jls/ +

+

8 +
+ S. E. Hudson, CUP LALR Parser Generator for Java, +
http://www.cs.princeton.edu/~appel/modern/java/CUP/ +

+

9 +
+ B. Jamison, BYacc/J, +
http://troi.lincom-asg.com/~rjamison/byacc/ +

+

10 +
+ T. Lindholm, F. Yellin, The Java Virtual Machine Specification, 1996, +
http://www.javasoft.com/docs/books/vmspec/ +

+

11 +
+ V. Paxon, flex - The fast lexical analyzer generator, 1995 + +

+

12 +
+ R. E. Tarjan, A. Yao, Storing a Sparse Table, in: Communications of the ACM 22(11), 1979 + +

+

13 +
+ R. Wilhelm, D. Maurer, Übersetzerbau, Berlin 19972 + +

+

+ +

+


Footnotes

+
+
... Java[*] +
Java is a trademark of +Sun Microsystems, Inc., and refers to Sun's Java programming language. +JFlex is not sponsored by or affiliated with Sun Microsystems, Inc. + +


+
+Mon Apr 12 20:58:12 EST 2004, Gerwin Klein +
+ + diff --git a/tools/lexer/jflex-1.4/doc/manual.pdf b/tools/lexer/jflex-1.4/doc/manual.pdf new file mode 100644 index 0000000000000000000000000000000000000000..96734f8321220623295ca9388cec91c81da3bb7b GIT binary patch literal 392211 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 E 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 #;AgSTKvQZp8x8GX_(`& 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

+ * Most of the time you want to do character encoding translation when translating bytes to + * characters. If you are planning on displaying the text, you should always do this and should + * use an InputStreamReader for the purpose. Sometimes it is useful to treat characters as bytes + * with some extra bits. In these cases you would want to use a StraightStreamReader. + *

+ * For top efficiency, consider wrapping an StraightStreamReader within a BufferedReader. For example:
+ * BufferedReader in = new BufferedReader(new StraightStreamReader(System.in)); + */ +public class StraightStreamReader extends Reader{ + + /** + * The input stream from which all methods in this class read. + */ + private InputStream in; + + /** + * A byte array to be used for calls to the InputStream. This + * is cached as a class variable to avoid object creation and + * deletion each time a read is called. This buffer may be + * null and may not be large enough. Make sure to check it + * before using it. + */ + private byte[] buffer; + + /** + * Create a StraightStreamReader from an InputStream + * + * @param in InputStream to wrap a Reader around. + */ + public StraightStreamReader(InputStream in) { + this.in = in; + } + + /** + * Close the stream. + * + * @throws IOException If an I/O error occurs + */ + public void close() throws IOException { + in.close(); + } + + /** + * Mark the present position in the stream. Subsequent calls to reset() + * will attempt to reposition the stream to this point. Not all + * character-input streams support the mark() operation. + * + * @param readAheadLimit Limit on the number of characters that may be read + * while still preserving the mark. After reading this many characters, + * attempting to reset the stream may fail. + * @throws IOException If the stream does not support mark(), or if some other I/O error occurs + */ + public void mark(int readAheadLimit) throws IOException { + in.mark(readAheadLimit); + } + + /** + * Tell whether this stream supports the mark() operation. + * + * @return true if and only if this stream supports the mark operation. + */ + public boolean markSupported(){ + return in.markSupported(); + } + + /** + * Read a single character. This method will block until a character is available, an + * I/O error occurs, or the end of the stream is reached. + * + * @return The character read, as an integer in the range 0 to 256 (0x00-0xff), or -1 if + * the end of the stream has been reached + * @throws IOException If an I/O error occurs + */ + public int read() throws IOException { + return in.read(); + } + + /** + * Read characters into an array. This method will block until some input is available, + * an I/O error occurs, or the end of the stream is reached. + * + * @param cbuf Destination buffer + * @return The number of bytes read, or -1 if the end of the stream has been reached + * @throws IOException If an I/O error occurs + */ + public int read(char[] cbuf) throws IOException { + return read(cbuf, 0, cbuf.length); + } + + /** + * Read characters into an array. This method will block until some input is available, + * an I/O error occurs, or the end of the stream is reached. + * + * @param cbuf Destination buffer + * @param off Offset at which to start storing characters + * @param len Maximum number of characters to read + * @return The number of bytes read, or -1 if the end of the stream has been reached + * @throws IOException If an I/O error occurs + */ + public int read(char[] cbuf, int off, int len) throws IOException { + // ensure the capacity of the buffer that we will be using + // to read from the input stream + if (buffer == null || buffer.length < len){ + buffer = new byte[len]; + } + // read from the input stream and copy it to the character array + int length = in.read(buffer, 0, len); + for (int i=0; i 0); + } + + /** + * Reset the stream. If the stream has been marked, then attempt to reposition it at the mark. + * If the stream has not been marked, then attempt to reset it in some way appropriate to the + * particular stream, for example by repositioning it to its starting point. Not all + * character-input streams support the reset() operation, and some support reset() + * without supporting mark(). + * + * @throws IOException If the stream has not been marked, or if the mark has been invalidated, + * or if the stream does not support reset(), or if some other I/O error occurs + */ + public void reset() throws IOException { + in.reset(); + } + + /** + * Skip characters. This method will block until some characters are available, + * an I/O error occurs, or the end of the stream is reached. + * + * @param n The number of characters to skip + * @return The number of characters actually skipped + * @throws IllegalArgumentException If n is negative + * @throws IOException If an I/O error occurs + */ + public long skip(long n) throws IOException { + return in.skip(n); + } + + /** + * Regression test for this class. If this class is working, this should + * run and print no errors. + *

+ * This method creates a tempory file in the working directory called "test.txt". + * This file should not exist before hand, and the program should have create, + * read, write, and delete access to this file. + * + * @param args command line arguments (ignored) + */ + private static void main(String[] args){ + try { + File f = new File("test.txt"); + if (f.exists()){ + throw new IOException(f + " already exists. I don't want to overwrite it."); + } + StraightStreamReader in; + char[] cbuf = new char[0x1000]; + int read; + int totRead; + + // write a file with all possible values of bytes + FileOutputStream out = new FileOutputStream(f); + for (int i=0x00; i<0x100; i++){ + out.write(i); + } + out.close(); + + // read it back using the read single character method + in = new StraightStreamReader(new FileInputStream(f)); + for (int i=0x00; i<0x100; i++){ + read = in.read(); + if (read != i){ + System.err.println("Error: " + i + " read as " + read); + } + } + in.close(); + + // read as much of it back as possible with one simple buffer read. + in = new StraightStreamReader(new FileInputStream(f)); + totRead = in.read(cbuf); + if (totRead != 0x100){ + System.err.println("Simple buffered read did not read the full amount: 0x" + Integer.toHexString(totRead)); + } + for (int i=0x00; i 0){ + totRead += read; + } + if (totRead != 0x100){ + System.err.println("Not enough read. Bytes read: " + Integer.toHexString(totRead)); + } + for (int i=0x00; i 0){ + totRead += read; + } + if (totRead != 0x100){ + System.err.println("Not enough read. Bytes read: " + Integer.toHexString(totRead)); + } + for (int i=0x00; i 0){ + totRead += read; + } + if (totRead != 0x100){ + System.err.println("Not enough read. Bytes read: " + Integer.toHexString(totRead)); + } + for (int i=0x00; i * + * All rights reserved. * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License. See the file * + * COPYRIGHT for more information. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License along * + * with this program; if not, write to the Free Software Foundation, Inc., * + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + + +import java.io.*; + +%% + +%class BinaryLexer +%8bit + +%int + +%{ + public static void main(String [] argv) { + for (int i = 0; i < argv.length; i++) { + try { + System.out.print("["+argv[i]+"] is "); + BinaryLexer l = new BinaryLexer(new StraightStreamReader(new FileInputStream(argv[i]))); + l.yylex(); + } + catch (Exception e) { + e.printStackTrace(System.out); + System.exit(1); + } + } + } +%} + +magic = \xCA \xFE \xBA \xBE + +%% + +{magic} [^]+ { System.out.println("a class file"); } + +[^]+ { System.out.println("not a class file"); } diff --git a/tools/lexer/jflex-1.4/examples/byaccj/Makefile b/tools/lexer/jflex-1.4/examples/byaccj/Makefile new file mode 100644 index 000000000000..28a361dda157 --- /dev/null +++ b/tools/lexer/jflex-1.4/examples/byaccj/Makefile @@ -0,0 +1,27 @@ +# only works with the Java extension of yacc: +# byacc/j from http://troi.lincom-asg.com/~rjamison/byacc/ + +JFLEX = jflex +BYACCJ = yacc -J +JAVAC = javac + +# targets: + +all: Parser.class + +run: Parser.class + java Parser + +build: clean Parser.class + +clean: + rm -f *~ *.class *.java + +Parser.class: Yylex.java Parser.java + $(JAVAC) Parser.java + +Yylex.java: calc.flex + $(JFLEX) calc.flex + +Parser.java: calc.y + $(BYACCJ) calc.y diff --git a/tools/lexer/jflex-1.4/examples/byaccj/README b/tools/lexer/jflex-1.4/examples/byaccj/README new file mode 100644 index 000000000000..ab6831e8026c --- /dev/null +++ b/tools/lexer/jflex-1.4/examples/byaccj/README @@ -0,0 +1,22 @@ +This directory contains an interoperability example for BYacc/J and JFlex +(a small calculator) + +You need the parser generator byacc/j from +http://troi.lincom-asg.com/~rjamison/byacc/ +for this example to work (version byacc/j 1.1 has been tested). + +Use the Makefile to generate the lexer and parser. +The example can then be started with + +java Parser + + +files: + +calc.flex + JFlex specification for the lexical part of the arithmetic expressions + +calc.y + BYacc/J specification and main program for the calculator + + diff --git a/tools/lexer/jflex-1.4/examples/byaccj/calc.flex b/tools/lexer/jflex-1.4/examples/byaccj/calc.flex new file mode 100644 index 000000000000..8ad62bc4332f --- /dev/null +++ b/tools/lexer/jflex-1.4/examples/byaccj/calc.flex @@ -0,0 +1,62 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Copyright (C) 2000 Gerwin Klein * + * All rights reserved. * + * * + * Thanks to Larry Bell and Bob Jamison for suggestions and comments. * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License. See the file * + * COPYRIGHT for more information. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License along * + * with this program; if not, write to the Free Software Foundation, Inc., * + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +%% + +%byaccj + +%{ + private Parser yyparser; + + public Yylex(java.io.Reader r, Parser yyparser) { + this(r); + this.yyparser = yyparser; + } +%} + +NUM = [0-9]+ ("." [0-9]+)? +NL = \n | \r | \r\n + +%% + +/* operators */ +"+" | +"-" | +"*" | +"/" | +"^" | +"(" | +")" { return (int) yycharat(0); } + +/* newline */ +{NL} { return Parser.NL; } + +/* float */ +{NUM} { yyparser.yylval = new ParserVal(Double.parseDouble(yytext())); + return Parser.NUM; } + +/* whitespace */ +[ \t]+ { } + +\b { System.err.println("Sorry, backspace doesn't work"); } + +/* error fallback */ +[^] { System.err.println("Error: unexpected character '"+yytext()+"'"); return -1; } diff --git a/tools/lexer/jflex-1.4/examples/byaccj/calc.y b/tools/lexer/jflex-1.4/examples/byaccj/calc.y new file mode 100644 index 000000000000..7ab42c271729 --- /dev/null +++ b/tools/lexer/jflex-1.4/examples/byaccj/calc.y @@ -0,0 +1,112 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Copyright (C) 2001 Gerwin Klein * + * All rights reserved. * + * * + * This is a modified version of the example from * + * http://www.lincom-asg.com/~rjamison/byacc/ * + * * + * Thanks to Larry Bell and Bob Jamison for suggestions and comments. * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License. See the file * + * COPYRIGHT for more information. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License along * + * with this program; if not, write to the Free Software Foundation, Inc., * + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +%{ + import java.io.*; +%} + +%token NL /* newline */ +%token NUM /* a number */ + +%type exp + +%left '-' '+' +%left '*' '/' +%left NEG /* negation--unary minus */ +%right '^' /* exponentiation */ + +%% + +input: /* empty string */ + | input line + ; + +line: NL { if (interactive) System.out.print("Expression: "); } + | exp NL { System.out.println(" = " + $1); + if (interactive) System.out.print("Expression: "); } + ; + +exp: NUM { $$ = $1; } + | exp '+' exp { $$ = $1 + $3; } + | exp '-' exp { $$ = $1 - $3; } + | exp '*' exp { $$ = $1 * $3; } + | exp '/' exp { $$ = $1 / $3; } + | '-' exp %prec NEG { $$ = -$2; } + | exp '^' exp { $$ = Math.pow($1, $3); } + | '(' exp ')' { $$ = $2; } + ; + +%% + + private Yylex lexer; + + + private int yylex () { + int yyl_return = -1; + try { + yylval = new ParserVal(0); + yyl_return = lexer.yylex(); + } + catch (IOException e) { + System.err.println("IO error :"+e); + } + return yyl_return; + } + + + public void yyerror (String error) { + System.err.println ("Error: " + error); + } + + + public Parser(Reader r) { + lexer = new Yylex(r, this); + } + + + static boolean interactive; + + public static void main(String args[]) throws IOException { + System.out.println("BYACC/Java with JFlex Calculator Demo"); + + Parser yyparser; + if ( args.length > 0 ) { + // parse a file + yyparser = new Parser(new FileReader(args[0])); + } + else { + // interactive mode + System.out.println("[Quit with CTRL-D]"); + System.out.print("Expression: "); + interactive = true; + yyparser = new Parser(new InputStreamReader(System.in)); + } + + yyparser.yyparse(); + + if (interactive) { + System.out.println(); + System.out.println("Have a nice day"); + } + } diff --git a/tools/lexer/jflex-1.4/examples/cup/Main.java b/tools/lexer/jflex-1.4/examples/cup/Main.java new file mode 100644 index 000000000000..fba453289fe3 --- /dev/null +++ b/tools/lexer/jflex-1.4/examples/cup/Main.java @@ -0,0 +1,39 @@ +/* + This example comes from a short article series in the Linux + Gazette by Richard A. Sevenich and Christopher Lopes, titled + "Compiler Construction Tools". The article series starts at + + http://www.linuxgazette.com/issue39/sevenich.html + + Small changes and updates to newest JFlex+Cup versions + by Gerwin Klein +*/ + +/* + Commented By: Christopher Lopes + File Name: Main.java + To Create: + After the scanner, lcalc.flex, and the parser, ycalc.cup, have been created. + > javac Main.java + + To Run: + > java Main test.txt + where test.txt is an test input file for the calculator. +*/ + +import java.io.FileReader; + +public class Main { + static public void main(String argv[]) { + /* Start the parser */ + try { + parser p = new parser(new Lexer(new FileReader(argv[0]))); + Object result = p.parse().value; + } catch (Exception e) { + /* do cleanup here -- possibly rethrow e */ + e.printStackTrace(); + } + } +} + + diff --git a/tools/lexer/jflex-1.4/examples/cup/Makefile b/tools/lexer/jflex-1.4/examples/cup/Makefile new file mode 100644 index 000000000000..fff6fbced6b4 --- /dev/null +++ b/tools/lexer/jflex-1.4/examples/cup/Makefile @@ -0,0 +1,26 @@ +JAVA=java +JAVAC=javac +JFLEX=jflex +CUP=$(JAVA) java_cup.Main < + +all: test + +test: output.txt + @(diff output.txt output.good && echo "Test OK!") || echo "Test failed!" + +output.txt: Main.class test.txt + $(JAVA) Main test.txt > output.txt + +Main.class: Main.java Lexer.java parser.java + +%.class: %.java + $(JAVAC) $^ + +Lexer.java: lcalc.flex + $(JFLEX) lcalc.flex + +parser.java: ycalc.cup + $(CUP) ycalc.cup + +clean: + rm -f parser.java Lexer.java sym.java output.txt *.class *~ diff --git a/tools/lexer/jflex-1.4/examples/cup/README b/tools/lexer/jflex-1.4/examples/cup/README new file mode 100644 index 000000000000..6b0d333bd188 --- /dev/null +++ b/tools/lexer/jflex-1.4/examples/cup/README @@ -0,0 +1,30 @@ +A small JFlex+Cup example + +It comes from a short article series in the Linux Gazette by Richard +A. Sevenich and Christopher Lopes, titled "Compiler Construction +Tools". The article series starts at + +http://www.linuxgazette.com/issue39/sevenich.html + +Small changes and updates to newest JFlex+Cup versions by Gerwin Klein + + +To compile: +>jflex lcalc.flex +>java java_cup.Main < ycalc.cup +>javac Main.java + +To run: +>java Main test.txt + + +Files: + +Main.java demo of a main program +Makefile makefile to compile and test the example +README this file +lcalc.flex the lexer spec +output.good how the output should look like for the test +ycalc.cup the parser spec +test.txt sample input for testing + diff --git a/tools/lexer/jflex-1.4/examples/cup/lcalc.flex b/tools/lexer/jflex-1.4/examples/cup/lcalc.flex new file mode 100644 index 000000000000..181bf0198f01 --- /dev/null +++ b/tools/lexer/jflex-1.4/examples/cup/lcalc.flex @@ -0,0 +1,142 @@ +/* + This example comes from a short article series in the Linux + Gazette by Richard A. Sevenich and Christopher Lopes, titled + "Compiler Construction Tools". The article series starts at + + http://www.linuxgazette.com/issue39/sevenich.html + + Small changes and updates to newest JFlex+Cup versions + by Gerwin Klein +*/ + +/* + Commented By: Christopher Lopes + File Name: lcalc.flex + To Create: > jflex lcalc.flex + + and then after the parser is created + > javac Lexer.java +*/ + +/* --------------------------Usercode Section------------------------ */ + +import java_cup.runtime.*; + +%% + +/* -----------------Options and Declarations Section----------------- */ + +/* + The name of the class JFlex will create will be Lexer. + Will write the code to the file Lexer.java. +*/ +%class Lexer + +/* + The current line number can be accessed with the variable yyline + and the current column number with the variable yycolumn. +*/ +%line +%column + +/* + Will switch to a CUP compatibility mode to interface with a CUP + generated parser. +*/ +%cup + +/* + Declarations + + Code between %{ and %}, both of which must be at the beginning of a + line, will be copied letter to letter into the lexer class source. + Here you declare member variables and functions that are used inside + scanner actions. +*/ +%{ + /* To create a new java_cup.runtime.Symbol with information about + the current token, the token will have no value in this + case. */ + private Symbol symbol(int type) { + return new Symbol(type, yyline, yycolumn); + } + + /* Also creates a new java_cup.runtime.Symbol with information + about the current token, but this object has a value. */ + private Symbol symbol(int type, Object value) { + return new Symbol(type, yyline, yycolumn, value); + } +%} + + +/* + Macro Declarations + + These declarations are regular expressions that will be used latter + in the Lexical Rules Section. +*/ + +/* A line terminator is a \r (carriage return), \n (line feed), or + \r\n. */ +LineTerminator = \r|\n|\r\n + +/* White space is a line terminator, space, tab, or line feed. */ +WhiteSpace = {LineTerminator} | [ \t\f] + +/* A literal integer is is a number beginning with a number between + one and nine followed by zero or more numbers between zero and nine + or just a zero. */ +dec_int_lit = 0 | [1-9][0-9]* + +/* A identifier integer is a word beginning a letter between A and + Z, a and z, or an underscore followed by zero or more letters + between A and Z, a and z, zero and nine, or an underscore. */ +dec_int_id = [A-Za-z_][A-Za-z_0-9]* + +%% +/* ------------------------Lexical Rules Section---------------------- */ + +/* + This section contains regular expressions and actions, i.e. Java + code, that will be executed when the scanner matches the associated + regular expression. */ + + /* YYINITIAL is the state at which the lexer begins scanning. So + these regular expressions will only be matched if the scanner is in + the start state YYINITIAL. */ + + { + + /* Return the token SEMI declared in the class sym that was found. */ + ";" { return symbol(sym.SEMI); } + + /* Print the token found that was declared in the class sym and then + return it. */ + "+" { System.out.print(" + "); return symbol(sym.PLUS); } + "-" { System.out.print(" - "); return symbol(sym.MINUS); } + "*" { System.out.print(" * "); return symbol(sym.TIMES); } + "/" { System.out.print(" / "); return symbol(sym.DIVIDE); } + "(" { System.out.print(" ( "); return symbol(sym.LPAREN); } + ")" { System.out.print(" ) "); return symbol(sym.RPAREN); } + + /* If an integer is found print it out, return the token NUMBER + that represents an integer and the value of the integer that is + held in the string yytext which will get turned into an integer + before returning */ + {dec_int_lit} { System.out.print(yytext()); + return symbol(sym.NUMBER, new Integer(yytext())); } + + /* If an identifier is found print it out, return the token ID + that represents an identifier and the default value one that is + given to all identifiers. */ + {dec_int_id} { System.out.print(yytext()); + return symbol(sym.ID, new Integer(1));} + + /* Don't do anything if whitespace is found */ + {WhiteSpace} { /* just skip what was found, do nothing */ } +} + + +/* No token was found for the input so through an error. Print out an + Illegal character message with the illegal character that was found. */ +[^] { throw new Error("Illegal character <"+yytext()+">"); } diff --git a/tools/lexer/jflex-1.4/examples/cup/output.good b/tools/lexer/jflex-1.4/examples/cup/output.good new file mode 100644 index 000000000000..cbceb636f601 --- /dev/null +++ b/tools/lexer/jflex-1.4/examples/cup/output.good @@ -0,0 +1,4 @@ +2 + 4 = 6 +5 * ( 6 - 3 ) + 1 = 16 +6 / 3 * 5 + 20 = 30 +4 * 76 / 31 = 9 diff --git a/tools/lexer/jflex-1.4/examples/cup/test.txt b/tools/lexer/jflex-1.4/examples/cup/test.txt new file mode 100644 index 000000000000..3f8344bccdb2 --- /dev/null +++ b/tools/lexer/jflex-1.4/examples/cup/test.txt @@ -0,0 +1,4 @@ +2+4; +5*(6-3)+1; +6/3*5+20; +4*76/31; diff --git a/tools/lexer/jflex-1.4/examples/cup/ycalc.cup b/tools/lexer/jflex-1.4/examples/cup/ycalc.cup new file mode 100644 index 000000000000..a67a20d3b09a --- /dev/null +++ b/tools/lexer/jflex-1.4/examples/cup/ycalc.cup @@ -0,0 +1,234 @@ +/* + This example comes from a short article series in the Linux + Gazette by Richard A. Sevenich and Christopher Lopes, titled + "Compiler Construction Tools". The article series starts at + + http://www.linuxgazette.com/issue39/sevenich.html + + Small changes and updates to newest JFlex+Cup versions + by Gerwin Klein +*/ + +/* + Commented By: Christopher Lopes + File Name: ycalc.cup + To Create: > java java_cup.Main < ycalc.cup +*/ + + +/* ----------------------Preliminary Declarations Section--------------------*/ + +/* Import the class java_cup.runtime.* */ +import java_cup.runtime.*; + +/* Parser code to change the way the parser reports errors (include + line and column number of the error). */ +parser code {: + + /* Change the method report_error so it will display the line and + column of where the error occurred in the input as well as the + reason for the error which is passed into the method in the + String 'message'. */ + public void report_error(String message, Object info) { + + /* Create a StringBuffer called 'm' with the string 'Error' in it. */ + StringBuffer m = new StringBuffer("Error"); + + /* Check if the information passed to the method is the same + type as the type java_cup.runtime.Symbol. */ + if (info instanceof java_cup.runtime.Symbol) { + /* Declare a java_cup.runtime.Symbol object 's' with the + information in the object info that is being typecasted + as a java_cup.runtime.Symbol object. */ + java_cup.runtime.Symbol s = ((java_cup.runtime.Symbol) info); + + /* Check if the line number in the input is greater or + equal to zero. */ + if (s.left >= 0) { + /* Add to the end of the StringBuffer error message + the line number of the error in the input. */ + m.append(" in line "+(s.left+1)); + /* Check if the column number in the input is greater + or equal to zero. */ + if (s.right >= 0) + /* Add to the end of the StringBuffer error message + the column number of the error in the input. */ + m.append(", column "+(s.right+1)); + } + } + + /* Add to the end of the StringBuffer error message created in + this method the message that was passed into this method. */ + m.append(" : "+message); + + /* Print the contents of the StringBuffer 'm', which contains + an error message, out on a line. */ + System.err.println(m); + } + + /* Change the method report_fatal_error so when it reports a fatal + error it will display the line and column number of where the + fatal error occurred in the input as well as the reason for the + fatal error which is passed into the method in the object + 'message' and then exit.*/ + public void report_fatal_error(String message, Object info) { + report_error(message, info); + System.exit(1); + } +:}; + + + +/* ------------Declaration of Terminals and Non Terminals Section----------- */ + +/* Terminals (tokens returned by the scanner). + + Terminals that have no value are listed first and then terminals + that do have an value, in this case an integer value, are listed on + the next line down. */ +terminal SEMI, PLUS, MINUS, TIMES, DIVIDE, LPAREN, RPAREN; +terminal Integer NUMBER, ID; + +/* Non terminals used in the grammar section. + + Non terminals that have an object value are listed first and then + non terminals that have an integer value are listed. An object + value means that it can be any type, it isn't set to a specific + type. So it could be an Integer or a String or whatever. */ +non terminal Object expr_list, expr_part; +non terminal Integer expr, factor, term; + + +/* -------------Precedence and Associatively of Terminals Section----------- */ + +/* + Precedence of non terminals could be defined here. If you do define + precedence here you won't need to worry about precedence in the + Grammar Section, i.e. that TIMES should have a higher precedence + than PLUS. + + The precedence defined here would look something like this where the + lower line always will have higher precedence than the line before it. + + precedence left PLUS, MINUS; + precedence left TIMES, DIVIDE; +*/ + + +/* ----------------------------Grammar Section-------------------- */ + +/* The grammar for our parser. + + expr_list ::= expr_list expr_part + | expr_part + expr_part ::= expr SEMI + expr ::= factor PLUS expr + | factor MINUS expr + | factor + factor ::= factor TIMES term + | factor DIVIDE term + | term + term ::= LPAREN expr RPAREN + | NUMBER + | ID +*/ + +/* 'expr_list' is the start of our grammar. It can lead to another + 'expr_list' followed by an 'expr_part' or it can just lead to an + 'expr_part'. The lhs of the non terminals 'expr_list' and + 'expr_part' that are in the rhs side of the production below need + to be found. Then the rhs sides of those non terminals need to be + followed in a similar manner, i.e. if there are any non terminals + in the rhs of those productions then the productions with those non + terminals need to be found and those rhs's followed. This process + keeps continuing until only terminals are found in the rhs of a + production. Then we can work our way back up the grammar bringing + any values that might have been assigned from a terminal. */ + + expr_list ::= expr_list expr_part + | + expr_part; + +/* 'expr_part' is an 'expr' followed by the terminal 'SEMI'. The ':e' + after the non terminal 'expr' is a label an is used to access the + value of 'expr' which will be an integer. The action for the + production lies between {: and :}. This action will print out the + line " = + e" where e is the value of 'expr'. Before the action + takes places we need to go deeper into the grammar since 'expr' is + a non terminal. Whenever a non terminal is encountered on the rhs + of a production we need to find the rhs of that non terminal until + there are no more non terminals in the rhs. So when we finish + going through the grammar and don't encounter any more non + terminals in the rhs productions will return until we get back to + 'expr' and at that point 'expr' will contain an integer value. */ + + expr_part ::= expr:e + {: System.out.println(" = " + e); :} + SEMI + ; + +/* 'expr' can lead to 'factor PLUS expr', 'factor MINUS expr', or + 'factor'. The 'TIMES' and 'DIVIDE' productions are not at this + level. They are at a lower level in the grammar which in affect + makes them have higher precedence. Actions for the rhs of the non + terminal 'expr' return a value to 'expr'. This value that is + created is an integer and gets stored in 'RESULT' in the action. + RESULT is the label that is assigned automatically to the rhs, in + this case 'expr'. If the rhs is just 'factor' then 'f' refers to + the non terminal 'factor'. The value of 'f' is retrieved with the + function 'intValue()' and will be stored in 'RESULT'. In the other + two cases 'f' and 'e' refers to the non terminals 'factor' and + 'expr' respectively with a terminal between them, either 'PLUS' or + 'MINUS'. The value of each is retrieved with the same function + 'intValue'. The values will be added or subtracted and then the + new integer will be stored in 'RESULT'.*/ + + expr ::= factor:f PLUS expr:e + {: RESULT = new Integer(f.intValue() + e.intValue()); :} + | + factor:f MINUS expr:e + {: RESULT = new Integer(f.intValue() - e.intValue()); :} + | + factor:f + {: RESULT = new Integer(f.intValue()); :} + ; + +/* 'factor' can lead to 'factor TIMES term', 'factor DIVIDE term', or + 'term'. Since the productions for TIMES and DIVIDE are lower in + the grammar than 'PLUS' and 'MINUS' they will have higher + precedence. The same sort of actions take place in the rhs of + 'factor' as in 'expr'. The only difference is the operations that + takes place on the values retrieved with 'intValue()', 'TIMES' and + 'DIVIDE' here instead of 'PLUS' and 'MINUS'. */ + + factor ::= factor:f TIMES term:t + {: RESULT = new Integer(f.intValue() * t.intValue()); :} + | + factor:f DIVIDE term:t + {: RESULT = new Integer(f.intValue() / t.intValue()); :} + | + term:t + {: RESULT = new Integer(t.intValue()); :} + ; + +/* 'term' can lead to 'LPAREN expr RPAREN', 'NUMBER', or 'ID'. The + first production has the non terminal 'expr' in it so the + production with its lhs side needs to be found and followed. The + next rhs has no non terminals. So the grammar ends here and can go + back up. When it goes back up it will bring the value that was + retrieved when the scanner encounter the token 'NUMBER'. 'RESULT' + is assigned 'n', which refers to 'NUMBER', as the action for this + production. The same action occurs for 'ID', except the 'i' is + used to refer to 'ID'. 'ID' is also the only thing on the rhs of + the production. And since 'ID' is a terminal the grammar will end + here and go back up. */ + + term ::= LPAREN expr:e RPAREN + {: RESULT = e; :} + | + NUMBER:n + {: RESULT = n; :} + | + ID:i + {: RESULT = i; :} + ; diff --git a/tools/lexer/jflex-1.4/examples/interpreter/AST.java b/tools/lexer/jflex-1.4/examples/interpreter/AST.java new file mode 100644 index 000000000000..194a42c4a33c --- /dev/null +++ b/tools/lexer/jflex-1.4/examples/interpreter/AST.java @@ -0,0 +1,30 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Copyright (C) 2001 Gerwin Klein * + * Copyright (C) 2001 Bernhard Rumpe * + * All rights reserved. * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License. See the file * + * COPYRIGHT for more information. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License along * + * with this program; if not, write to the Free Software Foundation, Inc., * + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +/** + * General interface for nodes in the abstract syntax tree. Contains + * only the method toString which is already inherited from Object, + * so the interface doesn't add any functionality. It only provides + * a common super type for all elements in the AST. + */ +interface AST { + public String toString(); // already inherited from Object +} + diff --git a/tools/lexer/jflex-1.4/examples/interpreter/Main.java b/tools/lexer/jflex-1.4/examples/interpreter/Main.java new file mode 100644 index 000000000000..4fbaf1a7a6e1 --- /dev/null +++ b/tools/lexer/jflex-1.4/examples/interpreter/Main.java @@ -0,0 +1,88 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Copyright (C) 2001 Gerwin Klein * + * Copyright (C) 2001 Bernhard Rumpe * + * All rights reserved. * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License. See the file * + * COPYRIGHT for more information. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License along * + * with this program; if not, write to the Free Software Foundation, Inc., * + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + + +import java.io.File; +import java.io.FileReader; +import java.io.InputStreamReader; +import java.io.Reader; + +/** + * Main program of the interpreter for the AS programming language. + * Based on JFlex/CUP. + * + * Steps: + * - scanning (Yylex) + * - context free parsing and AST building (yyparse) + * - build up symbol table (setSymtabs) + * - check context conditions (checkcontext) + * - prepare interpretation (prepInterp) + * - start interpretation (interpret) + */ +public class Main { + + public static void main(String [] args) throws Exception { + Reader reader = null; + + if (args.length == 1) { + File input = new File(args[0]); + if (!input.canRead()) { + System.out.println("Error: could not read ["+input+"]"); + } + reader = new FileReader(input); + } + else { + reader = new InputStreamReader(System.in); + } + + Yylex scanner = new Yylex(reader); // create scanner + SymTab symtab = new SymTab(); // set global symbol table + scanner.setSymtab(symtab); + + parser parser = new parser(scanner); // create parser + Tprogram syntaxbaum = null; + + try { + syntaxbaum = (Tprogram) parser.parse().value; // parse + } + catch (Exception e) { + e.printStackTrace(); + } + + // System.out.println(symtab); + System.out.println(syntaxbaum); + + syntaxbaum.setSymtabs(); // set symbol table + // syntaxbaum.printSymtabs(); // print symbol table + + syntaxbaum.checkcontext(); // CoCo (DefVar, DefFun, Arity) + if(contexterror>0) return; + + syntaxbaum.prepInterp(); // var. indices and function pointers + // im Syntaxbaum setzen + syntaxbaum.interpret(); // interpretation + } + + static int contexterror = 0; // number of errors in context conditions + + public static void error(String s) { + System.out.println((contexterror++)+". "+s); + } +} diff --git a/tools/lexer/jflex-1.4/examples/interpreter/Makefile b/tools/lexer/jflex-1.4/examples/interpreter/Makefile new file mode 100644 index 000000000000..de5afbe94d7b --- /dev/null +++ b/tools/lexer/jflex-1.4/examples/interpreter/Makefile @@ -0,0 +1,42 @@ +# uses JFlex >= 1.3.2, and CUP >= 0.10j +# +# targets: +# +# make all +# generates lexer, and parser, and compiles all *.java files +# +# make run (or just: make) +# starts the program on a test example +# + + + +.SUFFIXES: $(SUFFIXES) .class .java + +.java.class: + javac $*.java + +FILE= Yylex.java parser.java sym.java \ + SymTab.java AST.java \ + Tnumber.java Tident.java Texp.java \ + Tfun.java Texpinfix.java Tuminus.java \ + Tboolexp.java Tifthenelse.java \ + Tdekl.java Tdekllist.java \ + Tparlist.java Texplist.java Tprogram.java \ + Main.java \ + SymtabEntry.java STEfun.java STEvar.java + + +run: all + java Main < example.as + +all: Yylex.java parser.java $(FILE:java=class) + +clean: + rm -f *.class *~ *.bak Yylex.java parser.java sym.java + +Yylex.java: scanner.flex + jflex scanner.flex + +parser.java: parser.cup + java java_cup.Main -interface < parser.cup diff --git a/tools/lexer/jflex-1.4/examples/interpreter/README b/tools/lexer/jflex-1.4/examples/interpreter/README new file mode 100644 index 000000000000..731bd5c1b208 --- /dev/null +++ b/tools/lexer/jflex-1.4/examples/interpreter/README @@ -0,0 +1,31 @@ +This directory contains an interpreter for a small functional +programming language (called "AS"). It uses JFlex and CUP. + +Directory contents: + +- Main.java is the main program. It reads an AS program from + std in and interprets it. + +- Makefile runs jflex, cup, javac and the compiled interpreter + +- Classes beginning with "T" implement the abstract syntax tree. + They also contain context condition checking and the interpreter. + +- Symtab.java, SymtabEntry.java, STEfun.java, STEvar.java implement + the symbol table. + +- scanner.lex and parser.cup contain the scanner and parser. + +- example.as is an example program in AS + + +The language is described in: +Manfred Broy: Einfuehrung in die Informatik, Springer Verlag + +The files are a solution to excercise 3.40 in the book: +Manfred Broy,Bernhard Rumpe: +Uebungen zur Einfuehrung in die Informatik -- +Strukturierte Aufgabensammlung mit Musterloesungen, +Springer Verlag, 2001 + +Both books are only available in German. Sorry. diff --git a/tools/lexer/jflex-1.4/examples/interpreter/STEfun.java b/tools/lexer/jflex-1.4/examples/interpreter/STEfun.java new file mode 100644 index 000000000000..655813b4dcee --- /dev/null +++ b/tools/lexer/jflex-1.4/examples/interpreter/STEfun.java @@ -0,0 +1,54 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Copyright (C) 2001 Gerwin Klein * + * Copyright (C) 2001 Bernhard Rumpe * + * All rights reserved. * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License. See the file * + * COPYRIGHT for more information. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License along * + * with this program; if not, write to the Free Software Foundation, Inc., * + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + + +/** + * Symbol table entry for functions. + * + * Contains arity and reference to location of definition + */ +class STEfun extends SymtabEntry { + int arity; + Tdekl dekl; // location of definition + + public STEfun(String f, Tdekl d, int a) { + super(f); + dekl=d; + arity=a; + } + + public int kind() { + return SymtabEntry.FUN; + } + + public String toString() { + return "function "+name+", arity "+arity; + } + + public int arity() { + return arity; + } + + public Tdekl getDekl() { + return dekl; + } +} + + diff --git a/tools/lexer/jflex-1.4/examples/interpreter/STEvar.java b/tools/lexer/jflex-1.4/examples/interpreter/STEvar.java new file mode 100644 index 000000000000..c4d420db2e79 --- /dev/null +++ b/tools/lexer/jflex-1.4/examples/interpreter/STEvar.java @@ -0,0 +1,57 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Copyright (C) 2001 Gerwin Klein * + * Copyright (C) 2001 Bernhard Rumpe * + * All rights reserved. * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License. See the file * + * COPYRIGHT for more information. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License along * + * with this program; if not, write to the Free Software Foundation, Inc., * + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + + +/** + * Symbol table entry for variables. + * + * Contains index in the parameter list and a flag if it + * is an input variable. + */ +class STEvar extends SymtabEntry { + boolean is_input; + int index; + + public STEvar(String v, boolean ii, int ind) { + super(v); + is_input=ii; + index=ind; + } + + public int kind() { + return SymtabEntry.VAR; + } + + public String toString() { + if (is_input) + return "input var "+name+" ("+index+")"; + else + return "parameter "+name+" ("+index+")"; + } + + public int getIndex() { + return index; + } + + public boolean isInput() { + return is_input; + } +} + diff --git a/tools/lexer/jflex-1.4/examples/interpreter/SymTab.java b/tools/lexer/jflex-1.4/examples/interpreter/SymTab.java new file mode 100644 index 000000000000..676a736cfb15 --- /dev/null +++ b/tools/lexer/jflex-1.4/examples/interpreter/SymTab.java @@ -0,0 +1,79 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Copyright (C) 2001 Gerwin Klein * + * Copyright (C) 2001 Bernhard Rumpe * + * All rights reserved. * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License. See the file * + * COPYRIGHT for more information. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License along * + * with this program; if not, write to the Free Software Foundation, Inc., * + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + + +import java.util.Enumeration; +import java.util.Hashtable; + +/** + * Symbol table for the interpreter, contains information about + * variables and functions. + * + * For every binding location of a name a symbol will be created. + * The symbol tables are connected hierarchically by pointers to + * the predecessor. Lookup takes predecessors into account. + */ +public class SymTab { + Hashtable h; // contains the liste of words + // key: String, value: SymtabEntry + + SymTab pred; // predecessor symbol table (if exists) + + public SymTab() { + this(null); + } + + public SymTab(SymTab p) { + h = new Hashtable(); + pred = p; + } + + public boolean enter(String s, SymtabEntry e) { + Object value = lookup(s); + h.put(s, e); + return(value==null); + } + + public SymtabEntry lookup(String s) { + Object value = h.get(s); + if (value==null && pred!=null) + value = pred.lookup(s); + return ((SymtabEntry)value); + } + + public String toString() { // for output with print + String res = "symbol table\n=============\n"; + Enumeration e = h.keys(); + String key; + + while(e.hasMoreElements()) { + key = (String)e.nextElement(); + res += key+" \t"+h.get(key)+"\n"; + } + + if (pred!=null) res+="++ predecessor!\n"; + return(res); + } + + public int size() { + return(h.size()); + } +} + diff --git a/tools/lexer/jflex-1.4/examples/interpreter/SymtabEntry.java b/tools/lexer/jflex-1.4/examples/interpreter/SymtabEntry.java new file mode 100644 index 000000000000..9eb7f1385c0d --- /dev/null +++ b/tools/lexer/jflex-1.4/examples/interpreter/SymtabEntry.java @@ -0,0 +1,48 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Copyright (C) 2001 Gerwin Klein * + * Copyright (C) 2001 Bernhard Rumpe * + * All rights reserved. * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License. See the file * + * COPYRIGHT for more information. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License along * + * with this program; if not, write to the Free Software Foundation, Inc., * + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + + +/** + * Symbol table entry for names, there are subclasses for + * variables and functions. + * + * Defines constants UNKNOWN, VAR und FUN as kinds of + * symbol table entries. + */ +class SymtabEntry { + String name; + + public SymtabEntry(String v) { + name=v; + } + + public int kind() { + return UNKNOWN; + } + + public String toString() { + return("unknown "+name); + } + + static final int UNKNOWN = 12; + static final int VAR = 13; + static final int FUN = 14; +} + diff --git a/tools/lexer/jflex-1.4/examples/interpreter/Tboolexp.java b/tools/lexer/jflex-1.4/examples/interpreter/Tboolexp.java new file mode 100644 index 000000000000..59ab0e30a885 --- /dev/null +++ b/tools/lexer/jflex-1.4/examples/interpreter/Tboolexp.java @@ -0,0 +1,64 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Copyright (C) 2001 Gerwin Klein * + * Copyright (C) 2001 Bernhard Rumpe * + * All rights reserved. * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License. See the file * + * COPYRIGHT for more information. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License along * + * with this program; if not, write to the Free Software Foundation, Inc., * + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + + +/** + * AST node for bool expressions + */ +class Tboolexp implements AST { + Texp exp1, exp2; // left and right subexpression + char kind; // '=', '<' and '!' for "<=" + + public Tboolexp(Texp e1, char k, Texp e2) { + exp1=e1; + kind=k; + exp2=e2; + } + + public String toString() { + if (kind!='!') + return(""+exp1+kind+exp2); + else + return(exp1+"<="+exp2); + } + + public void checkcontext(SymTab st) { // context conditions + exp1.checkcontext(st); + exp2.checkcontext(st); + } + + public void prepInterp(SymTab st) { // set pointers and indices + exp1.prepInterp(st); + exp2.prepInterp(st); + } + + public boolean interpret(int[] in, int[] par) { + int e1 = exp1.interpret(in,par); + int e2 = exp2.interpret(in,par); + switch(kind) { + case '=': return(e1==e2); + case '<': return(e1 * + * Copyright (C) 2001 Bernhard Rumpe * + * All rights reserved. * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License. See the file * + * COPYRIGHT for more information. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License along * + * with this program; if not, write to the Free Software Foundation, Inc., * + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + + +/** + * AST node for function declarations. + * + * Also contains a reference to the symbol table of + * the paramaters and their arity. + */ +class Tdekl implements AST { + Tident ident; // identifier + Tparlist parlist; // liste of parameter + Texp exp; // function body + + public Tdekl(Tident i, Tparlist p, Texp e) { + parlist=p; + ident=i; + exp=e; + } + + public String toString() { + return(ident+"("+parlist+") = \n "+exp); + } + + SymTab params; // symbol table of the parameters + int arity; + + public void setSymtab(SymTab st) { + params = new SymTab(st); + parlist.setSymtab(params,false,0); + arity = params.size(); + + boolean isNew = st.enter(ident.toString(), + new STEfun(ident.toString(),this,arity)); + // CoCo (Fun) + if(!isNew) Main.error("funktion "+ident+" defined twice!"); + } + + public void printSymtabs() { + System.out.print("funktion "+ident.toString()+"\n"+params); + } + + public void checkcontext() { + exp.checkcontext(params); // CoCo (DefFun,DefVar,Arity) + } + + public void prepInterp(SymTab st) { // set pointers and indices + exp.prepInterp(params); + } + + public int interpret(int[] in, int[] par) { + return(exp.interpret(in,par)); + } + + public int arity() { return(arity); } +} + diff --git a/tools/lexer/jflex-1.4/examples/interpreter/Tdekllist.java b/tools/lexer/jflex-1.4/examples/interpreter/Tdekllist.java new file mode 100644 index 000000000000..6f409a6a7829 --- /dev/null +++ b/tools/lexer/jflex-1.4/examples/interpreter/Tdekllist.java @@ -0,0 +1,69 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Copyright (C) 2001 Gerwin Klein * + * Copyright (C) 2001 Bernhard Rumpe * + * All rights reserved. * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License. See the file * + * COPYRIGHT for more information. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License along * + * with this program; if not, write to the Free Software Foundation, Inc., * + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + + +/** + * AST node for declaration lists of functions + */ +class Tdekllist implements AST { + Tdekllist dekllist; // rest list (optional null) + Tdekl dekl; // declaration + + public Tdekllist(Tdekllist p, Tdekl e) { + dekllist=p; + dekl=e; + } + + public Tdekllist(Tdekl e) { + dekllist=null; + dekl=e; + } + + public String toString() { + if (dekllist!=null) + return(dekllist+",\n"+dekl); + else + return(dekl.toString()); + } + + public void setSymtab(SymTab st) { + if (dekllist!=null) + dekllist.setSymtab(st); + dekl.setSymtab(st); + } + + public void printSymtabs() { + if (dekllist!=null) + dekllist.printSymtabs(); + dekl.printSymtabs(); + } + + public void checkcontext() { + if (dekllist!=null) + dekllist.checkcontext(); + dekl.checkcontext(); // CoCo (DefFun,DefVar,Arity) + } // in function body + + public void prepInterp(SymTab st) { // set pointers and indices + dekl.prepInterp(st); + if (dekllist!=null) dekllist.prepInterp(st); + } +} + diff --git a/tools/lexer/jflex-1.4/examples/interpreter/Texp.java b/tools/lexer/jflex-1.4/examples/interpreter/Texp.java new file mode 100644 index 000000000000..8c4ef9460d9a --- /dev/null +++ b/tools/lexer/jflex-1.4/examples/interpreter/Texp.java @@ -0,0 +1,43 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Copyright (C) 2001 Gerwin Klein * + * Copyright (C) 2001 Bernhard Rumpe * + * All rights reserved. * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License. See the file * + * COPYRIGHT for more information. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License along * + * with this program; if not, write to the Free Software Foundation, Inc., * + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + + +/** + * AST node for an integer expression. + * + * The non terminal exp is the sum of multiple variants and + * therefore modeled as an abstract class. + * + * The interpretation function interpret is called with + * valuations of input variables in and parameters + * par. Before interpret can be called, pointers + * and variable indices must be set with prepInterp. + */ +abstract class Texp implements AST { + // test context conditions (DefFun,DefVar,Arity) + abstract public void checkcontext(SymTab st); + + // set pointers and indices for variables and functions + abstract public void prepInterp(SymTab st); + + // interpretation + abstract public int interpret(int[] in, int[] par); +} + diff --git a/tools/lexer/jflex-1.4/examples/interpreter/Texpinfix.java b/tools/lexer/jflex-1.4/examples/interpreter/Texpinfix.java new file mode 100644 index 000000000000..9db0b0c17c5b --- /dev/null +++ b/tools/lexer/jflex-1.4/examples/interpreter/Texpinfix.java @@ -0,0 +1,64 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Copyright (C) 2001 Gerwin Klein * + * Copyright (C) 2001 Bernhard Rumpe * + * All rights reserved. * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License. See the file * + * COPYRIGHT for more information. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License along * + * with this program; if not, write to the Free Software Foundation, Inc., * + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + + +/** + * AST node for infix expressions + */ +class Texpinfix extends Texp implements AST { + Texp exp1, exp2; // left and right sub expression + char kind; // kind ('+', '-', '*', '/') + + public Texpinfix(Texp e1, char k, Texp e2) { + exp1=e1; + kind=k; + exp2=e2; + } + + public String toString() { + return("("+exp1+kind+exp2+")"); + } + + public void checkcontext(SymTab st) { // context conditions + exp1.checkcontext(st); + exp2.checkcontext(st); + } + + public void prepInterp(SymTab st) { // set pointers und indices + exp1.prepInterp(st); + exp2.prepInterp(st); + } + + public int interpret(int[] in, int[] par) { + int e1 = exp1.interpret(in,par); + int e2 = exp2.interpret(in,par); + + switch (kind) { + case '+': return(e1+e2); + case '-': return(e1-e2); + case '*': return(e1*e2); + case '/': return(e1/e2); + } + + return -1; // error + } +} + + diff --git a/tools/lexer/jflex-1.4/examples/interpreter/Texplist.java b/tools/lexer/jflex-1.4/examples/interpreter/Texplist.java new file mode 100644 index 000000000000..84ffe96b8ae3 --- /dev/null +++ b/tools/lexer/jflex-1.4/examples/interpreter/Texplist.java @@ -0,0 +1,73 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Copyright (C) 2001 Gerwin Klein * + * Copyright (C) 2001 Bernhard Rumpe * + * All rights reserved. * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License. See the file * + * COPYRIGHT for more information. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License along * + * with this program; if not, write to the Free Software Foundation, Inc., * + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + + +/** + * AST node for a list of expressions. + * + * The interpretation of a list of expressions stores the + * results of the expressions in an array that can be used + * as parameter list for function calls. + */ +class Texplist implements AST { + Texplist explist; // next list element (optional null) + Texp exp; // expression of this list node + + public Texplist(Texplist p, Texp e) { + explist=p; + exp=e; + } + + public Texplist(Texp e) { + explist=null; + exp=e; + } + + public String toString() { + if (explist!=null) + return explist+","+exp; + else + return exp.toString(); + } + + public void checkcontext(SymTab st) { + if (explist!=null) + explist.checkcontext(st); + exp.checkcontext(st); // CoCo (DefFun,DefVar,Arity) + } // in expression + + public int length() { + if (explist!=null) + return 1+explist.length(); + else + return 1; + } + + public void prepInterp(SymTab st) { // set pointers and indices + exp.prepInterp(st); + if (explist!=null) explist.prepInterp(st); + } + + public void interpret(int[] in, int[] par, int[] res, int index) { + res[index] = exp.interpret(in,par); + if (explist!=null) explist.interpret(in,par,res,index+1); + } +} + diff --git a/tools/lexer/jflex-1.4/examples/interpreter/Tfun.java b/tools/lexer/jflex-1.4/examples/interpreter/Tfun.java new file mode 100644 index 000000000000..9776ae98be05 --- /dev/null +++ b/tools/lexer/jflex-1.4/examples/interpreter/Tfun.java @@ -0,0 +1,66 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Copyright (C) 2001 Gerwin Klein * + * Copyright (C) 2001 Bernhard Rumpe * + * All rights reserved. * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License. See the file * + * COPYRIGHT for more information. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License along * + * with this program; if not, write to the Free Software Foundation, Inc., * + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + + +/** + * AST node for function application. + * + * Also contains pointer to declaration location of the function. + */ +class Tfun extends Texp implements AST { + Tident ident; // name of the function + Texplist explist; // parameter list + + public Tfun(Tident i, Texplist e) { + ident=i; + explist=e; + } + + public String toString() { + return ident+"("+explist+")"; + } + + public void checkcontext(SymTab st) { // CoCo (DefFun,Arity) + explist.checkcontext(st); + SymtabEntry ste = st.lookup(ident.toString()); + if (ste==null) + Main.error("function not defined: "+ident); + else if (ste.kind() != SymtabEntry.FUN) + Main.error("variable used as funktion: "+ident); + else if (((STEfun)ste).arity() != explist.length()) + Main.error("wrong arity at function call: "+ident); + } + + Tdekl fundekl; // pointer to location of function declaration + + // set pointers and indices + public void prepInterp(SymTab st) { + fundekl = ((STEfun)st.lookup(ident.toString())).getDekl(); + explist.prepInterp(st); + } + + public int interpret(int[] in, int[] par) { + int[] newparams = new int[fundekl.arity()]; + explist.interpret(in,par,newparams,0); + return fundekl.interpret(in,newparams); + } +} + + diff --git a/tools/lexer/jflex-1.4/examples/interpreter/Tident.java b/tools/lexer/jflex-1.4/examples/interpreter/Tident.java new file mode 100644 index 000000000000..dc8cba98a825 --- /dev/null +++ b/tools/lexer/jflex-1.4/examples/interpreter/Tident.java @@ -0,0 +1,62 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Copyright (C) 2001 Gerwin Klein * + * Copyright (C) 2001 Bernhard Rumpe * + * All rights reserved. * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License. See the file * + * COPYRIGHT for more information. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License along * + * with this program; if not, write to the Free Software Foundation, Inc., * + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + + +/** + * AST node for an identifier + */ +class Tident extends Texp implements AST { + String name; + + public Tident(String s) { + name = s; + } + + public String toString() { + return name; + } + + public void checkcontext(SymTab st) { // CoCo (DefVar) + SymtabEntry ste = st.lookup(name); + + if (ste==null) + Main.error("variable not defined: "+name); + else if (ste.kind() != SymtabEntry.VAR) + Main.error("function used as variable: "+name); + } + + int index; // number of ident in environment + boolean is_input; // is it an input variable? + + public void prepInterp(SymTab st) { // set index for environment + STEvar ste = (STEvar)st.lookup(name); + index = ste.getIndex(); + is_input = ste.isInput(); + } + + public int interpret(int[] in, int[] par) { + if (is_input) + return(in[index]); + else + return(par[index]); + } +} + + diff --git a/tools/lexer/jflex-1.4/examples/interpreter/Tifthenelse.java b/tools/lexer/jflex-1.4/examples/interpreter/Tifthenelse.java new file mode 100644 index 000000000000..e7193f87ab66 --- /dev/null +++ b/tools/lexer/jflex-1.4/examples/interpreter/Tifthenelse.java @@ -0,0 +1,59 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Copyright (C) 2001 Gerwin Klein * + * Copyright (C) 2001 Bernhard Rumpe * + * All rights reserved. * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License. See the file * + * COPYRIGHT for more information. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License along * + * with this program; if not, write to the Free Software Foundation, Inc., * + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + + +/** + * AST node for if-then-else expressions + */ +class Tifthenelse extends Texp implements AST { + Tboolexp boolexp; // condition + Texp exp1, exp2; // then and else branch + + public Tifthenelse(Tboolexp b, Texp e1, Texp e2) { + boolexp=b; + exp1=e1; + exp2=e2; + } + + public String toString() { + return "if "+boolexp+" then "+exp1+" else "+exp2+" fi"; + } + + public void checkcontext(SymTab st) { + boolexp.checkcontext(st); + exp1.checkcontext(st); + exp2.checkcontext(st); + } + + public void prepInterp(SymTab st) { + boolexp.prepInterp(st); + exp1.prepInterp(st); + exp2.prepInterp(st); + } + + public int interpret(int[] in, int[] par) { + boolean b = boolexp.interpret(in,par); + if (b) + return exp1.interpret(in,par); + else + return exp2.interpret(in,par); + } +} + diff --git a/tools/lexer/jflex-1.4/examples/interpreter/Tnumber.java b/tools/lexer/jflex-1.4/examples/interpreter/Tnumber.java new file mode 100644 index 000000000000..fef710ae24c5 --- /dev/null +++ b/tools/lexer/jflex-1.4/examples/interpreter/Tnumber.java @@ -0,0 +1,47 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Copyright (C) 2001 Gerwin Klein * + * Copyright (C) 2001 Bernhard Rumpe * + * All rights reserved. * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License. See the file * + * COPYRIGHT for more information. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License along * + * with this program; if not, write to the Free Software Foundation, Inc., * + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + + +/** + * AST node for a number + */ +class Tnumber extends Texp implements AST { + int n; // value of the number + + public Tnumber(String s) { + try { n = Integer.parseInt(s); } + catch (NumberFormatException e) { n=-1; }; + } + + public String toString() { + return(""+n); + } + + public void checkcontext(SymTab st) { + } + + public void prepInterp(SymTab st) { + } + + public int interpret(int[] in, int[] par) { + return(n); + } +} + diff --git a/tools/lexer/jflex-1.4/examples/interpreter/Tparlist.java b/tools/lexer/jflex-1.4/examples/interpreter/Tparlist.java new file mode 100644 index 000000000000..6f2ada93f0a6 --- /dev/null +++ b/tools/lexer/jflex-1.4/examples/interpreter/Tparlist.java @@ -0,0 +1,54 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Copyright (C) 2001 Gerwin Klein * + * Copyright (C) 2001 Bernhard Rumpe * + * All rights reserved. * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License. See the file * + * COPYRIGHT for more information. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License along * + * with this program; if not, write to the Free Software Foundation, Inc., * + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + + +/** + * AST node for a parameter list. + */ +class Tparlist implements AST { + Tparlist parlist; // rest of the liste (optional null) + Tident ident; // identifier + + public Tparlist(Tparlist p, Tident i) { + parlist=p; + ident=i; + } + + public Tparlist(Tident i) { + parlist=null; + ident=i; + } + + public String toString() { + if (parlist!=null) + return parlist+","+ident; + else + return ident.toString(); + } + + public void setSymtab(SymTab st, boolean isInput, int index) { + boolean isNew = st.enter(ident.toString(), + new STEvar(ident.toString(), isInput, index)); + + if (!isNew) Main.error("Variable "+ident+" defined twice!"); + if (parlist!=null) parlist.setSymtab(st, isInput, index+1); + } +} + diff --git a/tools/lexer/jflex-1.4/examples/interpreter/Tprogram.java b/tools/lexer/jflex-1.4/examples/interpreter/Tprogram.java new file mode 100644 index 000000000000..08a93d17fc80 --- /dev/null +++ b/tools/lexer/jflex-1.4/examples/interpreter/Tprogram.java @@ -0,0 +1,99 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Copyright (C) 2001 Gerwin Klein * + * Copyright (C) 2001 Bernhard Rumpe * + * All rights reserved. * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License. See the file * + * COPYRIGHT for more information. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License along * + * with this program; if not, write to the Free Software Foundation, Inc., * + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + + +/** + * AST node for the whole program (top node). + * + * Also contains two symbol tables, one for input variables, + * one for function names. + * + * All operations like context check, symbol table build up + * etc. start here. + */ +class Tprogram implements AST { + + Tparlist parlist; // input variables + Tdekllist dekllist; // function declarations + Texplist explist; // result expressions + Texplist arguments; // input values + + public Tprogram(Tparlist p, Tdekllist d, Texplist e, Texplist a) { + parlist=p; + dekllist=d; + explist=e; + arguments=a; + } + + public String toString() { + return("Program:\n=============\ninput "+parlist+ + "\nfunctions\n"+dekllist+"\noutput "+explist+ + "\narguments "+arguments+"\nend"); + } + + SymTab inputs; // table of input variables + SymTab functions; // table of functions + + public void setSymtabs() { // calculate symbol table entries + inputs = new SymTab(); // set input variables + parlist.setSymtab(inputs, true, 0); + functions = new SymTab(inputs); + dekllist.setSymtab(functions); + } + + public void printSymtabs() { + System.out.print("Input variables-\n"+inputs); + System.out.print("Functions-\n"+functions); + dekllist.printSymtabs(); + } + + public void checkcontext() { + dekllist.checkcontext(); // CoCo (DefFun,DefVar,Arity) + // in function bodies + explist.checkcontext(functions); // CoCo (DefFun,DefVar,Arity) + // in result expressions + arguments.checkcontext(new SymTab()); // CoCo (constants) + // in arguments + if (arguments.length()!=inputs.size()) + Main.error("Argument list and input variables list differ!"); + } + + public void prepInterp() { // set pointers and indices + dekllist.prepInterp(functions); + explist.prepInterp(functions); + } + + public void interpret() { + int[] inputEnv = new int[inputs.size()]; // set input + + arguments.interpret(null,null,inputEnv,0); + + System.out.println("Result:\n============="); + + int[] ergebnis = new int[explist.length()]; + explist.interpret(inputEnv,null,ergebnis,0); // calculate result + + int i; + for (i=explist.length()-1; i > 0; i--) + System.out.print(ergebnis[i]+", "); + System.out.println(ergebnis[i]); + } +} + diff --git a/tools/lexer/jflex-1.4/examples/interpreter/Tuminus.java b/tools/lexer/jflex-1.4/examples/interpreter/Tuminus.java new file mode 100644 index 000000000000..d269b34f4a5e --- /dev/null +++ b/tools/lexer/jflex-1.4/examples/interpreter/Tuminus.java @@ -0,0 +1,49 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Copyright (C) 2001 Gerwin Klein * + * Copyright (C) 2001 Bernhard Rumpe * + * All rights reserved. * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License. See the file * + * COPYRIGHT for more information. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License along * + * with this program; if not, write to the Free Software Foundation, Inc., * + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + + +/** + * AST node for unary minus expressions. + */ +class Tuminus extends Texp implements AST { + + Texp exp; // the negated expression + + public Tuminus(Texp e) { + exp=e; + } + + public String toString() { + return "-"+exp; + } + + public void checkcontext(SymTab st) { + exp.checkcontext(st); + } + + public void prepInterp(SymTab st) { + exp.prepInterp(st); + } + + public int interpret(int[] in, int[] par) { + return -(exp.interpret(in,par)); + } +} + diff --git a/tools/lexer/jflex-1.4/examples/interpreter/build.xml b/tools/lexer/jflex-1.4/examples/interpreter/build.xml new file mode 100644 index 000000000000..51829ba97893 --- /dev/null +++ b/tools/lexer/jflex-1.4/examples/interpreter/build.xml @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tools/lexer/jflex-1.4/examples/interpreter/example.as b/tools/lexer/jflex-1.4/examples/interpreter/example.as new file mode 100644 index 000000000000..81522472e175 --- /dev/null +++ b/tools/lexer/jflex-1.4/examples/interpreter/example.as @@ -0,0 +1,16 @@ + +// example program for interpreter testing +// contains division and modulo functins + +input a,b +functions div(x,y) = if x < y + then 0 + else div(x-y,y)+1 + fi, + mod(x,y) = if x < y + then x + else mod(x-y,y) + fi +output div(a,b), mod(a,b) +arguments 324, 17 +end diff --git a/tools/lexer/jflex-1.4/examples/interpreter/parser.cup b/tools/lexer/jflex-1.4/examples/interpreter/parser.cup new file mode 100644 index 000000000000..3d7f856a679d --- /dev/null +++ b/tools/lexer/jflex-1.4/examples/interpreter/parser.cup @@ -0,0 +1,112 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Copyright (C) 2001 Gerwin Klein * + * Copyright (C) 2001 Bernhard Rumpe * + * All rights reserved. * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License. See the file * + * COPYRIGHT for more information. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License along * + * with this program; if not, write to the Free Software Foundation, Inc., * + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + + +// definition of tokens, if applicable with token type +terminal INPUT, FUNCTIONS, OUTPUT, END, ARGUMENTS; +terminal IF, THEN, ELSE, FI, ERROR; +terminal COMMA, LPAR, RPAR; +terminal EQ, LE, LEQ, MINUS, PLUS, TIMES, DIV, UMINUS; + +terminal String ID, NUMBER; + +non terminal Tprogram program; +non terminal Tparlist parlist; +non terminal Texplist explist; +non terminal Tdekllist dekllist; +non terminal Tdekl dekl; +non terminal Texp exp; +non terminal Tboolexp boolexp; +non terminal Tident ident; +non terminal Tnumber number; + + +// precedences, left associativity +precedence left EQ, LE, LEQ; +precedence left MINUS, PLUS; +precedence left TIMES, DIV; +precedence left UMINUS; + + +// here the rules start +program ::= INPUT parlist:p FUNCTIONS dekllist:d OUTPUT explist:o + ARGUMENTS explist:a END + {: RESULT = new Tprogram(p,d,o,a); :} + ; + +parlist ::= ident:i + {: RESULT = new Tparlist(i); :} + | parlist:p COMMA ident:i + {: RESULT = new Tparlist(p,i); :} + ; + +explist ::= exp:e + {: RESULT = new Texplist(e); :} + | explist:l COMMA exp:e + {: RESULT = new Texplist(l,e); :} + ; + +dekllist ::= dekl:d + {: RESULT = new Tdekllist(d);:} + | dekllist:l COMMA dekl:d + {: RESULT = new Tdekllist(l,d); :} + ; + +dekl ::= ident:i LPAR parlist:p RPAR EQ exp:e + {: RESULT = new Tdekl(i,p,e); :} + ; + +exp ::= number:n + {: RESULT = n; :} + | ident:i + {: RESULT = i; :} + | ident:i LPAR explist:e RPAR + {: RESULT = new Tfun(i,e); :} + | LPAR exp:e RPAR + {: RESULT = e; :} + | MINUS exp:e + {: RESULT = new Tuminus(e); :} %prec UMINUS + | exp:l PLUS exp:r + {: RESULT = new Texpinfix(l,'+',r); :} + | exp:l TIMES exp:r + {: RESULT = new Texpinfix(l,'*',r); :} + | exp:l DIV exp:r + {: RESULT = new Texpinfix(l,'/',r); :} + | exp:l MINUS exp:r + {: RESULT = new Texpinfix(l,'-',r); :} + | IF boolexp:b THEN exp:t ELSE exp:e FI + {: RESULT = new Tifthenelse(b,t,e); :} + ; + +boolexp ::= exp:l EQ exp:r + {: RESULT = new Tboolexp(l,'=',r); :} + | exp:l LE exp:r + {: RESULT = new Tboolexp(l,'<',r); :} + | exp:l LEQ exp:r + {: RESULT = new Tboolexp(l,'!',r); :} + ; + +ident ::= ID:n + {: RESULT = new Tident(n); :} + ; + +number ::= NUMBER:z + {: RESULT = new Tnumber(z); :} + ; diff --git a/tools/lexer/jflex-1.4/examples/interpreter/scanner.flex b/tools/lexer/jflex-1.4/examples/interpreter/scanner.flex new file mode 100644 index 000000000000..a6c3ca7e6c91 --- /dev/null +++ b/tools/lexer/jflex-1.4/examples/interpreter/scanner.flex @@ -0,0 +1,71 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Copyright (C) 2001 Gerwin Klein * + * Copyright (C) 2001 Bernhard Rumpe * + * All rights reserved. * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License. See the file * + * COPYRIGHT for more information. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License along * + * with this program; if not, write to the Free Software Foundation, Inc., * + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + + +import java_cup.runtime.Symbol; + +%% + +%cup +%implements sym + +%{ + SymTab symtab; // externe symbol table + + public void setSymtab(SymTab symtab) { + this.symtab = symtab; + } + + private Symbol sym(int sym) { + return new Symbol(sym); + } + + private Symbol sym(int sym, Object val) { + return new Symbol(sym, val); + } +%} + +%% + +"arguments" { return sym(ARGUMENTS); } +"input" { return sym(INPUT); } +"functions" { return sym(FUNCTIONS); } +"output" { return sym(OUTPUT); } +"end" { return sym(END); } +"if" { return sym(IF); } +"then" { return sym(THEN); } +"else" { return sym(ELSE); } +"fi" { return sym(FI); } +[a-z]+ { symtab.enter(yytext(),new SymtabEntry(yytext())); + return sym(ID,yytext()); } +[0-9]+ { return sym(NUMBER,yytext()); } +"," { return sym(COMMA); } +"(" { return sym(LPAR); } +")" { return sym(RPAR); } +"=" { return sym(EQ); } +"-" { return sym(MINUS); } +"+" { return sym(PLUS); } +"*" { return sym(TIMES); } +"/" { return sym(DIV); } +"<" { return sym(LE); } +"<=" { return sym(LEQ); } +[\ \t\b\f\r\n]+ { /* eat whitespace */ } +"//"[^\n]* { /* one-line comment */ } +. { throw new Error("Unexpected character ["+yytext()+"]"); } diff --git a/tools/lexer/jflex-1.4/examples/java/JavaParser.java b/tools/lexer/jflex-1.4/examples/java/JavaParser.java new file mode 100644 index 000000000000..4c587051b460 --- /dev/null +++ b/tools/lexer/jflex-1.4/examples/java/JavaParser.java @@ -0,0 +1,47 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Copyright (C) 1998-2004 Gerwin Klein * + * All rights reserved. * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License. See the file * + * COPYRIGHT for more information. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License along * + * with this program; if not, write to the Free Software Foundation, Inc., * + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +import java.io.FileReader; + + +/** + * Simple test driver for the java parser. Just runs it on some + * input files, gives no useful output. + */ +public class JavaParser { + + public static void main(String argv[]) { + + for (int i = 0; i < argv.length; i++) { + try { + System.out.println("Parsing ["+argv[i]+"]"); + Scanner s = new Scanner(new UnicodeEscapes(new FileReader(argv[i]))); + parser p = new parser(s); + p.parse(); + + System.out.println("No errors."); + } + catch (Exception e) { + e.printStackTrace(System.out); + System.exit(1); + } + } + } + +} diff --git a/tools/lexer/jflex-1.4/examples/java/JavaSymbol.java b/tools/lexer/jflex-1.4/examples/java/JavaSymbol.java new file mode 100644 index 000000000000..d27b63dfe69f --- /dev/null +++ b/tools/lexer/jflex-1.4/examples/java/JavaSymbol.java @@ -0,0 +1,31 @@ + +public class JavaSymbol extends java_cup.runtime.Symbol { + private int line; + private int column; + + public JavaSymbol(int type, int line, int column) { + this(type, line, column, -1, -1, null); + } + + public JavaSymbol(int type, int line, int column, Object value) { + this(type, line, column, -1, -1, value); + } + + public JavaSymbol(int type, int line, int column, int left, int right, Object value) { + super(type, left, right, value); + this.line = line; + this.column = column; + } + + public int getLine() { + return line; + } + + public int getColumn() { + return column; + } + + public String toString() { + return "line "+line+", column "+column+", sym: "+sym+(value == null ? "" : (", value: '"+value+"'")); + } +} diff --git a/tools/lexer/jflex-1.4/examples/java/Makefile b/tools/lexer/jflex-1.4/examples/java/Makefile new file mode 100644 index 000000000000..655ebd368150 --- /dev/null +++ b/tools/lexer/jflex-1.4/examples/java/Makefile @@ -0,0 +1,48 @@ +# You need CUP v0.10j (or newer) for this makefile to work (for java12.cup) +# +# CUP classes should be included in CLASSPATH + +CUP = java java_cup.Main -interface < +JFLEX = jflex +JAVA = java +JAVAC = javac +#JAVAC = jikes +JAVACFLAGS = + +# -------------------------------------------------- + +all: test + +test: lexer-output.txt + @(diff lexer-output.txt lexer-output.good && echo "Test OK!") || echo "Test failed!" + +lexer-output.txt: compile + $(JAVA) TestLexer TestLexer.java > lexer-output.txt + + +compile: scanner parser unicode + $(JAVAC) $(JAVACFLAGS) JavaParser.java TestLexer.java + +parser: parser.java + +parser.java: java12.cup + $(CUP) java12.cup + +scanner: Scanner.java + +Scanner.java: java.flex + $(JFLEX) java.flex + +unicode: UnicodeEscapes.java + +UnicodeEscapes.java: unicode.flex + $(JFLEX) unicode.flex + +clean: + rm -f *.class + rm -f *~ + rm -f Scanner.java + rm -f parser.java + rm -f sym.java + rm -f UnicodeEscapes.java + rm -f lexer-output.txt diff --git a/tools/lexer/jflex-1.4/examples/java/README b/tools/lexer/jflex-1.4/examples/java/README new file mode 100644 index 000000000000..096582bf4417 --- /dev/null +++ b/tools/lexer/jflex-1.4/examples/java/README @@ -0,0 +1,41 @@ +This directory contains a scanner and parser for the Java programming language. + +You need the parser generator CUP v0.10j (or newer) for the parser to work. +Use the Makefile to generate the lexer and parser, or type: + +jflex unicode.flex +jflex java.flex +java java_cup.Main -interface < java12.cup +javac JavaParser.java TestLexer.java + + +The parser can be tested with: +java JavaParser + +The scanner (without parser attached) can be test with: +java TestLexer + + +files: + +unicode.flex + JFlex specification for the Unicode preprocessing phase + (see section 3.3 of the Java Language Specification). + Demonstrates how to implement a FilterReader with JFlex. + +java.flex + JFlex specification for the "real" Java 1.2 lexer. + +java12.cup + CUP specification for the Java 1.2 parser + Copyright (C) 1998 by C. Scott Ananian + (with small modifications to interface with the Lexer) + +JavaParser.java + a simple main class to run the parser (no other useful output though) + +TestLexer.java + a simple test driver for the scanner, produces debug output + +lexer-output.good + lexer output for input file TestLexer.java for testing diff --git a/tools/lexer/jflex-1.4/examples/java/TestLexer.java b/tools/lexer/jflex-1.4/examples/java/TestLexer.java new file mode 100644 index 000000000000..90e4f35681bf --- /dev/null +++ b/tools/lexer/jflex-1.4/examples/java/TestLexer.java @@ -0,0 +1,62 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Copyright (C) 2004 Gerwin Klein * + * All rights reserved. * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License. See the file * + * COPYRIGHT for more information. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License along * + * with this program; if not, write to the Free Software Foundation, Inc., * + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +import java_cup.runtime.Symbol; + +import java.io.FileReader; + + +/** + * Simple test driver for the java lexer. Just runs it on some + * input files and produces debug output. Needs symbol class from + * parser. + */ +public class TestLexer { + + /** some numerals to for lexer testing */ + int intDec = 37; + long longDec = 37l; + int intHex = 0x0001; + long longHex = 0xFFFFl; + int intOct = 0377; + long longOc = 007l; + + + public static void main(String argv[]) { + + for (int i = 0; i < argv.length; i++) { + try { + System.out.println("Lexing ["+argv[i]+"]"); + Scanner scanner = new Scanner(new UnicodeEscapes(new FileReader(argv[i]))); + + Symbol s; + do { + s = scanner.debug_next_token(); + System.out.println("token: "+s); + } while (s.sym != sym.EOF); + + System.out.println("No errors."); + } + catch (Exception e) { + e.printStackTrace(System.out); + System.exit(1); + } + } + } +} diff --git a/tools/lexer/jflex-1.4/examples/java/java.flex b/tools/lexer/jflex-1.4/examples/java/java.flex new file mode 100644 index 000000000000..cdce5b6a11cb --- /dev/null +++ b/tools/lexer/jflex-1.4/examples/java/java.flex @@ -0,0 +1,312 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Copyright (C) 1998-2004 Gerwin Klein * + * All rights reserved. * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License. See the file * + * COPYRIGHT for more information. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License along * + * with this program; if not, write to the Free Software Foundation, Inc., * + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +/* Java 1.2 language lexer specification */ + +/* Use together with unicode.flex for Unicode preprocesssing */ +/* and java12.cup for a Java 1.2 parser */ + +/* Note that this lexer specification is not tuned for speed. + It is in fact quite slow on integer and floating point literals, + because the input is read twice and the methods used to parse + the numbers are not very fast. + For a production quality application (e.g. a Java compiler) + this could be optimized */ + + +import java_cup.runtime.*; + +%% + +%public +%class Scanner +%implements sym + +%unicode + +%line +%column + +%cup +%cupdebug + +%{ + StringBuffer string = new StringBuffer(); + + private Symbol symbol(int type) { + return new JavaSymbol(type, yyline+1, yycolumn+1); + } + + private Symbol symbol(int type, Object value) { + return new JavaSymbol(type, yyline+1, yycolumn+1, value); + } + + /** + * assumes correct representation of a long value for + * specified radix in scanner buffer from start + * to end + */ + private long parseLong(int start, int end, int radix) { + long result = 0; + long digit; + + for (int i = start; i < end; i++) { + digit = Character.digit(yycharat(i),radix); + result*= radix; + result+= digit; + } + + return result; + } +%} + +/* main character classes */ +LineTerminator = \r|\n|\r\n +InputCharacter = [^\r\n] + +WhiteSpace = {LineTerminator} | [ \t\f] + +/* comments */ +Comment = {TraditionalComment} | {EndOfLineComment} | + {DocumentationComment} + +TraditionalComment = "/*" [^*] ~"*/" | "/*" "*"+ "/" +EndOfLineComment = "//" {InputCharacter}* {LineTerminator}? +DocumentationComment = "/*" "*"+ [^/*] ~"*/" + +/* identifiers */ +Identifier = [:jletter:][:jletterdigit:]* + +/* integer literals */ +DecIntegerLiteral = 0 | [1-9][0-9]* +DecLongLiteral = {DecIntegerLiteral} [lL] + +HexIntegerLiteral = 0 [xX] 0* {HexDigit} {1,8} +HexLongLiteral = 0 [xX] 0* {HexDigit} {1,16} [lL] +HexDigit = [0-9a-fA-F] + +OctIntegerLiteral = 0+ [1-3]? {OctDigit} {1,15} +OctLongLiteral = 0+ 1? {OctDigit} {1,21} [lL] +OctDigit = [0-7] + +/* floating point literals */ +FloatLiteral = ({FLit1}|{FLit2}|{FLit3}) {Exponent}? [fF] +DoubleLiteral = ({FLit1}|{FLit2}|{FLit3}) {Exponent}? + +FLit1 = [0-9]+ \. [0-9]* +FLit2 = \. [0-9]+ +FLit3 = [0-9]+ +Exponent = [eE] [+-]? [0-9]+ + +/* string and character literals */ +StringCharacter = [^\r\n\"\\] +SingleCharacter = [^\r\n\'\\] + +%state STRING, CHARLITERAL + +%% + + { + + /* keywords */ + "abstract" { return symbol(ABSTRACT); } + "boolean" { return symbol(BOOLEAN); } + "break" { return symbol(BREAK); } + "byte" { return symbol(BYTE); } + "case" { return symbol(CASE); } + "catch" { return symbol(CATCH); } + "char" { return symbol(CHAR); } + "class" { return symbol(CLASS); } + "const" { return symbol(CONST); } + "continue" { return symbol(CONTINUE); } + "do" { return symbol(DO); } + "double" { return symbol(DOUBLE); } + "else" { return symbol(ELSE); } + "extends" { return symbol(EXTENDS); } + "final" { return symbol(FINAL); } + "finally" { return symbol(FINALLY); } + "float" { return symbol(FLOAT); } + "for" { return symbol(FOR); } + "default" { return symbol(DEFAULT); } + "implements" { return symbol(IMPLEMENTS); } + "import" { return symbol(IMPORT); } + "instanceof" { return symbol(INSTANCEOF); } + "int" { return symbol(INT); } + "interface" { return symbol(INTERFACE); } + "long" { return symbol(LONG); } + "native" { return symbol(NATIVE); } + "new" { return symbol(NEW); } + "goto" { return symbol(GOTO); } + "if" { return symbol(IF); } + "public" { return symbol(PUBLIC); } + "short" { return symbol(SHORT); } + "super" { return symbol(SUPER); } + "switch" { return symbol(SWITCH); } + "synchronized" { return symbol(SYNCHRONIZED); } + "package" { return symbol(PACKAGE); } + "private" { return symbol(PRIVATE); } + "protected" { return symbol(PROTECTED); } + "transient" { return symbol(TRANSIENT); } + "return" { return symbol(RETURN); } + "void" { return symbol(VOID); } + "static" { return symbol(STATIC); } + "while" { return symbol(WHILE); } + "this" { return symbol(THIS); } + "throw" { return symbol(THROW); } + "throws" { return symbol(THROWS); } + "try" { return symbol(TRY); } + "volatile" { return symbol(VOLATILE); } + "strictfp" { return symbol(STRICTFP); } + + /* boolean literals */ + "true" { return symbol(BOOLEAN_LITERAL, new Boolean(true)); } + "false" { return symbol(BOOLEAN_LITERAL, new Boolean(false)); } + + /* null literal */ + "null" { return symbol(NULL_LITERAL); } + + + /* separators */ + "(" { return symbol(LPAREN); } + ")" { return symbol(RPAREN); } + "{" { return symbol(LBRACE); } + "}" { return symbol(RBRACE); } + "[" { return symbol(LBRACK); } + "]" { return symbol(RBRACK); } + ";" { return symbol(SEMICOLON); } + "," { return symbol(COMMA); } + "." { return symbol(DOT); } + + /* operators */ + "=" { return symbol(EQ); } + ">" { return symbol(GT); } + "<" { return symbol(LT); } + "!" { return symbol(NOT); } + "~" { return symbol(COMP); } + "?" { return symbol(QUESTION); } + ":" { return symbol(COLON); } + "==" { return symbol(EQEQ); } + "<=" { return symbol(LTEQ); } + ">=" { return symbol(GTEQ); } + "!=" { return symbol(NOTEQ); } + "&&" { return symbol(ANDAND); } + "||" { return symbol(OROR); } + "++" { return symbol(PLUSPLUS); } + "--" { return symbol(MINUSMINUS); } + "+" { return symbol(PLUS); } + "-" { return symbol(MINUS); } + "*" { return symbol(MULT); } + "/" { return symbol(DIV); } + "&" { return symbol(AND); } + "|" { return symbol(OR); } + "^" { return symbol(XOR); } + "%" { return symbol(MOD); } + "<<" { return symbol(LSHIFT); } + ">>" { return symbol(RSHIFT); } + ">>>" { return symbol(URSHIFT); } + "+=" { return symbol(PLUSEQ); } + "-=" { return symbol(MINUSEQ); } + "*=" { return symbol(MULTEQ); } + "/=" { return symbol(DIVEQ); } + "&=" { return symbol(ANDEQ); } + "|=" { return symbol(OREQ); } + "^=" { return symbol(XOREQ); } + "%=" { return symbol(MODEQ); } + "<<=" { return symbol(LSHIFTEQ); } + ">>=" { return symbol(RSHIFTEQ); } + ">>>=" { return symbol(URSHIFTEQ); } + + /* string literal */ + \" { yybegin(STRING); string.setLength(0); } + + /* character literal */ + \' { yybegin(CHARLITERAL); } + + /* numeric literals */ + + {DecIntegerLiteral} { return symbol(INTEGER_LITERAL, new Integer(yytext())); } + {DecLongLiteral} { return symbol(INTEGER_LITERAL, new Long(yytext().substring(0,yylength()-1))); } + + {HexIntegerLiteral} { return symbol(INTEGER_LITERAL, new Integer((int) parseLong(2, yylength(), 16))); } + {HexLongLiteral} { return symbol(INTEGER_LITERAL, new Long(parseLong(2, yylength()-1, 16))); } + + {OctIntegerLiteral} { return symbol(INTEGER_LITERAL, new Integer((int) parseLong(0, yylength(), 8))); } + {OctLongLiteral} { return symbol(INTEGER_LITERAL, new Long(parseLong(0, yylength()-1, 8))); } + + {FloatLiteral} { return symbol(FLOATING_POINT_LITERAL, new Float(yytext().substring(0,yylength()-1))); } + {DoubleLiteral} { return symbol(FLOATING_POINT_LITERAL, new Double(yytext())); } + {DoubleLiteral}[dD] { return symbol(FLOATING_POINT_LITERAL, new Double(yytext().substring(0,yylength()-1))); } + + /* comments */ + {Comment} { /* ignore */ } + + /* whitespace */ + {WhiteSpace} { /* ignore */ } + + /* identifiers */ + {Identifier} { return symbol(IDENTIFIER, yytext()); } +} + + { + \" { yybegin(YYINITIAL); return symbol(STRING_LITERAL, string.toString()); } + + {StringCharacter}+ { string.append( yytext() ); } + + /* escape sequences */ + "\\b" { string.append( '\b' ); } + "\\t" { string.append( '\t' ); } + "\\n" { string.append( '\n' ); } + "\\f" { string.append( '\f' ); } + "\\r" { string.append( '\r' ); } + "\\\"" { string.append( '\"' ); } + "\\'" { string.append( '\'' ); } + "\\\\" { string.append( '\\' ); } + \\[0-3]?{OctDigit}?{OctDigit} { char val = (char) Integer.parseInt(yytext().substring(1),8); + string.append( val ); } + + /* error cases */ + \\. { throw new RuntimeException("Illegal escape sequence \""+yytext()+"\""); } + {LineTerminator} { throw new RuntimeException("Unterminated string at end of line"); } +} + + { + {SingleCharacter}\' { yybegin(YYINITIAL); return symbol(CHARACTER_LITERAL, new Character(yytext().charAt(0))); } + + /* escape sequences */ + "\\b"\' { yybegin(YYINITIAL); return symbol(CHARACTER_LITERAL, new Character('\b'));} + "\\t"\' { yybegin(YYINITIAL); return symbol(CHARACTER_LITERAL, new Character('\t'));} + "\\n"\' { yybegin(YYINITIAL); return symbol(CHARACTER_LITERAL, new Character('\n'));} + "\\f"\' { yybegin(YYINITIAL); return symbol(CHARACTER_LITERAL, new Character('\f'));} + "\\r"\' { yybegin(YYINITIAL); return symbol(CHARACTER_LITERAL, new Character('\r'));} + "\\\""\' { yybegin(YYINITIAL); return symbol(CHARACTER_LITERAL, new Character('\"'));} + "\\'"\' { yybegin(YYINITIAL); return symbol(CHARACTER_LITERAL, new Character('\''));} + "\\\\"\' { yybegin(YYINITIAL); return symbol(CHARACTER_LITERAL, new Character('\\')); } + \\[0-3]?{OctDigit}?{OctDigit}\' { yybegin(YYINITIAL); + int val = Integer.parseInt(yytext().substring(1,yylength()-1),8); + return symbol(CHARACTER_LITERAL, new Character((char)val)); } + + /* error cases */ + \\. { throw new RuntimeException("Illegal escape sequence \""+yytext()+"\""); } + {LineTerminator} { throw new RuntimeException("Unterminated character literal at end of line"); } +} + +/* error fallback */ +.|\n { throw new RuntimeException("Illegal character \""+yytext()+ + "\" at line "+yyline+", column "+yycolumn); } +<> { return symbol(EOF); } \ No newline at end of file diff --git a/tools/lexer/jflex-1.4/examples/java/java12.cup b/tools/lexer/jflex-1.4/examples/java/java12.cup new file mode 100644 index 000000000000..d8c258775b48 --- /dev/null +++ b/tools/lexer/jflex-1.4/examples/java/java12.cup @@ -0,0 +1,885 @@ +import java_cup.runtime.*; + + +/* August 1999 - modified by Gerwin Klein + to interface with JFlex scanners, + allows empty semicolon in class decls. + + changed productions: + + class_member_declaration ::= + field_declaration + | method_declaration + [..] + | interface_declaration + | SEMICOLON + ; + + interface_member_declaration ::= + constant_declaration + | abstract_method_declaration + | class_declaration + | interface_declaration + | SEMICOLON + ; + +*/ + + +/* Java 1.2 parser for CUP. + * Copyright (C) 1998 C. Scott Ananian + * This program is released under the terms of the GPL; see the file + * COPYING for more details. There is NO WARRANTY on this code. + */ + +/* +JDK 1.2 Features added: + strictfp modifier. + explicit_constructor_invocation ::= ... + | primary DOT THIS LPAREN argument_list_opt RPAREN SEMICOLON ; + field_access ::= ... + | name DOT SUPER DOT IDENTIFIER ; + method_invocation ::= ... + | name DOT SUPER DOT IDENTIFIER LPAREN argument_list_opt RPAREN ; +*/ + +parser code {: + public void report_error(String message, Object info) { + StringBuffer m = new StringBuffer("Error "); + + if (info instanceof java_cup.runtime.Symbol) + m.append( "("+info.toString()+")" ); + + m.append(" : "+message); + + System.out.println(m); + } + + public void report_fatal_error(String message, Object info) { + report_error(message, info); + throw new RuntimeException("Fatal Syntax Error"); + } +:}; + +terminal BOOLEAN; // primitive_type +terminal BYTE, SHORT, INT, LONG, CHAR; // integral_type +terminal FLOAT, DOUBLE; // floating_point_type +terminal LBRACK, RBRACK; // array_type +terminal DOT; // qualified_name +terminal SEMICOLON, MULT, COMMA, LBRACE, RBRACE, EQ, LPAREN, RPAREN, COLON; +terminal PACKAGE; // package_declaration +terminal IMPORT; // import_declaration +terminal PUBLIC, PROTECTED, PRIVATE; // modifier +terminal STATIC; // modifier +terminal ABSTRACT, FINAL, NATIVE, SYNCHRONIZED, TRANSIENT, VOLATILE; +terminal CLASS; // class_declaration +terminal EXTENDS; // super +terminal IMPLEMENTS; // interfaces +terminal VOID; // method_header +terminal THROWS; // throws +terminal THIS, SUPER; // explicit_constructor_invocation +terminal INTERFACE; // interface_declaration +terminal IF, ELSE; // if_then_statement, if_then_else_statement +terminal SWITCH; // switch_statement +terminal CASE, DEFAULT; // switch_label +terminal DO, WHILE; // while_statement, do_statement +terminal FOR; // for_statement +terminal BREAK; // break_statement +terminal CONTINUE; // continue_statement +terminal RETURN; // return_statement +terminal THROW; // throw_statement +terminal TRY; // try_statement +terminal CATCH; // catch_clause +terminal FINALLY; // finally +terminal NEW; // class_instance_creation_expression +terminal PLUSPLUS; // postincrement_expression +terminal MINUSMINUS; // postdecrement_expression +terminal PLUS, MINUS, COMP, NOT, DIV, MOD; +terminal LSHIFT, RSHIFT, URSHIFT; // shift_expression +terminal LT, GT, LTEQ, GTEQ, INSTANCEOF; // relational_expression +terminal EQEQ, NOTEQ; // equality_expression +terminal AND; // and_expression +terminal XOR; // exclusive_or_expression +terminal OR; // inclusive_or_expression +terminal ANDAND; // conditional_and_expression +terminal OROR; // conditional_or_expression +terminal QUESTION; // conditional_expression +terminal MULTEQ, DIVEQ, MODEQ, PLUSEQ, MINUSEQ; // assignment_operator +terminal LSHIFTEQ, RSHIFTEQ, URSHIFTEQ; // assignment_operator +terminal ANDEQ, XOREQ, OREQ; // assignment_operator + +terminal java.lang.Number INTEGER_LITERAL; +terminal java.lang.Number FLOATING_POINT_LITERAL; +terminal java.lang.Boolean BOOLEAN_LITERAL; +terminal java.lang.Character CHARACTER_LITERAL; +terminal java.lang.String STRING_LITERAL; +terminal java.lang.String IDENTIFIER; // name +terminal NULL_LITERAL; + +// strictfp keyword, new in Java 1.2 +terminal STRICTFP; + +// Reserved but unused: +terminal CONST, GOTO; + +// 19.2) The Syntactic Grammar +non terminal goal; +// 19.3) Lexical Structure +non terminal literal; +// 19.4) Types, Values, and Variables +non terminal type, primitive_type, numeric_type; +non terminal integral_type, floating_point_type; +non terminal reference_type; +non terminal class_or_interface_type; +non terminal class_type, interface_type; +non terminal array_type; +// 19.5) Names +non terminal name, simple_name, qualified_name; +// 19.6) Packages +non terminal compilation_unit; +non terminal package_declaration_opt, package_declaration; +non terminal import_declarations_opt, import_declarations; +non terminal type_declarations_opt, type_declarations; +non terminal import_declaration; +non terminal single_type_import_declaration; +non terminal type_import_on_demand_declaration; +non terminal type_declaration; +// 19.7) Productions used only in the LALR(1) grammar +non terminal modifiers_opt, modifiers, modifier; +// 19.8.1) Class Declaration +non terminal class_declaration, super, super_opt; +non terminal interfaces, interfaces_opt, interface_type_list; +non terminal class_body; +non terminal class_body_declarations, class_body_declarations_opt; +non terminal class_body_declaration, class_member_declaration; +// 19.8.2) Field Declarations +non terminal field_declaration, variable_declarators, variable_declarator; +non terminal variable_declarator_id, variable_initializer; +// 19.8.3) Method Declarations +non terminal method_declaration, method_header, method_declarator; +non terminal formal_parameter_list_opt, formal_parameter_list; +non terminal formal_parameter; +non terminal throws_opt, throws; +non terminal class_type_list, method_body; +// 19.8.4) Static Initializers +non terminal static_initializer; +// 19.8.5) Constructor Declarations +non terminal constructor_declaration, constructor_declarator; +non terminal constructor_body; +non terminal explicit_constructor_invocation; +// 19.9.1) Interface Declarations +non terminal interface_declaration; +non terminal extends_interfaces_opt, extends_interfaces; +non terminal interface_body; +non terminal interface_member_declarations_opt, interface_member_declarations; +non terminal interface_member_declaration, constant_declaration; +non terminal abstract_method_declaration; +// 19.10) Arrays +non terminal array_initializer; +non terminal variable_initializers; +// 19.11) Blocks and Statements +non terminal block; +non terminal block_statements_opt, block_statements, block_statement; +non terminal local_variable_declaration_statement, local_variable_declaration; +non terminal statement, statement_no_short_if; +non terminal statement_without_trailing_substatement; +non terminal empty_statement; +non terminal labeled_statement, labeled_statement_no_short_if; +non terminal expression_statement, statement_expression; +non terminal if_then_statement; +non terminal if_then_else_statement, if_then_else_statement_no_short_if; +non terminal switch_statement, switch_block; +non terminal switch_block_statement_groups; +non terminal switch_block_statement_group; +non terminal switch_labels, switch_label; +non terminal while_statement, while_statement_no_short_if; +non terminal do_statement; +non terminal for_statement, for_statement_no_short_if; +non terminal for_init_opt, for_init; +non terminal for_update_opt, for_update; +non terminal statement_expression_list; +non terminal identifier_opt; +non terminal break_statement, continue_statement; +non terminal return_statement, throw_statement; +non terminal synchronized_statement, try_statement; +non terminal catches_opt, catches, catch_clause; +non terminal finally; +// 19.12) Expressions +non terminal primary, primary_no_new_array; +non terminal class_instance_creation_expression; +non terminal argument_list_opt, argument_list; +non terminal array_creation_expression; +non terminal dim_exprs, dim_expr, dims_opt, dims; +non terminal field_access, method_invocation, array_access; +non terminal postfix_expression; +non terminal postincrement_expression, postdecrement_expression; +non terminal unary_expression, unary_expression_not_plus_minus; +non terminal preincrement_expression, predecrement_expression; +non terminal cast_expression; +non terminal multiplicative_expression, additive_expression; +non terminal shift_expression, relational_expression, equality_expression; +non terminal and_expression, exclusive_or_expression, inclusive_or_expression; +non terminal conditional_and_expression, conditional_or_expression; +non terminal conditional_expression, assignment_expression; +non terminal assignment; +non terminal left_hand_side; +non terminal assignment_operator; +non terminal expression_opt, expression; +non terminal constant_expression; + + +start with goal; + +// 19.2) The Syntactic Grammar +goal ::= compilation_unit + ; + +// 19.3) Lexical Structure. +literal ::= INTEGER_LITERAL + | FLOATING_POINT_LITERAL + | BOOLEAN_LITERAL + | CHARACTER_LITERAL + | STRING_LITERAL + | NULL_LITERAL + ; + +// 19.4) Types, Values, and Variables +type ::= primitive_type + | reference_type + ; +primitive_type ::= + numeric_type + | BOOLEAN + ; +numeric_type::= integral_type + | floating_point_type + ; +integral_type ::= + BYTE + | SHORT + | INT + | LONG + | CHAR + ; +floating_point_type ::= + FLOAT + | DOUBLE + ; + +reference_type ::= + class_or_interface_type + | array_type + ; +class_or_interface_type ::= name; + +class_type ::= class_or_interface_type; +interface_type ::= class_or_interface_type; + +array_type ::= primitive_type dims + | name dims + ; + +// 19.5) Names +name ::= simple_name + | qualified_name + ; +simple_name ::= IDENTIFIER + ; +qualified_name ::= + name DOT IDENTIFIER + ; + +// 19.6) Packages +compilation_unit ::= + package_declaration_opt + import_declarations_opt + type_declarations_opt + ; +package_declaration_opt ::= package_declaration | ; +import_declarations_opt ::= import_declarations | ; +type_declarations_opt ::= type_declarations | ; + +import_declarations ::= + import_declaration + | import_declarations import_declaration + ; +type_declarations ::= + type_declaration + | type_declarations type_declaration + ; +package_declaration ::= + PACKAGE name SEMICOLON + ; +import_declaration ::= + single_type_import_declaration + | type_import_on_demand_declaration + ; +single_type_import_declaration ::= + IMPORT name SEMICOLON + ; +type_import_on_demand_declaration ::= + IMPORT name DOT MULT SEMICOLON + ; +type_declaration ::= + class_declaration + | interface_declaration + | SEMICOLON + ; + +// 19.7) Productions used only in the LALR(1) grammar +modifiers_opt::= + | modifiers + ; +modifiers ::= modifier + | modifiers modifier + ; +modifier ::= PUBLIC | PROTECTED | PRIVATE + | STATIC + | ABSTRACT | FINAL | NATIVE | SYNCHRONIZED | TRANSIENT | VOLATILE + | STRICTFP // note that semantic analysis must check that the + // context of the modifier allows strictfp. + ; + +// 19.8) Classes + +// 19.8.1) Class Declaration: +class_declaration ::= + modifiers_opt CLASS IDENTIFIER super_opt interfaces_opt class_body + ; +super ::= EXTENDS class_type + ; +super_opt ::= + | super + ; +interfaces ::= IMPLEMENTS interface_type_list + ; +interfaces_opt::= + | interfaces + ; +interface_type_list ::= + interface_type + | interface_type_list COMMA interface_type + ; +class_body ::= LBRACE class_body_declarations_opt RBRACE + ; +class_body_declarations_opt ::= + | class_body_declarations ; +class_body_declarations ::= + class_body_declaration + | class_body_declarations class_body_declaration + ; +class_body_declaration ::= + class_member_declaration + | static_initializer + | constructor_declaration + | block + ; +class_member_declaration ::= + field_declaration + | method_declaration + /* repeat the prod for 'class_declaration' here: */ + | modifiers_opt CLASS IDENTIFIER super_opt interfaces_opt class_body + | interface_declaration + | SEMICOLON + ; + +// 19.8.2) Field Declarations +field_declaration ::= + modifiers_opt type variable_declarators SEMICOLON + ; +variable_declarators ::= + variable_declarator + | variable_declarators COMMA variable_declarator + ; +variable_declarator ::= + variable_declarator_id + | variable_declarator_id EQ variable_initializer + ; +variable_declarator_id ::= + IDENTIFIER + | variable_declarator_id LBRACK RBRACK + ; +variable_initializer ::= + expression + | array_initializer + ; + +// 19.8.3) Method Declarations +method_declaration ::= + method_header method_body + ; +method_header ::= + modifiers_opt type method_declarator throws_opt + | modifiers_opt VOID method_declarator throws_opt + ; +method_declarator ::= + IDENTIFIER LPAREN formal_parameter_list_opt RPAREN + | method_declarator LBRACK RBRACK // deprecated + // be careful; the above production also allows 'void foo() []' + ; +formal_parameter_list_opt ::= + | formal_parameter_list + ; +formal_parameter_list ::= + formal_parameter + | formal_parameter_list COMMA formal_parameter + ; +formal_parameter ::= + type variable_declarator_id + | FINAL type variable_declarator_id + ; +throws_opt ::= + | throws + ; +throws ::= THROWS class_type_list + ; +class_type_list ::= + class_type + | class_type_list COMMA class_type + ; +method_body ::= block + | SEMICOLON + ; + +// 19.8.4) Static Initializers +static_initializer ::= + STATIC block + ; + +// 19.8.5) Constructor Declarations +constructor_declaration ::= + modifiers_opt constructor_declarator throws_opt + constructor_body + ; +constructor_declarator ::= + simple_name LPAREN formal_parameter_list_opt RPAREN + ; +constructor_body ::= + LBRACE explicit_constructor_invocation + block_statements RBRACE + | LBRACE explicit_constructor_invocation RBRACE + | LBRACE block_statements RBRACE + | LBRACE RBRACE + ; +explicit_constructor_invocation ::= + THIS LPAREN argument_list_opt RPAREN SEMICOLON + | SUPER LPAREN argument_list_opt RPAREN SEMICOLON + | primary DOT THIS LPAREN argument_list_opt RPAREN SEMICOLON + | primary DOT SUPER LPAREN argument_list_opt RPAREN SEMICOLON + ; + +// 19.9) Interfaces + +// 19.9.1) Interface Declarations +interface_declaration ::= + modifiers_opt INTERFACE IDENTIFIER extends_interfaces_opt + interface_body + ; +extends_interfaces_opt ::= + | extends_interfaces + ; +extends_interfaces ::= + EXTENDS interface_type + | extends_interfaces COMMA interface_type + ; +interface_body ::= + LBRACE interface_member_declarations_opt RBRACE + ; +interface_member_declarations_opt ::= + | interface_member_declarations + ; +interface_member_declarations ::= + interface_member_declaration + | interface_member_declarations interface_member_declaration + ; +interface_member_declaration ::= + constant_declaration + | abstract_method_declaration + | class_declaration + | interface_declaration + | SEMICOLON + ; +constant_declaration ::= + field_declaration + ; +abstract_method_declaration ::= + method_header SEMICOLON + ; + +// 19.10) Arrays +array_initializer ::= + LBRACE variable_initializers COMMA RBRACE + | LBRACE variable_initializers RBRACE + | LBRACE COMMA RBRACE + | LBRACE RBRACE + ; +variable_initializers ::= + variable_initializer + | variable_initializers COMMA variable_initializer + ; + +// 19.11) Blocks and Statements +block ::= LBRACE block_statements_opt RBRACE + ; +block_statements_opt ::= + | block_statements + ; +block_statements ::= + block_statement + | block_statements block_statement + ; +block_statement ::= + local_variable_declaration_statement + | statement + | class_declaration + | interface_declaration + ; +local_variable_declaration_statement ::= + local_variable_declaration SEMICOLON + ; +local_variable_declaration ::= + type variable_declarators + | FINAL type variable_declarators + ; +statement ::= statement_without_trailing_substatement + | labeled_statement + | if_then_statement + | if_then_else_statement + | while_statement + | for_statement + ; +statement_no_short_if ::= + statement_without_trailing_substatement + | labeled_statement_no_short_if + | if_then_else_statement_no_short_if + | while_statement_no_short_if + | for_statement_no_short_if + ; +statement_without_trailing_substatement ::= + block + | empty_statement + | expression_statement + | switch_statement + | do_statement + | break_statement + | continue_statement + | return_statement + | synchronized_statement + | throw_statement + | try_statement + ; +empty_statement ::= + SEMICOLON + ; +labeled_statement ::= + IDENTIFIER COLON statement + ; +labeled_statement_no_short_if ::= + IDENTIFIER COLON statement_no_short_if + ; +expression_statement ::= + statement_expression SEMICOLON + ; +statement_expression ::= + assignment + | preincrement_expression + | predecrement_expression + | postincrement_expression + | postdecrement_expression + | method_invocation + | class_instance_creation_expression + ; +if_then_statement ::= + IF LPAREN expression RPAREN statement + ; +if_then_else_statement ::= + IF LPAREN expression RPAREN statement_no_short_if + ELSE statement + ; +if_then_else_statement_no_short_if ::= + IF LPAREN expression RPAREN statement_no_short_if + ELSE statement_no_short_if + ; +switch_statement ::= + SWITCH LPAREN expression RPAREN switch_block + ; +switch_block ::= + LBRACE switch_block_statement_groups switch_labels RBRACE + | LBRACE switch_block_statement_groups RBRACE + | LBRACE switch_labels RBRACE + | LBRACE RBRACE + ; +switch_block_statement_groups ::= + switch_block_statement_group + | switch_block_statement_groups switch_block_statement_group + ; +switch_block_statement_group ::= + switch_labels block_statements + ; +switch_labels ::= + switch_label + | switch_labels switch_label + ; +switch_label ::= + CASE constant_expression COLON + | DEFAULT COLON + ; + +while_statement ::= + WHILE LPAREN expression RPAREN statement + ; +while_statement_no_short_if ::= + WHILE LPAREN expression RPAREN statement_no_short_if + ; +do_statement ::= + DO statement WHILE LPAREN expression RPAREN SEMICOLON + ; +for_statement ::= + FOR LPAREN for_init_opt SEMICOLON expression_opt SEMICOLON + for_update_opt RPAREN statement + ; +for_statement_no_short_if ::= + FOR LPAREN for_init_opt SEMICOLON expression_opt SEMICOLON + for_update_opt RPAREN statement_no_short_if + ; +for_init_opt ::= + | for_init + ; +for_init ::= statement_expression_list + | local_variable_declaration + ; +for_update_opt ::= + | for_update + ; +for_update ::= statement_expression_list + ; +statement_expression_list ::= + statement_expression + | statement_expression_list COMMA statement_expression + ; + +identifier_opt ::= + | IDENTIFIER + ; + +break_statement ::= + BREAK identifier_opt SEMICOLON + ; + +continue_statement ::= + CONTINUE identifier_opt SEMICOLON + ; +return_statement ::= + RETURN expression_opt SEMICOLON + ; +throw_statement ::= + THROW expression SEMICOLON + ; +synchronized_statement ::= + SYNCHRONIZED LPAREN expression RPAREN block + ; +try_statement ::= + TRY block catches + | TRY block catches_opt finally + ; +catches_opt ::= + | catches + ; +catches ::= catch_clause + | catches catch_clause + ; +catch_clause ::= + CATCH LPAREN formal_parameter RPAREN block + ; +finally ::= FINALLY block + ; + +// 19.12) Expressions +primary ::= primary_no_new_array + | array_creation_expression + ; +primary_no_new_array ::= + literal + | THIS + | LPAREN expression RPAREN + | class_instance_creation_expression + | field_access + | method_invocation + | array_access + | primitive_type DOT CLASS + | VOID DOT CLASS + | array_type DOT CLASS + | name DOT CLASS + | name DOT THIS + ; +class_instance_creation_expression ::= + NEW class_type LPAREN argument_list_opt RPAREN + | NEW class_type LPAREN argument_list_opt RPAREN class_body + | primary DOT NEW IDENTIFIER + LPAREN argument_list_opt RPAREN + | primary DOT NEW IDENTIFIER + LPAREN argument_list_opt RPAREN class_body + ; +argument_list_opt ::= + | argument_list + ; +argument_list ::= + expression + | argument_list COMMA expression + ; +array_creation_expression ::= + NEW primitive_type dim_exprs dims_opt + | NEW class_or_interface_type dim_exprs dims_opt + | NEW primitive_type dims array_initializer + | NEW class_or_interface_type dims array_initializer + ; +dim_exprs ::= dim_expr + | dim_exprs dim_expr + ; +dim_expr ::= LBRACK expression RBRACK + ; +dims_opt ::= + | dims + ; +dims ::= LBRACK RBRACK + | dims LBRACK RBRACK + ; +field_access ::= + primary DOT IDENTIFIER + | SUPER DOT IDENTIFIER + | name DOT SUPER DOT IDENTIFIER + ; +method_invocation ::= + name LPAREN argument_list_opt RPAREN + | primary DOT IDENTIFIER LPAREN argument_list_opt RPAREN + | SUPER DOT IDENTIFIER LPAREN argument_list_opt RPAREN + | name DOT SUPER DOT IDENTIFIER LPAREN argument_list_opt RPAREN + ; +array_access ::= + name LBRACK expression RBRACK + | primary_no_new_array LBRACK expression RBRACK + ; +postfix_expression ::= + primary + | name + | postincrement_expression + | postdecrement_expression + ; +postincrement_expression ::= + postfix_expression PLUSPLUS + ; +postdecrement_expression ::= + postfix_expression MINUSMINUS + ; +unary_expression ::= + preincrement_expression + | predecrement_expression + | PLUS unary_expression + | MINUS unary_expression + | unary_expression_not_plus_minus + ; +preincrement_expression ::= + PLUSPLUS unary_expression + ; +predecrement_expression ::= + MINUSMINUS unary_expression + ; +unary_expression_not_plus_minus ::= + postfix_expression + | COMP unary_expression + | NOT unary_expression + | cast_expression + ; +cast_expression ::= + LPAREN primitive_type dims_opt RPAREN unary_expression + | LPAREN expression RPAREN unary_expression_not_plus_minus + | LPAREN name dims RPAREN unary_expression_not_plus_minus + ; +multiplicative_expression ::= + unary_expression + | multiplicative_expression MULT unary_expression + | multiplicative_expression DIV unary_expression + | multiplicative_expression MOD unary_expression + ; +additive_expression ::= + multiplicative_expression + | additive_expression PLUS multiplicative_expression + | additive_expression MINUS multiplicative_expression + ; +shift_expression ::= + additive_expression + | shift_expression LSHIFT additive_expression + | shift_expression RSHIFT additive_expression + | shift_expression URSHIFT additive_expression + ; +relational_expression ::= + shift_expression + | relational_expression LT shift_expression + | relational_expression GT shift_expression + | relational_expression LTEQ shift_expression + | relational_expression GTEQ shift_expression + | relational_expression INSTANCEOF reference_type + ; +equality_expression ::= + relational_expression + | equality_expression EQEQ relational_expression + | equality_expression NOTEQ relational_expression + ; +and_expression ::= + equality_expression + | and_expression AND equality_expression + ; +exclusive_or_expression ::= + and_expression + | exclusive_or_expression XOR and_expression + ; +inclusive_or_expression ::= + exclusive_or_expression + | inclusive_or_expression OR exclusive_or_expression + ; +conditional_and_expression ::= + inclusive_or_expression + | conditional_and_expression ANDAND inclusive_or_expression + ; +conditional_or_expression ::= + conditional_and_expression + | conditional_or_expression OROR conditional_and_expression + ; +conditional_expression ::= + conditional_or_expression + | conditional_or_expression QUESTION expression + COLON conditional_expression + ; +assignment_expression ::= + conditional_expression + | assignment + ; +assignment ::= left_hand_side assignment_operator assignment_expression + ; +left_hand_side ::= + name + | field_access + | array_access + ; +assignment_operator ::= + EQ + | MULTEQ + | DIVEQ + | MODEQ + | PLUSEQ + | MINUSEQ + | LSHIFTEQ + | RSHIFTEQ + | URSHIFTEQ + | ANDEQ + | XOREQ + | OREQ + ; +expression_opt ::= + | expression + ; +expression ::= assignment_expression + ; +constant_expression ::= + expression + ; diff --git a/tools/lexer/jflex-1.4/examples/java/lexer-output.good b/tools/lexer/jflex-1.4/examples/java/lexer-output.good new file mode 100644 index 000000000000..d6d9af33c3d4 --- /dev/null +++ b/tools/lexer/jflex-1.4/examples/java/lexer-output.good @@ -0,0 +1,376 @@ +Lexing [TestLexer.java] +line:20 col:1 --import--IMPORT-- +token: line 20, column 1, sym: 23 +line:20 col:8 --java--IDENTIFIER-- +token: line 20, column 8, sym: 98, value: 'java' +line:20 col:12 --.--DOT-- +token: line 20, column 12, sym: 12 +line:20 col:13 --io--IDENTIFIER-- +token: line 20, column 13, sym: 98, value: 'io' +line:20 col:15 --.--DOT-- +token: line 20, column 15, sym: 12 +line:20 col:16 --*--MULT-- +token: line 20, column 16, sym: 14 +line:20 col:17 --;--SEMICOLON-- +token: line 20, column 17, sym: 13 +line:21 col:1 --import--IMPORT-- +token: line 21, column 1, sym: 23 +line:21 col:8 --java_cup--IDENTIFIER-- +token: line 21, column 8, sym: 98, value: 'java_cup' +line:21 col:16 --.--DOT-- +token: line 21, column 16, sym: 12 +line:21 col:17 --runtime--IDENTIFIER-- +token: line 21, column 17, sym: 98, value: 'runtime' +line:21 col:24 --.--DOT-- +token: line 21, column 24, sym: 12 +line:21 col:25 --Symbol--IDENTIFIER-- +token: line 21, column 25, sym: 98, value: 'Symbol' +line:21 col:31 --;--SEMICOLON-- +token: line 21, column 31, sym: 13 +line:29 col:1 --public--PUBLIC-- +token: line 29, column 1, sym: 24 +line:29 col:8 --class--CLASS-- +token: line 29, column 8, sym: 34 +line:29 col:14 --TestLexer--IDENTIFIER-- +token: line 29, column 14, sym: 98, value: 'TestLexer' +line:29 col:24 --{--LBRACE-- +token: line 29, column 24, sym: 16 +line:32 col:3 --int--INT-- +token: line 32, column 3, sym: 5 +line:32 col:7 --intDec--IDENTIFIER-- +token: line 32, column 7, sym: 98, value: 'intDec' +line:32 col:14 --=--EQ-- +token: line 32, column 14, sym: 18 +line:32 col:16 --37--INTEGER_LITERAL-- +token: line 32, column 16, sym: 93, value: '37' +line:32 col:18 --;--SEMICOLON-- +token: line 32, column 18, sym: 13 +line:33 col:3 --long--LONG-- +token: line 33, column 3, sym: 6 +line:33 col:8 --longDec--IDENTIFIER-- +token: line 33, column 8, sym: 98, value: 'longDec' +line:33 col:16 --=--EQ-- +token: line 33, column 16, sym: 18 +line:33 col:18 --37l--INTEGER_LITERAL-- +token: line 33, column 18, sym: 93, value: '37' +line:33 col:21 --;--SEMICOLON-- +token: line 33, column 21, sym: 13 +line:34 col:3 --int--INT-- +token: line 34, column 3, sym: 5 +line:34 col:7 --intHex--IDENTIFIER-- +token: line 34, column 7, sym: 98, value: 'intHex' +line:34 col:14 --=--EQ-- +token: line 34, column 14, sym: 18 +line:34 col:16 --0x0001--INTEGER_LITERAL-- +token: line 34, column 16, sym: 93, value: '1' +line:34 col:22 --;--SEMICOLON-- +token: line 34, column 22, sym: 13 +line:35 col:3 --long--LONG-- +token: line 35, column 3, sym: 6 +line:35 col:8 --longHex--IDENTIFIER-- +token: line 35, column 8, sym: 98, value: 'longHex' +line:35 col:16 --=--EQ-- +token: line 35, column 16, sym: 18 +line:35 col:18 --0xFFFFl--INTEGER_LITERAL-- +token: line 35, column 18, sym: 93, value: '65535' +line:35 col:25 --;--SEMICOLON-- +token: line 35, column 25, sym: 13 +line:36 col:3 --int--INT-- +token: line 36, column 3, sym: 5 +line:36 col:7 --intOct--IDENTIFIER-- +token: line 36, column 7, sym: 98, value: 'intOct' +line:36 col:14 --=--EQ-- +token: line 36, column 14, sym: 18 +line:36 col:16 --0377--INTEGER_LITERAL-- +token: line 36, column 16, sym: 93, value: '255' +line:36 col:20 --;--SEMICOLON-- +token: line 36, column 20, sym: 13 +line:37 col:3 --long--LONG-- +token: line 37, column 3, sym: 6 +line:37 col:8 --longOc--IDENTIFIER-- +token: line 37, column 8, sym: 98, value: 'longOc' +line:37 col:15 --=--EQ-- +token: line 37, column 15, sym: 18 +line:37 col:17 --007l--INTEGER_LITERAL-- +token: line 37, column 17, sym: 93, value: '7' +line:37 col:21 --;--SEMICOLON-- +token: line 37, column 21, sym: 13 +line:40 col:3 --public--PUBLIC-- +token: line 40, column 3, sym: 24 +line:40 col:10 --static--STATIC-- +token: line 40, column 10, sym: 27 +line:40 col:17 --void--VOID-- +token: line 40, column 17, sym: 37 +line:40 col:22 --main--IDENTIFIER-- +token: line 40, column 22, sym: 98, value: 'main' +line:40 col:26 --(--LPAREN-- +token: line 40, column 26, sym: 19 +line:40 col:27 --String--IDENTIFIER-- +token: line 40, column 27, sym: 98, value: 'String' +line:40 col:34 --argv--IDENTIFIER-- +token: line 40, column 34, sym: 98, value: 'argv' +line:40 col:38 --[--LBRACK-- +token: line 40, column 38, sym: 10 +line:40 col:39 --]--RBRACK-- +token: line 40, column 39, sym: 11 +line:40 col:40 --)--RPAREN-- +token: line 40, column 40, sym: 20 +line:40 col:42 --{--LBRACE-- +token: line 40, column 42, sym: 16 +line:42 col:5 --for--FOR-- +token: line 42, column 5, sym: 49 +line:42 col:9 --(--LPAREN-- +token: line 42, column 9, sym: 19 +line:42 col:10 --int--INT-- +token: line 42, column 10, sym: 5 +line:42 col:14 --i--IDENTIFIER-- +token: line 42, column 14, sym: 98, value: 'i' +line:42 col:16 --=--EQ-- +token: line 42, column 16, sym: 18 +line:42 col:18 --0--INTEGER_LITERAL-- +token: line 42, column 18, sym: 93, value: '0' +line:42 col:19 --;--SEMICOLON-- +token: line 42, column 19, sym: 13 +line:42 col:21 --i--IDENTIFIER-- +token: line 42, column 21, sym: 98, value: 'i' +line:42 col:23 --<--LT-- +token: line 42, column 23, sym: 69 +line:42 col:25 --argv--IDENTIFIER-- +token: line 42, column 25, sym: 98, value: 'argv' +line:42 col:29 --.--DOT-- +token: line 42, column 29, sym: 12 +line:42 col:30 --length--IDENTIFIER-- +token: line 42, column 30, sym: 98, value: 'length' +line:42 col:36 --;--SEMICOLON-- +token: line 42, column 36, sym: 13 +line:42 col:38 --i--IDENTIFIER-- +token: line 42, column 38, sym: 98, value: 'i' +line:42 col:39 --++--PLUSPLUS-- +token: line 42, column 39, sym: 58 +line:42 col:41 --)--RPAREN-- +token: line 42, column 41, sym: 20 +line:42 col:43 --{--LBRACE-- +token: line 42, column 43, sym: 16 +line:43 col:7 --try--TRY-- +token: line 43, column 7, sym: 54 +line:43 col:11 --{--LBRACE-- +token: line 43, column 11, sym: 16 +line:44 col:9 --System--IDENTIFIER-- +token: line 44, column 9, sym: 98, value: 'System' +line:44 col:15 --.--DOT-- +token: line 44, column 15, sym: 12 +line:44 col:16 --out--IDENTIFIER-- +token: line 44, column 16, sym: 98, value: 'out' +line:44 col:19 --.--DOT-- +token: line 44, column 19, sym: 12 +line:44 col:20 --println--IDENTIFIER-- +token: line 44, column 20, sym: 98, value: 'println' +line:44 col:27 --(--LPAREN-- +token: line 44, column 27, sym: 19 +line:44 col:37 --"--STRING_LITERAL-- +token: line 44, column 37, sym: 97, value: 'Lexing [' +line:44 col:38 --+--PLUS-- +token: line 44, column 38, sym: 60 +line:44 col:39 --argv--IDENTIFIER-- +token: line 44, column 39, sym: 98, value: 'argv' +line:44 col:43 --[--LBRACK-- +token: line 44, column 43, sym: 10 +line:44 col:44 --i--IDENTIFIER-- +token: line 44, column 44, sym: 98, value: 'i' +line:44 col:45 --]--RBRACK-- +token: line 44, column 45, sym: 11 +line:44 col:46 --+--PLUS-- +token: line 44, column 46, sym: 60 +line:44 col:49 --"--STRING_LITERAL-- +token: line 44, column 49, sym: 97, value: ']' +line:44 col:50 --)--RPAREN-- +token: line 44, column 50, sym: 20 +line:44 col:51 --;--SEMICOLON-- +token: line 44, column 51, sym: 13 +line:45 col:9 --Scanner--IDENTIFIER-- +token: line 45, column 9, sym: 98, value: 'Scanner' +line:45 col:17 --scanner--IDENTIFIER-- +token: line 45, column 17, sym: 98, value: 'scanner' +line:45 col:25 --=--EQ-- +token: line 45, column 25, sym: 18 +line:45 col:27 --new--NEW-- +token: line 45, column 27, sym: 57 +line:45 col:31 --Scanner--IDENTIFIER-- +token: line 45, column 31, sym: 98, value: 'Scanner' +line:45 col:38 --(--LPAREN-- +token: line 45, column 38, sym: 19 +line:45 col:39 --new--NEW-- +token: line 45, column 39, sym: 57 +line:45 col:43 --UnicodeEscapes--IDENTIFIER-- +token: line 45, column 43, sym: 98, value: 'UnicodeEscapes' +line:45 col:57 --(--LPAREN-- +token: line 45, column 57, sym: 19 +line:45 col:58 --new--NEW-- +token: line 45, column 58, sym: 57 +line:45 col:62 --FileReader--IDENTIFIER-- +token: line 45, column 62, sym: 98, value: 'FileReader' +line:45 col:72 --(--LPAREN-- +token: line 45, column 72, sym: 19 +line:45 col:73 --argv--IDENTIFIER-- +token: line 45, column 73, sym: 98, value: 'argv' +line:45 col:77 --[--LBRACK-- +token: line 45, column 77, sym: 10 +line:45 col:78 --i--IDENTIFIER-- +token: line 45, column 78, sym: 98, value: 'i' +line:45 col:79 --]--RBRACK-- +token: line 45, column 79, sym: 11 +line:45 col:80 --)--RPAREN-- +token: line 45, column 80, sym: 20 +line:45 col:81 --)--RPAREN-- +token: line 45, column 81, sym: 20 +line:45 col:82 --)--RPAREN-- +token: line 45, column 82, sym: 20 +line:45 col:83 --;--SEMICOLON-- +token: line 45, column 83, sym: 13 +line:47 col:9 --Symbol--IDENTIFIER-- +token: line 47, column 9, sym: 98, value: 'Symbol' +line:47 col:16 --s--IDENTIFIER-- +token: line 47, column 16, sym: 98, value: 's' +line:47 col:17 --;--SEMICOLON-- +token: line 47, column 17, sym: 13 +line:48 col:9 --do--DO-- +token: line 48, column 9, sym: 47 +line:48 col:12 --{--LBRACE-- +token: line 48, column 12, sym: 16 +line:49 col:11 --s--IDENTIFIER-- +token: line 49, column 11, sym: 98, value: 's' +line:49 col:13 --=--EQ-- +token: line 49, column 13, sym: 18 +line:49 col:15 --scanner--IDENTIFIER-- +token: line 49, column 15, sym: 98, value: 'scanner' +line:49 col:22 --.--DOT-- +token: line 49, column 22, sym: 12 +line:49 col:23 --debug_next_token--IDENTIFIER-- +token: line 49, column 23, sym: 98, value: 'debug_next_token' +line:49 col:39 --(--LPAREN-- +token: line 49, column 39, sym: 19 +line:49 col:40 --)--RPAREN-- +token: line 49, column 40, sym: 20 +line:49 col:41 --;--SEMICOLON-- +token: line 49, column 41, sym: 13 +line:50 col:11 --System--IDENTIFIER-- +token: line 50, column 11, sym: 98, value: 'System' +line:50 col:17 --.--DOT-- +token: line 50, column 17, sym: 12 +line:50 col:18 --out--IDENTIFIER-- +token: line 50, column 18, sym: 98, value: 'out' +line:50 col:21 --.--DOT-- +token: line 50, column 21, sym: 12 +line:50 col:22 --println--IDENTIFIER-- +token: line 50, column 22, sym: 98, value: 'println' +line:50 col:29 --(--LPAREN-- +token: line 50, column 29, sym: 19 +line:50 col:38 --"--STRING_LITERAL-- +token: line 50, column 38, sym: 97, value: 'token: ' +line:50 col:39 --+--PLUS-- +token: line 50, column 39, sym: 60 +line:50 col:40 --s--IDENTIFIER-- +token: line 50, column 40, sym: 98, value: 's' +line:50 col:41 --)--RPAREN-- +token: line 50, column 41, sym: 20 +line:50 col:42 --;--SEMICOLON-- +token: line 50, column 42, sym: 13 +line:51 col:9 --}--RBRACE-- +token: line 51, column 9, sym: 17 +line:51 col:11 --while--WHILE-- +token: line 51, column 11, sym: 48 +line:51 col:17 --(--LPAREN-- +token: line 51, column 17, sym: 19 +line:51 col:18 --s--IDENTIFIER-- +token: line 51, column 18, sym: 98, value: 's' +line:51 col:19 --.--DOT-- +token: line 51, column 19, sym: 12 +line:51 col:20 --sym--IDENTIFIER-- +token: line 51, column 20, sym: 98, value: 'sym' +line:51 col:24 --!=--NOTEQ-- +token: line 51, column 24, sym: 75 +line:51 col:27 --sym--IDENTIFIER-- +token: line 51, column 27, sym: 98, value: 'sym' +line:51 col:30 --.--DOT-- +token: line 51, column 30, sym: 12 +line:51 col:31 --EOF--IDENTIFIER-- +token: line 51, column 31, sym: 98, value: 'EOF' +line:51 col:34 --)--RPAREN-- +token: line 51, column 34, sym: 20 +line:51 col:35 --;--SEMICOLON-- +token: line 51, column 35, sym: 13 +line:53 col:9 --System--IDENTIFIER-- +token: line 53, column 9, sym: 98, value: 'System' +line:53 col:15 --.--DOT-- +token: line 53, column 15, sym: 12 +line:53 col:16 --out--IDENTIFIER-- +token: line 53, column 16, sym: 98, value: 'out' +line:53 col:19 --.--DOT-- +token: line 53, column 19, sym: 12 +line:53 col:20 --println--IDENTIFIER-- +token: line 53, column 20, sym: 98, value: 'println' +line:53 col:27 --(--LPAREN-- +token: line 53, column 27, sym: 19 +line:53 col:39 --"--STRING_LITERAL-- +token: line 53, column 39, sym: 97, value: 'No errors.' +line:53 col:40 --)--RPAREN-- +token: line 53, column 40, sym: 20 +line:53 col:41 --;--SEMICOLON-- +token: line 53, column 41, sym: 13 +line:54 col:7 --}--RBRACE-- +token: line 54, column 7, sym: 17 +line:55 col:7 --catch--CATCH-- +token: line 55, column 7, sym: 55 +line:55 col:13 --(--LPAREN-- +token: line 55, column 13, sym: 19 +line:55 col:14 --Exception--IDENTIFIER-- +token: line 55, column 14, sym: 98, value: 'Exception' +line:55 col:24 --e--IDENTIFIER-- +token: line 55, column 24, sym: 98, value: 'e' +line:55 col:25 --)--RPAREN-- +token: line 55, column 25, sym: 20 +line:55 col:27 --{--LBRACE-- +token: line 55, column 27, sym: 16 +line:56 col:9 --e--IDENTIFIER-- +token: line 56, column 9, sym: 98, value: 'e' +line:56 col:10 --.--DOT-- +token: line 56, column 10, sym: 12 +line:56 col:11 --printStackTrace--IDENTIFIER-- +token: line 56, column 11, sym: 98, value: 'printStackTrace' +line:56 col:26 --(--LPAREN-- +token: line 56, column 26, sym: 19 +line:56 col:27 --System--IDENTIFIER-- +token: line 56, column 27, sym: 98, value: 'System' +line:56 col:33 --.--DOT-- +token: line 56, column 33, sym: 12 +line:56 col:34 --out--IDENTIFIER-- +token: line 56, column 34, sym: 98, value: 'out' +line:56 col:37 --)--RPAREN-- +token: line 56, column 37, sym: 20 +line:56 col:38 --;--SEMICOLON-- +token: line 56, column 38, sym: 13 +line:57 col:9 --System--IDENTIFIER-- +token: line 57, column 9, sym: 98, value: 'System' +line:57 col:15 --.--DOT-- +token: line 57, column 15, sym: 12 +line:57 col:16 --exit--IDENTIFIER-- +token: line 57, column 16, sym: 98, value: 'exit' +line:57 col:20 --(--LPAREN-- +token: line 57, column 20, sym: 19 +line:57 col:21 --1--INTEGER_LITERAL-- +token: line 57, column 21, sym: 93, value: '1' +line:57 col:22 --)--RPAREN-- +token: line 57, column 22, sym: 20 +line:57 col:23 --;--SEMICOLON-- +token: line 57, column 23, sym: 13 +line:58 col:7 --}--RBRACE-- +token: line 58, column 7, sym: 17 +line:59 col:5 --}--RBRACE-- +token: line 59, column 5, sym: 17 +line:60 col:3 --}--RBRACE-- +token: line 60, column 3, sym: 17 +line:61 col:1 --}--RBRACE-- +token: line 61, column 1, sym: 17 +line:62 col:1 ----EOF-- +token: line 62, column 1, sym: 0 +No errors. diff --git a/tools/lexer/jflex-1.4/examples/java/unicode.flex b/tools/lexer/jflex-1.4/examples/java/unicode.flex new file mode 100644 index 000000000000..31af811a72e7 --- /dev/null +++ b/tools/lexer/jflex-1.4/examples/java/unicode.flex @@ -0,0 +1,149 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Copyright (C) 1998-2004 Gerwin Klein * + * All rights reserved. * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License. See the file * + * COPYRIGHT for more information. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License along * + * with this program; if not, write to the Free Software Foundation, Inc., * + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + + +/* §3.3 of the Java Language Specification : + +UnicodeInputCharacter: + + UnicodeEscape + + RawInputCharacter + + UnicodeEscape: + + \ UnicodeMarker HexDigit HexDigit HexDigit HexDigit + + UnicodeMarker: + + u + + UnicodeMarker u + + RawInputCharacter: + + any Unicode character + + HexDigit: one of + + 0 1 2 3 4 5 6 7 8 9 a b c d e f A B C D E F + +only an even number of '\' is eligible to start a Unicode escape sequence + +*/ + +import java.io.*; + +%% + +%public +%final +%class UnicodeEscapes +%extends FilterReader + +%int +%function read + +%switch +%16bit + +UnicodeEscape = {UnicodeMarker} {HexDigit} {4} +UnicodeMarker = "u"+ +HexDigit = [0-9a-fA-F] + +%state DIGITS + +%init{ + super(in); +%init} + +%{ + private boolean even; + + private int value() { + int r = 0; + + for (int k = zzMarkedPos-4; k < zzMarkedPos; k++) { + int c = zzBuffer[k]; + + if (c >= 'a') + c-= 'a'-10; + else if (c >= 'A') + c-= 'A'-10; + else + c-= '0'; + + r <<= 4; + r += c; + } + + return r; + } + + public int read(char cbuf[], int off, int len) throws IOException { + if ( !ready() ) return -1; + + len+= off; + + for (int i=off; i { + \\ { even = false; return '\\'; } + \\ / \\ { even = !even; return '\\'; } + \\ / "u" { + if (even) { + even = false; + return '\\'; + } + else + yybegin(DIGITS); + } + .|\n { return zzBuffer[zzStartRead]; } + + <> { return -1; } +} + + { + {UnicodeEscape} { yybegin(YYINITIAL); return value(); } + .|\n { throw new Error("incorrect Unicode escape"); } + + <> { throw new Error("EOF in Unicode escape"); } +} diff --git a/tools/lexer/jflex-1.4/examples/simple/Makefile b/tools/lexer/jflex-1.4/examples/simple/Makefile new file mode 100644 index 000000000000..d46a13e02feb --- /dev/null +++ b/tools/lexer/jflex-1.4/examples/simple/Makefile @@ -0,0 +1,23 @@ +JAVA=java +JAVAC=javac +JFLEX=jflex +CUP=$(JAVA) java_cup.Main < + +all: test + +test: output.txt + @(diff output.txt output.good && echo "Test OK!") || echo "Test failed!" + +output.txt: Yylex.class test.txt + $(JAVA) Yylex test.txt > output.txt + +Yylex.class: Yylex.java Yytoken.java Utility.java + +%.class: %.java + $(JAVAC) $^ + +Yylex.java: simple.flex + $(JFLEX) simple.flex + +clean: + rm -f Yylex.java output.txt *.class *~ diff --git a/tools/lexer/jflex-1.4/examples/simple/README b/tools/lexer/jflex-1.4/examples/simple/README new file mode 100644 index 000000000000..b050b3e242b1 --- /dev/null +++ b/tools/lexer/jflex-1.4/examples/simple/README @@ -0,0 +1,29 @@ +This directory contains a scanner for a toy programming language. + +It is the example from the JLex website with some small modifications, +to make it a bit more readable. + +It does nothing really useful, because there is no parser for the +toy programming language. It's just a demonstatration how a small simple +scanner looks like. + +files: + +YYtoken.java: + the tokens returned by the scanner + +Utility.java: + small class collecting some utility functions + +simple.flex: + the example specification + +test.txt: + sample input + +output.good: + output matching the sample input from test.txt + +Makefile: (for Unix only) + make to generate scanner and run test + make clean to remove generated files diff --git a/tools/lexer/jflex-1.4/examples/simple/Utility.java b/tools/lexer/jflex-1.4/examples/simple/Utility.java new file mode 100644 index 000000000000..889b030531d0 --- /dev/null +++ b/tools/lexer/jflex-1.4/examples/simple/Utility.java @@ -0,0 +1,19 @@ +class Utility { + + private static final String errorMsg[] = { + "Error: Unmatched end-of-comment punctuation.", + "Error: Unmatched start-of-comment punctuation.", + "Error: Unclosed string.", + "Error: Illegal character." + }; + + public static final int E_ENDCOMMENT = 0; + public static final int E_STARTCOMMENT = 1; + public static final int E_UNCLOSEDSTR = 2; + public static final int E_UNMATCHED = 3; + + public static void error(int code) { + System.out.println(errorMsg[code]); + } +} + diff --git a/tools/lexer/jflex-1.4/examples/simple/Yytoken.java b/tools/lexer/jflex-1.4/examples/simple/Yytoken.java new file mode 100644 index 000000000000..ed60fb8f10c5 --- /dev/null +++ b/tools/lexer/jflex-1.4/examples/simple/Yytoken.java @@ -0,0 +1,24 @@ +class Yytoken { + public int m_index; + public String m_text; + public int m_line; + public int m_charBegin; + public int m_charEnd; + + Yytoken (int index, String text, int line, int charBegin, int charEnd) { + m_index = index; + m_text = text; + m_line = line; + m_charBegin = charBegin; + m_charEnd = charEnd; + } + + public String toString() { + return "Text : "+m_text+ + "\nindex : "+m_index+ + "\nline : "+m_line+ + "\ncBeg. : "+m_charBegin+ + "\ncEnd. : "+m_charEnd; + } +} + diff --git a/tools/lexer/jflex-1.4/examples/simple/output.good b/tools/lexer/jflex-1.4/examples/simple/output.good new file mode 100644 index 000000000000..04599b114d0e --- /dev/null +++ b/tools/lexer/jflex-1.4/examples/simple/output.good @@ -0,0 +1,660 @@ +line: 1 match: --class-- +action [70] { return (new Yytoken(43,yytext(),yyline,yychar,yychar+yylength())); } +Text : class +index : 43 +line : 0 +cBeg. : 0 +cEnd. : 5 +line: 1 match: -- -- +action [76] { } +line: 1 match: --Utility-- +action [70] { return (new Yytoken(43,yytext(),yyline,yychar,yychar+yylength())); } +Text : Utility +index : 43 +line : 0 +cBeg. : 6 +cEnd. : 13 +line: 1 match: -- -- +action [76] { } +line: 1 match: --{-- +action [36] { return (new Yytoken(7,yytext(),yyline,yychar,yychar+1)); } +Text : { +index : 7 +line : 0 +cBeg. : 14 +cEnd. : 15 +line: 1 match: -- + + -- +action [76] { } +line: 3 match: --private-- +action [70] { return (new Yytoken(43,yytext(),yyline,yychar,yychar+yylength())); } +Text : private +index : 43 +line : 2 +cBeg. : 21 +cEnd. : 28 +line: 3 match: -- -- +action [76] { } +line: 3 match: --static-- +action [70] { return (new Yytoken(43,yytext(),yyline,yychar,yychar+yylength())); } +Text : static +index : 43 +line : 2 +cBeg. : 29 +cEnd. : 35 +line: 3 match: -- -- +action [76] { } +line: 3 match: --final-- +action [70] { return (new Yytoken(43,yytext(),yyline,yychar,yychar+yylength())); } +Text : final +index : 43 +line : 2 +cBeg. : 36 +cEnd. : 41 +line: 3 match: -- -- +action [76] { } +line: 3 match: --String-- +action [70] { return (new Yytoken(43,yytext(),yyline,yychar,yychar+yylength())); } +Text : String +index : 43 +line : 2 +cBeg. : 42 +cEnd. : 48 +line: 3 match: -- -- +action [76] { } +line: 3 match: --errorMsg-- +action [70] { return (new Yytoken(43,yytext(),yyline,yychar,yychar+yylength())); } +Text : errorMsg +index : 43 +line : 2 +cBeg. : 49 +cEnd. : 57 +line: 3 match: --[-- +action [34] { return (new Yytoken(5,yytext(),yyline,yychar,yychar+1)); } +Text : [ +index : 5 +line : 2 +cBeg. : 57 +cEnd. : 58 +line: 3 match: --]-- +action [35] { return (new Yytoken(6,yytext(),yyline,yychar,yychar+1)); } +Text : ] +index : 6 +line : 2 +cBeg. : 58 +cEnd. : 59 +line: 3 match: -- -- +action [76] { } +line: 3 match: --=-- +action [43] { return (new Yytoken(14,yytext(),yyline,yychar,yychar+1)); } +Text : = +index : 14 +line : 2 +cBeg. : 60 +cEnd. : 61 +line: 3 match: -- -- +action [76] { } +line: 3 match: --{-- +action [36] { return (new Yytoken(7,yytext(),yyline,yychar,yychar+1)); } +Text : { +index : 7 +line : 2 +cBeg. : 62 +cEnd. : 63 +line: 3 match: -- + -- +action [76] { } +line: 4 match: --"Error: Unmatched end-of-comment punctuation."-- +action [57] { String str = yytext().substring(1,yylength()-1); + return (new Yytoken(40,str,yyline,yychar,yychar+yylength())); } +Text : Error: Unmatched end-of-comment punctuation. +index : 40 +line : 3 +cBeg. : 68 +cEnd. : 114 +line: 4 match: --,-- +action [29] { return (new Yytoken(0,yytext(),yyline,yychar,yychar+1)); } +Text : , +index : 0 +line : 3 +cBeg. : 114 +cEnd. : 115 +line: 4 match: -- + -- +action [76] { } +line: 5 match: --"Error: Unmatched start-of-comment punctuation."-- +action [57] { String str = yytext().substring(1,yylength()-1); + return (new Yytoken(40,str,yyline,yychar,yychar+yylength())); } +Text : Error: Unmatched start-of-comment punctuation. +index : 40 +line : 4 +cBeg. : 120 +cEnd. : 168 +line: 5 match: --,-- +action [29] { return (new Yytoken(0,yytext(),yyline,yychar,yychar+1)); } +Text : , +index : 0 +line : 4 +cBeg. : 168 +cEnd. : 169 +line: 5 match: -- + -- +action [76] { } +line: 6 match: --"Error: Unclosed string."-- +action [57] { String str = yytext().substring(1,yylength()-1); + return (new Yytoken(40,str,yyline,yychar,yychar+yylength())); } +Text : Error: Unclosed string. +index : 40 +line : 5 +cBeg. : 174 +cEnd. : 199 +line: 6 match: --,-- +action [29] { return (new Yytoken(0,yytext(),yyline,yychar,yychar+1)); } +Text : , +index : 0 +line : 5 +cBeg. : 199 +cEnd. : 200 +line: 6 match: -- + -- +action [76] { } +line: 7 match: --"Error: Illegal character."-- +action [57] { String str = yytext().substring(1,yylength()-1); + return (new Yytoken(40,str,yyline,yychar,yychar+yylength())); } +Text : Error: Illegal character. +index : 40 +line : 6 +cBeg. : 205 +cEnd. : 232 +line: 7 match: -- + -- +action [76] { } +line: 8 match: --}-- +action [37] { return (new Yytoken(8,yytext(),yyline,yychar,yychar+1)); } +Text : } +index : 8 +line : 7 +cBeg. : 237 +cEnd. : 238 +line: 8 match: --;-- +action [31] { return (new Yytoken(2,yytext(),yyline,yychar,yychar+1)); } +Text : ; +index : 2 +line : 7 +cBeg. : 238 +cEnd. : 239 +line: 8 match: -- + + -- +action [76] { } +line: 10 match: --public-- +action [70] { return (new Yytoken(43,yytext(),yyline,yychar,yychar+yylength())); } +Text : public +index : 43 +line : 9 +cBeg. : 245 +cEnd. : 251 +line: 10 match: -- -- +action [76] { } +line: 10 match: --static-- +action [70] { return (new Yytoken(43,yytext(),yyline,yychar,yychar+yylength())); } +Text : static +index : 43 +line : 9 +cBeg. : 252 +cEnd. : 258 +line: 10 match: -- -- +action [76] { } +line: 10 match: --final-- +action [70] { return (new Yytoken(43,yytext(),yyline,yychar,yychar+yylength())); } +Text : final +index : 43 +line : 9 +cBeg. : 259 +cEnd. : 264 +line: 10 match: -- -- +action [76] { } +line: 10 match: --int-- +action [70] { return (new Yytoken(43,yytext(),yyline,yychar,yychar+yylength())); } +Text : int +index : 43 +line : 9 +cBeg. : 265 +cEnd. : 268 +line: 10 match: -- -- +action [76] { } +line: 10 match: --E_ENDCOMMENT-- +action [70] { return (new Yytoken(43,yytext(),yyline,yychar,yychar+yylength())); } +Text : E_ENDCOMMENT +index : 43 +line : 9 +cBeg. : 269 +cEnd. : 281 +line: 10 match: -- -- +action [76] { } +line: 10 match: --=-- +action [43] { return (new Yytoken(14,yytext(),yyline,yychar,yychar+1)); } +Text : = +index : 14 +line : 9 +cBeg. : 282 +cEnd. : 283 +line: 10 match: -- -- +action [76] { } +line: 10 match: --0-- +action [68] { return (new Yytoken(42,yytext(),yyline,yychar,yychar+yylength())); } +Text : 0 +index : 42 +line : 9 +cBeg. : 284 +cEnd. : 285 +line: 10 match: --;-- +action [31] { return (new Yytoken(2,yytext(),yyline,yychar,yychar+1)); } +Text : ; +index : 2 +line : 9 +cBeg. : 285 +cEnd. : 286 +line: 10 match: -- + -- +action [76] { } +line: 11 match: --public-- +action [70] { return (new Yytoken(43,yytext(),yyline,yychar,yychar+yylength())); } +Text : public +index : 43 +line : 10 +cBeg. : 290 +cEnd. : 296 +line: 11 match: -- -- +action [76] { } +line: 11 match: --static-- +action [70] { return (new Yytoken(43,yytext(),yyline,yychar,yychar+yylength())); } +Text : static +index : 43 +line : 10 +cBeg. : 297 +cEnd. : 303 +line: 11 match: -- -- +action [76] { } +line: 11 match: --final-- +action [70] { return (new Yytoken(43,yytext(),yyline,yychar,yychar+yylength())); } +Text : final +index : 43 +line : 10 +cBeg. : 304 +cEnd. : 309 +line: 11 match: -- -- +action [76] { } +line: 11 match: --int-- +action [70] { return (new Yytoken(43,yytext(),yyline,yychar,yychar+yylength())); } +Text : int +index : 43 +line : 10 +cBeg. : 310 +cEnd. : 313 +line: 11 match: -- -- +action [76] { } +line: 11 match: --E_STARTCOMMENT-- +action [70] { return (new Yytoken(43,yytext(),yyline,yychar,yychar+yylength())); } +Text : E_STARTCOMMENT +index : 43 +line : 10 +cBeg. : 314 +cEnd. : 328 +line: 11 match: -- -- +action [76] { } +line: 11 match: --=-- +action [43] { return (new Yytoken(14,yytext(),yyline,yychar,yychar+1)); } +Text : = +index : 14 +line : 10 +cBeg. : 329 +cEnd. : 330 +line: 11 match: -- -- +action [76] { } +line: 11 match: --1-- +action [68] { return (new Yytoken(42,yytext(),yyline,yychar,yychar+yylength())); } +Text : 1 +index : 42 +line : 10 +cBeg. : 331 +cEnd. : 332 +line: 11 match: --;-- +action [31] { return (new Yytoken(2,yytext(),yyline,yychar,yychar+1)); } +Text : ; +index : 2 +line : 10 +cBeg. : 332 +cEnd. : 333 +line: 11 match: -- + -- +action [76] { } +line: 12 match: --public-- +action [70] { return (new Yytoken(43,yytext(),yyline,yychar,yychar+yylength())); } +Text : public +index : 43 +line : 11 +cBeg. : 337 +cEnd. : 343 +line: 12 match: -- -- +action [76] { } +line: 12 match: --static-- +action [70] { return (new Yytoken(43,yytext(),yyline,yychar,yychar+yylength())); } +Text : static +index : 43 +line : 11 +cBeg. : 344 +cEnd. : 350 +line: 12 match: -- -- +action [76] { } +line: 12 match: --final-- +action [70] { return (new Yytoken(43,yytext(),yyline,yychar,yychar+yylength())); } +Text : final +index : 43 +line : 11 +cBeg. : 351 +cEnd. : 356 +line: 12 match: -- -- +action [76] { } +line: 12 match: --int-- +action [70] { return (new Yytoken(43,yytext(),yyline,yychar,yychar+yylength())); } +Text : int +index : 43 +line : 11 +cBeg. : 357 +cEnd. : 360 +line: 12 match: -- -- +action [76] { } +line: 12 match: --E_UNCLOSEDSTR-- +action [70] { return (new Yytoken(43,yytext(),yyline,yychar,yychar+yylength())); } +Text : E_UNCLOSEDSTR +index : 43 +line : 11 +cBeg. : 361 +cEnd. : 374 +line: 12 match: -- -- +action [76] { } +line: 12 match: --=-- +action [43] { return (new Yytoken(14,yytext(),yyline,yychar,yychar+1)); } +Text : = +index : 14 +line : 11 +cBeg. : 375 +cEnd. : 376 +line: 12 match: -- -- +action [76] { } +line: 12 match: --2-- +action [68] { return (new Yytoken(42,yytext(),yyline,yychar,yychar+yylength())); } +Text : 2 +index : 42 +line : 11 +cBeg. : 377 +cEnd. : 378 +line: 12 match: --;-- +action [31] { return (new Yytoken(2,yytext(),yyline,yychar,yychar+1)); } +Text : ; +index : 2 +line : 11 +cBeg. : 378 +cEnd. : 379 +line: 12 match: -- + -- +action [76] { } +line: 13 match: --public-- +action [70] { return (new Yytoken(43,yytext(),yyline,yychar,yychar+yylength())); } +Text : public +index : 43 +line : 12 +cBeg. : 383 +cEnd. : 389 +line: 13 match: -- -- +action [76] { } +line: 13 match: --static-- +action [70] { return (new Yytoken(43,yytext(),yyline,yychar,yychar+yylength())); } +Text : static +index : 43 +line : 12 +cBeg. : 390 +cEnd. : 396 +line: 13 match: -- -- +action [76] { } +line: 13 match: --final-- +action [70] { return (new Yytoken(43,yytext(),yyline,yychar,yychar+yylength())); } +Text : final +index : 43 +line : 12 +cBeg. : 397 +cEnd. : 402 +line: 13 match: -- -- +action [76] { } +line: 13 match: --int-- +action [70] { return (new Yytoken(43,yytext(),yyline,yychar,yychar+yylength())); } +Text : int +index : 43 +line : 12 +cBeg. : 403 +cEnd. : 406 +line: 13 match: -- -- +action [76] { } +line: 13 match: --E_UNMATCHED-- +action [70] { return (new Yytoken(43,yytext(),yyline,yychar,yychar+yylength())); } +Text : E_UNMATCHED +index : 43 +line : 12 +cBeg. : 407 +cEnd. : 418 +line: 13 match: -- -- +action [76] { } +line: 13 match: --=-- +action [43] { return (new Yytoken(14,yytext(),yyline,yychar,yychar+1)); } +Text : = +index : 14 +line : 12 +cBeg. : 419 +cEnd. : 420 +line: 13 match: -- -- +action [76] { } +line: 13 match: --3-- +action [68] { return (new Yytoken(42,yytext(),yyline,yychar,yychar+yylength())); } +Text : 3 +index : 42 +line : 12 +cBeg. : 421 +cEnd. : 422 +line: 13 match: --;-- +action [31] { return (new Yytoken(2,yytext(),yyline,yychar,yychar+1)); } +Text : ; +index : 2 +line : 12 +cBeg. : 422 +cEnd. : 423 +line: 13 match: -- + + -- +action [76] { } +line: 15 match: --public-- +action [70] { return (new Yytoken(43,yytext(),yyline,yychar,yychar+yylength())); } +Text : public +index : 43 +line : 14 +cBeg. : 428 +cEnd. : 434 +line: 15 match: -- -- +action [76] { } +line: 15 match: --static-- +action [70] { return (new Yytoken(43,yytext(),yyline,yychar,yychar+yylength())); } +Text : static +index : 43 +line : 14 +cBeg. : 435 +cEnd. : 441 +line: 15 match: -- -- +action [76] { } +line: 15 match: --void-- +action [70] { return (new Yytoken(43,yytext(),yyline,yychar,yychar+yylength())); } +Text : void +index : 43 +line : 14 +cBeg. : 442 +cEnd. : 446 +line: 15 match: -- -- +action [76] { } +line: 15 match: --error-- +action [70] { return (new Yytoken(43,yytext(),yyline,yychar,yychar+yylength())); } +Text : error +index : 43 +line : 14 +cBeg. : 447 +cEnd. : 452 +line: 15 match: --(-- +action [32] { return (new Yytoken(3,yytext(),yyline,yychar,yychar+1)); } +Text : ( +index : 3 +line : 14 +cBeg. : 452 +cEnd. : 453 +line: 15 match: --int-- +action [70] { return (new Yytoken(43,yytext(),yyline,yychar,yychar+yylength())); } +Text : int +index : 43 +line : 14 +cBeg. : 453 +cEnd. : 456 +line: 15 match: -- -- +action [76] { } +line: 15 match: --code-- +action [70] { return (new Yytoken(43,yytext(),yyline,yychar,yychar+yylength())); } +Text : code +index : 43 +line : 14 +cBeg. : 457 +cEnd. : 461 +line: 15 match: --)-- +action [33] { return (new Yytoken(4,yytext(),yyline,yychar,yychar+1)); } +Text : ) +index : 4 +line : 14 +cBeg. : 461 +cEnd. : 462 +line: 15 match: -- -- +action [76] { } +line: 15 match: --{-- +action [36] { return (new Yytoken(7,yytext(),yyline,yychar,yychar+1)); } +Text : { +index : 7 +line : 14 +cBeg. : 463 +cEnd. : 464 +line: 15 match: -- + -- +action [76] { } +line: 16 match: --System-- +action [70] { return (new Yytoken(43,yytext(),yyline,yychar,yychar+yylength())); } +Text : System +index : 43 +line : 15 +cBeg. : 468 +cEnd. : 474 +line: 16 match: --.-- +action [38] { return (new Yytoken(9,yytext(),yyline,yychar,yychar+1)); } +Text : . +index : 9 +line : 15 +cBeg. : 474 +cEnd. : 475 +line: 16 match: --out-- +action [70] { return (new Yytoken(43,yytext(),yyline,yychar,yychar+yylength())); } +Text : out +index : 43 +line : 15 +cBeg. : 475 +cEnd. : 478 +line: 16 match: --.-- +action [38] { return (new Yytoken(9,yytext(),yyline,yychar,yychar+1)); } +Text : . +index : 9 +line : 15 +cBeg. : 478 +cEnd. : 479 +line: 16 match: --println-- +action [70] { return (new Yytoken(43,yytext(),yyline,yychar,yychar+yylength())); } +Text : println +index : 43 +line : 15 +cBeg. : 479 +cEnd. : 486 +line: 16 match: --(-- +action [32] { return (new Yytoken(3,yytext(),yyline,yychar,yychar+1)); } +Text : ( +index : 3 +line : 15 +cBeg. : 486 +cEnd. : 487 +line: 16 match: --errorMsg-- +action [70] { return (new Yytoken(43,yytext(),yyline,yychar,yychar+yylength())); } +Text : errorMsg +index : 43 +line : 15 +cBeg. : 487 +cEnd. : 495 +line: 16 match: --[-- +action [34] { return (new Yytoken(5,yytext(),yyline,yychar,yychar+1)); } +Text : [ +index : 5 +line : 15 +cBeg. : 495 +cEnd. : 496 +line: 16 match: --code-- +action [70] { return (new Yytoken(43,yytext(),yyline,yychar,yychar+yylength())); } +Text : code +index : 43 +line : 15 +cBeg. : 496 +cEnd. : 500 +line: 16 match: --]-- +action [35] { return (new Yytoken(6,yytext(),yyline,yychar,yychar+1)); } +Text : ] +index : 6 +line : 15 +cBeg. : 500 +cEnd. : 501 +line: 16 match: --)-- +action [33] { return (new Yytoken(4,yytext(),yyline,yychar,yychar+1)); } +Text : ) +index : 4 +line : 15 +cBeg. : 501 +cEnd. : 502 +line: 16 match: --;-- +action [31] { return (new Yytoken(2,yytext(),yyline,yychar,yychar+1)); } +Text : ; +index : 2 +line : 15 +cBeg. : 502 +cEnd. : 503 +line: 16 match: -- + -- +action [76] { } +line: 17 match: --}-- +action [37] { return (new Yytoken(8,yytext(),yyline,yychar,yychar+1)); } +Text : } +index : 8 +line : 16 +cBeg. : 506 +cEnd. : 507 +line: 17 match: -- +-- +action [76] { } +line: 18 match: --}-- +action [37] { return (new Yytoken(8,yytext(),yyline,yychar,yychar+1)); } +Text : } +index : 8 +line : 17 +cBeg. : 508 +cEnd. : 509 +line: 18 match: -- + +-- +action [76] { } +null diff --git a/tools/lexer/jflex-1.4/examples/simple/simple.flex b/tools/lexer/jflex-1.4/examples/simple/simple.flex new file mode 100644 index 000000000000..790133952271 --- /dev/null +++ b/tools/lexer/jflex-1.4/examples/simple/simple.flex @@ -0,0 +1,86 @@ +/* this is the scanner example from the JLex website + (with small modifications to make it more readable) */ + +%% + +%{ + private int comment_count = 0; +%} + +%line +%char +%state COMMENT +%full + +%debug + +ALPHA=[A-Za-z] +DIGIT=[0-9] +NONNEWLINE_WHITE_SPACE_CHAR=[\ \t\b\012] +NEWLINE=\r|\n|\r\n +WHITE_SPACE_CHAR=[\n\r\ \t\b\012] +STRING_TEXT=(\\\"|[^\n\r\"]|\\{WHITE_SPACE_CHAR}+\\)* +COMMENT_TEXT=([^*/\n]|[^*\n]"/"[^*\n]|[^/\n]"*"[^/\n]|"*"[^/\n]|"/"[^*\n])* +Ident = {ALPHA}({ALPHA}|{DIGIT}|_)* + +%% + + { + "," { return (new Yytoken(0,yytext(),yyline,yychar,yychar+1)); } + ":" { return (new Yytoken(1,yytext(),yyline,yychar,yychar+1)); } + ";" { return (new Yytoken(2,yytext(),yyline,yychar,yychar+1)); } + "(" { return (new Yytoken(3,yytext(),yyline,yychar,yychar+1)); } + ")" { return (new Yytoken(4,yytext(),yyline,yychar,yychar+1)); } + "[" { return (new Yytoken(5,yytext(),yyline,yychar,yychar+1)); } + "]" { return (new Yytoken(6,yytext(),yyline,yychar,yychar+1)); } + "{" { return (new Yytoken(7,yytext(),yyline,yychar,yychar+1)); } + "}" { return (new Yytoken(8,yytext(),yyline,yychar,yychar+1)); } + "." { return (new Yytoken(9,yytext(),yyline,yychar,yychar+1)); } + "+" { return (new Yytoken(10,yytext(),yyline,yychar,yychar+1)); } + "-" { return (new Yytoken(11,yytext(),yyline,yychar,yychar+1)); } + "*" { return (new Yytoken(12,yytext(),yyline,yychar,yychar+1)); } + "/" { return (new Yytoken(13,yytext(),yyline,yychar,yychar+1)); } + "=" { return (new Yytoken(14,yytext(),yyline,yychar,yychar+1)); } + "<>" { return (new Yytoken(15,yytext(),yyline,yychar,yychar+2)); } + "<" { return (new Yytoken(16,yytext(),yyline,yychar,yychar+1)); } + "<=" { return (new Yytoken(17,yytext(),yyline,yychar,yychar+2)); } + ">" { return (new Yytoken(18,yytext(),yyline,yychar,yychar+1)); } + ">=" { return (new Yytoken(19,yytext(),yyline,yychar,yychar+2)); } + "&" { return (new Yytoken(20,yytext(),yyline,yychar,yychar+1)); } + "|" { return (new Yytoken(21,yytext(),yyline,yychar,yychar+1)); } + ":=" { return (new Yytoken(22,yytext(),yyline,yychar,yychar+2)); } + + {NONNEWLINE_WHITE_SPACE_CHAR}+ { } + + "/*" { yybegin(COMMENT); comment_count++; } + + \"{STRING_TEXT}\" { + String str = yytext().substring(1,yylength()-1); + return (new Yytoken(40,str,yyline,yychar,yychar+yylength())); + } + + \"{STRING_TEXT} { + String str = yytext().substring(1,yytext().length()); + Utility.error(Utility.E_UNCLOSEDSTR); + return (new Yytoken(41,str,yyline,yychar,yychar + str.length())); + } + + {DIGIT}+ { return (new Yytoken(42,yytext(),yyline,yychar,yychar+yylength())); } + + {Ident} { return (new Yytoken(43,yytext(),yyline,yychar,yychar+yylength())); } +} + + { + "/*" { comment_count++; } + "*/" { if (--comment_count == 0) yybegin(YYINITIAL); } + {COMMENT_TEXT} { } +} + + +{NEWLINE} { } + +. { + System.out.println("Illegal character: <" + yytext() + ">"); + Utility.error(Utility.E_UNMATCHED); +} + diff --git a/tools/lexer/jflex-1.4/examples/simple/test.txt b/tools/lexer/jflex-1.4/examples/simple/test.txt new file mode 100644 index 000000000000..889b030531d0 --- /dev/null +++ b/tools/lexer/jflex-1.4/examples/simple/test.txt @@ -0,0 +1,19 @@ +class Utility { + + private static final String errorMsg[] = { + "Error: Unmatched end-of-comment punctuation.", + "Error: Unmatched start-of-comment punctuation.", + "Error: Unclosed string.", + "Error: Illegal character." + }; + + public static final int E_ENDCOMMENT = 0; + public static final int E_STARTCOMMENT = 1; + public static final int E_UNCLOSEDSTR = 2; + public static final int E_UNMATCHED = 3; + + public static void error(int code) { + System.out.println(errorMsg[code]); + } +} + diff --git a/tools/lexer/jflex-1.4/examples/standalone/Makefile b/tools/lexer/jflex-1.4/examples/standalone/Makefile new file mode 100644 index 000000000000..c9a9ab6951f7 --- /dev/null +++ b/tools/lexer/jflex-1.4/examples/standalone/Makefile @@ -0,0 +1,13 @@ +all: run + +run: Subst.class + java Subst sample.inp + +Subst.class: Subst.java + javac Subst.java + +Subst.java: standalone.flex + jflex standalone.flex + +clean: + rm -rf *.class *~ *.java diff --git a/tools/lexer/jflex-1.4/examples/standalone/README b/tools/lexer/jflex-1.4/examples/standalone/README new file mode 100644 index 000000000000..1be85a86998f --- /dev/null +++ b/tools/lexer/jflex-1.4/examples/standalone/README @@ -0,0 +1,20 @@ +This is a small example of a standalone text substitution scanner. + +It reads a name after the keyword name and replaces all occurences +of "hello" by "hello !". + +sample.inp + contains a sample input for the scanner + +standalone.flex + the lexical specification for the scanner + +build.xml + ant build file + +to run the example use ant or type: + +jflex standalone.flex +javac Subst.java +java Subst sample.inp + diff --git a/tools/lexer/jflex-1.4/examples/standalone/build.xml b/tools/lexer/jflex-1.4/examples/standalone/build.xml new file mode 100644 index 000000000000..3d8bae7ca2a5 --- /dev/null +++ b/tools/lexer/jflex-1.4/examples/standalone/build.xml @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tools/lexer/jflex-1.4/examples/standalone/sample.inp b/tools/lexer/jflex-1.4/examples/standalone/sample.inp new file mode 100644 index 000000000000..550ac7373812 --- /dev/null +++ b/tools/lexer/jflex-1.4/examples/standalone/sample.inp @@ -0,0 +1,8 @@ +name someone + +Hello +This is a sample input file for the +standalone example scanner. + +Have a nice day! + diff --git a/tools/lexer/jflex-1.4/examples/standalone/standalone.flex b/tools/lexer/jflex-1.4/examples/standalone/standalone.flex new file mode 100644 index 000000000000..0c7e12f94d8f --- /dev/null +++ b/tools/lexer/jflex-1.4/examples/standalone/standalone.flex @@ -0,0 +1,44 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Copyright (C) 1998-2004 Gerwin Klein * + * All rights reserved. * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License. See the file * + * COPYRIGHT for more information. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License along * + * with this program; if not, write to the Free Software Foundation, Inc., * + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + + +/** + This is a small example of a standalone text substitution scanner + It reads a name after the keyword name and substitutes all occurences + of "hello" with "hello !". There is a sample input file + "sample.inp" provided in this directory +*/ + +%% + +%public +%class Subst +%standalone + +%unicode + +%{ + String name; +%} + +%% + +"name " [a-zA-Z]+ { name = yytext().substring(5); } +[Hh] "ello" { System.out.print(yytext()+" "+name+"!"); } + diff --git a/tools/lexer/jflex-1.4/lib/JFlex.jar b/tools/lexer/jflex-1.4/lib/JFlex.jar new file mode 100644 index 0000000000000000000000000000000000000000..ac5ec6e9f4a9868451a1a3caccddfcb006f1b3b2 GIT binary patch literal 169541 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 +;;; $Revision: 2.1 $, $Date: 2003/06/08 11:01:12 $ + +(require 'derived) +(require 'font-lock) + +(define-derived-mode jflex-mode java-mode "JFlex" + "Major mode for editing JFlex files" + + ;; set the indentation + (setq c-basic-offset 2) + + (c-set-offset 'knr-argdecl-intro 0) + (c-set-offset 'topmost-intro-cont 0) + + ;; remove auto and hungry anything + (c-toggle-auto-hungry-state -1) + (c-toggle-auto-state -1) + (c-toggle-hungry-state -1) + + (use-local-map jflex-mode-map) + + ;; get rid of that damn electric-brace + (define-key jflex-mode-map "{" 'self-insert-command) + (define-key jflex-mode-map "}" 'self-insert-command) + + (define-key jflex-mode-map [tab] 'jflex-indent-command) + + ) + +(defalias 'jflex-indent-command 'c-indent-command) + +(defconst jflex-font-lock-keywords + (append + '( + ("^%%" . font-lock-reference-face) + "^%{" + "^%init{" + "^%initthrow{" + "^%eof{" + "^%eofthrow{" + "^%yylexthrow{" + "^%eofval{" + "^%}" + "^%init}" + "^%initthrow}" + "^%eof}" + "^%eofthrow}" + "^%yylexthrow}" + "^%eofval}" + "^%standalone" + "^%scanerror" + "^%switch" + "^%states" ; fixme: state identifiers + "^%state" + "^%s" + "^%xstates" + "^%xstate" + "^%x" + "^%char" + "^%line" + "^%column" + "^%byaccj" + "^%cupsym" + "^%cupdebug" + "^%cup" + "^%eofclose" + "^%class" + "^%function" + "^%type" + "^%integer" + "^%intwrap" + "^%int" + "^%yyeof" + "^%notunix" + "^%7bit" + "^%full" + "^%8bit" + "^%unicode" + "^%16bit" + "^%caseless" + "^%ignorecase" + "^%implements" + "^%extends" + "^%public" + "^%apiprivate" + "^%final" + "^%abstract" + "^%debug" + "^%table" + "^%pack" + "^%include" + "^%buffer" + "^%initthrow" + "^%eofthrow" + "^%yylexthrow" + "^%throws" + ("%[%{}0-9a-zA-Z]+" . font-lock-warning-face) ; errors + ("{[ \t]*[a-zA-Z][0-9a-zA-Z_]+[ \t]*}" . font-lock-variable-name-face) ; macro uses + "<>" ; special <> symbol + ("<[ \t]*[a-zA-Z][0-9a-zA-Z_]+[ \t]*\\(,[ \t]*[a-zA-Z][0-9a-zA-Z_]+[ \t]*\\)*>" . font-lock-type-face) ; lex state list + ) + java-font-lock-keywords-2) + "JFlex keywords for font-lock mode") + +(put 'jflex-mode 'font-lock-defaults + '(jflex-font-lock-keywords + nil nil ((?_ . "w")) beginning-of-defun)) + +(provide 'jflex-mode) diff --git a/tools/lexer/jflex-1.4/lib/jflex.vim b/tools/lexer/jflex-1.4/lib/jflex.vim new file mode 100644 index 000000000000..a6b5c3c40d41 --- /dev/null +++ b/tools/lexer/jflex-1.4/lib/jflex.vim @@ -0,0 +1,149 @@ +" Vim syntax file +" Language: JFlex +" Maintainer: Gerwin Klein +" Last Change: $Revision: 2.1 $, $Date: 2003/06/08 11:01:12 $ + +" Thanks to Michael Brailsford for help and suggestions + +" Quit when a syntax file was already loaded {{{ +if exists("b:current_syntax") + finish +endif +"}}} + +" Include java syntax {{{ +if version >= 600 + runtime! syntax/java.vim + unlet b:current_syntax +else + so $VIMRUNTIME/syntax/java.vim +endif +"}}} + +syn cluster jflexOptions contains=jflexOption,jflexCodeInclude,jflexComment,jflexMacroIdent,jflexMacroRegExp,jflexOptionError +syn cluster jflexRules contains=jflexRule,jflexComment,jflexActionCode,jflexRuleStates,jflexRegExp + +" java code section +syn region jflexStart start="/\*\|//\|import\|package\|class"me=s end="^%%"me=e-2 contains=@javaTop nextgroup=jflexOptionReg + +" %% +" options +syn region jflexOptionReg matchgroup=jflexSectionSep start="^%%" end="^%%"me=e-2 contains=@jflexOptions nextgroup=jflexRulesReg + +syn match jflexOptionError "%\i*" contained + +syn match jflexOption "^\(%s\|%x\)" contained +syn match jflexOption "^%state" contained +syn match jflexOption "^%states" contained +syn match jflexOption "^%xstate" contained +syn match jflexOption "^%xstates" contained +syn match jflexOption "^%char" contained +syn match jflexOption "^%line" contained +syn match jflexOption "^%column" contained +syn match jflexOption "^%byaccj" contained +syn match jflexOption "^%cup" contained +syn match jflexOption "^%cupsym" contained +syn match jflexOption "^%cupdebug" contained +syn match jflexOption "^%eofclose" contained +syn match jflexOption "^%class" contained +syn match jflexOption "^%function" contained +syn match jflexOption "^%type" contained +syn match jflexOption "^%integer" contained +syn match jflexOption "^%int" contained +syn match jflexOption "^%intwrap" contained +syn match jflexOption "^%yyeof" contained +syn match jflexOption "^%notunix" contained +syn match jflexOption "^%7bit" contained +syn match jflexOption "^%8bit" contained +syn match jflexOption "^%full" contained +syn match jflexOption "^%16bit" contained +syn match jflexOption "^%unicode" contained +syn match jflexOption "^%caseless" contained +syn match jflexOption "^%ignorecase" contained +syn match jflexOption "^%implements" contained +syn match jflexOption "^%extends" contained +syn match jflexOption "^%public" contained +syn match jflexOption "^%apiprivate" contained +syn match jflexOption "^%final" contained +syn match jflexOption "^%abstract" contained +syn match jflexOption "^%debug" contained +syn match jflexOption "^%standalone" contained +syn match jflexOption "^%switch" contained +syn match jflexOption "^%table" contained +syn match jflexOption "^%pack" contained +syn match jflexOption "^%include" contained +syn match jflexOption "^%buffer" contained +syn match jflexOption "^%initthrow" contained +syn match jflexOption "^%eofthrow" contained +syn match jflexOption "^%yylexthrow" contained +syn match jflexOption "^%throws" contained +syn match jflexOption "^%scannerror" contained + +syn match jflexMacroIdent "\I\i*\s*="me=e-1 contained nextgroup=jflexMacroRegExp + +syn region jflexMacroRegExp matchgroup=jflexOperator start="=" end="^\(%\|\I\|\i\|/\)"me=e-1 contains=NONE contained + +syn region jflexCodeInclude matchgroup=jflexCodeIncludeMark start="^%{" end="^%}" contains=@javaTop contained +syn region jflexCodeInclude matchgroup=jflexCodeIncludeMark start="^%init{" end="^%init}" contains=@javaTop contained +syn region jflexCodeInclude matchgroup=jflexCodeIncludeMark start="^%initthrow{" end="^%initthrow}" contains=@javaTop contained +syn region jflexCodeInclude matchgroup=jflexCodeIncludeMark start="^%eof{" end="^%eof}" contains=@javaTop contained +syn region jflexCodeInclude matchgroup=jflexCodeIncludeMark start="^%eofthrow{" end="^%eofthrow}" contains=@javaTop contained +syn region jflexCodeInclude matchgroup=jflexCodeIncludeMark start="^%yylexthrow{" end="^%yylexthrow}" contains=@javaTop contained +syn region jflexCodeInclude matchgroup=jflexCodeIncludeMark start="^%eofval{" end="^%eofval}" contains=@javaTop contained + +" rules (end pattern shouldn't occur, if it does anyway we just stay in jflexRulesReg) +syn region jflexRulesReg matchgroup=jflexSectionSep start="^%%" end="^%%"me=e-2 contains=@jflexRules + +" at first everything but strings is a regexp +syn match jflexRegExp "\([^\" \t]\|\\\"\)\+" contained + +" take out comments +syn match jflexComment "//.*" contained +syn region jflexComment start="/\*" end="\*/" contained contains=jflexComment + +" lex states +syn match jflexRuleStates "<\s*\I\i*\(\s*,\s*\I\i*\)*\s*>" contained skipnl skipwhite nextgroup=jflexStateGroup + +" action code (only after states braces and macro use) +syn region jflexActionCode matchgroup=Delimiter start="{" end="}" contained contains=@javaTop,jflexJavaBraces + +" macro use +syn match jflexRegExp "{\s*\I\i*\s*}" contained + +" state braces (only active after ) +syn region jflexStateGroup matchgroup=jflexRuleStates start="{$" start="{\s" end="}" contained contains=@jflexRules + +" string +syn region jflexRegExp matchgroup=String start=+"+ skip=+\\\\\|\\"+ end=+"+ contained + +" not to be confused with a state +syn match jflexRegExp "<>" contained + +" escape sequence +syn match jflexRegExp "\\." contained + + +" keep braces in actions balanced +syn region jflexJavaBraces start="{" end="}" contained contains=@javaTop,jflexJavaBraces + + +" syncing +syn sync clear +syn sync minlines=10 +syn sync match jflexSync grouphere jflexOptionReg "^%[a-z]" +syn sync match jflexSync grouphere jflexRulesReg "^<" + + +" highlighting +hi link jflexOption Special +hi link jflexMacroIdent Ident +hi link jflexMacroRegExp Macro +hi link jflexOptionError Error +hi link jflexComment Comment +hi link jflexOperator Operator +hi link jflexRuleStates Special +hi link jflexRegExp Function +hi jflexSectionSep guifg=yellow ctermfg=yellow guibg=blue ctermbg=blue gui=bold cterm=bold +hi link jflexCodeIncludeMark jflexSectionSep + +let b:current_syntax="jflex" diff --git a/tools/lexer/jflex-1.4/src/JFlex/Action.java b/tools/lexer/jflex-1.4/src/JFlex/Action.java new file mode 100644 index 000000000000..de2e9a251096 --- /dev/null +++ b/tools/lexer/jflex-1.4/src/JFlex/Action.java @@ -0,0 +1,149 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * JFlex 1.4.1 * + * Copyright (C) 1998-2004 Gerwin Klein * + * All rights reserved. * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License. See the file * + * COPYRIGHT for more information. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License along * + * with this program; if not, write to the Free Software Foundation, Inc., * + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +package JFlex; + + +/** + * Encapsulates an action in the specification. + * + * It stores the Java code as String together with a priority (line number in the specification). + * + * @author Gerwin Klein + * @version JFlex 1.4.1, $Revision: 2.6 $, $Date: 2004/11/06 23:03:30 $ + */ +final public class Action { + + + /** + * The Java code this Action represents + */ + String content; + + /** + * The priority (i.e. line number in the specification) of this Action. + */ + int priority; + + /** + * True iff the action belongs to an lookahead expresstion + * (a/b or r$) + */ + private boolean isLookAction; + + + /** + * Creates a new Action object with specified content and line number. + * + * @param content java code + * @param priority line number + */ + public Action(String content, int priority) { + this.content = content.trim(); + this.priority = priority; + } + + + /** + * Compares the priority value of this Action with the specified action. + * + * @param other the other Action to compare this Action with. + * + * @return this Action if it has higher priority - the specified one, if not. + */ + public Action getHigherPriority(Action other) { + if (other == null) return this; + + // the smaller the number the higher the priority + if (other.priority > this.priority) + return this; + else + return other; + } + + + /** + * Returns the String representation of this object. + * + * @return string representation of the action + */ + public String toString() { + return "Action (priority "+priority+", lookahead "+isLookAction+") :"+Out.NL+content; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + } + + + /** + * Returns true iff the parameter is an + * Action with the same content as this one. + * + * @param a the object to compare this Action with + * @return true if the action strings are equal + */ + public boolean isEquiv(Action a) { + return this == a || this.content.equals(a.content); + } + + + /** + * Calculate hash value. + * + * @return a hash value for this Action + */ + public int hashCode() { + return content.hashCode(); + } + + + /** + * Test for equality to another object. + * + * This action equals another object if the other + * object is an equivalent action. + * + * @param o the other object. + * + * @see Action#isEquiv(Action) + */ + public boolean equals(Object o) { + if (o instanceof Action) + return isEquiv((Action) o); + else + return false; + } + + /** + * Return look ahead flag. + * + * @return true if this actions belongs to a lookahead rule + */ + public boolean isLookAction() { + return isLookAction; + } + + /** + * Sets the look ahead flag for this action + * + * @param b set to true if this action belongs to a look ahead rule + */ + public void setLookAction(boolean b) { + isLookAction = b; + } + +} diff --git a/tools/lexer/jflex-1.4/src/JFlex/CharClassException.java b/tools/lexer/jflex-1.4/src/JFlex/CharClassException.java new file mode 100644 index 000000000000..d720cd0bf97a --- /dev/null +++ b/tools/lexer/jflex-1.4/src/JFlex/CharClassException.java @@ -0,0 +1,49 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * JFlex 1.4.1 * + * Copyright (C) 1998-2004 Gerwin Klein * + * All rights reserved. * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License. See the file * + * COPYRIGHT for more information. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License along * + * with this program; if not, write to the Free Software Foundation, Inc., * + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +package JFlex; + + + +/** + * This Exception is used in class CharClasses. + * + * @author Gerwin Klein + * @version JFlex 1.4.1, $Revision: 2.2 $, $Date: 2004/11/06 23:03:30 $ + */ +public class CharClassException extends RuntimeException { + + /** + * Creates a new CharClassException without message + */ + public CharClassException() { + } + + + /** + * Creates a new CharClassException with the specified message + * + * @param message the error description presented to the user. + */ + public CharClassException(String message) { + super(message); + } + +} diff --git a/tools/lexer/jflex-1.4/src/JFlex/CharClassInterval.java b/tools/lexer/jflex-1.4/src/JFlex/CharClassInterval.java new file mode 100644 index 000000000000..caa6ad4d6eef --- /dev/null +++ b/tools/lexer/jflex-1.4/src/JFlex/CharClassInterval.java @@ -0,0 +1,73 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * JFlex 1.4.1 * + * Copyright (C) 1998-2004 Gerwin Klein * + * All rights reserved. * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License. See the file * + * COPYRIGHT for more information. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License along * + * with this program; if not, write to the Free Software Foundation, Inc., * + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +package JFlex; + +/** + * Stores an interval of characters together with the character class + * + * A character belongs to an interval, if its Unicode value is greater than or equal + * to the Unicode value of start and smaller than or euqal to the Unicode + * value of end. + * + * All characters of the interval must belong to the same character class. + * + * @author Gerwin Klein + * @version JFlex 1.4.1, $Revision: 2.3 $, $Date: 2004/11/06 23:03:30 $ + */ +public class CharClassInterval { + + /** + * The first character of the interval + */ + int start; + + /** + * The last character of the interval + */ + int end; + + /** + * The code of the class all characters of this interval belong to. + */ + int charClass; + + + /** + * Creates a new CharClassInterval from start to end + * that belongs to character class charClass. + * + * @param start The first character of the interval + * @param end The last character of the interval + * @param charClass The code of the class all characters of this interval belong to. + */ + public CharClassInterval(int start, int end, int charClass) { + this.start = start; + this.end = end; + this.charClass = charClass; + } + + /** + * returns string representation of this class interval + */ + public String toString() { + return "["+start+"-"+end+"="+charClass+"]"; + } +} diff --git a/tools/lexer/jflex-1.4/src/JFlex/CharClasses.java b/tools/lexer/jflex-1.4/src/JFlex/CharClasses.java new file mode 100644 index 000000000000..01fc24eaa023 --- /dev/null +++ b/tools/lexer/jflex-1.4/src/JFlex/CharClasses.java @@ -0,0 +1,388 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * JFlex 1.4.1 * + * Copyright (C) 1998-2004 Gerwin Klein * + * All rights reserved. * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License. See the file * + * COPYRIGHT for more information. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License along * + * with this program; if not, write to the Free Software Foundation, Inc., * + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +package JFlex; + +import java.util.Vector; + + +/** + * + * @author Gerwin Klein + * @version JFlex 1.4.1, $Revision: 2.6 $, $Date: 2004/11/06 23:03:32 $ + */ +public class CharClasses { + + /** debug flag (for char classes only) */ + private static final boolean DEBUG = false; + + /** the largest character that can be used in char classes */ + public static final char maxChar = '\uFFFF'; + + /** the char classes */ + private Vector /* of IntCharSet */ classes; + + /** the largest character actually used in a specification */ + private char maxCharUsed; + + /** + * Constructs a new CharClass object that provides space for + * classes of characters from 0 to maxCharCode. + * + * Initially all characters are in class 0. + * + * @param maxCharCode the last character code to be + * considered. (127 for 7bit Lexers, + * 255 for 8bit Lexers and 0xFFFF + * for Unicode Lexers). + */ + public CharClasses(int maxCharCode) { + if (maxCharCode < 0 || maxCharCode > 0xFFFF) + throw new IllegalArgumentException(); + + maxCharUsed = (char) maxCharCode; + + classes = new Vector(); + classes.addElement(new IntCharSet(new Interval((char) 0, maxChar))); + } + + + /** + * Returns the greatest Unicode value of the current input character set. + */ + public char getMaxCharCode() { + return maxCharUsed; + } + + + /** + * Sets the larges Unicode value of the current input character set. + * + * @param charCode the largest character code, used for the scanner + * (i.e. %7bit, %8bit, %16bit etc.) + */ + public void setMaxCharCode(int charCode) { + if (charCode < 0 || charCode > 0xFFFF) + throw new IllegalArgumentException(); + + maxCharUsed = (char) charCode; + } + + + /** + * Returns the current number of character classes. + */ + public int getNumClasses() { + return classes.size(); + } + + + + /** + * Updates the current partition, so that the specified set of characters + * gets a new character class. + * + * Characters that are elements of set are not in the same + * equivalence class with characters that are not elements of set. + * + * @param set the set of characters to distinguish from the rest + * @param caseless if true upper/lower/title case are considered equivalent + */ + public void makeClass(IntCharSet set, boolean caseless) { + if (caseless) set = set.getCaseless(); + + if ( DEBUG ) { + Out.dump("makeClass("+set+")"); + dump(); + } + + int oldSize = classes.size(); + for (int i = 0; i < oldSize; i++) { + IntCharSet x = (IntCharSet) classes.elementAt(i); + + if (x.equals(set)) return; + + IntCharSet and = x.and(set); + + if ( and.containsElements() ) { + if ( x.equals(and) ) { + set.sub(and); + continue; + } + else if ( set.equals(and) ) { + x.sub(and); + classes.addElement(and); + if (DEBUG) { + Out.dump("makeClass(..) finished"); + dump(); + } + return; + } + + set.sub(and); + x.sub(and); + classes.addElement(and); + } + } + + if (DEBUG) { + Out.dump("makeClass(..) finished"); + dump(); + } + } + + + /** + * Returns the code of the character class the specified character belongs to. + */ + public int getClassCode(char letter) { + int i = -1; + while (true) { + IntCharSet x = (IntCharSet) classes.elementAt(++i); + if ( x.contains(letter) ) return i; + } + } + + /** + * Dump charclasses to the dump output stream + */ + public void dump() { + Out.dump(toString()); + } + + + /** + * Return a string representation of one char class + * + * @param theClass the index of the class to + */ + public String toString(int theClass) { + return classes.elementAt(theClass).toString(); + } + + + /** + * Return a string representation of the char classes + * stored in this class. + * + * Enumerates the classes by index. + */ + public String toString() { + StringBuffer result = new StringBuffer("CharClasses:"); + + result.append(Out.NL); + + for (int i = 0; i < classes.size(); i++) + result.append("class "+i+":"+Out.NL+classes.elementAt(i)+Out.NL); + + return result.toString(); + } + + + /** + * Creates a new character class for the single character singleChar. + * + * @param caseless if true upper/lower/title case are considered equivalent + */ + public void makeClass(char singleChar, boolean caseless) { + makeClass(new IntCharSet(singleChar), caseless); + } + + + /** + * Creates a new character class for each character of the specified String. + * + * @param caseless if true upper/lower/title case are considered equivalent + */ + public void makeClass(String str, boolean caseless) { + for (int i = 0; i < str.length(); i++) makeClass(str.charAt(i), caseless); + } + + + /** + * Updates the current partition, so that the specified set of characters + * gets a new character class. + * + * Characters that are elements of the set v are not in the same + * equivalence class with characters that are not elements of the set v. + * + * @param v a Vector of Interval objects. + * This Vector represents a set of characters. The set of characters is + * the union of all intervalls in the Vector. + * + * @param caseless if true upper/lower/title case are considered equivalent + */ + public void makeClass(Vector /* Interval */ v, boolean caseless) { + makeClass(new IntCharSet(v), caseless); + } + + + /** + * Updates the current partition, so that the set of all characters not contained in the specified + * set of characters gets a new character class. + * + * Characters that are elements of the set v are not in the same + * equivalence class with characters that are not elements of the set v. + * + * This method is equivalent to makeClass(v) + * + * @param v a Vector of Interval objects. + * This Vector represents a set of characters. The set of characters is + * the union of all intervalls in the Vector. + * + * @param caseless if true upper/lower/title case are considered equivalent + */ + public void makeClassNot(Vector v, boolean caseless) { + makeClass(new IntCharSet(v), caseless); + } + + + /** + * Returns an array that contains the character class codes of all characters + * in the specified set of input characters. + */ + private int [] getClassCodes(IntCharSet set, boolean negate) { + + if (DEBUG) { + Out.dump("getting class codes for "+set); + if (negate) + Out.dump("[negated]"); + } + + int size = classes.size(); + + // [fixme: optimize] + int temp [] = new int [size]; + int length = 0; + + for (int i = 0; i < size; i++) { + IntCharSet x = (IntCharSet) classes.elementAt(i); + if ( negate ) { + if ( !set.and(x).containsElements() ) { + temp[length++] = i; + if (DEBUG) Out.dump("code "+i); + } + } + else { + if ( set.and(x).containsElements() ) { + temp[length++] = i; + if (DEBUG) Out.dump("code "+i); + } + } + } + + int result [] = new int [length]; + System.arraycopy(temp, 0, result, 0, length); + + return result; + } + + + /** + * Returns an array that contains the character class codes of all characters + * in the specified set of input characters. + * + * @param intervallVec a Vector of Intervalls, the set of characters to get + * the class codes for + * + * @return an array with the class codes for intervallVec + */ + public int [] getClassCodes(Vector /* Interval */ intervallVec) { + return getClassCodes(new IntCharSet(intervallVec), false); + } + + + /** + * Returns an array that contains the character class codes of all characters + * that are not in the specified set of input characters. + * + * @param intervallVec a Vector of Intervalls, the complement of the + * set of characters to get the class codes for + * + * @return an array with the class codes for the complement of intervallVec + */ + public int [] getNotClassCodes(Vector /* Interval */ intervallVec) { + return getClassCodes(new IntCharSet(intervallVec), true); + } + + + /** + * Check consistency of the stored classes [debug]. + * + * all classes must be disjoint, checks if all characters + * have a class assigned. + */ + public void check() { + for (int i = 0; i < classes.size(); i++) + for (int j = i+1; j < classes.size(); j++) { + IntCharSet x = (IntCharSet) classes.elementAt(i); + IntCharSet y = (IntCharSet) classes.elementAt(j); + if ( x.and(y).containsElements() ) { + System.out.println("Error: non disjoint char classes "+i+" and "+j); + System.out.println("class "+i+": "+x); + System.out.println("class "+j+": "+y); + } + } + + // check if each character has a classcode + // (= if getClassCode terminates) + for (char c = 0; c < maxChar; c++) { + getClassCode(c); + if (c % 100 == 0) System.out.print("."); + } + + getClassCode(maxChar); + } + + + /** + * Returns an array of all CharClassIntervalls in this + * char class collection. + * + * The array is ordered by char code, i.e. + * result[i+1].start = result[i].end+1 + * + * Each CharClassInterval contains the number of the + * char class it belongs to. + */ + public CharClassInterval [] getIntervalls() { + int i, c; + int size = classes.size(); + int numIntervalls = 0; + + for (i = 0; i < size; i++) + numIntervalls+= ((IntCharSet) classes.elementAt(i)).numIntervalls(); + + CharClassInterval [] result = new CharClassInterval[numIntervalls]; + + i = 0; + c = 0; + while (i < numIntervalls) { + int code = getClassCode((char) c); + IntCharSet set = (IntCharSet) classes.elementAt(code); + Interval iv = set.getNext(); + + result[i++] = new CharClassInterval(iv.start, iv.end, code); + c = iv.end+1; + } + + return result; + } +} diff --git a/tools/lexer/jflex-1.4/src/JFlex/CharSet.java b/tools/lexer/jflex-1.4/src/JFlex/CharSet.java new file mode 100644 index 000000000000..322228087cbd --- /dev/null +++ b/tools/lexer/jflex-1.4/src/JFlex/CharSet.java @@ -0,0 +1,112 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * JFlex 1.4.1 * + * Copyright (C) 1998-2004 Gerwin Klein * + * All rights reserved. * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License. See the file * + * COPYRIGHT for more information. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License along * + * with this program; if not, write to the Free Software Foundation, Inc., * + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +package JFlex; + + +/** + * + * @author Gerwin Klein + * @version JFlex 1.4.1, $Revision: 2.3 $, $Date: 2004/11/06 23:03:31 $ + */ +public final class CharSet { + + final static int BITS = 6; // the number of bits to shift (2^6 = 64) + final static int MOD = (1<> BITS)+1]; + add(character); + } + + + public void add(int character) { + resize(character); + + if ( (bits[character >> BITS] & (1L << (character & MOD))) == 0) numElements++; + + bits[character >> BITS] |= (1L << (character & MOD)); + } + + + private int nbits2size (int nbits) { + return ((nbits >> BITS) + 1); + } + + + private void resize(int nbits) { + int needed = nbits2size(nbits); + + if (needed < bits.length) return; + + long newbits[] = new long[Math.max(bits.length*2,needed)]; + System.arraycopy(bits, 0, newbits, 0, bits.length); + + bits = newbits; + } + + + public boolean isElement(int character) { + int index = character >> BITS; + if (index >= bits.length) return false; + return (bits[index] & (1L << (character & MOD))) != 0; + } + + + public CharSetEnumerator characters() { + return new CharSetEnumerator(this); + } + + + public boolean containsElements() { + return numElements > 0; + } + + public int size() { + return numElements; + } + + public String toString() { + CharSetEnumerator set = characters(); + + StringBuffer result = new StringBuffer("{"); + + if ( set.hasMoreElements() ) result.append(""+set.nextElement()); + + while ( set.hasMoreElements() ) { + int i = set.nextElement(); + result.append( ", "+(int)i); + } + + result.append("}"); + + return result.toString(); + } +} diff --git a/tools/lexer/jflex-1.4/src/JFlex/CharSetEnumerator.java b/tools/lexer/jflex-1.4/src/JFlex/CharSetEnumerator.java new file mode 100644 index 000000000000..4f5f1c2ba4e9 --- /dev/null +++ b/tools/lexer/jflex-1.4/src/JFlex/CharSetEnumerator.java @@ -0,0 +1,88 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * JFlex 1.4.1 * + * Copyright (C) 1998-2004 Gerwin Klein * + * All rights reserved. * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License. See the file * + * COPYRIGHT for more information. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License along * + * with this program; if not, write to the Free Software Foundation, Inc., * + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +package JFlex; + + +/** + * Enumerator for the elements of a CharSet. + * + * Does not implement java.util.Enumeration, but supports the same protocol. + * + * @author Gerwin Klein + * @version JFlex 1.4.1, $Revision: 2.3 $, $Date: 2004/11/06 23:03:30 $ + */ +final public class CharSetEnumerator { + + private int index; + private int offset; + private long mask = 1; + + private CharSet set; + + public CharSetEnumerator(CharSet characters) { + set = characters; + + while (index < set.bits.length && set.bits[index] == 0) + index++; + + if (index >= set.bits.length) return; + + while (offset <= CharSet.MOD && ((set.bits[index] & mask) == 0)) { + mask<<= 1; + offset++; + } + } + + private void advance() { + do { + offset++; + mask<<= 1; + } while (offset <= CharSet.MOD && ((set.bits[index] & mask) == 0)); + + if (offset > CharSet.MOD) { + do + index++; + while (index < set.bits.length && set.bits[index] == 0); + + if (index >= set.bits.length) return; + + offset = 0; + mask = 1; + + while (offset <= CharSet.MOD && ((set.bits[index] & mask) == 0)) { + mask<<= 1; + offset++; + } + } + } + + public boolean hasMoreElements() { + return index < set.bits.length; + } + + public int nextElement() { + int x = (index << CharSet.BITS) + offset; + advance(); + return x; + } + +} + diff --git a/tools/lexer/jflex-1.4/src/JFlex/CountEmitter.java b/tools/lexer/jflex-1.4/src/JFlex/CountEmitter.java new file mode 100644 index 000000000000..177adf4f7771 --- /dev/null +++ b/tools/lexer/jflex-1.4/src/JFlex/CountEmitter.java @@ -0,0 +1,115 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * jflex 1.4 * + * Copyright (C) 1998-2004 Gerwin Klein * + * All rights reserved. * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License. See the file * + * COPYRIGHT for more information. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License along * + * with this program; if not, write to the Free Software Foundation, Inc., * + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +package JFlex; + +/** + * An emitter for an array encoded as count/value pairs in a string. + * + * @author Gerwin Klein + * @version $Revision: 1.6 $, $Date: 2004/04/12 10:07:48 $ + */ +public class CountEmitter extends PackEmitter { + /** number of entries in expanded array */ + private int numEntries; + + /** translate all values by this amount */ + private int translate = 0; + + + /** + * Create a count/value emitter for a specific field. + * + * @param name name of the generated array + */ + protected CountEmitter(String name) { + super(name); + } + + /** + * Emits count/value unpacking code for the generated array. + * + * @see JFlex.PackEmitter#emitUnPack() + */ + public void emitUnpack() { + // close last string chunk: + println("\";"); + + nl(); + println(" private static int [] zzUnpack"+name+"() {"); + println(" int [] result = new int["+numEntries+"];"); + println(" int offset = 0;"); + + for (int i = 0; i < chunks; i++) { + println(" offset = zzUnpack"+name+"("+constName()+"_PACKED_"+i+", offset, result);"); + } + + println(" return result;"); + println(" }"); + nl(); + + println(" private static int zzUnpack"+name+"(String packed, int offset, int [] result) {"); + println(" int i = 0; /* index in packed string */"); + println(" int j = offset; /* index in unpacked array */"); + println(" int l = packed.length();"); + println(" while (i < l) {"); + println(" int count = packed.charAt(i++);"); + println(" int value = packed.charAt(i++);"); + if (translate == 1) { + println(" value--;"); + } + else if (translate != 0) { + println(" value-= "+translate); + } + println(" do result[j++] = value; while (--count > 0);"); + println(" }"); + println(" return j;"); + println(" }"); + } + + /** + * Translate all values by given amount. + * + * Use to move value interval from [0, 0xFFFF] to something different. + * + * @param i amount the value will be translated by. + * Example: i = 1 allows values in [-1, 0xFFFE]. + */ + public void setValTranslation(int i) { + this.translate = i; + } + + /** + * Emit one count/value pair. + * + * Automatically translates value by the translate value. + * + * @param count + * @param value + * + * @see CountEmitter#setValTranslation(int) + */ + public void emit(int count, int value) { + numEntries+= count; + breaks(); + emitUC(count); + emitUC(value+translate); + } +} diff --git a/tools/lexer/jflex-1.4/src/JFlex/DFA.java b/tools/lexer/jflex-1.4/src/JFlex/DFA.java new file mode 100644 index 000000000000..37e2556504ee --- /dev/null +++ b/tools/lexer/jflex-1.4/src/JFlex/DFA.java @@ -0,0 +1,940 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * JFlex 1.4.1 * + * Copyright (C) 1998-2004 Gerwin Klein * + * All rights reserved. * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License. See the file * + * COPYRIGHT for more information. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License along * + * with this program; if not, write to the Free Software Foundation, Inc., * + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +package JFlex; + + +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; +import java.io.PrintWriter; +import java.util.Enumeration; +import java.util.Hashtable; + + +/** + * DFA representation in JFlex. + * Contains minimization algorithm. + * + * @author Gerwin Klein + * @version JFlex 1.4.1, $Revision: 2.7 $, $Date: 2004/11/06 23:03:31 $ + */ +final public class DFA { + + /** + * The initial number of states + */ + private static final int STATES = 500; + + /** + * The code for "no target state" in the transition table. + */ + public static final int NO_TARGET = -1; + + /** + * table[current_state][character] is the next state for current_state + * with input character, NO_TARGET if there is no transition for + * this input in current_state + */ + int [][] table; + + + /** + * isFinal[state] == true <=> the state state is + * a final state. + */ + boolean [] isFinal; + + /** + * isPushback[state] == true <=> the state state is + * a final state of an expression that can only be matched when followed by + * a certain lookaead. + */ + boolean [] isPushback; + + + /** + * isLookEnd[state] == true <=> the state state is + * a final state of a lookahead expression. + */ + boolean [] isLookEnd; + + + /** + * action[state] is the action that is to be carried out in + * state state, null if there is no action. + */ + Action [] action; + + /** + * lexState[i] is the start-state of lexical state i + */ + int lexState []; + + /** + * The number of states in this DFA + */ + int numStates; + + + /** + * The current maximum number of input characters + */ + int numInput; + + + /** + * all actions that are used in this DFA + */ + Hashtable usedActions = new Hashtable(); + + public DFA(int numLexStates, int numInp) { + numInput = numInp; + + int statesNeeded = Math.max(numLexStates, STATES); + + table = new int [statesNeeded] [numInput]; + action = new Action [statesNeeded]; + isFinal = new boolean [statesNeeded]; + isPushback = new boolean [statesNeeded]; + isLookEnd = new boolean [statesNeeded]; + lexState = new int [numLexStates]; + numStates = 0; + + for (int i = 0; i < statesNeeded; i++) { + for (char j = 0; j < numInput; j++) + table [i][j] = NO_TARGET; + } + } + + + public void setLexState(int lState, int trueState) { + lexState[lState] = trueState; + } + + private void ensureStateCapacity(int newNumStates) { + int oldLength = isFinal.length; + + if ( newNumStates < oldLength ) return; + + int newLength = oldLength*2; + while ( newLength <= newNumStates ) newLength*= 2; + + boolean [] newFinal = new boolean [newLength]; + boolean [] newPushback = new boolean [newLength]; + boolean [] newLookEnd = new boolean [newLength]; + Action [] newAction = new Action [newLength]; + int [] [] newTable = new int [newLength] [numInput]; + + System.arraycopy(isFinal,0,newFinal,0,numStates); + System.arraycopy(isPushback,0,newPushback,0,numStates); + System.arraycopy(isLookEnd,0,newLookEnd,0,numStates); + System.arraycopy(action,0,newAction,0,numStates); + System.arraycopy(table,0,newTable,0,oldLength); + + int i,j; + + for (i = oldLength; i < newLength; i++) { + for (j = 0; j < numInput; j++) { + newTable[i][j] = NO_TARGET; + } + } + + isFinal = newFinal; + isPushback = newPushback; + isLookEnd = newLookEnd; + action = newAction; + table = newTable; + } + + + public void setAction(int state, Action stateAction) { + action[state] = stateAction; + if (stateAction != null) { + isLookEnd[state] = stateAction.isLookAction(); + usedActions.put(stateAction,stateAction); + } + } + + public void setFinal(int state, boolean isFinalState) { + isFinal[state] = isFinalState; + } + + public void setPushback(int state, boolean isPushbackState) { + isPushback[state] = isPushbackState; + } + + + public void addTransition(int start, char input, int dest) { + int max = Math.max(start,dest)+1; + ensureStateCapacity(max); + if (max > numStates) numStates = max; + + // Out.debug("Adding DFA transition ("+start+", "+(int)input+", "+dest+")"); + + table[start][input] = dest; + } + + + + public String toString() { + StringBuffer result = new StringBuffer(); + + for (int i=0; i < numStates; i++) { + result.append("State "); + if ( isFinal[i] ) result.append("[FINAL] "); // (action "+action[i].priority+")] "); + if ( isPushback[i] ) result.append("[PUSH] "); + result.append(i+":"+Out.NL); + + for (char j=0; j < numInput; j++) { + if ( table[i][j] >= 0 ) + result.append(" with "+(int)j+" in "+table[i][j]+Out.NL); + } + } + + return result.toString(); + } + + + public void writeDot(File file) { + try { + PrintWriter writer = new PrintWriter(new FileWriter(file)); + writer.println(dotFormat()); + writer.close(); + } + catch (IOException e) { + Out.error(ErrorMessages.FILE_WRITE, file); + throw new GeneratorException(); + } + } + + + public String dotFormat() { + StringBuffer result = new StringBuffer(); + + result.append("digraph DFA {"+Out.NL); + result.append("rankdir = LR"+Out.NL); + + for (int i=0; i < numStates; i++) { + if ( isFinal[i] || isPushback[i] ) result.append(i); + if ( isFinal[i] ) result.append(" [shape = doublecircle]"); + if ( isPushback[i] ) result.append(" [shape = box]"); + if ( isFinal[i] || isPushback[i] ) result.append(Out.NL); + } + + for (int i=0; i < numStates; i++) { + for (int input = 0; input < numInput; input++) { + if ( table[i][input] >= 0 ) { + result.append(i+" -> "+table[i][input]); + result.append(" [label=\"["+input+"]\"]"+Out.NL); + // result.append(" [label=\"["+classes.toString(input)+"]\"]\n"); + } + } + } + + result.append("}"+Out.NL); + + return result.toString(); + } + + + // check if all actions can actually be matched in this DFA + public void checkActions(LexScan scanner, LexParse parser) { + EOFActions eofActions = parser.getEOFActions(); + Enumeration l = scanner.actions.elements(); + + while (l.hasMoreElements()) { + Object next = l.nextElement(); + if ( !next.equals(usedActions.get(next)) && !eofActions.isEOFAction(next) ) + Out.warning(scanner.file, ErrorMessages.NEVER_MATCH, ((Action) next).priority-1, -1); + } + } + + + /** + * Implementation of Hopcroft's O(n log n) minimization algorithm, follows + * description by D. Gries. + * + * Time: O(n log n) + * Space: O(c n), size < 4*(5*c*n + 13*n + 3*c) byte + */ + public void minimize() { + Out.print(numStates+" states before minimization, "); + + if (numStates == 0) { + Out.error(ErrorMessages.ZERO_STATES); + throw new GeneratorException(); + } + + if (Options.no_minimize) { + Out.println("minimization skipped."); + return; + } + + // the algorithm needs the DFA to be total, so we add an error state 0, + // and translate the rest of the states by +1 + final int n = numStates+1; + + // block information: + // [0..n-1] stores which block a state belongs to, + // [n..2*n-1] stores how many elements each block has + int [] block = new int[2*n]; + + // implements a doubly linked list of states (these are the actual blocks) + int [] b_forward = new int[2*n]; + int [] b_backward = new int[2*n]; + + // the last of the blocks currently in use (in [n..2*n-1]) + // (end of list marker, points to the last used block) + int lastBlock = n; // at first we start with one empty block + final int b0 = n; // the first block + + // the circular doubly linked list L of pairs (B_i, c) + // (B_i, c) in L iff l_forward[(B_i-n)*numInput+c] > 0 // numeric value of block 0 = n! + int [] l_forward = new int[n*numInput+1]; + int [] l_backward = new int[n*numInput+1]; + int anchorL = n*numInput; // list anchor + + // inverse of the transition table + // if t = inv_delta[s][c] then { inv_delta_set[t], inv_delta_set[t+1], .. inv_delta_set[k] } + // is the set of states, with inv_delta_set[k] = -1 and inv_delta_set[j] >= 0 for t <= j < k + int [] [] inv_delta = new int[n][numInput]; + int [] inv_delta_set = new int [2*n*numInput]; + + // twin stores two things: + // twin[0]..twin[numSplit-1] is the list of blocks that have been split + // twin[B_i] is the twin of block B_i + int [] twin = new int[2*n]; + int numSplit; + + // SD[B_i] is the the number of states s in B_i with delta(s,a) in B_j + // if SD[B_i] == block[B_i], there is no need to split + int [] SD = new int[2*n]; // [only SD[n..2*n-1] is used] + + + // for fixed (B_j,a), the D[0]..D[numD-1] are the inv_delta(B_j,a) + int [] D = new int[n]; + int numD; + + + // initialize inverse of transition table + int lastDelta = 0; + int [] inv_lists = new int[n]; // holds a set of lists of states + int [] inv_list_last = new int[n]; // the last element + for (int c = 0; c < numInput; c++) { + // clear "head" and "last element" pointers + for (int s = 0; s < n; s++) { + inv_list_last[s] = -1; + inv_delta[s][c] = -1; + } + + // the error state has a transition for each character into itself + inv_delta[0][c] = 0; + inv_list_last[0] = 0; + + // accumulate states of inverse delta into lists (inv_delta serves as head of list) + for (int s = 1; s < n; s++) { + int t = table[s-1][c]+1; + + if (inv_list_last[t] == -1) { // if there are no elements in the list yet + inv_delta[t][c] = s; // mark t as first and last element + inv_list_last[t] = s; + } + else { + inv_lists[inv_list_last[t]] = s; // link t into chain + inv_list_last[t] = s; // and mark as last element + } + } + + // now move them to inv_delta_set in sequential order, + // and update inv_delta accordingly + for (int s = 0; s < n; s++) { + int i = inv_delta[s][c]; inv_delta[s][c] = lastDelta; + int j = inv_list_last[s]; + boolean go_on = (i != -1); + while (go_on) { + go_on = (i != j); + inv_delta_set[lastDelta++] = i; + i = inv_lists[i]; + } + inv_delta_set[lastDelta++] = -1; + } + } // of initialize inv_delta + + // printInvDelta(inv_delta, inv_delta_set); + + // initialize blocks + + // make b0 = {0} where 0 = the additional error state + b_forward[b0] = 0; + b_backward[b0] = 0; + b_forward[0] = b0; + b_backward[0] = b0; + block[0] = b0; + block[b0] = 1; + + for (int s = 1; s < n; s++) { + // System.out.println("Checking state ["+(s-1)+"]"); + // search the blocks if it fits in somewhere + // (fit in = same pushback behavior, same finalness, same lookahead behavior, same action) + int b = b0+1; // no state can be equivalent to the error state + boolean found = false; + while (!found && b <= lastBlock) { + // get some state out of the current block + int t = b_forward[b]; + // System.out.println(" picking state ["+(t-1)+"]"); + + // check, if s could be equivalent with t + found = (isPushback[s-1] == isPushback[t-1]) && (isLookEnd[s-1] == isLookEnd[t-1]); + if (found) { + if (isFinal[s-1]) { + found = isFinal[t-1] && action[s-1].isEquiv(action[t-1]); + } + else { + found = !isFinal[t-1]; + } + + if (found) { // found -> add state s to block b + // System.out.println("Found! Adding to block "+(b-b0)); + // update block information + block[s] = b; + block[b]++; + + // chain in the new element + int last = b_backward[b]; + b_forward[last] = s; + b_forward[s] = b; + b_backward[b] = s; + b_backward[s] = last; + } + } + + b++; + } + + if (!found) { // fits in nowhere -> create new block + // System.out.println("not found, lastBlock = "+lastBlock); + + // update block information + block[s] = b; + block[b]++; + + // chain in the new element + b_forward[b] = s; + b_forward[s] = b; + b_backward[b] = s; + b_backward[s] = b; + + lastBlock++; + } + } // of initialize blocks + + // printBlocks(block,b_forward,b_backward,lastBlock); + + // initialize worklist L + // first, find the largest block B_max, then, all other (B_i,c) go into the list + int B_max = b0; + int B_i; + for (B_i = b0+1; B_i <= lastBlock; B_i++) + if (block[B_max] < block[B_i]) B_max = B_i; + + // L = empty + l_forward[anchorL] = anchorL; + l_backward[anchorL] = anchorL; + + // set up the first list element + if (B_max == b0) B_i = b0+1; else B_i = b0; // there must be at least two blocks + + int index = (B_i-b0)*numInput; // (B_i, 0) + while (index < (B_i+1-b0)*numInput) { + int last = l_backward[anchorL]; + l_forward[last] = index; + l_forward[index] = anchorL; + l_backward[index] = last; + l_backward[anchorL] = index; + index++; + } + + // now do the rest of L + while (B_i <= lastBlock) { + if (B_i != B_max) { + index = (B_i-b0)*numInput; + while (index < (B_i+1-b0)*numInput) { + int last = l_backward[anchorL]; + l_forward[last] = index; + l_forward[index] = anchorL; + l_backward[index] = last; + l_backward[anchorL] = index; + index++; + } + } + B_i++; + } + // end of setup L + + // start of "real" algorithm + // int step = 0; + // System.out.println("max_steps = "+(n*numInput)); + // while L not empty + while (l_forward[anchorL] != anchorL) { + // System.out.println("step : "+(step++)); + // printL(l_forward, l_backward, anchorL); + + // pick and delete (B_j, a) in L: + + // pick + int B_j_a = l_forward[anchorL]; + // delete + l_forward[anchorL] = l_forward[B_j_a]; + l_backward[l_forward[anchorL]] = anchorL; + l_forward[B_j_a] = 0; + // take B_j_a = (B_j-b0)*numInput+c apart into (B_j, a) + int B_j = b0 + B_j_a / numInput; + int a = B_j_a % numInput; + + // printL(l_forward, l_backward, anchorL); + + // System.out.println("picked ("+B_j+","+a+")"); + // printL(l_forward, l_backward, anchorL); + + // determine splittings of all blocks wrt (B_j, a) + // i.e. D = inv_delta(B_j,a) + numD = 0; + int s = b_forward[B_j]; + while (s != B_j) { + // System.out.println("splitting wrt. state "+s); + int t = inv_delta[s][a]; + // System.out.println("inv_delta chunk "+t); + while (inv_delta_set[t] != -1) { + // System.out.println("D+= state "+inv_delta_set[t]); + D[numD++] = inv_delta_set[t++]; + } + s = b_forward[s]; + } + + // clear the twin list + numSplit = 0; + + // System.out.println("splitting blocks according to D"); + + // clear SD and twins (only those B_i that occur in D) + for (int indexD = 0; indexD < numD; indexD++) { // for each s in D + s = D[indexD]; + B_i = block[s]; + SD[B_i] = -1; + twin[B_i] = 0; + } + + // count how many states of each B_i occuring in D go with a into B_j + // Actually we only check, if *all* t in B_i go with a into B_j. + // In this case SD[B_i] == block[B_i] will hold. + for (int indexD = 0; indexD < numD; indexD++) { // for each s in D + s = D[indexD]; + B_i = block[s]; + + // only count, if we haven't checked this block already + if (SD[B_i] < 0) { + SD[B_i] = 0; + int t = b_forward[B_i]; + while (t != B_i && (t != 0 || block[0] == B_j) && + (t == 0 || block[table[t-1][a]+1] == B_j)) { + SD[B_i]++; + t = b_forward[t]; + } + } + } + + // split each block according to D + for (int indexD = 0; indexD < numD; indexD++) { // for each s in D + s = D[indexD]; + B_i = block[s]; + + // System.out.println("checking if block "+(B_i-b0)+" must be split because of state "+s); + + if (SD[B_i] != block[B_i]) { + // System.out.println("state "+(s-1)+" must be moved"); + int B_k = twin[B_i]; + if (B_k == 0) { + // no twin for B_i yet -> generate new block B_k, make it B_i's twin + B_k = ++lastBlock; + // System.out.println("creating block "+(B_k-n)); + // printBlocks(block,b_forward,b_backward,lastBlock-1); + b_forward[B_k] = B_k; + b_backward[B_k] = B_k; + + twin[B_i] = B_k; + + // mark B_i as split + twin[numSplit++] = B_i; + } + // move s from B_i to B_k + + // remove s from B_i + b_forward[b_backward[s]] = b_forward[s]; + b_backward[b_forward[s]] = b_backward[s]; + + // add s to B_k + int last = b_backward[B_k]; + b_forward[last] = s; + b_forward[s] = B_k; + b_backward[s] = last; + b_backward[B_k] = s; + + block[s] = B_k; + block[B_k]++; + block[B_i]--; + + SD[B_i]--; // there is now one state less in B_i that goes with a into B_j + // printBlocks(block, b_forward, b_backward, lastBlock); + // System.out.println("finished move"); + } + } // of block splitting + + // printBlocks(block, b_forward, b_backward, lastBlock); + + // System.out.println("updating L"); + + // update L + for (int indexTwin = 0; indexTwin < numSplit; indexTwin++) { + B_i = twin[indexTwin]; + int B_k = twin[B_i]; + for (int c = 0; c < numInput; c++) { + int B_i_c = (B_i-b0)*numInput+c; + int B_k_c = (B_k-b0)*numInput+c; + if (l_forward[B_i_c] > 0) { + // (B_i,c) already in L --> put (B_k,c) in L + int last = l_backward[anchorL]; + l_backward[anchorL] = B_k_c; + l_forward[last] = B_k_c; + l_backward[B_k_c] = last; + l_forward[B_k_c] = anchorL; + } + else { + // put the smaller block in L + if (block[B_i] <= block[B_k]) { + int last = l_backward[anchorL]; + l_backward[anchorL] = B_i_c; + l_forward[last] = B_i_c; + l_backward[B_i_c] = last; + l_forward[B_i_c] = anchorL; + } + else { + int last = l_backward[anchorL]; + l_backward[anchorL] = B_k_c; + l_forward[last] = B_k_c; + l_backward[B_k_c] = last; + l_forward[B_k_c] = anchorL; + } + } + } + } + } + + // System.out.println("Result"); + // printBlocks(block,b_forward,b_backward,lastBlock); + + /* + System.out.println("Old minimization:"); + boolean [] [] equiv = old_minimize(); + + boolean error = false; + for (int i = 1; i < equiv.length; i++) { + for (int j = 0; j < equiv[i].length; j++) { + if (equiv[i][j] != (block[i+1] == block[j+1])) { + System.out.println("error: equiv["+i+"]["+j+"] = "+equiv[i][j]+ + ", block["+i+"] = "+block[i+1]+", block["+j+"] = "+block[j]); + error = true; + } + } + } + + if (error) System.exit(1); + System.out.println("check"); + */ + + // transform the transition table + + // trans[i] is the state j that will replace state i, i.e. + // states i and j are equivalent + int trans [] = new int [numStates]; + + // kill[i] is true iff state i is redundant and can be removed + boolean kill [] = new boolean [numStates]; + + // move[i] is the amount line i has to be moved in the transition table + // (because states j < i have been removed) + int move [] = new int [numStates]; + + // fill arrays trans[] and kill[] (in O(n)) + for (int b = b0+1; b <= lastBlock; b++) { // b0 contains the error state + // get the state with smallest value in current block + int s = b_forward[b]; + int min_s = s; // there are no empty blocks! + for (; s != b; s = b_forward[s]) + if (min_s > s) min_s = s; + // now fill trans[] and kill[] for this block + // (and translate states back to partial DFA) + min_s--; + for (s = b_forward[b]-1; s != b-1; s = b_forward[s+1]-1) { + trans[s] = min_s; + kill[s] = s != min_s; + } + } + + // fill array move[] (in O(n)) + int amount = 0; + for (int i = 0; i < numStates; i++) { + if ( kill[i] ) + amount++; + else + move[i] = amount; + } + + int i,j; + // j is the index in the new transition table + // the transition table is transformed in place (in O(c n)) + for (i = 0, j = 0; i < numStates; i++) { + + // we only copy lines that have not been removed + if ( !kill[i] ) { + + // translate the target states + for (int c = 0; c < numInput; c++) { + if ( table[i][c] >= 0 ) { + table[j][c] = trans[ table[i][c] ]; + table[j][c]-= move[ table[j][c] ]; + } + else { + table[j][c] = table[i][c]; + } + } + + isFinal[j] = isFinal[i]; + isPushback[j] = isPushback[i]; + isLookEnd[j] = isLookEnd[i]; + action[j] = action[i]; + + j++; + } + } + + numStates = j; + + // translate lexical states + for (i = 0; i < lexState.length; i++) { + lexState[i] = trans[ lexState[i] ]; + lexState[i]-= move[ lexState[i] ]; + } + + Out.println(numStates+" states in minimized DFA"); + } + + public String toString(int [] a) { + String r = "{"; + int i; + for (i = 0; i < a.length-1; i++) r += a[i]+","; + return r+a[i]+"}"; + } + + public void printBlocks(int [] b, int [] b_f, int [] b_b, int last) { + Out.dump("block : "+toString(b)); + Out.dump("b_forward : "+toString(b_f)); + Out.dump("b_backward: "+toString(b_b)); + Out.dump("lastBlock : "+last); + final int n = numStates+1; + for (int i = n; i <= last; i ++) { + Out.dump("Block "+(i-n)+" (size "+b[i]+"):"); + String line = "{"; + int s = b_f[i]; + while (s != i) { + line = line+(s-1); + int t = s; + s = b_f[s]; + if (s != i) { + line = line+","; + if (b[s] != i) Out.dump("consistency error for state "+(s-1)+" (block "+b[s]+")"); + } + if (b_b[s] != t) Out.dump("consistency error for b_back in state "+(s-1)+" (back = "+b_b[s]+", should be = "+t+")"); + } + Out.dump(line+"}"); + } + } + + public void printL(int [] l_f, int [] l_b, int anchor) { + String l = "L = {"; + int bc = l_f[anchor]; + while (bc != anchor) { + int b = bc / numInput; + int c = bc % numInput; + l+= "("+b+","+c+")"; + int old_bc = bc; + bc = l_f[bc]; + if (bc != anchor) l+= ","; + if (l_b[bc] != old_bc) Out.dump("consistency error for ("+b+","+c+")"); + } + Out.dump(l+"}"); + } + + + public boolean [] [] old_minimize() { + + int i,j; + char c; + + Out.print(numStates+" states before minimization, "); + + if (numStates == 0) { + Out.error(ErrorMessages.ZERO_STATES); + throw new GeneratorException(); + } + + if (Options.no_minimize) { + Out.println("minimization skipped."); + return null; + } + + // notequiv[i][j] == true <=> state i and state j are equivalent + boolean [] [] equiv = new boolean [numStates] []; + + // list[i][j] contains all pairs of states that have to be marked "not equivalent" + // if states i and j are recognized to be not equivalent + StatePairList [] [] list = new StatePairList [numStates] []; + + // construct a triangular matrix equiv[i][j] with j < i + // and mark pairs (final state, not final state) as not equivalent + for (i = 1; i < numStates; i++) { + list[i] = new StatePairList[i]; + equiv[i] = new boolean [i]; + for (j = 0; j < i; j++) { + // i and j are equivalent, iff : + // i and j are both final and their actions are equivalent and have same pushback behaviour or + // i and j are both not final + + if ( isFinal[i] && isFinal[j] && (isPushback[i] == isPushback[j]) && (isLookEnd[i] == isLookEnd[j]) ) + equiv[i][j] = action[i].isEquiv(action[j]); + else + equiv[i][j] = !isFinal[j] && !isFinal[i] && (isPushback[i] == isPushback[j]) && (isLookEnd[i] == isLookEnd[j]); + } + } + + + for (i = 1; i < numStates; i++) { + + Out.debug("Testing state "+i); + + for (j = 0; j < i; j++) { + + if ( equiv[i][j] ) { + + for (c = 0; c < numInput; c++) { + + if (equiv[i][j]) { + + int p = table[i][c]; + int q = table[j][c]; + if (p < q) { + int t = p; + p = q; + q = t; + } + if ( p >= 0 || q >= 0 ) { + // Out.debug("Testing input '"+c+"' for ("+i+","+j+")"); + // Out.debug("Target states are ("+p+","+q+")"); + if ( p!=q && (p == -1 || q == -1 || !equiv[p][q]) ) { + equiv[i][j] = false; + if (list[i][j] != null) list[i][j].markAll(list,equiv); + } + // printTable(equiv); + } // if (p >= 0) .. + } // if (equiv[i][j] + } // for (char c = 0; c < numInput .. + + // if i and j are still marked equivalent.. + + if ( equiv[i][j] ) { + + // Out.debug("("+i+","+j+") are still marked equivalent"); + + for (c = 0; c < numInput; c++) { + + int p = table[i][c]; + int q = table[j][c]; + if (p < q) { + int t = p; + p = q; + q = t; + } + + if (p != q && p >= 0 && q >= 0) { + if ( list[p][q] == null ) { + list[p][q] = new StatePairList(); + } + list[p][q].addPair(i,j); + } + } + } + else { + // Out.debug("("+i+","+j+") are not equivalent"); + } + + } // of first if (equiv[i][j]) + } // of for j + } // of for i + // } + + // printTable(equiv); + + return equiv; + } + + + public void printInvDelta(int [] [] inv_delta, int [] inv_delta_set) { + Out.dump("Inverse of transition table: "); + for (int s = 0; s < numStates+1; s++) { + Out.dump("State ["+(s-1)+"]"); + for (int c = 0; c < numInput; c++) { + String line = "With <"+c+"> in {"; + int t = inv_delta[s][c]; + while (inv_delta_set[t] != -1) { + line += inv_delta_set[t++]-1; + if (inv_delta_set[t] != -1) line += ","; + } + if (inv_delta_set[inv_delta[s][c]] != -1) + Out.dump(line+"}"); + } + } + } + + public void printTable(boolean [] [] equiv) { + + Out.dump("Equivalence table is : "); + for (int i = 1; i < numStates; i++) { + String line = i+" :"; + for (int j = 0; j < i; j++) { + if (equiv[i][j]) + line+= " E"; + else + line+= " x"; + } + Out.dump(line); + } + } + +} diff --git a/tools/lexer/jflex-1.4/src/JFlex/EOFActions.java b/tools/lexer/jflex-1.4/src/JFlex/EOFActions.java new file mode 100644 index 000000000000..76242fb3a9a9 --- /dev/null +++ b/tools/lexer/jflex-1.4/src/JFlex/EOFActions.java @@ -0,0 +1,96 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * JFlex 1.4.1 * + * Copyright (C) 1998-2004 Gerwin Klein * + * All rights reserved. * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License. See the file * + * COPYRIGHT for more information. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License along * + * with this program; if not, write to the Free Software Foundation, Inc., * + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +package JFlex; + +import java.util.Enumeration; +import java.util.Hashtable; +import java.util.Vector; + + +/** + * A simple table to store EOF actions for each lexical state. + * + * @author Gerwin Klein + * @version JFlex 1.4.1, $Revision: 2.2 $, $Date: 2004/11/06 23:03:32 $ + */ +public class EOFActions { + + /** maps lexical states to actions */ + private Hashtable /* Integer -> Action */ actions = new Hashtable(); + private Action defaultAction; + private int numLexStates; + + public void setNumLexStates(int num) { + numLexStates = num; + } + + public void add(Vector stateList, Action action) { + + if (stateList != null && stateList.size() > 0) { + Enumeration states = stateList.elements(); + + while (states.hasMoreElements()) + add( (Integer) states.nextElement(), action ); + } + else { + defaultAction = action.getHigherPriority(defaultAction); + + for (int i = 0; i < numLexStates; i++) { + Integer state = new Integer(i); + if ( actions.get(state) != null ) { + Action oldAction = (Action) actions.get(state); + actions.put(state, oldAction.getHigherPriority(action)); + } + } + } + } + + public void add(Integer state, Action action) { + if ( actions.get(state) == null ) + actions.put(state, action); + else { + Action oldAction = (Action) actions.get(state); + actions.put(state, oldAction.getHigherPriority(action)); + } + } + + public boolean isEOFAction(Object a) { + if (a == defaultAction) return true; + + Enumeration e = actions.elements(); + while ( e.hasMoreElements() ) + if (a == e.nextElement()) return true; + + return false; + } + + public Action getAction(int state) { + return (Action) actions.get(new Integer(state)); + } + + public Action getDefault() { + return defaultAction; + } + + public int numActions() { + return actions.size(); + } +} diff --git a/tools/lexer/jflex-1.4/src/JFlex/Emitter.java b/tools/lexer/jflex-1.4/src/JFlex/Emitter.java new file mode 100644 index 000000000000..eba3be2052b1 --- /dev/null +++ b/tools/lexer/jflex-1.4/src/JFlex/Emitter.java @@ -0,0 +1,1616 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * JFlex 1.4.1 * + * Copyright (C) 1998-2004 Gerwin Klein * + * All rights reserved. * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License. See the file * + * COPYRIGHT for more information. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License along * + * with this program; if not, write to the Free Software Foundation, Inc., * + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +package JFlex; + +import java.io.*; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.Enumeration; +import java.util.Hashtable; + +/** + * This class manages the actual code generation, putting + * the scanner together, filling in skeleton sections etc. + * + * Table compression, String packing etc. is also done here. + * + * @author Gerwin Klein + * @version JFlex 1.4.1, $Revision: 2.26 $, $Date: 2004/11/07 03:12:46 $ + */ +final public class Emitter { + + // bit masks for state attributes + static final private int FINAL = 1; + static final private int PUSHBACK = 2; + static final private int LOOKEND = 4; + static final private int NOLOOK = 8; + + static final private String date = (new SimpleDateFormat()).format(new Date()); + + private File inputFile; + + private PrintWriter out; + private Skeleton skel; + private LexScan scanner; + private LexParse parser; + private DFA dfa; + + // for switch statement: + // table[i][j] is the set of input characters that leads from state i to state j + private CharSet table[][]; + + private boolean isTransition[]; + + // noTarget[i] is the set of input characters that have no target state in state i + private CharSet noTarget[]; + + // for row killing: + private int numRows; + private int [] rowMap; + private boolean [] rowKilled; + + // for col killing: + private int numCols; + private int [] colMap; + private boolean [] colKilled; + + + /** maps actions to their switch label */ + private Hashtable actionTable = new Hashtable(); + + private CharClassInterval [] intervalls; + + private String visibility = "public"; + + public Emitter(File inputFile, LexParse parser, DFA dfa) throws IOException { + + String name = parser.scanner.className+".java"; + + File outputFile = normalize(name, inputFile); + + Out.println("Writing code to \""+outputFile+"\""); + + this.out = new PrintWriter(new BufferedWriter(new FileWriter(outputFile))); + this.parser = parser; + this.scanner = parser.scanner; + this.visibility = scanner.visibility; + this.inputFile = inputFile; + this.dfa = dfa; + this.skel = new Skeleton(out); + } + + + /** + * Constructs a file in Options.getDir() or in the same directory as + * another file. Makes a backup if the file already exists. + * + * @param name the name (without path) of the file + * @param path the path where to construct the file + * @param input fallback location if path = null + * (expected to be a file in the directory to write to) + */ + public static File normalize(String name, File input) { + File outputFile; + + if ( Options.getDir() == null ) + if ( input == null || input.getParent() == null ) + outputFile = new File(name); + else + outputFile = new File(input.getParent(), name); + else + outputFile = new File(Options.getDir(), name); + + if ( outputFile.exists() && !Options.no_backup ) { + File backup = new File( outputFile.toString()+"~" ); + + if ( backup.exists() ) backup.delete(); + + if ( outputFile.renameTo( backup ) ) + Out.println("Old file \""+outputFile+"\" saved as \""+backup+"\""); + else + Out.println("Couldn't save old file \""+outputFile+"\", overwriting!"); + } + + return outputFile; + } + + private void println() { + out.println(); + } + + private void println(String line) { + out.println(line); + } + + private void println(int i) { + out.println(i); + } + + private void print(String line) { + out.print(line); + } + + private void print(int i) { + out.print(i); + } + + private void print(int i, int tab) { + int exp; + + if (i < 0) + exp = 1; + else + exp = 10; + + while (tab-- > 1) { + if (Math.abs(i) < exp) print(" "); + exp*= 10; + } + + print(i); + } + + private void emitScanError() { + print(" private void zzScanError(int errorCode)"); + + if (scanner.scanErrorException != null) + print(" throws "+scanner.scanErrorException); + + println(" {"); + + skel.emitNext(); + + if (scanner.scanErrorException == null) + println(" throw new Error(message);"); + else + println(" throw new "+scanner.scanErrorException+"(message);"); + + skel.emitNext(); + + print(" "+visibility+" void yypushback(int number) "); + + if (scanner.scanErrorException == null) + println(" {"); + else + println(" throws "+scanner.scanErrorException+" {"); + } + + private void emitMain() { + if ( !(scanner.standalone || scanner.debugOption || scanner.cupDebug) ) return; + + if ( scanner.cupDebug ) { + println(" /**"); + println(" * Converts an int token code into the name of the"); + println(" * token by reflection on the cup symbol class/interface "+scanner.cupSymbol); + println(" *"); + println(" * This code was contributed by Karl Meissner "); + println(" */"); + println(" private String getTokenName(int token) {"); + println(" try {"); + println(" java.lang.reflect.Field [] classFields = " + scanner.cupSymbol + ".class.getFields();"); + println(" for (int i = 0; i < classFields.length; i++) {"); + println(" if (classFields[i].getInt(null) == token) {"); + println(" return classFields[i].getName();"); + println(" }"); + println(" }"); + println(" } catch (Exception e) {"); + println(" e.printStackTrace(System.err);"); + println(" }"); + println(""); + println(" return \"UNKNOWN TOKEN\";"); + println(" }"); + println(""); + println(" /**"); + println(" * Same as "+scanner.functionName+" but also prints the token to standard out"); + println(" * for debugging."); + println(" *"); + println(" * This code was contributed by Karl Meissner "); + println(" */"); + + print(" "+visibility+" "); + if ( scanner.tokenType == null ) { + if ( scanner.isInteger ) + print( "int" ); + else + if ( scanner.isIntWrap ) + print( "Integer" ); + else + print( "Yytoken" ); + } + else + print( scanner.tokenType ); + + print(" debug_"); + + print(scanner.functionName); + + print("() throws java.io.IOException"); + + if ( scanner.lexThrow != null ) { + print(", "); + print(scanner.lexThrow); + } + + if ( scanner.scanErrorException != null ) { + print(", "); + print(scanner.scanErrorException); + } + + println(" {"); + + println(" java_cup.runtime.Symbol s = "+scanner.functionName+"();"); + print(" System.out.println( "); + if (scanner.lineCount) print("\"line:\" + (yyline+1) + "); + if (scanner.columnCount) print("\" col:\" + (yycolumn+1) + "); + println("\" --\"+ yytext() + \"--\" + getTokenName(s.sym) + \"--\");"); + println(" return s;"); + println(" }"); + println(""); + } + + if ( scanner.standalone ) { + println(" /**"); + println(" * Runs the scanner on input files."); + println(" *"); + println(" * This is a standalone scanner, it will print any unmatched"); + println(" * text to System.out unchanged."); + println(" *"); + println(" * @param argv the command line, contains the filenames to run"); + println(" * the scanner on."); + println(" */"); + } + else { + println(" /**"); + println(" * Runs the scanner on input files."); + println(" *"); + println(" * This main method is the debugging routine for the scanner."); + println(" * It prints debugging information about each returned token to"); + println(" * System.out until the end of file is reached, or an error occured."); + println(" *"); + println(" * @param argv the command line, contains the filenames to run"); + println(" * the scanner on."); + println(" */"); + } + + println(" public static void main(String argv[]) {"); + println(" if (argv.length == 0) {"); + println(" System.out.println(\"Usage : java "+scanner.className+" \");"); + println(" }"); + println(" else {"); + println(" for (int i = 0; i < argv.length; i++) {"); + println(" "+scanner.className+" scanner = null;"); + println(" try {"); + println(" scanner = new "+scanner.className+"( new java.io.FileReader(argv[i]) );"); + + if ( scanner.standalone ) { + println(" while ( !scanner.zzAtEOF ) scanner."+scanner.functionName+"();"); + } + else if (scanner.cupDebug ) { + println(" while ( !scanner.zzAtEOF ) scanner.debug_"+scanner.functionName+"();"); + } + else { + println(" do {"); + println(" System.out.println(scanner."+scanner.functionName+"());"); + println(" } while (!scanner.zzAtEOF);"); + println(""); + } + + println(" }"); + println(" catch (java.io.FileNotFoundException e) {"); + println(" System.out.println(\"File not found : \\\"\"+argv[i]+\"\\\"\");"); + println(" }"); + println(" catch (java.io.IOException e) {"); + println(" System.out.println(\"IO error scanning file \\\"\"+argv[i]+\"\\\"\");"); + println(" System.out.println(e);"); + println(" }"); + println(" catch (Exception e) {"); + println(" System.out.println(\"Unexpected exception:\");"); + println(" e.printStackTrace();"); + println(" }"); + println(" }"); + println(" }"); + println(" }"); + println(""); + } + + private void emitNoMatch() { + println(" zzScanError(ZZ_NO_MATCH);"); + } + + private String zzBufferLAccess(String idx) { + if (Options.sliceAndCharAt) { + return "zzBufferArrayL != null ? zzBufferArrayL[" + idx + "]:zzBufferL.charAt("+idx+")"; + } + if (Options.char_at) { + return "zzBufferL.charAt("+idx+")"; + } + return "zzBufferL[" + idx + "]"; + } + + private void emitNextInput() { + println(" if (zzCurrentPosL < zzEndReadL)"); + println(" zzInput = " + zzBufferLAccess("zzCurrentPosL++") + ";"); + println(" else if (zzAtEOF) {"); + println(" zzInput = YYEOF;"); + println(" break zzForAction;"); + println(" }"); + println(" else {"); + println(" // store back cached positions"); + println(" zzCurrentPos = zzCurrentPosL;"); + println(" zzMarkedPos = zzMarkedPosL;"); + if ( scanner.lookAheadUsed ) + println(" zzPushbackPos = zzPushbackPosL;"); + println(" boolean eof = zzRefill();"); + println(" // get translated positions and possibly new buffer"); + println(" zzCurrentPosL = zzCurrentPos;"); + println(" zzMarkedPosL = zzMarkedPos;"); + println(" zzBufferL = zzBuffer;"); + println(" zzEndReadL = zzEndRead;"); + if ( scanner.lookAheadUsed ) + println(" zzPushbackPosL = zzPushbackPos;"); + println(" if (eof) {"); + println(" zzInput = YYEOF;"); + println(" break zzForAction;"); + println(" }"); + println(" else {"); + println(" zzInput = " + zzBufferLAccess("zzCurrentPosL++") + ";"); + println(" }"); + println(" }"); + } + + private void emitHeader() { + println("/* The following code was generated by JFlex "+Main.version+" on "+date+" */"); + println(""); + } + + private void emitUserCode() { + if ( scanner.userCode.length() > 0 ) + println(scanner.userCode.toString()); + } + + private void emitClassName() { + if (!endsWithJavadoc(scanner.userCode)) { + String path = inputFile.toString(); + // slashify path (avoid backslash u sequence = unicode escape) + if (File.separatorChar != '/') { + path = path.replace(File.separatorChar, '/'); + } + + println("/**"); + println(" * This class is a scanner generated by "); + println(" *
JFlex "+Main.version); + println(" * on "+date+" from the specification file"); + println(" * "+path+""); + println(" */"); + } + + if ( scanner.isPublic ) print("public "); + + if ( scanner.isAbstract) print("abstract "); + + if ( scanner.isFinal ) print("final "); + + print("class "); + print(scanner.className); + + if ( scanner.isExtending != null ) { + print(" extends "); + print(scanner.isExtending); + } + + if ( scanner.isImplementing != null ) { + print(" implements "); + print(scanner.isImplementing); + } + + println(" {"); + } + + /** + * Try to find out if user code ends with a javadoc comment + * + * @param buffer the user code + * @return true if it ends with a javadoc comment + */ + public static boolean endsWithJavadoc(StringBuffer usercode) { + String s = usercode.toString().trim(); + + if (!s.endsWith("*/")) return false; + + // find beginning of javadoc comment + int i = s.lastIndexOf("/**"); + if (i < 0) return false; + + // javadoc comment shouldn't contain a comment end + return s.substring(i,s.length()-2).indexOf("*/") < 0; + } + + + private void emitLexicalStates() { + Enumeration stateNames = scanner.states.names(); + + while ( stateNames.hasMoreElements() ) { + String name = (String) stateNames.nextElement(); + + int num = scanner.states.getNumber(name).intValue(); + + if (scanner.bolUsed) + println(" "+visibility+" static final int "+name+" = "+2*num+";"); + else + println(" "+visibility+" static final int "+name+" = "+dfa.lexState[2*num]+";"); + } + + if (scanner.bolUsed) { + println(""); + println(" /**"); + println(" * ZZ_LEXSTATE[l] is the state in the DFA for the lexical state l"); + println(" * ZZ_LEXSTATE[l+1] is the state in the DFA for the lexical state l"); + println(" * at the beginning of a line"); + println(" * l is of the form l = 2*k, k a non negative integer"); + println(" */"); + println(" private static final int ZZ_LEXSTATE[] = { "); + + int i, j = 0; + print(" "); + + for (i = 0; i < dfa.lexState.length-1; i++) { + print( dfa.lexState[i], 2 ); + + print(", "); + + if (++j >= 16) { + println(); + print(" "); + j = 0; + } + } + + println( dfa.lexState[i] ); + println(" };"); + + } + } + + private void emitDynamicInit() { + int count = 0; + int value = dfa.table[0][0]; + + println(" /** "); + println(" * The transition table of the DFA"); + println(" */"); + + CountEmitter e = new CountEmitter("Trans"); + e.setValTranslation(+1); // allow vals in [-1, 0xFFFE] + e.emitInit(); + + for (int i = 0; i < dfa.numStates; i++) { + if ( !rowKilled[i] ) { + for (int c = 0; c < dfa.numInput; c++) { + if ( !colKilled[c] ) { + if (dfa.table[i][c] == value) { + count++; + } + else { + e.emit(count, value); + + count = 1; + value = dfa.table[i][c]; + } + } + } + } + } + + e.emit(count, value); + e.emitUnpack(); + + println(e.toString()); + } + + + private void emitCharMapInitFunction() { + + CharClasses cl = parser.getCharClasses(); + + if ( cl.getMaxCharCode() < 256 ) return; + + println(""); + println(" /** "); + println(" * Unpacks the compressed character translation table."); + println(" *"); + println(" * @param packed the packed character translation table"); + println(" * @return the unpacked character translation table"); + println(" */"); + println(" private static char [] zzUnpackCMap(String packed) {"); + println(" char [] map = new char[0x10000];"); + println(" int i = 0; /* index in packed string */"); + println(" int j = 0; /* index in unpacked array */"); + println(" while (i < "+2*intervalls.length+") {"); + println(" int count = packed.charAt(i++);"); + println(" char value = packed.charAt(i++);"); + println(" do map[j++] = value; while (--count > 0);"); + println(" }"); + println(" return map;"); + println(" }"); + } + + private void emitZZTrans() { + + int i,c; + int n = 0; + + println(" /** "); + println(" * The transition table of the DFA"); + println(" */"); + println(" private static final int ZZ_TRANS [] = {"); //XXX + + print(" "); + for (i = 0; i < dfa.numStates; i++) { + + if ( !rowKilled[i] ) { + for (c = 0; c < dfa.numInput; c++) { + if ( !colKilled[c] ) { + if (n >= 10) { + println(); + print(" "); + n = 0; + } + print( dfa.table[i][c] ); + if (i != dfa.numStates-1 || c != dfa.numInput-1) + print( ", "); + n++; + } + } + } + } + + println(); + println(" };"); + } + + private void emitCharMapArrayUnPacked() { + + CharClasses cl = parser.getCharClasses(); + intervalls = cl.getIntervalls(); + + println(""); + println(" /** "); + println(" * Translates characters to character classes"); + println(" */"); + println(" private static final char [] ZZ_CMAP = {"); + + int n = 0; // numbers of entries in current line + print(" "); + + int max = cl.getMaxCharCode(); + int i = 0; + while ( i < intervalls.length && intervalls[i].start <= max ) { + + int end = Math.min(intervalls[i].end, max); + for (int c = intervalls[i].start; c <= end; c++) { + + print(colMap[intervalls[i].charClass], 2); + + if (c < max) { + print(", "); + if ( ++n >= 16 ) { + println(); + print(" "); + n = 0; + } + } + } + + i++; + } + + println(); + println(" };"); + println(); + } + + private void emitCharMapArray() { + CharClasses cl = parser.getCharClasses(); + + if ( cl.getMaxCharCode() < 256 ) { + emitCharMapArrayUnPacked(); + return; + } + + // ignores cl.getMaxCharCode(), emits all intervalls instead + + intervalls = cl.getIntervalls(); + + println(""); + println(" /** "); + println(" * Translates characters to character classes"); + println(" */"); + println(" private static final String ZZ_CMAP_PACKED = "); + + int n = 0; // numbers of entries in current line + print(" \""); + + int i = 0; + while ( i < intervalls.length-1 ) { + int count = intervalls[i].end-intervalls[i].start+1; + int value = colMap[intervalls[i].charClass]; + + printUC(count); + printUC(value); + + if ( ++n >= 10 ) { + println("\"+"); + print(" \""); + n = 0; + } + + i++; + } + + printUC(intervalls[i].end-intervalls[i].start+1); + printUC(colMap[intervalls[i].charClass]); + + println("\";"); + println(); + + println(" /** "); + println(" * Translates characters to character classes"); + println(" */"); + println(" private static final char [] ZZ_CMAP = zzUnpackCMap(ZZ_CMAP_PACKED);"); + println(); + } + + + /** + * Print number as octal/unicode escaped string character. + * + * @param c the value to print + * @prec 0 <= c <= 0xFFFF + */ + private void printUC(int c) { + if (c > 255) { + out.print("\\u"); + if (c < 0x1000) out.print("0"); + out.print(Integer.toHexString(c)); + } + else { + out.print("\\"); + out.print(Integer.toOctalString(c)); + } + } + + + private void emitRowMapArray() { + println(""); + println(" /** "); + println(" * Translates a state to a row index in the transition table"); + println(" */"); + + HiLowEmitter e = new HiLowEmitter("RowMap"); + e.emitInit(); + for (int i = 0; i < dfa.numStates; i++) { + e.emit(rowMap[i]*numCols); + } + e.emitUnpack(); + println(e.toString()); + } + + + private void emitAttributes() { + println(" /**"); + println(" * ZZ_ATTRIBUTE[aState] contains the attributes of state aState"); + println(" */"); + + CountEmitter e = new CountEmitter("Attribute"); + e.emitInit(); + + int count = 1; + int value = 0; + if ( dfa.isFinal[0] ) value = FINAL; + if ( dfa.isPushback[0] ) value|= PUSHBACK; + if ( dfa.isLookEnd[0] ) value|= LOOKEND; + if ( !isTransition[0] ) value|= NOLOOK; + + for (int i = 1; i < dfa.numStates; i++) { + int attribute = 0; + if ( dfa.isFinal[i] ) attribute = FINAL; + if ( dfa.isPushback[i] ) attribute|= PUSHBACK; + if ( dfa.isLookEnd[i] ) attribute|= LOOKEND; + if ( !isTransition[i] ) attribute|= NOLOOK; + + if (value == attribute) { + count++; + } + else { + e.emit(count, value); + count = 1; + value = attribute; + } + } + + e.emit(count, value); + e.emitUnpack(); + + println(e.toString()); + } + + + private void emitClassCode() { + if ( scanner.eofCode != null ) { + println(" /** denotes if the user-EOF-code has already been executed */"); + println(" private boolean zzEOFDone;"); + println(""); + } + + if ( scanner.classCode != null ) { + println(" /* user code: */"); + println(scanner.classCode); + } + } + + private void emitConstructorDecl() { + + print(" "); + + if ( scanner.isPublic ) print("public "); + print( scanner.className ); + print("(java.io.Reader in)"); + + if ( scanner.initThrow != null ) { + print(" throws "); + print( scanner.initThrow ); + } + + println(" {"); + + if ( scanner.initCode != null ) { + print(" "); + print( scanner.initCode ); + } + + println(" this.zzReader = in;"); + + println(" }"); + println(); + + + println(" /**"); + println(" * Creates a new scanner."); + println(" * There is also java.io.Reader version of this constructor."); + println(" *"); + println(" * @param in the java.io.Inputstream to read input from."); + println(" */"); + + print(" "); + if ( scanner.isPublic ) print("public "); + print( scanner.className ); + print("(java.io.InputStream in)"); + + if ( scanner.initThrow != null ) { + print(" throws "); + print( scanner.initThrow ); + } + + println(" {"); + println(" this(new java.io.InputStreamReader(in));"); + println(" }"); + } + + + private void emitDoEOF() { + if ( scanner.eofCode == null ) return; + + println(" /**"); + println(" * Contains user EOF-code, which will be executed exactly once,"); + println(" * when the end of file is reached"); + println(" */"); + + print(" private void zzDoEOF()"); + + if ( scanner.eofThrow != null ) { + print(" throws "); + print(scanner.eofThrow); + } + + println(" {"); + + println(" if (!zzEOFDone) {"); + println(" zzEOFDone = true;"); + println(" "+scanner.eofCode ); + println(" }"); + println(" }"); + println(""); + println(""); + } + + private void emitLexFunctHeader() { + + if (scanner.cupCompatible) { + // force public, because we have to implement java_cup.runtime.Symbol + print(" public "); + } + else { + print(" "+visibility+" "); + } + + if ( scanner.tokenType == null ) { + if ( scanner.isInteger ) + print( "int" ); + else + if ( scanner.isIntWrap ) + print( "Integer" ); + else + print( "Yytoken" ); + } + else + print( scanner.tokenType ); + + print(" "); + + print(scanner.functionName); + + print("() throws java.io.IOException"); + + if ( scanner.lexThrow != null ) { + print(", "); + print(scanner.lexThrow); + } + + if ( scanner.scanErrorException != null ) { + print(", "); + print(scanner.scanErrorException); + } + + println(" {"); + + skel.emitNext(); + + if ( scanner.useRowMap ) { + println(" int [] zzTransL = ZZ_TRANS;"); + println(" int [] zzRowMapL = ZZ_ROWMAP;"); + println(" int [] zzAttrL = ZZ_ATTRIBUTE;"); + + } + + if ( scanner.lookAheadUsed ) { + println(" int zzPushbackPosL = zzPushbackPos = -1;"); + println(" boolean zzWasPushback;"); + } + + skel.emitNext(); + + if ( scanner.charCount ) { + println(" yychar+= zzMarkedPosL-zzStartRead;"); + println(""); + } + + if ( scanner.lineCount || scanner.columnCount ) { + println(" boolean zzR = false;"); + println(" for (zzCurrentPosL = zzStartRead; zzCurrentPosL < zzMarkedPosL;"); + println(" zzCurrentPosL++) {"); + println(" switch (" + zzBufferLAccess("zzCurrentPosL") + ") {"); + println(" case '\\u000B':"); + println(" case '\\u000C':"); + println(" case '\\u0085':"); + println(" case '\\u2028':"); + println(" case '\\u2029':"); + if ( scanner.lineCount ) + println(" yyline++;"); + if ( scanner.columnCount ) + println(" yycolumn = 0;"); + println(" zzR = false;"); + println(" break;"); + println(" case '\\r':"); + if ( scanner.lineCount ) + println(" yyline++;"); + if ( scanner.columnCount ) + println(" yycolumn = 0;"); + println(" zzR = true;"); + println(" break;"); + println(" case '\\n':"); + println(" if (zzR)"); + println(" zzR = false;"); + println(" else {"); + if ( scanner.lineCount ) + println(" yyline++;"); + if ( scanner.columnCount ) + println(" yycolumn = 0;"); + println(" }"); + println(" break;"); + println(" default:"); + println(" zzR = false;"); + if ( scanner.columnCount ) + println(" yycolumn++;"); + println(" }"); + println(" }"); + println(); + + if ( scanner.lineCount ) { + println(" if (zzR) {"); + println(" // peek one character ahead if it is \\n (if we have counted one line too much)"); + println(" boolean zzPeek;"); + println(" if (zzMarkedPosL < zzEndReadL)"); + println(" zzPeek = " + zzBufferLAccess("zzMarkedPosL") + " == '\\n';"); + println(" else if (zzAtEOF)"); + println(" zzPeek = false;"); + println(" else {"); + println(" boolean eof = zzRefill();"); + println(" zzEndReadL = zzEndRead;"); + println(" zzMarkedPosL = zzMarkedPos;"); + println(" zzBufferL = zzBuffer;"); + println(" if (eof) "); + println(" zzPeek = false;"); + println(" else "); + println(" zzPeek = " + zzBufferLAccess("zzMarkedPosL") + " == '\\n';"); + println(" }"); + println(" if (zzPeek) yyline--;"); + println(" }"); + } + } + + if ( scanner.bolUsed ) { + // zzMarkedPos > zzStartRead <=> last match was not empty + // if match was empty, last value of zzAtBOL can be used + // zzStartRead is always >= 0 + println(" if (zzMarkedPosL > zzStartRead) {"); + println(" switch (" + zzBufferLAccess("zzMarkedPosL-1") + ") {"); + println(" case '\\n':"); + println(" case '\\u000B':"); + println(" case '\\u000C':"); + println(" case '\\u0085':"); + println(" case '\\u2028':"); + println(" case '\\u2029':"); + println(" zzAtBOL = true;"); + println(" break;"); + println(" case '\\r': "); + println(" if (zzMarkedPosL < zzEndReadL)"); + println(" zzAtBOL = " + zzBufferLAccess("zzMarkedPosL") + " != '\\n';"); + println(" else if (zzAtEOF)"); + println(" zzAtBOL = false;"); + println(" else {"); + println(" boolean eof = zzRefill();"); + println(" zzMarkedPosL = zzMarkedPos;"); + println(" zzEndReadL = zzEndRead;"); + println(" zzBufferL = zzBuffer;"); + println(" if (eof) "); + println(" zzAtBOL = false;"); + println(" else "); + println(" zzAtBOL = " + zzBufferLAccess("zzMarkedPosL") + " != '\\n';"); + println(" }"); + println(" break;"); + println(" default:"); + println(" zzAtBOL = false;"); + println(" }"); + println(" }"); + } + + skel.emitNext(); + + if (scanner.bolUsed) { + println(" if (zzAtBOL)"); + println(" zzState = ZZ_LEXSTATE[zzLexicalState+1];"); + println(" else"); + println(" zzState = ZZ_LEXSTATE[zzLexicalState];"); + println(); + } + else { + println(" zzState = zzLexicalState;"); + println(); + } + + if (scanner.lookAheadUsed) + println(" zzWasPushback = false;"); + + skel.emitNext(); + } + + + private void emitGetRowMapNext() { + println(" int zzNext = zzTransL[ zzRowMapL[zzState] + zzCMapL[zzInput] ];"); + println(" if (zzNext == "+DFA.NO_TARGET+") break zzForAction;"); + println(" zzState = zzNext;"); + println(); + + println(" int zzAttributes = zzAttrL[zzState];"); + + if ( scanner.lookAheadUsed ) { + println(" if ( (zzAttributes & "+PUSHBACK+") == "+PUSHBACK+" )"); + println(" zzPushbackPosL = zzCurrentPosL;"); + println(); + } + + println(" if ( (zzAttributes & "+FINAL+") == "+FINAL+" ) {"); + if ( scanner.lookAheadUsed ) + println(" zzWasPushback = (zzAttributes & "+LOOKEND+") == "+LOOKEND+";"); + + skel.emitNext(); + + println(" if ( (zzAttributes & "+NOLOOK+") == "+NOLOOK+" ) break zzForAction;"); + + skel.emitNext(); + } + + private void emitTransitionTable() { + transformTransitionTable(); + + println(" zzInput = zzCMapL[zzInput];"); + println(); + + if ( scanner.lookAheadUsed ) + println(" boolean zzPushback = false;"); + + println(" boolean zzIsFinal = false;"); + println(" boolean zzNoLookAhead = false;"); + println(); + + println(" zzForNext: { switch (zzState) {"); + + for (int state = 0; state < dfa.numStates; state++) + if (isTransition[state]) emitState(state); + + println(" default:"); + println(" // if this is ever reached, there is a serious bug in JFlex"); + println(" zzScanError(ZZ_UNKNOWN_ERROR);"); + println(" break;"); + println(" } }"); + println(); + + println(" if ( zzIsFinal ) {"); + + if ( scanner.lookAheadUsed ) + println(" zzWasPushback = zzPushback;"); + + skel.emitNext(); + + println(" if ( zzNoLookAhead ) break zzForAction;"); + + skel.emitNext(); + } + + + /** + * Escapes all " ' \ tabs and newlines + */ + private String escapify(String s) { + StringBuffer result = new StringBuffer(s.length()*2); + + for (int i = 0; i < s.length(); i++) { + char c = s.charAt(i); + switch (c) { + case '\'': result.append("\\\'"); break; + case '\"': result.append("\\\""); break; + case '\\': result.append("\\\\"); break; + case '\t': result.append("\\t"); break; + case '\r': if (i+1 == s.length() || s.charAt(i+1) != '\n') result.append("\"+ZZ_NL+\""); + break; + case '\n': result.append("\"+ZZ_NL+\""); break; + default: result.append(c); + } + } + + return result.toString(); + } + + public void emitActionTable() { + int lastAction = 1; + int count = 0; + int value = 0; + + println(" /** "); + println(" * Translates DFA states to action switch labels."); + println(" */"); + CountEmitter e = new CountEmitter("Action"); + e.emitInit(); + + for (int i = 0; i < dfa.numStates; i++) { + int newVal; + if ( dfa.isFinal[i] ) { + Action action = dfa.action[i]; + Integer stored = (Integer) actionTable.get(action); + if ( stored == null ) { + stored = new Integer(lastAction++); + actionTable.put(action, stored); + } + newVal = stored.intValue(); + } + else { + newVal = 0; + } + + if (value == newVal) { + count++; + } + else { + if (count > 0) e.emit(count,value); + count = 1; + value = newVal; + } + } + + if (count > 0) e.emit(count,value); + + e.emitUnpack(); + println(e.toString()); + } + + private void emitActions() { + println(" switch (zzAction < 0 ? zzAction : ZZ_ACTION[zzAction]) {"); + + int i = actionTable.size()+1; + Enumeration actions = actionTable.keys(); + while ( actions.hasMoreElements() ) { + Action action = (Action) actions.nextElement(); + int label = ((Integer) actionTable.get(action)).intValue(); + + println(" case "+label+": "); + + if ( scanner.debugOption ) { + print(" System.out.println("); + if ( scanner.lineCount ) + print("\"line: \"+(yyline+1)+\" \"+"); + if ( scanner.columnCount ) + print("\"col: \"+(yycolumn+1)+\" \"+"); + println("\"match: --\"+yytext()+\"--\");"); + print(" System.out.println(\"action ["+action.priority+"] { "); + print(escapify(action.content)); + println(" }\");"); + } + + println(" { "+action.content); + println(" }"); + println(" case "+(i++)+": break;"); + } + } + + private void emitEOFVal() { + EOFActions eofActions = parser.getEOFActions(); + + if ( scanner.eofCode != null ) + println(" zzDoEOF();"); + + if ( eofActions.numActions() > 0 ) { + println(" switch (zzLexicalState) {"); + + Enumeration stateNames = scanner.states.names(); + + // record lex states already emitted: + Hashtable used = new Hashtable(); + + // pick a start value for break case labels. + // must be larger than any value of a lex state: + int last = dfa.numStates; + + while ( stateNames.hasMoreElements() ) { + String name = (String) stateNames.nextElement(); + int num = scanner.states.getNumber(name).intValue(); + Action action = eofActions.getAction(num); + + // only emit code if the lex state is not redundant, so + // that case labels don't overlap + // (redundant = points to the same dfa state as another one). + // applies only to scanners that don't use BOL, because + // in BOL scanners lex states get mapped at runtime, so + // case labels will always be unique. + boolean unused = true; + if (!scanner.bolUsed) { + Integer key = new Integer(dfa.lexState[2*num]); + unused = used.get(key) == null; + + if (!unused) + Out.warning("Lexical states <"+name+"> and <"+used.get(key)+"> are equivalent."); + else + used.put(key,name); + } + + if (action != null && unused) { + println(" case "+name+": {"); + if ( scanner.debugOption ) { + print(" System.out.println("); + if ( scanner.lineCount ) + print("\"line: \"+(yyline+1)+\" \"+"); + if ( scanner.columnCount ) + print("\"col: \"+(yycolumn+1)+\" \"+"); + println("\"match: <>\");"); + print(" System.out.println(\"action ["+action.priority+"] { "); + print(escapify(action.content)); + println(" }\");"); + } + println(" "+action.content); + println(" }"); + println(" case "+(++last)+": break;"); + } + } + + println(" default:"); + } + + Action defaultAction = eofActions.getDefault(); + + if (defaultAction != null) { + println(" {"); + if ( scanner.debugOption ) { + print(" System.out.println("); + if ( scanner.lineCount ) + print("\"line: \"+(yyline+1)+\" \"+"); + if ( scanner.columnCount ) + print("\"col: \"+(yycolumn+1)+\" \"+"); + println("\"match: <>\");"); + print(" System.out.println(\"action ["+defaultAction.priority+"] { "); + print(escapify(defaultAction.content)); + println(" }\");"); + } + println(" " + defaultAction.content); + println(" }"); + } + else if ( scanner.eofVal != null ) + println(" { " + scanner.eofVal + " }"); + else if ( scanner.isInteger ) + println(" return YYEOF;"); + else + println(" return null;"); + + if (eofActions.numActions() > 0) + println(" }"); + } + + private void emitState(int state) { + + println(" case "+state+":"); + println(" switch (zzInput) {"); + + int defaultTransition = getDefaultTransition(state); + + for (int next = 0; next < dfa.numStates; next++) { + + if ( next != defaultTransition && table[state][next] != null ) { + emitTransition(state, next); + } + } + + if ( defaultTransition != DFA.NO_TARGET && noTarget[state] != null ) { + emitTransition(state, DFA.NO_TARGET); + } + + emitDefaultTransition(state, defaultTransition); + + println(" }"); + println(""); + } + + private void emitTransition(int state, int nextState) { + + CharSetEnumerator chars; + + if (nextState != DFA.NO_TARGET) + chars = table[state][nextState].characters(); + else + chars = noTarget[state].characters(); + + print(" case "); + print((int)chars.nextElement()); + print(": "); + + while ( chars.hasMoreElements() ) { + println(); + print(" case "); + print((int)chars.nextElement()); + print(": "); + } + + if ( nextState != DFA.NO_TARGET ) { + if ( dfa.isFinal[nextState] ) + print("zzIsFinal = true; "); + + if ( dfa.isPushback[nextState] ) + print("zzPushbackPosL = zzCurrentPosL; "); + + if ( dfa.isLookEnd[nextState] ) + print("zzPushback = true; "); + + if ( !isTransition[nextState] ) + print("zzNoLookAhead = true; "); + + if ( nextState == state ) + println("break zzForNext;"); + else + println("zzState = "+nextState+"; break zzForNext;"); + } + else + println("break zzForAction;"); + } + + private void emitDefaultTransition(int state, int nextState) { + print(" default: "); + + if ( nextState != DFA.NO_TARGET ) { + if ( dfa.isFinal[nextState] ) + print("zzIsFinal = true; "); + + if ( dfa.isPushback[nextState] ) + print("zzPushbackPosL = zzCurrentPosL; "); + + if ( dfa.isLookEnd[nextState] ) + print("zzPushback = true; "); + + if ( !isTransition[nextState] ) + print("zzNoLookAhead = true; "); + + if ( nextState == state ) + println("break zzForNext;"); + else + println("zzState = "+nextState+"; break zzForNext;"); + } + else + println( "break zzForAction;" ); + } + + private void emitPushback() { + println(" if (zzWasPushback)"); + println(" zzMarkedPos = zzPushbackPosL;"); + } + + private int getDefaultTransition(int state) { + int max = 0; + + for (int i = 0; i < dfa.numStates; i++) { + if ( table[state][max] == null ) + max = i; + else + if ( table[state][i] != null && table[state][max].size() < table[state][i].size() ) + max = i; + } + + if ( table[state][max] == null ) return DFA.NO_TARGET; + if ( noTarget[state] == null ) return max; + + if ( table[state][max].size() < noTarget[state].size() ) + max = DFA.NO_TARGET; + + return max; + } + + // for switch statement: + private void transformTransitionTable() { + + int numInput = parser.getCharClasses().getNumClasses()+1; + + int i; + char j; + + table = new CharSet[dfa.numStates][dfa.numStates]; + noTarget = new CharSet[dfa.numStates]; + + for (i = 0; i < dfa.numStates; i++) + for (j = 0; j < dfa.numInput; j++) { + + int nextState = dfa.table[i][j]; + + if ( nextState == DFA.NO_TARGET ) { + if ( noTarget[i] == null ) + noTarget[i] = new CharSet(numInput, colMap[j]); + else + noTarget[i].add(colMap[j]); + } + else { + if ( table[i][nextState] == null ) + table[i][nextState] = new CharSet(numInput, colMap[j]); + else + table[i][nextState].add(colMap[j]); + } + } + } + + private void findActionStates() { + isTransition = new boolean [dfa.numStates]; + + for (int i = 0; i < dfa.numStates; i++) { + char j = 0; + while ( !isTransition[i] && j < dfa.numInput ) + isTransition[i] = dfa.table[i][j++] != DFA.NO_TARGET; + } + } + + + private void reduceColumns() { + colMap = new int [dfa.numInput]; + colKilled = new boolean [dfa.numInput]; + + int i,j,k; + int translate = 0; + boolean equal; + + numCols = dfa.numInput; + + for (i = 0; i < dfa.numInput; i++) { + + colMap[i] = i-translate; + + for (j = 0; j < i; j++) { + + // test for equality: + k = -1; + equal = true; + while (equal && ++k < dfa.numStates) + equal = dfa.table[k][i] == dfa.table[k][j]; + + if (equal) { + translate++; + colMap[i] = colMap[j]; + colKilled[i] = true; + numCols--; + break; + } // if + } // for j + } // for i + } + + private void reduceRows() { + rowMap = new int [dfa.numStates]; + rowKilled = new boolean [dfa.numStates]; + + int i,j,k; + int translate = 0; + boolean equal; + + numRows = dfa.numStates; + + // i is the state to add to the new table + for (i = 0; i < dfa.numStates; i++) { + + rowMap[i] = i-translate; + + // check if state i can be removed (i.e. already + // exists in entries 0..i-1) + for (j = 0; j < i; j++) { + + // test for equality: + k = -1; + equal = true; + while (equal && ++k < dfa.numInput) + equal = dfa.table[i][k] == dfa.table[j][k]; + + if (equal) { + translate++; + rowMap[i] = rowMap[j]; + rowKilled[i] = true; + numRows--; + break; + } // if + } // for j + } // for i + + } + + + /** + * Set up EOF code sectioin according to scanner.eofcode + */ + private void setupEOFCode() { + if (scanner.eofclose) { + scanner.eofCode = LexScan.conc(scanner.eofCode, " yyclose();"); + scanner.eofThrow = LexScan.concExc(scanner.eofThrow, "java.io.IOException"); + } + } + + + /** + * Main Emitter method. + */ + public void emit() { + + setupEOFCode(); + + if (scanner.functionName == null) + scanner.functionName = "yylex"; + + reduceColumns(); + findActionStates(); + + emitHeader(); + emitUserCode(); + emitClassName(); + + skel.emitNext(); + + println(" private static final int ZZ_BUFFERSIZE = "+scanner.bufferSize+";"); + + if (scanner.debugOption) { + println(" private static final String ZZ_NL = System.getProperty(\"line.separator\");"); + } + + skel.emitNext(); + + emitLexicalStates(); + + emitCharMapArray(); + + emitActionTable(); + + if (scanner.useRowMap) { + reduceRows(); + + emitRowMapArray(); + + if (scanner.packed) + emitDynamicInit(); + else + emitZZTrans(); + } + + skel.emitNext(); + + if (scanner.useRowMap) + emitAttributes(); + + skel.emitNext(); + + emitClassCode(); + + skel.emitNext(); + + emitConstructorDecl(); + + emitCharMapInitFunction(); + + skel.emitNext(); + + emitScanError(); + + skel.emitNext(); + + emitDoEOF(); + + skel.emitNext(); + + emitLexFunctHeader(); + + emitNextInput(); + + if (scanner.useRowMap) + emitGetRowMapNext(); + else + emitTransitionTable(); + + if (scanner.lookAheadUsed) + emitPushback(); + + skel.emitNext(); + + emitActions(); + + skel.emitNext(); + + emitEOFVal(); + + skel.emitNext(); + + emitNoMatch(); + + skel.emitNext(); + + emitMain(); + + skel.emitNext(); + + out.close(); + } + +} diff --git a/tools/lexer/jflex-1.4/src/JFlex/ErrorMessages.java b/tools/lexer/jflex-1.4/src/JFlex/ErrorMessages.java new file mode 100644 index 000000000000..11da2770865c --- /dev/null +++ b/tools/lexer/jflex-1.4/src/JFlex/ErrorMessages.java @@ -0,0 +1,140 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * JFlex 1.4.1 * + * Copyright (C) 1998-2004 Gerwin Klein * + * All rights reserved. * + * * + * This program is free software); you can redistribute it and/or modify * + * it under the terms of the GNU General Public License. See the file * + * COPYRIGHT for more information. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY); without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License along * + * with this program); if not, write to the Free Software Foundation, Inc., * + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +package JFlex; + +import java.text.MessageFormat; +import java.util.MissingResourceException; +import java.util.ResourceBundle; + + +/** + * Central class for all kinds of JFlex messages. + * + * [Is not yet used exclusively, but should] + * + * @author Gerwin Klein + * @version JFlex 1.4.1, $Revision: 2.8 $, $Date: 2004/11/06 23:03:30 $ + */ +public class ErrorMessages { + private String key; + + private static final ResourceBundle RESOURCE_BUNDLE = + ResourceBundle.getBundle("JFlex.Messages"); + + private ErrorMessages(String key) { + this.key = key; + } + + public static String get(ErrorMessages msg) { + try { + return RESOURCE_BUNDLE.getString(msg.key); + } catch (MissingResourceException e) { + return '!' + msg.key + '!'; + } + } + + public static String get(ErrorMessages msg, String data) { + Object [] args = { data }; + return MessageFormat.format(get(msg),args); + } + + public static String get(ErrorMessages msg, String data1, String data2) { + Object [] args = { data1, data2 }; + return MessageFormat.format(get(msg),args); + } + + public static String get(ErrorMessages msg, int data) { + Object [] args = { new Integer(data) }; + return MessageFormat.format(get(msg),args); + } + + // typesafe enumeration (generated, do not edit) + public static ErrorMessages UNTERMINATED_STR = new ErrorMessages("UNTERMINATED_STR"); + public static ErrorMessages EOF_WO_ACTION = new ErrorMessages("EOF_WO_ACTION"); + public static ErrorMessages EOF_SINGLERULE = new ErrorMessages("EOF_SINGLERULE"); + public static ErrorMessages UNKNOWN_OPTION = new ErrorMessages("UNKNOWN_OPTION"); + public static ErrorMessages UNEXPECTED_CHAR = new ErrorMessages("UNEXPECTED_CHAR"); + public static ErrorMessages UNEXPECTED_NL = new ErrorMessages("UNEXPECTED_NL"); + public static ErrorMessages LEXSTATE_UNDECL = new ErrorMessages("LEXSTATE_UNDECL"); + public static ErrorMessages STATE_IDENT_EXP = new ErrorMessages("STATE_IDENT_EXP"); + public static ErrorMessages REPEAT_ZERO = new ErrorMessages("REPEAT_ZERO"); + public static ErrorMessages REPEAT_GREATER = new ErrorMessages("REPEAT_GREATER"); + public static ErrorMessages REGEXP_EXPECTED = new ErrorMessages("REGEXP_EXPECTED"); + public static ErrorMessages MACRO_UNDECL = new ErrorMessages("MACRO_UNDECL"); + public static ErrorMessages CHARSET_2_SMALL = new ErrorMessages("CHARSET_2_SMALL"); + public static ErrorMessages CS2SMALL_STRING = new ErrorMessages("CS2SMALL_STRING"); + public static ErrorMessages CS2SMALL_CHAR = new ErrorMessages("CS2SMALL_CHAR"); + public static ErrorMessages CHARCLASS_MACRO = new ErrorMessages("CHARCLASS_MACRO"); + public static ErrorMessages UNKNOWN_SYNTAX = new ErrorMessages("UNKNOWN_SYNTAX"); + public static ErrorMessages SYNTAX_ERROR = new ErrorMessages("SYNTAX_ERROR"); + public static ErrorMessages NOT_AT_BOL = new ErrorMessages("NOT_AT_BOL"); + public static ErrorMessages NO_MATCHING_BR = new ErrorMessages("NO_MATCHING_BR"); + public static ErrorMessages EOF_IN_ACTION = new ErrorMessages("EOF_IN_ACTION"); + public static ErrorMessages EOF_IN_COMMENT = new ErrorMessages("EOF_IN_COMMENT"); + public static ErrorMessages EOF_IN_STRING = new ErrorMessages("EOF_IN_STRING"); + public static ErrorMessages EOF_IN_MACROS = new ErrorMessages("EOF_IN_MACROS"); + public static ErrorMessages EOF_IN_STATES = new ErrorMessages("EOF_IN_STATES"); + public static ErrorMessages EOF_IN_REGEXP = new ErrorMessages("EOF_IN_REGEXP"); + public static ErrorMessages UNEXPECTED_EOF = new ErrorMessages("UNEXPECTED_EOF"); + public static ErrorMessages NO_LEX_SPEC = new ErrorMessages("NO_LEX_SPEC"); + public static ErrorMessages NO_LAST_ACTION = new ErrorMessages("NO_LAST_ACTION"); + public static ErrorMessages LOOKAHEAD_ERROR = new ErrorMessages("LOOKAHEAD_ERROR"); + public static ErrorMessages NO_DIRECTORY = new ErrorMessages("NO_DIRECTORY"); + public static ErrorMessages NO_SKEL_FILE = new ErrorMessages("NO_SKEL_FILE"); + public static ErrorMessages WRONG_SKELETON = new ErrorMessages("WRONG_SKELETON"); + public static ErrorMessages OUT_OF_MEMORY = new ErrorMessages("OUT_OF_MEMORY"); + public static ErrorMessages QUIL_INITTHROW = new ErrorMessages("QUIL_INITTHROW"); + public static ErrorMessages QUIL_EOFTHROW = new ErrorMessages("QUIL_EOFTHROW"); + public static ErrorMessages QUIL_YYLEXTHROW = new ErrorMessages("QUIL_YYLEXTHROW"); + public static ErrorMessages ZERO_STATES = new ErrorMessages("ZERO_STATES"); + public static ErrorMessages NO_BUFFER_SIZE = new ErrorMessages("NO_BUFFER_SIZE"); + public static ErrorMessages NOT_READABLE = new ErrorMessages("NOT_READABLE"); + public static ErrorMessages FILE_CYCLE = new ErrorMessages("FILE_CYCLE"); + public static ErrorMessages FILE_WRITE = new ErrorMessages("FILE_WRITE"); + public static ErrorMessages QUIL_SCANERROR = new ErrorMessages("QUIL_SCANERROR"); + public static ErrorMessages NEVER_MATCH = new ErrorMessages("NEVER_MATCH"); + public static ErrorMessages QUIL_THROW = new ErrorMessages("QUIL_THROW"); + public static ErrorMessages EOL_IN_CHARCLASS = new ErrorMessages("EOL_IN_CHARCLASS"); + public static ErrorMessages QUIL_CUPSYM = new ErrorMessages("QUIL_CUPSYM"); + public static ErrorMessages CUPSYM_AFTER_CUP = new ErrorMessages("CUPSYM_AFTER_CUP"); + public static ErrorMessages ALREADY_RUNNING = new ErrorMessages("ALREADY_RUNNING"); + public static ErrorMessages CANNOT_READ_SKEL = new ErrorMessages("CANNOT_READ_SKEL"); + public static ErrorMessages READING_SKEL = new ErrorMessages("READING_SKEL"); + public static ErrorMessages SKEL_IO_ERROR = new ErrorMessages("SKEL_IO_ERROR"); + public static ErrorMessages SKEL_IO_ERROR_DEFAULT = new ErrorMessages("SKEL_IO_ERROR_DEFAULT"); + public static ErrorMessages READING = new ErrorMessages("READING"); + public static ErrorMessages CANNOT_OPEN = new ErrorMessages("CANNOT_OPEN"); + public static ErrorMessages NFA_IS = new ErrorMessages("NFA_IS"); + public static ErrorMessages NFA_STATES = new ErrorMessages("NFA_STATES"); + public static ErrorMessages DFA_TOOK = new ErrorMessages("DFA_TOOK"); + public static ErrorMessages DFA_IS = new ErrorMessages("DFA_IS"); + public static ErrorMessages MIN_TOOK = new ErrorMessages("MIN_TOOK"); + public static ErrorMessages MIN_DFA_IS = new ErrorMessages("MIN_DFA_IS"); + public static ErrorMessages WRITE_TOOK = new ErrorMessages("WRITE_TOOK"); + public static ErrorMessages TOTAL_TIME = new ErrorMessages("TOTAL_TIME"); + public static ErrorMessages IO_ERROR = new ErrorMessages("IO_ERROR"); + public static ErrorMessages THIS_IS_JFLEX = new ErrorMessages("THIS_IS_JFLEX"); + public static ErrorMessages UNKNOWN_COMMANDLINE = new ErrorMessages("UNKNOWN_COMMANDLINE"); + public static ErrorMessages MACRO_CYCLE = new ErrorMessages("MACRO_CYCLE"); + public static ErrorMessages MACRO_DEF_MISSING = new ErrorMessages("MACRO_DEF_MISSING"); + public static ErrorMessages PARSING_TOOK = new ErrorMessages("PARSING_TOOK"); + public static ErrorMessages NFA_TOOK = new ErrorMessages("NFA_TOOK"); +} \ No newline at end of file diff --git a/tools/lexer/jflex-1.4/src/JFlex/GeneratorException.java b/tools/lexer/jflex-1.4/src/JFlex/GeneratorException.java new file mode 100644 index 000000000000..b4a59e688f85 --- /dev/null +++ b/tools/lexer/jflex-1.4/src/JFlex/GeneratorException.java @@ -0,0 +1,36 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * JFlex 1.4.1 * + * Copyright (C) 1998-2004 Gerwin Klein * + * All rights reserved. * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License. See the file * + * COPYRIGHT for more information. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License along * + * with this program; if not, write to the Free Software Foundation, Inc., * + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +package JFlex; + + +/** + * Thrown when code generation has to be aborted. + * + * @author Gerwin Klein + * @version JFlex 1.4.1, $Revision: 2.2 $, $Date: 2004/11/06 23:03:32 $ + */ +public class GeneratorException extends RuntimeException { + + public GeneratorException() { + super("Generation aborted"); + } + +} diff --git a/tools/lexer/jflex-1.4/src/JFlex/HiLowEmitter.java b/tools/lexer/jflex-1.4/src/JFlex/HiLowEmitter.java new file mode 100644 index 000000000000..450cc2fc241a --- /dev/null +++ b/tools/lexer/jflex-1.4/src/JFlex/HiLowEmitter.java @@ -0,0 +1,88 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * jflex * + * Copyright (C) 1998-2004 Gerwin Klein * + * All rights reserved. * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License. See the file * + * COPYRIGHT for more information. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License along * + * with this program; if not, write to the Free Software Foundation, Inc., * + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +package JFlex; + +/** + * HiLowEmitter + * + * @author Gerwin Klein + * @version $Revision: 1.5 $, $Date: 2004/04/12 10:07:48 $ + */ +public class HiLowEmitter extends PackEmitter { + + /** number of entries in expanded array */ + private int numEntries; + + /** + * Create new emitter for values in [0, 0xFFFFFFFF] using hi/low encoding. + * + * @param name the name of the generated array + */ + public HiLowEmitter(String name) { + super(name); + } + + /** + * Emits hi/low pair unpacking code for the generated array. + * + * @see JFlex.PackEmitter#emitUnPack() + */ + public void emitUnpack() { + // close last string chunk: + println("\";"); + nl(); + println(" private static int [] zzUnpack"+name+"() {"); + println(" int [] result = new int["+numEntries+"];"); + println(" int offset = 0;"); + + for (int i = 0; i < chunks; i++) { + println(" offset = zzUnpack"+name+"("+constName()+"_PACKED_"+i+", offset, result);"); + } + + println(" return result;"); + println(" }"); + + nl(); + println(" private static int zzUnpack"+name+"(String packed, int offset, int [] result) {"); + println(" int i = 0; /* index in packed string */"); + println(" int j = offset; /* index in unpacked array */"); + println(" int l = packed.length();"); + println(" while (i < l) {"); + println(" int high = packed.charAt(i++) << 16;"); + println(" result[j++] = high | packed.charAt(i++);"); + println(" }"); + println(" return j;"); + println(" }"); + } + + /** + * Emit one value using two characters. + * + * @param val the value to emit + * @prec 0 <= val <= 0xFFFFFFFF + */ + public void emit(int val) { + numEntries+= 1; + breaks(); + emitUC(val >> 16); + emitUC(val & 0xFFFF); + } +} diff --git a/tools/lexer/jflex-1.4/src/JFlex/IntCharSet.java b/tools/lexer/jflex-1.4/src/JFlex/IntCharSet.java new file mode 100644 index 000000000000..d05200602cfc --- /dev/null +++ b/tools/lexer/jflex-1.4/src/JFlex/IntCharSet.java @@ -0,0 +1,411 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * JFlex 1.4.1 * + * Copyright (C) 1998-2004 Gerwin Klein * + * All rights reserved. * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License. See the file * + * COPYRIGHT for more information. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License along * + * with this program; if not, write to the Free Software Foundation, Inc., * + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +package JFlex; + +import java.util.Vector; + + +/** + * CharSet implemented with intervalls + * + * [fixme: optimizations possible] + * + * @author Gerwin Klein + * @version JFlex 1.4.1, $Revision: 2.9 $, $Date: 2004/11/07 00:12:48 $ + */ +public final class IntCharSet { + + private final static boolean DEBUG = false; + + /* invariant: all intervals are disjoint, ordered */ + private Vector intervalls; + private int pos; + + public IntCharSet() { + this.intervalls = new Vector(); + } + + public IntCharSet(char c) { + this(new Interval(c,c)); + } + + public IntCharSet(Interval intervall) { + this(); + intervalls.addElement(intervall); + } + + public IntCharSet(Vector /* Interval */ chars) { + int size = chars.size(); + + this.intervalls = new Vector(size); + + for (int i = 0; i < size; i++) + add( (Interval) chars.elementAt(i) ); + } + + + + + /** + * returns the index of the intervall that contains + * the character c, -1 if there is no such intevall + * + * @prec: true + * @post: -1 <= return < intervalls.size() && + * (return > -1 --> intervalls[return].contains(c)) + * + * @param c the character + * @return the index of the enclosing interval, -1 if no such interval + */ + private int indexOf(char c) { + int start = 0; + int end = intervalls.size()-1; + + while (start <= end) { + int check = (start+end) / 2; + Interval i = (Interval) intervalls.elementAt(check); + + if (start == end) + return i.contains(c) ? start : -1; + + if (c < i.start) { + end = check-1; + continue; + } + + if (c > i.end) { + start = check+1; + continue; + } + + return check; + } + + return -1; + } + + public IntCharSet add(IntCharSet set) { + for (int i = 0; i < set.intervalls.size(); i++) + add( (Interval) set.intervalls.elementAt(i) ); + return this; + } + + public void add(Interval intervall) { + + int size = intervalls.size(); + + for (int i = 0; i < size; i++) { + Interval elem = (Interval) intervalls.elementAt(i); + + if ( elem.end+1 < intervall.start ) continue; + + if ( elem.contains(intervall) ) return; + + if ( elem.start > intervall.end+1 ) { + intervalls.insertElementAt(new Interval(intervall), i); + return; + } + + if (intervall.start < elem.start) + elem.start = intervall.start; + + if (intervall.end <= elem.end) + return; + + elem.end = intervall.end; + + i++; + // delete all x with x.contains( intervall.end ) + while (i < size) { + Interval x = (Interval) intervalls.elementAt(i); + if (x.start > elem.end+1) return; + + elem.end = x.end; + intervalls.removeElementAt(i); + size--; + } + return; + } + + intervalls.addElement(new Interval(intervall)); + } + + public void add(char c) { + int size = intervalls.size(); + + for (int i = 0; i < size; i++) { + Interval elem = (Interval) intervalls.elementAt(i); + if (elem.end+1 < c) continue; + + if (elem.contains(c)) return; // already there, nothing to do + + // assert(elem.end+1 >= c && (elem.start > c || elem.end < c)); + + if (elem.start > c+1) { + intervalls.insertElementAt(new Interval(c,c), i); + return; + } + + // assert(elem.end+1 >= c && elem.start <= c+1 && (elem.start > c || elem.end < c)); + + if (c+1 == elem.start) { + elem.start = c; + return; + } + + // assert(elem.end+1 == c); + elem.end = c; + + // merge with next interval if it contains c + if (i+1 >= size) return; + Interval x = (Interval) intervalls.elementAt(i+1); + if (x.start <= c+1) { + elem.end = x.end; + intervalls.removeElementAt(i+1); + } + return; + } + + // end reached but nothing found -> append at end + intervalls.addElement(new Interval(c,c)); + } + + + public boolean contains(char singleChar) { + return indexOf(singleChar) >= 0; + } + + + /** + * o instanceof Interval + */ + public boolean equals(Object o) { + IntCharSet set = (IntCharSet) o; + if ( intervalls.size() != set.intervalls.size() ) return false; + + for (int i = 0; i < intervalls.size(); i++) { + if ( !intervalls.elementAt(i).equals( set.intervalls.elementAt(i)) ) + return false; + } + + return true; + } + + private char min(char a, char b) { + return a <= b ? a : b; + } + + private char max(char a, char b) { + return a >= b ? a : b; + } + + /* intersection */ + public IntCharSet and(IntCharSet set) { + if (DEBUG) { + Out.dump("intersection"); + Out.dump("this : "+this); + Out.dump("other : "+set); + } + + IntCharSet result = new IntCharSet(); + + int i = 0; // index in this.intervalls + int j = 0; // index in set.intervalls + + int size = intervalls.size(); + int setSize = set.intervalls.size(); + + while (i < size && j < setSize) { + Interval x = (Interval) this.intervalls.elementAt(i); + Interval y = (Interval) set.intervalls.elementAt(j); + + if (x.end < y.start) { + i++; + continue; + } + + if (y.end < x.start) { + j++; + continue; + } + + result.intervalls.addElement( + new Interval( + max(x.start, y.start), + min(x.end, y.end) + ) + ); + + if (x.end >= y.end) j++; + if (y.end >= x.end) i++; + } + + if (DEBUG) { + Out.dump("result: "+result); + } + + return result; + } + + /* complement */ + /* prec: this.contains(set), set != null */ + public void sub(IntCharSet set) { + if (DEBUG) { + Out.dump("complement"); + Out.dump("this : "+this); + Out.dump("other : "+set); + } + + int i = 0; // index in this.intervalls + int j = 0; // index in set.intervalls + + int setSize = set.intervalls.size(); + + while (i < intervalls.size() && j < setSize) { + Interval x = (Interval) this.intervalls.elementAt(i); + Interval y = (Interval) set.intervalls.elementAt(j); + + if (DEBUG) { + Out.dump("this : "+this); + Out.dump("this ["+i+"] : "+x); + Out.dump("other ["+j+"] : "+y); + } + + if (x.end < y.start) { + i++; + continue; + } + + if (y.end < x.start) { + j++; + continue; + } + + // x.end >= y.start && y.end >= x.start -> + // x.end <= y.end && x.start >= y.start (prec) + + if ( x.start == y.start && x.end == y.end ) { + intervalls.removeElementAt(i); + j++; + continue; + } + + // x.end <= y.end && x.start >= y.start && + // (x.end < y.end || x.start > y.start) -> + // x.start < x.end + + if ( x.start == y.start ) { + x.start = (char) (y.end+1); + j++; + continue; + } + + if ( x.end == y.end ) { + x.end = (char) (y.start-1); + i++; + j++; + continue; + } + + intervalls.insertElementAt(new Interval(x.start, (char) (y.start-1)), i); + x.start = (char) (y.end+1); + + i++; + j++; + } + + if (DEBUG) { + Out.dump("result: "+this); + } + } + + public boolean containsElements() { + return intervalls.size() > 0; + } + + public int numIntervalls() { + return intervalls.size(); + } + + // beware: depends on caller protocol, single user only + public Interval getNext() { + if (pos == intervalls.size()) pos = 0; + return (Interval) intervalls.elementAt(pos++); + } + + /** + * Create a caseless version of this charset. + *

+ * The caseless version contains all characters of this char set, + * and additionally all lower/upper/title case variants of the + * characters in this set. + * + * @return a caseless copy of this set + */ + public IntCharSet getCaseless() { + IntCharSet n = copy(); + + int size = intervalls.size(); + for (int i=0; i < size; i++) { + Interval elem = (Interval) intervalls.elementAt(i); + for (char c = elem.start; c <= elem.end; c++) { + n.add(Character.toLowerCase(c)); + n.add(Character.toUpperCase(c)); + n.add(Character.toTitleCase(c)); + } + } + + return n; + } + + + /** + * Make a string representation of this char set. + * + * @return a string representing this char set. + */ + public String toString() { + StringBuffer result = new StringBuffer("{ "); + + for (int i = 0; i < intervalls.size(); i++) + result.append( intervalls.elementAt(i) ); + + result.append(" }"); + + return result.toString(); + } + + + /** + * Return a (deep) copy of this char set + * + * @return the copy + */ + public IntCharSet copy() { + IntCharSet result = new IntCharSet(); + int size = intervalls.size(); + for (int i=0; i < size; i++) { + Interval iv = ((Interval) intervalls.elementAt(i)).copy(); + result.intervalls.addElement(iv); + } + return result; + } +} diff --git a/tools/lexer/jflex-1.4/src/JFlex/IntPair.java b/tools/lexer/jflex-1.4/src/JFlex/IntPair.java new file mode 100644 index 000000000000..012eda6960e2 --- /dev/null +++ b/tools/lexer/jflex-1.4/src/JFlex/IntPair.java @@ -0,0 +1,57 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * JFlex 1.4.1 * + * Copyright (C) 1998-2004 Gerwin Klein * + * All rights reserved. * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License. See the file * + * COPYRIGHT for more information. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License along * + * with this program; if not, write to the Free Software Foundation, Inc., * + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +package JFlex; + + +/** + * Simple pair of integers. + * + * Used in NFA to represent a partial NFA by its start and end state. + * + * @author Gerwin Klein + * @version JFlex 1.4.1, $Revision: 2.2 $, $Date: 2004/11/06 23:03:32 $ + */ +final class IntPair { + + int start; + int end; + + IntPair(int start, int end) { + this.start = start; + this.end = end; + } + + public int hashCode() { + return end + (start << 8); + } + + public boolean equals(Object o) { + if ( o instanceof IntPair ) { + IntPair p = (IntPair) o; + return start == p.start && end == p.end; + } + return false; + } + + public String toString() { + return "("+start+","+end+")"; + } +} diff --git a/tools/lexer/jflex-1.4/src/JFlex/Interval.java b/tools/lexer/jflex-1.4/src/JFlex/Interval.java new file mode 100644 index 000000000000..64d30a283335 --- /dev/null +++ b/tools/lexer/jflex-1.4/src/JFlex/Interval.java @@ -0,0 +1,163 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * JFlex 1.4.1 * + * Copyright (C) 1998-2004 Gerwin Klein * + * All rights reserved. * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License. See the file * + * COPYRIGHT for more information. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License along * + * with this program; if not, write to the Free Software Foundation, Inc., * + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +package JFlex; + + +/** + * An intervall of characters with basic operations. + * + * @author Gerwin Klein + * @version JFlex 1.4.1, $Revision: 2.4 $, $Date: 2004/11/06 23:03:30 $ + */ +public final class Interval { + + /* start and end of the intervall */ + public char start, end; + + + /** + * Constuct a new intervall from start to end. + * + * @param start first character the intervall should contain + * @param end last character the intervall should contain + */ + public Interval(char start, char end) { + this.start = start; + this.end = end; + } + + + /** + * Copy constructor + */ + public Interval(Interval other) { + this.start = other.start; + this.end = other.end; + } + + + /** + * Return true iff point is contained in this intervall. + * + * @param point the character to check + */ + public boolean contains(char point) { + return start <= point && end >= point; + } + + + /** + * Return true iff this intervall completely contains the + * other one. + * + * @param other the other intervall + */ + public boolean contains(Interval other) { + return this.start <= other.start && this.end >= other.end; + } + + + /** + * Return true if o is an intervall + * with the same borders. + * + * @param o the object to check equality with + */ + public boolean equals(Object o) { + if ( o == this ) return true; + if ( !(o instanceof Interval) ) return false; + + Interval other = (Interval) o; + return other.start == this.start && other.end == this.end; + } + + + /** + * Set a new last character + * + * @param end the new last character of this intervall + */ + public void setEnd(char end) { + this.end = end; + } + + + /** + * Set a new first character + * + * @param start the new first character of this intervall + */ + public void setStart(char start) { + this.start = start; + } + + + /** + * Check wether a character is printable. + * + * @param c the character to check + */ + private static boolean isPrintable(char c) { + // fixme: should make unicode test here + return c > 31 && c < 127; + } + + + /** + * Get a String representation of this intervall. + * + * @return a string "[start-end]" or + * "[start]" (if there is only one character in + * the intervall) where start and + * end are either a number (the character code) + * or something of the from 'a'. + */ + public String toString() { + StringBuffer result = new StringBuffer("["); + + if ( isPrintable(start) ) + result.append("'"+start+"'"); + else + result.append( (int) start ); + + if (start != end) { + result.append("-"); + + if ( isPrintable(end) ) + result.append("'"+end+"'"); + else + result.append( (int) end ); + } + + result.append("]"); + return result.toString(); + } + + + /** + * Make a copy of this interval. + * + * @return the copy + */ + public Interval copy() { + return new Interval(start,end); + } +} diff --git a/tools/lexer/jflex-1.4/src/JFlex/LexParse.cup b/tools/lexer/jflex-1.4/src/JFlex/LexParse.cup new file mode 100644 index 000000000000..408ed0553914 --- /dev/null +++ b/tools/lexer/jflex-1.4/src/JFlex/LexParse.cup @@ -0,0 +1,632 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * JFlex 1.4.1 * + * Copyright (C) 1998-2004 Gerwin Klein * + * All rights reserved. * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License. See the file * + * COPYRIGHT for more information. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License along * + * with this program; if not, write to the Free Software Foundation, Inc., * + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +package JFlex; + +import java.util.*; + +/* customizing code */ + +action code {: + + LexScan scanner; + CharClasses charClasses = new CharClasses(127); + RegExps regExps = new RegExps(); + Macros macros = new Macros(); + Integer stateNumber; + Timer t = new Timer(); + EOFActions eofActions = new EOFActions(); + + void fatalError(ErrorMessages message, int line, int col) { + syntaxError(message, line, col); + throw new GeneratorException(); + } + + void fatalError(ErrorMessages message) { + fatalError(message, scanner.currentLine(), -1); + throw new GeneratorException(); + } + + void syntaxError(ErrorMessages message) { + Out.error(scanner.file, message, scanner.currentLine(), -1); + } + + void syntaxError(ErrorMessages message, int line) { + Out.error(scanner.file, message, line, -1); + } + + void syntaxError(ErrorMessages message, int line, int col) { + Out.error(scanner.file, message, line, col); + } + + + private boolean check(int type, char c) { + switch (type) { + case sym.JLETTERCLASS: + return Character.isJavaIdentifierStart(c); + + case sym.JLETTERDIGITCLASS: + return Character.isJavaIdentifierPart(c); + + case sym.LETTERCLASS: + return Character.isLetter(c); + + case sym.DIGITCLASS: + return Character.isDigit(c); + + case sym.UPPERCLASS: + return Character.isUpperCase(c); + + case sym.LOWERCLASS: + return Character.isLowerCase(c); + + default: return false; + } + } + + private Vector makePreClass(int type) { + + Vector result = new Vector(); + + char c = 0; + char start = 0; + char last = charClasses.getMaxCharCode(); + + boolean prev, current; + + prev = check(type,'\u0000'); + + for (c = 1; c < last; c++) { + + current = check(type,c); + + if (!prev && current) start = c; + if (prev && !current) { + result.addElement(new Interval(start, (char)(c-1))); + } + + prev = current; + } + + // the last iteration is moved out of the loop to + // avoid an endless loop if last == maxCharCode and + // last+1 == 0 + current = check(type,c); + + if (!prev && current) result.addElement(new Interval(c,c)); + if (prev && current) result.addElement(new Interval(start, c)); + if (prev && !current) result.addElement(new Interval(start, (char)(c-1))); + + return result; + } + + private RegExp makeRepeat(RegExp r, int n1, int n2, int line, int col) { + + if (n1 <= 0 && n2 <= 0) { + syntaxError(ErrorMessages.REPEAT_ZERO, line, col); + return null; + } + + if (n1 > n2) { + syntaxError(ErrorMessages.REPEAT_GREATER, line, col); + return null; + } + + int i; + RegExp result; + + if (n1 > 0) { + result = r; + n1--; n2--; // we need one concatenation less than the number of expressions to match + } + else { + result = new RegExp1(sym.QUESTION,r); + n2--; + } + + for (i = 0; i < n1; i++) + result = new RegExp2(sym.CONCAT, result, r); + + n2-= n1; + for (i = 0; i < n2; i++) + result = new RegExp2(sym.CONCAT, result, new RegExp1(sym.QUESTION,r)); + + return result; + } + + private RegExp makeNL() { + Vector list = new Vector(); + list.addElement(new Interval('\n','\r')); + list.addElement(new Interval('\u0085','\u0085')); + list.addElement(new Interval('\u2028','\u2029')); + + // assumption: line feeds are caseless + charClasses.makeClass(list, false); + charClasses.makeClass('\n', false); + charClasses.makeClass('\r', false); + + RegExp1 c = new RegExp1(sym.CCLASS, list); + Character n = new Character('\n'); + Character r = new Character('\r'); + + return new RegExp2(sym.BAR, + c, + new RegExp2(sym.CONCAT, + new RegExp1(sym.CHAR, r), + new RegExp1(sym.CHAR, n))); + } + +:}; + +parser code {: + public LexScan scanner; + + public LexParse(LexScan scanner) { + super(scanner); + this.scanner = scanner; + } + + public CharClasses getCharClasses() { + return action_obj.charClasses; + } + + public EOFActions getEOFActions() { + return action_obj.eofActions; + } + + public void report_error(String message, Object info) { + if ( info instanceof java_cup.runtime.Symbol ) { + java_cup.runtime.Symbol s = (java_cup.runtime.Symbol) info; + + if (s.sym == sym.EOF) + Out.error(ErrorMessages.UNEXPECTED_EOF); + else + Out.error(scanner.file, ErrorMessages.SYNTAX_ERROR, s.left, s.right); + } + else + Out.error(ErrorMessages.UNKNOWN_SYNTAX); + } + + public void report_fatal_error(String message, Object info) { + // report_error(message, info); + throw new GeneratorException(); + } + +:}; + +init with {: + action_obj.scanner = this.scanner; +:}; + +/* token declarations */ + +terminal OPENBRACKET, CLOSEBRACKET, HAT, DOLLAR, OPENCLASS, + CLOSECLASS, DASH, DELIMITER, EQUALS, COMMA, LESSTHAN, + MORETHAN, LBRACE, RBRACE, FULL, UNICODE, REGEXPEND; + +terminal JLETTERCLASS, JLETTERDIGITCLASS, LETTERCLASS, DIGITCLASS, + UPPERCLASS, LOWERCLASS, EOFRULE, NOACTION, LOOKAHEAD; + +terminal Action ACTION; +terminal String IDENT, USERCODE; +terminal Integer REPEAT; + +/* tokens used in RegExp parse tree */ +terminal STAR, PLUS, BAR, QUESTION, POINT, BANG, TILDE; + +terminal Character CHAR; +terminal String STRING, MACROUSE; + +/* symbols *only* used in the parse tree (not in the grammar) */ +terminal CCLASS, CCLASSNOT, CONCAT; +terminal STRING_I, CHAR_I; /* case insensitive strings/chars */ + + +non terminal macros, macro; +non terminal Integer rule; +non terminal NFA specification; +non terminal RegExp series, concs, nregexp, regexp, charclass, lookaheadOPT; +non terminal Interval classcontentelem; +non terminal Vector states, statesOPT, classcontent, preclass, rules; +non terminal Boolean hatOPT; +non terminal Action actions; + + +/* grammar specification */ +start with specification; + +specification ::= USERCODE + /* delimiter is checked in lexer */ + macros + DELIMITER + rules + {: + scanner.t.stop(); + + Out.checkErrors(); + + Out.time(ErrorMessages.PARSING_TOOK, t); + + macros.expand(); + Enumeration unused = macros.unused(); + while ( unused.hasMoreElements() ) { + Out.warning("Macro \""+unused.nextElement()+"\" has been declared but never used."); + } + + SemCheck.check(regExps, macros, charClasses.getMaxCharCode(), scanner.file); + + regExps.checkActions(); + + if (Options.dump) charClasses.dump(); + + Out.print("Constructing NFA : "); + + t.start(); + int num = regExps.getNum(); + + RESULT = new NFA(charClasses.getNumClasses(), + scanner, regExps, macros, charClasses); + + eofActions.setNumLexStates(scanner.states.number()); + + for (int i = 0; i < num; i++) { + if (regExps.isEOF(i)) + eofActions.add( regExps.getStates(i), regExps.getAction(i) ); + else + RESULT.addRegExp(i); + } + + if (scanner.standalone) RESULT.addStandaloneRule(); + t.stop(); + + Out.time(""); + Out.time(ErrorMessages.NFA_TOOK, t); + + :} + | /* emtpy spec. error */ + {: + fatalError(ErrorMessages.NO_LEX_SPEC); + :} + ; + +macros ::= /* empty, most switches & state declarations are parsed in lexer */ + | macros macro + | error; + +macro ::= FULL + {: charClasses.setMaxCharCode(255); :} + | UNICODE + {: charClasses.setMaxCharCode(0xFFFF); :} + | IDENT:name EQUALS series:definition REGEXPEND + {: macros.insert(name, definition); :} + | IDENT EQUALS:e + {: syntaxError(ErrorMessages.REGEXP_EXPECTED, eleft, eright); :} + ; + + +rules ::= rules:rlist rule:r + {: rlist.addElement(r); RESULT = rlist; :} + | rules:rlist1 LESSTHAN states:states MORETHAN LBRACE rules:rlist2 RBRACE + {: + Enumeration rs = rlist2.elements(); + while ( rs.hasMoreElements() ) { + Integer elem = (Integer) rs.nextElement(); + regExps.addStates( elem.intValue(), states ); + rlist1.addElement( elem ); + } + RESULT = rlist1; + :} + | LESSTHAN states:states MORETHAN LBRACE rules:rlist RBRACE + {: + Enumeration rs = rlist.elements(); + while ( rs.hasMoreElements() ) { + Integer elem = (Integer) rs.nextElement(); + regExps.addStates( elem.intValue(), states ); + } + RESULT = rlist; + :} + | rule:r + {: RESULT = new Vector(); RESULT.addElement(r); :} + ; + +rule ::= statesOPT:s hatOPT:bol series:r lookaheadOPT:l actions:a + {: RESULT = new Integer(regExps.insert(rleft, s, r, a, bol, l)); :} + | statesOPT:s EOFRULE ACTION:a + {: RESULT = new Integer(regExps.insert(s, a)); :} + | error + ; + +lookaheadOPT ::= DOLLAR + {: RESULT = makeNL(); :} + | LOOKAHEAD series:r + {: RESULT = r; :} + | /* empty */ + {: RESULT = null; :} + | LOOKAHEAD series:s DOLLAR + {: RESULT = new RegExp2(sym.CONCAT, s, makeNL()); :} + ; + +actions ::= REGEXPEND ACTION:a + {: RESULT = a; :} + | NOACTION + {: RESULT = null; :} + ; + + +statesOPT ::= LESSTHAN states:list MORETHAN + {: RESULT = list; :} + | /* empty */ + {: RESULT = new Vector(); :} + ; + +states ::= IDENT:id COMMA states:list + {: + stateNumber = scanner.states.getNumber( id ); + if ( stateNumber != null ) + list.addElement( stateNumber ); + else { + throw new ScannerException(scanner.file, ErrorMessages.LEXSTATE_UNDECL, + idleft, idright); + } + RESULT = list; + :} + | IDENT:id + {: + Vector list = new Vector(); + stateNumber = scanner.states.getNumber( id ); + if ( stateNumber != null ) + list.addElement( stateNumber ); + else { + throw new ScannerException(scanner.file, ErrorMessages.LEXSTATE_UNDECL, + idleft, idright); + } + RESULT = list; + :} + | IDENT COMMA:c + {: syntaxError(ErrorMessages.REGEXP_EXPECTED, cleft, cright+1); :} + ; + +hatOPT ::= HAT + {: // assumption: there is no upper case for \n + charClasses.makeClass('\n', false); + RESULT = new Boolean(true); :} + | /* empty */ + {: RESULT = new Boolean(false); :} + ; + +series ::= series:r1 BAR concs:r2 + {: RESULT = new RegExp2(sym.BAR, r1, r2); :} + | concs:r + {: RESULT = r; :} + | BAR:b + {: syntaxError(ErrorMessages.REGEXP_EXPECTED, bleft, bright); :} + ; + +concs ::= concs:r1 nregexp:r2 + {: RESULT = new RegExp2(sym.CONCAT, r1, r2); :} + | nregexp:r + {: RESULT = r; :} + ; + +nregexp ::= regexp:r + {: RESULT = r; :} + | BANG nregexp:r + {: RESULT = new RegExp1(sym.BANG, r); :} + | TILDE nregexp:r + {: RESULT = new RegExp1(sym.TILDE, r); :} + ; + +regexp ::= regexp:r STAR + {: RESULT = new RegExp1(sym.STAR, r); :} + | regexp:r PLUS + {: RESULT = new RegExp1(sym.PLUS, r); :} + | regexp:r QUESTION + {: RESULT = new RegExp1(sym.QUESTION, r); :} + | regexp:r REPEAT:n RBRACE:b + {: RESULT = makeRepeat(r, n.intValue(), n.intValue(), bleft, bright); :} + | regexp:r REPEAT:n1 REPEAT:n2 RBRACE + {: RESULT = makeRepeat(r, n1.intValue(), n2.intValue(), n1left, n2right); :} + | OPENBRACKET series:r CLOSEBRACKET + {: RESULT = r; :} + | MACROUSE:ident + {: + if ( !scanner.macroDefinition ) { + if ( ! macros.markUsed(ident) ) + throw new ScannerException(scanner.file, ErrorMessages.MACRO_UNDECL, + identleft, identright); + } + RESULT = new RegExp1(sym.MACROUSE, ident); + :} + | charclass:c + {: RESULT = c; :} + | preclass:list + {: + try { + // assumption [correct?]: preclasses are already closed under case + charClasses.makeClass(list, false); + } + catch (CharClassException e) { + syntaxError(ErrorMessages.CHARSET_2_SMALL, listleft); + } + RESULT = new RegExp1(sym.CCLASS, list); + :} + | STRING:str + {: + try { + if ( scanner.caseless ) { + charClasses.makeClass(str, true); + RESULT = new RegExp1(sym.STRING_I, str); + } + else { + charClasses.makeClass(str, false); + RESULT = new RegExp1(sym.STRING, str); + } + } + catch (CharClassException e) { + syntaxError(ErrorMessages.CS2SMALL_STRING, strleft, strright); + } + + :} + | POINT + {: + Vector any = new Vector(); + any.addElement(new Interval('\n','\n')); + // assumption: there is no upper case for \n + charClasses.makeClass('\n', false); + RESULT = new RegExp1(sym.CCLASSNOT, any); + :} + | CHAR:c + {: + try { + if ( scanner.caseless ) { + charClasses.makeClass(c.charValue(), true); + RESULT = new RegExp1(sym.CHAR_I, c); + } + else { + charClasses.makeClass(c.charValue(), false); + RESULT = new RegExp1(sym.CHAR, c); + } + } + catch (CharClassException e) { + syntaxError(ErrorMessages.CS2SMALL_CHAR, cleft, cright); + } + :} + ; + +charclass ::= OPENCLASS CLOSECLASS + {: + RESULT = new RegExp1(sym.CCLASS,null); + :} + | OPENCLASS classcontent:list CLOSECLASS:close + {: + try { + charClasses.makeClass(list, Options.jlex && scanner.caseless); + } + catch (CharClassException e) { + syntaxError(ErrorMessages.CHARSET_2_SMALL, closeleft, closeright); + } + RESULT = new RegExp1(sym.CCLASS,list); + :} + | OPENCLASS HAT CLOSECLASS:close + {: + Vector list = new Vector(); + list.addElement(new Interval((char)0,CharClasses.maxChar)); + try { + charClasses.makeClass(list, false); + } + catch (CharClassException e) { + syntaxError(ErrorMessages.CHARSET_2_SMALL, closeleft, closeright); + } + RESULT = new RegExp1(sym.CCLASS,list); + :} + | OPENCLASS HAT classcontent:list CLOSECLASS:close + {: + try { + charClasses.makeClassNot(list, Options.jlex && scanner.caseless); + } + catch (CharClassException e) { + syntaxError(ErrorMessages.CHARSET_2_SMALL, closeleft, closeright); + } + RESULT = new RegExp1(sym.CCLASSNOT,list); + :} + | OPENCLASS DASH classcontent:list CLOSECLASS:close + {: + try { + list.addElement(new Interval('-','-')); + charClasses.makeClass(list, Options.jlex && scanner.caseless); + } + catch (CharClassException e) { + syntaxError(ErrorMessages.CHARSET_2_SMALL, closeleft, closeright); + } + RESULT = new RegExp1(sym.CCLASS,list); + :} + | OPENCLASS HAT DASH classcontent:list CLOSECLASS:close + {: + try { + list.addElement(new Interval('-','-')); + charClasses.makeClassNot(list, Options.jlex && scanner.caseless); + } + catch (CharClassException e) { + syntaxError(ErrorMessages.CHARSET_2_SMALL, closeleft, closeright); + } + RESULT = new RegExp1(sym.CCLASSNOT,list); + :} + ; + +classcontent ::= classcontent:list classcontentelem:elem + {: + list.addElement(elem); + RESULT = list; + :} + | classcontentelem:elem + {: + Vector list = new Vector(); + list.addElement(elem); + RESULT = list; + :} + | classcontent:list preclass:plist + {: + for (Enumeration e = plist.elements(); e.hasMoreElements();) + list.addElement(e.nextElement()); + RESULT = list; + :} + | preclass:list + {: RESULT = list; :} + | classcontent:list STRING:s + {: + for (int i = 0; i < s.length(); i++) + list.addElement(new Interval(s.charAt(i),s.charAt(i))); + RESULT = list; + :} + | STRING:s + {: + RESULT = new Vector(); + for (int i = 0; i < s.length(); i++) + RESULT.addElement(new Interval(s.charAt(i),s.charAt(i))); + :} + | classcontent:list MACROUSE:ident + {: + syntaxError(ErrorMessages.CHARCLASS_MACRO, identleft, identright); + :} + | MACROUSE:ident + {: + syntaxError(ErrorMessages.CHARCLASS_MACRO, identleft, identright); + :} + ; + +classcontentelem ::= CHAR:c1 DASH CHAR:c2 + {: RESULT = new Interval(c1.charValue(), c2.charValue()); :} + | CHAR:c + {: RESULT = new Interval(c.charValue(), c.charValue()); :} + ; + +preclass ::= JLETTERCLASS + {: RESULT = makePreClass(sym.JLETTERCLASS); :} + | JLETTERDIGITCLASS + {: RESULT = makePreClass(sym.JLETTERDIGITCLASS); :} + | LETTERCLASS + {: RESULT = makePreClass(sym.LETTERCLASS); :} + | DIGITCLASS + {: RESULT = makePreClass(sym.DIGITCLASS); :} + | UPPERCLASS + {: RESULT = makePreClass(sym.UPPERCLASS); :} + | LOWERCLASS + {: RESULT = makePreClass(sym.LOWERCLASS); :} + ; diff --git a/tools/lexer/jflex-1.4/src/JFlex/LexParse.java b/tools/lexer/jflex-1.4/src/JFlex/LexParse.java new file mode 100644 index 000000000000..8694d238001a --- /dev/null +++ b/tools/lexer/jflex-1.4/src/JFlex/LexParse.java @@ -0,0 +1,1711 @@ + +//---------------------------------------------------- +// The following code was generated by CUP v0.10k +// Sun Nov 07 14:07:52 GMT+10:00 2004 +//---------------------------------------------------- + +package JFlex; + +import java.util.Enumeration; +import java.util.Timer; +import java.util.Vector; + +/** CUP v0.10k generated parser. + * @version Sun Nov 07 14:07:52 GMT+10:00 2004 + */ +public class LexParse extends java_cup.runtime.lr_parser { + + /** Default constructor. */ + public LexParse() {super();} + + /** Constructor which sets the default scanner. */ + public LexParse(java_cup.runtime.Scanner s) {super(s);} + + /** Production table. */ + protected static final short _production_table[][] = + unpackFromStrings(new String[] { + "\000\110\000\002\002\004\000\002\006\006\000\002\006" + + "\002\000\002\003\002\000\002\003\004\000\002\003\003" + + "\000\002\004\003\000\002\004\003\000\002\004\006\000" + + "\002\004\004\000\002\022\004\000\002\022\011\000\002" + + "\022\010\000\002\022\003\000\002\005\007\000\002\005" + + "\005\000\002\005\003\000\002\014\003\000\002\014\004" + + "\000\002\014\002\000\002\014\005\000\002\024\004\000" + + "\002\024\003\000\002\017\005\000\002\017\002\000\002" + + "\016\005\000\002\016\003\000\002\016\004\000\002\023" + + "\003\000\002\023\002\000\002\007\005\000\002\007\003" + + "\000\002\007\003\000\002\010\004\000\002\010\003\000" + + "\002\011\003\000\002\011\004\000\002\011\004\000\002" + + "\012\004\000\002\012\004\000\002\012\004\000\002\012" + + "\005\000\002\012\006\000\002\012\005\000\002\012\003" + + "\000\002\012\003\000\002\012\003\000\002\012\003\000" + + "\002\012\003\000\002\012\003\000\002\013\004\000\002" + + "\013\005\000\002\013\005\000\002\013\006\000\002\013" + + "\006\000\002\013\007\000\002\020\004\000\002\020\003" + + "\000\002\020\004\000\002\020\003\000\002\020\004\000" + + "\002\020\003\000\002\020\004\000\002\020\003\000\002" + + "\015\005\000\002\015\003\000\002\021\003\000\002\021" + + "\003\000\002\021\003\000\002\021\003\000\002\021\003" + + "\000\002\021\003" }); + + /** Access to production table. */ + public short[][] production_table() {return _production_table;} + + /** Parse-action table. */ + protected static final short[][] _action_table = + unpackFromStrings(new String[] { + "\000\152\000\006\002\uffff\040\004\001\002\000\014\003" + + "\007\013\ufffe\022\ufffe\023\ufffe\037\ufffe\001\002\000\004" + + "\002\006\001\002\000\004\002\001\001\002\000\012\013" + + "\ufffc\022\ufffc\023\ufffc\037\ufffc\001\002\000\012\013\011" + + "\022\015\023\014\037\013\001\002\000\050\003\113\004" + + "\uffe9\006\uffe9\010\uffe9\016\115\025\uffe9\026\uffe9\027\uffe9" + + "\030\uffe9\031\uffe9\032\uffe9\033\uffe9\044\uffe9\046\uffe9\047" + + "\uffe9\050\uffe9\051\uffe9\052\uffe9\053\uffe9\001\002\000\012" + + "\013\ufffd\022\ufffd\023\ufffd\037\ufffd\001\002\000\004\014" + + "\016\001\002\000\012\013\ufffa\022\ufffa\023\ufffa\037\ufffa" + + "\001\002\000\012\013\ufffb\022\ufffb\023\ufffb\037\ufffb\001" + + "\002\000\050\004\033\010\043\013\ufff8\022\ufff8\023\ufff8" + + "\025\023\026\030\027\017\030\041\031\034\032\031\037" + + "\ufff8\044\040\046\021\047\036\050\022\051\020\052\027" + + "\053\024\001\002\000\064\004\uffbd\005\uffbd\007\uffbd\010" + + "\uffbd\011\uffbd\024\uffbd\025\uffbd\026\uffbd\027\uffbd\030\uffbd" + + "\031\uffbd\032\uffbd\034\uffbd\035\uffbd\041\uffbd\042\uffbd\043" + + "\uffbd\044\uffbd\045\uffbd\046\uffbd\047\uffbd\050\uffbd\051\uffbd" + + "\052\uffbd\053\uffbd\001\002\000\062\004\uffd0\005\uffd0\007" + + "\uffd0\010\uffd0\024\uffd0\025\uffd0\026\uffd0\027\uffd0\030\uffd0" + + "\031\uffd0\032\uffd0\034\uffd0\035\uffd0\041\uffd0\042\uffd0\043" + + "\uffd0\044\uffd0\045\uffd0\046\uffd0\047\uffd0\050\uffd0\051\uffd0" + + "\052\uffd0\053\uffd0\001\002\000\062\004\uffd1\005\uffd1\007" + + "\uffd1\010\uffd1\024\uffd1\025\uffd1\026\uffd1\027\uffd1\030\uffd1" + + "\031\uffd1\032\uffd1\034\uffd1\035\uffd1\041\uffd1\042\uffd1\043" + + "\uffd1\044\uffd1\045\uffd1\046\uffd1\047\uffd1\050\uffd1\051\uffd1" + + "\052\uffd1\053\uffd1\001\002\000\036\004\033\010\043\025" + + "\023\026\030\027\017\030\041\031\034\032\031\046\021" + + "\047\036\050\022\051\020\052\027\053\024\001\002\000" + + "\064\004\uffbf\005\uffbf\007\uffbf\010\uffbf\011\uffbf\024\uffbf" + + "\025\uffbf\026\uffbf\027\uffbf\030\uffbf\031\uffbf\032\uffbf\034" + + "\uffbf\035\uffbf\041\uffbf\042\uffbf\043\uffbf\044\uffbf\045\uffbf" + + "\046\uffbf\047\uffbf\050\uffbf\051\uffbf\052\uffbf\053\uffbf\001" + + "\002\000\062\004\uffd5\005\uffd5\007\uffd5\010\uffd5\024\uffd5" + + "\025\uffd5\026\uffd5\027\uffd5\030\uffd5\031\uffd5\032\uffd5\034" + + "\uffd5\035\uffd5\041\uffd5\042\uffd5\043\uffd5\044\uffd5\045\uffd5" + + "\046\uffd5\047\uffd5\050\uffd5\051\uffd5\052\uffd5\053\uffd5\001" + + "\002\000\006\024\111\044\105\001\002\000\062\004\uffd3" + + "\005\uffd3\007\uffd3\010\uffd3\024\uffd3\025\uffd3\026\uffd3\027" + + "\uffd3\030\uffd3\031\uffd3\032\uffd3\034\uffd3\035\uffd3\041\uffd3" + + "\042\uffd3\043\uffd3\044\uffd3\045\uffd3\046\uffd3\047\uffd3\050" + + "\uffd3\051\uffd3\052\uffd3\053\uffd3\001\002\000\062\004\uffd2" + + "\005\uffd2\007\uffd2\010\uffd2\024\uffd2\025\uffd2\026\uffd2\027" + + "\uffd2\030\uffd2\031\uffd2\032\uffd2\034\uffd2\035\uffd2\041\uffd2" + + "\042\uffd2\043\uffd2\044\uffd2\045\uffd2\046\uffd2\047\uffd2\050" + + "\uffd2\051\uffd2\052\uffd2\053\uffd2\001\002\000\064\004\uffbe" + + "\005\uffbe\007\uffbe\010\uffbe\011\uffbe\024\uffbe\025\uffbe\026" + + "\uffbe\027\uffbe\030\uffbe\031\uffbe\032\uffbe\034\uffbe\035\uffbe" + + "\041\uffbe\042\uffbe\043\uffbe\044\uffbe\045\uffbe\046\uffbe\047" + + "\uffbe\050\uffbe\051\uffbe\052\uffbe\053\uffbe\001\002\000\064" + + "\004\uffba\005\uffba\007\uffba\010\uffba\011\uffba\024\uffba\025" + + "\uffba\026\uffba\027\uffba\030\uffba\031\uffba\032\uffba\034\uffba" + + "\035\uffba\041\uffba\042\uffba\043\uffba\044\uffba\045\uffba\046" + + "\uffba\047\uffba\050\uffba\051\uffba\052\uffba\053\uffba\001\002" + + "\000\052\004\033\005\uffe2\007\uffe2\010\043\024\uffe2\025" + + "\023\026\030\027\017\030\041\031\034\032\031\034\uffe2" + + "\035\uffe2\044\uffe2\046\021\047\036\050\022\051\020\052" + + "\027\053\024\001\002\000\040\004\033\010\043\025\023" + + "\026\030\027\017\030\041\031\034\032\031\044\040\046" + + "\021\047\036\050\022\051\020\052\027\053\024\001\002" + + "\000\064\004\uffbb\005\uffbb\007\uffbb\010\uffbb\011\uffbb\024" + + "\uffbb\025\uffbb\026\uffbb\027\uffbb\030\uffbb\031\uffbb\032\uffbb" + + "\034\uffbb\035\uffbb\041\uffbb\042\uffbb\043\uffbb\044\uffbb\045" + + "\uffbb\046\uffbb\047\uffbb\050\uffbb\051\uffbb\052\uffbb\053\uffbb" + + "\001\002\000\062\004\uffd4\005\uffd4\007\uffd4\010\uffd4\024" + + "\uffd4\025\uffd4\026\uffd4\027\uffd4\030\uffd4\031\uffd4\032\uffd4" + + "\034\uffd4\035\uffd4\041\uffd4\042\uffd4\043\uffd4\044\uffd4\045" + + "\uffd4\046\uffd4\047\uffd4\050\uffd4\051\uffd4\052\uffd4\053\uffd4" + + "\001\002\000\036\004\033\010\043\025\023\026\030\027" + + "\017\030\041\031\034\032\031\046\021\047\036\050\022" + + "\051\020\052\027\053\024\001\002\000\052\004\uffdf\005" + + "\uffdf\007\uffdf\010\uffdf\024\uffdf\025\uffdf\026\uffdf\027\uffdf" + + "\030\uffdf\031\uffdf\032\uffdf\034\uffdf\035\uffdf\044\uffdf\046" + + "\uffdf\047\uffdf\050\uffdf\051\uffdf\052\uffdf\053\uffdf\001\002" + + "\000\016\005\uffe1\007\uffe1\024\uffe1\034\uffe1\035\uffe1\044" + + "\uffe1\001\002\000\064\004\uffbc\005\uffbc\007\uffbc\010\uffbc" + + "\011\uffbc\024\uffbc\025\uffbc\026\uffbc\027\uffbc\030\uffbc\031" + + "\uffbc\032\uffbc\034\uffbc\035\uffbc\041\uffbc\042\uffbc\043\uffbc" + + "\044\uffbc\045\uffbc\046\uffbc\047\uffbc\050\uffbc\051\uffbc\052" + + "\uffbc\053\uffbc\001\002\000\062\004\uffde\005\uffde\007\uffde" + + "\010\uffde\024\uffde\025\uffde\026\uffde\027\uffde\030\uffde\031" + + "\uffde\032\uffde\034\uffde\035\uffde\041\076\042\074\043\075" + + "\044\uffde\045\077\046\uffde\047\uffde\050\uffde\051\uffde\052" + + "\uffde\053\uffde\001\002\000\032\006\047\011\050\012\046" + + "\025\023\026\030\027\017\030\041\031\034\032\031\051" + + "\054\052\051\053\053\001\002\000\026\011\uffc6\025\uffc6" + + "\026\uffc6\027\uffc6\030\uffc6\031\uffc6\032\uffc6\051\uffc6\052" + + "\uffc6\053\uffc6\001\002\000\026\011\uffc8\025\uffc8\026\uffc8" + + "\027\uffc8\030\uffc8\031\uffc8\032\uffc8\051\uffc8\052\uffc8\053" + + "\uffc8\001\002\000\024\025\023\026\030\027\017\030\041" + + "\031\034\032\031\051\054\052\051\053\053\001\002\000" + + "\030\011\065\012\064\025\023\026\030\027\017\030\041" + + "\031\034\032\031\051\054\052\051\053\053\001\002\000" + + "\062\004\uffcf\005\uffcf\007\uffcf\010\uffcf\024\uffcf\025\uffcf" + + "\026\uffcf\027\uffcf\030\uffcf\031\uffcf\032\uffcf\034\uffcf\035" + + "\uffcf\041\uffcf\042\uffcf\043\uffcf\044\uffcf\045\uffcf\046\uffcf" + + "\047\uffcf\050\uffcf\051\uffcf\052\uffcf\053\uffcf\001\002\000" + + "\026\011\uffc4\025\uffc4\026\uffc4\027\uffc4\030\uffc4\031\uffc4" + + "\032\uffc4\051\uffc4\052\uffc4\053\uffc4\001\002\000\026\011" + + "\061\025\023\026\030\027\017\030\041\031\034\032\031" + + "\051\054\052\062\053\063\001\002\000\026\011\uffc2\025" + + "\uffc2\026\uffc2\027\uffc2\030\uffc2\031\uffc2\032\uffc2\051\uffc2" + + "\052\uffc2\053\uffc2\001\002\000\030\011\uffc0\012\055\025" + + "\uffc0\026\uffc0\027\uffc0\030\uffc0\031\uffc0\032\uffc0\051\uffc0" + + "\052\uffc0\053\uffc0\001\002\000\004\051\056\001\002\000" + + "\026\011\uffc1\025\uffc1\026\uffc1\027\uffc1\030\uffc1\031\uffc1" + + "\032\uffc1\051\uffc1\052\uffc1\053\uffc1\001\002\000\026\011" + + "\uffc7\025\uffc7\026\uffc7\027\uffc7\030\uffc7\031\uffc7\032\uffc7" + + "\051\uffc7\052\uffc7\053\uffc7\001\002\000\026\011\uffc9\025" + + "\uffc9\026\uffc9\027\uffc9\030\uffc9\031\uffc9\032\uffc9\051\uffc9" + + "\052\uffc9\053\uffc9\001\002\000\062\004\uffce\005\uffce\007" + + "\uffce\010\uffce\024\uffce\025\uffce\026\uffce\027\uffce\030\uffce" + + "\031\uffce\032\uffce\034\uffce\035\uffce\041\uffce\042\uffce\043" + + "\uffce\044\uffce\045\uffce\046\uffce\047\uffce\050\uffce\051\uffce" + + "\052\uffce\053\uffce\001\002\000\026\011\uffc5\025\uffc5\026" + + "\uffc5\027\uffc5\030\uffc5\031\uffc5\032\uffc5\051\uffc5\052\uffc5" + + "\053\uffc5\001\002\000\026\011\uffc3\025\uffc3\026\uffc3\027" + + "\uffc3\030\uffc3\031\uffc3\032\uffc3\051\uffc3\052\uffc3\053\uffc3" + + "\001\002\000\024\025\023\026\030\027\017\030\041\031" + + "\034\032\031\051\054\052\051\053\053\001\002\000\062" + + "\004\uffcd\005\uffcd\007\uffcd\010\uffcd\024\uffcd\025\uffcd\026" + + "\uffcd\027\uffcd\030\uffcd\031\uffcd\032\uffcd\034\uffcd\035\uffcd" + + "\041\uffcd\042\uffcd\043\uffcd\044\uffcd\045\uffcd\046\uffcd\047" + + "\uffcd\050\uffcd\051\uffcd\052\uffcd\053\uffcd\001\002\000\026" + + "\011\067\025\023\026\030\027\017\030\041\031\034\032" + + "\031\051\054\052\062\053\063\001\002\000\062\004\uffcc" + + "\005\uffcc\007\uffcc\010\uffcc\024\uffcc\025\uffcc\026\uffcc\027" + + "\uffcc\030\uffcc\031\uffcc\032\uffcc\034\uffcc\035\uffcc\041\uffcc" + + "\042\uffcc\043\uffcc\044\uffcc\045\uffcc\046\uffcc\047\uffcc\050" + + "\uffcc\051\uffcc\052\uffcc\053\uffcc\001\002\000\026\011\071" + + "\025\023\026\030\027\017\030\041\031\034\032\031\051" + + "\054\052\062\053\063\001\002\000\062\004\uffca\005\uffca" + + "\007\uffca\010\uffca\024\uffca\025\uffca\026\uffca\027\uffca\030" + + "\uffca\031\uffca\032\uffca\034\uffca\035\uffca\041\uffca\042\uffca" + + "\043\uffca\044\uffca\045\uffca\046\uffca\047\uffca\050\uffca\051" + + "\uffca\052\uffca\053\uffca\001\002\000\026\011\073\025\023" + + "\026\030\027\017\030\041\031\034\032\031\051\054\052" + + "\062\053\063\001\002\000\062\004\uffcb\005\uffcb\007\uffcb" + + "\010\uffcb\024\uffcb\025\uffcb\026\uffcb\027\uffcb\030\uffcb\031" + + "\uffcb\032\uffcb\034\uffcb\035\uffcb\041\uffcb\042\uffcb\043\uffcb" + + "\044\uffcb\045\uffcb\046\uffcb\047\uffcb\050\uffcb\051\uffcb\052" + + "\uffcb\053\uffcb\001\002\000\062\004\uffdb\005\uffdb\007\uffdb" + + "\010\uffdb\024\uffdb\025\uffdb\026\uffdb\027\uffdb\030\uffdb\031" + + "\uffdb\032\uffdb\034\uffdb\035\uffdb\041\uffdb\042\uffdb\043\uffdb" + + "\044\uffdb\045\uffdb\046\uffdb\047\uffdb\050\uffdb\051\uffdb\052" + + "\uffdb\053\uffdb\001\002\000\062\004\uffda\005\uffda\007\uffda" + + "\010\uffda\024\uffda\025\uffda\026\uffda\027\uffda\030\uffda\031" + + "\uffda\032\uffda\034\uffda\035\uffda\041\uffda\042\uffda\043\uffda" + + "\044\uffda\045\uffda\046\uffda\047\uffda\050\uffda\051\uffda\052" + + "\uffda\053\uffda\001\002\000\006\021\100\041\101\001\002" + + "\000\062\004\uffd9\005\uffd9\007\uffd9\010\uffd9\024\uffd9\025" + + "\uffd9\026\uffd9\027\uffd9\030\uffd9\031\uffd9\032\uffd9\034\uffd9" + + "\035\uffd9\041\uffd9\042\uffd9\043\uffd9\044\uffd9\045\uffd9\046" + + "\uffd9\047\uffd9\050\uffd9\051\uffd9\052\uffd9\053\uffd9\001\002" + + "\000\062\004\uffd8\005\uffd8\007\uffd8\010\uffd8\024\uffd8\025" + + "\uffd8\026\uffd8\027\uffd8\030\uffd8\031\uffd8\032\uffd8\034\uffd8" + + "\035\uffd8\041\uffd8\042\uffd8\043\uffd8\044\uffd8\045\uffd8\046" + + "\uffd8\047\uffd8\050\uffd8\051\uffd8\052\uffd8\053\uffd8\001\002" + + "\000\004\021\102\001\002\000\062\004\uffd7\005\uffd7\007" + + "\uffd7\010\uffd7\024\uffd7\025\uffd7\026\uffd7\027\uffd7\030\uffd7" + + "\031\uffd7\032\uffd7\034\uffd7\035\uffd7\041\uffd7\042\uffd7\043" + + "\uffd7\044\uffd7\045\uffd7\046\uffd7\047\uffd7\050\uffd7\051\uffd7" + + "\052\uffd7\053\uffd7\001\002\000\052\004\uffdd\005\uffdd\007" + + "\uffdd\010\uffdd\024\uffdd\025\uffdd\026\uffdd\027\uffdd\030\uffdd" + + "\031\uffdd\032\uffdd\034\uffdd\035\uffdd\044\uffdd\046\uffdd\047" + + "\uffdd\050\uffdd\051\uffdd\052\uffdd\053\uffdd\001\002\000\006" + + "\005\106\044\105\001\002\000\036\004\033\010\043\025" + + "\023\026\030\027\017\030\041\031\034\032\031\046\021" + + "\047\036\050\022\051\020\052\027\053\024\001\002\000" + + "\062\004\uffd6\005\uffd6\007\uffd6\010\uffd6\024\uffd6\025\uffd6" + + "\026\uffd6\027\uffd6\030\uffd6\031\uffd6\032\uffd6\034\uffd6\035" + + "\uffd6\041\uffd6\042\uffd6\043\uffd6\044\uffd6\045\uffd6\046\uffd6" + + "\047\uffd6\050\uffd6\051\uffd6\052\uffd6\053\uffd6\001\002\000" + + "\052\004\033\005\uffe3\007\uffe3\010\043\024\uffe3\025\023" + + "\026\030\027\017\030\041\031\034\032\031\034\uffe3\035" + + "\uffe3\044\uffe3\046\021\047\036\050\022\051\020\052\027" + + "\053\024\001\002\000\052\004\uffe0\005\uffe0\007\uffe0\010" + + "\uffe0\024\uffe0\025\uffe0\026\uffe0\027\uffe0\030\uffe0\031\uffe0" + + "\032\uffe0\034\uffe0\035\uffe0\044\uffe0\046\uffe0\047\uffe0\050" + + "\uffe0\051\uffe0\052\uffe0\053\uffe0\001\002\000\012\013\ufff9" + + "\022\ufff9\023\ufff9\037\ufff9\001\002\000\052\004\uffdc\005" + + "\uffdc\007\uffdc\010\uffdc\024\uffdc\025\uffdc\026\uffdc\027\uffdc" + + "\030\uffdc\031\uffdc\032\uffdc\034\uffdc\035\uffdc\044\uffdc\046" + + "\uffdc\047\uffdc\050\uffdc\051\uffdc\052\uffdc\053\uffdc\001\002" + + "\000\054\002\ufff1\003\ufff1\004\ufff1\006\ufff1\010\ufff1\016" + + "\ufff1\021\ufff1\025\ufff1\026\ufff1\027\ufff1\030\ufff1\031\ufff1" + + "\032\ufff1\033\ufff1\044\ufff1\046\ufff1\047\ufff1\050\ufff1\051" + + "\ufff1\052\ufff1\053\ufff1\001\002\000\044\004\uffe4\006\141" + + "\010\uffe4\025\uffe4\026\uffe4\027\uffe4\030\uffe4\031\uffe4\032" + + "\uffe4\033\137\044\uffe4\046\uffe4\047\uffe4\050\uffe4\051\uffe4" + + "\052\uffe4\053\uffe4\001\002\000\004\037\123\001\002\000" + + "\054\002\ufff4\003\ufff4\004\ufff4\006\ufff4\010\ufff4\016\ufff4" + + "\021\ufff4\025\ufff4\026\ufff4\027\ufff4\030\ufff4\031\ufff4\032" + + "\ufff4\033\ufff4\044\ufff4\046\ufff4\047\ufff4\050\ufff4\051\ufff4" + + "\052\ufff4\053\ufff4\001\002\000\052\002\000\003\113\004" + + "\uffe9\006\uffe9\010\uffe9\016\120\025\uffe9\026\uffe9\027\uffe9" + + "\030\uffe9\031\uffe9\032\uffe9\033\uffe9\044\uffe9\046\uffe9\047" + + "\uffe9\050\uffe9\051\uffe9\052\uffe9\053\uffe9\001\002\000\004" + + "\037\123\001\002\000\054\002\ufff7\003\ufff7\004\ufff7\006" + + "\ufff7\010\ufff7\016\ufff7\021\ufff7\025\ufff7\026\ufff7\027\ufff7" + + "\030\ufff7\031\ufff7\032\ufff7\033\ufff7\044\ufff7\046\ufff7\047" + + "\ufff7\050\ufff7\051\ufff7\052\ufff7\053\ufff7\001\002\000\004" + + "\017\126\001\002\000\006\015\124\017\uffe7\001\002\000" + + "\006\017\uffe6\037\123\001\002\000\004\017\uffe8\001\002" + + "\000\046\004\uffea\006\uffea\010\uffea\020\127\025\uffea\026" + + "\uffea\027\uffea\030\uffea\031\uffea\032\uffea\033\uffea\044\uffea" + + "\046\uffea\047\uffea\050\uffea\051\uffea\052\uffea\053\uffea\001" + + "\002\000\050\003\113\004\uffe9\006\uffe9\010\uffe9\016\115" + + "\025\uffe9\026\uffe9\027\uffe9\030\uffe9\031\uffe9\032\uffe9\033" + + "\uffe9\044\uffe9\046\uffe9\047\uffe9\050\uffe9\051\uffe9\052\uffe9" + + "\053\uffe9\001\002\000\052\003\113\004\uffe9\006\uffe9\010" + + "\uffe9\016\120\021\131\025\uffe9\026\uffe9\027\uffe9\030\uffe9" + + "\031\uffe9\032\uffe9\033\uffe9\044\uffe9\046\uffe9\047\uffe9\050" + + "\uffe9\051\uffe9\052\uffe9\053\uffe9\001\002\000\054\002\ufff6" + + "\003\ufff6\004\ufff6\006\ufff6\010\ufff6\016\ufff6\021\ufff6\025" + + "\ufff6\026\ufff6\027\ufff6\030\ufff6\031\ufff6\032\ufff6\033\ufff6" + + "\044\ufff6\046\ufff6\047\ufff6\050\ufff6\051\ufff6\052\ufff6\053" + + "\ufff6\001\002\000\004\017\133\001\002\000\046\004\uffea" + + "\006\uffea\010\uffea\020\134\025\uffea\026\uffea\027\uffea\030" + + "\uffea\031\uffea\032\uffea\033\uffea\044\uffea\046\uffea\047\uffea" + + "\050\uffea\051\uffea\052\uffea\053\uffea\001\002\000\050\003" + + "\113\004\uffe9\006\uffe9\010\uffe9\016\115\025\uffe9\026\uffe9" + + "\027\uffe9\030\uffe9\031\uffe9\032\uffe9\033\uffe9\044\uffe9\046" + + "\uffe9\047\uffe9\050\uffe9\051\uffe9\052\uffe9\053\uffe9\001\002" + + "\000\052\003\113\004\uffe9\006\uffe9\010\uffe9\016\120\021" + + "\136\025\uffe9\026\uffe9\027\uffe9\030\uffe9\031\uffe9\032\uffe9" + + "\033\uffe9\044\uffe9\046\uffe9\047\uffe9\050\uffe9\051\uffe9\052" + + "\uffe9\053\uffe9\001\002\000\054\002\ufff5\003\ufff5\004\ufff5" + + "\006\ufff5\010\ufff5\016\ufff5\021\ufff5\025\ufff5\026\ufff5\027" + + "\ufff5\030\ufff5\031\ufff5\032\ufff5\033\ufff5\044\ufff5\046\ufff5" + + "\047\ufff5\050\ufff5\051\ufff5\052\ufff5\053\ufff5\001\002\000" + + "\004\036\154\001\002\000\040\004\033\010\043\025\023" + + "\026\030\027\017\030\041\031\034\032\031\044\040\046" + + "\021\047\036\050\022\051\020\052\027\053\024\001\002" + + "\000\040\004\uffe5\010\uffe5\025\uffe5\026\uffe5\027\uffe5\030" + + "\uffe5\031\uffe5\032\uffe5\044\uffe5\046\uffe5\047\uffe5\050\uffe5" + + "\051\uffe5\052\uffe5\053\uffe5\001\002\000\014\007\145\024" + + "\uffee\034\uffee\035\143\044\105\001\002\000\040\004\033" + + "\010\043\025\023\026\030\027\017\030\041\031\034\032" + + "\031\044\040\046\021\047\036\050\022\051\020\052\027" + + "\053\024\001\002\000\006\024\147\034\146\001\002\000" + + "\006\024\ufff0\034\ufff0\001\002\000\054\002\uffeb\003\uffeb" + + "\004\uffeb\006\uffeb\010\uffeb\016\uffeb\021\uffeb\025\uffeb\026" + + "\uffeb\027\uffeb\030\uffeb\031\uffeb\032\uffeb\033\uffeb\044\uffeb" + + "\046\uffeb\047\uffeb\050\uffeb\051\uffeb\052\uffeb\053\uffeb\001" + + "\002\000\004\036\151\001\002\000\054\002\ufff3\003\ufff3" + + "\004\ufff3\006\ufff3\010\ufff3\016\ufff3\021\ufff3\025\ufff3\026" + + "\ufff3\027\ufff3\030\ufff3\031\ufff3\032\ufff3\033\ufff3\044\ufff3" + + "\046\ufff3\047\ufff3\050\ufff3\051\ufff3\052\ufff3\053\ufff3\001" + + "\002\000\054\002\uffec\003\uffec\004\uffec\006\uffec\010\uffec" + + "\016\uffec\021\uffec\025\uffec\026\uffec\027\uffec\030\uffec\031" + + "\uffec\032\uffec\033\uffec\044\uffec\046\uffec\047\uffec\050\uffec" + + "\051\uffec\052\uffec\053\uffec\001\002\000\012\007\153\024" + + "\uffef\034\uffef\044\105\001\002\000\006\024\uffed\034\uffed" + + "\001\002\000\054\002\ufff2\003\ufff2\004\ufff2\006\ufff2\010" + + "\ufff2\016\ufff2\021\ufff2\025\ufff2\026\ufff2\027\ufff2\030\ufff2" + + "\031\ufff2\032\ufff2\033\ufff2\044\ufff2\046\ufff2\047\ufff2\050" + + "\ufff2\051\ufff2\052\ufff2\053\ufff2\001\002" }); + + /** Access to parse-action table. */ + public short[][] action_table() {return _action_table;} + + /** reduce_goto table. */ + protected static final short[][] _reduce_table = + unpackFromStrings(new String[] { + "\000\152\000\004\006\004\001\001\000\004\003\007\001" + + "\001\000\002\001\001\000\002\001\001\000\002\001\001" + + "\000\004\004\011\001\001\000\010\005\115\017\113\022" + + "\116\001\001\000\002\001\001\000\002\001\001\000\002" + + "\001\001\000\002\001\001\000\016\007\024\010\031\011" + + "\036\012\041\013\034\021\025\001\001\000\002\001\001" + + "\000\002\001\001\000\002\001\001\000\012\011\111\012" + + "\041\013\034\021\025\001\001\000\002\001\001\000\002" + + "\001\001\000\002\001\001\000\002\001\001\000\002\001" + + "\001\000\002\001\001\000\002\001\001\000\012\011\107" + + "\012\041\013\034\021\025\001\001\000\016\007\103\010" + + "\031\011\036\012\041\013\034\021\025\001\001\000\002" + + "\001\001\000\002\001\001\000\012\011\102\012\041\013" + + "\034\021\025\001\001\000\002\001\001\000\002\001\001" + + "\000\002\001\001\000\002\001\001\000\010\015\044\020" + + "\051\021\043\001\001\000\002\001\001\000\002\001\001" + + "\000\010\015\044\020\071\021\043\001\001\000\010\015" + + "\044\020\065\021\043\001\001\000\002\001\001\000\002" + + "\001\001\000\006\015\057\021\056\001\001\000\002\001" + + "\001\000\002\001\001\000\002\001\001\000\002\001\001" + + "\000\002\001\001\000\002\001\001\000\002\001\001\000" + + "\002\001\001\000\002\001\001\000\010\015\044\020\067" + + "\021\043\001\001\000\002\001\001\000\006\015\057\021" + + "\056\001\001\000\002\001\001\000\006\015\057\021\056" + + "\001\001\000\002\001\001\000\006\015\057\021\056\001" + + "\001\000\002\001\001\000\002\001\001\000\002\001\001" + + "\000\002\001\001\000\002\001\001\000\002\001\001\000" + + "\002\001\001\000\002\001\001\000\002\001\001\000\002" + + "\001\001\000\014\010\106\011\036\012\041\013\034\021" + + "\025\001\001\000\002\001\001\000\012\011\107\012\041" + + "\013\034\021\025\001\001\000\002\001\001\000\002\001" + + "\001\000\002\001\001\000\002\001\001\000\004\023\137" + + "\001\001\000\004\016\131\001\001\000\002\001\001\000" + + "\006\005\120\017\113\001\001\000\004\016\121\001\001" + + "\000\002\001\001\000\002\001\001\000\002\001\001\000" + + "\004\016\124\001\001\000\002\001\001\000\002\001\001" + + "\000\010\005\115\017\113\022\127\001\001\000\006\005" + + "\120\017\113\001\001\000\002\001\001\000\002\001\001" + + "\000\002\001\001\000\010\005\115\017\113\022\134\001" + + "\001\000\006\005\120\017\113\001\001\000\002\001\001" + + "\000\002\001\001\000\016\007\141\010\031\011\036\012" + + "\041\013\034\021\025\001\001\000\002\001\001\000\004" + + "\014\143\001\001\000\016\007\151\010\031\011\036\012" + + "\041\013\034\021\025\001\001\000\004\024\147\001\001" + + "\000\002\001\001\000\002\001\001\000\002\001\001\000" + + "\002\001\001\000\002\001\001\000\002\001\001\000\002" + + "\001\001\000\002\001\001" }); + + /** Access to reduce_goto table. */ + public short[][] reduce_table() {return _reduce_table;} + + /** Instance of action encapsulation class. */ + protected CUP$LexParse$actions action_obj; + + /** Action encapsulation object initializer. */ + protected void init_actions() + { + action_obj = new CUP$LexParse$actions(this); + } + + /** Invoke a user supplied parse action. */ + public java_cup.runtime.Symbol do_action( + int act_num, + java_cup.runtime.lr_parser parser, + java.util.Stack stack, + int top) + throws java.lang.Exception + { + /* call code in generated class */ + return action_obj.CUP$LexParse$do_action(act_num, parser, stack, top); + } + + /** Indicates start state. */ + public int start_state() {return 0;} + /** Indicates start production. */ + public int start_production() {return 0;} + + /** EOF Symbol index. */ + public int EOF_sym() {return 0;} + + /** error Symbol index. */ + public int error_sym() {return 1;} + + + /** User initialization code. */ + public void user_init() throws java.lang.Exception + { + + action_obj.scanner = this.scanner; + + } + + + public LexScan scanner; + + public LexParse(LexScan scanner) { + super(scanner); + this.scanner = scanner; + } + + public CharClasses getCharClasses() { + return action_obj.charClasses; + } + + public EOFActions getEOFActions() { + return action_obj.eofActions; + } + + public void report_error(String message, Object info) { + if ( info instanceof java_cup.runtime.Symbol ) { + java_cup.runtime.Symbol s = (java_cup.runtime.Symbol) info; + + if (s.sym == sym.EOF) + Out.error(ErrorMessages.UNEXPECTED_EOF); + else + Out.error(scanner.file, ErrorMessages.SYNTAX_ERROR, s.left, s.right); + } + else + Out.error(ErrorMessages.UNKNOWN_SYNTAX); + } + + public void report_fatal_error(String message, Object info) { + // report_error(message, info); + throw new GeneratorException(); + } + + +} + +/** Cup generated class to encapsulate user supplied action code.*/ +class CUP$LexParse$actions { + + + + LexScan scanner; + CharClasses charClasses = new CharClasses(127); + RegExps regExps = new RegExps(); + Macros macros = new Macros(); + Integer stateNumber; + Timer t = new Timer(); + EOFActions eofActions = new EOFActions(); + + void fatalError(ErrorMessages message, int line, int col) { + syntaxError(message, line, col); + throw new GeneratorException(); + } + + void fatalError(ErrorMessages message) { + fatalError(message, scanner.currentLine(), -1); + throw new GeneratorException(); + } + + void syntaxError(ErrorMessages message) { + Out.error(scanner.file, message, scanner.currentLine(), -1); + } + + void syntaxError(ErrorMessages message, int line) { + Out.error(scanner.file, message, line, -1); + } + + void syntaxError(ErrorMessages message, int line, int col) { + Out.error(scanner.file, message, line, col); + } + + + private boolean check(int type, char c) { + switch (type) { + case sym.JLETTERCLASS: + return Character.isJavaIdentifierStart(c); + + case sym.JLETTERDIGITCLASS: + return Character.isJavaIdentifierPart(c); + + case sym.LETTERCLASS: + return Character.isLetter(c); + + case sym.DIGITCLASS: + return Character.isDigit(c); + + case sym.UPPERCLASS: + return Character.isUpperCase(c); + + case sym.LOWERCLASS: + return Character.isLowerCase(c); + + default: return false; + } + } + + private Vector makePreClass(int type) { + + Vector result = new Vector(); + + char c = 0; + char start = 0; + char last = charClasses.getMaxCharCode(); + + boolean prev, current; + + prev = check(type,'\u0000'); + + for (c = 1; c < last; c++) { + + current = check(type,c); + + if (!prev && current) start = c; + if (prev && !current) { + result.addElement(new Interval(start, (char)(c-1))); + } + + prev = current; + } + + // the last iteration is moved out of the loop to + // avoid an endless loop if last == maxCharCode and + // last+1 == 0 + current = check(type,c); + + if (!prev && current) result.addElement(new Interval(c,c)); + if (prev && current) result.addElement(new Interval(start, c)); + if (prev && !current) result.addElement(new Interval(start, (char)(c-1))); + + return result; + } + + private RegExp makeRepeat(RegExp r, int n1, int n2, int line, int col) { + + if (n1 <= 0 && n2 <= 0) { + syntaxError(ErrorMessages.REPEAT_ZERO, line, col); + return null; + } + + if (n1 > n2) { + syntaxError(ErrorMessages.REPEAT_GREATER, line, col); + return null; + } + + int i; + RegExp result; + + if (n1 > 0) { + result = r; + n1--; n2--; // we need one concatenation less than the number of expressions to match + } + else { + result = new RegExp1(sym.QUESTION,r); + n2--; + } + + for (i = 0; i < n1; i++) + result = new RegExp2(sym.CONCAT, result, r); + + n2-= n1; + for (i = 0; i < n2; i++) + result = new RegExp2(sym.CONCAT, result, new RegExp1(sym.QUESTION,r)); + + return result; + } + + private RegExp makeNL() { + Vector list = new Vector(); + list.addElement(new Interval('\n','\r')); + list.addElement(new Interval('\u0085','\u0085')); + list.addElement(new Interval('\u2028','\u2029')); + + // assumption: line feeds are caseless + charClasses.makeClass(list, false); + charClasses.makeClass('\n', false); + charClasses.makeClass('\r', false); + + RegExp1 c = new RegExp1(sym.CCLASS, list); + Character n = new Character('\n'); + Character r = new Character('\r'); + + return new RegExp2(sym.BAR, + c, + new RegExp2(sym.CONCAT, + new RegExp1(sym.CHAR, r), + new RegExp1(sym.CHAR, n))); + } + + + private final LexParse parser; + + /** Constructor */ + CUP$LexParse$actions(LexParse parser) { + this.parser = parser; + } + + /** Method with the actual generated action code. */ + public final java_cup.runtime.Symbol CUP$LexParse$do_action( + int CUP$LexParse$act_num, + java_cup.runtime.lr_parser CUP$LexParse$parser, + java.util.Stack CUP$LexParse$stack, + int CUP$LexParse$top) + throws java.lang.Exception + { + /* Symbol object for return from actions */ + java_cup.runtime.Symbol CUP$LexParse$result; + + /* select the action based on the action number */ + switch (CUP$LexParse$act_num) + { + /*. . . . . . . . . . . . . . . . . . . .*/ + case 71: // preclass ::= LOWERCLASS + { + Vector RESULT = null; + RESULT = makePreClass(sym.LOWERCLASS); + CUP$LexParse$result = new java_cup.runtime.Symbol(15/*preclass*/, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).left, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).right, RESULT); + } + return CUP$LexParse$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 70: // preclass ::= UPPERCLASS + { + Vector RESULT = null; + RESULT = makePreClass(sym.UPPERCLASS); + CUP$LexParse$result = new java_cup.runtime.Symbol(15/*preclass*/, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).left, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).right, RESULT); + } + return CUP$LexParse$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 69: // preclass ::= DIGITCLASS + { + Vector RESULT = null; + RESULT = makePreClass(sym.DIGITCLASS); + CUP$LexParse$result = new java_cup.runtime.Symbol(15/*preclass*/, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).left, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).right, RESULT); + } + return CUP$LexParse$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 68: // preclass ::= LETTERCLASS + { + Vector RESULT = null; + RESULT = makePreClass(sym.LETTERCLASS); + CUP$LexParse$result = new java_cup.runtime.Symbol(15/*preclass*/, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).left, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).right, RESULT); + } + return CUP$LexParse$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 67: // preclass ::= JLETTERDIGITCLASS + { + Vector RESULT = null; + RESULT = makePreClass(sym.JLETTERDIGITCLASS); + CUP$LexParse$result = new java_cup.runtime.Symbol(15/*preclass*/, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).left, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).right, RESULT); + } + return CUP$LexParse$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 66: // preclass ::= JLETTERCLASS + { + Vector RESULT = null; + RESULT = makePreClass(sym.JLETTERCLASS); + CUP$LexParse$result = new java_cup.runtime.Symbol(15/*preclass*/, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).left, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).right, RESULT); + } + return CUP$LexParse$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 65: // classcontentelem ::= CHAR + { + Interval RESULT = null; + int cleft = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).left; + int cright = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).right; + Character c = (Character)((java_cup.runtime.Symbol) CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).value; + RESULT = new Interval(c.charValue(), c.charValue()); + CUP$LexParse$result = new java_cup.runtime.Symbol(11/*classcontentelem*/, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).left, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).right, RESULT); + } + return CUP$LexParse$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 64: // classcontentelem ::= CHAR DASH CHAR + { + Interval RESULT = null; + int c1left = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-2)).left; + int c1right = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-2)).right; + Character c1 = (Character)((java_cup.runtime.Symbol) CUP$LexParse$stack.elementAt(CUP$LexParse$top-2)).value; + int c2left = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).left; + int c2right = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).right; + Character c2 = (Character)((java_cup.runtime.Symbol) CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).value; + RESULT = new Interval(c1.charValue(), c2.charValue()); + CUP$LexParse$result = new java_cup.runtime.Symbol(11/*classcontentelem*/, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-2)).left, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).right, RESULT); + } + return CUP$LexParse$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 63: // classcontent ::= MACROUSE + { + Vector RESULT = null; + int identleft = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).left; + int identright = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).right; + String ident = (String)((java_cup.runtime.Symbol) CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).value; + + syntaxError(ErrorMessages.CHARCLASS_MACRO, identleft, identright); + + CUP$LexParse$result = new java_cup.runtime.Symbol(14/*classcontent*/, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).left, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).right, RESULT); + } + return CUP$LexParse$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 62: // classcontent ::= classcontent MACROUSE + { + Vector RESULT = null; + int listleft = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-1)).left; + int listright = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-1)).right; + Vector list = (Vector)((java_cup.runtime.Symbol) CUP$LexParse$stack.elementAt(CUP$LexParse$top-1)).value; + int identleft = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).left; + int identright = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).right; + String ident = (String)((java_cup.runtime.Symbol) CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).value; + + syntaxError(ErrorMessages.CHARCLASS_MACRO, identleft, identright); + + CUP$LexParse$result = new java_cup.runtime.Symbol(14/*classcontent*/, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-1)).left, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).right, RESULT); + } + return CUP$LexParse$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 61: // classcontent ::= STRING + { + Vector RESULT = null; + int sleft = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).left; + int sright = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).right; + String s = (String)((java_cup.runtime.Symbol) CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).value; + + RESULT = new Vector(); + for (int i = 0; i < s.length(); i++) + RESULT.addElement(new Interval(s.charAt(i),s.charAt(i))); + + CUP$LexParse$result = new java_cup.runtime.Symbol(14/*classcontent*/, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).left, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).right, RESULT); + } + return CUP$LexParse$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 60: // classcontent ::= classcontent STRING + { + Vector RESULT = null; + int listleft = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-1)).left; + int listright = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-1)).right; + Vector list = (Vector)((java_cup.runtime.Symbol) CUP$LexParse$stack.elementAt(CUP$LexParse$top-1)).value; + int sleft = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).left; + int sright = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).right; + String s = (String)((java_cup.runtime.Symbol) CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).value; + + for (int i = 0; i < s.length(); i++) + list.addElement(new Interval(s.charAt(i),s.charAt(i))); + RESULT = list; + + CUP$LexParse$result = new java_cup.runtime.Symbol(14/*classcontent*/, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-1)).left, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).right, RESULT); + } + return CUP$LexParse$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 59: // classcontent ::= preclass + { + Vector RESULT = null; + int listleft = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).left; + int listright = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).right; + Vector list = (Vector)((java_cup.runtime.Symbol) CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).value; + RESULT = list; + CUP$LexParse$result = new java_cup.runtime.Symbol(14/*classcontent*/, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).left, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).right, RESULT); + } + return CUP$LexParse$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 58: // classcontent ::= classcontent preclass + { + Vector RESULT = null; + int listleft = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-1)).left; + int listright = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-1)).right; + Vector list = (Vector)((java_cup.runtime.Symbol) CUP$LexParse$stack.elementAt(CUP$LexParse$top-1)).value; + int plistleft = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).left; + int plistright = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).right; + Vector plist = (Vector)((java_cup.runtime.Symbol) CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).value; + + for (Enumeration e = plist.elements(); e.hasMoreElements();) + list.addElement(e.nextElement()); + RESULT = list; + + CUP$LexParse$result = new java_cup.runtime.Symbol(14/*classcontent*/, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-1)).left, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).right, RESULT); + } + return CUP$LexParse$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 57: // classcontent ::= classcontentelem + { + Vector RESULT = null; + int elemleft = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).left; + int elemright = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).right; + Interval elem = (Interval)((java_cup.runtime.Symbol) CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).value; + + Vector list = new Vector(); + list.addElement(elem); + RESULT = list; + + CUP$LexParse$result = new java_cup.runtime.Symbol(14/*classcontent*/, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).left, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).right, RESULT); + } + return CUP$LexParse$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 56: // classcontent ::= classcontent classcontentelem + { + Vector RESULT = null; + int listleft = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-1)).left; + int listright = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-1)).right; + Vector list = (Vector)((java_cup.runtime.Symbol) CUP$LexParse$stack.elementAt(CUP$LexParse$top-1)).value; + int elemleft = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).left; + int elemright = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).right; + Interval elem = (Interval)((java_cup.runtime.Symbol) CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).value; + + list.addElement(elem); + RESULT = list; + + CUP$LexParse$result = new java_cup.runtime.Symbol(14/*classcontent*/, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-1)).left, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).right, RESULT); + } + return CUP$LexParse$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 55: // charclass ::= OPENCLASS HAT DASH classcontent CLOSECLASS + { + RegExp RESULT = null; + int listleft = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-1)).left; + int listright = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-1)).right; + Vector list = (Vector)((java_cup.runtime.Symbol) CUP$LexParse$stack.elementAt(CUP$LexParse$top-1)).value; + int closeleft = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).left; + int closeright = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).right; + Object close = (Object)((java_cup.runtime.Symbol) CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).value; + + try { + list.addElement(new Interval('-','-')); + charClasses.makeClassNot(list, Options.jlex && scanner.caseless); + } + catch (CharClassException e) { + syntaxError(ErrorMessages.CHARSET_2_SMALL, closeleft, closeright); + } + RESULT = new RegExp1(sym.CCLASSNOT,list); + + CUP$LexParse$result = new java_cup.runtime.Symbol(9/*charclass*/, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-4)).left, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).right, RESULT); + } + return CUP$LexParse$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 54: // charclass ::= OPENCLASS DASH classcontent CLOSECLASS + { + RegExp RESULT = null; + int listleft = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-1)).left; + int listright = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-1)).right; + Vector list = (Vector)((java_cup.runtime.Symbol) CUP$LexParse$stack.elementAt(CUP$LexParse$top-1)).value; + int closeleft = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).left; + int closeright = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).right; + Object close = (Object)((java_cup.runtime.Symbol) CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).value; + + try { + list.addElement(new Interval('-','-')); + charClasses.makeClass(list, Options.jlex && scanner.caseless); + } + catch (CharClassException e) { + syntaxError(ErrorMessages.CHARSET_2_SMALL, closeleft, closeright); + } + RESULT = new RegExp1(sym.CCLASS,list); + + CUP$LexParse$result = new java_cup.runtime.Symbol(9/*charclass*/, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-3)).left, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).right, RESULT); + } + return CUP$LexParse$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 53: // charclass ::= OPENCLASS HAT classcontent CLOSECLASS + { + RegExp RESULT = null; + int listleft = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-1)).left; + int listright = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-1)).right; + Vector list = (Vector)((java_cup.runtime.Symbol) CUP$LexParse$stack.elementAt(CUP$LexParse$top-1)).value; + int closeleft = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).left; + int closeright = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).right; + Object close = (Object)((java_cup.runtime.Symbol) CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).value; + + try { + charClasses.makeClassNot(list, Options.jlex && scanner.caseless); + } + catch (CharClassException e) { + syntaxError(ErrorMessages.CHARSET_2_SMALL, closeleft, closeright); + } + RESULT = new RegExp1(sym.CCLASSNOT,list); + + CUP$LexParse$result = new java_cup.runtime.Symbol(9/*charclass*/, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-3)).left, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).right, RESULT); + } + return CUP$LexParse$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 52: // charclass ::= OPENCLASS HAT CLOSECLASS + { + RegExp RESULT = null; + int closeleft = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).left; + int closeright = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).right; + Object close = (Object)((java_cup.runtime.Symbol) CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).value; + + Vector list = new Vector(); + list.addElement(new Interval((char)0,CharClasses.maxChar)); + try { + charClasses.makeClass(list, false); + } + catch (CharClassException e) { + syntaxError(ErrorMessages.CHARSET_2_SMALL, closeleft, closeright); + } + RESULT = new RegExp1(sym.CCLASS,list); + + CUP$LexParse$result = new java_cup.runtime.Symbol(9/*charclass*/, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-2)).left, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).right, RESULT); + } + return CUP$LexParse$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 51: // charclass ::= OPENCLASS classcontent CLOSECLASS + { + RegExp RESULT = null; + int listleft = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-1)).left; + int listright = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-1)).right; + Vector list = (Vector)((java_cup.runtime.Symbol) CUP$LexParse$stack.elementAt(CUP$LexParse$top-1)).value; + int closeleft = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).left; + int closeright = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).right; + Object close = (Object)((java_cup.runtime.Symbol) CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).value; + + try { + charClasses.makeClass(list, Options.jlex && scanner.caseless); + } + catch (CharClassException e) { + syntaxError(ErrorMessages.CHARSET_2_SMALL, closeleft, closeright); + } + RESULT = new RegExp1(sym.CCLASS,list); + + CUP$LexParse$result = new java_cup.runtime.Symbol(9/*charclass*/, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-2)).left, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).right, RESULT); + } + return CUP$LexParse$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 50: // charclass ::= OPENCLASS CLOSECLASS + { + RegExp RESULT = null; + + RESULT = new RegExp1(sym.CCLASS,null); + + CUP$LexParse$result = new java_cup.runtime.Symbol(9/*charclass*/, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-1)).left, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).right, RESULT); + } + return CUP$LexParse$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 49: // regexp ::= CHAR + { + RegExp RESULT = null; + int cleft = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).left; + int cright = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).right; + Character c = (Character)((java_cup.runtime.Symbol) CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).value; + + try { + if ( scanner.caseless ) { + charClasses.makeClass(c.charValue(), true); + RESULT = new RegExp1(sym.CHAR_I, c); + } + else { + charClasses.makeClass(c.charValue(), false); + RESULT = new RegExp1(sym.CHAR, c); + } + } + catch (CharClassException e) { + syntaxError(ErrorMessages.CS2SMALL_CHAR, cleft, cright); + } + + CUP$LexParse$result = new java_cup.runtime.Symbol(8/*regexp*/, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).left, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).right, RESULT); + } + return CUP$LexParse$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 48: // regexp ::= POINT + { + RegExp RESULT = null; + + Vector any = new Vector(); + any.addElement(new Interval('\n','\n')); + // assumption: there is no upper case for \n + charClasses.makeClass('\n', false); + RESULT = new RegExp1(sym.CCLASSNOT, any); + + CUP$LexParse$result = new java_cup.runtime.Symbol(8/*regexp*/, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).left, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).right, RESULT); + } + return CUP$LexParse$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 47: // regexp ::= STRING + { + RegExp RESULT = null; + int strleft = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).left; + int strright = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).right; + String str = (String)((java_cup.runtime.Symbol) CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).value; + + try { + if ( scanner.caseless ) { + charClasses.makeClass(str, true); + RESULT = new RegExp1(sym.STRING_I, str); + } + else { + charClasses.makeClass(str, false); + RESULT = new RegExp1(sym.STRING, str); + } + } + catch (CharClassException e) { + syntaxError(ErrorMessages.CS2SMALL_STRING, strleft, strright); + } + + + CUP$LexParse$result = new java_cup.runtime.Symbol(8/*regexp*/, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).left, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).right, RESULT); + } + return CUP$LexParse$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 46: // regexp ::= preclass + { + RegExp RESULT = null; + int listleft = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).left; + int listright = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).right; + Vector list = (Vector)((java_cup.runtime.Symbol) CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).value; + + try { + // assumption [correct?]: preclasses are already closed under case + charClasses.makeClass(list, false); + } + catch (CharClassException e) { + syntaxError(ErrorMessages.CHARSET_2_SMALL, listleft); + } + RESULT = new RegExp1(sym.CCLASS, list); + + CUP$LexParse$result = new java_cup.runtime.Symbol(8/*regexp*/, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).left, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).right, RESULT); + } + return CUP$LexParse$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 45: // regexp ::= charclass + { + RegExp RESULT = null; + int cleft = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).left; + int cright = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).right; + RegExp c = (RegExp)((java_cup.runtime.Symbol) CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).value; + RESULT = c; + CUP$LexParse$result = new java_cup.runtime.Symbol(8/*regexp*/, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).left, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).right, RESULT); + } + return CUP$LexParse$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 44: // regexp ::= MACROUSE + { + RegExp RESULT = null; + int identleft = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).left; + int identright = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).right; + String ident = (String)((java_cup.runtime.Symbol) CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).value; + + if ( !scanner.macroDefinition ) { + if ( ! macros.markUsed(ident) ) + throw new ScannerException(scanner.file, ErrorMessages.MACRO_UNDECL, + identleft, identright); + } + RESULT = new RegExp1(sym.MACROUSE, ident); + + CUP$LexParse$result = new java_cup.runtime.Symbol(8/*regexp*/, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).left, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).right, RESULT); + } + return CUP$LexParse$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 43: // regexp ::= OPENBRACKET series CLOSEBRACKET + { + RegExp RESULT = null; + int rleft = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-1)).left; + int rright = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-1)).right; + RegExp r = (RegExp)((java_cup.runtime.Symbol) CUP$LexParse$stack.elementAt(CUP$LexParse$top-1)).value; + RESULT = r; + CUP$LexParse$result = new java_cup.runtime.Symbol(8/*regexp*/, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-2)).left, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).right, RESULT); + } + return CUP$LexParse$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 42: // regexp ::= regexp REPEAT REPEAT RBRACE + { + RegExp RESULT = null; + int rleft = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-3)).left; + int rright = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-3)).right; + RegExp r = (RegExp)((java_cup.runtime.Symbol) CUP$LexParse$stack.elementAt(CUP$LexParse$top-3)).value; + int n1left = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-2)).left; + int n1right = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-2)).right; + Integer n1 = (Integer)((java_cup.runtime.Symbol) CUP$LexParse$stack.elementAt(CUP$LexParse$top-2)).value; + int n2left = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-1)).left; + int n2right = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-1)).right; + Integer n2 = (Integer)((java_cup.runtime.Symbol) CUP$LexParse$stack.elementAt(CUP$LexParse$top-1)).value; + RESULT = makeRepeat(r, n1.intValue(), n2.intValue(), n1left, n2right); + CUP$LexParse$result = new java_cup.runtime.Symbol(8/*regexp*/, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-3)).left, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).right, RESULT); + } + return CUP$LexParse$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 41: // regexp ::= regexp REPEAT RBRACE + { + RegExp RESULT = null; + int rleft = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-2)).left; + int rright = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-2)).right; + RegExp r = (RegExp)((java_cup.runtime.Symbol) CUP$LexParse$stack.elementAt(CUP$LexParse$top-2)).value; + int nleft = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-1)).left; + int nright = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-1)).right; + Integer n = (Integer)((java_cup.runtime.Symbol) CUP$LexParse$stack.elementAt(CUP$LexParse$top-1)).value; + int bleft = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).left; + int bright = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).right; + Object b = (Object)((java_cup.runtime.Symbol) CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).value; + RESULT = makeRepeat(r, n.intValue(), n.intValue(), bleft, bright); + CUP$LexParse$result = new java_cup.runtime.Symbol(8/*regexp*/, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-2)).left, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).right, RESULT); + } + return CUP$LexParse$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 40: // regexp ::= regexp QUESTION + { + RegExp RESULT = null; + int rleft = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-1)).left; + int rright = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-1)).right; + RegExp r = (RegExp)((java_cup.runtime.Symbol) CUP$LexParse$stack.elementAt(CUP$LexParse$top-1)).value; + RESULT = new RegExp1(sym.QUESTION, r); + CUP$LexParse$result = new java_cup.runtime.Symbol(8/*regexp*/, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-1)).left, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).right, RESULT); + } + return CUP$LexParse$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 39: // regexp ::= regexp PLUS + { + RegExp RESULT = null; + int rleft = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-1)).left; + int rright = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-1)).right; + RegExp r = (RegExp)((java_cup.runtime.Symbol) CUP$LexParse$stack.elementAt(CUP$LexParse$top-1)).value; + RESULT = new RegExp1(sym.PLUS, r); + CUP$LexParse$result = new java_cup.runtime.Symbol(8/*regexp*/, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-1)).left, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).right, RESULT); + } + return CUP$LexParse$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 38: // regexp ::= regexp STAR + { + RegExp RESULT = null; + int rleft = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-1)).left; + int rright = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-1)).right; + RegExp r = (RegExp)((java_cup.runtime.Symbol) CUP$LexParse$stack.elementAt(CUP$LexParse$top-1)).value; + RESULT = new RegExp1(sym.STAR, r); + CUP$LexParse$result = new java_cup.runtime.Symbol(8/*regexp*/, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-1)).left, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).right, RESULT); + } + return CUP$LexParse$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 37: // nregexp ::= TILDE nregexp + { + RegExp RESULT = null; + int rleft = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).left; + int rright = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).right; + RegExp r = (RegExp)((java_cup.runtime.Symbol) CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).value; + RESULT = new RegExp1(sym.TILDE, r); + CUP$LexParse$result = new java_cup.runtime.Symbol(7/*nregexp*/, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-1)).left, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).right, RESULT); + } + return CUP$LexParse$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 36: // nregexp ::= BANG nregexp + { + RegExp RESULT = null; + int rleft = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).left; + int rright = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).right; + RegExp r = (RegExp)((java_cup.runtime.Symbol) CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).value; + RESULT = new RegExp1(sym.BANG, r); + CUP$LexParse$result = new java_cup.runtime.Symbol(7/*nregexp*/, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-1)).left, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).right, RESULT); + } + return CUP$LexParse$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 35: // nregexp ::= regexp + { + RegExp RESULT = null; + int rleft = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).left; + int rright = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).right; + RegExp r = (RegExp)((java_cup.runtime.Symbol) CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).value; + RESULT = r; + CUP$LexParse$result = new java_cup.runtime.Symbol(7/*nregexp*/, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).left, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).right, RESULT); + } + return CUP$LexParse$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 34: // concs ::= nregexp + { + RegExp RESULT = null; + int rleft = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).left; + int rright = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).right; + RegExp r = (RegExp)((java_cup.runtime.Symbol) CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).value; + RESULT = r; + CUP$LexParse$result = new java_cup.runtime.Symbol(6/*concs*/, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).left, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).right, RESULT); + } + return CUP$LexParse$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 33: // concs ::= concs nregexp + { + RegExp RESULT = null; + int r1left = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-1)).left; + int r1right = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-1)).right; + RegExp r1 = (RegExp)((java_cup.runtime.Symbol) CUP$LexParse$stack.elementAt(CUP$LexParse$top-1)).value; + int r2left = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).left; + int r2right = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).right; + RegExp r2 = (RegExp)((java_cup.runtime.Symbol) CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).value; + RESULT = new RegExp2(sym.CONCAT, r1, r2); + CUP$LexParse$result = new java_cup.runtime.Symbol(6/*concs*/, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-1)).left, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).right, RESULT); + } + return CUP$LexParse$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 32: // series ::= BAR + { + RegExp RESULT = null; + int bleft = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).left; + int bright = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).right; + Object b = (Object)((java_cup.runtime.Symbol) CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).value; + syntaxError(ErrorMessages.REGEXP_EXPECTED, bleft, bright); + CUP$LexParse$result = new java_cup.runtime.Symbol(5/*series*/, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).left, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).right, RESULT); + } + return CUP$LexParse$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 31: // series ::= concs + { + RegExp RESULT = null; + int rleft = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).left; + int rright = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).right; + RegExp r = (RegExp)((java_cup.runtime.Symbol) CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).value; + RESULT = r; + CUP$LexParse$result = new java_cup.runtime.Symbol(5/*series*/, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).left, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).right, RESULT); + } + return CUP$LexParse$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 30: // series ::= series BAR concs + { + RegExp RESULT = null; + int r1left = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-2)).left; + int r1right = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-2)).right; + RegExp r1 = (RegExp)((java_cup.runtime.Symbol) CUP$LexParse$stack.elementAt(CUP$LexParse$top-2)).value; + int r2left = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).left; + int r2right = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).right; + RegExp r2 = (RegExp)((java_cup.runtime.Symbol) CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).value; + RESULT = new RegExp2(sym.BAR, r1, r2); + CUP$LexParse$result = new java_cup.runtime.Symbol(5/*series*/, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-2)).left, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).right, RESULT); + } + return CUP$LexParse$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 29: // hatOPT ::= + { + Boolean RESULT = null; + RESULT = new Boolean(false); + CUP$LexParse$result = new java_cup.runtime.Symbol(17/*hatOPT*/, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).right, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).right, RESULT); + } + return CUP$LexParse$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 28: // hatOPT ::= HAT + { + Boolean RESULT = null; + // assumption: there is no upper case for \n + charClasses.makeClass('\n', false); + RESULT = new Boolean(true); + CUP$LexParse$result = new java_cup.runtime.Symbol(17/*hatOPT*/, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).left, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).right, RESULT); + } + return CUP$LexParse$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 27: // states ::= IDENT COMMA + { + Vector RESULT = null; + int cleft = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).left; + int cright = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).right; + Object c = (Object)((java_cup.runtime.Symbol) CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).value; + syntaxError(ErrorMessages.REGEXP_EXPECTED, cleft, cright+1); + CUP$LexParse$result = new java_cup.runtime.Symbol(12/*states*/, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-1)).left, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).right, RESULT); + } + return CUP$LexParse$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 26: // states ::= IDENT + { + Vector RESULT = null; + int idleft = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).left; + int idright = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).right; + String id = (String)((java_cup.runtime.Symbol) CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).value; + + Vector list = new Vector(); + stateNumber = scanner.states.getNumber( id ); + if ( stateNumber != null ) + list.addElement( stateNumber ); + else { + throw new ScannerException(scanner.file, ErrorMessages.LEXSTATE_UNDECL, + idleft, idright); + } + RESULT = list; + + CUP$LexParse$result = new java_cup.runtime.Symbol(12/*states*/, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).left, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).right, RESULT); + } + return CUP$LexParse$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 25: // states ::= IDENT COMMA states + { + Vector RESULT = null; + int idleft = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-2)).left; + int idright = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-2)).right; + String id = (String)((java_cup.runtime.Symbol) CUP$LexParse$stack.elementAt(CUP$LexParse$top-2)).value; + int listleft = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).left; + int listright = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).right; + Vector list = (Vector)((java_cup.runtime.Symbol) CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).value; + + stateNumber = scanner.states.getNumber( id ); + if ( stateNumber != null ) + list.addElement( stateNumber ); + else { + throw new ScannerException(scanner.file, ErrorMessages.LEXSTATE_UNDECL, + idleft, idright); + } + RESULT = list; + + CUP$LexParse$result = new java_cup.runtime.Symbol(12/*states*/, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-2)).left, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).right, RESULT); + } + return CUP$LexParse$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 24: // statesOPT ::= + { + Vector RESULT = null; + RESULT = new Vector(); + CUP$LexParse$result = new java_cup.runtime.Symbol(13/*statesOPT*/, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).right, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).right, RESULT); + } + return CUP$LexParse$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 23: // statesOPT ::= LESSTHAN states MORETHAN + { + Vector RESULT = null; + int listleft = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-1)).left; + int listright = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-1)).right; + Vector list = (Vector)((java_cup.runtime.Symbol) CUP$LexParse$stack.elementAt(CUP$LexParse$top-1)).value; + RESULT = list; + CUP$LexParse$result = new java_cup.runtime.Symbol(13/*statesOPT*/, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-2)).left, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).right, RESULT); + } + return CUP$LexParse$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 22: // actions ::= NOACTION + { + Action RESULT = null; + RESULT = null; + CUP$LexParse$result = new java_cup.runtime.Symbol(18/*actions*/, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).left, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).right, RESULT); + } + return CUP$LexParse$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 21: // actions ::= REGEXPEND ACTION + { + Action RESULT = null; + int aleft = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).left; + int aright = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).right; + Action a = (Action)((java_cup.runtime.Symbol) CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).value; + RESULT = a; + CUP$LexParse$result = new java_cup.runtime.Symbol(18/*actions*/, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-1)).left, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).right, RESULT); + } + return CUP$LexParse$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 20: // lookaheadOPT ::= LOOKAHEAD series DOLLAR + { + RegExp RESULT = null; + int sleft = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-1)).left; + int sright = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-1)).right; + RegExp s = (RegExp)((java_cup.runtime.Symbol) CUP$LexParse$stack.elementAt(CUP$LexParse$top-1)).value; + RESULT = new RegExp2(sym.CONCAT, s, makeNL()); + CUP$LexParse$result = new java_cup.runtime.Symbol(10/*lookaheadOPT*/, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-2)).left, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).right, RESULT); + } + return CUP$LexParse$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 19: // lookaheadOPT ::= + { + RegExp RESULT = null; + RESULT = null; + CUP$LexParse$result = new java_cup.runtime.Symbol(10/*lookaheadOPT*/, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).right, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).right, RESULT); + } + return CUP$LexParse$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 18: // lookaheadOPT ::= LOOKAHEAD series + { + RegExp RESULT = null; + int rleft = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).left; + int rright = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).right; + RegExp r = (RegExp)((java_cup.runtime.Symbol) CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).value; + RESULT = r; + CUP$LexParse$result = new java_cup.runtime.Symbol(10/*lookaheadOPT*/, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-1)).left, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).right, RESULT); + } + return CUP$LexParse$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 17: // lookaheadOPT ::= DOLLAR + { + RegExp RESULT = null; + RESULT = makeNL(); + CUP$LexParse$result = new java_cup.runtime.Symbol(10/*lookaheadOPT*/, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).left, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).right, RESULT); + } + return CUP$LexParse$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 16: // rule ::= error + { + Integer RESULT = null; + + CUP$LexParse$result = new java_cup.runtime.Symbol(3/*rule*/, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).left, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).right, RESULT); + } + return CUP$LexParse$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 15: // rule ::= statesOPT EOFRULE ACTION + { + Integer RESULT = null; + int sleft = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-2)).left; + int sright = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-2)).right; + Vector s = (Vector)((java_cup.runtime.Symbol) CUP$LexParse$stack.elementAt(CUP$LexParse$top-2)).value; + int aleft = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).left; + int aright = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).right; + Action a = (Action)((java_cup.runtime.Symbol) CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).value; + RESULT = new Integer(regExps.insert(s, a)); + CUP$LexParse$result = new java_cup.runtime.Symbol(3/*rule*/, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-2)).left, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).right, RESULT); + } + return CUP$LexParse$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 14: // rule ::= statesOPT hatOPT series lookaheadOPT actions + { + Integer RESULT = null; + int sleft = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-4)).left; + int sright = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-4)).right; + Vector s = (Vector)((java_cup.runtime.Symbol) CUP$LexParse$stack.elementAt(CUP$LexParse$top-4)).value; + int bolleft = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-3)).left; + int bolright = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-3)).right; + Boolean bol = (Boolean)((java_cup.runtime.Symbol) CUP$LexParse$stack.elementAt(CUP$LexParse$top-3)).value; + int rleft = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-2)).left; + int rright = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-2)).right; + RegExp r = (RegExp)((java_cup.runtime.Symbol) CUP$LexParse$stack.elementAt(CUP$LexParse$top-2)).value; + int lleft = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-1)).left; + int lright = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-1)).right; + RegExp l = (RegExp)((java_cup.runtime.Symbol) CUP$LexParse$stack.elementAt(CUP$LexParse$top-1)).value; + int aleft = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).left; + int aright = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).right; + Action a = (Action)((java_cup.runtime.Symbol) CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).value; + RESULT = new Integer(regExps.insert(rleft, s, r, a, bol, l)); + CUP$LexParse$result = new java_cup.runtime.Symbol(3/*rule*/, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-4)).left, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).right, RESULT); + } + return CUP$LexParse$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 13: // rules ::= rule + { + Vector RESULT = null; + int rleft = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).left; + int rright = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).right; + Integer r = (Integer)((java_cup.runtime.Symbol) CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).value; + RESULT = new Vector(); RESULT.addElement(r); + CUP$LexParse$result = new java_cup.runtime.Symbol(16/*rules*/, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).left, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).right, RESULT); + } + return CUP$LexParse$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 12: // rules ::= LESSTHAN states MORETHAN LBRACE rules RBRACE + { + Vector RESULT = null; + int statesleft = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-4)).left; + int statesright = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-4)).right; + Vector states = (Vector)((java_cup.runtime.Symbol) CUP$LexParse$stack.elementAt(CUP$LexParse$top-4)).value; + int rlistleft = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-1)).left; + int rlistright = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-1)).right; + Vector rlist = (Vector)((java_cup.runtime.Symbol) CUP$LexParse$stack.elementAt(CUP$LexParse$top-1)).value; + + Enumeration rs = rlist.elements(); + while ( rs.hasMoreElements() ) { + Integer elem = (Integer) rs.nextElement(); + regExps.addStates( elem.intValue(), states ); + } + RESULT = rlist; + + CUP$LexParse$result = new java_cup.runtime.Symbol(16/*rules*/, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-5)).left, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).right, RESULT); + } + return CUP$LexParse$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 11: // rules ::= rules LESSTHAN states MORETHAN LBRACE rules RBRACE + { + Vector RESULT = null; + int rlist1left = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-6)).left; + int rlist1right = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-6)).right; + Vector rlist1 = (Vector)((java_cup.runtime.Symbol) CUP$LexParse$stack.elementAt(CUP$LexParse$top-6)).value; + int statesleft = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-4)).left; + int statesright = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-4)).right; + Vector states = (Vector)((java_cup.runtime.Symbol) CUP$LexParse$stack.elementAt(CUP$LexParse$top-4)).value; + int rlist2left = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-1)).left; + int rlist2right = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-1)).right; + Vector rlist2 = (Vector)((java_cup.runtime.Symbol) CUP$LexParse$stack.elementAt(CUP$LexParse$top-1)).value; + + Enumeration rs = rlist2.elements(); + while ( rs.hasMoreElements() ) { + Integer elem = (Integer) rs.nextElement(); + regExps.addStates( elem.intValue(), states ); + rlist1.addElement( elem ); + } + RESULT = rlist1; + + CUP$LexParse$result = new java_cup.runtime.Symbol(16/*rules*/, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-6)).left, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).right, RESULT); + } + return CUP$LexParse$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 10: // rules ::= rules rule + { + Vector RESULT = null; + int rlistleft = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-1)).left; + int rlistright = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-1)).right; + Vector rlist = (Vector)((java_cup.runtime.Symbol) CUP$LexParse$stack.elementAt(CUP$LexParse$top-1)).value; + int rleft = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).left; + int rright = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).right; + Integer r = (Integer)((java_cup.runtime.Symbol) CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).value; + rlist.addElement(r); RESULT = rlist; + CUP$LexParse$result = new java_cup.runtime.Symbol(16/*rules*/, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-1)).left, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).right, RESULT); + } + return CUP$LexParse$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 9: // macro ::= IDENT EQUALS + { + Object RESULT = null; + int eleft = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).left; + int eright = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).right; + Object e = (Object)((java_cup.runtime.Symbol) CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).value; + syntaxError(ErrorMessages.REGEXP_EXPECTED, eleft, eright); + CUP$LexParse$result = new java_cup.runtime.Symbol(2/*macro*/, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-1)).left, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).right, RESULT); + } + return CUP$LexParse$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 8: // macro ::= IDENT EQUALS series REGEXPEND + { + Object RESULT = null; + int nameleft = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-3)).left; + int nameright = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-3)).right; + String name = (String)((java_cup.runtime.Symbol) CUP$LexParse$stack.elementAt(CUP$LexParse$top-3)).value; + int definitionleft = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-1)).left; + int definitionright = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-1)).right; + RegExp definition = (RegExp)((java_cup.runtime.Symbol) CUP$LexParse$stack.elementAt(CUP$LexParse$top-1)).value; + macros.insert(name, definition); + CUP$LexParse$result = new java_cup.runtime.Symbol(2/*macro*/, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-3)).left, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).right, RESULT); + } + return CUP$LexParse$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 7: // macro ::= UNICODE + { + Object RESULT = null; + charClasses.setMaxCharCode(0xFFFF); + CUP$LexParse$result = new java_cup.runtime.Symbol(2/*macro*/, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).left, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).right, RESULT); + } + return CUP$LexParse$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 6: // macro ::= FULL + { + Object RESULT = null; + charClasses.setMaxCharCode(255); + CUP$LexParse$result = new java_cup.runtime.Symbol(2/*macro*/, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).left, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).right, RESULT); + } + return CUP$LexParse$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 5: // macros ::= error + { + Object RESULT = null; + + CUP$LexParse$result = new java_cup.runtime.Symbol(1/*macros*/, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).left, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).right, RESULT); + } + return CUP$LexParse$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 4: // macros ::= macros macro + { + Object RESULT = null; + + CUP$LexParse$result = new java_cup.runtime.Symbol(1/*macros*/, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-1)).left, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).right, RESULT); + } + return CUP$LexParse$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 3: // macros ::= + { + Object RESULT = null; + + CUP$LexParse$result = new java_cup.runtime.Symbol(1/*macros*/, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).right, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).right, RESULT); + } + return CUP$LexParse$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 2: // specification ::= + { + NFA RESULT = null; + + fatalError(ErrorMessages.NO_LEX_SPEC); + + CUP$LexParse$result = new java_cup.runtime.Symbol(4/*specification*/, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).right, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).right, RESULT); + } + return CUP$LexParse$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 1: // specification ::= USERCODE macros DELIMITER rules + { + NFA RESULT = null; + + scanner.t.stop(); + + Out.checkErrors(); + + Out.time(ErrorMessages.PARSING_TOOK, t); + + macros.expand(); + Enumeration unused = macros.unused(); + while ( unused.hasMoreElements() ) { + Out.warning("Macro \""+unused.nextElement()+"\" has been declared but never used."); + } + + SemCheck.check(regExps, macros, charClasses.getMaxCharCode(), scanner.file); + + regExps.checkActions(); + + if (Options.dump) charClasses.dump(); + + Out.print("Constructing NFA : "); + + t.start(); + int num = regExps.getNum(); + + RESULT = new NFA(charClasses.getNumClasses(), + scanner, regExps, macros, charClasses); + + eofActions.setNumLexStates(scanner.states.number()); + + for (int i = 0; i < num; i++) { + if (regExps.isEOF(i)) + eofActions.add( regExps.getStates(i), regExps.getAction(i) ); + else + RESULT.addRegExp(i); + } + + if (scanner.standalone) RESULT.addStandaloneRule(); + t.stop(); + + Out.time(""); + Out.time(ErrorMessages.NFA_TOOK, t); + + + CUP$LexParse$result = new java_cup.runtime.Symbol(4/*specification*/, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-3)).left, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).right, RESULT); + } + return CUP$LexParse$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 0: // $START ::= specification EOF + { + Object RESULT = null; + int start_valleft = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-1)).left; + int start_valright = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-1)).right; + NFA start_val = (NFA)((java_cup.runtime.Symbol) CUP$LexParse$stack.elementAt(CUP$LexParse$top-1)).value; + RESULT = start_val; + CUP$LexParse$result = new java_cup.runtime.Symbol(0/*$START*/, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-1)).left, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).right, RESULT); + } + /* ACCEPT */ + CUP$LexParse$parser.done_parsing(); + return CUP$LexParse$result; + + /* . . . . . .*/ + default: + throw new Exception( + "Invalid action number found in internal parse table"); + + } + } +} + diff --git a/tools/lexer/jflex-1.4/src/JFlex/LexScan.flex b/tools/lexer/jflex-1.4/src/JFlex/LexScan.flex new file mode 100644 index 000000000000..2a4157b517c5 --- /dev/null +++ b/tools/lexer/jflex-1.4/src/JFlex/LexScan.flex @@ -0,0 +1,569 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * JFlex 1.4.1 * + * Copyright (C) 1998-2004 Gerwin Klein * + * All rights reserved. * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License. See the file * + * COPYRIGHT for more information. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License along * + * with this program; if not, write to the Free Software Foundation, Inc., * + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +package JFlex; + +import java_cup.runtime.Symbol; +import java.util.Vector; +import java.io.*; +import java.util.Stack; + +/** + * The lexer of JFlex. + * + * Generated by JFlex. + * + * @author Gerwin Klein + * @version JFlex 1.4.1, $Revision: 2.8 $, $Date: 2004/11/07 03:09:30 $ + */ +%% + +%final +%public +%class LexScan +%implements sym, java_cup.runtime.Scanner +%function next_token + +%type Symbol +%unicode + +%column +%line + +%eofclose + +%state COMMENT, STATELIST, MACROS, REGEXPSTART +%state REGEXP, JAVA_CODE, STATES, STRING_CONTENT +%state CHARCLASS, COPY, REPEATEXP, EATWSPNL + +%cupdebug + +%{ + int balance = 0; + int commentbalance = 0; + int action_line = 0; + int bufferSize = 16384; + + File file; + Stack files = new Stack(); + + StringBuffer userCode = new StringBuffer(); + + String classCode; + String initCode; + String initThrow; + String eofCode; + String eofThrow; + String lexThrow; + String eofVal; + String scanErrorException; + String cupSymbol = "sym"; + + StringBuffer actionText = new StringBuffer(); + StringBuffer string = new StringBuffer(); + + boolean charCount; + boolean lineCount; + boolean columnCount; + boolean cupCompatible; + boolean cupDebug; + boolean isInteger; + boolean isIntWrap; + boolean isYYEOF; + boolean notUnix; + boolean isPublic; + boolean isFinal; + boolean isAbstract; + boolean lookAheadUsed; + boolean bolUsed; + boolean standalone; + boolean debugOption; + boolean useRowMap = Options.gen_method == Options.PACK || Options.gen_method == Options.TABLE; + boolean packed = Options.gen_method == Options.PACK; + boolean caseless; + boolean inclusive_states; + boolean eofclose; + + String isImplementing; + String isExtending; + String className = "Yylex"; + String functionName; + String tokenType; + String visibility = "public"; + + LexicalStates states = new LexicalStates(); + + Vector actions = new Vector(); + + private int nextState; + + boolean macroDefinition; + + Timer t = new Timer(); + + public int currentLine() { + return yyline; + } + + public void setFile(File file) { + this.file = file; + } + + private Symbol symbol(int type, Object value) { + return new Symbol(type, yyline, yycolumn, value); + } + + private Symbol symbol(int type) { + return new Symbol(type, yyline, yycolumn); + } + + // updates line and column count to the beginning of the first + // non whitespace character in yytext, but leaves yyline+yycolumn + // untouched + private Symbol symbol_countUpdate(int type, Object value) { + int lc = yyline; + int cc = yycolumn; + String text = yytext(); + + for (int i=0; i < text.length(); i++) { + char c = text.charAt(i); + + if (c != '\n' && c != '\r' && c != ' ' && c != '\t' ) + return new Symbol(type, lc, cc, value); + + if (c == '\n') { + lc++; + cc = 0; + } + else + cc++; + } + + return new Symbol(type, yyline, yycolumn, value); + } + + private String makeMacroIdent() { + String matched = yytext().trim(); + return matched.substring(1, matched.length()-1).trim(); + } + + public static String conc(Object a, Object b) { + if (a == null && b == null) return null; + if (a == null) return b.toString(); + if (b == null) return a.toString(); + + return a.toString()+b.toString(); + } + + public static String concExc(Object a, Object b) { + if (a == null && b == null) return null; + if (a == null) return b.toString(); + if (b == null) return a.toString(); + + return a.toString()+", "+b.toString(); + } +%} + +%init{ + states.insert("YYINITIAL", true); +%init} + + +Digit = [0-9] +HexDigit = [0-9a-fA-F] +OctDigit = [0-7] + +Number = {Digit}+ +HexNumber = \\ x {HexDigit} {2} +Unicode = \\ u {HexDigit} {1, 4} +OctNumber = \\ [0-3]? {OctDigit} {1, 2} + +// see http://www.unicode.org/unicode/reports/tr18/ +WSP = [ \t\b] +WSPNL = [\u2028\u2029\u000A\u000B\u000C\u000D\u0085\t\b\ ] +NL = [\u2028\u2029\u000A\u000B\u000C\u000D\u0085] | \u000D\u000A +NNL = [^\u2028\u2029\u000A\u000B\u000C\u000D\u0085] + +Ident = {IdentStart} {IdentPart}* +QualIdent = {Ident} ( {WSP}* "." {WSP}* {Ident} )* +QUIL = {QualIdent} ( {WSP}* "," {WSP}* {QualIdent} )* +Array = "[" {WSP}* "]" +ArrType = {QualIdent} ({WSP}* {Array})* + +IdentStart = [:jletter:] +IdentPart = [:jletterdigit:] + +JFlexCommentChar = [^*/]|"/"+[^*/]|"*"+[^*/] +JFlexComment = {JFlexCommentChar}* + +/* Java comments */ +JavaComment = {TraditionalComment}|{EndOfLineComment} +TraditionalComment = "/*"{CommentContent}\*+"/" +EndOfLineComment = "//".*{NL} + +CommentContent = ([^*]|\*+[^*/])* + +StringCharacter = [^\u2028\u2029\u000A\u000B\u000C\u000D\u0085\"\\] + +CharLiteral = \'([^\u2028\u2029\u000A\u000B\u000C\u000D\u0085\'\\]|{EscapeSequence})\' +StringLiteral = \"({StringCharacter}|{EscapeSequence})*\" + +EscapeSequence = \\[^\u2028\u2029\u000A\u000B\u000C\u000D\u0085]|\\+u{HexDigit}{4}|\\[0-3]?{OctDigit}{1,2} + +/* \\(b|t|n|f|r|\"|\'|\\|[0-3]?{OctDigit}{1,2}|u{HexDigit}{4}) */ + +JavaRest = [^\{\}\"\'/]|"/"[^*/] +JavaCode = ({JavaRest}|{StringLiteral}|{CharLiteral}|{JavaComment})+ + +%% + + { + "%%".*{NL}? { + t.start(); + yybegin(MACROS); + macroDefinition = true; + return symbol(USERCODE,userCode); + } + .*{NL} { userCode.append(yytext()); } + .* { return symbol(EOF); } +} + + ("%{"|"%init{"|"%initthrow{"|"%eof{"|"%eofthrow{"|"%yylexthrow{"|"%eofval{").*{NL} + { string.setLength(0); yybegin(COPY); } + { + "%}".*{NL} { classCode = conc(classCode,string); yybegin(MACROS); } + "%init}".*{NL} { initCode = conc(initCode,string); yybegin(MACROS); } + "%initthrow}".*{NL} { initThrow = concExc(initThrow,string); yybegin(MACROS); } + "%eof}".*{NL} { eofCode = conc(eofCode,string); yybegin(MACROS); } + "%eofthrow}".*{NL} { eofThrow = concExc(eofThrow,string); yybegin(MACROS); } + "%yylexthrow}".*{NL} { lexThrow = concExc(lexThrow,string); yybegin(MACROS); } + "%eofval}".*{NL} { eofVal = string.toString(); yybegin(MACROS); } + + .*{NL} { string.append(yytext()); } + + <> { throw new ScannerException(file,ErrorMessages.EOF_IN_MACROS); } +} + + + ^"%s" ("tate" "s"?)? {WSP}+ { inclusive_states = true; yybegin(STATELIST); } + ^"%x" ("state" "s"?)? {WSP}+ { inclusive_states = false; yybegin(STATELIST); } + { + {Ident} { states.insert(yytext(),inclusive_states); } + ([\ \t]*","[\ \t]*)|([\ \t]+) { } + {NL} { yybegin(MACROS); } + <> { throw new ScannerException(file,ErrorMessages.EOF_IN_MACROS); } +} + + { + "%char" { charCount = true; } + "%line" { lineCount = true; } + "%column" { columnCount = true; } + "%byaccj" { isInteger = true; + if (eofVal == null) + eofVal = "return 0;"; + eofclose = true; + } + "%cup" { cupCompatible = true; + isImplementing = concExc(isImplementing, "java_cup.runtime.Scanner"); + if (functionName == null) + functionName = "next_token"; + if (tokenType == null) + tokenType = "java_cup.runtime.Symbol"; + if (eofVal == null) + eofVal = "return new java_cup.runtime.Symbol("+cupSymbol+".EOF);"; + if (!Options.jlex) eofclose = true; + } + "%cupsym"{WSP}+{QualIdent} {WSP}* { cupSymbol = yytext().substring(8).trim(); + if (cupCompatible) Out.warning(ErrorMessages.CUPSYM_AFTER_CUP, yyline); } + "%cupsym"{WSP}+{NNL}* { throw new ScannerException(file,ErrorMessages.QUIL_CUPSYM, yyline); } + "%cupdebug" { cupDebug = true; } + "%eofclose"({WSP}+"true")? { eofclose = true; } + "%eofclose"({WSP}+"false") { eofclose = false; } + "%class"{WSP}+{Ident} {WSP}* { className = yytext().substring(7).trim(); } + "%function"{WSP}+{Ident} {WSP}* { functionName = yytext().substring(10).trim(); } + "%type"{WSP}+{ArrType} {WSP}* { tokenType = yytext().substring(6).trim(); } + "%integer"|"%int" { isInteger = true; } + "%intwrap" { isIntWrap = true; } + "%yyeof" { isYYEOF = true; } + "%notunix" { notUnix = true; } + "%7bit" { } + "%full"|"%8bit" { return symbol(FULL); } + "%unicode"|"%16bit" { return symbol(UNICODE); } + "%caseless"|"%ignorecase" { caseless = true; } + "%implements"{WSP}+.* { isImplementing = concExc(isImplementing, yytext().substring(12).trim()); } + "%extends"{WSP}+{QualIdent}{WSP}* { isExtending = yytext().substring(9).trim(); } + "%public" { isPublic = true; } + "%apiprivate" { visibility = "private"; Skeleton.makePrivate(); } + "%final" { isFinal = true; } + "%abstract" { isAbstract = true; } + "%debug" { debugOption = true; } + "%standalone" { standalone = true; isInteger = true; } + "%switch" { packed = false; useRowMap = false; } + "%table" { packed = false; useRowMap = true; } + "%pack" { packed = true; useRowMap = true; } + "%include" {WSP}+ .* { File f = new File(yytext().substring(9).trim()); + if ( !f.canRead() ) + throw new ScannerException(file,ErrorMessages.NOT_READABLE, yyline); + // check for cycle + if (files.search(f) > 0) + throw new ScannerException(file,ErrorMessages.FILE_CYCLE, yyline); + try { + yypushStream( new FileReader(f) ); + files.push(file); + file = f; + Out.println("Including \""+file+"\""); + } + catch (FileNotFoundException e) { + throw new ScannerException(file,ErrorMessages.NOT_READABLE, yyline); + } + } + "%buffer" {WSP}+ {Number} {WSP}* { bufferSize = Integer.parseInt(yytext().substring(8).trim()); } + "%buffer" {WSP}+ {NNL}* { throw new ScannerException(file,ErrorMessages.NO_BUFFER_SIZE, yyline); } + "%initthrow" {WSP}+ {QUIL} {WSP}* { initThrow = concExc(initThrow,yytext().substring(11).trim()); } + "%initthrow" {WSP}+ {NNL}* { throw new ScannerException(file,ErrorMessages.QUIL_INITTHROW, yyline); } + "%eofthrow" {WSP}+ {QUIL} {WSP}* { eofThrow = concExc(eofThrow,yytext().substring(10).trim()); } + "%eofthrow" {WSP}+ {NNL}* { throw new ScannerException(file,ErrorMessages.QUIL_EOFTHROW, yyline); } + "%yylexthrow"{WSP}+ {QUIL} {WSP}* { lexThrow = concExc(lexThrow,yytext().substring(12).trim()); } + "%throws" {WSP}+ {QUIL} {WSP}* { lexThrow = concExc(lexThrow,yytext().substring(8).trim()); } + "%yylexthrow"{WSP}+ {NNL}* { throw new ScannerException(file,ErrorMessages.QUIL_YYLEXTHROW, yyline); } + "%throws" {WSP}+ {NNL}* { throw new ScannerException(file,ErrorMessages.QUIL_THROW, yyline); } + "%scanerror" {WSP}+ {QualIdent} {WSP}* { scanErrorException = yytext().substring(11).trim(); } + "%scanerror" {WSP}+ {NNL}* { throw new ScannerException(file,ErrorMessages.QUIL_SCANERROR, yyline); } + + {Ident} { return symbol(IDENT, yytext()); } + "="{WSP}* { yybegin(REGEXP); return symbol(EQUALS); } + + "/*" { nextState = MACROS; yybegin(COMMENT); } + + {EndOfLineComment} { } + + /* no {NL} at the end of this expression, because + needs at least one {WSPNL} to start a regular expression! */ + ^"%%" {NNL}* { macroDefinition = false; yybegin(REGEXPSTART); return symbol(DELIMITER); } + "%"{Ident} { throw new ScannerException(file,ErrorMessages.UNKNOWN_OPTION, yyline, yycolumn); } + "%" { throw new ScannerException(file,ErrorMessages.UNKNOWN_OPTION, yyline, yycolumn); } + ^{WSP}+"%" { Out.warning(ErrorMessages.NOT_AT_BOL, yyline); yypushback(1); } + + {WSP}+ { } + {NL}+ { } + <> { if ( yymoreStreams() ) { + file = (File) files.pop(); + yypopStream(); + } + else + throw new ScannerException(file,ErrorMessages.EOF_IN_MACROS); + } +} + + { + {WSPNL}* "/*" { nextState = REGEXPSTART; yybegin(COMMENT); } + {WSPNL}+ { yybegin(REGEXP); } + {WSPNL}* "<" { yybegin(STATES); return symbol_countUpdate(LESSTHAN, null); } + {WSPNL}* "}" { return symbol_countUpdate(RBRACE, null); } + {WSPNL}* "//" {NNL}* { } + {WSPNL}* "<>" {WSPNL}* "{" + { actionText.setLength(0); yybegin(JAVA_CODE); + Symbol s = symbol_countUpdate(EOFRULE, null); + action_line = s.left+1; + return s; + } +} + + { + {Ident} { return symbol(IDENT, yytext()); } + "," { return symbol(COMMA); } + {WSPNL}+ { } + + // "{" will be caught in REGEXP + ">"{WSPNL}* { yybegin(REGEXP); return symbol(MORETHAN); } + + <> { throw new ScannerException(file,ErrorMessages.EOF_IN_STATES); } +} + + + { + "<>" {WSPNL}+ "{" { actionText.setLength(0); yybegin(JAVA_CODE); action_line = yyline+1; return symbol(EOFRULE); } + "<>" { throw new ScannerException(file,ErrorMessages.EOF_WO_ACTION); } + + {WSPNL}*"|"{WSP}*$ { if (macroDefinition) { + yybegin(EATWSPNL); + return symbol(BAR); + } + else { + yybegin(REGEXPSTART); + return symbol(NOACTION); + } + } + + // stategroup + "{" { yybegin(REGEXPSTART); return symbol(LBRACE); } + + {WSPNL}*"|" { return symbol(BAR); } + + {WSPNL}*\" { string.setLength(0); nextState = REGEXP; yybegin(STRING_CONTENT); } + {WSPNL}*"!" { return symbol(BANG); } + {WSPNL}*"~" { return symbol(TILDE); } + {WSPNL}*"(" { return symbol(OPENBRACKET); } + {WSPNL}*")" { return symbol(CLOSEBRACKET); } + {WSPNL}*"*" { return symbol(STAR); } + {WSPNL}*"+" { return symbol(PLUS); } + {WSPNL}*"?" { return symbol(QUESTION); } + {WSPNL}*"$" { lookAheadUsed = true; return symbol(DOLLAR); } + {WSPNL}*"^" { bolUsed = true; return symbol(HAT); } + {WSPNL}*"." { return symbol(POINT); } + {WSPNL}*"[" { yybegin(CHARCLASS); return symbol(OPENCLASS); } + {WSPNL}*"/" { lookAheadUsed = true; return symbol(LOOKAHEAD); } + + {WSPNL}* "{" {WSP}* {Ident} {WSP}* "}" { return symbol_countUpdate(MACROUSE, makeMacroIdent()); } + {WSPNL}* "{" {WSP}* {Number} { yybegin(REPEATEXP); return symbol(REPEAT, new Integer(yytext().trim().substring(1).trim())); } + + {WSPNL}+ "{" { actionText.setLength(0); yybegin(JAVA_CODE); action_line = yyline+1; return symbol(REGEXPEND); } + {NL} { if (macroDefinition) { yybegin(MACROS); } return symbol(REGEXPEND); } + + {WSPNL}*"/*" { nextState = REGEXP; yybegin(COMMENT); } + + {WSPNL}*"//"{NNL}* { } + + {WSP}+ { } + + { + {WSPNL}*"[:jletter:]" { return symbol(JLETTERCLASS); } + {WSPNL}*"[:jletterdigit:]" { return symbol(JLETTERDIGITCLASS); } + {WSPNL}*"[:letter:]" { return symbol(LETTERCLASS); } + {WSPNL}*"[:digit:]" { return symbol(DIGITCLASS); } + {WSPNL}*"[:uppercase:]" { return symbol(UPPERCLASS); } + {WSPNL}*"[:lowercase:]" { return symbol(LOWERCLASS); } + } + + . { return symbol(CHAR, new Character(yytext().charAt(0))); } +} + + {WSPNL}+ { yybegin(REGEXP); } + + + { + "}" { yybegin(REGEXP); return symbol(RBRACE); } + "," {WSP}* {Number} { return symbol(REPEAT, new Integer(yytext().substring(1).trim())); } + {WSP}+ { } + + <> { throw new ScannerException(file,ErrorMessages.EOF_IN_REGEXP); } +} + + { + "{"{Ident}"}" { return symbol(MACROUSE, yytext().substring(1,yytext().length()-1)); } + "[" { balance++; return symbol(OPENCLASS); } + "]" { if (balance > 0) balance--; else yybegin(REGEXP); return symbol(CLOSECLASS); } + "^" { return symbol(HAT); } + "-" { return symbol(DASH); } + + // this is a hack to keep JLex compatibilty with char class + // expressions like [+-] + "-]" { yypushback(1); yycolumn--; return symbol(CHAR, new Character(yytext().charAt(0))); } + + \" { string.setLength(0); nextState = CHARCLASS; yybegin(STRING_CONTENT); } + + . { return symbol(CHAR, new Character(yytext().charAt(0))); } + + \n { throw new ScannerException(file,ErrorMessages.EOL_IN_CHARCLASS,yyline,yycolumn); } + + <> { throw new ScannerException(file,ErrorMessages.EOF_IN_REGEXP); } +} + + { + \" { yybegin(nextState); return symbol(STRING, string.toString()); } + \\\" { string.append('\"'); } + [^\"\\\u2028\u2029\u000A\u000B\u000C\u000D\u0085]+ { string.append(yytext()); } + + {NL} { throw new ScannerException(file,ErrorMessages.UNTERMINATED_STR, yyline, yycolumn); } + + {HexNumber} { string.append( (char) Integer.parseInt(yytext().substring(2,yytext().length()), 16)); } + {Unicode} { string.append( (char) Integer.parseInt(yytext().substring(2,yytext().length()), 16)); } + {OctNumber} { string.append( (char) Integer.parseInt(yytext().substring(1,yytext().length()), 8)); } + + \\b { string.append('\b'); } + \\n { string.append('\n'); } + \\t { string.append('\t'); } + \\f { string.append('\f'); } + \\r { string.append('\r'); } + + \\. { string.append(yytext().charAt(1)); } + + <> { throw new ScannerException(file,ErrorMessages.EOF_IN_STRING); } +} + + + { + {HexNumber} { return symbol(CHAR, new Character( (char) Integer.parseInt(yytext().substring(2,yytext().length()), 16))); } + {Unicode} { return symbol(CHAR, new Character( (char) Integer.parseInt(yytext().substring(2,yytext().length()), 16))); } + {OctNumber} { return symbol(CHAR, new Character( (char) Integer.parseInt(yytext().substring(1,yytext().length()), 8))); } + + \\b { return symbol(CHAR,new Character('\b')); } + \\n { return symbol(CHAR,new Character('\n')); } + \\t { return symbol(CHAR,new Character('\t')); } + \\f { return symbol(CHAR,new Character('\f')); } + \\r { return symbol(CHAR,new Character('\r')); } + + \\. { return symbol(CHAR, new Character(yytext().charAt(1))); } +} + + + { + "{" { balance++; actionText.append('{'); } + "}" { if (balance > 0) { + balance--; + actionText.append('}'); + } + else { + yybegin(REGEXPSTART); + Action a = new Action(actionText.toString(), action_line); + actions.addElement(a); + return symbol(ACTION, a); + } + } + + {JavaCode} { actionText.append(yytext()); } + + <> { throw new ScannerException(file,ErrorMessages.EOF_IN_ACTION, action_line-1); } +} + + { + + "/"+ "*" { commentbalance++; } + "*"+ "/" { if (commentbalance > 0) + commentbalance--; + else + yybegin(nextState); + } + + {JFlexComment} { /* ignore */ } + + <> { throw new ScannerException(file,ErrorMessages.EOF_IN_COMMENT); } +} + + +. { throw new ScannerException(file,ErrorMessages.UNEXPECTED_CHAR, yyline, yycolumn); } +\n { throw new ScannerException(file,ErrorMessages.UNEXPECTED_NL, yyline, yycolumn); } + +<> { if ( yymoreStreams() ) { + file = (File) files.pop(); + yypopStream(); + } + else + return symbol(EOF); } diff --git a/tools/lexer/jflex-1.4/src/JFlex/LexScan.java b/tools/lexer/jflex-1.4/src/JFlex/LexScan.java new file mode 100644 index 000000000000..796a58a2035f --- /dev/null +++ b/tools/lexer/jflex-1.4/src/JFlex/LexScan.java @@ -0,0 +1,2849 @@ +/* The following code was generated by JFlex 1.4.1 on 11/7/04 2:07 PM */ + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * JFlex 1.4.1 * + * Copyright (C) 1998-2004 Gerwin Klein * + * All rights reserved. * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License. See the file * + * COPYRIGHT for more information. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License along * + * with this program; if not, write to the Free Software Foundation, Inc., * + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +package JFlex; + +import java_cup.runtime.Symbol; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileReader; +import java.util.Stack; +import java.util.Vector; + +/** + * The lexer of JFlex. + * + * Generated by JFlex. + * + * @author Gerwin Klein + * @version JFlex 1.4.1, $Revision: 2.8 $, $Date: 2004/11/07 03:09:30 $ + */ + +public final class LexScan implements sym, java_cup.runtime.Scanner { + + /** This character denotes the end of file */ + public static final int YYEOF = -1; + + /** initial size of the lookahead buffer */ + private static final int ZZ_BUFFERSIZE = 16384; + + /** lexical states */ + public static final int STRING_CONTENT = 16; + public static final int REGEXPSTART = 8; + public static final int MACROS = 6; + public static final int STATELIST = 4; + public static final int EATWSPNL = 24; + public static final int CHARCLASS = 18; + public static final int JAVA_CODE = 12; + public static final int REGEXP = 10; + public static final int YYINITIAL = 0; + public static final int REPEATEXP = 22; + public static final int COMMENT = 2; + public static final int STATES = 14; + public static final int COPY = 20; + + /** + * ZZ_LEXSTATE[l] is the state in the DFA for the lexical state l + * ZZ_LEXSTATE[l+1] is the state in the DFA for the lexical state l + * at the beginning of a line + * l is of the form l = 2*k, k a non negative integer + */ + private static final int ZZ_LEXSTATE[] = { + 0, 0, 1, 1, 2, 2, 3, 4, 5, 5, 6, 6, 7, 7, 8, 8, + 9, 9, 10, 10, 11, 11, 12, 12, 13, 13 + }; + + /** + * Translates characters to character classes + */ + private static final String ZZ_CMAP_PACKED = + "\10\21\1\22\1\10\1\13\2\11\1\12\16\21\4\0\1\10\1\74"+ + "\1\26\1\0\1\102\1\31\1\0\1\27\1\76\1\77\1\24\1\100"+ + "\1\15\1\105\1\14\1\25\1\7\1\62\2\7\2\3\1\63\1\60"+ + "\1\61\1\1\1\104\1\0\1\66\1\65\1\72\1\101\1\0\4\2"+ + "\1\67\1\71\10\20\1\70\13\20\1\16\1\4\1\17\1\103\1\20"+ + "\1\0\1\47\1\53\1\51\1\56\1\42\1\43\1\57\1\36\1\33"+ + "\1\54\1\64\1\45\1\52\1\34\1\40\1\55\1\20\1\37\1\50"+ + "\1\35\1\6\1\46\1\41\1\5\1\44\1\20\1\32\1\73\1\30"+ + "\1\75\6\21\1\23\32\21\2\0\4\20\4\0\1\20\12\0\1\20"+ + "\4\0\1\20\5\0\27\20\1\0\37\20\1\0\u0128\20\2\0\22\20"+ + "\34\0\136\20\2\0\11\20\2\0\7\20\16\0\2\20\16\0\5\20"+ + "\11\0\1\20\21\0\117\21\21\0\3\21\27\0\1\20\13\0\1\20"+ + "\1\0\3\20\1\0\1\20\1\0\24\20\1\0\54\20\1\0\10\20"+ + "\2\0\32\20\14\0\202\20\1\0\4\21\5\0\71\20\2\0\2\20"+ + "\2\0\2\20\3\0\46\20\2\0\2\20\67\0\46\20\2\0\1\20"+ + "\7\0\47\20\11\0\21\21\1\0\27\21\1\0\3\21\1\0\1\21"+ + "\1\0\2\21\1\0\1\21\13\0\33\20\5\0\3\20\56\0\32\20"+ + "\5\0\13\20\13\21\12\0\12\21\6\0\1\21\143\20\1\0\1\20"+ + "\7\21\2\0\6\21\2\20\2\21\1\0\4\21\2\0\12\21\3\20"+ + "\22\0\1\21\1\20\1\21\33\20\3\0\33\21\65\0\46\20\13\21"+ + "\u0150\0\3\21\1\0\65\20\2\0\1\21\1\20\20\21\2\0\1\20"+ + "\4\21\3\0\12\20\2\21\2\0\12\21\21\0\3\21\1\0\10\20"+ + "\2\0\2\20\2\0\26\20\1\0\7\20\1\0\1\20\3\0\4\20"+ + "\2\0\1\21\1\0\7\21\2\0\2\21\2\0\3\21\11\0\1\21"+ + "\4\0\2\20\1\0\3\20\2\21\2\0\12\21\4\20\16\0\1\21"+ + "\2\0\6\20\4\0\2\20\2\0\26\20\1\0\7\20\1\0\2\20"+ + "\1\0\2\20\1\0\2\20\2\0\1\21\1\0\5\21\4\0\2\21"+ + "\2\0\3\21\13\0\4\20\1\0\1\20\7\0\14\21\3\20\14\0"+ + "\3\21\1\0\7\20\1\0\1\20\1\0\3\20\1\0\26\20\1\0"+ + "\7\20\1\0\2\20\1\0\5\20\2\0\1\21\1\20\10\21\1\0"+ + "\3\21\1\0\3\21\2\0\1\20\17\0\1\20\5\0\12\21\21\0"+ + "\3\21\1\0\10\20\2\0\2\20\2\0\26\20\1\0\7\20\1\0"+ + "\2\20\2\0\4\20\2\0\1\21\1\20\6\21\3\0\2\21\2\0"+ + "\3\21\10\0\2\21\4\0\2\20\1\0\3\20\4\0\12\21\22\0"+ + "\2\21\1\0\6\20\3\0\3\20\1\0\4\20\3\0\2\20\1\0"+ + "\1\20\1\0\2\20\3\0\2\20\3\0\3\20\3\0\10\20\1\0"+ + "\3\20\4\0\5\21\3\0\3\21\1\0\4\21\11\0\1\21\17\0"+ + "\11\21\21\0\3\21\1\0\10\20\1\0\3\20\1\0\27\20\1\0"+ + "\12\20\1\0\5\20\4\0\7\21\1\0\3\21\1\0\4\21\7\0"+ + "\2\21\11\0\2\20\4\0\12\21\22\0\2\21\1\0\10\20\1\0"+ + "\3\20\1\0\27\20\1\0\12\20\1\0\5\20\4\0\7\21\1\0"+ + "\3\21\1\0\4\21\7\0\2\21\7\0\1\20\1\0\2\20\4\0"+ + "\12\21\22\0\2\21\1\0\10\20\1\0\3\20\1\0\27\20\1\0"+ + "\20\20\4\0\6\21\2\0\3\21\1\0\4\21\11\0\1\21\10\0"+ + "\2\20\4\0\12\21\22\0\2\21\1\0\22\20\3\0\30\20\1\0"+ + "\11\20\1\0\1\20\2\0\7\20\3\0\1\21\4\0\6\21\1\0"+ + "\1\21\1\0\10\21\22\0\2\21\15\0\60\20\1\21\2\20\7\21"+ + "\4\0\10\20\10\21\1\0\12\21\47\0\2\20\1\0\1\20\2\0"+ + "\2\20\1\0\1\20\2\0\1\20\6\0\4\20\1\0\7\20\1\0"+ + "\3\20\1\0\1\20\1\0\1\20\2\0\2\20\1\0\4\20\1\21"+ + "\2\20\6\21\1\0\2\21\1\20\2\0\5\20\1\0\1\20\1\0"+ + "\6\21\2\0\12\21\2\0\2\20\42\0\1\20\27\0\2\21\6\0"+ + "\12\21\13\0\1\21\1\0\1\21\1\0\1\21\4\0\2\21\10\20"+ + "\1\0\42\20\6\0\24\21\1\0\2\21\4\20\4\0\10\21\1\0"+ + "\44\21\11\0\1\21\71\0\42\20\1\0\5\20\1\0\2\20\1\0"+ + "\7\21\3\0\4\21\6\0\12\21\6\0\6\20\4\21\106\0\46\20"+ + "\12\0\47\20\11\0\132\20\5\0\104\20\5\0\122\20\6\0\7\20"+ + "\1\0\77\20\1\0\1\20\1\0\4\20\2\0\7\20\1\0\1\20"+ + "\1\0\4\20\2\0\47\20\1\0\1\20\1\0\4\20\2\0\37\20"+ + "\1\0\1\20\1\0\4\20\2\0\7\20\1\0\1\20\1\0\4\20"+ + "\2\0\7\20\1\0\7\20\1\0\27\20\1\0\37\20\1\0\1\20"+ + "\1\0\4\20\2\0\7\20\1\0\47\20\1\0\23\20\16\0\11\21"+ + "\56\0\125\20\14\0\u026c\20\2\0\10\20\12\0\32\20\5\0\113\20"+ + "\225\0\64\20\40\21\7\0\1\20\4\0\12\21\41\0\4\21\1\0"+ + "\12\21\6\0\130\20\10\0\51\20\1\21\u0556\0\234\20\4\0\132\20"+ + "\6\0\26\20\2\0\6\20\2\0\46\20\2\0\6\20\2\0\10\20"+ + "\1\0\1\20\1\0\1\20\1\0\1\20\1\0\37\20\2\0\65\20"+ + "\1\0\7\20\1\0\1\20\3\0\3\20\1\0\7\20\3\0\4\20"+ + "\2\0\6\20\4\0\15\20\5\0\3\20\1\0\7\20\17\0\4\21"+ + "\30\0\2\11\5\21\20\0\2\20\51\0\6\21\17\0\1\20\40\0"+ + "\20\20\40\0\15\21\4\0\1\21\40\0\1\20\4\0\1\20\2\0"+ + "\12\20\1\0\1\20\3\0\5\20\6\0\1\20\1\0\1\20\1\0"+ + "\1\20\1\0\4\20\1\0\3\20\1\0\7\20\46\0\44\20\u0e81\0"+ + "\3\20\31\0\11\20\6\21\1\0\5\20\2\0\3\20\6\0\124\20"+ + "\4\0\2\21\2\0\2\20\2\0\136\20\6\0\50\20\4\0\136\20"+ + "\21\0\30\20\u0248\0\u19b6\20\112\0\u51a6\20\132\0\u048d\20\u0773\0\u2ba4\20"+ + "\u215c\0\u012e\20\322\0\7\20\14\0\5\20\5\0\1\20\1\21\12\20"+ + "\1\0\15\20\1\0\5\20\1\0\1\20\1\0\2\20\1\0\2\20"+ + "\1\0\154\20\41\0\u016b\20\22\0\100\20\2\0\66\20\50\0\14\20"+ + "\44\0\4\21\17\0\2\20\30\0\3\20\31\0\1\20\6\0\3\20"+ + "\1\0\1\20\1\0\207\20\2\0\1\21\4\0\1\20\13\0\12\21"+ + "\7\0\32\20\4\0\1\20\1\0\32\20\12\0\132\20\3\0\6\20"+ + "\2\0\6\20\2\0\6\20\2\0\3\20\3\0\2\20\3\0\2\20"+ + "\22\0\3\21\4\0"; + + /** + * Translates characters to character classes + */ + private static final char [] ZZ_CMAP = zzUnpackCMap(ZZ_CMAP_PACKED); + + /** + * Translates DFA states to action switch labels. + */ + private static final int [] ZZ_ACTION = zzUnpackAction(); + + private static final String ZZ_ACTION_PACKED_0 = + "\1\1\1\2\14\0\1\1\2\3\1\1\1\2\3\4"+ + "\1\5\1\6\2\7\1\6\1\10\2\6\1\4\1\11"+ + "\1\12\1\6\1\11\1\13\1\4\1\14\1\15\2\16"+ + "\1\6\2\17\1\20\1\21\1\22\1\23\1\24\1\25"+ + "\1\16\1\26\1\27\1\30\1\31\1\32\1\33\1\34"+ + "\1\35\1\36\1\37\3\4\1\40\1\41\1\6\1\42"+ + "\1\43\1\44\1\4\2\45\1\46\1\16\1\47\1\50"+ + "\1\51\1\52\1\16\1\53\1\54\1\4\2\44\1\4"+ + "\1\55\1\4\1\56\1\13\1\57\3\0\1\60\1\61"+ + "\1\0\1\62\1\0\2\11\1\0\15\11\3\0\1\63"+ + "\1\11\1\64\1\11\1\0\1\65\1\6\1\0\1\66"+ + "\1\67\2\66\1\67\1\70\1\71\1\72\1\73\1\74"+ + "\1\0\1\75\1\0\1\76\1\77\4\0\2\100\10\0"+ + "\1\101\1\102\2\101\1\102\1\103\1\104\1\105\1\106"+ + "\1\107\1\110\3\0\1\111\5\0\1\112\1\0\1\57"+ + "\2\6\1\11\2\113\34\11\3\0\2\114\1\11\2\115"+ + "\1\11\1\0\1\67\1\0\1\116\5\0\1\117\2\0"+ + "\1\37\4\0\1\102\1\0\1\120\1\121\2\122\3\0"+ + "\2\11\1\123\24\11\1\124\11\11\3\0\2\11\1\0"+ + "\2\116\14\0\2\120\3\0\20\11\1\125\3\11\1\126"+ + "\7\11\1\127\6\11\1\130\1\11\1\125\1\0\2\11"+ + "\1\0\1\116\13\0\1\120\5\0\11\11\1\0\1\11"+ + "\1\131\5\11\1\132\1\133\16\11\1\134\1\135\2\11"+ + "\7\0\2\37\10\0\2\136\3\0\11\11\1\137\11\11"+ + "\1\140\3\11\1\141\1\0\3\11\1\142\1\143\2\11"+ + "\6\0\1\144\1\37\3\0\1\37\6\0\2\145\4\0"+ + "\1\135\1\11\1\146\1\123\3\11\1\147\2\150\1\137"+ + "\1\0\11\11\2\151\1\11\1\152\1\11\2\153\1\11"+ + "\1\154\6\0\1\37\6\0\1\37\13\0\1\11\1\155"+ + "\2\11\1\150\1\156\1\150\1\137\1\0\2\11\1\157"+ + "\2\11\1\160\3\11\1\151\1\161\1\151\1\162\1\152"+ + "\1\163\1\153\2\164\1\153\4\0\1\165\1\166\2\37"+ + "\4\0\2\37\7\0\2\167\1\0\3\11\2\156\1\170"+ + "\2\171\1\0\1\11\1\0\5\11\2\161\2\164\2\0"+ + "\1\172\2\0\1\37\2\0\2\37\4\0\1\37\2\0"+ + "\2\37\7\0\2\173\1\11\1\156\1\0\1\170\1\171"+ + "\1\174\1\171\2\0\2\11\1\175\1\11\1\176\1\177"+ + "\2\200\1\161\4\0\1\201\1\0\4\37\3\0\4\37"+ + "\3\0\2\202\1\0\1\173\1\203\1\173\1\204\2\174"+ + "\2\0\2\11\1\175\2\205\1\200\1\206\1\200\7\0"+ + "\3\37\5\0\3\37\1\0\2\207\1\0\2\203\1\174"+ + "\3\0\2\11\1\205\1\210\1\205\2\206\1\211\1\212"+ + "\4\0\1\37\3\0\1\37\2\213\1\203\1\0\1\157"+ + "\1\0\1\157\1\11\2\210\1\206\4\0\1\37\2\0"+ + "\1\37\2\214\1\210\4\0\1\215"; + + private static int [] zzUnpackAction() { + int [] result = new int[764]; + int offset = 0; + offset = zzUnpackAction(ZZ_ACTION_PACKED_0, offset, result); + return result; + } + + private static int zzUnpackAction(String packed, int offset, int [] result) { + int i = 0; /* index in packed string */ + int j = offset; /* index in unpacked array */ + int l = packed.length(); + while (i < l) { + int count = packed.charAt(i++); + int value = packed.charAt(i++); + do result[j++] = value; while (--count > 0); + } + return j; + } + + + /** + * Translates a state to a row index in the transition table + */ + private static final int [] ZZ_ROWMAP = zzUnpackRowMap(); + + private static final String ZZ_ROWMAP_PACKED_0 = + "\0\0\0\106\0\214\0\322\0\u0118\0\u015e\0\u01a4\0\u01ea"+ + "\0\u0230\0\u0276\0\u02bc\0\u0302\0\u0348\0\u038e\0\u03d4\0\u03d4"+ + "\0\u041a\0\u0460\0\u04a6\0\u04ec\0\u0532\0\u041a\0\u0578\0\u05be"+ + "\0\u041a\0\u0604\0\u064a\0\u0690\0\u06d6\0\u071c\0\u0762\0\u07a8"+ + "\0\u07ee\0\u0834\0\u087a\0\u08c0\0\u0906\0\u041a\0\u094c\0\u041a"+ + "\0\u0992\0\u09d8\0\u0a1e\0\u0a64\0\u041a\0\u0aaa\0\u041a\0\u0af0"+ + "\0\u041a\0\u0b36\0\u0b7c\0\u0bc2\0\u041a\0\u041a\0\u041a\0\u041a"+ + "\0\u041a\0\u041a\0\u041a\0\u041a\0\u0c08\0\u0c4e\0\u0c94\0\u0cda"+ + "\0\u041a\0\u041a\0\u0d20\0\u041a\0\u0d66\0\u0dac\0\u0df2\0\u041a"+ + "\0\u0e38\0\u041a\0\u0e7e\0\u0e7e\0\u0aaa\0\u041a\0\u041a\0\u0ec4"+ + "\0\u041a\0\u0f0a\0\u0f50\0\u0f50\0\u041a\0\u0f96\0\u041a\0\u0fdc"+ + "\0\u041a\0\u1022\0\u1068\0\u10ae\0\u10f4\0\u04ec\0\u041a\0\u041a"+ + "\0\u0532\0\u041a\0\u113a\0\u1180\0\u11c6\0\u120c\0\u1252\0\u1298"+ + "\0\u12de\0\u1324\0\u136a\0\u13b0\0\u13f6\0\u143c\0\u1482\0\u14c8"+ + "\0\u150e\0\u1554\0\u159a\0\u15e0\0\u1626\0\u166c\0\u041a\0\u16b2"+ + "\0\u16f8\0\u173e\0\u0906\0\u041a\0\u1784\0\u17ca\0\u041a\0\u1810"+ + "\0\u1856\0\u189c\0\u18e2\0\u041a\0\u041a\0\u041a\0\u041a\0\u041a"+ + "\0\u0a1e\0\u0b36\0\u1928\0\u041a\0\u196e\0\u19b4\0\u0b36\0\u19fa"+ + "\0\u0bc2\0\u041a\0\u1a40\0\u0c4e\0\u0c94\0\u0cda\0\u1a86\0\u1acc"+ + "\0\u1b12\0\u1b58\0\u1b9e\0\u041a\0\u1be4\0\u1c2a\0\u1c70\0\u1cb6"+ + "\0\u041a\0\u041a\0\u041a\0\u041a\0\u041a\0\u041a\0\u0e7e\0\u0aaa"+ + "\0\u1cfc\0\u041a\0\u0f50\0\u1d42\0\u1d88\0\u1dce\0\u1e14\0\u1e5a"+ + "\0\u0fdc\0\u041a\0\u113a\0\u041a\0\u1ea0\0\u120c\0\u041a\0\u1ee6"+ + "\0\u1f2c\0\u1f72\0\u1fb8\0\u1ffe\0\u2044\0\u208a\0\u20d0\0\u2116"+ + "\0\u215c\0\u21a2\0\u21e8\0\u222e\0\u2274\0\u22ba\0\u2300\0\u2346"+ + "\0\u238c\0\u23d2\0\u2418\0\u245e\0\u24a4\0\u24ea\0\u2530\0\u2576"+ + "\0\u25bc\0\u2602\0\u2648\0\u268e\0\u26d4\0\u271a\0\u2760\0\u27a6"+ + "\0\u27ec\0\u2832\0\u2878\0\u28be\0\u2904\0\u041a\0\u294a\0\u2990"+ + "\0\u29d6\0\u2a1c\0\u2a62\0\u2aa8\0\u2aee\0\u041a\0\u2b34\0\u2b7a"+ + "\0\u2bc0\0\u2c06\0\u2c4c\0\u2c92\0\u2cd8\0\u041a\0\u2d1e\0\u2d64"+ + "\0\u041a\0\u1d42\0\u041a\0\u2daa\0\u2df0\0\u2e36\0\u2e7c\0\u2ec2"+ + "\0\u2f08\0\u2f4e\0\u2f94\0\u2fda\0\u3020\0\u3066\0\u30ac\0\u30f2"+ + "\0\u3138\0\u317e\0\u31c4\0\u320a\0\u3250\0\u3296\0\u32dc\0\u3322"+ + "\0\u3368\0\u33ae\0\u33f4\0\u343a\0\u3480\0\u34c6\0\u350c\0\u3552"+ + "\0\u3598\0\u35de\0\u3624\0\u366a\0\u36b0\0\u36f6\0\u373c\0\u3782"+ + "\0\u37c8\0\u380e\0\u3854\0\u389a\0\u38e0\0\u041a\0\u3926\0\u396c"+ + "\0\u39b2\0\u39f8\0\u3a3e\0\u3a84\0\u3aca\0\u3b10\0\u3b56\0\u3b9c"+ + "\0\u3be2\0\u3c28\0\u3c6e\0\u041a\0\u3cb4\0\u3cfa\0\u3d40\0\u3d86"+ + "\0\u3dcc\0\u3e12\0\u3e58\0\u3e9e\0\u3ee4\0\u3f2a\0\u3f70\0\u3fb6"+ + "\0\u3ffc\0\u4042\0\u4088\0\u40ce\0\u4114\0\u415a\0\u41a0\0\u41e6"+ + "\0\u1180\0\u422c\0\u4272\0\u42b8\0\u1180\0\u42fe\0\u4344\0\u438a"+ + "\0\u43d0\0\u4416\0\u445c\0\u44a2\0\u1180\0\u44e8\0\u452e\0\u4574"+ + "\0\u45ba\0\u4600\0\u4646\0\u1180\0\u468c\0\u041a\0\u46d2\0\u4718"+ + "\0\u475e\0\u47a4\0\u294a\0\u47ea\0\u4830\0\u4876\0\u48bc\0\u4902"+ + "\0\u4948\0\u498e\0\u49d4\0\u4a1a\0\u4a60\0\u4aa6\0\u2d1e\0\u4aec"+ + "\0\u4b32\0\u4b78\0\u4bbe\0\u4c04\0\u4c4a\0\u4c90\0\u4cd6\0\u4d1c"+ + "\0\u4d62\0\u4da8\0\u4dee\0\u4e34\0\u4e7a\0\u4ec0\0\u4f06\0\u1180"+ + "\0\u4f4c\0\u4f92\0\u4fd8\0\u501e\0\u5064\0\u1180\0\u1180\0\u50aa"+ + "\0\u50f0\0\u5136\0\u517c\0\u51c2\0\u5208\0\u524e\0\u5294\0\u52da"+ + "\0\u5320\0\u5366\0\u53ac\0\u53f2\0\u5438\0\u1180\0\u041a\0\u547e"+ + "\0\u54c4\0\u550a\0\u5550\0\u5596\0\u55dc\0\u5622\0\u5668\0\u56ae"+ + "\0\u56f4\0\u573a\0\u5780\0\u57c6\0\u580c\0\u5852\0\u5898\0\u58de"+ + "\0\u5924\0\u596a\0\u4b32\0\u041a\0\u59b0\0\u59f6\0\u5a3c\0\u5a82"+ + "\0\u5ac8\0\u5b0e\0\u5b54\0\u5b9a\0\u5be0\0\u5c26\0\u5c6c\0\u5cb2"+ + "\0\u5cf8\0\u5d3e\0\u5d84\0\u5dca\0\u5e10\0\u5e56\0\u5e9c\0\u5ee2"+ + "\0\u5f28\0\u5f6e\0\u1180\0\u5fb4\0\u5ffa\0\u6040\0\u1180\0\u6086"+ + "\0\u60cc\0\u6112\0\u6158\0\u1180\0\u1180\0\u619e\0\u2878\0\u61e4"+ + "\0\u622a\0\u6270\0\u62b6\0\u62fc\0\u6342\0\u6388\0\u63ce\0\u6414"+ + "\0\u645a\0\u64a0\0\u64e6\0\u652c\0\u6572\0\u65b8\0\u65fe\0\u6644"+ + "\0\u668a\0\u5924\0\u041a\0\u66d0\0\u6716\0\u675c\0\u67a2\0\u1180"+ + "\0\u67e8\0\u1180\0\u1180\0\u682e\0\u6874\0\u68ba\0\u1180\0\u6900"+ + "\0\u6946\0\u698c\0\u69d2\0\u6a18\0\u6a5e\0\u6aa4\0\u6aea\0\u6b30"+ + "\0\u6b76\0\u6bbc\0\u6c02\0\u6c48\0\u6c8e\0\u6cd4\0\u6d1a\0\u6d60"+ + "\0\u6da6\0\u6dec\0\u6e32\0\u27a6\0\u041a\0\u6e78\0\u6ebe\0\u6f04"+ + "\0\u6f4a\0\u6f90\0\u6fd6\0\u701c\0\u7062\0\u70a8\0\u70ee\0\u7134"+ + "\0\u717a\0\u71c0\0\u7206\0\u724c\0\u7292\0\u72d8\0\u731e\0\u7364"+ + "\0\u73aa\0\u73f0\0\u7436\0\u747c\0\u74c2\0\u7508\0\u754e\0\u7594"+ + "\0\u75da\0\u7620\0\u7666\0\u76ac\0\u76f2\0\u7738\0\u777e\0\u77c4"+ + "\0\u780a\0\u7850\0\u7896\0\u78dc\0\u1180\0\u7922\0\u7968\0\u79ae"+ + "\0\u79f4\0\u7a3a\0\u7a80\0\u1180\0\u7ac6\0\u1180\0\u7b0c\0\u7b52"+ + "\0\u7b98\0\u7bde\0\u7c24\0\u7c6a\0\u7cb0\0\u7cf6\0\u041a\0\u041a"+ + "\0\u7d3c\0\u7d82\0\u7dc8\0\u7e0e\0\u7e54\0\u7e9a\0\u7ee0\0\u7f26"+ + "\0\u7f6c\0\u7fb2\0\u7ff8\0\u803e\0\u8084\0\u80ca\0\u8110\0\u74c2"+ + "\0\u041a\0\u8156\0\u819c\0\u81e2\0\u8228\0\u826e\0\u82b4\0\u82fa"+ + "\0\u8340\0\u8386\0\u83cc\0\u8412\0\u8458\0\u849e\0\u84e4\0\u852a"+ + "\0\u8570\0\u85b6\0\u85fc\0\u8642\0\u8688\0\u86ce\0\u8714\0\u875a"+ + "\0\u041a\0\u87a0\0\u87e6\0\u882c\0\u8872\0\u88b8\0\u88fe\0\u8944"+ + "\0\u898a\0\u89d0\0\u8a16\0\u8a5c\0\u8aa2\0\u8ae8\0\u8b2e\0\u8b74"+ + "\0\u8bba\0\u8c00\0\u8c46\0\u8c8c\0\u8cd2\0\u8d18\0\u8d5e\0\u8da4"+ + "\0\u8dea\0\u8e30\0\u8e76\0\u8ebc\0\u8f02\0\u8f48\0\u8f8e\0\u8fd4"+ + "\0\u901a\0\u9060\0\u90a6\0\u90ec\0\u9132\0\u9178\0\u91be\0\u1180"+ + "\0\u1180\0\u9204\0\u924a\0\u9290\0\u92d6\0\u931c\0\u9362\0\u93a8"+ + "\0\u041a\0\u93ee\0\u9434\0\u947a\0\u94c0\0\u9506\0\u954c\0\u9592"+ + "\0\u95d8\0\u961e\0\u9664\0\u96aa\0\u96f0\0\u9736\0\u977c\0\u97c2"+ + "\0\u8d5e\0\u041a\0\u9808\0\u984e\0\u9894\0\u98da\0\u9920\0\u9966"+ + "\0\u99ac\0\u99f2\0\u9a38\0\u9a7e\0\u9ac4\0\u9b0a\0\u9b50\0\u9b96"+ + "\0\u9bdc\0\u9c22\0\u9c68\0\u9cae\0\u9cf4\0\u9d3a\0\u9d80\0\u9dc6"+ + "\0\u9e0c\0\u9e52\0\u9e98\0\u9ede\0\u9f24\0\u9f6a\0\u9fb0\0\u9ff6"+ + "\0\ua03c\0\ua082\0\ua0c8\0\ua10e\0\ua154\0\ua19a\0\u97c2\0\u041a"+ + "\0\ua1e0\0\ua226\0\ua26c\0\ua2b2\0\ua2f8\0\ua33e\0\ua384\0\ua3ca"+ + "\0\ua410\0\ua456\0\ua49c\0\ua4e2\0\ua528\0\ua56e\0\u041a\0\u041a"+ + "\0\ua5b4\0\ua5fa\0\ua640\0\ua686\0\ua6cc\0\ua712\0\ua758\0\ua79e"+ + "\0\ua7e4\0\ua1e0\0\u041a\0\ua82a\0\ua870\0\u041a\0\ua8b6\0\u1180"+ + "\0\ua8fc\0\ua942\0\ua988\0\ua9ce\0\uaa14\0\uaa5a\0\uaaa0\0\uaae6"+ + "\0\uab2c\0\uab72\0\uabb8\0\uabfe\0\u041a\0\u1180\0\uac44\0\uac8a"+ + "\0\uacd0\0\uad16\0\uad5c\0\u041a"; + + private static int [] zzUnpackRowMap() { + int [] result = new int[764]; + int offset = 0; + offset = zzUnpackRowMap(ZZ_ROWMAP_PACKED_0, offset, result); + return result; + } + + private static int zzUnpackRowMap(String packed, int offset, int [] result) { + int i = 0; /* index in packed string */ + int j = offset; /* index in unpacked array */ + int l = packed.length(); + while (i < l) { + int high = packed.charAt(i++) << 16; + result[j++] = high | packed.charAt(i++); + } + return j; + } + + /** + * The transition table of the DFA + */ + private static final int [] ZZ_TRANS = zzUnpackTrans(); + + private static final String ZZ_TRANS_PACKED_0 = + "\11\17\2\20\1\21\7\17\1\20\5\17\1\22\54\17"+ + "\24\23\1\24\1\25\60\23\2\26\1\27\2\26\2\27"+ + "\1\26\1\30\1\31\1\32\1\31\1\26\1\33\2\26"+ + "\1\27\2\26\1\31\7\26\25\27\4\26\1\27\2\26"+ + "\3\27\10\26\1\27\5\26\1\34\2\26\2\34\1\26"+ + "\1\35\3\36\4\26\1\34\1\26\1\35\1\36\1\26"+ + "\1\37\3\26\1\40\1\26\25\34\4\26\1\34\1\41"+ + "\1\26\3\34\10\26\1\34\5\26\1\34\2\26\2\34"+ + "\1\26\1\42\3\36\4\26\1\34\1\26\1\42\1\36"+ + "\1\26\1\37\3\26\1\43\1\26\25\34\4\26\1\34"+ + "\1\41\1\26\3\34\10\26\1\34\13\26\4\44\6\26"+ + "\2\44\1\26\1\45\2\26\1\46\35\26\1\47\17\26"+ + "\4\50\1\51\3\50\1\52\1\53\1\54\1\53\1\55"+ + "\1\50\1\56\3\50\1\52\1\53\1\57\1\60\1\61"+ + "\3\50\1\62\33\50\1\63\4\50\1\64\1\65\1\66"+ + "\1\67\1\70\1\71\1\72\1\73\1\74\2\50\25\75"+ + "\1\76\1\77\1\100\1\101\1\75\1\102\53\75\2\26"+ + "\1\34\2\26\2\34\1\26\4\103\1\26\1\104\2\26"+ + "\1\34\1\26\2\103\7\26\25\34\4\26\1\34\2\26"+ + "\3\34\1\105\7\26\1\34\3\26\4\106\1\107\4\106"+ + "\1\110\1\111\1\110\7\106\1\110\2\106\1\112\57\106"+ + "\4\50\1\51\3\50\3\113\1\114\2\50\1\115\1\116"+ + "\2\50\2\113\2\50\1\117\3\50\1\120\50\50\1\121"+ + "\1\50\1\122\11\123\2\124\1\125\7\123\1\124\5\123"+ + "\1\126\54\123\10\26\1\35\2\26\1\127\1\26\1\130"+ + "\4\26\1\35\5\26\1\131\65\26\4\132\6\26\2\132"+ + "\62\26\11\17\2\20\1\21\7\17\1\20\62\17\106\0"+ + "\11\17\2\20\1\21\7\17\1\20\5\17\1\133\54\17"+ + "\24\23\1\134\1\135\104\23\1\136\1\137\104\23\1\140"+ + "\1\141\60\23\1\0\3\27\1\0\3\27\10\0\4\27"+ + "\7\0\32\27\2\0\3\27\10\0\1\27\13\0\1\30"+ + "\4\0\1\33\103\0\1\31\102\0\1\33\76\0\3\34"+ + "\1\0\3\34\10\0\4\34\7\0\32\34\2\0\3\34"+ + "\10\0\1\34\13\0\1\35\11\0\1\35\74\0\3\36"+ + "\7\0\1\36\106\0\1\142\1\143\62\0\1\144\2\0"+ + "\1\144\1\145\11\0\1\144\11\0\1\146\1\147\1\150"+ + "\1\151\4\144\1\152\1\153\1\154\1\155\1\144\1\156"+ + "\1\157\1\160\1\144\1\161\1\144\1\162\1\163\1\144"+ + "\1\164\1\165\1\166\1\0\1\144\2\0\3\144\10\0"+ + "\1\144\13\0\1\41\11\0\1\41\73\0\1\42\11\0"+ + "\1\42\6\0\1\167\56\0\1\144\2\0\1\170\1\145"+ + "\11\0\1\144\10\0\1\171\1\146\1\147\1\150\1\151"+ + "\4\144\1\152\1\153\1\154\1\155\1\144\1\156\1\172"+ + "\1\160\1\144\1\161\1\144\1\162\1\163\1\144\1\164"+ + "\1\165\1\166\1\0\1\144\2\0\3\144\10\0\1\144"+ + "\13\0\4\44\6\0\2\44\1\0\1\173\2\0\1\46"+ + "\35\0\1\47\43\0\1\174\1\175\146\0\1\176\17\0"+ + "\3\177\1\200\1\177\1\201\1\202\1\203\3\177\1\0"+ + "\20\177\1\204\1\205\1\177\1\206\3\177\1\207\7\177"+ + "\1\210\4\177\1\200\1\177\1\203\1\200\22\177\10\0"+ + "\1\52\3\211\1\55\1\0\1\56\3\0\1\52\1\211"+ + "\1\57\1\60\1\61\3\0\1\212\40\0\1\64\1\65"+ + "\1\66\1\67\1\70\1\71\1\72\1\73\1\74\12\0"+ + "\4\211\1\55\1\0\1\56\3\0\2\211\1\57\1\60"+ + "\1\61\3\0\1\212\40\0\1\64\1\65\1\66\1\67"+ + "\1\70\1\71\1\72\1\73\1\74\12\0\3\211\1\53"+ + "\1\55\1\0\1\56\3\0\2\211\1\57\1\60\1\61"+ + "\3\0\1\212\40\0\1\64\1\65\1\66\1\67\1\70"+ + "\1\71\1\72\1\73\1\74\106\0\1\213\25\0\1\214"+ + "\1\175\61\0\1\215\1\216\1\215\1\0\2\216\1\215"+ + "\1\217\7\0\1\216\1\0\1\217\10\0\25\216\4\215"+ + "\1\216\2\0\3\216\10\0\1\216\71\0\1\220\27\0"+ + "\1\221\1\222\1\223\1\222\6\0\1\221\1\222\62\0"+ + "\25\75\1\224\1\225\1\226\1\0\1\75\1\0\77\75"+ + "\1\227\1\230\60\75\4\225\1\231\4\225\3\0\7\225"+ + "\1\0\2\225\1\75\57\225\4\232\1\233\4\232\3\0"+ + "\7\232\1\0\3\232\1\0\56\232\10\0\4\103\6\0"+ + "\2\103\72\0\4\105\6\0\2\105\62\0\4\106\1\0"+ + "\4\106\3\0\7\106\1\0\2\106\1\0\57\106\3\234"+ + "\1\235\1\234\1\236\1\237\1\240\3\234\1\0\12\234"+ + "\1\241\5\234\1\242\1\243\1\234\1\244\3\234\1\245"+ + "\7\234\1\246\4\234\1\235\1\234\1\240\1\235\22\234"+ + "\13\0\1\110\102\0\4\247\2\0\1\250\3\0\2\247"+ + "\64\0\1\251\2\0\2\251\11\0\1\251\12\0\25\251"+ + "\4\0\1\251\2\0\3\251\10\0\1\251\22\0\1\252"+ + "\66\0\11\253\2\124\1\125\7\253\1\124\73\253\2\124"+ + "\1\125\7\253\1\124\4\253\1\254\2\253\1\255\6\253"+ + "\1\256\1\253\1\257\41\253\1\0\1\260\1\0\1\260"+ + "\3\0\1\260\1\261\11\0\1\261\35\0\4\260\32\0"+ + "\4\132\6\0\2\132\62\0\13\133\1\262\72\133\24\23"+ + "\1\134\1\0\104\23\1\0\1\135\60\23\11\143\2\263"+ + "\1\264\7\143\1\263\62\143\1\0\3\144\1\0\3\144"+ + "\10\0\4\144\7\0\32\144\2\0\3\144\10\0\1\144"+ + "\4\0\3\144\1\0\3\144\10\0\4\144\7\0\1\144"+ + "\1\265\30\144\2\0\3\144\10\0\1\144\3\0\11\146"+ + "\2\266\1\267\7\146\1\266\62\146\1\0\3\144\1\0"+ + "\3\144\10\0\4\144\7\0\1\144\1\270\15\144\1\271"+ + "\4\144\1\272\5\144\2\0\3\144\10\0\1\144\4\0"+ + "\3\144\1\0\3\144\10\0\4\144\7\0\5\144\1\273"+ + "\24\144\2\0\3\144\10\0\1\144\4\0\3\144\1\0"+ + "\3\144\10\0\4\144\7\0\3\144\1\274\5\144\1\275"+ + "\2\144\1\276\15\144\2\0\3\144\10\0\1\144\4\0"+ + "\3\144\1\0\1\277\2\144\10\0\4\144\7\0\5\144"+ + "\1\300\24\144\2\0\3\144\10\0\1\144\4\0\3\144"+ + "\1\0\1\144\1\301\1\144\10\0\4\144\7\0\1\302"+ + "\31\144\2\0\3\144\10\0\1\144\4\0\3\144\1\0"+ + "\3\144\10\0\4\144\7\0\11\144\1\303\20\144\2\0"+ + "\3\144\10\0\1\144\4\0\3\144\1\0\3\144\10\0"+ + "\4\144\7\0\1\304\31\144\2\0\3\144\10\0\1\144"+ + "\4\0\3\144\1\0\3\144\10\0\4\144\7\0\20\144"+ + "\1\305\1\144\1\306\7\144\2\0\3\144\10\0\1\144"+ + "\4\0\3\144\1\0\3\144\10\0\4\144\7\0\2\144"+ + "\1\307\3\144\1\310\7\144\1\311\13\144\2\0\3\144"+ + "\10\0\1\144\4\0\3\144\1\0\1\144\1\312\1\144"+ + "\10\0\4\144\7\0\3\144\1\313\1\144\1\314\4\144"+ + "\1\315\1\144\1\316\15\144\2\0\3\144\10\0\1\144"+ + "\4\0\3\144\1\0\1\144\1\317\1\144\10\0\4\144"+ + "\7\0\11\144\1\320\20\144\2\0\3\144\10\0\1\144"+ + "\4\0\3\144\1\0\1\144\1\321\1\144\10\0\4\144"+ + "\7\0\14\144\1\322\15\144\2\0\3\144\10\0\1\144"+ + "\4\0\3\144\1\0\3\144\10\0\4\144\7\0\7\144"+ + "\1\323\22\144\2\0\3\144\10\0\1\144\56\0\1\324"+ + "\105\0\1\325\115\0\1\326\23\0\3\144\1\0\3\144"+ + "\1\327\7\0\2\144\1\330\1\144\7\0\15\144\1\331"+ + "\14\144\2\0\3\144\10\0\1\144\3\0\11\171\3\0"+ + "\7\171\1\0\62\171\1\0\3\144\1\0\3\144\1\332"+ + "\7\0\2\144\1\333\1\144\7\0\2\144\1\334\3\144"+ + "\1\310\7\144\1\311\13\144\2\0\3\144\10\0\1\144"+ + "\3\0\11\175\3\0\7\175\1\0\62\175\67\0\1\335"+ + "\21\0\1\336\3\0\1\336\50\0\1\336\1\0\2\336"+ + "\23\0\3\337\3\0\1\337\32\0\2\337\3\0\1\337"+ + "\1\0\1\337\1\0\1\337\2\0\1\337\1\0\4\337"+ + "\3\0\1\337\1\0\1\337\15\0\3\340\3\0\1\340"+ + "\32\0\2\340\3\0\1\340\1\0\1\340\1\0\1\340"+ + "\2\0\1\340\1\0\4\340\3\0\1\340\1\0\1\340"+ + "\17\0\1\200\3\0\1\200\50\0\1\200\1\0\2\200"+ + "\30\0\1\341\36\0\1\342\6\0\1\343\1\0\1\344"+ + "\30\0\1\215\1\0\1\215\3\0\1\215\50\0\4\215"+ + "\23\0\3\216\1\0\3\216\1\345\7\0\4\216\4\0"+ + "\1\346\2\0\32\216\2\0\3\216\10\0\1\216\72\0"+ + "\1\347\31\0\1\222\72\0\24\227\1\350\61\227\11\230"+ + "\2\351\1\75\7\230\1\351\62\230\11\225\3\0\7\225"+ + "\1\0\62\225\27\0\1\75\56\0\3\232\1\352\1\353"+ + "\1\232\1\354\1\355\1\232\3\0\7\232\1\0\34\232"+ + "\1\352\1\232\1\355\1\352\22\232\3\0\1\356\3\0"+ + "\1\356\50\0\1\356\1\0\2\356\23\0\3\357\3\0"+ + "\1\357\32\0\2\357\3\0\1\357\1\0\1\357\1\0"+ + "\1\357\2\0\1\357\1\0\4\357\3\0\1\357\1\0"+ + "\1\357\15\0\3\360\3\0\1\360\32\0\2\360\3\0"+ + "\1\360\1\0\1\360\1\0\1\360\2\0\1\360\1\0"+ + "\4\360\3\0\1\360\1\0\1\360\17\0\1\235\3\0"+ + "\1\235\50\0\1\235\1\0\2\235\23\0\3\251\1\0"+ + "\3\251\10\0\4\251\4\0\1\361\2\0\32\251\2\0"+ + "\3\251\10\0\1\251\3\0\11\254\2\362\1\363\7\254"+ + "\1\362\62\254\11\253\2\124\1\125\7\253\1\124\10\253"+ + "\1\364\62\253\2\124\1\125\7\253\1\124\14\253\1\365"+ + "\56\253\2\124\1\125\7\253\1\124\20\253\1\366\41\253"+ + "\1\0\1\260\1\0\1\260\3\0\1\260\50\0\4\260"+ + "\23\0\3\144\1\0\3\144\10\0\4\144\7\0\1\367"+ + "\31\144\2\0\3\144\10\0\1\144\4\0\3\144\1\0"+ + "\3\144\10\0\4\144\7\0\1\370\1\144\1\371\13\144"+ + "\1\372\13\144\2\0\3\144\10\0\1\144\4\0\3\144"+ + "\1\0\3\144\10\0\4\144\7\0\22\144\1\373\7\144"+ + "\2\0\3\144\10\0\1\144\4\0\3\144\1\0\3\144"+ + "\10\0\4\144\7\0\1\144\1\374\30\144\2\0\3\144"+ + "\10\0\1\144\4\0\3\144\1\0\3\144\10\0\4\144"+ + "\7\0\2\144\1\375\27\144\2\0\3\144\10\0\1\144"+ + "\4\0\3\144\1\0\3\144\10\0\4\144\7\0\4\144"+ + "\1\376\25\144\2\0\3\144\10\0\1\144\4\0\3\144"+ + "\1\0\3\144\10\0\4\144\7\0\22\144\1\377\7\144"+ + "\2\0\3\144\10\0\1\144\4\0\3\144\1\0\3\144"+ + "\10\0\4\144\7\0\20\144\1\u0100\11\144\2\0\3\144"+ + "\10\0\1\144\4\0\3\144\1\0\3\144\10\0\4\144"+ + "\7\0\2\144\1\u0101\27\144\2\0\3\144\10\0\1\144"+ + "\4\0\3\144\1\0\3\144\10\0\4\144\7\0\10\144"+ + "\1\u0102\21\144\2\0\3\144\10\0\1\144\4\0\3\144"+ + "\1\0\3\144\10\0\4\144\7\0\1\144\1\u0103\10\144"+ + "\1\u0104\17\144\2\0\3\144\10\0\1\144\4\0\3\144"+ + "\1\0\3\144\10\0\4\144\7\0\1\144\1\u0105\30\144"+ + "\2\0\3\144\10\0\1\144\4\0\3\144\1\0\3\144"+ + "\10\0\4\144\7\0\7\144\1\u0106\2\144\1\u0107\17\144"+ + "\2\0\3\144\10\0\1\144\4\0\3\144\1\0\3\144"+ + "\10\0\4\144\7\0\1\144\1\u0108\30\144\2\0\3\144"+ + "\10\0\1\144\4\0\3\144\1\0\3\144\10\0\4\144"+ + "\7\0\15\144\1\u0109\14\144\2\0\3\144\10\0\1\144"+ + "\4\0\3\144\1\0\3\144\10\0\4\144\7\0\1\u010a"+ + "\31\144\2\0\3\144\10\0\1\144\4\0\3\144\1\0"+ + "\3\144\10\0\4\144\7\0\14\144\1\u010b\15\144\2\0"+ + "\3\144\10\0\1\144\4\0\3\144\1\0\3\144\10\0"+ + "\4\144\7\0\1\u010c\31\144\2\0\3\144\10\0\1\144"+ + "\4\0\3\144\1\0\3\144\10\0\4\144\7\0\14\144"+ + "\1\u010d\15\144\2\0\3\144\10\0\1\144\4\0\3\144"+ + "\1\0\3\144\10\0\4\144\7\0\22\144\1\u010e\7\144"+ + "\2\0\3\144\10\0\1\144\4\0\3\144\1\0\3\144"+ + "\10\0\4\144\7\0\14\144\1\u010f\15\144\2\0\3\144"+ + "\10\0\1\144\4\0\3\144\1\0\3\144\10\0\4\144"+ + "\7\0\12\144\1\u0110\17\144\2\0\3\144\10\0\1\144"+ + "\4\0\3\144\1\0\3\144\10\0\4\144\7\0\14\144"+ + "\1\u0111\15\144\2\0\3\144\10\0\1\144\4\0\3\144"+ + "\1\0\3\144\10\0\4\144\7\0\15\144\1\u0112\14\144"+ + "\2\0\3\144\10\0\1\144\4\0\3\144\1\0\3\144"+ + "\10\0\4\144\7\0\10\144\1\u0113\21\144\2\0\3\144"+ + "\10\0\1\144\4\0\3\144\1\0\3\144\10\0\4\144"+ + "\7\0\14\144\1\u0114\15\144\2\0\3\144\10\0\1\144"+ + "\4\0\3\144\1\0\3\144\10\0\4\144\7\0\20\144"+ + "\1\u0115\11\144\2\0\3\144\10\0\1\144\4\0\3\144"+ + "\1\0\3\144\10\0\4\144\7\0\16\144\1\u0116\13\144"+ + "\2\0\3\144\10\0\1\144\4\0\3\144\1\0\3\144"+ + "\10\0\4\144\7\0\20\144\1\u0117\11\144\2\0\3\144"+ + "\10\0\1\144\36\0\1\u0118\105\0\1\u0119\125\0\1\u011a"+ + "\42\0\1\327\11\0\1\327\64\0\3\144\1\0\3\144"+ + "\1\327\7\0\2\144\1\330\1\144\7\0\32\144\2\0"+ + "\3\144\10\0\1\144\4\0\3\144\1\0\3\144\10\0"+ + "\4\144\7\0\2\144\1\u011b\27\144\2\0\3\144\10\0"+ + "\1\144\13\0\1\332\11\0\1\332\64\0\3\144\1\0"+ + "\3\144\1\332\7\0\2\144\1\333\1\144\7\0\32\144"+ + "\2\0\3\144\10\0\1\144\4\0\3\144\1\0\3\144"+ + "\10\0\4\144\7\0\14\144\1\u011c\15\144\2\0\3\144"+ + "\10\0\1\144\73\0\1\u011d\16\0\3\u011e\3\0\1\u011e"+ + "\32\0\2\u011e\3\0\1\u011e\1\0\1\u011e\1\0\1\u011e"+ + "\2\0\1\u011e\1\0\4\u011e\3\0\1\u011e\1\0\1\u011e"+ + "\15\0\3\u011f\3\0\1\u011f\32\0\2\u011f\3\0\1\u011f"+ + "\1\0\1\u011f\1\0\1\u011f\2\0\1\u011f\1\0\4\u011f"+ + "\3\0\1\u011f\1\0\1\u011f\71\0\1\u0120\70\0\1\u0121"+ + "\1\0\1\u0122\110\0\1\u0123\73\0\1\u0124\62\0\1\345"+ + "\11\0\1\345\5\0\1\346\145\0\1\u0125\15\0\24\227"+ + "\1\350\1\75\60\227\13\351\1\75\11\351\1\u0126\1\u0127"+ + "\1\u0128\1\230\1\351\1\230\53\351\3\0\1\232\3\0"+ + "\1\232\17\0\1\75\30\0\1\232\1\0\2\232\26\0"+ + "\1\u0129\1\0\1\u012a\20\0\1\75\57\0\3\u012b\3\0"+ + "\1\u012b\17\0\1\75\12\0\2\u012b\3\0\1\u012b\1\0"+ + "\1\u012b\1\0\1\u012b\2\0\1\u012b\1\0\4\u012b\3\0"+ + "\1\u012b\1\0\1\u012b\17\0\1\352\3\0\1\352\17\0"+ + "\1\75\30\0\1\352\1\0\2\352\23\0\3\u012c\3\0"+ + "\1\u012c\32\0\2\u012c\3\0\1\u012c\1\0\1\u012c\1\0"+ + "\1\u012c\2\0\1\u012c\1\0\4\u012c\3\0\1\u012c\1\0"+ + "\1\u012c\15\0\3\u012d\3\0\1\u012d\32\0\2\u012d\3\0"+ + "\1\u012d\1\0\1\u012d\1\0\1\u012d\2\0\1\u012d\1\0"+ + "\4\u012d\3\0\1\u012d\1\0\1\u012d\14\0\11\253\2\124"+ + "\1\125\7\253\1\124\7\253\1\u012e\63\253\2\124\1\125"+ + "\7\253\1\124\17\253\1\u012f\53\253\2\124\1\125\7\253"+ + "\1\124\21\253\1\u0130\40\253\1\0\3\144\1\0\3\144"+ + "\10\0\4\144\7\0\16\144\1\u0131\13\144\2\0\3\144"+ + "\10\0\1\144\4\0\3\144\1\0\3\144\10\0\4\144"+ + "\7\0\2\144\1\u0132\27\144\2\0\3\144\10\0\1\144"+ + "\4\0\3\144\1\0\3\144\10\0\4\144\7\0\6\144"+ + "\1\u0133\1\u0134\22\144\2\0\3\144\10\0\1\144\4\0"+ + "\3\144\1\0\3\144\10\0\4\144\7\0\12\144\1\u0135"+ + "\17\144\2\0\3\144\10\0\1\144\4\0\3\144\1\0"+ + "\3\144\10\0\4\144\7\0\12\144\1\u0136\17\144\2\0"+ + "\3\144\10\0\1\144\4\0\3\144\1\0\3\144\10\0"+ + "\4\144\7\0\5\144\1\u0137\24\144\2\0\3\144\10\0"+ + "\1\144\4\0\3\144\1\0\1\144\1\u0138\1\144\10\0"+ + "\4\144\7\0\32\144\2\0\3\144\10\0\1\144\4\0"+ + "\3\144\1\0\3\144\10\0\4\144\7\0\5\144\1\u0139"+ + "\24\144\2\0\3\144\10\0\1\144\4\0\3\144\1\0"+ + "\3\144\10\0\4\144\7\0\7\144\1\u013a\22\144\2\0"+ + "\3\144\10\0\1\144\4\0\3\144\1\0\3\144\10\0"+ + "\4\144\7\0\12\144\1\u013b\17\144\2\0\3\144\10\0"+ + "\1\144\4\0\3\144\1\0\3\144\10\0\4\144\7\0"+ + "\7\144\1\u013c\22\144\2\0\3\144\10\0\1\144\4\0"+ + "\3\144\1\0\3\144\10\0\4\144\6\0\1\146\2\144"+ + "\1\u013d\10\144\1\u013e\2\144\1\u013f\13\144\2\0\3\144"+ + "\10\0\1\144\4\0\3\144\1\0\3\144\10\0\4\144"+ + "\7\0\16\144\1\u0140\13\144\2\0\3\144\10\0\1\144"+ + "\4\0\3\144\1\0\3\144\10\0\4\144\7\0\12\144"+ + "\1\u0141\17\144\2\0\3\144\10\0\1\144\4\0\3\144"+ + "\1\0\3\144\10\0\4\144\7\0\14\144\1\u0142\15\144"+ + "\2\0\3\144\10\0\1\144\4\0\3\144\1\0\3\144"+ + "\10\0\4\144\7\0\5\144\1\u0143\24\144\2\0\3\144"+ + "\10\0\1\144\4\0\3\144\1\0\3\144\10\0\4\144"+ + "\7\0\7\144\1\u0144\22\144\2\0\3\144\10\0\1\144"+ + "\4\0\3\144\1\0\3\144\10\0\4\144\7\0\7\144"+ + "\1\u0145\22\144\2\0\3\144\10\0\1\144\4\0\3\144"+ + "\1\0\3\144\10\0\4\144\7\0\2\144\1\u0146\27\144"+ + "\2\0\3\144\10\0\1\144\4\0\3\144\1\0\3\144"+ + "\10\0\4\144\7\0\22\144\1\u0147\7\144\2\0\3\144"+ + "\10\0\1\144\4\0\3\144\1\0\3\144\10\0\4\144"+ + "\7\0\1\144\1\u0148\30\144\2\0\3\144\10\0\1\144"+ + "\4\0\3\144\1\0\3\144\10\0\4\144\7\0\2\144"+ + "\1\u0149\27\144\2\0\3\144\10\0\1\144\4\0\3\144"+ + "\1\0\3\144\10\0\4\144\7\0\1\144\1\u014a\30\144"+ + "\2\0\3\144\10\0\1\144\4\0\3\144\1\0\3\144"+ + "\10\0\4\144\7\0\15\144\1\u014b\5\144\1\u014c\6\144"+ + "\2\0\3\144\10\0\1\144\4\0\3\144\1\0\3\144"+ + "\10\0\4\144\7\0\4\144\1\u014d\25\144\2\0\3\144"+ + "\10\0\1\144\4\0\3\144\1\0\1\144\1\u014e\1\144"+ + "\10\0\4\144\7\0\32\144\2\0\3\144\10\0\1\144"+ + "\4\0\3\144\1\0\3\144\10\0\4\144\7\0\15\144"+ + "\1\u014f\14\144\2\0\3\144\10\0\1\144\4\0\3\144"+ + "\1\0\3\144\10\0\4\144\7\0\7\144\1\u0150\22\144"+ + "\2\0\3\144\10\0\1\144\4\0\3\144\1\0\3\144"+ + "\10\0\4\144\7\0\10\144\1\u0151\21\144\2\0\3\144"+ + "\10\0\1\144\4\0\3\144\1\0\3\144\10\0\4\144"+ + "\7\0\16\144\1\u0152\13\144\2\0\3\144\10\0\1\144"+ + "\4\0\3\144\1\0\3\144\10\0\4\144\7\0\12\144"+ + "\1\u0153\17\144\2\0\3\144\10\0\1\144\4\0\3\144"+ + "\1\0\3\144\10\0\4\144\7\0\31\144\1\u0154\2\0"+ + "\3\144\10\0\1\144\4\0\3\144\1\0\1\144\1\u0155"+ + "\1\144\10\0\4\144\7\0\32\144\2\0\3\144\10\0"+ + "\1\144\40\0\1\264\105\0\1\u0156\103\0\1\u0157\53\0"+ + "\3\144\1\0\3\144\10\0\4\144\7\0\14\144\1\u0158"+ + "\15\144\2\0\3\144\10\0\1\144\4\0\3\144\1\0"+ + "\3\144\10\0\4\144\7\0\1\144\1\u0148\1\u0159\27\144"+ + "\2\0\3\144\10\0\1\144\74\0\1\u015a\15\0\3\u015b"+ + "\3\0\1\u015b\32\0\2\u015b\3\0\1\u015b\1\0\1\u015b"+ + "\1\0\1\u015b\2\0\1\u015b\1\0\4\u015b\3\0\1\u015b"+ + "\1\0\1\u015b\71\0\1\u015c\71\0\1\u015d\101\0\1\u015e"+ + "\112\0\1\u015f\122\0\1\u0160\117\0\1\u0161\14\0\13\351"+ + "\1\75\10\351\1\u0162\1\230\60\351\4\u0127\1\u0163\4\u0127"+ + "\2\351\1\75\7\u0127\1\351\2\u0127\1\351\57\u0127\4\u0164"+ + "\1\u0165\4\u0164\2\351\1\75\7\u0164\1\351\3\u0164\1\230"+ + "\56\u0164\4\0\1\u0129\1\0\1\u012a\100\0\3\u012b\3\0"+ + "\1\u012b\32\0\2\u012b\3\0\1\u012b\1\0\1\u012b\1\0"+ + "\1\u012b\2\0\1\u012b\1\0\4\u012b\3\0\1\u012b\1\0"+ + "\1\u012b\15\0\3\u0166\3\0\1\u0166\32\0\2\u0166\3\0"+ + "\1\u0166\1\0\1\u0166\1\0\1\u0166\2\0\1\u0166\1\0"+ + "\4\u0166\3\0\1\u0166\1\0\1\u0166\15\0\3\u0167\3\0"+ + "\1\u0167\32\0\2\u0167\3\0\1\u0167\1\0\1\u0167\1\0"+ + "\1\u0167\2\0\1\u0167\1\0\4\u0167\3\0\1\u0167\1\0"+ + "\1\u0167\14\0\11\253\2\124\1\125\7\253\1\124\11\253"+ + "\1\u0168\61\253\2\124\1\125\7\253\1\124\4\253\1\u0169"+ + "\4\253\1\u016a\10\253\1\u016b\50\253\2\124\1\125\7\253"+ + "\1\124\16\253\1\u016c\43\253\1\0\3\144\1\0\3\144"+ + "\10\0\4\144\7\0\5\144\1\u016d\24\144\2\0\3\144"+ + "\10\0\1\144\4\0\3\144\1\0\3\144\10\0\4\144"+ + "\6\0\1\146\2\144\1\u016e\27\144\2\0\3\144\10\0"+ + "\1\144\4\0\3\144\1\0\3\144\10\0\4\144\7\0"+ + "\4\144\1\u016f\25\144\2\0\3\144\10\0\1\144\4\0"+ + "\3\144\1\0\3\144\10\0\4\144\7\0\24\144\1\u0170"+ + "\5\144\2\0\3\144\10\0\1\144\4\0\3\144\1\0"+ + "\1\144\1\u0171\1\144\10\0\4\144\7\0\32\144\2\0"+ + "\3\144\10\0\1\144\4\0\3\144\1\0\3\144\10\0"+ + "\4\144\7\0\7\144\1\u0172\22\144\2\0\3\144\10\0"+ + "\1\144\4\0\3\144\1\0\3\144\10\0\4\144\7\0"+ + "\4\144\1\u0173\25\144\2\0\3\144\10\0\1\144\4\0"+ + "\3\144\1\0\3\144\10\0\4\144\7\0\1\144\1\u0174"+ + "\30\144\2\0\3\144\10\0\1\144\4\0\3\144\1\0"+ + "\3\144\10\0\4\144\7\0\6\144\1\u0175\23\144\2\0"+ + "\3\144\10\0\1\144\4\0\3\144\1\0\3\144\1\u0176"+ + "\7\0\2\144\1\u0177\1\144\7\0\32\144\2\0\3\144"+ + "\10\0\1\144\4\0\3\144\1\0\3\144\10\0\4\144"+ + "\7\0\7\144\1\u0178\22\144\2\0\3\144\10\0\1\144"+ + "\4\0\3\144\1\0\3\144\10\0\4\144\7\0\1\144"+ + "\1\u0179\30\144\2\0\3\144\10\0\1\144\4\0\3\144"+ + "\1\0\3\144\10\0\4\144\7\0\3\144\1\u017a\26\144"+ + "\2\0\3\144\10\0\1\144\4\0\3\144\1\0\3\144"+ + "\10\0\4\144\7\0\14\144\1\u017b\15\144\2\0\3\144"+ + "\10\0\1\144\4\0\3\144\1\0\3\144\10\0\4\144"+ + "\7\0\12\144\1\u017c\17\144\2\0\3\144\10\0\1\144"+ + "\4\0\3\144\1\0\3\144\10\0\4\144\7\0\2\144"+ + "\1\u017d\27\144\2\0\3\144\10\0\1\144\4\0\3\144"+ + "\1\0\3\144\10\0\4\144\7\0\12\144\1\u017e\17\144"+ + "\2\0\3\144\10\0\1\144\4\0\3\144\1\0\3\144"+ + "\10\0\4\144\7\0\10\144\1\u017f\21\144\2\0\3\144"+ + "\10\0\1\144\4\0\3\144\1\0\1\u0180\2\144\10\0"+ + "\4\144\7\0\32\144\2\0\3\144\10\0\1\144\4\0"+ + "\3\144\1\0\3\144\10\0\4\144\7\0\4\144\1\u0181"+ + "\25\144\2\0\3\144\10\0\1\144\4\0\3\144\1\0"+ + "\3\144\10\0\4\144\7\0\4\144\1\u0182\25\144\2\0"+ + "\3\144\10\0\1\144\4\0\3\144\1\0\3\144\10\0"+ + "\4\144\7\0\23\144\1\u0183\6\144\2\0\3\144\10\0"+ + "\1\144\4\0\3\144\1\0\3\144\10\0\4\144\7\0"+ + "\16\144\1\u0184\13\144\2\0\3\144\10\0\1\144\4\0"+ + "\3\144\1\0\3\144\10\0\4\144\7\0\7\144\1\u0185"+ + "\22\144\2\0\3\144\10\0\1\144\4\0\3\144\1\0"+ + "\3\144\10\0\4\144\7\0\11\144\1\u0186\20\144\2\0"+ + "\3\144\10\0\1\144\4\0\3\144\1\0\3\144\10\0"+ + "\4\144\7\0\7\144\1\u0187\22\144\2\0\3\144\10\0"+ + "\1\144\4\0\3\144\1\0\3\144\10\0\4\144\7\0"+ + "\17\144\1\u0188\12\144\2\0\3\144\10\0\1\144\4\0"+ + "\3\144\1\0\3\144\10\0\4\144\7\0\15\144\1\u0189"+ + "\14\144\2\0\3\144\10\0\1\144\4\0\3\144\1\0"+ + "\3\144\10\0\4\144\7\0\12\144\1\u018a\17\144\2\0"+ + "\3\144\10\0\1\144\4\0\3\144\1\0\3\144\10\0"+ + "\4\144\7\0\7\144\1\u018b\22\144\2\0\3\144\10\0"+ + "\1\144\4\0\3\144\1\0\3\144\10\0\4\144\7\0"+ + "\16\144\1\u018c\13\144\2\0\3\144\10\0\1\144\4\0"+ + "\3\144\1\0\3\144\10\0\4\144\7\0\1\u018d\31\144"+ + "\2\0\3\144\10\0\1\144\4\0\3\144\1\0\3\144"+ + "\10\0\4\144\7\0\24\144\1\u018e\5\144\2\0\3\144"+ + "\10\0\1\144\40\0\1\u018f\51\0\3\144\1\0\3\144"+ + "\10\0\4\144\7\0\2\144\1\u0190\27\144\2\0\3\144"+ + "\10\0\1\144\4\0\3\144\1\0\3\144\10\0\4\144"+ + "\7\0\7\144\1\u0191\22\144\2\0\3\144\10\0\1\144"+ + "\75\0\1\u0192\55\0\1\u0193\105\0\1\u0194\100\0\1\u0195"+ + "\105\0\1\u0196\103\0\1\u0197\144\0\1\u0198\13\0\11\u0162"+ + "\2\u0199\1\u019a\7\u0162\1\u0199\1\u019b\61\u0162\11\u0127\2\351"+ + "\1\75\7\u0127\1\351\62\u0127\11\230\2\351\1\75\7\230"+ + "\1\351\3\230\1\351\56\230\3\u0164\1\u019c\1\u019d\1\u0164"+ + "\1\u019e\1\u019f\1\u0164\2\351\1\75\7\u0164\1\351\34\u0164"+ + "\1\u019c\1\u0164\1\u019f\1\u019c\22\u0164\1\0\3\u01a0\3\0"+ + "\1\u01a0\32\0\2\u01a0\3\0\1\u01a0\1\0\1\u01a0\1\0"+ + "\1\u01a0\2\0\1\u01a0\1\0\4\u01a0\3\0\1\u01a0\1\0"+ + "\1\u01a0\14\0\11\253\2\124\1\125\7\253\1\124\4\253"+ + "\1\u01a1\4\253\1\u01a2\50\253\11\u0169\2\u01a3\1\u01a4\7\u0169"+ + "\1\u01a3\62\u0169\11\253\2\124\1\125\7\253\1\124\12\253"+ + "\1\u01a5\60\253\2\124\1\125\7\253\1\124\23\253\1\u01a6"+ + "\43\253\1\u01a7\3\253\2\124\1\125\7\253\1\124\62\253"+ + "\1\0\3\144\1\0\3\144\10\0\4\144\7\0\23\144"+ + "\1\u01a8\6\144\2\0\3\144\10\0\1\144\4\0\3\144"+ + "\1\0\3\144\10\0\4\144\7\0\3\144\1\u01a9\26\144"+ + "\2\0\3\144\10\0\1\144\4\0\3\144\1\0\3\144"+ + "\10\0\4\144\7\0\14\144\1\u01aa\15\144\2\0\3\144"+ + "\10\0\1\144\4\0\3\144\1\0\3\144\10\0\4\144"+ + "\7\0\7\144\1\u01ab\22\144\2\0\3\144\10\0\1\144"+ + "\4\0\3\144\1\0\3\144\10\0\4\144\7\0\23\144"+ + "\1\u01ac\6\144\2\0\3\144\10\0\1\144\4\0\3\144"+ + "\1\0\3\144\10\0\4\144\7\0\17\144\1\u01ad\12\144"+ + "\2\0\3\144\10\0\1\144\4\0\3\144\1\0\3\144"+ + "\10\0\4\144\7\0\7\144\1\u01ae\22\144\2\0\3\144"+ + "\10\0\1\144\4\0\3\144\1\0\3\144\10\0\4\144"+ + "\7\0\1\u01af\31\144\2\0\3\144\10\0\1\144\4\0"+ + "\3\144\1\0\3\144\10\0\4\144\7\0\15\144\1\u01b0"+ + "\14\144\2\0\3\144\10\0\1\144\5\0\1\u01b1\2\0"+ + "\2\u01b1\1\0\1\u0176\7\0\1\u01b1\1\0\1\u0176\10\0"+ + "\25\u01b1\4\0\1\u01b1\2\0\3\u01b1\10\0\1\u01b1\4\0"+ + "\1\144\1\u01b1\1\144\1\0\2\u01b1\1\144\1\u0176\7\0"+ + "\1\u01b1\1\144\1\u0177\1\144\7\0\25\u01b1\4\144\1\u01b1"+ + "\2\0\3\u01b1\10\0\1\u01b1\4\0\3\144\1\0\3\144"+ + "\10\0\4\144\7\0\23\144\1\u01b2\6\144\2\0\3\144"+ + "\10\0\1\144\4\0\3\144\1\0\3\144\10\0\4\144"+ + "\7\0\4\144\1\u01b3\25\144\2\0\3\144\10\0\1\144"+ + "\4\0\3\144\1\0\3\144\10\0\4\144\7\0\12\144"+ + "\1\u01b4\17\144\2\0\3\144\10\0\1\144\4\0\3\144"+ + "\1\0\3\144\10\0\4\144\7\0\5\144\1\u01b5\24\144"+ + "\2\0\3\144\10\0\1\144\4\0\3\144\1\0\3\144"+ + "\10\0\4\144\7\0\1\u01b6\31\144\2\0\3\144\10\0"+ + "\1\144\4\0\3\144\1\0\3\144\10\0\4\144\7\0"+ + "\2\144\1\u01b7\27\144\2\0\3\144\10\0\1\144\4\0"+ + "\3\144\1\0\3\144\10\0\4\144\7\0\14\144\1\u01b8"+ + "\15\144\2\0\3\144\10\0\1\144\4\0\3\144\1\0"+ + "\3\144\10\0\4\144\7\0\1\u01b9\31\144\2\0\3\144"+ + "\10\0\1\144\4\0\3\144\1\0\3\144\10\0\4\144"+ + "\7\0\14\144\1\u01ba\15\144\2\0\3\144\10\0\1\144"+ + "\4\0\3\144\1\0\3\144\10\0\4\144\7\0\3\144"+ + "\1\u01bb\26\144\2\0\3\144\10\0\1\144\4\0\3\144"+ + "\1\0\3\144\10\0\4\144\7\0\4\144\1\u01bc\25\144"+ + "\2\0\3\144\10\0\1\144\4\0\3\144\1\0\3\144"+ + "\10\0\4\144\7\0\17\144\1\u01bd\12\144\2\0\3\144"+ + "\10\0\1\144\4\0\3\144\1\0\3\144\10\0\4\144"+ + "\7\0\20\144\1\u01be\11\144\2\0\3\144\10\0\1\144"+ + "\4\0\3\144\1\0\3\144\10\0\4\144\7\0\1\144"+ + "\1\u01bf\30\144\2\0\3\144\10\0\1\144\4\0\3\144"+ + "\1\0\3\144\1\u01c0\7\0\2\144\1\u01c1\1\144\7\0"+ + "\32\144\2\0\3\144\10\0\1\144\4\0\3\144\1\0"+ + "\3\144\10\0\4\144\7\0\7\144\1\u01c2\22\144\2\0"+ + "\3\144\10\0\1\144\4\0\3\144\1\0\3\144\10\0"+ + "\4\144\7\0\4\144\1\u01c3\25\144\2\0\3\144\10\0"+ + "\1\144\4\0\3\144\1\0\3\144\10\0\4\144\7\0"+ + "\21\144\1\u01c4\10\144\2\0\3\144\10\0\1\144\4\0"+ + "\3\144\1\0\3\144\10\0\4\144\7\0\16\144\1\u01c5"+ + "\13\144\2\0\3\144\10\0\1\144\4\0\3\144\1\0"+ + "\3\144\10\0\4\144\7\0\7\144\1\u01c6\22\144\2\0"+ + "\3\144\10\0\1\144\4\0\3\144\1\0\3\144\1\332"+ + "\7\0\2\144\1\333\1\144\7\0\15\144\1\u01c7\14\144"+ + "\2\0\3\144\10\0\1\144\75\0\1\u01c8\52\0\1\u01c9"+ + "\105\0\1\u01ca\110\0\1\u01cb\100\0\1\u01cc\105\0\1\u01cd"+ + "\142\0\1\u01ce\13\0\13\u0199\1\u019a\10\u0199\1\u01cf\1\u01d0"+ + "\1\u01d1\1\u01d2\1\u0162\1\u0199\1\u0162\53\u0199\24\u019a\1\u01d3"+ + "\1\u01d4\1\u01d5\1\u01d6\1\227\1\u019a\1\227\53\u019a\11\u0162"+ + "\2\u0199\1\u019a\7\u0162\1\u0199\1\u019b\1\351\60\u0162\3\230"+ + "\1\u0164\3\230\1\u0164\1\230\2\351\1\75\7\230\1\351"+ + "\3\230\1\351\30\230\1\u0164\1\230\2\u0164\26\230\1\u01d7"+ + "\1\230\1\u01d8\2\230\2\351\1\75\7\230\1\351\3\230"+ + "\1\351\57\230\3\u01d9\3\230\1\u01d9\1\230\2\351\1\75"+ + "\7\230\1\351\3\230\1\351\12\230\2\u01d9\3\230\1\u01d9"+ + "\1\230\1\u01d9\1\230\1\u01d9\2\230\1\u01d9\1\230\4\u01d9"+ + "\3\230\1\u01d9\1\230\1\u01d9\17\230\1\u019c\3\230\1\u019c"+ + "\1\230\2\351\1\75\7\230\1\351\3\230\1\351\30\230"+ + "\1\u019c\1\230\2\u019c\22\230\1\0\3\232\3\0\1\232"+ + "\32\0\2\232\3\0\1\232\1\0\1\232\1\0\1\232"+ + "\2\0\1\232\1\0\4\232\3\0\1\232\1\0\1\232"+ + "\14\0\11\u01a1\2\u01da\1\u01db\7\u01a1\1\u01da\62\u01a1\11\253"+ + "\2\124\1\125\7\253\1\124\12\253\1\u01dc\60\253\2\124"+ + "\1\125\7\253\1\124\13\253\1\u01dd\57\253\2\124\1\125"+ + "\7\253\1\124\21\253\1\u01de\51\253\2\124\1\125\7\253"+ + "\1\124\11\253\1\u01df\50\253\1\0\3\144\1\0\3\144"+ + "\10\0\4\144\7\0\7\144\1\u01e0\22\144\2\0\3\144"+ + "\10\0\1\144\4\0\3\144\1\0\3\144\10\0\4\144"+ + "\7\0\4\144\1\u01e1\25\144\2\0\3\144\10\0\1\144"+ + "\4\0\3\144\1\0\3\144\10\0\4\144\7\0\22\144"+ + "\1\u01e2\7\144\2\0\3\144\10\0\1\144\4\0\3\144"+ + "\1\0\3\144\10\0\4\144\7\0\4\144\1\u01e3\25\144"+ + "\2\0\3\144\10\0\1\144\4\0\3\144\1\0\3\144"+ + "\10\0\4\144\7\0\7\144\1\u01e4\22\144\2\0\3\144"+ + "\10\0\1\144\4\0\3\144\1\0\3\144\10\0\4\144"+ + "\7\0\7\144\1\u01e5\22\144\2\0\3\144\10\0\1\144"+ + "\4\0\3\144\1\0\3\144\10\0\4\144\7\0\16\144"+ + "\1\u01e6\13\144\2\0\3\144\10\0\1\144\4\0\3\144"+ + "\1\0\1\u01e7\2\144\10\0\4\144\7\0\32\144\2\0"+ + "\3\144\10\0\1\144\4\0\3\144\1\0\3\144\1\u01e8"+ + "\7\0\2\144\1\u01e9\1\144\7\0\32\144\2\0\3\144"+ + "\10\0\1\144\4\0\3\u01b1\1\0\3\u01b1\1\u01ea\3\0"+ + "\1\u0176\1\0\1\u01eb\1\0\4\u01b1\7\0\32\u01b1\2\0"+ + "\3\u01b1\10\0\1\u01b1\4\0\3\144\1\0\3\144\10\0"+ + "\4\144\7\0\15\144\1\u01ec\14\144\2\0\3\144\10\0"+ + "\1\144\4\0\3\144\1\0\3\144\10\0\4\144\7\0"+ + "\5\144\1\u01ed\24\144\2\0\3\144\10\0\1\144\4\0"+ + "\3\144\1\0\3\144\10\0\4\144\6\0\1\146\32\144"+ + "\2\0\3\144\10\0\1\144\4\0\3\144\1\0\3\144"+ + "\10\0\4\144\7\0\15\144\1\u01ee\14\144\2\0\3\144"+ + "\10\0\1\144\4\0\3\144\1\0\3\144\10\0\4\144"+ + "\7\0\5\144\1\u01ef\24\144\2\0\3\144\10\0\1\144"+ + "\4\0\3\144\1\0\3\144\10\0\4\144\7\0\3\144"+ + "\1\u01f0\26\144\2\0\3\144\10\0\1\144\4\0\3\144"+ + "\1\0\3\144\10\0\4\144\7\0\16\144\1\u01f1\13\144"+ + "\2\0\3\144\10\0\1\144\4\0\3\144\1\0\3\144"+ + "\10\0\4\144\7\0\13\144\1\u01f2\16\144\2\0\3\144"+ + "\10\0\1\144\4\0\3\144\1\0\3\144\10\0\4\144"+ + "\7\0\12\144\1\u01f3\17\144\2\0\3\144\10\0\1\144"+ + "\4\0\3\144\1\0\3\144\10\0\4\144\7\0\4\144"+ + "\1\u01f4\25\144\2\0\3\144\10\0\1\144\4\0\3\144"+ + "\1\0\3\144\1\u01f5\7\0\2\144\1\u01f6\1\144\7\0"+ + "\32\144\2\0\3\144\10\0\1\144\4\0\3\144\1\0"+ + "\1\144\1\u01f7\1\144\10\0\4\144\7\0\32\144\2\0"+ + "\3\144\10\0\1\144\5\0\1\u01f8\2\0\2\u01f8\1\0"+ + "\1\u01c0\7\0\1\u01f8\1\0\1\u01c0\10\0\25\u01f8\4\0"+ + "\1\u01f8\2\0\3\u01f8\10\0\1\u01f8\4\0\1\144\1\u01f8"+ + "\1\144\1\0\2\u01f8\1\144\1\u01c0\7\0\1\u01f8\1\144"+ + "\1\u01c1\1\144\7\0\25\u01f8\4\144\1\u01f8\2\0\3\u01f8"+ + "\10\0\1\u01f8\4\0\3\144\1\0\3\144\10\0\4\144"+ + "\7\0\15\144\1\u01f9\14\144\2\0\3\144\10\0\1\144"+ + "\4\0\3\144\1\0\3\144\1\u01fa\7\0\2\144\1\u01fb"+ + "\1\144\7\0\32\144\2\0\3\144\10\0\1\144\4\0"+ + "\3\144\1\0\3\144\1\327\7\0\2\144\1\330\1\144"+ + "\7\0\15\144\1\u01fc\14\144\2\0\3\144\10\0\1\144"+ + "\13\0\4\u01c8\6\0\2\u01c8\6\0\1\u01fd\124\0\1\u01fe"+ + "\105\0\1\u01ff\73\0\1\u0200\110\0\1\u0201\147\0\1\u0202"+ + "\11\0\4\u0203\6\0\2\u0203\62\0\13\u0199\1\u019a\10\u0199"+ + "\1\u01cf\1\u0204\1\u01d1\1\u01d2\1\u0162\1\u0199\1\u0162\66\u0199"+ + "\1\u019a\10\u0199\1\u0205\1\u0162\60\u0199\4\u01d1\1\u0206\4\u01d1"+ + "\2\u0199\1\u019a\7\u01d1\1\u0199\1\u0207\1\u01d1\1\u0199\57\u01d1"+ + "\4\u0208\1\u0209\4\u0208\2\u0199\1\u019a\7\u0208\1\u0199\1\u020a"+ + "\2\u0208\1\u0162\56\u0208\24\u019a\1\u01d3\1\u020b\1\u01d5\1\u01d6"+ + "\1\227\1\u019a\1\227\77\u019a\1\u020c\1\u0162\60\u019a\4\u01d5"+ + "\1\u020d\4\u01d5\3\227\7\u01d5\1\227\1\u020e\1\u01d5\1\u019a"+ + "\57\u01d5\4\u020f\1\u0210\4\u020f\3\227\7\u020f\1\227\1\u0211"+ + "\2\u020f\1\227\56\u020f\4\230\1\u01d7\1\230\1\u01d8\2\230"+ + "\2\351\1\75\7\230\1\351\63\230\3\u01d9\3\230\1\u01d9"+ + "\1\230\2\351\1\75\7\230\1\351\16\230\2\u01d9\3\230"+ + "\1\u01d9\1\230\1\u01d9\1\230\1\u01d9\2\230\1\u01d9\1\230"+ + "\4\u01d9\3\230\1\u01d9\1\230\1\u01d9\15\230\3\u0212\3\230"+ + "\1\u0212\1\230\2\351\1\75\7\230\1\351\16\230\2\u0212"+ + "\3\230\1\u0212\1\230\1\u0212\1\230\1\u0212\2\230\1\u0212"+ + "\1\230\4\u0212\3\230\1\u0212\1\230\1\u0212\14\230\11\253"+ + "\2\124\1\125\7\253\1\124\13\253\1\u0213\57\253\2\124"+ + "\1\125\7\253\1\124\14\253\1\u0214\56\253\2\124\1\125"+ + "\7\253\1\124\4\253\1\u0215\66\253\2\124\1\125\7\253"+ + "\1\124\12\253\1\u0216\47\253\1\0\3\144\1\0\3\144"+ + "\10\0\4\144\7\0\5\144\1\u0217\24\144\2\0\3\144"+ + "\10\0\1\144\4\0\3\144\1\0\3\144\1\u0218\7\0"+ + "\2\144\1\u0218\1\144\7\0\32\144\2\0\3\144\10\0"+ + "\1\144\4\0\3\144\1\0\3\144\10\0\4\144\7\0"+ + "\1\144\1\u0219\30\144\2\0\3\144\10\0\1\144\4\0"+ + "\3\144\1\0\3\144\10\0\4\144\7\0\14\144\1\u021a"+ + "\15\144\2\0\3\144\10\0\1\144\3\0\2\u021b\1\u021c"+ + "\2\u021b\2\u021c\1\u021b\1\u01e8\3\0\4\u021b\1\u021c\1\u021b"+ + "\1\u01e8\1\0\7\u021b\25\u021c\4\u021b\1\u021c\2\u021b\3\u021c"+ + "\10\u021b\1\u021c\4\u021b\1\u021d\1\u021c\1\u021d\1\u021b\2\u021c"+ + "\1\u021d\1\u01e8\3\0\4\u021b\1\u021c\1\u021d\1\u01e9\1\144"+ + "\7\u021b\25\u021c\4\u021d\1\u021c\2\u021b\3\u021c\10\u021b\1\u021c"+ + "\3\u021b\10\0\1\u01ea\3\0\1\u0176\1\0\1\u01eb\3\0"+ + "\1\u01ea\73\0\1\u01eb\6\0\1\u021e\2\0\1\u01eb\64\0"+ + "\3\144\1\0\3\144\1\u021f\7\0\2\144\1\u0220\1\144"+ + "\7\0\32\144\2\0\3\144\10\0\1\144\4\0\3\144"+ + "\1\0\3\144\10\0\4\144\7\0\6\144\1\u0221\23\144"+ + "\2\0\3\144\10\0\1\144\4\0\3\144\1\0\3\144"+ + "\10\0\4\144\7\0\7\144\1\u0222\22\144\2\0\3\144"+ + "\10\0\1\144\4\0\3\144\1\0\3\144\10\0\4\144"+ + "\7\0\1\144\1\u0223\30\144\2\0\3\144\10\0\1\144"+ + "\4\0\3\144\1\0\3\144\10\0\4\144\7\0\4\144"+ + "\1\u0224\25\144\2\0\3\144\10\0\1\144\4\0\3\144"+ + "\1\0\3\144\10\0\4\144\7\0\2\144\1\u0225\27\144"+ + "\2\0\3\144\10\0\1\144\4\0\3\144\1\0\3\144"+ + "\10\0\4\144\7\0\14\144\1\u0226\15\144\2\0\3\144"+ + "\10\0\1\144\4\0\3\144\1\0\3\144\10\0\4\144"+ + "\7\0\5\144\1\u0227\24\144\2\0\3\144\10\0\1\144"+ + "\4\0\3\144\1\0\3\144\10\0\4\144\7\0\5\144"+ + "\1\u0228\24\144\2\0\3\144\10\0\1\144\3\0\2\u0229"+ + "\1\u022a\2\u0229\2\u022a\1\u0229\1\u01f5\3\0\4\u0229\1\u022a"+ + "\1\u0229\1\u01f5\1\0\7\u0229\25\u022a\4\u0229\1\u022a\2\u0229"+ + "\3\u022a\10\u0229\1\u022a\4\u0229\1\u022b\1\u022a\1\u022b\1\u0229"+ + "\2\u022a\1\u022b\1\u01f5\3\0\4\u0229\1\u022a\1\u022b\1\u01f6"+ + "\1\144\7\u0229\25\u022a\4\u022b\1\u022a\2\u0229\3\u022a\10\u0229"+ + "\1\u022a\3\u0229\1\0\3\144\1\0\3\144\10\0\4\144"+ + "\7\0\24\144\1\u022c\5\144\2\0\3\144\10\0\1\144"+ + "\4\0\3\u01f8\1\0\3\u01f8\1\u022d\7\0\4\u01f8\7\0"+ + "\32\u01f8\2\0\3\u01f8\10\0\1\u01f8\4\0\3\144\1\0"+ + "\3\144\10\0\4\144\7\0\15\144\1\u022e\14\144\2\0"+ + "\3\144\10\0\1\144\3\0\1\u022f\1\u0230\1\u022f\1\u0230"+ + "\3\u022f\1\u0230\1\u01fa\3\0\6\u022f\1\u01fa\1\0\34\u022f"+ + "\4\u0230\23\u022f\1\u0231\1\u0232\1\u0231\1\u022f\2\u0232\1\u0231"+ + "\1\u01fa\3\0\4\u022f\2\u0232\1\u01fb\1\144\7\u022f\25\u0232"+ + "\4\u0231\1\u0232\2\u022f\3\u0232\10\u022f\1\u0232\3\u022f\47\0"+ + "\1\u0233\105\0\1\u0234\142\0\1\u0235\40\0\1\u0236\65\0"+ + "\1\u0237\76\0\4\u0203\6\0\2\u0203\6\0\1\u0238\53\0"+ + "\13\351\1\75\10\351\1\u0199\1\u0126\1\u0239\1\u023a\56\351"+ + "\11\u0162\2\u0199\1\u019a\7\u0162\1\u0199\1\u019b\1\u0199\60\u0162"+ + "\11\u01d1\2\u0199\1\u019a\7\u01d1\1\u0199\1\u0207\65\u01d1\1\u0206"+ + "\4\u01d1\2\u0199\1\u019a\7\u01d1\1\u0199\1\u0207\1\u0239\1\u0199"+ + "\57\u01d1\11\u0162\2\u0199\1\u019a\7\u0162\1\u0199\1\u019b\2\u0162"+ + "\1\u0199\56\u0162\3\u0208\1\u023b\1\u023c\1\u0208\1\u023d\1\u023e"+ + "\1\u0208\2\u0199\1\u019a\7\u0208\1\u0199\1\u020a\33\u0208\1\u023b"+ + "\1\u0208\1\u023e\1\u023b\22\u0208\11\u0162\2\u0199\1\u019a\7\u0162"+ + "\1\u0199\1\u019b\1\351\1\u0162\1\u0199\56\u0162\24\75\1\u019a"+ + "\1\u0126\1\u023f\1\u0240\56\75\24\227\1\350\1\u019a\60\227"+ + "\11\u01d5\3\227\7\u01d5\1\227\1\u020e\65\u01d5\1\u020d\4\u01d5"+ + "\3\227\7\u01d5\1\227\1\u020e\1\u023f\1\u019a\57\u01d5\24\227"+ + "\1\350\2\227\1\u019a\56\227\3\u020f\1\u0241\1\u0242\1\u020f"+ + "\1\u0243\1\u0244\1\u020f\3\227\7\u020f\1\227\1\u0211\33\u020f"+ + "\1\u0241\1\u020f\1\u0244\1\u0241\22\u020f\24\227\1\350\1\75"+ + "\1\227\1\u019a\56\227\1\230\3\u0245\3\230\1\u0245\1\230"+ + "\2\351\1\75\7\230\1\351\16\230\2\u0245\3\230\1\u0245"+ + "\1\230\1\u0245\1\230\1\u0245\2\230\1\u0245\1\230\4\u0245"+ + "\3\230\1\u0245\1\230\1\u0245\14\230\11\253\2\124\1\125"+ + "\7\253\1\124\14\253\1\u0246\56\253\2\124\1\125\7\253"+ + "\1\124\15\253\1\u0247\44\253\11\u0215\2\u0248\1\u0249\7\u0215"+ + "\1\u0248\62\u0215\11\253\2\124\1\125\7\253\1\124\13\253"+ + "\1\u024a\46\253\1\0\3\144\1\0\3\144\10\0\4\144"+ + "\7\0\6\144\1\u024b\23\144\2\0\3\144\10\0\1\144"+ + "\3\0\13\u0218\1\0\72\u0218\1\0\3\144\1\0\3\144"+ + "\10\0\4\144\7\0\2\144\1\u024c\27\144\2\0\3\144"+ + "\10\0\1\144\4\0\3\144\1\0\3\144\10\0\4\144"+ + "\7\0\15\144\1\u024d\14\144\2\0\3\144\10\0\1\144"+ + "\3\0\11\u021b\3\0\7\u021b\1\0\63\u021b\3\u021c\1\u021b"+ + "\3\u021c\1\u024e\3\0\2\u01e8\2\u021b\3\u021c\1\u024f\7\u021b"+ + "\32\u021c\2\u021b\3\u021c\10\u021b\1\u021c\4\u021b\3\u021d\1\u021b"+ + "\3\u021d\1\u021b\3\0\4\u021b\3\u021d\1\144\7\u021b\32\u021d"+ + "\2\u021b\3\u021d\10\u021b\1\u021d\3\u021b\10\0\1\u021e\5\0"+ + "\1\u01eb\3\0\1\u021e\65\0\1\u0250\2\0\2\u0250\1\0"+ + "\1\u021f\7\0\1\u0250\1\0\1\u021f\10\0\25\u0250\4\0"+ + "\1\u0250\2\0\3\u0250\10\0\1\u0250\4\0\1\144\1\u0250"+ + "\1\144\1\0\2\u0250\1\144\1\u021f\7\0\1\u0250\1\144"+ + "\1\u0220\1\144\7\0\25\u0250\4\144\1\u0250\2\0\3\u0250"+ + "\10\0\1\u0250\4\0\3\144\1\0\3\144\1\u0251\7\0"+ + "\2\144\1\u0252\1\144\6\0\1\146\32\144\2\0\3\144"+ + "\10\0\1\144\4\0\3\144\1\0\3\144\1\u0253\7\0"+ + "\2\144\1\u0254\1\144\7\0\32\144\2\0\3\144\10\0"+ + "\1\144\4\0\3\144\1\0\3\144\1\u0255\7\0\2\144"+ + "\1\u0256\1\144\7\0\32\144\2\0\3\144\10\0\1\144"+ + "\4\0\3\144\1\0\3\144\10\0\4\144\7\0\5\144"+ + "\1\u0257\24\144\2\0\3\144\10\0\1\144\4\0\3\144"+ + "\1\0\3\144\10\0\4\144\7\0\2\144\1\u0258\27\144"+ + "\2\0\3\144\10\0\1\144\4\0\3\144\1\0\3\144"+ + "\10\0\4\144\7\0\1\144\1\u0259\30\144\2\0\3\144"+ + "\10\0\1\144\4\0\3\144\1\0\3\144\10\0\4\144"+ + "\7\0\4\144\1\u025a\25\144\2\0\3\144\10\0\1\144"+ + "\3\0\11\u0229\3\0\7\u0229\1\0\63\u0229\3\u022a\1\u0229"+ + "\3\u022a\1\u025b\3\0\1\u01f5\3\u0229\3\u022a\1\u025c\7\u0229"+ + "\32\u022a\2\u0229\3\u022a\10\u0229\1\u022a\4\u0229\3\u022b\1\u0229"+ + "\3\u022b\1\u0229\3\0\4\u0229\3\u022b\1\144\7\u0229\32\u022b"+ + "\2\u0229\3\u022b\10\u0229\1\u022b\3\u0229\10\0\1\u022d\11\0"+ + "\1\u022d\63\0\11\u022f\3\0\7\u022f\1\0\63\u022f\1\u0230"+ + "\1\u022f\1\u0230\3\u022f\1\u0230\1\u025d\3\0\6\u022f\1\u025d"+ + "\1\0\34\u022f\4\u0230\23\u022f\1\u0231\1\u0232\1\u0231\1\u022f"+ + "\2\u0232\1\u0231\1\u025d\3\0\4\u022f\2\u0232\1\u025e\1\144"+ + "\7\u022f\25\u0232\4\u0231\1\u0232\2\u022f\3\u0232\10\u022f\1\u0232"+ + "\4\u022f\3\u0232\1\u022f\3\u0232\1\u022f\3\0\4\u022f\3\u0232"+ + "\1\144\7\u022f\32\u0232\2\u022f\3\u0232\10\u022f\1\u0232\3\u022f"+ + "\50\0\1\u025f\105\0\1\u0260\54\0\1\u0261\144\0\1\u0262"+ + "\25\0\1\u0263\1\0\4\u0239\1\u0264\4\u0239\2\351\1\75"+ + "\7\u0239\1\351\1\u0239\1\u0265\1\u0239\1\u0266\1\u0127\1\u0239"+ + "\1\u0127\53\u0239\4\u0267\1\u0268\4\u0267\2\351\1\75\7\u0267"+ + "\1\351\1\u0267\1\u0126\1\u0269\1\u0128\1\u0164\1\u0267\1\u0164"+ + "\53\u0267\3\u0162\1\u0208\3\u0162\1\u0208\1\u0162\2\u0199\1\u019a"+ + "\7\u0162\1\u0199\1\u019b\2\u0162\1\u0199\30\u0162\1\u0208\1\u0162"+ + "\2\u0208\26\u0162\1\u026a\1\u0162\1\u026b\2\u0162\2\u0199\1\u019a"+ + "\7\u0162\1\u0199\1\u019b\2\u0162\1\u0199\57\u0162\3\u026c\3\u0162"+ + "\1\u026c\1\u0162\2\u0199\1\u019a\7\u0162\1\u0199\1\u019b\2\u0162"+ + "\1\u0199\12\u0162\2\u026c\3\u0162\1\u026c\1\u0162\1\u026c\1\u0162"+ + "\1\u026c\2\u0162\1\u026c\1\u0162\4\u026c\3\u0162\1\u026c\1\u0162"+ + "\1\u026c\17\u0162\1\u023b\3\u0162\1\u023b\1\u0162\2\u0199\1\u019a"+ + "\7\u0162\1\u0199\1\u019b\2\u0162\1\u0199\30\u0162\1\u023b\1\u0162"+ + "\2\u023b\22\u0162\4\u023f\1\u026d\4\u023f\3\75\7\u023f\1\75"+ + "\1\u023f\1\u026e\1\u023f\1\u026f\1\225\1\u023f\1\225\53\u023f"+ + "\4\u0270\1\u0271\4\u0270\3\75\7\u0270\1\75\1\u0270\1\224"+ + "\1\u0272\1\226\1\232\1\u0270\1\232\53\u0270\3\227\1\u020f"+ + "\3\227\1\u020f\14\227\1\350\2\227\1\u019a\30\227\1\u020f"+ + "\1\227\2\u020f\26\227\1\u0273\1\227\1\u0274\15\227\1\350"+ + "\2\227\1\u019a\57\227\3\u0275\3\227\1\u0275\14\227\1\350"+ + "\2\227\1\u019a\12\227\2\u0275\3\227\1\u0275\1\227\1\u0275"+ + "\1\227\1\u0275\2\227\1\u0275\1\227\4\u0275\3\227\1\u0275"+ + "\1\227\1\u0275\17\227\1\u0241\3\227\1\u0241\14\227\1\350"+ + "\2\227\1\u019a\30\227\1\u0241\1\227\2\u0241\22\227\1\230"+ + "\3\u0164\3\230\1\u0164\1\230\2\351\1\75\7\230\1\351"+ + "\16\230\2\u0164\3\230\1\u0164\1\230\1\u0164\1\230\1\u0164"+ + "\2\230\1\u0164\1\230\4\u0164\3\230\1\u0164\1\230\1\u0164"+ + "\14\230\11\253\2\124\1\125\7\253\1\124\15\253\1\u0276"+ + "\55\253\2\124\1\125\7\253\1\124\4\253\1\u0277\66\253"+ + "\2\124\1\125\7\253\1\124\14\253\1\u0278\45\253\1\0"+ + "\3\144\1\0\3\144\1\u0279\7\0\2\144\1\u027a\1\144"+ + "\6\0\1\146\32\144\2\0\3\144\10\0\1\144\4\0"+ + "\3\144\1\0\3\144\10\0\4\144\7\0\15\144\1\u027b"+ + "\14\144\2\0\3\144\10\0\1\144\4\0\3\144\1\0"+ + "\3\144\10\0\4\144\7\0\7\144\1\u022e\22\144\2\0"+ + "\3\144\10\0\1\144\3\0\10\u021b\1\u024e\3\0\2\u01e8"+ + "\4\u021b\1\u024e\1\0\62\u021b\1\0\3\u024f\1\0\3\u024f"+ + "\1\u027c\3\0\2\u027d\2\0\4\u024f\7\0\32\u024f\2\0"+ + "\3\u024f\10\0\1\u024f\4\0\3\u0250\1\0\3\u0250\1\u027e"+ + "\3\0\1\u021f\3\0\4\u0250\7\0\32\u0250\2\0\3\u0250"+ + "\10\0\1\u0250\3\0\2\u027f\1\u0280\2\u027f\2\u0280\1\u027f"+ + "\1\u0251\3\0\4\u027f\1\u0280\1\u027f\1\u0251\1\0\7\u027f"+ + "\25\u0280\4\u027f\1\u0280\2\u027f\3\u0280\10\u027f\1\u0280\4\u027f"+ + "\1\u0281\1\u0280\1\u0281\1\u027f\2\u0280\1\u0281\1\u0251\3\0"+ + "\4\u027f\1\u0280\1\u0281\1\u0252\1\144\7\u027f\25\u0280\4\u0281"+ + "\1\u0280\2\u027f\3\u0280\10\u027f\1\u0280\3\u027f\10\0\1\u0253"+ + "\11\0\1\u0253\12\0\1\u0282\5\0\1\u0283\43\0\3\144"+ + "\1\0\3\144\1\u0253\7\0\2\144\1\u0254\1\144\7\0"+ + "\2\144\1\u0284\5\144\1\u0285\21\144\2\0\3\144\10\0"+ + "\1\144\5\0\1\u0286\2\0\2\u0286\1\0\1\u0255\7\0"+ + "\1\u0286\1\0\1\u0255\10\0\25\u0286\4\0\1\u0286\2\0"+ + "\3\u0286\10\0\1\u0286\4\0\1\144\1\u0286\1\144\1\0"+ + "\2\u0286\1\144\1\u0255\7\0\1\u0286\1\144\1\u0256\1\144"+ + "\7\0\25\u0286\4\144\1\u0286\2\0\3\u0286\10\0\1\u0286"+ + "\4\0\3\144\1\0\3\144\10\0\4\144\7\0\6\144"+ + "\1\u0287\23\144\2\0\3\144\10\0\1\144\4\0\3\144"+ + "\1\0\3\144\10\0\4\144\7\0\7\144\1\u0288\22\144"+ + "\2\0\3\144\10\0\1\144\4\0\3\144\1\0\3\144"+ + "\10\0\4\144\7\0\7\144\1\u0289\22\144\2\0\3\144"+ + "\10\0\1\144\4\0\3\144\1\0\3\144\1\u028a\7\0"+ + "\2\144\1\u028b\1\144\7\0\32\144\2\0\3\144\10\0"+ + "\1\144\3\0\10\u0229\1\u025b\3\0\1\u01f5\5\u0229\1\u025b"+ + "\1\0\62\u0229\1\0\3\u025c\1\0\3\u025c\1\u028c\3\0"+ + "\1\u028d\3\0\4\u025c\7\0\32\u025c\2\0\3\u025c\10\0"+ + "\1\u025c\3\0\10\u022f\1\u025d\3\0\6\u022f\1\u025d\1\0"+ + "\63\u022f\3\u0232\1\u022f\3\u0232\1\u025d\3\0\4\u022f\2\u0232"+ + "\1\u025e\1\144\7\u022f\32\u0232\2\u022f\3\u0232\10\u022f\1\u0232"+ + "\3\u022f\42\0\1\u028e\105\0\1\u028f\76\0\1\u0290\71\0"+ + "\1\u0291\66\0\11\u0239\2\351\1\75\7\u0239\1\351\1\u0239"+ + "\1\u0265\1\u0127\1\u0266\1\u0127\1\u0239\1\u0127\57\u0239\1\u0264"+ + "\4\u0239\2\351\1\75\7\u0239\1\351\1\u01d1\1\u0127\1\351"+ + "\57\u0239\4\u0269\1\u0292\4\u0269\2\351\1\75\7\u0269\1\351"+ + "\2\u0269\1\u0267\1\u0127\56\u0269\13\351\1\75\11\351\1\u0126"+ + "\1\u0127\1\u023a\1\230\1\351\1\230\53\351\3\u0267\1\u0293"+ + "\1\u0294\1\u0267\1\u0295\1\u0296\1\u0267\2\351\1\75\7\u0267"+ + "\1\351\1\u0267\1\u0126\1\u0269\1\u0297\1\u0164\1\u0267\1\u0164"+ + "\25\u0267\1\u0293\1\u0267\1\u0296\1\u0293\22\u0267\4\u0127\1\u0163"+ + "\4\u0127\2\351\1\75\7\u0127\1\351\2\u0127\1\351\1\u0239"+ + "\56\u0127\4\u0162\1\u026a\1\u0162\1\u026b\2\u0162\2\u0199\1\u019a"+ + "\7\u0162\1\u0199\1\u019b\62\u0162\3\u026c\3\u0162\1\u026c\1\u0162"+ + "\2\u0199\1\u019a\7\u0162\1\u0199\1\u019b\15\u0162\2\u026c\3\u0162"+ + "\1\u026c\1\u0162\1\u026c\1\u0162\1\u026c\2\u0162\1\u026c\1\u0162"+ + "\4\u026c\3\u0162\1\u026c\1\u0162\1\u026c\15\u0162\3\u0298\3\u0162"+ + "\1\u0298\1\u0162\2\u0199\1\u019a\7\u0162\1\u0199\1\u019b\15\u0162"+ + "\2\u0298\3\u0162\1\u0298\1\u0162\1\u0298\1\u0162\1\u0298\2\u0162"+ + "\1\u0298\1\u0162\4\u0298\3\u0162\1\u0298\1\u0162\1\u0298\14\u0162"+ + "\11\u023f\3\75\7\u023f\1\75\1\u023f\1\u026e\1\225\1\u026f"+ + "\1\225\1\u023f\1\225\57\u023f\1\u026d\4\u023f\3\75\7\u023f"+ + "\1\75\1\u01d5\1\u0127\1\75\57\u023f\4\u0272\1\u0299\4\u0272"+ + "\3\0\7\u0272\1\0\2\u0272\1\u0270\1\225\56\u0272\25\75"+ + "\1\224\1\225\1\u0240\1\0\1\75\1\0\53\75\3\u0270"+ + "\1\u029a\1\u029b\1\u0270\1\u029c\1\u029d\1\u0270\3\75\7\u0270"+ + "\1\75\1\u0270\1\224\1\u0272\1\u029e\1\232\1\u0270\1\232"+ + "\25\u0270\1\u029a\1\u0270\1\u029d\1\u029a\22\u0270\4\225\1\231"+ + "\4\225\3\0\7\225\1\0\2\225\1\75\1\u023f\56\225"+ + "\4\227\1\u0273\1\227\1\u0274\15\227\1\350\62\227\3\u0275"+ + "\3\227\1\u0275\14\227\1\350\15\227\2\u0275\3\227\1\u0275"+ + "\1\227\1\u0275\1\227\1\u0275\2\227\1\u0275\1\227\4\u0275"+ + "\3\227\1\u0275\1\227\1\u0275\15\227\3\u029f\3\227\1\u029f"+ + "\14\227\1\350\15\227\2\u029f\3\227\1\u029f\1\227\1\u029f"+ + "\1\227\1\u029f\2\227\1\u029f\1\227\4\u029f\3\227\1\u029f"+ + "\1\227\1\u029f\14\227\11\253\2\124\1\125\7\253\1\124"+ + "\4\253\1\u02a0\55\253\11\u0277\2\u02a1\1\u02a2\7\u0277\1\u02a1"+ + "\62\u0277\11\253\2\124\1\125\7\253\1\124\15\253\1\u02a3"+ + "\44\253\2\u02a4\1\u02a5\2\u02a4\2\u02a5\1\u02a4\1\u0279\3\0"+ + "\4\u02a4\1\u02a5\1\u02a4\1\u0279\1\0\7\u02a4\25\u02a5\4\u02a4"+ + "\1\u02a5\2\u02a4\3\u02a5\10\u02a4\1\u02a5\4\u02a4\1\u02a6\1\u02a5"+ + "\1\u02a6\1\u02a4\2\u02a5\1\u02a6\1\u0279\3\0\4\u02a4\1\u02a5"+ + "\1\u02a6\1\u027a\1\144\7\u02a4\25\u02a5\4\u02a6\1\u02a5\2\u02a4"+ + "\3\u02a5\10\u02a4\1\u02a5\3\u02a4\1\0\3\144\1\0\3\144"+ + "\1\u02a7\7\0\2\144\1\u02a7\1\144\7\0\32\144\2\0"+ + "\3\144\10\0\1\144\13\0\1\u027c\3\0\2\u027d\4\0"+ + "\1\u027c\65\0\1\u024f\2\0\2\u024f\1\0\1\u027d\7\0"+ + "\1\u024f\1\0\1\u027d\10\0\25\u024f\4\0\1\u024f\2\0"+ + "\3\u024f\10\0\1\u024f\13\0\1\u027e\3\0\1\u021f\5\0"+ + "\1\u027e\63\0\11\u027f\3\0\7\u027f\1\0\63\u027f\3\u0280"+ + "\1\u027f\3\u0280\1\u02a8\3\0\2\u0251\2\u027f\3\u0280\1\u02a9"+ + "\7\u027f\32\u0280\2\u027f\3\u0280\10\u027f\1\u0280\4\u027f\3\u0281"+ + "\1\u027f\3\u0281\1\u027f\3\0\4\u027f\3\u0281\1\144\7\u027f"+ + "\32\u0281\2\u027f\3\u0281\10\u027f\1\u0281\3\u027f\37\0\1\u02aa"+ + "\115\0\1\u02ab\37\0\3\144\1\0\3\144\10\0\4\144"+ + "\7\0\4\144\1\u02ac\25\144\2\0\3\144\10\0\1\144"+ + "\4\0\3\144\1\0\3\144\10\0\4\144\7\0\14\144"+ + "\1\u02ad\15\144\2\0\3\144\10\0\1\144\4\0\3\u0286"+ + "\1\0\3\u0286\1\u02ae\7\0\4\u0286\7\0\32\u0286\2\0"+ + "\3\u0286\10\0\1\u0286\4\0\3\144\1\0\3\144\1\u02af"+ + "\7\0\2\144\1\u02b0\1\144\6\0\1\146\32\144\2\0"+ + "\3\144\10\0\1\144\3\0\2\u02b1\1\u02b2\2\u02b1\2\u02b2"+ + "\1\u02b1\1\u028a\3\0\4\u02b1\1\u02b2\1\u02b1\1\u028a\1\0"+ + "\7\u02b1\25\u02b2\4\u02b1\1\u02b2\2\u02b1\3\u02b2\10\u02b1\1\u02b2"+ + "\4\u02b1\1\u02b3\1\u02b2\1\u02b3\1\u02b1\2\u02b2\1\u02b3\1\u028a"+ + "\3\0\4\u02b1\1\u02b2\1\u02b3\1\u028b\1\144\7\u02b1\25\u02b2"+ + "\4\u02b3\1\u02b2\2\u02b1\3\u02b2\10\u02b1\1\u02b2\3\u02b1\10\0"+ + "\1\u028c\3\0\1\u028d\5\0\1\u028c\65\0\1\u025c\2\0"+ + "\2\u025c\1\0\1\u028d\7\0\1\u025c\1\0\1\u028d\10\0"+ + "\25\u025c\4\0\1\u025c\2\0\3\u025c\10\0\1\u025c\107\0"+ + "\1\u02b4\105\0\1\u02b5\60\0\1\u02b6\26\0\3\u0269\1\u02b7"+ + "\1\u02b8\1\u0269\1\u02b9\1\u02ba\1\u0269\2\351\1\75\7\u0269"+ + "\1\351\34\u0269\1\u02b7\1\u0269\1\u02ba\1\u02b7\22\u0269\3\351"+ + "\1\u0267\3\351\1\u0267\3\351\1\75\11\351\1\u0126\1\u0127"+ + "\1\u023a\1\230\1\351\1\230\25\351\1\u0267\1\351\2\u0267"+ + "\26\351\1\u02bb\1\351\1\u02bc\4\351\1\75\11\351\1\u0126"+ + "\1\u0127\1\u023a\1\230\1\351\1\230\54\351\3\u02bd\3\351"+ + "\1\u02bd\3\351\1\75\11\351\1\u0126\1\u0127\1\u023a\1\230"+ + "\1\351\1\230\7\351\2\u02bd\3\351\1\u02bd\1\351\1\u02bd"+ + "\1\351\1\u02bd\2\351\1\u02bd\1\351\4\u02bd\3\351\1\u02bd"+ + "\1\351\1\u02bd\17\351\1\u0293\3\351\1\u0293\3\351\1\75"+ + "\11\351\1\u0126\1\u0127\1\u023a\1\230\1\351\1\230\25\351"+ + "\1\u0293\1\351\2\u0293\22\351\4\u0164\1\u0165\4\u0164\2\351"+ + "\1\75\7\u0164\1\351\3\u0164\1\351\56\u0164\1\u0162\3\u02be"+ + "\3\u0162\1\u02be\1\u0162\2\u0199\1\u019a\7\u0162\1\u0199\1\u019b"+ + "\15\u0162\2\u02be\3\u0162\1\u02be\1\u0162\1\u02be\1\u0162\1\u02be"+ + "\2\u0162\1\u02be\1\u0162\4\u02be\3\u0162\1\u02be\1\u0162\1\u02be"+ + "\14\u0162\3\u0272\1\u02bf\1\u02c0\1\u0272\1\u02c1\1\u02c2\1\u0272"+ + "\3\0\7\u0272\1\0\34\u0272\1\u02bf\1\u0272\1\u02c2\1\u02bf"+ + "\22\u0272\3\75\1\u0270\3\75\1\u0270\15\75\1\224\1\225"+ + "\1\u0240\1\0\1\75\1\0\25\75\1\u0270\1\75\2\u0270"+ + "\26\75\1\u02c3\1\75\1\u02c4\16\75\1\224\1\225\1\u0240"+ + "\1\0\1\75\1\0\54\75\3\u02c5\3\75\1\u02c5\15\75"+ + "\1\224\1\225\1\u0240\1\0\1\75\1\0\7\75\2\u02c5"+ + "\3\75\1\u02c5\1\75\1\u02c5\1\75\1\u02c5\2\75\1\u02c5"+ + "\1\75\4\u02c5\3\75\1\u02c5\1\75\1\u02c5\17\75\1\u029a"+ + "\3\75\1\u029a\15\75\1\224\1\225\1\u0240\1\0\1\75"+ + "\1\0\25\75\1\u029a\1\75\2\u029a\22\75\4\232\1\233"+ + "\4\232\3\0\7\232\1\0\3\232\1\75\56\232\1\227"+ + "\3\u02c6\3\227\1\u02c6\14\227\1\350\15\227\2\u02c6\3\227"+ + "\1\u02c6\1\227\1\u02c6\1\227\1\u02c6\2\227\1\u02c6\1\227"+ + "\4\u02c6\3\227\1\u02c6\1\227\1\u02c6\14\227\11\u02a0\2\u02c7"+ + "\1\u02c8\7\u02a0\1\u02c7\62\u02a0\11\253\2\124\1\125\7\253"+ + "\1\124\4\253\1\u02c9\55\253\11\u02a4\3\0\7\u02a4\1\0"+ + "\63\u02a4\3\u02a5\1\u02a4\3\u02a5\1\u02ca\3\0\2\u0279\2\u02a4"+ + "\3\u02a5\1\u02cb\7\u02a4\32\u02a5\2\u02a4\3\u02a5\10\u02a4\1\u02a5"+ + "\4\u02a4\3\u02a6\1\u02a4\3\u02a6\1\u02a4\3\0\4\u02a4\3\u02a6"+ + "\1\144\7\u02a4\32\u02a6\2\u02a4\3\u02a6\10\u02a4\1\u02a6\3\u02a4"+ + "\13\u02a7\1\0\72\u02a7\10\u027f\1\u02a8\3\0\2\u0251\4\u027f"+ + "\1\u02a8\1\0\62\u027f\1\0\3\u02a9\1\0\3\u02a9\1\u02cc"+ + "\3\0\2\u02cd\2\0\4\u02a9\7\0\32\u02a9\2\0\3\u02a9"+ + "\10\0\1\u02a9\11\0\1\u02ce\144\0\1\u02cf\41\0\3\144"+ + "\1\0\1\144\1\u02d0\1\144\10\0\4\144\7\0\32\144"+ + "\2\0\3\144\10\0\1\144\4\0\3\144\1\0\3\144"+ + "\10\0\4\144\7\0\12\144\1\u02d1\17\144\2\0\3\144"+ + "\10\0\1\144\13\0\1\u02ae\11\0\1\u02ae\63\0\2\u02d2"+ + "\1\u02d3\2\u02d2\2\u02d3\1\u02d2\1\u02af\3\0\4\u02d2\1\u02d3"+ + "\1\u02d2\1\u02af\1\0\7\u02d2\25\u02d3\4\u02d2\1\u02d3\2\u02d2"+ + "\3\u02d3\10\u02d2\1\u02d3\4\u02d2\1\u02d4\1\u02d3\1\u02d4\1\u02d2"+ + "\2\u02d3\1\u02d4\1\u02af\3\0\4\u02d2\1\u02d3\1\u02d4\1\u02b0"+ + "\1\144\7\u02d2\25\u02d3\4\u02d4\1\u02d3\2\u02d2\3\u02d3\10\u02d2"+ + "\1\u02d3\3\u02d2\11\u02b1\3\0\7\u02b1\1\0\63\u02b1\3\u02b2"+ + "\1\u02b1\3\u02b2\1\u02d5\3\0\1\u028a\3\u02b1\3\u02b2\1\u02d6"+ + "\7\u02b1\32\u02b2\2\u02b1\3\u02b2\10\u02b1\1\u02b2\4\u02b1\3\u02b3"+ + "\1\u02b1\3\u02b3\1\u02b1\3\0\4\u02b1\3\u02b3\1\144\7\u02b1"+ + "\32\u02b3\2\u02b1\3\u02b3\10\u02b1\1\u02b3\3\u02b1\17\0\1\u02d7"+ + "\105\0\1\u02d8\121\0\1\u02d9\52\0\3\u0127\1\u0269\1\u0163"+ + "\2\u0127\1\u0269\1\u0127\2\351\1\75\7\u0127\1\351\2\u0127"+ + "\1\351\1\u0239\30\u0127\1\u0269\1\u0127\2\u0269\26\u0127\1\u02da"+ + "\1\u0127\1\u02db\2\u0127\2\351\1\75\7\u0127\1\351\2\u0127"+ + "\1\351\1\u0239\57\u0127\3\u02dc\1\u0163\2\u0127\1\u02dc\1\u0127"+ + "\2\351\1\75\7\u0127\1\351\2\u0127\1\351\1\u0239\12\u0127"+ + "\2\u02dc\3\u0127\1\u02dc\1\u0127\1\u02dc\1\u0127\1\u02dc\2\u0127"+ + "\1\u02dc\1\u0127\4\u02dc\3\u0127\1\u02dc\1\u0127\1\u02dc\17\u0127"+ + "\1\u02b7\1\u0163\2\u0127\1\u02b7\1\u0127\2\351\1\75\7\u0127"+ + "\1\351\2\u0127\1\351\1\u0239\30\u0127\1\u02b7\1\u0127\2\u02b7"+ + "\22\u0127\4\351\1\u02bb\1\351\1\u02bc\4\351\1\75\11\351"+ + "\1\u0126\1\u0127\1\u0128\1\230\1\351\1\230\54\351\3\u02bd"+ + "\3\351\1\u02bd\3\351\1\75\11\351\1\u0126\1\u0127\1\u0128"+ + "\1\230\1\351\1\230\7\351\2\u02bd\3\351\1\u02bd\1\351"+ + "\1\u02bd\1\351\1\u02bd\2\351\1\u02bd\1\351\4\u02bd\3\351"+ + "\1\u02bd\1\351\1\u02bd\15\351\3\u02dd\3\351\1\u02dd\3\351"+ + "\1\75\11\351\1\u0126\1\u0127\1\u0128\1\230\1\351\1\230"+ + "\7\351\2\u02dd\3\351\1\u02dd\1\351\1\u02dd\1\351\1\u02dd"+ + "\2\351\1\u02dd\1\351\4\u02dd\3\351\1\u02dd\1\351\1\u02dd"+ + "\14\351\1\u0162\3\u0208\3\u0162\1\u0208\1\u0162\2\u0199\1\u019a"+ + "\7\u0162\1\u0199\1\u019b\15\u0162\2\u0208\3\u0162\1\u0208\1\u0162"+ + "\1\u0208\1\u0162\1\u0208\2\u0162\1\u0208\1\u0162\4\u0208\3\u0162"+ + "\1\u0208\1\u0162\1\u0208\14\u0162\3\225\1\u0272\1\231\2\225"+ + "\1\u0272\1\225\3\0\7\225\1\0\2\225\1\75\1\u023f"+ + "\30\225\1\u0272\1\225\2\u0272\26\225\1\u02de\1\225\1\u02df"+ + "\2\225\3\0\7\225\1\0\2\225\1\75\1\u023f\57\225"+ + "\3\u02e0\1\231\2\225\1\u02e0\1\225\3\0\7\225\1\0"+ + "\2\225\1\75\1\u023f\12\225\2\u02e0\3\225\1\u02e0\1\225"+ + "\1\u02e0\1\225\1\u02e0\2\225\1\u02e0\1\225\4\u02e0\3\225"+ + "\1\u02e0\1\225\1\u02e0\17\225\1\u02bf\1\231\2\225\1\u02bf"+ + "\1\225\3\0\7\225\1\0\2\225\1\75\1\u023f\30\225"+ + "\1\u02bf\1\225\2\u02bf\22\225\4\75\1\u02c3\1\75\1\u02c4"+ + "\16\75\1\224\1\225\1\226\1\0\1\75\1\0\54\75"+ + "\3\u02c5\3\75\1\u02c5\15\75\1\224\1\225\1\226\1\0"+ + "\1\75\1\0\7\75\2\u02c5\3\75\1\u02c5\1\75\1\u02c5"+ + "\1\75\1\u02c5\2\75\1\u02c5\1\75\4\u02c5\3\75\1\u02c5"+ + "\1\75\1\u02c5\15\75\3\u02e1\3\75\1\u02e1\15\75\1\224"+ + "\1\225\1\226\1\0\1\75\1\0\7\75\2\u02e1\3\75"+ + "\1\u02e1\1\75\1\u02e1\1\75\1\u02e1\2\75\1\u02e1\1\75"+ + "\4\u02e1\3\75\1\u02e1\1\75\1\u02e1\14\75\1\227\3\u020f"+ + "\3\227\1\u020f\14\227\1\350\15\227\2\u020f\3\227\1\u020f"+ + "\1\227\1\u020f\1\227\1\u020f\2\227\1\u020f\1\227\4\u020f"+ + "\3\227\1\u020f\1\227\1\u020f\14\227\11\u02c9\2\u02e2\1\u02e3"+ + "\7\u02c9\1\u02e2\62\u02c9\10\u02a4\1\u02ca\3\0\2\u0279\4\u02a4"+ + "\1\u02ca\1\0\62\u02a4\1\0\3\u02cb\1\0\3\u02cb\1\u02e4"+ + "\3\0\2\u02e5\2\0\4\u02cb\7\0\32\u02cb\2\0\3\u02cb"+ + "\10\0\1\u02cb\13\0\1\u02cc\3\0\2\u02cd\4\0\1\u02cc"+ + "\65\0\1\u02a9\2\0\2\u02a9\1\0\1\u02cd\7\0\1\u02a9"+ + "\1\0\1\u02cd\10\0\25\u02a9\4\0\1\u02a9\2\0\3\u02a9"+ + "\10\0\1\u02a9\45\0\1\u02e6\113\0\1\u02e7\36\0\3\144"+ + "\1\0\3\144\10\0\4\144\7\0\7\144\1\u02e8\22\144"+ + "\2\0\3\144\10\0\1\144\4\0\3\144\1\0\3\144"+ + "\10\0\4\144\7\0\15\144\1\u02e9\14\144\2\0\3\144"+ + "\10\0\1\144\3\0\11\u02d2\3\0\7\u02d2\1\0\63\u02d2"+ + "\3\u02d3\1\u02d2\3\u02d3\1\u02ea\3\0\2\u02af\2\u02d2\3\u02d3"+ + "\1\u02eb\7\u02d2\32\u02d3\2\u02d2\3\u02d3\10\u02d2\1\u02d3\4\u02d2"+ + "\3\u02d4\1\u02d2\3\u02d4\1\u02d2\3\0\4\u02d2\3\u02d4\1\144"+ + "\7\u02d2\32\u02d4\2\u02d2\3\u02d4\10\u02d2\1\u02d4\3\u02d2\10\u02b1"+ + "\1\u02d5\3\0\1\u028a\5\u02b1\1\u02d5\1\0\62\u02b1\1\0"+ + "\3\u02d6\1\0\3\u02d6\1\u02ec\3\0\1\u02ed\3\0\4\u02d6"+ + "\7\0\32\u02d6\2\0\3\u02d6\10\0\1\u02d6\40\0\1\u02ee"+ + "\50\0\4\u0127\1\u02ef\1\u0127\1\u02db\2\u0127\2\351\1\75"+ + "\7\u0127\1\351\63\u0127\3\u02dc\1\u0163\2\u0127\1\u02dc\1\u0127"+ + "\2\351\1\75\7\u0127\1\351\2\u0127\1\351\13\u0127\2\u02dc"+ + "\3\u0127\1\u02dc\1\u0127\1\u02dc\1\u0127\1\u02dc\2\u0127\1\u02dc"+ + "\1\u0127\4\u02dc\3\u0127\1\u02dc\1\u0127\1\u02dc\15\u0127\3\u02f0"+ + "\1\u0163\2\u0127\1\u02f0\1\u0127\2\351\1\75\7\u0127\1\351"+ + "\2\u0127\1\351\13\u0127\2\u02f0\3\u0127\1\u02f0\1\u0127\1\u02f0"+ + "\1\u0127\1\u02f0\2\u0127\1\u02f0\1\u0127\4\u02f0\3\u0127\1\u02f0"+ + "\1\u0127\1\u02f0\14\u0127\1\351\3\u02f1\3\351\1\u02f1\3\351"+ + "\1\75\11\351\1\u0126\1\u0127\1\u0128\1\230\1\351\1\230"+ + "\7\351\2\u02f1\3\351\1\u02f1\1\351\1\u02f1\1\351\1\u02f1"+ + "\2\351\1\u02f1\1\351\4\u02f1\3\351\1\u02f1\1\351\1\u02f1"+ + "\14\351\4\225\1\u02f2\1\225\1\u02df\2\225\3\0\7\225"+ + "\1\0\63\225\3\u02e0\1\231\2\225\1\u02e0\1\225\3\0"+ + "\7\225\1\0\2\225\1\75\13\225\2\u02e0\3\225\1\u02e0"+ + "\1\225\1\u02e0\1\225\1\u02e0\2\225\1\u02e0\1\225\4\u02e0"+ + "\3\225\1\u02e0\1\225\1\u02e0\15\225\3\u02f3\1\231\2\225"+ + "\1\u02f3\1\225\3\0\7\225\1\0\2\225\1\75\13\225"+ + "\2\u02f3\3\225\1\u02f3\1\225\1\u02f3\1\225\1\u02f3\2\225"+ + "\1\u02f3\1\225\4\u02f3\3\225\1\u02f3\1\225\1\u02f3\14\225"+ + "\1\75\3\u02f4\3\75\1\u02f4\15\75\1\224\1\225\1\226"+ + "\1\0\1\75\1\0\7\75\2\u02f4\3\75\1\u02f4\1\75"+ + "\1\u02f4\1\75\1\u02f4\2\75\1\u02f4\1\75\4\u02f4\3\75"+ + "\1\u02f4\1\75\1\u02f4\14\75\10\0\1\u02e4\3\0\2\u02e5"+ + "\4\0\1\u02e4\65\0\1\u02cb\2\0\2\u02cb\1\0\1\u02e5"+ + "\7\0\1\u02cb\1\0\1\u02e5\10\0\25\u02cb\4\0\1\u02cb"+ + "\2\0\3\u02cb\10\0\1\u02cb\45\0\1\u02f5\44\0\3\144"+ + "\1\0\3\144\10\0\4\144\7\0\7\144\1\u02f6\22\144"+ + "\2\0\3\144\10\0\1\144\3\0\10\u02d2\1\u02ea\3\0"+ + "\2\u02af\4\u02d2\1\u02ea\1\0\62\u02d2\1\0\3\u02eb\1\0"+ + "\3\u02eb\1\u02f7\3\0\2\u02f8\2\0\4\u02eb\7\0\32\u02eb"+ + "\2\0\3\u02eb\10\0\1\u02eb\13\0\1\u02ec\3\0\1\u02ed"+ + "\5\0\1\u02ec\65\0\1\u02d6\2\0\2\u02d6\1\0\1\u02ed"+ + "\7\0\1\u02d6\1\0\1\u02ed\10\0\25\u02d6\4\0\1\u02d6"+ + "\2\0\3\u02d6\10\0\1\u02d6\107\0\1\u02f9\1\0\4\u0127"+ + "\1\u02da\1\u0127\1\u02db\2\u0127\2\351\1\75\7\u0127\1\351"+ + "\2\u0127\1\351\60\u0127\3\u02fa\1\u0163\2\u0127\1\u02fa\1\u0127"+ + "\2\351\1\75\7\u0127\1\351\2\u0127\1\351\13\u0127\2\u02fa"+ + "\3\u0127\1\u02fa\1\u0127\1\u02fa\1\u0127\1\u02fa\2\u0127\1\u02fa"+ + "\1\u0127\4\u02fa\3\u0127\1\u02fa\1\u0127\1\u02fa\14\u0127\1\351"+ + "\3\u0267\3\351\1\u0267\3\351\1\75\11\351\1\u0126\1\u0127"+ + "\1\u0128\1\230\1\351\1\230\7\351\2\u0267\3\351\1\u0267"+ + "\1\351\1\u0267\1\351\1\u0267\2\351\1\u0267\1\351\4\u0267"+ + "\3\351\1\u0267\1\351\1\u0267\14\351\4\225\1\u02de\1\225"+ + "\1\u02df\2\225\3\0\7\225\1\0\2\225\1\75\60\225"+ + "\3\u02fb\1\231\2\225\1\u02fb\1\225\3\0\7\225\1\0"+ + "\2\225\1\75\13\225\2\u02fb\3\225\1\u02fb\1\225\1\u02fb"+ + "\1\225\1\u02fb\2\225\1\u02fb\1\225\4\u02fb\3\225\1\u02fb"+ + "\1\225\1\u02fb\14\225\1\75\3\u0270\3\75\1\u0270\15\75"+ + "\1\224\1\225\1\226\1\0\1\75\1\0\7\75\2\u0270"+ + "\3\75\1\u0270\1\75\1\u0270\1\75\1\u0270\2\75\1\u0270"+ + "\1\75\4\u0270\3\75\1\u0270\1\75\1\u0270\14\75\10\0"+ + "\1\u02f7\3\0\2\u02f8\4\0\1\u02f7\65\0\1\u02eb\2\0"+ + "\2\u02eb\1\0\1\u02f8\7\0\1\u02eb\1\0\1\u02f8\10\0"+ + "\25\u02eb\4\0\1\u02eb\2\0\3\u02eb\10\0\1\u02eb\22\0"+ + "\1\u02fc\66\0\1\u0127\3\u0269\1\u0163\2\u0127\1\u0269\1\u0127"+ + "\2\351\1\75\7\u0127\1\351\2\u0127\1\351\13\u0127\2\u0269"+ + "\3\u0127\1\u0269\1\u0127\1\u0269\1\u0127\1\u0269\2\u0127\1\u0269"+ + "\1\u0127\4\u0269\3\u0127\1\u0269\1\u0127\1\u0269\14\u0127\1\225"+ + "\3\u0272\1\231\2\225\1\u0272\1\225\3\0\7\225\1\0"+ + "\2\225\1\75\13\225\2\u0272\3\225\1\u0272\1\225\1\u0272"+ + "\1\225\1\u0272\2\225\1\u0272\1\225\4\u0272\3\225\1\u0272"+ + "\1\225\1\u0272\14\225"; + + private static int [] zzUnpackTrans() { + int [] result = new int[44450]; + int offset = 0; + offset = zzUnpackTrans(ZZ_TRANS_PACKED_0, offset, result); + return result; + } + + private static int zzUnpackTrans(String packed, int offset, int [] result) { + int i = 0; /* index in packed string */ + int j = offset; /* index in unpacked array */ + int l = packed.length(); + while (i < l) { + int count = packed.charAt(i++); + int value = packed.charAt(i++); + value--; + do result[j++] = value; while (--count > 0); + } + return j; + } + + + /* error codes */ + private static final int ZZ_UNKNOWN_ERROR = 0; + private static final int ZZ_NO_MATCH = 1; + private static final int ZZ_PUSHBACK_2BIG = 2; + + /* error messages for the codes above */ + private static final String ZZ_ERROR_MSG[] = { + "Unkown internal scanner error", + "Error: could not match input", + "Error: pushback value was too large" + }; + + /** + * ZZ_ATTRIBUTE[aState] contains the attributes of state aState + */ + private static final int [] ZZ_ATTRIBUTE = zzUnpackAttribute(); + + private static final String ZZ_ATTRIBUTE_PACKED_0 = + "\2\1\14\0\2\1\1\11\4\1\1\11\2\1\1\11"+ + "\14\1\1\11\1\1\1\11\4\1\1\11\1\1\1\11"+ + "\1\1\1\11\2\1\1\3\10\11\4\1\2\11\1\1"+ + "\1\11\3\1\1\11\1\1\1\11\3\1\2\11\1\1"+ + "\1\11\3\1\1\11\1\1\1\11\1\1\1\11\2\1"+ + "\3\0\2\11\1\0\1\11\1\0\2\1\1\0\15\1"+ + "\3\0\1\11\3\1\1\0\1\11\1\1\1\0\1\11"+ + "\4\1\5\11\1\0\1\1\1\0\1\11\1\1\3\0"+ + "\1\2\1\15\1\5\10\0\1\11\4\1\6\11\3\0"+ + "\1\11\5\0\1\1\1\0\1\11\1\1\1\11\2\1"+ + "\1\11\34\1\3\0\6\1\1\0\1\11\1\0\1\1"+ + "\5\0\1\11\2\0\1\1\4\0\1\11\1\0\1\1"+ + "\1\11\1\1\1\11\3\0\41\1\3\0\2\1\1\0"+ + "\1\11\1\1\14\0\1\11\1\1\3\0\45\1\1\11"+ + "\1\0\2\1\1\0\1\1\13\0\1\1\5\0\11\1"+ + "\1\0\30\1\1\11\2\1\7\0\2\1\10\0\1\1"+ + "\1\11\3\0\30\1\1\0\7\1\6\0\2\1\3\0"+ + "\1\1\6\0\1\1\1\11\4\0\13\1\1\0\21\1"+ + "\1\11\6\0\1\1\6\0\1\1\13\0\10\1\1\0"+ + "\23\1\4\0\2\11\2\1\4\0\2\1\7\0\1\1"+ + "\1\11\1\0\10\1\1\0\1\1\1\0\11\1\2\0"+ + "\1\11\2\0\1\1\2\0\2\1\4\0\1\1\2\0"+ + "\2\1\7\0\4\1\1\0\4\1\2\0\11\1\4\0"+ + "\1\11\1\0\4\1\3\0\4\1\3\0\1\1\1\11"+ + "\1\0\6\1\2\0\10\1\7\0\3\1\5\0\3\1"+ + "\1\0\1\1\1\11\1\0\3\1\3\0\7\1\2\11"+ + "\4\0\1\1\3\0\2\1\1\11\1\1\1\0\1\11"+ + "\1\0\5\1\4\0\1\1\2\0\1\1\1\11\2\1"+ + "\4\0\1\11"; + + private static int [] zzUnpackAttribute() { + int [] result = new int[764]; + int offset = 0; + offset = zzUnpackAttribute(ZZ_ATTRIBUTE_PACKED_0, offset, result); + return result; + } + + private static int zzUnpackAttribute(String packed, int offset, int [] result) { + int i = 0; /* index in packed string */ + int j = offset; /* index in unpacked array */ + int l = packed.length(); + while (i < l) { + int count = packed.charAt(i++); + int value = packed.charAt(i++); + do result[j++] = value; while (--count > 0); + } + return j; + } + + /** the input device */ + private java.io.Reader zzReader; + + /** the current state of the DFA */ + private int zzState; + + /** the current lexical state */ + private int zzLexicalState = YYINITIAL; + + /** this buffer contains the current text to be matched and is + the source of the yytext() string */ + private char zzBuffer[] = new char[ZZ_BUFFERSIZE]; + + /** the textposition at the last accepting state */ + private int zzMarkedPos; + + /** the textposition at the last state to be included in yytext */ + private int zzPushbackPos; + + /** the current text position in the buffer */ + private int zzCurrentPos; + + /** startRead marks the beginning of the yytext() string in the buffer */ + private int zzStartRead; + + /** endRead marks the last character in the buffer, that has been read + from input */ + private int zzEndRead; + + /** number of newlines encountered up to the start of the matched text */ + private int yyline; + + /** the number of characters up to the start of the matched text */ + private int yychar; + + /** + * the number of characters from the last newline up to the start of the + * matched text + */ + private int yycolumn; + + /** + * zzAtBOL == true <=> the scanner is currently at the beginning of a line + */ + private boolean zzAtBOL = true; + + /** zzAtEOF == true <=> the scanner is at the EOF */ + private boolean zzAtEOF; + + + /** the stack of open (nested) input streams to read from */ + private java.util.Stack zzStreams = new java.util.Stack(); + + /** + * inner class used to store info for nested + * input streams + */ + private static final class ZzFlexStreamInfo { + java.io.Reader zzReader; + int zzEndRead; + int zzStartRead; + int zzCurrentPos; + int zzMarkedPos; + int zzPushbackPos; + int yyline; + int yycolumn; + char [] zzBuffer; + boolean zzAtEOF; + + /** sets all values stored in this class */ + ZzFlexStreamInfo(java.io.Reader zzReader, int zzEndRead, int zzStartRead, + int zzCurrentPos, int zzMarkedPos, int zzPushbackPos, + char [] zzBuffer, boolean zzAtEOF, int yyline, int yycolumn) { + this.zzReader = zzReader; + this.zzEndRead = zzEndRead; + this.zzStartRead = zzStartRead; + this.zzCurrentPos = zzCurrentPos; + this.zzMarkedPos = zzMarkedPos; + this.zzPushbackPos = zzPushbackPos; + this.zzBuffer = zzBuffer; + this.zzAtEOF = zzAtEOF; + this.yyline = yyline; + this.yycolumn = yycolumn; + } + } + + /** denotes if the user-EOF-code has already been executed */ + private boolean zzEOFDone; + + /* user code: */ + int balance = 0; + int commentbalance = 0; + int action_line = 0; + int bufferSize = 16384; + + File file; + Stack files = new Stack(); + + StringBuffer userCode = new StringBuffer(); + + String classCode; + String initCode; + String initThrow; + String eofCode; + String eofThrow; + String lexThrow; + String eofVal; + String scanErrorException; + String cupSymbol = "sym"; + + StringBuffer actionText = new StringBuffer(); + StringBuffer string = new StringBuffer(); + + boolean charCount; + boolean lineCount; + boolean columnCount; + boolean cupCompatible; + boolean cupDebug; + boolean isInteger; + boolean isIntWrap; + boolean isYYEOF; + boolean notUnix; + boolean isPublic; + boolean isFinal; + boolean isAbstract; + boolean lookAheadUsed; + boolean bolUsed; + boolean standalone; + boolean debugOption; + boolean useRowMap = Options.gen_method == Options.PACK || Options.gen_method == Options.TABLE; + boolean packed = Options.gen_method == Options.PACK; + boolean caseless; + boolean inclusive_states; + boolean eofclose; + + String isImplementing; + String isExtending; + String className = "Yylex"; + String functionName; + String tokenType; + String visibility = "public"; + + LexicalStates states = new LexicalStates(); + + Vector actions = new Vector(); + + private int nextState; + + boolean macroDefinition; + + Timer t = new Timer(); + + public int currentLine() { + return yyline; + } + + public void setFile(File file) { + this.file = file; + } + + private Symbol symbol(int type, Object value) { + return new Symbol(type, yyline, yycolumn, value); + } + + private Symbol symbol(int type) { + return new Symbol(type, yyline, yycolumn); + } + + // updates line and column count to the beginning of the first + // non whitespace character in yytext, but leaves yyline+yycolumn + // untouched + private Symbol symbol_countUpdate(int type, Object value) { + int lc = yyline; + int cc = yycolumn; + String text = yytext(); + + for (int i=0; i < text.length(); i++) { + char c = text.charAt(i); + + if (c != '\n' && c != '\r' && c != ' ' && c != '\t' ) + return new Symbol(type, lc, cc, value); + + if (c == '\n') { + lc++; + cc = 0; + } + else + cc++; + } + + return new Symbol(type, yyline, yycolumn, value); + } + + private String makeMacroIdent() { + String matched = yytext().trim(); + return matched.substring(1, matched.length()-1).trim(); + } + + public static String conc(Object a, Object b) { + if (a == null && b == null) return null; + if (a == null) return b.toString(); + if (b == null) return a.toString(); + + return a.toString()+b.toString(); + } + + public static String concExc(Object a, Object b) { + if (a == null && b == null) return null; + if (a == null) return b.toString(); + if (b == null) return a.toString(); + + return a.toString()+", "+b.toString(); + } + + + /** + * Creates a new scanner + * There is also a java.io.InputStream version of this constructor. + * + * @param in the java.io.Reader to read input from. + */ + public LexScan(java.io.Reader in) { + states.insert("YYINITIAL", true); + this.zzReader = in; + } + + /** + * Creates a new scanner. + * There is also java.io.Reader version of this constructor. + * + * @param in the java.io.Inputstream to read input from. + */ + public LexScan(java.io.InputStream in) { + this(new java.io.InputStreamReader(in)); + } + + /** + * Unpacks the compressed character translation table. + * + * @param packed the packed character translation table + * @return the unpacked character translation table + */ + private static char [] zzUnpackCMap(String packed) { + char [] map = new char[0x10000]; + int i = 0; /* index in packed string */ + int j = 0; /* index in unpacked array */ + while (i < 1666) { + int count = packed.charAt(i++); + char value = packed.charAt(i++); + do map[j++] = value; while (--count > 0); + } + return map; + } + + + /** + * Refills the input buffer. + * + * @return false, iff there was new input. + * + * @exception java.io.IOException if any I/O-Error occurs + */ + private boolean zzRefill() throws java.io.IOException { + + /* first: make room (if you can) */ + if (zzStartRead > 0) { + System.arraycopy(zzBuffer, zzStartRead, + zzBuffer, 0, + zzEndRead-zzStartRead); + + /* translate stored positions */ + zzEndRead-= zzStartRead; + zzCurrentPos-= zzStartRead; + zzMarkedPos-= zzStartRead; + zzPushbackPos-= zzStartRead; + zzStartRead = 0; + } + + /* is the buffer big enough? */ + if (zzCurrentPos >= zzBuffer.length) { + /* if not: blow it up */ + char newBuffer[] = new char[zzCurrentPos*2]; + System.arraycopy(zzBuffer, 0, newBuffer, 0, zzBuffer.length); + zzBuffer = newBuffer; + } + + /* finally: fill the buffer with new input */ + int numRead = zzReader.read(zzBuffer, zzEndRead, + zzBuffer.length-zzEndRead); + + if (numRead < 0) { + return true; + } + else { + zzEndRead+= numRead; + return false; + } + } + + + /** + * Closes the input stream. + */ + public final void yyclose() throws java.io.IOException { + zzAtEOF = true; /* indicate end of file */ + zzEndRead = zzStartRead; /* invalidate buffer */ + + if (zzReader != null) + zzReader.close(); + } + + + /** + * Stores the current input stream on a stack, and + * reads from a new stream. Lexical state, line, + * char, and column counting remain untouched. + * + * The current input stream can be restored with + * yypopstream (usually in an <> action). + * + * @param reader the new input stream to read from + * + * @see #yypopStream() + */ + public final void yypushStream(java.io.Reader reader) { + zzStreams.push( + new ZzFlexStreamInfo(zzReader, zzEndRead, zzStartRead, zzCurrentPos, + zzMarkedPos, zzPushbackPos, zzBuffer, zzAtEOF, + yyline, yycolumn) + ); + zzAtEOF = false; + zzBuffer = new char[ZZ_BUFFERSIZE]; + zzReader = reader; + zzEndRead = zzStartRead = 0; + zzCurrentPos = zzMarkedPos = zzPushbackPos = 0; + yyline = yycolumn = 0; + } + + + /** + * Closes the current input stream and continues to + * read from the one on top of the stream stack. + * + * @throws java.util.EmptyStackException + * if there is no further stream to read from. + * + * @throws java.io.IOException + * if there was an error in closing the stream. + * + * @see #yypushStream(java.io.Reader) + */ + public final void yypopStream() throws java.io.IOException { + zzReader.close(); + ZzFlexStreamInfo s = (ZzFlexStreamInfo) zzStreams.pop(); + zzBuffer = s.zzBuffer; + zzReader = s.zzReader; + zzEndRead = s.zzEndRead; + zzStartRead = s.zzStartRead; + zzCurrentPos = s.zzCurrentPos; + zzMarkedPos = s.zzMarkedPos ; + zzPushbackPos = s.zzPushbackPos; + zzAtEOF = s.zzAtEOF; + yyline = s.yyline; + yycolumn = s.yycolumn; + } + + + /** + * Returns true iff there are still streams left + * to read from on the stream stack. + */ + public final boolean yymoreStreams() { + return !zzStreams.isEmpty(); + } + + + /** + * Resets the scanner to read from a new input stream. + * Does not close the old reader. + * + * All internal variables are reset, the old input stream + * cannot be reused (internal buffer is discarded and lost). + * Lexical state is set to ZZ_INITIAL. + * + * @param reader the new input stream + * + * @see #yypushStream(java.io.Reader) + * @see #yypopStream() + */ + public final void yyreset(java.io.Reader reader) { + zzReader = reader; + zzAtBOL = true; + zzAtEOF = false; + zzEndRead = zzStartRead = 0; + zzCurrentPos = zzMarkedPos = zzPushbackPos = 0; + yyline = yychar = yycolumn = 0; + zzLexicalState = YYINITIAL; + } + + + /** + * Returns the current lexical state. + */ + public final int yystate() { + return zzLexicalState; + } + + + /** + * Enters a new lexical state + * + * @param newState the new lexical state + */ + public final void yybegin(int newState) { + zzLexicalState = newState; + } + + + /** + * Returns the text matched by the current regular expression. + */ + public final String yytext() { + return new String( zzBuffer, zzStartRead, zzMarkedPos-zzStartRead ); + } + + + /** + * Returns the character at position pos from the + * matched text. + * + * It is equivalent to yytext().charAt(pos), but faster + * + * @param pos the position of the character to fetch. + * A value from 0 to yylength()-1. + * + * @return the character at position pos + */ + public final char yycharat(int pos) { + return zzBuffer[zzStartRead+pos]; + } + + + /** + * Returns the length of the matched text region. + */ + public final int yylength() { + return zzMarkedPos-zzStartRead; + } + + + /** + * Reports an error that occured while scanning. + * + * In a wellformed scanner (no or only correct usage of + * yypushback(int) and a match-all fallback rule) this method + * will only be called with things that "Can't Possibly Happen". + * If this method is called, something is seriously wrong + * (e.g. a JFlex bug producing a faulty scanner etc.). + * + * Usual syntax/scanner level error handling should be done + * in error fallback rules. + * + * @param errorCode the code of the errormessage to display + */ + private void zzScanError(int errorCode) { + String message; + try { + message = ZZ_ERROR_MSG[errorCode]; + } + catch (ArrayIndexOutOfBoundsException e) { + message = ZZ_ERROR_MSG[ZZ_UNKNOWN_ERROR]; + } + + throw new Error(message); + } + + + /** + * Pushes the specified amount of characters back into the input stream. + * + * They will be read again by then next call of the scanning method + * + * @param number the number of characters to be read again. + * This number must not be greater than yylength()! + */ + public void yypushback(int number) { + if ( number > yylength() ) + zzScanError(ZZ_PUSHBACK_2BIG); + + zzMarkedPos -= number; + } + + + /** + * Contains user EOF-code, which will be executed exactly once, + * when the end of file is reached + */ + private void zzDoEOF() throws java.io.IOException { + if (!zzEOFDone) { + zzEOFDone = true; + yyclose(); + } + } + + + /** + * Resumes scanning until the next regular expression is matched, + * the end of input is encountered or an I/O-Error occurs. + * + * @return the next token + * @exception java.io.IOException if any I/O-Error occurs + */ + public Symbol next_token() throws java.io.IOException { + int zzInput; + int zzAction; + + int [] zzTransL = ZZ_TRANS; + int [] zzRowMapL = ZZ_ROWMAP; + int [] zzAttrL = ZZ_ATTRIBUTE; + int zzPushbackPosL = zzPushbackPos = -1; + boolean zzWasPushback; + + while (true) { + // cached fields: + int zzCurrentPosL; + int zzMarkedPosL = zzMarkedPos; + int zzEndReadL = zzEndRead; + char [] zzBufferL = zzBuffer; + char [] zzCMapL = ZZ_CMAP; + + boolean zzR = false; + for (zzCurrentPosL = zzStartRead; zzCurrentPosL < zzMarkedPosL; + zzCurrentPosL++) { + switch (zzBufferL[zzCurrentPosL]) { + case '\u000B': + case '\u000C': + case '\u0085': + case '\u2028': + case '\u2029': + yyline++; + yycolumn = 0; + zzR = false; + break; + case '\r': + yyline++; + yycolumn = 0; + zzR = true; + break; + case '\n': + if (zzR) + zzR = false; + else { + yyline++; + yycolumn = 0; + } + break; + default: + zzR = false; + yycolumn++; + } + } + + if (zzR) { + // peek one character ahead if it is \n (if we have counted one line too much) + boolean zzPeek; + if (zzMarkedPosL < zzEndReadL) + zzPeek = zzBufferL[zzMarkedPosL] == '\n'; + else if (zzAtEOF) + zzPeek = false; + else { + boolean eof = zzRefill(); + zzEndReadL = zzEndRead; + zzMarkedPosL = zzMarkedPos; + zzBufferL = zzBuffer; + if (eof) + zzPeek = false; + else + zzPeek = zzBufferL[zzMarkedPosL] == '\n'; + } + if (zzPeek) yyline--; + } + if (zzMarkedPosL > zzStartRead) { + switch (zzBufferL[zzMarkedPosL-1]) { + case '\n': + case '\u000B': + case '\u000C': + case '\u0085': + case '\u2028': + case '\u2029': + zzAtBOL = true; + break; + case '\r': + if (zzMarkedPosL < zzEndReadL) + zzAtBOL = zzBufferL[zzMarkedPosL] != '\n'; + else if (zzAtEOF) + zzAtBOL = false; + else { + boolean eof = zzRefill(); + zzMarkedPosL = zzMarkedPos; + zzEndReadL = zzEndRead; + zzBufferL = zzBuffer; + if (eof) + zzAtBOL = false; + else + zzAtBOL = zzBufferL[zzMarkedPosL] != '\n'; + } + break; + default: + zzAtBOL = false; + } + } + zzAction = -1; + + zzCurrentPosL = zzCurrentPos = zzStartRead = zzMarkedPosL; + + if (zzAtBOL) + zzState = ZZ_LEXSTATE[zzLexicalState+1]; + else + zzState = ZZ_LEXSTATE[zzLexicalState]; + + zzWasPushback = false; + + zzForAction: { + while (true) { + + if (zzCurrentPosL < zzEndReadL) + zzInput = zzBufferL[zzCurrentPosL++]; + else if (zzAtEOF) { + zzInput = YYEOF; + break zzForAction; + } + else { + // store back cached positions + zzCurrentPos = zzCurrentPosL; + zzMarkedPos = zzMarkedPosL; + zzPushbackPos = zzPushbackPosL; + boolean eof = zzRefill(); + // get translated positions and possibly new buffer + zzCurrentPosL = zzCurrentPos; + zzMarkedPosL = zzMarkedPos; + zzBufferL = zzBuffer; + zzEndReadL = zzEndRead; + zzPushbackPosL = zzPushbackPos; + if (eof) { + zzInput = YYEOF; + break zzForAction; + } + else { + zzInput = zzBufferL[zzCurrentPosL++]; + } + } + int zzNext = zzTransL[ zzRowMapL[zzState] + zzCMapL[zzInput] ]; + if (zzNext == -1) break zzForAction; + zzState = zzNext; + + int zzAttributes = zzAttrL[zzState]; + if ( (zzAttributes & 2) == 2 ) + zzPushbackPosL = zzCurrentPosL; + + if ( (zzAttributes & 1) == 1 ) { + zzWasPushback = (zzAttributes & 4) == 4; + zzAction = zzState; + zzMarkedPosL = zzCurrentPosL; + if ( (zzAttributes & 8) == 8 ) break zzForAction; + } + + } + } + + // store back cached position + zzMarkedPos = zzMarkedPosL; + if (zzWasPushback) + zzMarkedPos = zzPushbackPosL; + + switch (zzAction < 0 ? zzAction : ZZ_ACTION[zzAction]) { + case 85: + { return symbol(FULL); + } + case 142: break; + case 92: + { debugOption = true; + } + case 143: break; + case 57: + { return symbol(CHAR,new Character('\t')); + } + case 144: break; + case 108: + { actionText.setLength(0); yybegin(JAVA_CODE); + Symbol s = symbol_countUpdate(EOFRULE, null); + action_line = s.left+1; + return s; + } + case 145: break; + case 107: + { throw new ScannerException(file,ErrorMessages.NO_BUFFER_SIZE, yyline); + } + case 146: break; + case 91: + { isYYEOF = true; + } + case 147: break; + case 54: + { return symbol(CHAR, new Character(yytext().charAt(1))); + } + case 148: break; + case 98: + { isInteger = true; + if (eofVal == null) + eofVal = "return 0;"; + eofclose = true; + } + case 149: break; + case 11: + { yybegin(REGEXP); + } + case 150: break; + case 112: + { isAbstract = true; + } + case 151: break; + case 101: + { initCode = conc(initCode,string); yybegin(MACROS); + } + case 152: break; + case 45: + { throw new ScannerException(file,ErrorMessages.UNEXPECTED_NL, yyline, yycolumn); + } + case 153: break; + case 12: + { return symbol_countUpdate(RBRACE, null); + } + case 154: break; + case 74: + { return symbol(REPEAT, new Integer(yytext().substring(1).trim())); + } + case 155: break; + case 55: + { return symbol(CHAR, new Character( (char) Integer.parseInt(yytext().substring(1,yytext().length()), 8))); + } + case 156: break; + case 97: + { columnCount = true; + } + case 157: break; + case 122: + { return symbol(LETTERCLASS); + } + case 158: break; + case 15: + { if (macroDefinition) { yybegin(MACROS); } return symbol(REGEXPEND); + } + case 159: break; + case 77: + { inclusive_states = true; yybegin(STATELIST); + } + case 160: break; + case 56: + { return symbol(CHAR,new Character('\n')); + } + case 161: break; + case 81: + { return symbol(MACROUSE, yytext().substring(1,yytext().length()-1)); + } + case 162: break; + case 25: + { return symbol(OPENBRACKET); + } + case 163: break; + case 123: + { throw new ScannerException(file,ErrorMessages.QUIL_INITTHROW, yyline); + } + case 164: break; + case 126: + { visibility = "private"; Skeleton.makePrivate(); + } + case 165: break; + case 49: + { commentbalance++; + } + case 166: break; + case 9: + { throw new ScannerException(file,ErrorMessages.UNKNOWN_OPTION, yyline, yycolumn); + } + case 167: break; + case 68: + { string.append('\n'); + } + case 168: break; + case 33: + { balance++; actionText.append('{'); + } + case 169: break; + case 48: + { if (commentbalance > 0) + commentbalance--; + else + yybegin(nextState); + } + case 170: break; + case 67: + { string.append('\"'); + } + case 171: break; + case 95: + { tokenType = yytext().substring(6).trim(); + } + case 172: break; + case 79: + { return symbol_countUpdate(MACROUSE, makeMacroIdent()); + } + case 173: break; + case 14: + { return symbol(CHAR, new Character(yytext().charAt(0))); + } + case 174: break; + case 140: + { eofclose = false; + } + case 175: break; + case 32: + { if (balance > 0) { + balance--; + actionText.append('}'); + } + else { + yybegin(REGEXPSTART); + Action a = new Action(actionText.toString(), action_line); + actions.addElement(a); + return symbol(ACTION, a); + } + } + case 176: break; + case 120: + { isExtending = yytext().substring(9).trim(); + } + case 177: break; + case 113: + { cupSymbol = yytext().substring(8).trim(); + if (cupCompatible) Out.warning(ErrorMessages.CUPSYM_AFTER_CUP, yyline); + } + case 178: break; + case 63: + { yybegin(REPEATEXP); return symbol(REPEAT, new Integer(yytext().trim().substring(1).trim())); + } + case 179: break; + case 88: + { packed = true; useRowMap = true; + } + case 180: break; + case 27: + { return symbol(PLUS); + } + case 181: break; + case 99: + { isPublic = true; + } + case 182: break; + case 70: + { string.append('\r'); + } + case 183: break; + case 76: + { inclusive_states = false; yybegin(STATELIST); + } + case 184: break; + case 3: + { userCode.append(yytext()); + } + case 185: break; + case 19: + { lookAheadUsed = true; return symbol(LOOKAHEAD); + } + case 186: break; + case 110: + { lexThrow = concExc(lexThrow,yytext().substring(8).trim()); + } + case 187: break; + case 26: + { return symbol(CLOSEBRACKET); + } + case 188: break; + case 80: + { string.append( (char) Integer.parseInt(yytext().substring(2,yytext().length()), 16)); + } + case 189: break; + case 37: + { throw new ScannerException(file,ErrorMessages.UNTERMINATED_STR, yyline, yycolumn); + } + case 190: break; + case 69: + { string.append('\t'); + } + case 191: break; + case 23: + { return symbol(BANG); + } + case 192: break; + case 111: + { eofclose = true; + } + case 193: break; + case 17: + { yybegin(CHARCLASS); return symbol(OPENCLASS); + } + case 194: break; + case 114: + { cupDebug = true; + } + case 195: break; + case 87: + { charCount = true; + } + case 196: break; + case 58: + { return symbol(CHAR,new Character('\r')); + } + case 197: break; + case 66: + { string.append( (char) Integer.parseInt(yytext().substring(1,yytext().length()), 8)); + } + case 198: break; + case 134: + { scanErrorException = yytext().substring(11).trim(); + } + case 199: break; + case 60: + { return symbol(CHAR,new Character('\b')); + } + case 200: break; + case 35: + { yybegin(REGEXP); return symbol(MORETHAN); + } + case 201: break; + case 132: + { isImplementing = concExc(isImplementing, yytext().substring(12).trim()); + } + case 202: break; + case 78: + { return symbol(CHAR, new Character( (char) Integer.parseInt(yytext().substring(2,yytext().length()), 16))); + } + case 203: break; + case 90: + { isFinal = true; + } + case 204: break; + case 137: + { return symbol(UPPERCLASS); + } + case 205: break; + case 46: + { yybegin(REGEXP); return symbol(RBRACE); + } + case 206: break; + case 51: + { Out.warning(ErrorMessages.NOT_AT_BOL, yyline); yypushback(1); + } + case 207: break; + case 28: + { return symbol(QUESTION); + } + case 208: break; + case 36: + { string.append(yytext()); + } + case 209: break; + case 135: + { initThrow = concExc(initThrow,string); yybegin(MACROS); + } + case 210: break; + case 141: + { return symbol(JLETTERDIGITCLASS); + } + case 211: break; + case 53: + { nextState = REGEXPSTART; yybegin(COMMENT); + } + case 212: break; + case 130: + { eofThrow = concExc(eofThrow,string); yybegin(MACROS); + } + case 213: break; + case 61: + { actionText.setLength(0); yybegin(JAVA_CODE); action_line = yyline+1; return symbol(REGEXPEND); + } + case 214: break; + case 138: + { return symbol(LOWERCLASS); + } + case 215: break; + case 38: + { yybegin(nextState); return symbol(STRING, string.toString()); + } + case 216: break; + case 82: + { classCode = conc(classCode,string); yybegin(MACROS); + } + case 217: break; + case 8: + { return symbol(IDENT, yytext()); + } + case 218: break; + case 43: + { return symbol(HAT); + } + case 219: break; + case 29: + { lookAheadUsed = true; return symbol(DOLLAR); + } + case 220: break; + case 124: + { eofThrow = concExc(eofThrow,yytext().substring(10).trim()); + } + case 221: break; + case 5: + { states.insert(yytext(),inclusive_states); + } + case 222: break; + case 127: + { standalone = true; isInteger = true; + } + case 223: break; + case 4: + { throw new ScannerException(file,ErrorMessages.UNEXPECTED_CHAR, yyline, yycolumn); + } + case 224: break; + case 47: + { t.start(); + yybegin(MACROS); + macroDefinition = true; + return symbol(USERCODE,userCode); + } + case 225: break; + case 59: + { return symbol(CHAR,new Character('\f')); + } + case 226: break; + case 94: + { eofCode = conc(eofCode,string); yybegin(MACROS); + } + case 227: break; + case 65: + { string.append(yytext().charAt(1)); + } + case 228: break; + case 115: + { caseless = true; + } + case 229: break; + case 39: + { throw new ScannerException(file,ErrorMessages.EOL_IN_CHARCLASS,yyline,yycolumn); + } + case 230: break; + case 117: + { return symbol(DIGITCLASS); + } + case 231: break; + case 64: + { if (macroDefinition) { + yybegin(EATWSPNL); + return symbol(BAR); + } + else { + yybegin(REGEXPSTART); + return symbol(NOACTION); + } + } + case 232: break; + case 30: + { bolUsed = true; return symbol(HAT); + } + case 233: break; + case 105: + { throw new ScannerException(file,ErrorMessages.QUIL_CUPSYM, yyline); + } + case 234: break; + case 102: + { isIntWrap = true; + } + case 235: break; + case 41: + { if (balance > 0) balance--; else yybegin(REGEXP); return symbol(CLOSECLASS); + } + case 236: break; + case 84: + { cupCompatible = true; + isImplementing = concExc(isImplementing, "java_cup.runtime.Scanner"); + if (functionName == null) + functionName = "next_token"; + if (tokenType == null) + tokenType = "java_cup.runtime.Symbol"; + if (eofVal == null) + eofVal = "return new java_cup.runtime.Symbol("+cupSymbol+".EOF);"; + if (!Options.jlex) eofclose = true; + } + case 237: break; + case 116: + { bufferSize = Integer.parseInt(yytext().substring(8).trim()); + } + case 238: break; + case 31: + { actionText.append(yytext()); + } + case 239: break; + case 86: + { lineCount = true; + } + case 240: break; + case 128: + { throw new ScannerException(file,ErrorMessages.QUIL_SCANERROR, yyline); + } + case 241: break; + case 104: + { throw new ScannerException(file,ErrorMessages.QUIL_THROW, yyline); + } + case 242: break; + case 83: + { isInteger = true; + } + case 243: break; + case 129: + { return symbol(JLETTERCLASS); + } + case 244: break; + case 18: + { return symbol(STAR); + } + case 245: break; + case 121: + { throw new ScannerException(file,ErrorMessages.QUIL_EOFTHROW, yyline); + } + case 246: break; + case 44: + { return symbol(DASH); + } + case 247: break; + case 106: + { className = yytext().substring(7).trim(); + } + case 248: break; + case 62: + { nextState = REGEXP; yybegin(COMMENT); + } + case 249: break; + case 136: + { lexThrow = concExc(lexThrow,yytext().substring(12).trim()); + } + case 250: break; + case 22: + { return symbol(BAR); + } + case 251: break; + case 125: + { functionName = yytext().substring(10).trim(); + } + case 252: break; + case 13: + { yybegin(STATES); return symbol_countUpdate(LESSTHAN, null); + } + case 253: break; + case 119: + { eofVal = string.toString(); yybegin(MACROS); + } + case 254: break; + case 73: + { yypushback(1); yycolumn--; return symbol(CHAR, new Character(yytext().charAt(0))); + } + case 255: break; + case 24: + { return symbol(TILDE); + } + case 256: break; + case 139: + { lexThrow = concExc(lexThrow,string); yybegin(MACROS); + } + case 257: break; + case 103: + { notUnix = true; + } + case 258: break; + case 89: + { packed = false; useRowMap = true; + } + case 259: break; + case 20: + { string.setLength(0); nextState = REGEXP; yybegin(STRING_CONTENT); + } + case 260: break; + case 2: + { /* ignore */ + } + case 261: break; + case 93: + { return symbol(UNICODE); + } + case 262: break; + case 16: + { return symbol(POINT); + } + case 263: break; + case 72: + { string.append('\b'); + } + case 264: break; + case 21: + { yybegin(REGEXPSTART); return symbol(LBRACE); + } + case 265: break; + case 131: + { initThrow = concExc(initThrow,yytext().substring(11).trim()); + } + case 266: break; + case 96: + { packed = false; useRowMap = false; + } + case 267: break; + case 7: + { yybegin(MACROS); + } + case 268: break; + case 75: + { string.setLength(0); yybegin(COPY); + } + case 269: break; + case 42: + { string.setLength(0); nextState = CHARCLASS; yybegin(STRING_CONTENT); + } + case 270: break; + case 118: + { actionText.setLength(0); yybegin(JAVA_CODE); action_line = yyline+1; return symbol(EOFRULE); + } + case 271: break; + case 52: + { macroDefinition = false; yybegin(REGEXPSTART); return symbol(DELIMITER); + } + case 272: break; + case 50: + { nextState = MACROS; yybegin(COMMENT); + } + case 273: break; + case 10: + { yybegin(REGEXP); return symbol(EQUALS); + } + case 274: break; + case 34: + { return symbol(COMMA); + } + case 275: break; + case 1: + { return symbol(EOF); + } + case 276: break; + case 100: + { throw new ScannerException(file,ErrorMessages.EOF_WO_ACTION); + } + case 277: break; + case 71: + { string.append('\f'); + } + case 278: break; + case 40: + { balance++; return symbol(OPENCLASS); + } + case 279: break; + case 133: + { throw new ScannerException(file,ErrorMessages.QUIL_YYLEXTHROW, yyline); + } + case 280: break; + case 109: + { File f = new File(yytext().substring(9).trim()); + if ( !f.canRead() ) + throw new ScannerException(file,ErrorMessages.NOT_READABLE, yyline); + // check for cycle + if (files.search(f) > 0) + throw new ScannerException(file,ErrorMessages.FILE_CYCLE, yyline); + try { + yypushStream( new FileReader(f) ); + files.push(file); + file = f; + Out.println("Including \""+file+"\""); + } + catch (FileNotFoundException e) { + throw new ScannerException(file,ErrorMessages.NOT_READABLE, yyline); + } + } + case 281: break; + case 6: + { + } + case 282: break; + default: + if (zzInput == YYEOF && zzStartRead == zzCurrentPos) { + zzAtEOF = true; + zzDoEOF(); + switch (zzLexicalState) { + case STRING_CONTENT: { + throw new ScannerException(file,ErrorMessages.EOF_IN_STRING); + } + case 765: break; + case MACROS: { + if ( yymoreStreams() ) { + file = (File) files.pop(); + yypopStream(); + } + else + throw new ScannerException(file,ErrorMessages.EOF_IN_MACROS); + } + case 766: break; + case STATELIST: { + throw new ScannerException(file,ErrorMessages.EOF_IN_MACROS); + } + case 767: break; + case CHARCLASS: { + throw new ScannerException(file,ErrorMessages.EOF_IN_REGEXP); + } + case 768: break; + case JAVA_CODE: { + throw new ScannerException(file,ErrorMessages.EOF_IN_ACTION, action_line-1); + } + case 769: break; + case REPEATEXP: { + throw new ScannerException(file,ErrorMessages.EOF_IN_REGEXP); + } + case 770: break; + case COMMENT: { + throw new ScannerException(file,ErrorMessages.EOF_IN_COMMENT); + } + case 771: break; + case STATES: { + throw new ScannerException(file,ErrorMessages.EOF_IN_STATES); + } + case 772: break; + case COPY: { + throw new ScannerException(file,ErrorMessages.EOF_IN_MACROS); + } + case 773: break; + default: + { + if ( yymoreStreams() ) { + file = (File) files.pop(); + yypopStream(); + } + else + return symbol(EOF); + } + } + } + else { + zzScanError(ZZ_NO_MATCH); + } + } + } + } + + /** + * Converts an int token code into the name of the + * token by reflection on the cup symbol class/interface sym + * + * This code was contributed by Karl Meissner + */ + private String getTokenName(int token) { + try { + java.lang.reflect.Field [] classFields = sym.class.getFields(); + for (int i = 0; i < classFields.length; i++) { + if (classFields[i].getInt(null) == token) { + return classFields[i].getName(); + } + } + } catch (Exception e) { + e.printStackTrace(System.err); + } + + return "UNKNOWN TOKEN"; + } + + /** + * Same as next_token but also prints the token to standard out + * for debugging. + * + * This code was contributed by Karl Meissner + */ + public Symbol debug_next_token() throws java.io.IOException { + java_cup.runtime.Symbol s = next_token(); + System.out.println( "line:" + (yyline+1) + " col:" + (yycolumn+1) + " --"+ yytext() + "--" + getTokenName(s.sym) + "--"); + return s; + } + + /** + * Runs the scanner on input files. + * + * This main method is the debugging routine for the scanner. + * It prints debugging information about each returned token to + * System.out until the end of file is reached, or an error occured. + * + * @param argv the command line, contains the filenames to run + * the scanner on. + */ + public static void main(String argv[]) { + if (argv.length == 0) { + System.out.println("Usage : java LexScan "); + } + else { + for (int i = 0; i < argv.length; i++) { + LexScan scanner = null; + try { + scanner = new LexScan( new java.io.FileReader(argv[i]) ); + while ( !scanner.zzAtEOF ) scanner.debug_next_token(); + } + catch (java.io.FileNotFoundException e) { + System.out.println("File not found : \""+argv[i]+"\""); + } + catch (java.io.IOException e) { + System.out.println("IO error scanning file \""+argv[i]+"\""); + System.out.println(e); + } + catch (Exception e) { + System.out.println("Unexpected exception:"); + e.printStackTrace(); + } + } + } + } + + +} diff --git a/tools/lexer/jflex-1.4/src/JFlex/LexicalStates.java b/tools/lexer/jflex-1.4/src/JFlex/LexicalStates.java new file mode 100644 index 000000000000..4fca957831be --- /dev/null +++ b/tools/lexer/jflex-1.4/src/JFlex/LexicalStates.java @@ -0,0 +1,99 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * JFlex 1.4.1 * + * Copyright (C) 1998-2004 Gerwin Klein * + * All rights reserved. * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License. See the file * + * COPYRIGHT for more information. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License along * + * with this program; if not, write to the Free Software Foundation, Inc., * + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +package JFlex; + +import java.util.Enumeration; +import java.util.Hashtable; +import java.util.Vector; + + +/** + * Simple symbol table, mapping lexical state names to integers. + * + * @author Gerwin Klein + * @version JFlex 1.4.1, $Revision: 2.2 $, $Date: 2004/11/06 23:03:32 $ + */ +public class LexicalStates { + + /** maps state name to state number */ + Hashtable states; + + /** codes of inclusive states (subset of states) */ + Vector inclusive; + + /** number of declared states */ + int numStates; + + + /** + * constructs a new lexical state symbol table + */ + public LexicalStates() { + states = new Hashtable(); + inclusive = new Vector(); + } + + + /** + * insert a new state declaration + */ + public void insert(String name, boolean is_inclusive) { + if ( states.containsKey(name) ) return; + + Integer code = new Integer(numStates++); + states.put(name, code); + + if (is_inclusive) + inclusive.addElement(code); + } + + + /** + * returns the number (code) of a declared state, + * null if no such state has been declared. + */ + public Integer getNumber(String name) { + return (Integer) states.get(name); + } + + + /** + * returns the number of declared states + */ + public int number() { + return numStates; + } + + + /** + * returns the names of all states + */ + public Enumeration names() { + return states.keys(); + } + + /** + * returns the code of all inclusive states + */ + public Enumeration getInclusiveStates() { + return inclusive.elements(); + } +} diff --git a/tools/lexer/jflex-1.4/src/JFlex/MacroException.java b/tools/lexer/jflex-1.4/src/JFlex/MacroException.java new file mode 100644 index 000000000000..85db5ad23c3a --- /dev/null +++ b/tools/lexer/jflex-1.4/src/JFlex/MacroException.java @@ -0,0 +1,49 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * JFlex 1.4.1 * + * Copyright (C) 1998-2004 Gerwin Klein * + * All rights reserved. * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License. See the file * + * COPYRIGHT for more information. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License along * + * with this program; if not, write to the Free Software Foundation, Inc., * + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +package JFlex; + + +/** + * This Exception is used in the macro expander to report cycles or + * undefined macro usages. + * + * @author Gerwin Klein + * @version JFlex 1.4.1, $Revision: 2.2 $, $Date: 2004/11/06 23:03:32 $ + */ +public class MacroException extends RuntimeException { + + /** + * Creates a new MacroException without message + */ + public MacroException() { + } + + + /** + * Creates a new MacroException with the specified message + * + * @param message the error description presented to the user. + */ + public MacroException(String message) { + super(message); + } + +} diff --git a/tools/lexer/jflex-1.4/src/JFlex/Macros.java b/tools/lexer/jflex-1.4/src/JFlex/Macros.java new file mode 100644 index 000000000000..a1f18e538402 --- /dev/null +++ b/tools/lexer/jflex-1.4/src/JFlex/Macros.java @@ -0,0 +1,219 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * JFlex 1.4.1 * + * Copyright (C) 1998-2004 Gerwin Klein * + * All rights reserved. * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License. See the file * + * COPYRIGHT for more information. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License along * + * with this program; if not, write to the Free Software Foundation, Inc., * + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +package JFlex; + +import java.util.Enumeration; +import java.util.Hashtable; +import java.util.Vector; + + +/** + * Symbol table and expander for macros. + * + * Maps macros to their (expanded) definitions, detects cycles and + * unused macros. + * + * @author Gerwin Klein + * @version JFlex 1.4.1, $Revision: 2.4 $, $Date: 2004/11/06 23:03:32 $ + */ +final public class Macros { + + /** Maps names of macros to their definition */ + private Hashtable macros; + + /** Maps names of macros to their "used" flag */ + private Hashtable used; + + + /** + * Creates a new macro expander. + */ + public Macros() { + macros = new Hashtable(); + used = new Hashtable(); + } + + + /** + * Stores a new macro and its definition. + * + * @param name the name of the new macro + * @param definition the definition of the new macro + * + * @return true, iff the macro name has not been + * stored before. + */ + public boolean insert(String name, RegExp definition) { + + if (Options.DEBUG) + Out.debug("inserting macro "+name+" with definition :"+Out.NL+definition); //$NON-NLS-1$ //$NON-NLS-2$ + + used.put(name, Boolean.FALSE); + return macros.put(name,definition) == null; + } + + + /** + * Marks a makro as used. + * + * @return true, iff the macro name has been + * stored before. + */ + public boolean markUsed(String name) { + return used.put(name, Boolean.TRUE) != null; + } + + + /** + * Tests if a macro has been used. + * + * @return true, iff the macro has been used in + * a regular expression. + */ + public boolean isUsed(String name) { + return ((Boolean)used.get(name)).booleanValue(); + } + + + /** + * Returns all unused macros. + * + * @return the enumeration of macro names that have not been used. + */ + public Enumeration unused() { + + Vector unUsed = new Vector(); + + Enumeration names = used.keys(); + while ( names.hasMoreElements() ) { + String name = (String) names.nextElement(); + Boolean isUsed = (Boolean) used.get( name ); + if ( !isUsed.booleanValue() ) unUsed.addElement(name); + } + + return unUsed.elements(); + } + + + /** + * Fetches the definition of the macro with the specified name, + *

+ * The definition will either be the same as stored (expand() not + * called), or an equivalent one, that doesn't contain any macro + * usages (expand() called before). + * + * @param name the name of the macro + * + * @return the definition of the macro, null if + * no macro with the specified name has been stored. + * + * @see JFlex.Macros#expand + */ + public RegExp getDefinition(String name) { + return (RegExp) macros.get(name); + } + + + /** + * Expands all stored macros, so that getDefinition always returns + * a defintion that doesn't contain any macro usages. + * + * @throws MacroException if there is a cycle in the macro usage graph. + */ + public void expand() throws MacroException { + + Enumeration names; + + names = macros.keys(); + + while ( names.hasMoreElements() ) { + String name = (String) names.nextElement(); + if ( isUsed(name) ) + macros.put(name, expandMacro(name, getDefinition(name))); + // this put doesn't get a new key, so only a new value + // is set for the key "name" (without changing the enumeration + // "names"!) + } + } + + + /** + * Expands the specified macro by replacing each macro usage + * with the stored definition. + * + * @param name the name of the macro to expand (for detecting cycles) + * @param definition the definition of the macro to expand + * + * @return the expanded definition of the macro. + * + * @throws MacroException when an error (such as a cyclic definition) + * occurs during expansion + */ + private RegExp expandMacro(String name, RegExp definition) throws MacroException { + + // Out.print("checking macro "+name); + // Out.print("definition is "+definition); + + switch ( definition.type ) { + case sym.BAR: + case sym.CONCAT: + RegExp2 binary = (RegExp2) definition; + binary.r1 = expandMacro(name, binary.r1); + binary.r2 = expandMacro(name, binary.r2); + return definition; + + case sym.STAR: + case sym.PLUS: + case sym.QUESTION: + case sym.BANG: + case sym.TILDE: + RegExp1 unary = (RegExp1) definition; + unary.content = expandMacro(name, (RegExp) unary.content); + return definition; + + case sym.MACROUSE: + String usename = (String) ((RegExp1) definition).content; + + if ( name.equals(usename) ) + throw new MacroException(ErrorMessages.get(ErrorMessages.MACRO_CYCLE, name)); + + RegExp usedef = getDefinition(usename); + + if ( usedef == null ) + throw new MacroException(ErrorMessages.get(ErrorMessages.MACRO_DEF_MISSING, usename, name)); + + markUsed(usename); + + return expandMacro(name, usedef); + + case sym.STRING: + case sym.STRING_I: + case sym.CHAR: + case sym.CHAR_I: + case sym.CCLASS: + case sym.CCLASSNOT: + return definition; + + default: + throw new MacroException("unknown expression type "+definition.type+" in macro expansion"); //$NON-NLS-1$ //$NON-NLS-2$ + } + } +} diff --git a/tools/lexer/jflex-1.4/src/JFlex/Main.java b/tools/lexer/jflex-1.4/src/JFlex/Main.java new file mode 100644 index 000000000000..20227c03cbdf --- /dev/null +++ b/tools/lexer/jflex-1.4/src/JFlex/Main.java @@ -0,0 +1,344 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * JFlex 1.4.1 * + * Copyright (C) 1998-2004 Gerwin Klein * + * All rights reserved. * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License. See the file * + * COPYRIGHT for more information. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License along * + * with this program; if not, write to the Free Software Foundation, Inc., * + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +package JFlex; + +import JFlex.gui.MainFrame; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileReader; +import java.io.IOException; +import java.util.Vector; + + +/** + * This is the main class of JFlex controlling the scanner generation process. + * It is responsible for parsing the commandline, getting input files, + * starting up the GUI if necessary, etc. + * + * @author Gerwin Klein + * @version JFlex 1.4.1, $Revision: 2.20 $, $Date: 2004/11/06 23:03:32 $ + */ +public class Main { + + /** JFlex version */ + final public static String version = "1.4.1"; //$NON-NLS-1$ + + /** + * Generates a scanner for the specified input file. + * + * @param inputFile a file containing a lexical specification + * to generate a scanner for. + */ + public static void generate(File inputFile) { + + Out.resetCounters(); + + Timer totalTime = new Timer(); + Timer time = new Timer(); + + LexScan scanner = null; + LexParse parser = null; + FileReader inputReader = null; + + totalTime.start(); + + try { + Out.println(ErrorMessages.READING, inputFile.toString()); + inputReader = new FileReader(inputFile); + scanner = new LexScan(inputReader); + scanner.setFile(inputFile); + parser = new LexParse(scanner); + } + catch (FileNotFoundException e) { + Out.error(ErrorMessages.CANNOT_OPEN, inputFile.toString()); + throw new GeneratorException(); + } + + try { + NFA nfa = (NFA) parser.parse().value; + + Out.checkErrors(); + + if (Options.dump) Out.dump(ErrorMessages.get(ErrorMessages.NFA_IS)+ + Out.NL+nfa+Out.NL); + + if (Options.dot) + nfa.writeDot(Emitter.normalize("nfa.dot", null)); //$NON-NLS-1$ + + Out.println(ErrorMessages.NFA_STATES, nfa.numStates); + + time.start(); + DFA dfa = nfa.getDFA(); + time.stop(); + Out.time(ErrorMessages.DFA_TOOK, time); + + dfa.checkActions(scanner, parser); + + nfa = null; + + if (Options.dump) Out.dump(ErrorMessages.get(ErrorMessages.DFA_IS)+ + Out.NL+dfa+Out.NL); + + if (Options.dot) + dfa.writeDot(Emitter.normalize("dfa-big.dot", null)); //$NON-NLS-1$ + + time.start(); + dfa.minimize(); + time.stop(); + + Out.time(ErrorMessages.MIN_TOOK, time); + + if (Options.dump) + Out.dump(ErrorMessages.get(ErrorMessages.MIN_DFA_IS)+ + Out.NL+dfa); + + if (Options.dot) + dfa.writeDot(Emitter.normalize("dfa-min.dot", null)); //$NON-NLS-1$ + + time.start(); + + Emitter e = new Emitter(inputFile, parser, dfa); + e.emit(); + + time.stop(); + + Out.time(ErrorMessages.WRITE_TOOK, time); + + totalTime.stop(); + + Out.time(ErrorMessages.TOTAL_TIME, totalTime); + } + catch (ScannerException e) { + Out.error(e.file, e.message, e.line, e.column); + throw new GeneratorException(); + } + catch (MacroException e) { + Out.error(e.getMessage()); + throw new GeneratorException(); + } + catch (IOException e) { + Out.error(ErrorMessages.IO_ERROR, e.toString()); + throw new GeneratorException(); + } + catch (OutOfMemoryError e) { + Out.error(ErrorMessages.OUT_OF_MEMORY); + throw new GeneratorException(); + } + catch (GeneratorException e) { + throw new GeneratorException(); + } + catch (Exception e) { + e.printStackTrace(); + throw new GeneratorException(); + } + + } + + public static Vector parseOptions(String argv[]) throws SilentExit { + Vector files = new Vector(); + + for (int i = 0; i < argv.length; i++) { + + if ( argv[i].equals("-d") || argv[i].equals("--outdir") ) { //$NON-NLS-1$ //$NON-NLS-2$ + if ( ++i >= argv.length ) { + Out.error(ErrorMessages.NO_DIRECTORY); + throw new GeneratorException(); + } + Options.setDir(argv[i]); + continue; + } + + if ( argv[i].equals("--skel") || argv[i].equals("-skel") ) { //$NON-NLS-1$ //$NON-NLS-2$ + if ( ++i >= argv.length ) { + Out.error(ErrorMessages.NO_SKEL_FILE); + throw new GeneratorException(); + } + + Options.setSkeleton(new File(argv[i])); + continue; + } + + if ( argv[i].equals("-jlex") || argv[i].equals("--jlex") ) { //$NON-NLS-1$ //$NON-NLS-2$ + Options.jlex = true; + continue; + } + + if ( argv[i].equals("-v") || argv[i].equals("--verbose") || argv[i].equals("-verbose") ) { //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + Options.verbose = true; + Options.progress = true; + continue; + } + + if ( argv[i].equals("-q") || argv[i].equals("--quiet") || argv[i].equals("-quiet") ) { //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + Options.verbose = false; + Options.progress = false; + continue; + } + + if ( argv[i].equals("--dump") || argv[i].equals("-dump") ) { //$NON-NLS-1$ //$NON-NLS-2$ + Options.dump = true; + continue; + } + + if ( argv[i].equals("--time") || argv[i].equals("-time") ) { //$NON-NLS-1$ //$NON-NLS-2$ + Options.time = true; + continue; + } + + if ( argv[i].equals("--version") || argv[i].equals("-version") ) { //$NON-NLS-1$ //$NON-NLS-2$ + Out.println(ErrorMessages.THIS_IS_JFLEX, version); + throw new SilentExit(); + } + + if ( argv[i].equals("--dot") || argv[i].equals("-dot") ) { //$NON-NLS-1$ //$NON-NLS-2$ + Options.dot = true; + continue; + } + + if ( argv[i].equals("--help") || argv[i].equals("-h") || argv[i].equals("/h") ) { //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + printUsage(); + throw new SilentExit(); + } + + if ( argv[i].equals("--info") || argv[i].equals("-info") ) { //$NON-NLS-1$ //$NON-NLS-2$ + Out.printSystemInfo(); + throw new SilentExit(); + } + + if ( argv[i].equals("--nomin") || argv[i].equals("-nomin") ) { //$NON-NLS-1$ //$NON-NLS-2$ + Options.no_minimize = true; + continue; + } + + if ( argv[i].equals("--pack") || argv[i].equals("-pack") ) { //$NON-NLS-1$ //$NON-NLS-2$ + Options.gen_method = Options.PACK; + continue; + } + + if ( argv[i].equals("--table") || argv[i].equals("-table") ) { //$NON-NLS-1$ //$NON-NLS-2$ + Options.gen_method = Options.TABLE; + continue; + } + + if ( argv[i].equals("--switch") || argv[i].equals("-switch") ) { //$NON-NLS-1$ //$NON-NLS-2$ + Options.gen_method = Options.SWITCH; + continue; + } + + if ( argv[i].equals("--nobak") || argv[i].equals("-nobak") ) { //$NON-NLS-1$ //$NON-NLS-2$ + Options.no_backup = true; + continue; + } + + if ( argv[i].equals("--charat") || argv[i].equals("-charat") ) { //$NON-NLS-1$ //$NON-NLS-2$ + Options.char_at = true; + continue; + } + + if ( argv[i].equals("--sliceandcharat") || argv[i].equals("-sliceandcharat") ) { //$NON-NLS-1$ //$NON-NLS-2$ + Options.sliceAndCharAt = true; + continue; + } + + if ( argv[i].startsWith("-") ) { //$NON-NLS-1$ + Out.error(ErrorMessages.UNKNOWN_COMMANDLINE, argv[i]); + printUsage(); + throw new SilentExit(); + } + + // if argv[i] is not an option, try to read it as file + File f = new File(argv[i]); + if ( f.isFile() && f.canRead() ) + files.addElement(f); + else { + Out.error("Sorry, couldn't open \""+f+"\""); //$NON-NLS-2$ + throw new GeneratorException(); + } + } + + return files; + } + + + public static void printUsage() { + Out.println(""); //$NON-NLS-1$ + Out.println("Usage: jflex "); + Out.println(""); + Out.println("Where can be one or more of"); + Out.println("-d write generated file to "); + Out.println("--skel use external skeleton "); + Out.println("--switch"); + Out.println("--table"); + Out.println("--pack set default code generation method"); + Out.println("--jlex strict JLex compatibility"); + Out.println("--nomin skip minimization step"); + Out.println("--nobak don't create backup files"); + Out.println("--dump display transition tables"); + Out.println("--dot write graphviz .dot files for the generated automata (alpha)"); + Out.println("--verbose"); + Out.println("-v display generation progress messages (default)"); + Out.println("--quiet"); + Out.println("-q display errors only"); + Out.println("--time display generation time statistics"); + Out.println("--version print the version number of this copy of jflex"); + Out.println("--info print system + JDK information"); + Out.println("--help"); + Out.println("-h print this message"); + Out.println(""); + Out.println(ErrorMessages.THIS_IS_JFLEX, version); + Out.println("Have a nice day!"); + } + + + public static void generate(String argv[]) throws SilentExit { + Vector files = parseOptions(argv); + + if (files.size() > 0) { + for (int i = 0; i < files.size(); i++) + generate((File) files.elementAt(i)); + } + else { + new MainFrame(); + } + } + + + /** + * Starts the generation process with the files in argv or + * pops up a window to choose a file, when argv doesn't have + * any file entries. + * + * @param argv the commandline. + */ + public static void main(String argv[]) { + try { + generate(argv); + } + catch (GeneratorException e) { + Out.statistics(); + System.exit(1); + } + catch (SilentExit e) { + System.exit(1); + } + } +} diff --git a/tools/lexer/jflex-1.4/src/JFlex/Messages.properties b/tools/lexer/jflex-1.4/src/JFlex/Messages.properties new file mode 100644 index 000000000000..e491a95005ab --- /dev/null +++ b/tools/lexer/jflex-1.4/src/JFlex/Messages.properties @@ -0,0 +1,70 @@ +UNTERMINATED_STR = Unterminated string at end of line. +EOF_WO_ACTION = <> must be followed by an action. +EOF_SINGLERULE = <> can only be used as a single rule. +UNKNOWN_OPTION = Unkown %-option +UNEXPECTED_CHAR = Unexpected character +UNEXPECTED_NL = Unexpected character +LEXSTATE_UNDECL = Lexical state has not been declared. +STATE_IDENT_EXP = State identifier expected. +REPEAT_ZERO = Illegal repeat statement. At least one operand must be > 0 +REPEAT_GREATER = Illegal repeat statement. First operand must not be greater than second one. +REGEXP_EXPECTED = Regular expression expected. +MACRO_UNDECL = Macro has not been declared. +CHARSET_2_SMALL = Character set is too small for this class. +CS2SMALL_STRING = Character set is too small for a charactor of this string. +CS2SMALL_CHAR = Character set is too small for this character. +CHARCLASS_MACRO = Macros in character classes are not supported. +UNKNOWN_SYNTAX = Syntax error. +SYNTAX_ERROR = Syntax error. +NOT_AT_BOL = %-option is not at the beginning of the line. +NO_MATCHING_BR = Didn't find matching bracket +EOF_IN_ACTION = Unexpected end of file in action code +EOF_IN_COMMENT = Unexpected end of file in comment +EOF_IN_STRING = Unexpected end of file in string +EOF_IN_MACROS = Unexpected end of file in macros +EOF_IN_STATES = Unexpected end of file in state list +EOF_IN_REGEXP = Unexpected end of file in regular expression +UNEXPECTED_EOF = Unexpected end of file (maybe missing "*/" ")" "]" or "}") +NO_LEX_SPEC = This seems not to be a lexical specification (first %% is missing) +NO_LAST_ACTION = Last action in the specification must not be "|" +LOOKAHEAD_ERROR = Dangerous lookahead expression, yytext might contain too many characters. +NO_DIRECTORY = No directory for -d option +NO_SKEL_FILE = No file provided for -skel option +WRONG_SKELETON = Incorrect skeleton file (wrong number of sections). +OUT_OF_MEMORY = JFlex has run out of memory. Please try increasing the maximum JVM heap size +QUIL_INITTHROW = %initthrow needs a list of (qualified) identifiers +QUIL_EOFTHROW = %eofthrow needs a list of (qualified) identifiers +QUIL_YYLEXTHROW = %yylexthrow needs a list of (qualified) identifiers +ZERO_STATES = Your scanner has zero states. Very funny. +NO_BUFFER_SIZE = %buffer expects the size of the scanner buffer as decimal number +NOT_READABLE = Could not open file. +FILE_CYCLE = Cyclic file inclusion. +FILE_WRITE = Error writing to file +QUIL_SCANERROR = %scannerror needs a (qualified) identifier +NEVER_MATCH = Rule can never be matched: +QUIL_THROW = %throws needs a list of (qualified) identifiers +EOL_IN_CHARCLASS = Unexpected newline in character class (closing "]" is missing) +QUIL_CUPSYM = %cupsym needs a (qualified) identifier +CUPSYM_AFTER_CUP = %cupsym should be used before %cup +ALREADY_RUNNING = The generator is already running +CANNOT_READ_SKEL = Cannot read skeleton file "{0}". +READING_SKEL = Reading skeleton file "{0}". +SKEL_IO_ERROR = IO problem reading skeleton file. +SKEL_IO_ERROR_DEFAULT = IO problem reading default skeleton file. +READING=Reading "{0}" +CANNOT_OPEN=Sorry, couldn''t find the file "{0}". +NFA_IS=NFA is +NFA_STATES={0} states in NFA +DFA_TOOK=DFA construction took {0} +DFA_IS=DFA is +MIN_TOOK=Minimization took {0} +MIN_DFA_IS=Miniminal DFA is +WRITE_TOOK=Writing took {0} +TOTAL_TIME=Overall scanner generation time: {0} +IO_ERROR=An I/O-Error occured: {0} +THIS_IS_JFLEX=This is JFlex {0} +UNKNOWN_COMMANDLINE=Error: unknown option "{0}". +MACRO_CYCLE=Macro {0} contains a cycle. +MACRO_DEF_MISSING=Found no definition for '{{0}'} while expanding '{{1}'} +PARSING_TOOK=Parsing took {0} +NFA_TOOK=NFA construction took {0} \ No newline at end of file diff --git a/tools/lexer/jflex-1.4/src/JFlex/NFA.java b/tools/lexer/jflex-1.4/src/JFlex/NFA.java new file mode 100644 index 000000000000..219c95249d30 --- /dev/null +++ b/tools/lexer/jflex-1.4/src/JFlex/NFA.java @@ -0,0 +1,996 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * JFlex 1.4.1 * + * Copyright (C) 1998-2004 Gerwin Klein * + * All rights reserved. * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License. See the file * + * COPYRIGHT for more information. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License along * + * with this program; if not, write to the Free Software Foundation, Inc., * + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ +package JFlex; + +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; +import java.io.PrintWriter; +import java.util.Enumeration; +import java.util.Hashtable; +import java.util.Vector; + + +/** + * NFA representation in JFlex. + * + * Contains algorithms RegExp -> NFA and NFA -> DFA. + * + * @author Gerwin Klein + * @version JFlex 1.4.1, $Revision: 2.8 $, $Date: 2004/11/06 23:03:32 $ + */ +final public class NFA { + + // table[current_state][next_char] is the set of states that can be reached + // from current_state with an input next_char + StateSet [][] table; + + // epsilon[current_state] is the set of states that can be reached + // from current_state via epsilon-edges + StateSet [] epsilon; + + // isFinal[state] == true <=> state is a final state of the NFA + boolean [] isFinal; + + // isPushback[state] == true <=> state is the final state of a regexp that + // should only be matched when followed by a certain lookahead. + boolean [] isPushback; + + // action[current_state]: the action associated with the state + // current_state (null, if there is no action for the state) + Action [] action; + + // the number of states in this NFA + int numStates; + + // the current maximum number of input characters + int numInput; + + // the number of lexical States. Lexical states have the indices + // 0..numLexStates-1 in the transition table + int numLexStates; + + // estimated size of the NFA (before actual construction) + int estSize = 256; + + Macros macros; + CharClasses classes; + + LexScan scanner; + RegExps regExps; + + // will be reused by several methods (avoids excessive object creation) + private static StateSetEnumerator states = new StateSetEnumerator(); + private static StateSet tempStateSet = new StateSet(); + + public NFA(int numInput, int estSize) { + this.numInput = numInput; + this.estSize = estSize; + numStates = 0; + epsilon = new StateSet [estSize]; + action = new Action [estSize]; + isFinal = new boolean [estSize]; + isPushback = new boolean [estSize]; + table = new StateSet [estSize][numInput]; + } + + public NFA(int numInput, LexScan scanner, RegExps regExps, + Macros macros, CharClasses classes) { + this(numInput, regExps.NFASize(macros)+2*scanner.states.number()); + + this.scanner = scanner; + this.regExps = regExps; + this.macros = macros; + this.classes = classes; + + numLexStates = scanner.states.number(); + + ensureCapacity(2*numLexStates); + + numStates = 2*numLexStates; + } + + public void addStandaloneRule() { + // standalone rule has least priority, fires + // transition on all characters and has "print it rule" + int start = numStates; + int end = numStates+1; + + for (int c = 0; c < classes.getNumClasses(); c++) + addTransition(start, c, end); + + for (int i = 0; i < numLexStates*2; i++) + addEpsilonTransition(i, start); + + action[end] = new Action("System.out.print(yytext());", Integer.MAX_VALUE); + isFinal[end] = true; + } + + + public void addRegExp(int regExpNum) { + + if (Options.DEBUG) + Out.debug("Adding nfa for regexp "+regExpNum+" :"+Out.NL+regExps.getRegExp(regExpNum)); + + IntPair nfa = insertNFA( regExps.getRegExp(regExpNum) ); + + Enumeration lexStates = regExps.getStates(regExpNum).elements(); + + if ( !lexStates.hasMoreElements() ) + lexStates = scanner.states.getInclusiveStates(); + + while ( lexStates.hasMoreElements() ) { + int stateNum = ((Integer)lexStates.nextElement()).intValue(); + + if ( !regExps.isBOL(regExpNum) ) + addEpsilonTransition(2*stateNum, nfa.start); + + addEpsilonTransition(2*stateNum+1, nfa.start); + } + + + if ( regExps.getLookAhead(regExpNum) != null ) { + IntPair look = insertNFA( regExps.getLookAhead(regExpNum) ); + + addEpsilonTransition(nfa.end, look.start); + + Action a = regExps.getAction(regExpNum); + a.setLookAction(true); + + isPushback[nfa.end] = true; + action[look.end] = a; + isFinal[look.end] = true; + } + else { + action[nfa.end] = regExps.getAction(regExpNum); + isFinal[nfa.end] = true; + } + } + + + private void ensureCapacity(int newNumStates) { + int oldLength = epsilon.length; + + if ( newNumStates < oldLength ) return; + + int newStatesLength = Math.max(oldLength*2, newNumStates); + + boolean [] newFinal = new boolean [newStatesLength]; + boolean [] newIsPush = new boolean [newStatesLength]; + Action [] newAction = new Action [newStatesLength]; + StateSet [] [] newTable = new StateSet [newStatesLength] [numInput]; + StateSet [] newEpsilon = new StateSet [newStatesLength]; + + System.arraycopy(isFinal,0,newFinal,0,numStates); + System.arraycopy(isPushback,0,newIsPush,0,numStates); + System.arraycopy(action,0,newAction,0,numStates); + System.arraycopy(epsilon,0,newEpsilon,0,numStates); + System.arraycopy(table,0,newTable,0,numStates); + + isFinal = newFinal; + isPushback = newIsPush; + action = newAction; + epsilon = newEpsilon; + table = newTable; + } + + public void addTransition(int start, int input, int dest) { + Out.debug("Adding transition ("+start+", "+input+", "+dest+")"); + + int maxS = Math.max(start,dest)+1; + + ensureCapacity( maxS ); + + if (maxS > numStates) numStates = maxS; + + if ( table[start][input] != null ) + table[start][input].addState(dest); + else + table[start][input] = new StateSet(estSize,dest); + } + + public void addEpsilonTransition(int start, int dest) { + int max = Math.max(start,dest)+1; + ensureCapacity( max ); + if (max > numStates) numStates = max; + + if (epsilon[start] != null) + epsilon[start].addState(dest); + else + epsilon[start] = new StateSet(estSize,dest); + } + + + /** + * Returns true, iff the specified set of states + * contains a final state. + * + * @param set the set of states that is tested for final states. + */ + private boolean containsFinal(StateSet set) { + states.reset(set); + + while ( states.hasMoreElements() ) + if ( isFinal[states.nextElement()] ) return true; + + return false; + } + + + /** + * Returns true, iff the specified set of states + * contains a pushback-state. + * + * @param set the set of states that is tested for pushback-states. + */ + private boolean containsPushback(StateSet set) { + states.reset(set); + + while ( states.hasMoreElements() ) + if ( isPushback[states.nextElement()] ) return true; + + return false; + } + + + /** + * Returns the action with highest priority in the specified + * set of states. + * + * @param set the set of states for which to determine the action + */ + private Action getAction(StateSet set) { + + states.reset(set); + + Action maxAction = null; + + Out.debug("Determining action of : "+set); + + while ( states.hasMoreElements() ) { + + Action currentAction = action[ states.nextElement() ]; + + if ( currentAction != null ) { + if (maxAction == null) + maxAction = currentAction; + else + maxAction = maxAction.getHigherPriority(currentAction); + } + + } + + return maxAction; + } + + + /** + * Calculates the epsilon closure for a specified set of states. + * + * The epsilon closure for set a is the set of states that can be reached + * by epsilon edges from a. + * + * @param set the set of states to calculate the epsilon closure for + * + * @return the epsilon closure of the specified set of states + * in this NFA + */ + private StateSet closure(int startState) { + + // Out.debug("Calculating closure of "+set); + + StateSet notvisited = tempStateSet; + StateSet closure = new StateSet(numStates,startState); + + notvisited.clear(); + notvisited.addState(startState); + + while ( notvisited.containsElements() ) { + // Out.debug("closure is now "+closure); + // Out.debug("notvisited is "+notvisited); + int state = notvisited.getAndRemoveElement(); + // Out.debug("removed element "+state+" of "+notvisited); + // Out.debug("epsilon[states] = "+epsilon[state]); + notvisited.add(closure.complement(epsilon[state])); + closure.add(epsilon[state]); + } + + // Out.debug("Closure is : "+closure); + + return closure; + } + + /** + * Returns the epsilon closure of a set of states + */ + private StateSet closure(StateSet startStates) { + StateSet result = new StateSet(numStates); + + if (startStates != null) { + states.reset(startStates); + while (states.hasMoreElements()) + result.add( closure(states.nextElement()) ); + } + + return result; + } + + + private void epsilonFill() { + for (int i = 0; i < numStates; i++) { + epsilon[i] = closure(i); + } + } + + /** + * Calculates the set of states that can be reached from another + * set of states start with an specified input + * character input + * + * @param start the set of states to start from + * @param input the input character for which to search the next states + * + * @return the set of states that are reached from start + * via input + */ + private StateSet DFAEdge(StateSet start, char input) { + // Out.debug("Calculating DFAEdge for state set "+start+" and input '"+input+"'"); + + tempStateSet.clear(); + + states.reset(start); + while ( states.hasMoreElements() ) + tempStateSet.add( table[states.nextElement()][input] ); + + StateSet result = new StateSet(tempStateSet); + + states.reset(tempStateSet); + while ( states.hasMoreElements() ) + result.add( epsilon[states.nextElement()] ); + + // Out.debug("DFAEdge is : "+result); + + return result; + } + + + /** + * Returns an DFA that accepts the same language as this NFA. + * This DFA is usualy not minimal. + */ + public DFA getDFA() { + + Hashtable dfaStates = new Hashtable(numStates); + Vector dfaVector = new Vector(numStates); + + DFA dfa = new DFA(2*numLexStates, numInput); + + int numDFAStates = 0; + int currentDFAState = 0; + + Out.println("Converting NFA to DFA : "); + + epsilonFill(); + + StateSet currentState, newState; + + for ( int i = 0; i < 2*numLexStates; i++ ) { + newState = epsilon[i]; + + dfaStates.put(newState, new Integer(numDFAStates)); + dfaVector.addElement(newState); + + dfa.setLexState( i, numDFAStates ); + + dfa.setFinal( numDFAStates, containsFinal(newState) ); + dfa.setPushback( numDFAStates, containsPushback(newState) ); + dfa.setAction( numDFAStates, getAction(newState) ); + + numDFAStates++; + } + + numDFAStates--; + + if (Options.DEBUG) + Out.debug("DFA start states are :"+Out.NL+dfaStates+Out.NL+Out.NL+"ordered :"+Out.NL+dfaVector); + + currentDFAState = 0; + + StateSet tempStateSet = NFA.tempStateSet; + StateSetEnumerator states = NFA.states; + + // will be reused + newState = new StateSet(numStates); + + while ( currentDFAState <= numDFAStates ) { + + currentState = (StateSet) dfaVector.elementAt(currentDFAState); + + for (char input = 0; input < numInput; input++) { + + // newState = DFAEdge(currentState, input); + + // inlining DFAEdge for performance: + + // Out.debug("Calculating DFAEdge for state set "+currentState+" and input '"+input+"'"); + + tempStateSet.clear(); + states.reset(currentState); + while ( states.hasMoreElements() ) + tempStateSet.add( table[states.nextElement()][input] ); + + newState.copy(tempStateSet); + + states.reset(tempStateSet); + while ( states.hasMoreElements() ) + newState.add( epsilon[states.nextElement()] ); + + // Out.debug("DFAEdge is : "+newState); + + + if ( newState.containsElements() ) { + + // Out.debug("DFAEdge for input "+(int)input+" and state set "+currentState+" is "+newState); + + // Out.debug("Looking for state set "+newState); + Integer nextDFAState = (Integer) dfaStates.get(newState); + + if ( nextDFAState != null ) { + // Out.debug("FOUND!"); + dfa.addTransition(currentDFAState, input, nextDFAState.intValue()); + } + else { + if (Options.progress) Out.print("."); + // Out.debug("NOT FOUND!"); + // Out.debug("Table was "+dfaStates); + numDFAStates++; + + // make a new copy of newState to store in dfaStates + StateSet storeState = new StateSet(newState); + + dfaStates.put(storeState, new Integer(numDFAStates)); + dfaVector.addElement(storeState); + + dfa.addTransition(currentDFAState, input, numDFAStates); + dfa.setFinal( numDFAStates, containsFinal(storeState) ); + dfa.setPushback( numDFAStates, containsPushback(storeState) ); + dfa.setAction( numDFAStates, getAction(storeState) ); + } + } + } + + currentDFAState++; + } + + if (Options.verbose) Out.println(""); + + return dfa; + } + + + public void dumpTable() { + Out.dump(toString()); + } + + public String toString() { + StringBuffer result = new StringBuffer(); + + for (int i=0; i < numStates; i++) { + result.append("State"); + if ( isFinal[i] ) result.append("[FINAL]"); + if ( isPushback[i] ) result.append(" [PUSHBACK]"); + result.append(" "+i+Out.NL); + + for (char input = 0; input < numInput; input++) { + if ( table[i][input] != null && table[i][input].containsElements() ) + result.append(" with "+((int) input)+" in "+table[i][input]+Out.NL); + + + } + + if ( epsilon[i] != null && epsilon[i].containsElements() ) + result.append(" with epsilon in "+epsilon[i]+Out.NL); + } + + return result.toString(); + } + + public void writeDot(File file) { + try { + PrintWriter writer = new PrintWriter(new FileWriter(file)); + writer.println(dotFormat()); + writer.close(); + } + catch (IOException e) { + Out.error(ErrorMessages.FILE_WRITE, file); + throw new GeneratorException(); + } + } + + public String dotFormat() { + StringBuffer result = new StringBuffer(); + + result.append("digraph NFA {"+Out.NL); + result.append("rankdir = LR"+Out.NL); + + for (int i=0; i < numStates; i++) { + if ( isFinal[i] || isPushback[i] ) result.append(i); + if ( isFinal[i] ) result.append(" [shape = doublecircle]"); + if ( isPushback[i] ) result.append(" [shape = box]"); + if ( isFinal[i] || isPushback[i] ) result.append(Out.NL); + } + + for (int i=0; i < numStates; i++) { + for (int input = 0; input < numInput; input++) { + if ( table[i][input] != null ) { + StateSetEnumerator states = table[i][input].states(); + + while (states.hasMoreElements()) { + int s = states.nextElement(); + result.append(i+" -> "+s); + result.append(" [label=\""+classes.toString(input)+"\"]"+Out.NL); + } + } + } + if ( epsilon[i] != null ) { + StateSetEnumerator states = epsilon[i].states(); + while (states.hasMoreElements()) { + int s = states.nextElement(); + result.append(i+" -> "+s+" [style=dotted]"+Out.NL); + } + } + } + + result.append("}"+Out.NL); + + return result.toString(); + } + + + //----------------------------------------------------------------------- + // Functions for constructing NFAs out of regular expressions. + + private void insertLetterNFA(boolean caseless, char letter, int start, int end) { + if (caseless) { + int lower = classes.getClassCode(Character.toLowerCase(letter)); + int upper = classes.getClassCode(Character.toUpperCase(letter)); + addTransition(start, lower, end); + if (upper != lower) addTransition(start, upper, end); + } + else { + addTransition(start, classes.getClassCode(letter), end); + } + } + + private IntPair insertStringNFA(boolean caseless, String letters) { + int start = numStates; + int i; + + for (i = 0; i < letters.length(); i++) { + if (caseless) { + char c = letters.charAt(i); + int lower = classes.getClassCode(Character.toLowerCase(c)); + int upper = classes.getClassCode(Character.toUpperCase(c)); + addTransition(i+start, lower, i+start+1); + if (upper != lower) addTransition(i+start, upper, i+start+1); + } + else { + addTransition(i+start, classes.getClassCode(letters.charAt(i)), i+start+1); + } + } + + return new IntPair(start, i+start); + } + + + private void insertClassNFA(Vector intervalls, int start, int end) { + // empty char class is ok: + if (intervalls == null) return; + + int [] cl = classes.getClassCodes(intervalls); + for (int i = 0; i < cl.length; i++) + addTransition(start, cl[i], end); + } + + private void insertNotClassNFA(Vector intervalls, int start, int end) { + int [] cl = classes.getNotClassCodes(intervalls); + + for (int i = 0; i < cl.length; i++) + addTransition(start, cl[i], end); + } + + + /** + * Constructs an NFA accepting the complement of the language + * of a given NFA. + * + * Converts the NFA into a DFA, then negates that DFA. + * Exponential state blowup possible and common. + * + * @param the NFA to construct the complement for. + * + * @return a pair of integers denoting the index of start + * and end state of the complement NFA. + */ + private IntPair complement(IntPair nfa) { + + if (Options.DEBUG) { + Out.debug("complement for "+nfa); + Out.debug("NFA is :"+Out.NL+this); + } + + int dfaStart = nfa.end+1; + + // fixme: only need epsilon closure of states reachable from nfa.start + epsilonFill(); + + Hashtable dfaStates = new Hashtable(numStates); + Vector dfaVector = new Vector(numStates); + + int numDFAStates = 0; + int currentDFAState = 0; + + StateSet currentState, newState; + + newState = epsilon[nfa.start]; + dfaStates.put(newState, new Integer(numDFAStates)); + dfaVector.addElement(newState); + + if (Options.DEBUG) + Out.debug("pos DFA start state is :"+Out.NL+dfaStates+Out.NL+Out.NL+"ordered :"+Out.NL+dfaVector); + + currentDFAState = 0; + + while ( currentDFAState <= numDFAStates ) { + + currentState = (StateSet) dfaVector.elementAt(currentDFAState); + + for (char input = 0; input < numInput; input++) { + newState = DFAEdge(currentState, input); + + if ( newState.containsElements() ) { + + // Out.debug("DFAEdge for input "+(int)input+" and state set "+currentState+" is "+newState); + + // Out.debug("Looking for state set "+newState); + Integer nextDFAState = (Integer) dfaStates.get(newState); + + if ( nextDFAState != null ) { + // Out.debug("FOUND!"); + addTransition(dfaStart+currentDFAState, input, dfaStart+nextDFAState.intValue()); + } + else { + if (Options.dump) Out.print("+"); + // Out.debug("NOT FOUND!"); + // Out.debug("Table was "+dfaStates); + numDFAStates++; + + dfaStates.put(newState, new Integer(numDFAStates)); + dfaVector.addElement(newState); + + addTransition(dfaStart+currentDFAState, input, dfaStart+numDFAStates); + } + } + } + + currentDFAState++; + } + + // We have a dfa accepting the positive regexp. + + // Now the complement: + if (Options.DEBUG) + Out.debug("dfa finished, nfa is now :"+Out.NL+this); + + int start = dfaStart+numDFAStates+1; + int error = dfaStart+numDFAStates+2; + int end = dfaStart+numDFAStates+3; + + addEpsilonTransition(start, dfaStart); + + for (int i = 0; i < numInput; i++) + addTransition(error, i, error); + + addEpsilonTransition(error, end); + + for (int s = 0; s <= numDFAStates; s++) { + currentState = (StateSet) dfaVector.elementAt(s); + + currentDFAState = dfaStart+s; + + // if it was not a final state, it is now in the complement + if (!currentState.isElement(nfa.end)) + addEpsilonTransition(currentDFAState, end); + + // all inputs not present (formerly leading to an implicit error) + // now lead to an explicit (final) state accepting everything. + for (int i = 0; i < numInput; i++) + if (table[currentDFAState][i] == null) + addTransition(currentDFAState, i, error); + } + + // eliminate transitions leading to dead states + if (live == null || live.length < numStates) { + live = new boolean [2*numStates]; + visited = new boolean [2*numStates]; + } + + _end = end; + _dfaStates = dfaVector; + _dfaStart = dfaStart; + removeDead(dfaStart); + + if (Options.DEBUG) + Out.debug("complement finished, nfa ("+start+","+end+") is now :"+this); + + return new IntPair(start, end); + } + + // "global" data for use in method removeDead only: + // live[s] == false <=> no final state can be reached from s + private boolean [] live; // = new boolean [estSize]; + private boolean [] visited; // = new boolean [estSize]; + private int _end; // final state of original nfa for dfa (nfa coordinates) + private Vector _dfaStates; + private int _dfaStart; // in nfa coordinates + + private void removeDead(int start) { + // Out.debug("removeDead ("+start+")"); + + if ( visited[start] || live[start] ) return; + visited[start] = true; + + // Out.debug("not yet visited"); + + if (closure(start).isElement(_end)) + live[start] = true; + + // Out.debug("is final :"+live[start]); + + for (int i = 0; i < numInput; i++) { + StateSet nextState = closure(table[start][i]); + StateSetEnumerator states = nextState.states(); + while (states.hasMoreElements()) { + int next = states.nextElement(); + + if (next != start) { + removeDead(next); + + if (live[next]) + live[start] = true; + else + table[start][i] = null; + } + } + } + + StateSet nextState = closure(epsilon[start]); + StateSetEnumerator states = nextState.states(); + while (states.hasMoreElements()) { + int next = states.nextElement(); + + if (next != start) { + removeDead(next); + + if (live[next]) + live[start] = true; + } + } + + // Out.debug("state "+start+" is live :"+live[start]); + } + + + /** + * Constructs a two state NFA for char class regexps, + * such that the NFA has + * + * exactly one start state, + * exactly one end state, + * no transitions leading out of the end state + * no transitions leading into the start state + * + * Assumes that regExp.isCharClass(macros) == true + * + * @param regExp the regular expression to construct the + * NFA for + * + * @return a pair of integers denoting the index of start + * and end state of the NFA. + */ + private void insertNFA(RegExp regExp, int start, int end) { + switch (regExp.type) { + + case sym.BAR: + RegExp2 r = (RegExp2) regExp; + insertNFA(r.r1, start, end); + insertNFA(r.r2, start, end); + return; + + case sym.CCLASS: + insertClassNFA( (Vector) ((RegExp1) regExp).content, start, end); + return; + + case sym.CCLASSNOT: + insertNotClassNFA( (Vector) ((RegExp1) regExp).content, start, end); + return; + + case sym.CHAR: + insertLetterNFA( + false, ((Character) ((RegExp1) regExp).content).charValue(), + start, end); + return; + + case sym.CHAR_I: + insertLetterNFA( + true, ((Character) ((RegExp1) regExp).content).charValue(), + start, end); + return; + + case sym.MACROUSE: + insertNFA(macros.getDefinition((String) ((RegExp1) regExp).content), + start, end); + return; + } + + throw new Error("Unknown expression type "+regExp.type+" in NFA construction"); + } + + + /** + * Constructs an NFA for regExp such that the NFA has + * + * exactly one start state, + * exactly one end state, + * no transitions leading out of the end state + * no transitions leading into the start state + * + * @param regExp the regular expression to construct the + * NFA for + * + * @return a pair of integers denoting the index of start + * and end state of the NFA. + */ + public IntPair insertNFA(RegExp regExp) { + + IntPair nfa1, nfa2; + int start, end; + RegExp2 r; + + if (Options.DEBUG) + Out.debug("Inserting RegExp : "+regExp); + + if (regExp.isCharClass(macros)) { + start = numStates; + end = numStates+1; + + ensureCapacity(end+1); + if (end+1 > numStates) numStates = end+1; + + insertNFA(regExp, start, end); + + return new IntPair(start, end); + } + + switch (regExp.type) { + + case sym.BAR: + + r = (RegExp2) regExp; + + nfa1 = insertNFA(r.r1); + nfa2 = insertNFA(r.r2); + + start = nfa2.end+1; + end = nfa2.end+2; + + addEpsilonTransition(start, nfa1.start); + addEpsilonTransition(start, nfa2.start); + addEpsilonTransition(nfa1.end, end); + addEpsilonTransition(nfa2.end, end); + + return new IntPair(start, end); + + case sym.CONCAT: + + r = (RegExp2) regExp; + + nfa1 = insertNFA(r.r1); + nfa2 = insertNFA(r.r2); + + addEpsilonTransition(nfa1.end, nfa2.start); + + return new IntPair(nfa1.start, nfa2.end); + + case sym.STAR: + nfa1 = insertNFA( (RegExp) ((RegExp1) regExp).content ); + + start = nfa1.end+1; + end = nfa1.end+2; + + addEpsilonTransition(nfa1.end, end); + addEpsilonTransition(start, nfa1.start); + + addEpsilonTransition(start, end); + addEpsilonTransition(nfa1.end, nfa1.start); + + return new IntPair(start, end); + + case sym.PLUS: + nfa1 = insertNFA( (RegExp) ((RegExp1) regExp).content ); + + start = nfa1.end+1; + end = nfa1.end+2; + + addEpsilonTransition(nfa1.end, end); + addEpsilonTransition(start, nfa1.start); + + addEpsilonTransition(nfa1.end, nfa1.start); + + return new IntPair(start, end); + + case sym.QUESTION: + nfa1 = insertNFA( (RegExp) ((RegExp1) regExp).content ); + + addEpsilonTransition(nfa1.start, nfa1.end); + + return new IntPair(nfa1.start, nfa1.end); + + case sym.BANG: + return complement(insertNFA((RegExp) ((RegExp1) regExp).content)); + + case sym.TILDE: + nfa1 = insertNFA((RegExp) ((RegExp1) regExp).content); + + start = nfa1.end+1; + int s1 = start+1; + int s2 = s1+1; + end = s2+1; + + for (int i = 0; i < numInput; i++) { + addTransition(s1,i,s1); + addTransition(s2,i,s2); + } + + addEpsilonTransition(start, s1); + addEpsilonTransition(s1, nfa1.start); + addEpsilonTransition(nfa1.end, s2); + addEpsilonTransition(s2, end); + + nfa1 = complement(new IntPair(start,end)); + nfa2 = insertNFA((RegExp) ((RegExp1) regExp).content); + + addEpsilonTransition(nfa1.end, nfa2.start); + + return new IntPair(nfa1.start, nfa2.end); + + case sym.STRING: + return insertStringNFA(false, (String) ((RegExp1) regExp).content ); + + case sym.STRING_I: + return insertStringNFA(true, (String) ((RegExp1) regExp).content ); + + case sym.MACROUSE: + return insertNFA(macros.getDefinition((String) ((RegExp1) regExp).content)); + } + + throw new Error("Unknown expression type "+regExp.type+" in NFA construction"); + } +} diff --git a/tools/lexer/jflex-1.4/src/JFlex/Options.java b/tools/lexer/jflex-1.4/src/JFlex/Options.java new file mode 100644 index 000000000000..fa308bb50eb2 --- /dev/null +++ b/tools/lexer/jflex-1.4/src/JFlex/Options.java @@ -0,0 +1,131 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * JFlex 1.4.1 * + * Copyright (C) 1998-2004 Gerwin Klein * + * All rights reserved. * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License. See the file * + * COPYRIGHT for more information. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License along * + * with this program; if not, write to the Free Software Foundation, Inc., * + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +package JFlex; + +import java.io.File; + +/** + * Collects all global JFlex options. Can be set from command line parser, + * ant taks, gui, etc. + * + * @author Gerwin Klein + * @version JFlex 1.4.1, $Revision: 2.10 $, $Date: 2004/11/06 23:03:31 $ + */ +public class Options { + + /** If true, additional verbose debug information is produced + * This is a compile time option */ + public final static boolean DEBUG = false; + + /** code generation method: maximum packing */ + final public static int PACK = 0; + /** code generation method: traditional */ + final public static int TABLE = 1; + /** code generation method: switch statement */ + final public static int SWITCH = 2; + + + /** output directory */ + private static File directory; + /** strict JLex compatibility */ + public static boolean jlex; + /** don't run minimization algorithm if this is true */ + public static boolean no_minimize; + /** don't write backup files if this is true */ + public static boolean no_backup; + /** use charAt function for accessing the zzBuffer */ + public static boolean char_at; + + /** use charAt function for accessing the zzBuffer and [] for zzBufferArray */ + public static boolean sliceAndCharAt; + + /** default code generation method */ + public static int gen_method; + /** If false, only error/warning output will be generated */ + public static boolean verbose; + /** If true, progress dots will be printed */ + public static boolean progress; + /** If true, jflex will print time statistics about the generation process */ + public static boolean time; + /** If true, jflex will write graphviz .dot files for generated automata */ + public static boolean dot; + /** If true, you will be flooded with information (e.g. dfa tables). */ + public static boolean dump; + + static { setDefaults(); } + + + /** + * @return the output directory + */ + public static File getDir() { + return directory; + } + + /** + * Set output directory + * + * @param dirName the name of the directory to write output files to + */ + public static void setDir(String dirName) { + setDir(new File(dirName)); + } + + + /** + * Set output directory + * + * @param d the directory to write output files to + */ + public static void setDir(File d) { + if ( d.isFile() ) { + Out.error("Error: \""+d+"\" is not a directory."); + throw new GeneratorException(); + } + + if ( !d.isDirectory() && !d.mkdirs() ) { + Out.error("Error: couldn't create directory \""+d+"\""); + throw new GeneratorException(); + } + + directory = d; + } + + /** + * Sets all options back to default values. + */ + public static void setDefaults() { + directory = null; + jlex = false; + no_minimize = false; + no_backup = false; + gen_method = Options.PACK; + verbose = true; + progress = true; + time = false; + dot = false; + dump = false; + } + + public static void setSkeleton(File skel) { + Skeleton.readSkelFile(skel); + } +} diff --git a/tools/lexer/jflex-1.4/src/JFlex/Out.java b/tools/lexer/jflex-1.4/src/JFlex/Out.java new file mode 100644 index 000000000000..026187fc1e34 --- /dev/null +++ b/tools/lexer/jflex-1.4/src/JFlex/Out.java @@ -0,0 +1,461 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * JFlex 1.4.1 * + * Copyright (C) 1998-2004 Gerwin Klein * + * All rights reserved. * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License. See the file * + * COPYRIGHT for more information. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License along * + * with this program; if not, write to the Free Software Foundation, Inc., * + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +package JFlex; + + +import java.awt.*; +import java.io.*; + + +/** + * In this class all output to the java console is filtered. + * + * Use the switches verbose, time and DUMP at compile time to determine + * the verbosity of JFlex output. There is no switch for + * suppressing error messages. verbose and time can be overridden + * by command line paramters. + * + * Redirects output to a TextArea in GUI mode. + * + * Counts error and warning messages. + * + * @author Gerwin Klein + * @version JFlex 1.4.1, $Revision: 2.9 $, $Date: 2004/11/06 23:03:30 $ + */ +public final class Out { + + /** platform dependent newline sequence */ + public static final String NL = System.getProperty("line.separator"); + + /** count total warnings */ + private static int warnings; + + /** count total errors */ + private static int errors; + + /** output device */ + private static StdOutWriter out = new StdOutWriter(); + + + /** + * Switches to GUI mode if text is not null + * + * @param text the message TextArea of the JFlex GUI + */ + public static void setGUIMode(TextArea text) { + out.setGUIMode(text); + } + + /** + * Sets a new output stream and switches to non-gui mode. + * + * @param stream the new output stream + */ + public static void setOutputStream(OutputStream stream) { + out = new StdOutWriter(stream); + out.setGUIMode(null); + } + + /** + * Report time statistic data. + * + * @param message the message to be printed + * @param time elapsed time + */ + public static void time(ErrorMessages message, Timer time) { + if (Options.time) { + String msg = ErrorMessages.get(message, time.toString()); + out.println(msg); + } + } + + /** + * Report time statistic data. + * + * @param message the message to be printed + */ + public static void time(String message) { + if (Options.time) { + out.println(message); + } + } + + /** + * Report generation progress. + * + * @param message the message to be printed + */ + public static void println(String message) { + if (Options.verbose) + out.println(message); + } + + /** + * Report generation progress. + * + * @param message the message to be printed + * @param data data to be inserted into the message + */ + public static void println(ErrorMessages message, String data) { + if (Options.verbose) { + out.println(ErrorMessages.get(message,data)); + } + } + + /** + * Report generation progress. + * + * @param message the message to be printed + * @param data data to be inserted into the message + */ + public static void println(ErrorMessages message, int data) { + if (Options.verbose) { + out.println(ErrorMessages.get(message,data)); + } + } + + /** + * Report generation progress. + * + * @param message the message to be printed + */ + public static void print(String message) { + if (Options.verbose) out.print(message); + } + + /** + * Dump debug information to System.out + * + * Use like this + * + * if (Out.DEBUG) Out.debug(message) + * + * to save performance during normal operation (when DEBUG + * is turned off). + */ + public static void debug(String message) { + if (Options.DEBUG) System.out.println(message); + } + + + /** + * All parts of JFlex, that want to provide dump information + * should use this method for their output. + * + * @message the message to be printed + */ + public static void dump(String message) { + if (Options.dump) out.println(message); + } + + + /** + * All parts of JFlex, that want to report error messages + * should use this method for their output. + * + * @message the message to be printed + */ + private static void err(String message) { + out.println(message); + } + + + /** + * throws a GeneratorException if there are any errors recorded + */ + public static void checkErrors() { + if (errors > 0) throw new GeneratorException(); + } + + + /** + * print error and warning statistics + */ + public static void statistics() { + StringBuffer line = new StringBuffer(errors+" error"); + if (errors != 1) line.append("s"); + + line.append(", "+warnings+" warning"); + if (warnings != 1) line.append("s"); + + line.append("."); + err(line.toString()); + } + + + /** + * reset error and warning counters + */ + public static void resetCounters() { + errors = 0; + warnings = 0; + } + + + /** + * print a warning without position information + * + * @param message the warning message + */ + public static void warning(String message) { + warnings++; + + err(NL+"Warning : "+message); + } + + + /** + * print a warning with line information + * + * @param message code of the warning message + * @param line the line information + * + * @see ErrorMessages + */ + public static void warning(ErrorMessages message, int line) { + warnings++; + + String msg = NL+"Warning"; + if (line > 0) msg = msg+" in line "+(line+1); + + err(msg+": "+ErrorMessages.get(message)); + } + + + /** + * print warning message with location information + * + * @param file the file the warning is issued for + * @param message the code of the message to print + * @param line the line number of the position + * @param column the column of the position + */ + public static void warning(File file, ErrorMessages message, int line, int column) { + + String msg = NL+"Warning"; + if (file != null) msg += " in file \""+file+"\""; + if (line >= 0) msg = msg+" (line "+(line+1)+")"; + + try { + err(msg+": "+NL+ErrorMessages.get(message)); + } + catch (ArrayIndexOutOfBoundsException e) { + err(msg); + } + + warnings++; + + if (line >= 0) { + if (column >= 0) + showPosition(file, line, column); + else + showPosition(file, line); + } + } + + + /** + * print error message (string) + * + * @param message the message to print + */ + public static void error(String message) { + errors++; + err(NL+message); + } + + + /** + * print error message (code) + * + * @param message the code of the error message + * + * @see ErrorMessages + */ + public static void error(ErrorMessages message) { + errors++; + err(NL+"Error: "+ErrorMessages.get(message) ); + } + + + /** + * print error message with data + * + * @param data data to insert into the message + * @param message the code of the error message + * + * @see ErrorMessages + */ + public static void error(ErrorMessages message, String data) { + errors++; + err(NL+"Error: "+ ErrorMessages.get(message,data)); + } + + + /** + * IO error message for a file (displays file + * name in parentheses). + * + * @param message the code of the error message + * @param file the file it occurred for + */ + public static void error(ErrorMessages message, File file) { + errors++; + err(NL+"Error: "+ErrorMessages.get(message)+" ("+file+")"); + } + + + /** + * print error message with location information + * + * @param file the file the error occurred for + * @param message the code of the error message to print + * @param line the line number of error position + * @param column the column of error position + */ + public static void error(File file, ErrorMessages message, int line, int column) { + + String msg = NL+"Error"; + if (file != null) msg += " in file \""+file+"\""; + if (line >= 0) msg = msg+" (line "+(line+1)+")"; + + try { + err(msg+": "+NL+ErrorMessages.get(message)); + } + catch (ArrayIndexOutOfBoundsException e) { + err(msg); + } + + errors++; + + if (line >= 0) { + if (column >= 0) + showPosition(file, line, column); + else + showPosition(file, line); + } + } + + + /** + * prints a line of a file with marked position. + * + * @param file the file of which to show the line + * @param line the line to show + * @param column the column in which to show the marker + */ + public static void showPosition(File file, int line, int column) { + try { + String ln = getLine(file, line); + if (ln != null) { + err( ln ); + + if (column < 0) return; + + String t = "^"; + for (int i = 0; i < column; i++) t = " "+t; + + err(t); + } + } + catch (IOException e) { + /* silently ignore IO errors, don't show anything */ + } + } + + + /** + * print a line of a file + * + * @param file the file to show + * @param line the line number + */ + public static void showPosition(File file, int line) { + try { + String ln = getLine(file, line); + if (ln != null) err(ln); + } + catch (IOException e) { + /* silently ignore IO errors, don't show anything */ + } + } + + + /** + * get one line from a file + * + * @param file the file to read + * @param line the line number to get + * + * @throw IOException if any error occurs + */ + private static String getLine(File file, int line) throws IOException { + BufferedReader reader = new BufferedReader(new FileReader(file)); + + String msg = ""; + + for (int i = 0; i <= line; i++) + msg = reader.readLine(); + + reader.close(); + + return msg; + } + + + /** + * Print system information (e.g. in case of unexpected exceptions) + */ + public static void printSystemInfo() { + err("Java version: "+System.getProperty("java.version")); + err("Runtime name: "+System.getProperty("java.runtime.name")); + err("Vendor: "+System.getProperty("java.vendor")); + err("VM version: "+System.getProperty("java.vm.version")); + err("VM vendor: "+System.getProperty("java.vm.vendor")); + err("VM name: "+System.getProperty("java.vm.name")); + err("VM info: "+System.getProperty("java.vm.info")); + err("OS name: "+System.getProperty("os.name")); + err("OS arch: "+System.getProperty("os.arch")); + err("OS version: "+System.getProperty("os.version")); + err("Encoding: "+System.getProperty("file.encoding")); + err("JFlex version: "+Main.version); + } + + + /** + * Request a bug report for an unexpected Exception/Error. + */ + public static void requestBugReport(Error e) { + err("An unexpected error occurred. Please send a report of this to"); + err(" and include the following information:"); + err(""); + printSystemInfo(); + err("Exception:"); + e.printStackTrace(out); + err(""); + err("Please also include a specification (as small as possible)"); + err("that triggers this error. You may also want to check at"); + err("http://www.jflex.de if there is a newer version available"); + err("that doesn't have this problem"); + err(""); + err("Thanks for your support."); + } +} diff --git a/tools/lexer/jflex-1.4/src/JFlex/PackEmitter.java b/tools/lexer/jflex-1.4/src/JFlex/PackEmitter.java new file mode 100644 index 000000000000..1e98b327f343 --- /dev/null +++ b/tools/lexer/jflex-1.4/src/JFlex/PackEmitter.java @@ -0,0 +1,230 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * jflex 1.4 * + * Copyright (C) 1998-2004 Gerwin Klein * + * All rights reserved. * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License. See the file * + * COPYRIGHT for more information. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License along * + * with this program; if not, write to the Free Software Foundation, Inc., * + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +package JFlex; + + +/** + * Encodes int arrays as strings. + * + * Also splits up strings when longer than 64K in UTF8 encoding. + * Subclasses emit unpacking code. + * + * Usage protocol: + * p.emitInit();
+ * for each data: p.emitData(data);
+ * p.emitUnpack(); + * + * @author Gerwin Klein + * @version $Revision: 1.6 $, $Date: 2004/04/12 10:07:47 $ + */ +public abstract class PackEmitter { + + /** name of the generated array (mixed case, no yy prefix) */ + protected String name; + + /** current UTF8 length of generated string in current chunk */ + private int UTF8Length; + + /** position in the current line */ + private int linepos; + + /** max number of entries per line */ + private static final int maxEntries = 16; + + /** output buffer */ + protected StringBuffer out = new StringBuffer(); + + /** number of existing string chunks */ + protected int chunks; + + /** maximum size of chunks */ + // String constants are stored as UTF8 with 2 bytes length + // field in class files. One Unicode char can be up to 3 + // UTF8 bytes. 64K max and two chars safety. + private static final int maxSize = 0xFFFF-6; + + /** indent for string lines */ + private static final String indent = " "; + + /** + * Create new emitter for an array. + * + * @param name the name of the generated array + */ + public PackEmitter(String name) { + this.name = name; + } + + /** + * Convert array name into all uppercase internal scanner + * constant name. + * + * @return name as a internal constant name. + * @see PackEmitter#name + */ + protected String constName() { + return "ZZ_" + name.toUpperCase(); + } + + /** + * Return current output buffer. + */ + public String toString() { + return out.toString(); + } + + /** + * Emit declaration of decoded member and open first chunk. + */ + public void emitInit() { + out.append(" private static final int [] "); + out.append(constName()); + out.append(" = zzUnpack"); + out.append(name); + out.append("();"); + nl(); + nextChunk(); + } + + /** + * Emit single unicode character. + * + * Updates length, position, etc. + * + * @param i the character to emit. + * @prec 0 <= i <= 0xFFFF + */ + public void emitUC(int i) { + if (i < 0 || i > 0xFFFF) + throw new IllegalArgumentException("character value expected"); + + // cast ok because of prec + char c = (char) i; + + printUC(c); + UTF8Length += UTF8Length(c); + linepos++; + } + + /** + * Execute line/chunk break if necessary. + * Leave space for at least two chars. + */ + public void breaks() { + if (UTF8Length >= maxSize) { + // close current chunk + out.append("\";"); + nl(); + + nextChunk(); + } + else { + if (linepos >= maxEntries) { + // line break + out.append("\"+"); + nl(); + out.append(indent); + out.append("\""); + linepos = 0; + } + } + } + + /** + * Emit the unpacking code. + */ + public abstract void emitUnpack(); + + /** + * emit next chunk + */ + private void nextChunk() { + nl(); + out.append(" private static final String "); + out.append(constName()); + out.append("_PACKED_"); + out.append(chunks); + out.append(" ="); + nl(); + out.append(indent); + out.append("\""); + + UTF8Length = 0; + linepos = 0; + chunks++; + } + + /** + * emit newline + */ + protected void nl() { + out.append(Out.NL); + } + + /** + * Append a unicode/octal escaped character + * to out buffer. + * + * @param c the character to append + */ + private void printUC(char c) { + if (c > 255) { + out.append("\\u"); + if (c < 0x1000) out.append("0"); + out.append(Integer.toHexString(c)); + } + else { + out.append("\\"); + out.append(Integer.toOctalString(c)); + } + } + + /** + * Calculates the number of bytes a Unicode character + * would have in UTF8 representation in a class file. + * + * @param value the char code of the Unicode character + * @prec 0 <= value <= 0xFFFF + * + * @return length of UTF8 representation. + */ + private int UTF8Length(char value) { + // if (value < 0 || value > 0xFFFF) throw new Error("not a char value ("+value+")"); + + // see JVM spec §4.4.7, p 111 + if (value == 0) return 2; + if (value <= 0x7F) return 1; + + // workaround for javac bug (up to jdk 1.3): + if (value < 0x0400) return 2; + if (value <= 0x07FF) return 3; + + // correct would be: + // if (value <= 0x7FF) return 2; + return 3; + } + + // convenience + protected void println(String s) { + out.append(s); + nl(); + } +} diff --git a/tools/lexer/jflex-1.4/src/JFlex/RegExp.java b/tools/lexer/jflex-1.4/src/JFlex/RegExp.java new file mode 100644 index 000000000000..e171b180d092 --- /dev/null +++ b/tools/lexer/jflex-1.4/src/JFlex/RegExp.java @@ -0,0 +1,172 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * JFlex 1.4.1 * + * Copyright (C) 1998-2004 Gerwin Klein * + * All rights reserved. * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License. See the file * + * COPYRIGHT for more information. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License along * + * with this program; if not, write to the Free Software Foundation, Inc., * + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +package JFlex; + + +/** + * Stores a regular expression of rules section in a JFlex-specification. + * + * This base class has no content other than its type. + * + * @author Gerwin Klein + * @version JFlex 1.4.1, $Revision: 2.4 $, $Date: 2004/11/06 23:03:32 $ + */ +public class RegExp { + + /** + * The type of the regular expression. This field will be + * filled with values from class sym.java (generated by cup) + */ + int type; + + + /** + * Create a new regular expression of the specified type. + * + * @param type a value from the cup generated class sym. + * + * @see JFlex.sym + */ + public RegExp(int type) { + this.type = type; + } + + + + /** + * Returns a String-representation of this regular expression + * with the specified indentation. + * + * @param tab a String that should contain only space characters and + * that is inserted in front of standard String-representation + * pf this object. + */ + public String print(String tab) { + return tab+toString(); + } + + + /** + * Returns a String-representation of this regular expression + */ + public String toString() { + return "type = "+type; + } + + + /** + * Find out if this regexp is a char class or equivalent to one. + * + * @param macros for macro expansion + * @return true if the regexp is equivalent to a char class. + */ + public boolean isCharClass(Macros macros) { + RegExp1 unary; + RegExp2 binary; + + switch (type) { + case sym.CHAR: + case sym.CHAR_I: + case sym.CCLASS: + case sym.CCLASSNOT: + return true; + + case sym.BAR: + binary = (RegExp2) this; + return binary.r1.isCharClass(macros) && binary.r2.isCharClass(macros); + + case sym.MACROUSE: + unary = (RegExp1) this; + return macros.getDefinition((String) unary.content).isCharClass(macros); + + default: return false; + } + } + + /** + * The approximate number of NFA states this expression will need (only + * works correctly after macro expansion and without negation) + * + * @param macros macro table for expansion + */ + public int size(Macros macros) { + RegExp1 unary; + RegExp2 binary; + RegExp content; + + switch ( type ) { + case sym.BAR: + binary = (RegExp2) this; + return binary.r1.size(macros) + binary.r2.size(macros) + 2; + + case sym.CONCAT: + binary = (RegExp2) this; + return binary.r1.size(macros) + binary.r2.size(macros); + + case sym.STAR: + unary = (RegExp1) this; + content = (RegExp) unary.content; + return content.size(macros) + 2; + + case sym.PLUS: + unary = (RegExp1) this; + content = (RegExp) unary.content; + return content.size(macros) + 2; + + case sym.QUESTION: + unary = (RegExp1) this; + content = (RegExp) unary.content; + return content.size(macros); + + case sym.BANG: + unary = (RegExp1) this; + content = (RegExp) unary.content; + return content.size(macros) * content.size(macros); + // this is only a very rough estimate (worst case 2^n) + // exact size too complicated (propably requires construction) + + case sym.TILDE: + unary = (RegExp1) this; + content = (RegExp) unary.content; + return content.size(macros) * content.size(macros) * 3; + // see sym.BANG + + case sym.STRING: + case sym.STRING_I: + unary = (RegExp1) this; + return ((String) unary.content).length()+1; + + case sym.CHAR: + case sym.CHAR_I: + return 2; + + case sym.CCLASS: + case sym.CCLASSNOT: + return 2; + + case sym.MACROUSE: + unary = (RegExp1) this; + return macros.getDefinition((String) unary.content).size(macros); + } + + throw new Error("unknown regexp type "+type); + } +} diff --git a/tools/lexer/jflex-1.4/src/JFlex/RegExp1.java b/tools/lexer/jflex-1.4/src/JFlex/RegExp1.java new file mode 100644 index 000000000000..fb83ba9c8c55 --- /dev/null +++ b/tools/lexer/jflex-1.4/src/JFlex/RegExp1.java @@ -0,0 +1,80 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * JFlex 1.4.1 * + * Copyright (C) 1998-2004 Gerwin Klein * + * All rights reserved. * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License. See the file * + * COPYRIGHT for more information. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License along * + * with this program; if not, write to the Free Software Foundation, Inc., * + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +package JFlex; + + +/** + * Stores a regular expression from the rules section of a JFlex specification. + * + * This class provides storage for one Object of content. + * It is used for all regular expressions that are constructed from one object. + * + * For instance: a* is new RegExp1(sym.STAR, new Character ('a')); + * + * @author Gerwin Klein + * @version JFlex 1.4.1, $Revision: 2.2 $, $Date: 2004/11/06 23:03:32 $ + */ +public class RegExp1 extends RegExp { + + /** + * The child of this expression node in the syntax tree of a regular expression. + */ + Object content; + + + /** + * Constructs a new regular expression with one child object. + * + * @param type a value from the cup generated class sym, defining the + * kind of this regular expression + * + * @param content the child of this expression + */ + public RegExp1(int type, Object content) { + super(type); + this.content = content; + } + + + /** + * Returns a String-representation of this regular expression + * with the specified indentation. + * + * @param tab a String that should contain only space characters and + * that is inserted in front of standard String-representation + * pf this object. + */ + public String print(String tab) { + if (content instanceof RegExp) { + return tab+"type = "+type+Out.NL+tab+"content :"+Out.NL+((RegExp)content).print(tab+" "); + } + else + return tab+"type = "+type+Out.NL+tab+"content :"+Out.NL+tab+" "+content; + } + + + /** + * Returns a String-representation of this regular expression + */ + public String toString() { + return print(""); + } +} diff --git a/tools/lexer/jflex-1.4/src/JFlex/RegExp2.java b/tools/lexer/jflex-1.4/src/JFlex/RegExp2.java new file mode 100644 index 000000000000..b656b0c6947d --- /dev/null +++ b/tools/lexer/jflex-1.4/src/JFlex/RegExp2.java @@ -0,0 +1,50 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * JFlex 1.4.1 * + * Copyright (C) 1998-2004 Gerwin Klein * + * All rights reserved. * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License. See the file * + * COPYRIGHT for more information. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License along * + * with this program; if not, write to the Free Software Foundation, Inc., * + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +package JFlex; + + +/** + * Regular expression with two children (e.g. a | b) + * + * @author Gerwin Klein + * @version JFlex 1.4.1, $Revision: 2.3 $, $Date: 2004/11/06 23:03:30 $ + */ +public class RegExp2 extends RegExp { + + RegExp r1, r2; + + public RegExp2(int type, RegExp r1, RegExp r2) { + super(type); + this.r1 = r1; + this.r2 = r2; + } + + public String print(String tab) { + return tab+"type = "+type+Out.NL+tab+"child 1 :"+Out.NL+ //$NON-NLS-1$ //$NON-NLS-2$ + r1.print(tab+" ")+Out.NL+tab+"child 2 :"+Out.NL+ //$NON-NLS-1$ //$NON-NLS-2$ + r2.print(tab+" "); //$NON-NLS-1$ + } + + public String toString() { + return print(""); //$NON-NLS-1$ + } +} + diff --git a/tools/lexer/jflex-1.4/src/JFlex/RegExps.java b/tools/lexer/jflex-1.4/src/JFlex/RegExps.java new file mode 100644 index 000000000000..f6ad2be95d0d --- /dev/null +++ b/tools/lexer/jflex-1.4/src/JFlex/RegExps.java @@ -0,0 +1,159 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * JFlex 1.4.1 * + * Copyright (C) 1998-2004 Gerwin Klein * + * All rights reserved. * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License. See the file * + * COPYRIGHT for more information. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License along * + * with this program; if not, write to the Free Software Foundation, Inc., * + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ +package JFlex; + +import java.util.Enumeration; +import java.util.Vector; + + +/** + * Stores all rules of the specification for later access in RegExp -> NFA + * + * @author Gerwin Klein + * @version JFlex 1.4.1, $Revision: 2.4 $, $Date: 2004/11/06 23:03:31 $ + */ +public class RegExps { + + /** the spec line in which a regexp is used */ + Vector /* of Integer */ lines; + + /** the lexical states in wich the regexp is used */ + Vector /* of Vector of Integer */ states; + + /** the regexp */ + Vector /* of RegExp */ regExps; + + /** the action of a regexp */ + Vector /* of Action */ actions; + + /** flag if it is a BOL regexp */ + Vector /* of Boolean */ BOL; + + /** the lookahead expression */ + Vector /* of RegExp */ look; + + public RegExps() { + states = new Vector(); + regExps = new Vector(); + actions = new Vector(); + BOL = new Vector(); + look = new Vector(); + lines = new Vector(); + } + + public int insert(int line, Vector stateList, RegExp regExp, Action action, + Boolean isBOL, RegExp lookAhead) { + if (Options.DEBUG) { + Out.debug("Inserting regular expression with statelist :"+Out.NL+stateList); //$NON-NLS-1$ + Out.debug("and action code :"+Out.NL+action.content+Out.NL); //$NON-NLS-1$ + Out.debug("expression :"+Out.NL+regExp); //$NON-NLS-1$ + } + + states.addElement(stateList); + regExps.addElement(regExp); + actions.addElement(action); + BOL.addElement(isBOL); + look.addElement(lookAhead); + lines.addElement(new Integer(line)); + + return states.size()-1; + } + + public int insert(Vector stateList, Action action) { + + if (Options.DEBUG) { + Out.debug("Inserting eofrule with statelist :"+Out.NL+stateList); //$NON-NLS-1$ + Out.debug("and action code :"+Out.NL+action.content+Out.NL); //$NON-NLS-1$ + } + + states.addElement(stateList); + regExps.addElement(null); + actions.addElement(action); + BOL.addElement(null); + look.addElement(null); + lines.addElement(null); + + return states.size()-1; + } + + public void addStates(int regNum, Vector newStates) { + Enumeration s = newStates.elements(); + + while (s.hasMoreElements()) + ((Vector)states.elementAt(regNum)).addElement(s.nextElement()); + } + + public int getNum() { + return states.size(); + } + + public boolean isBOL(int num) { + return ((Boolean) BOL.elementAt(num)).booleanValue(); + } + + public RegExp getLookAhead(int num) { + return (RegExp) look.elementAt(num); + } + + public boolean isEOF(int num) { + return BOL.elementAt(num) == null; + } + + public Vector getStates(int num) { + return (Vector) states.elementAt(num); + } + + public RegExp getRegExp(int num) { + return (RegExp) regExps.elementAt(num); + } + + public int getLine(int num) { + return ((Integer) lines.elementAt(num)).intValue(); + } + + public void checkActions() { + if ( actions.elementAt(actions.size()-1) == null ) { + Out.error(ErrorMessages.NO_LAST_ACTION); + throw new GeneratorException(); + } + } + + public Action getAction(int num) { + while ( num < actions.size() && actions.elementAt(num) == null ) + num++; + + return (Action) actions.elementAt(num); + } + + public int NFASize(Macros macros) { + int size = 0; + Enumeration e = regExps.elements(); + while (e.hasMoreElements()) { + RegExp r = (RegExp) e.nextElement(); + if (r != null) size += r.size(macros); + } + e = look.elements(); + while (e.hasMoreElements()) { + RegExp r = (RegExp) e.nextElement(); + if (r != null) size += r.size(macros); + } + return size; + } +} diff --git a/tools/lexer/jflex-1.4/src/JFlex/ScannerException.java b/tools/lexer/jflex-1.4/src/JFlex/ScannerException.java new file mode 100644 index 000000000000..004ce886a5af --- /dev/null +++ b/tools/lexer/jflex-1.4/src/JFlex/ScannerException.java @@ -0,0 +1,104 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * JFlex 1.4.1 * + * Copyright (C) 1998-2004 Gerwin Klein * + * All rights reserved. * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License. See the file * + * COPYRIGHT for more information. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License along * + * with this program; if not, write to the Free Software Foundation, Inc., * + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +package JFlex; + +import java.io.File; + +/** + * This Exception could be thrown while scanning the specification + * (e.g. unmatched input) + * + * @author Gerwin Klein + * @version JFlex 1.4.1, $Revision: 2.3 $, $Date: 2004/11/06 23:03:30 $ + */ +public class ScannerException extends RuntimeException { + + public int line; + public int column; + public ErrorMessages message; + public File file; + + private ScannerException(File file, String text, ErrorMessages message, int line, int column) { + super(text); + this.file = file; + this.message = message; + this.line = line; + this.column = column; + } + + + /** + * Creates a new ScannerException with a message only. + * + * @param message the code for the error description presented to the user. + */ + public ScannerException(ErrorMessages message) { + this( null, ErrorMessages.get(message), message, -1, -1 ); + } + + /** + * Creates a new ScannerException for a file with a message only. + * + * @param file the file in which the error occured + * @param message the code for the error description presented to the user. + */ + public ScannerException(File file, ErrorMessages message) { + this( file, ErrorMessages.get(message), message, -1, -1 ); + } + + + /** + * Creates a new ScannerException with a message and line number. + * + * @param message the code for the error description presented to the user. + * @param line the number of the line in the specification that + * contains the error + */ + public ScannerException(ErrorMessages message, int line) { + this( null, ErrorMessages.get(message), message, line, -1 ); + } + + + /** + * Creates a new ScannerException for a file with a message and line number. + * + * @param message the code for the error description presented to the user. + * @param line the number of the line in the specification that + * contains the error + */ + public ScannerException(File file, ErrorMessages message, int line) { + this( file, ErrorMessages.get(message), message, line, -1 ); + } + + + /** + * Creates a new ScannerException with a message, line number and column. + * + * @param message the code for the error description presented to the user. + * @param line the number of the line in the specification that + * contains the error + * @param column the column where the error starts + */ + public ScannerException(File file, ErrorMessages message, int line, int column) { + this( file, ErrorMessages.get(message), message, line, column ); + } + +} diff --git a/tools/lexer/jflex-1.4/src/JFlex/SemCheck.java b/tools/lexer/jflex-1.4/src/JFlex/SemCheck.java new file mode 100644 index 000000000000..04f66477b256 --- /dev/null +++ b/tools/lexer/jflex-1.4/src/JFlex/SemCheck.java @@ -0,0 +1,145 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * JFlex 1.4.1 * + * Copyright (C) 1998-2004 Gerwin Klein * + * All rights reserved. * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License. See the file * + * COPYRIGHT for more information. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License along * + * with this program; if not, write to the Free Software Foundation, Inc., * + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ +package JFlex; + +import java.io.File; + +/** + * Performs simple semantic analysis on regular expressions. + * + * (used for checking if trailing contexts are legal) + * + * @author Gerwin Klein + * @version JFlex 1.4.1, $Revision: 2.5 $, $Date: 2004/11/06 23:03:32 $ + */ +public final class SemCheck { + + // stored globally since they are used as constants in all checks + private static Macros macros; + private static char maxChar; + + + /** + * Performs semantic analysis for all expressions. + * + * Currently: illegal lookahead check only + * [fixme: more checks possible] + * + * @param rs the reg exps to be checked + * @param m the macro table (in expanded form) + * @param max max character of the used charset (for negation) + * @param f the spec file containing the rules [fixme] + */ + public static void check(RegExps rs, Macros m, char max, File f) { + macros = m; + maxChar = max; + + int num = rs.getNum(); + for (int i = 0; i < num; i++) { + RegExp r = rs.getRegExp(i); + RegExp l = rs.getLookAhead(i); + + if (!checkLookAhead(r,l)) { + Out.warning(f, ErrorMessages.LOOKAHEAD_ERROR, rs.getLine(i), -1); + } + } + } + + + /** + * Checks for illegal lookahead expressions. + * + * Lookahead in JFlex only works when the first expression has fixed + * length or when the intersection of the last set of the first expression + * and the first set of the second expression is empty. + * + * FIXME: this check is much too weak + * + * + * @param r1 first regexp + * @param r2 second regexp (the lookahead) + * + * @return true iff JFlex can generate code for the lookahead expression + */ + private static boolean checkLookAhead(RegExp r1, RegExp r2) { + return r2 == null || length(r1) > 0; + } + + + /** + * Returns length if expression has fixed length, -1 otherwise. + * + * Negation operators are treated as always variable length. + */ + private static int length(RegExp re) { + RegExp2 r; + + switch (re.type) { + + case sym.BAR: { + r = (RegExp2) re; + int l1 = length(r.r1); + if (l1 < 0) return -1; + int l2 = length(r.r2); + + if (l1 == l2) + return l1; + else + return -1; + } + + case sym.CONCAT: { + r = (RegExp2) re; + int l1 = length(r.r1); + if (l1 < 0) return -1; + int l2 = length(r.r2); + if (l2 < 0) return -1; + return l1+l2; + } + + case sym.STAR: + case sym.PLUS: + case sym.QUESTION: + return -1; + + case sym.CCLASS: + case sym.CCLASSNOT: + case sym.CHAR: + case sym.CHAR_I: + return 1; + + case sym.STRING: + case sym.STRING_I: { + String content = (String) ((RegExp1) re).content; + return content.length(); + } + + case sym.TILDE: + case sym.BANG: + // too hard to caculate at this level, use safe approx + return -1; + + case sym.MACROUSE: + return length(macros.getDefinition((String) ((RegExp1) re).content)); + } + + throw new Error("Unkown expression type "+re.type+" in "+re); //$NON-NLS-1$ //$NON-NLS-2$ + } +} diff --git a/tools/lexer/jflex-1.4/src/JFlex/SilentExit.java b/tools/lexer/jflex-1.4/src/JFlex/SilentExit.java new file mode 100644 index 000000000000..e60affa3338f --- /dev/null +++ b/tools/lexer/jflex-1.4/src/JFlex/SilentExit.java @@ -0,0 +1,31 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * JFlex 1.4.1 * + * Copyright (C) 1998-2004 Gerwin Klein * + * All rights reserved. * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License. See the file * + * COPYRIGHT for more information. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License along * + * with this program; if not, write to the Free Software Foundation, Inc., * + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +package JFlex; + +/** + * Signals a silent exit (no statistics printout). + * + * @author Gerwin Klein + * @version $Revision: 2.3 $, $Date: 2004/11/06 23:03:32 $ + */ +public class SilentExit extends Exception { + +} diff --git a/tools/lexer/jflex-1.4/src/JFlex/Skeleton.java b/tools/lexer/jflex-1.4/src/JFlex/Skeleton.java new file mode 100644 index 000000000000..89c519da3433 --- /dev/null +++ b/tools/lexer/jflex-1.4/src/JFlex/Skeleton.java @@ -0,0 +1,207 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * JFlex 1.4.1 * + * Copyright (C) 1998-2004 Gerwin Klein * + * All rights reserved. * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License. See the file * + * COPYRIGHT for more information. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License along * + * with this program; if not, write to the Free Software Foundation, Inc., * + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ +package JFlex; + +import java.io.*; +import java.net.URL; +import java.util.Vector; + + +/** + * This class stores the skeleton of generated scanners. + * + * The skeleton consists of several parts that can be emitted to + * a file. Usually there is a portion of generated code + * (produced in class Emitter) between every two parts of skeleton code. + * + * There is a static part (the skeleton code) and state based iterator + * part to this class. The iterator part is used to emit consecutive skeleton + * sections to some PrintWriter. + * + * @see JFlex.Emitter + * + * @author Gerwin Klein + * @version JFlex 1.4.1, $Revision: 2.13 $, $Date: 2004/11/06 23:03:31 $ + */ +public class Skeleton { + /** expected number of sections in the skeleton file */ + static final private int size = 21; + + /** platform specific newline */ + static final private String NL = System.getProperty("line.separator"); //$NON-NLS-1$ + + /** The skeleton */ + public static String line[]; + + /** initialization */ + static { readDefault(); } + + // the state based, iterator part of Skeleton: + + /** + * The current part of the skeleton (an index of nextStop[]) + */ + private int pos; + + /** + * The writer to write the skeleton-parts to + */ + private PrintWriter out; + + + /** + * Creates a new skeleton (iterator) instance. + * + * @param out the writer to write the skeleton-parts to + */ + public Skeleton(PrintWriter out) { + this.out = out; + } + + + /** + * Emits the next part of the skeleton + */ + public void emitNext() { + out.print( line[pos++] ); + } + + + /** + * Make the skeleton private. + * + * Replaces all occurences of " public " in the skeleton with " private ". + */ + public static void makePrivate() { + for (int i=0; i < line.length; i++) { + line[i] = replace(" public ", " private ", line[i]); //$NON-NLS-1$ //$NON-NLS-2$ + } + } + + + /** + * Reads an external skeleton file for later use with this class. + * + * @param skeletonFile the file to read (must be != null and readable) + */ + public static void readSkelFile(File skeletonFile) { + if (skeletonFile == null) + throw new IllegalArgumentException("Skeleton file must not be null"); //$NON-NLS-1$ + + if (!skeletonFile.isFile() || !skeletonFile.canRead()) { + Out.error(ErrorMessages.CANNOT_READ_SKEL, skeletonFile.toString()); + throw new GeneratorException(); + } + + Out.println(ErrorMessages.READING_SKEL, skeletonFile.toString()); + + try { + BufferedReader reader = new BufferedReader(new FileReader(skeletonFile)); + readSkel(reader); + } + catch (IOException e) { + Out.error(ErrorMessages.SKEL_IO_ERROR); + throw new GeneratorException(); + } + } + + + /** + * Reads an external skeleton file from a BufferedReader. + * + * @param reader the reader to read from (must be != null) + * @throws IOException if an IO error occurs + * @throws GeneratorException if the number of skeleton sections does not match + */ + public static void readSkel(BufferedReader reader) throws IOException { + Vector lines = new Vector(); + StringBuffer section = new StringBuffer(); + + String ln; + while ((ln = reader.readLine()) != null) { + if (ln.startsWith("---")) { //$NON-NLS-1$ + lines.addElement(section.toString()); + section.setLength(0); + } else { + section.append(ln); + section.append(NL); + } + } + + if (section.length() > 0) + lines.addElement(section.toString()); + + if (lines.size() != size) { + Out.error(ErrorMessages.WRONG_SKELETON); + throw new GeneratorException(); + } + + line = new String[size]; + for (int i = 0; i < size; i++) + line[i] = (String) lines.elementAt(i); + } + + /** + * Replaces a with b in c. + * + * @param a the String to be replaced + * @param b the replacement + * @param c the String in which to replace a by b + * @return a String object with a replaced by b in c + */ + public static String replace(String a, String b, String c) { + StringBuffer result = new StringBuffer(c.length()); + int i = 0; + int j = c.indexOf(a); + + while (j >= i) { + result.append(c.substring(i,j)); + result.append(b); + i = j+a.length(); + j = c.indexOf(a,i); + } + + result.append(c.substring(i,c.length())); + + return result.toString(); + } + + + /** + * (Re)load the default skeleton. Looks in the current system class path. + */ + public static void readDefault() { + ClassLoader l = Skeleton.class.getClassLoader(); + URL url = l.getResource("JFlex/skeleton.default"); //$NON-NLS-1$ + + if (url == null) { + Out.error(ErrorMessages.SKEL_IO_ERROR_DEFAULT); + throw new GeneratorException(); + } + + try { + InputStreamReader reader = new InputStreamReader(url.openStream()); + readSkel(new BufferedReader(reader)); + } catch (IOException e) { + Out.error(ErrorMessages.SKEL_IO_ERROR_DEFAULT); + throw new GeneratorException(); + } + } +} diff --git a/tools/lexer/jflex-1.4/src/JFlex/StatePairList.java b/tools/lexer/jflex-1.4/src/JFlex/StatePairList.java new file mode 100644 index 000000000000..d69deae8c56c --- /dev/null +++ b/tools/lexer/jflex-1.4/src/JFlex/StatePairList.java @@ -0,0 +1,83 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * JFlex 1.4.1 * + * Copyright (C) 1998-2004 Gerwin Klein * + * All rights reserved. * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License. See the file * + * COPYRIGHT for more information. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License along * + * with this program; if not, write to the Free Software Foundation, Inc., * + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +package JFlex; + +/** + * A list of pairs of states. Used in DFA minimization. + * + * @author Gerwin Klein + * @version JFlex 1.4.1, $Revision: 2.4 $, $Date: 2004/11/06 23:03:30 $ + */ +final public class StatePairList { + + // implemented as two arrays of integers. + // java.util classes proved too inefficient. + + int p []; + int q []; + + int num; + + public StatePairList() { + p = new int [8]; + q = new int [8]; + num = 0; + } + + public void addPair(int i, int j) { + for (int x = 0; x < num; x++) + if (p[x] == i && q[x] == j) return; + + if (num >= p.length) increaseSize(num); + + p[num] = i; + q[num] = j; + + num++; + } + + public void markAll(StatePairList [] [] list, boolean [] [] equiv) { + for (int x = 0; x < num; x++) { + int i = p[x]; + int j = q[x]; + + if (equiv[i][j]) { + equiv[i][j] = false; + if (list[i][j] != null) + list[i][j].markAll(list, equiv); + } + } + } + + private void increaseSize(int length) { + length = Math.max(length+1, 4*p.length); + Out.debug("increasing length to "+length); //$NON-NLS-1$ + + int pn [] = new int[length]; + int qn [] = new int[length]; + + System.arraycopy(p, 0, pn, 0, p.length); + System.arraycopy(q, 0, qn, 0, q.length); + + p = pn; + q = qn; + } +} diff --git a/tools/lexer/jflex-1.4/src/JFlex/StateSet.java b/tools/lexer/jflex-1.4/src/JFlex/StateSet.java new file mode 100644 index 000000000000..0fcbc22ee915 --- /dev/null +++ b/tools/lexer/jflex-1.4/src/JFlex/StateSet.java @@ -0,0 +1,329 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * JFlex 1.4.1 * + * Copyright (C) 1998-2004 Gerwin Klein * + * All rights reserved. * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License. See the file * + * COPYRIGHT for more information. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License along * + * with this program; if not, write to the Free Software Foundation, Inc., * + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ +package JFlex; + +/** + * A set of NFA states (= integers). + * + * Very similar to java.util.BitSet, but is faster and doesn't crash + * + * @author Gerwin Klein + * @version JFlex 1.4.1, $Revision: 2.4 $, $Date: 2004/11/06 23:03:32 $ + */ +final public class StateSet { + + private final boolean DEBUG = false; + + public final static StateSet EMPTY = new StateSet(); + + + final static int BITS = 6; + final static int MASK = (1<> BITS; + if (index >= bits.length) resize(state); + bits[index] |= (1L << (state & MASK)); + + if (DEBUG) { + Out.dump("StateSet.addState("+state+") end"); //$NON-NLS-1$ //$NON-NLS-2$ + Out.dump("Set is : "+this); //$NON-NLS-1$ + } + } + + + private int size2nbits (int size) { + return ((size >> BITS) + 1); + } + + + private void resize(int size) { + int needed = size2nbits(size); + + // if (needed < bits.length) return; + + long newbits[] = new long[Math.max(bits.length*4,needed)]; + System.arraycopy(bits, 0, newbits, 0, bits.length); + + bits = newbits; + } + + + public void clear() { + int l = bits.length; + for (int i = 0; i < l; i++) bits[i] = 0; + } + + public boolean isElement(int state) { + int index = state >> BITS; + if (index >= bits.length) return false; + return (bits[index] & (1L << (state & MASK))) != 0; + } + + /** + * Returns one element of the set and removes it. + * + * Precondition: the set is not empty. + */ + public int getAndRemoveElement() { + int i = 0; + int o = 0; + long m = 1; + + while (bits[i] == 0) i++; + + while ( (bits[i] & m) == 0 ) { + m<<= 1; + o++; + } + + bits[i]&= ~m; + + return (i << BITS) + o; + } + + public void remove(int state) { + int index = state >> BITS; + if (index >= bits.length) return; + bits[index] &= ~(1L << (state & MASK)); + } + + /** + * Returns the set of elements that contained are in the specified set + * but are not contained in this set. + */ + public StateSet complement(StateSet set) { + + if (set == null) return null; + + StateSet result = new StateSet(); + + result.bits = new long[set.bits.length]; + + int i; + int m = Math.min(bits.length, set.bits.length); + + for (i = 0; i < m; i++) { + result.bits[i] = ~bits[i] & set.bits[i]; + } + + if (bits.length < set.bits.length) + System.arraycopy(set.bits, m, result.bits, m, result.bits.length-m); + + if (DEBUG) + Out.dump("Complement of "+this+Out.NL+"and "+set+Out.NL+" is :"+result); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + + return result; + } + + public void add(StateSet set) { + + if (DEBUG) Out.dump("StateSet.add("+set+") start"); //$NON-NLS-1$ //$NON-NLS-2$ + + if (set == null) return; + + long tbits[]; + long sbits[] = set.bits; + int sbitsl = sbits.length; + + if (bits.length < sbitsl) { + tbits = new long[sbitsl]; + System.arraycopy(bits, 0, tbits, 0, bits.length); + } + else { + tbits = this.bits; + } + + for (int i = 0; i < sbitsl; i++) { + tbits[i] |= sbits[i]; + } + + this.bits = tbits; + + if (DEBUG) { + Out.dump("StateSet.add("+set+") end"); //$NON-NLS-1$ //$NON-NLS-2$ + Out.dump("Set is : "+this); //$NON-NLS-1$ + } + } + + + + public boolean containsSet(StateSet set) { + + if (DEBUG) + Out.dump("StateSet.containsSet("+set+"), this="+this); //$NON-NLS-1$ //$NON-NLS-2$ + + int i; + int min = Math.min(bits.length, set.bits.length); + + for (i = 0; i < min; i++) + if ( (bits[i] & set.bits[i]) != set.bits[i] ) return false; + + for (i = min; i < set.bits.length; i++) + if ( set.bits[i] != 0 ) return false; + + return true; + } + + + + /** + * @throws ClassCastException if b is not a StateSet + * @throws NullPointerException if b is null + */ + public boolean equals(Object b) { + + int i = 0; + int l1,l2; + StateSet set = (StateSet) b; + + if (DEBUG) Out.dump("StateSet.equals("+set+"), this="+this); //$NON-NLS-1$ //$NON-NLS-2$ + + l1 = bits.length; + l2 = set.bits.length; + + if (l1 <= l2) { + while (i < l1) { + if (bits[i] != set.bits[i]) return false; + i++; + } + + while (i < l2) + if (set.bits[i++] != 0) return false; + } + else { + while (i < l2) { + if (bits[i] != set.bits[i]) return false; + i++; + } + + while (i < l1) + if (bits[i++] != 0) return false; + } + + return true; + } + + public int hashCode() { + long h = 1234; + long [] _bits = bits; + int i = bits.length-1; + + // ignore zero high bits + while (i >= 0 && _bits[i] == 0) i--; + + while (i >= 0) + h ^= _bits[i--] * i; + + return (int)((h >> 32) ^ h); + } + + + public StateSetEnumerator states() { + return new StateSetEnumerator(this); + } + + + public boolean containsElements() { + for (int i = 0; i < bits.length; i++) + if (bits[i] != 0) return true; + + return false; + } + + + public StateSet copy() { + StateSet set = new StateSet(); + set.bits = new long[bits.length]; + System.arraycopy(bits, 0, set.bits, 0, bits.length); + return set; + } + + + public void copy(StateSet set) { + + if (DEBUG) + Out.dump("StateSet.copy("+set+") start"); //$NON-NLS-1$ //$NON-NLS-2$ + + if (set == null) { + for (int i = 0; i < bits.length; i++) bits[i] = 0; + return; + } + + if (bits.length < set.bits.length) { + bits = new long[set.bits.length]; + } + else { + for (int i = set.bits.length; i < bits.length; i++) bits[i] = 0; + } + + System.arraycopy(set.bits, 0, bits, 0, bits.length); + + if (DEBUG) { + Out.dump("StateSet.copy("+set+") end"); //$NON-NLS-1$ //$NON-NLS-2$ + Out.dump("Set is : "+this); //$NON-NLS-1$ + } + } + + + public String toString() { + StateSetEnumerator set = states(); + + StringBuffer result = new StringBuffer("{"); //$NON-NLS-1$ + + if ( set.hasMoreElements() ) result.append(""+set.nextElement()); //$NON-NLS-1$ + + while ( set.hasMoreElements() ) { + int i = set.nextElement(); + result.append( ", "+i); //$NON-NLS-1$ + } + + result.append("}"); //$NON-NLS-1$ + + return result.toString(); + } +} diff --git a/tools/lexer/jflex-1.4/src/JFlex/StateSetEnumerator.java b/tools/lexer/jflex-1.4/src/JFlex/StateSetEnumerator.java new file mode 100644 index 000000000000..5e5ac7b147b9 --- /dev/null +++ b/tools/lexer/jflex-1.4/src/JFlex/StateSetEnumerator.java @@ -0,0 +1,127 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * JFlex 1.4.1 * + * Copyright (C) 1998-2004 Gerwin Klein * + * All rights reserved. * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License. See the file * + * COPYRIGHT for more information. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License along * + * with this program; if not, write to the Free Software Foundation, Inc., * + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ +package JFlex; + +/** + * Enumerates the states of a StateSet. + * + * @author Gerwin Klein + * @version JFlex 1.4.1, $Revision: 2.3 $, $Date: 2004/11/06 23:03:32 $ + */ +final public class StateSetEnumerator { + + private final static boolean DEBUG = false; + + private int index; + private int offset; + private long mask; + + private int current; + private long [] bits; + + /** + * creates a new StateSetEnumerator that is not yet associated + * with a StateSet. hasMoreElements() and nextElement() will + * throw NullPointerException when used before reset() + */ + public StateSetEnumerator() { + } + + public StateSetEnumerator(StateSet states) { + reset(states); + } + + public void reset(StateSet states) { + bits = states.bits; + index = 0; + offset = 0; + mask = 1; + current = 0; + + while (index < bits.length && bits[index] == 0) + index++; + + if (index >= bits.length) return; + + while (offset <= StateSet.MASK && ((bits[index] & mask) == 0)) { + mask<<= 1; + offset++; + } + } + + private void advance() { + + if (DEBUG) Out.dump("Advancing, at start, index = "+index+", offset = "+offset); //$NON-NLS-1$ //$NON-NLS-2$ + + // cache fields in local variable for faster access + int _index = this.index; + int _offset = this.offset; + long _mask = this.mask; + long [] _bits = this.bits; + + long bi = _bits[_index]; + + do { + _offset++; + _mask<<= 1; + } while (_offset <= StateSet.MASK && ((bi & _mask) == 0)); + + if (_offset > StateSet.MASK) { + int length = _bits.length; + + do + _index++; + while (_index < length && _bits[_index] == 0); + + if (_index >= length) { + this.index = length; // indicates "no more elements" + return; + } + + _offset = 0; + _mask = 1; + bi = _bits[_index]; + + // terminates, because bi != 0 + while ((bi & _mask) == 0) { + _mask<<= 1; + _offset++; + } + } + + // write back cached values + this.index = _index; + this.mask = _mask; + this.offset = _offset; + } + + public boolean hasMoreElements() { + if (DEBUG) Out.dump("hasMoreElements, index = "+index+", offset = "+offset); //$NON-NLS-1$ //$NON-NLS-2$ + return index < bits.length; + } + + public int nextElement() { + if (DEBUG) Out.dump("nextElement, index = "+index+", offset = "+offset); //$NON-NLS-1$ //$NON-NLS-2$ + int x = (index << StateSet.BITS) + offset; + advance(); + return x; + } + +} diff --git a/tools/lexer/jflex-1.4/src/JFlex/StdOutWriter.java b/tools/lexer/jflex-1.4/src/JFlex/StdOutWriter.java new file mode 100644 index 000000000000..572a756c64bc --- /dev/null +++ b/tools/lexer/jflex-1.4/src/JFlex/StdOutWriter.java @@ -0,0 +1,114 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * JFlex 1.4.1 * + * Copyright (C) 1998-2004 Gerwin Klein * + * All rights reserved. * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License. See the file * + * COPYRIGHT for more information. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License along * + * with this program; if not, write to the Free Software Foundation, Inc., * + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +package JFlex; + + +import java.awt.*; +import java.io.OutputStream; +import java.io.PrintWriter; + + +/** + * Convenience class for JFlex stdout, redirects output to a TextArea + * if in GUI mode. + * + * @author Gerwin Klein + * @version JFlex 1.4.1, $Revision: 2.4 $, $Date: 2004/11/06 23:03:30 $ + */ +public final class StdOutWriter extends PrintWriter { + + /** text area to write to if in gui mode, gui mode = (text != null) */ + private TextArea text; + + /** + * approximation of the current column in the text area + * for auto wrapping at wrap characters + **/ + private int col; + + /** auto wrap lines in gui mode at this value */ + private final static int wrap = 78; + + /** A StdOutWriter, attached to System.out, no gui mode */ + public StdOutWriter() { + super(System.out,true); + } + + /** A StdOutWrite, attached to the specified output stream, no gui mode */ + public StdOutWriter(OutputStream out) { + super(out,true); + } + + /** + * Set the TextArea to write text to. Will continue + * to write to System.out if text is null. + * + * @param text the TextArea to write to + */ + public void setGUIMode(TextArea text) { + this.text = text; + } + + /** Write a single character. */ + public void write(int c) { + if (text != null) { + text.append(String.valueOf((char) c)); + if (++col > wrap) println(); + } + else + super.write(c); + } + + /** Write a portion of an array of characters. */ + public void write(char buf[], int off, int len) { + if (text != null) { + text.append(new String(buf,off,len)); + if ((col+=len) > wrap) println(); + } + else + super.write(buf, off, len); + } + + /** Write a portion of a string. */ + public void write(String s, int off, int len) { + if (text != null) { + text.append(s.substring(off,off+len)); + if ((col+=len) > wrap) println(); + } + else { + super.write(s,off,len); + flush(); + } + } + + /** + * Begin a new line. Which actual character/s is/are written + * depends on the runtime platform. + */ + public void println() { + if (text != null) { + text.append(Out.NL); + col = 0; + } + else + super.println(); + } +} diff --git a/tools/lexer/jflex-1.4/src/JFlex/Timer.java b/tools/lexer/jflex-1.4/src/JFlex/Timer.java new file mode 100644 index 000000000000..3cead204cfe2 --- /dev/null +++ b/tools/lexer/jflex-1.4/src/JFlex/Timer.java @@ -0,0 +1,110 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * JFlex 1.4.1 * + * Copyright (C) 1998-2004 Gerwin Klein * + * All rights reserved. * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License. See the file * + * COPYRIGHT for more information. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License along * + * with this program; if not, write to the Free Software Foundation, Inc., * + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ +package JFlex; + +/** + * Very simple timer for code generation time statistics. + * + * Not very exact, measures user time, not processor time. + * + * @author Gerwin Klein + * @version JFlex 1.4.1, $Revision: 2.3 $, $Date: 2004/11/06 23:03:32 $ + */ +public class Timer { + + /* the timer stores start and stop time from currentTimeMillis() */ + private long startTime, stopTime; + + /* flag if the timer is running (if stop time is valid) */ + private boolean running; + + + /** + * Construct a new timer that starts immediatly. + */ + public Timer() { + startTime = System.currentTimeMillis(); + running = true; + } + + + /** + * Start the timer. If it is already running, the old start + * time is lost. + */ + public void start() { + startTime = System.currentTimeMillis(); + running = true; + } + + + /** + * Stop the timer. + */ + public void stop() { + stopTime = System.currentTimeMillis(); + running = false; + } + + + /** + * Return the number of milliseconds the timer has been running. + * + * (up till now, if it still runs, up to the stop time if it has been stopped) + */ + public long diff() { + if (running) + return System.currentTimeMillis()-startTime; + else + return stopTime-startTime; + } + + + /** + * Return a string representation of the timer. + * + * @return a string displaying the diff-time in readable format (h m s ms) + * + * @see Timer#diff + */ + public String toString() { + long diff = diff(); + + long millis = diff%1000; + long secs = (diff/1000)%60; + long mins = (diff/(1000*60))%60; + long hs = (diff/(1000*3600))%24; + long days = diff/(1000*3600*24); + + if (days > 0) + return days+"d "+hs+"h "+mins+"m "+secs+"s "+millis+"ms"; + + if (hs > 0) + return hs+"h "+mins+"m "+secs+"s "+millis+"ms"; + + if (mins > 0) + return mins+"m "+secs+"s "+millis+"ms"; + + if (secs > 0) + return secs+"s "+millis+"ms"; + + return millis+"ms"; + } +} diff --git a/tools/lexer/jflex-1.4/src/JFlex/anttask/JFlexTask.java b/tools/lexer/jflex-1.4/src/JFlex/anttask/JFlexTask.java new file mode 100644 index 000000000000..10a95c5652c4 --- /dev/null +++ b/tools/lexer/jflex-1.4/src/JFlex/anttask/JFlexTask.java @@ -0,0 +1,268 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * JFlex Anttask * + * Copyright (C) 2001 Rafal Mantiuk * + * Copyright (C) 2003 changes by Gerwin Klein * + * All rights reserved. * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License. See the file * + * COPYRIGHT for more information. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License along * + * with this program; if not, write to the Free Software Foundation, Inc., * + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +package JFlex.anttask; + +import JFlex.Main; +import JFlex.Options; +import org.apache.tools.ant.BuildException; +import org.apache.tools.ant.Task; + +import java.io.File; +import java.io.FileReader; +import java.io.IOException; +import java.io.LineNumberReader; + +/** + * JFlex task class + * + * @author Rafal Mantiuk + * @version JFlex 1.4.1, $Revision: 2.14 $, $Date: 2004/11/06 23:03:33 $ + */ +public class JFlexTask extends Task { + private File inputFile; + + // found out by looking into .flex file + private String className = null; + private String packageName = null; + + /** for javac-like dest dir behaviour */ + private File destinationDir; + + /** the actual output directory (outputDir = destinationDir + package)) */ + private File outputDir = null; + + public JFlexTask() { + // ant default is different from the rest of JFlex + setVerbose(false); + Options.progress = false; + } + + public void execute() throws BuildException { + try { + if (inputFile == null) + throw new BuildException("Input file needed. Use "); + + if (!inputFile.canRead()) + throw new BuildException("Cannot read input file "+inputFile); + + try { + findPackageAndClass(); + normalizeOutdir(); + File destFile = new File(outputDir, className + ".java"); + + if (inputFile.lastModified() > destFile.lastModified()) { + Main.generate(inputFile); + if (!Options.verbose) + System.out.println("Generated: " + destFile.getName()); + } + } catch (IOException e1) { + throw new BuildException("IOException: " + e1.toString()); + } + } catch (JFlex.GeneratorException e) { + throw new BuildException("JFlex: generation failed!"); + } + } + + /** + * Peek into .flex file to get package and class name + * + * @throws IOException if there is a problem reading the .flex file + */ + public void findPackageAndClass() throws IOException { + // find name of the package and class in jflex source file + packageName = null; + className = null; + + LineNumberReader reader = new LineNumberReader(new FileReader(inputFile)); + + while (className == null || packageName == null) { + String line = reader.readLine(); + if (line == null) break; + + if (packageName == null) { + int index = line.indexOf("package"); + if (index >= 0) { + index += 7; + + int end = line.indexOf(';', index); + if (end >= index) { + packageName = line.substring(index, end); + packageName = packageName.trim(); + } + } + } + + if (className == null) { + int index = line.indexOf("%class"); + if (index >= 0) { + index += 6; + + className = line.substring(index); + className = className.trim(); + } + } + } + + // package name may be null, but class name not + if (className == null) className = "Yylex"; + } + + /** + * Sets the actual output directory if not already set. + * + * Uses javac logic to determine output dir = dest dir + package name + * If not destdir has been set, output dir = parent of input file + * + * Assumes that package name is already set. + */ + public void normalizeOutdir() { + if (outputDir != null) return; + + // find out what the destination directory is. Append packageName to dest dir. + File destDir; + + // this is not the default the jflex logic, but javac-like + if (destinationDir != null) { + if (packageName == null) { + destDir = destinationDir; + } + else { + String path = packageName.replace('.', File.separatorChar); + destDir = new File(destinationDir,path); + } + } else { //save parser to the same dir as .flex + destDir = new File(inputFile.getParent()); + } + + setOutdir(destDir); + } + + /** + * @return package name of input file + * + * @see JFlexTask.findPackageAndClass + */ + public String getPackage() { + return packageName; + } + + /** + * @return class name of input file + * + * @see JFlexTask.findPackageAndClass + */ + public String getClassName() { + return className; + } + + public void setDestdir(File destinationDir) { + this.destinationDir = destinationDir; + } + + public void setOutdir(File outDir) { + this.outputDir = outDir; + Options.setDir(outputDir); + } + + public void setFile(File file) { + this.inputFile = file; + } + + public void setGenerateDot(boolean genDot) { + setDot(genDot); + } + + public void setTimeStatistics(boolean displayTime) { + Options.time = displayTime; + } + + public void setTime(boolean displayTime) { + setTimeStatistics(displayTime); + } + + public void setVerbose(boolean verbose) { + Options.verbose = verbose; + } + + public void setSkeleton(File skeleton) { + Options.setSkeleton(skeleton); + } + + public void setSkel(File skeleton) { + setSkeleton(skeleton); + } + + public void setSkipMinimization(boolean skipMin) { + setNomin(skipMin); + } + + public void setNomin(boolean b) { + Options.no_minimize = b; + } + + public void setNobak(boolean b) { + Options.no_backup = b; + } + + public void setSwitch(boolean b) { + if (b) { + Options.gen_method = Options.SWITCH; + } + else { + Options.gen_method = Options.PACK; + } + } + + public void setTable(boolean b) { + if (b) { + Options.gen_method = Options.TABLE; + } + else { + Options.gen_method = Options.PACK; + } + } + + public void setPack(boolean b) { + if (b) { + Options.gen_method = Options.PACK; + } + else { + Options.gen_method = Options.SWITCH; + } + } + + public void setDot(boolean b) { + Options.dot = b; + } + + public void setDump(boolean b) { + Options.dump = b; + } + + public void setJLex(boolean b) { + Options.jlex = b; + } + + public void setCharAt(boolean b) { + Options.char_at = b; + } +} diff --git a/tools/lexer/jflex-1.4/src/JFlex/gui/GeneratorThread.java b/tools/lexer/jflex-1.4/src/JFlex/gui/GeneratorThread.java new file mode 100644 index 000000000000..40f0fb3a13a5 --- /dev/null +++ b/tools/lexer/jflex-1.4/src/JFlex/gui/GeneratorThread.java @@ -0,0 +1,93 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * JFlex 1.4.1 * + * Copyright (C) 1998-2004 Gerwin Klein * + * All rights reserved. * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License. See the file * + * COPYRIGHT for more information. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License along * + * with this program; if not, write to the Free Software Foundation, Inc., * + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +package JFlex.gui; + +import JFlex.*; + +import java.io.File; + + +/** + * Low priority thread for code generation (low priority + * that gui has time for screen updates) + * + * @author Gerwin Klein + * @version JFlex 1.4.1, $Revision: 2.6 $, $Date: 2004/11/06 23:03:33 $ + */ +public class GeneratorThread extends Thread { + + /** there must be at most one instance of this Thread running */ + private static volatile boolean running = false; + + /** input file setting from GUI */ + String inputFile; + + /** output directory */ + String outputDir; + + /** main UI component, likes to be notified when generator finishes */ + MainFrame parent; + + /** + * Create a new GeneratorThread, but do not run it yet. + * + * @param parent the frame, main UI component + * @param inputFile input file from UI settings + * @param messages where generator messages should appear + * @param outputDir output directory from UI settings + */ + public GeneratorThread(MainFrame parent, String inputFile, + String outputDir) { + this.parent = parent; + this.inputFile = inputFile; + this.outputDir = outputDir; + } + + + /** + * Run the generator thread. Only one instance of it can run at any time. + */ + public void run() { + if (running) { + Out.error(ErrorMessages.ALREADY_RUNNING); + parent.generationFinished(false); + } + else { + running = true; + setPriority(MIN_PRIORITY); + try { + if (!outputDir.equals("")) { + Options.setDir(outputDir); + } + Main.generate(new File(inputFile)); + Out.statistics(); + parent.generationFinished(true); + } + catch (GeneratorException e) { + Out.statistics(); + parent.generationFinished(false); + } + finally { + running = false; + } + } + } +} diff --git a/tools/lexer/jflex-1.4/src/JFlex/gui/GridPanel.java b/tools/lexer/jflex-1.4/src/JFlex/gui/GridPanel.java new file mode 100644 index 000000000000..e18a6320a670 --- /dev/null +++ b/tools/lexer/jflex-1.4/src/JFlex/gui/GridPanel.java @@ -0,0 +1,161 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * JFlex 1.4.1 * + * Copyright (C) 1998-2004 Gerwin Klein * + * All rights reserved. * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License. See the file * + * COPYRIGHT for more information. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License along * + * with this program; if not, write to the Free Software Foundation, Inc., * + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +package JFlex.gui; + +import java.awt.*; +import java.util.Vector; + +/** + * Grid layout manager like GridLayout but with predefinable + * grid size. + * + * @author Gerwin Klein + * @version JFlex 1.4.1, $Revision: 2.2 $, $Date: 2004/11/06 23:03:33 $ + */ +public class GridPanel extends Panel implements Handles { + + private int cols; + private int rows; + + private int hgap; + private int vgap; + + private Vector constraints = new Vector(); + private Insets insets = new Insets(0,0,0,0); + + public GridPanel(int cols, int rows) { + this(cols, rows, 0, 0); + } + + public GridPanel(int cols, int rows, int hgap, int vgap) { + this.cols = cols; + this.rows = rows; + this.hgap = hgap; + this.vgap = vgap; + } + + public void doLayout() { + Dimension size = getSize(); + size.height -= insets.top+insets.bottom; + size.width -= insets.left+insets.right; + + float cellWidth = size.width/cols; + float cellHeight = size.height/rows; + + for (int i = 0; i < constraints.size(); i++) { + GridPanelConstraint c = (GridPanelConstraint) constraints.elementAt(i); + + float x = cellWidth * c.x + insets.left + hgap/2; + float y = cellHeight * c.y + insets.right + vgap/2; + + float width, height; + + if (c.handle == FILL) { + width = (cellWidth-hgap) * c.width; + height = (cellHeight-vgap) * c.height; + } + else { + Dimension d = c.component.getPreferredSize(); + width = d.width; + height = d.height; + } + + switch (c.handle) { + case TOP_CENTER: + x+= (cellWidth+width)/2; + break; + case TOP_RIGHT: + x+= cellWidth-width; + break; + case CENTER_LEFT: + y+= (cellHeight+height)/2; + break; + case CENTER: + x+= (cellWidth+width)/2; + y+= (cellHeight+height)/2; + break; + case CENTER_RIGHT: + y+= (cellHeight+height)/2; + x+= cellWidth-width; + break; + case BOTTOM: + y+= cellHeight-height; + break; + case BOTTOM_CENTER: + x+= (cellWidth+width)/2; + y+= cellHeight-height; + break; + case BOTTOM_RIGHT: + y+= cellHeight-height; + x+= cellWidth-width; + break; + } + + c.component.setBounds(new Rectangle((int)x, (int)y, (int)width, (int)height)); + } + } + + public Dimension getPreferredSize() { + float dy = 0; + float dx = 0; + + for (int i = 0; i < constraints.size(); i++) { + GridPanelConstraint c = (GridPanelConstraint) constraints.elementAt(i); + + Dimension d = c.component.getPreferredSize(); + + dx = Math.max(dx, d.width/c.width); + dy = Math.max(dy, d.height/c.height); + } + + dx+= hgap; + dy+= vgap; + + dx*= cols; + dy*= rows; + + dx+= insets.left+insets.right; + dy+= insets.top+insets.bottom; + + return new Dimension((int)dx,(int)dy); + } + + public void setInsets(Insets insets) { + this.insets = insets; + } + + public void add(int x, int y, Component c) { + add(x,y,1,1,FILL,c); + } + + public void add(int x, int y, int handle, Component c) { + add(x,y,1,1,handle,c); + } + + public void add(int x, int y, int dx, int dy, Component c) { + add(x,y,dx,dy,FILL,c); + } + + public void add(int x, int y, int dx, int dy, int handle, Component c) { + super.add(c); + constraints.addElement(new GridPanelConstraint(x,y,dx,dy,handle,c)); + } +} diff --git a/tools/lexer/jflex-1.4/src/JFlex/gui/GridPanelConstraint.java b/tools/lexer/jflex-1.4/src/JFlex/gui/GridPanelConstraint.java new file mode 100644 index 000000000000..2bbcba719771 --- /dev/null +++ b/tools/lexer/jflex-1.4/src/JFlex/gui/GridPanelConstraint.java @@ -0,0 +1,44 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * JFlex 1.4.1 * + * Copyright (C) 1998-2004 Gerwin Klein * + * All rights reserved. * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License. See the file * + * COPYRIGHT for more information. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License along * + * with this program; if not, write to the Free Software Foundation, Inc., * + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ +package JFlex.gui; + +import java.awt.*; + +/** + * Constraints for layout elements of GridLayout + * + * @author Gerwin Klein + * @version JFlex 1.4.1, $Revision: 2.2 $, $Date: 2004/11/06 23:03:33 $ + */ +public class GridPanelConstraint { + + int x, y, width, height, handle; + Component component; + + public GridPanelConstraint(int x, int y, int width, int height, + int handle, Component component) { + this.x = x; + this.y = y; + this.width = width; + this.height = height; + this.handle = handle; + this.component = component; + } +} diff --git a/tools/lexer/jflex-1.4/src/JFlex/gui/Handles.java b/tools/lexer/jflex-1.4/src/JFlex/gui/Handles.java new file mode 100644 index 000000000000..46cddc1c7205 --- /dev/null +++ b/tools/lexer/jflex-1.4/src/JFlex/gui/Handles.java @@ -0,0 +1,49 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * JFlex 1.4.1 * + * Copyright (C) 1998-2004 Gerwin Klein * + * All rights reserved. * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License. See the file * + * COPYRIGHT for more information. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License along * + * with this program; if not, write to the Free Software Foundation, Inc., * + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +package JFlex.gui; + +/** + * Constants used for GridLayout + * + * @author Gerwin Klein + * @version JFlex 1.4.1, $Revision: 2.2 $, $Date: 2004/11/06 23:03:33 $ + */ +public interface Handles { + + int FILL = 0; + + int TOP = 1; + int TOP_LEFT = TOP; + int TOP_CENTER = 2; + int TOP_RIGHT = 3; + + int CENTER_LEFT = 4; + int CENTER = 5; + int CENTER_CENTER = CENTER; + int CENTER_RIGHT = 6; + + int BOTTOM = 7; + int BOTTOM_LEFT = BOTTOM; + int BOTTOM_CENTER = 8; + int BOTTOM_RIGHT = 9; + +} + diff --git a/tools/lexer/jflex-1.4/src/JFlex/gui/MainFrame.java b/tools/lexer/jflex-1.4/src/JFlex/gui/MainFrame.java new file mode 100644 index 000000000000..31be4d10d06d --- /dev/null +++ b/tools/lexer/jflex-1.4/src/JFlex/gui/MainFrame.java @@ -0,0 +1,275 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * JFlex 1.4.1 * + * Copyright (C) 1998-2004 Gerwin Klein * + * All rights reserved. * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License. See the file * + * COPYRIGHT for more information. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License along * + * with this program; if not, write to the Free Software Foundation, Inc., * + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +package JFlex.gui; + +import JFlex.Main; +import JFlex.Out; + +import java.awt.*; +import java.awt.event.*; +import java.io.File; + +/** + * JFlex main application frame (GUI mode only) + * + * @author Gerwin Klein + * @version JFlex 1.4.1, $Revision: 2.7 $, $Date: 2004/11/06 23:03:33 $ + */ +final public class MainFrame extends Frame implements Handles { + + private volatile boolean choosing; + + private String fileName = ""; + private String dirName = ""; + + private Button quit; + private Button options; + private Button generate; + private Button stop; + private Button specChoose; + private Button dirChoose; + + private TextField spec; + private TextField dir; + + private TextArea messages; + + private GeneratorThread thread; + + private OptionsDialog dialog; + + + public MainFrame() { + super("JFlex "+Main.version); + buildContent(); + + addWindowListener( new WindowAdapter() { + public void windowClosing(WindowEvent e) { + quit(); + } + }); + + pack(); + show(); + } + + + private void buildContent() { + setBackground(SystemColor.control); + + generate = new Button("Generate"); + quit = new Button("Quit"); + options = new Button("Options"); + stop = new Button("Stop"); + dirChoose = new Button("Browse"); + dir = new TextField(10); + specChoose = new Button("Browse"); + spec = new TextField(10); + messages = new TextArea(10,80); + + messages.setEditable(false); + Font font = messages.getFont(); + if (font != null) + messages.setFont(new Font("Monospaced", font.getStyle(), font.getSize())); + else + messages.setFont(new Font("Monospaced", Font.PLAIN, 12)); + + Out.setGUIMode(messages); + + generate.addActionListener( new ActionListener() { + public void actionPerformed(ActionEvent e) { + generate(); + } + } ); + + options.addActionListener( new ActionListener() { + public void actionPerformed(ActionEvent e) { + showOptions(); + } + } ); + + quit.addActionListener( new ActionListener() { + public void actionPerformed(ActionEvent e) { + quit(); + } + } ); + + stop.addActionListener( new ActionListener() { + public void actionPerformed(ActionEvent e) { + stop(); + } + } ); + + specChoose.addActionListener( new ActionListener() { + public void actionPerformed(ActionEvent e) { + specChoose(); + } + } ); + + dirChoose.addActionListener( new ActionListener() { + public void actionPerformed(ActionEvent e) { + dirChoose(); + } + } ); + + spec.addActionListener( new ActionListener() { + public void actionPerformed(ActionEvent e) { + fileName = spec.getText(); + generate(); + } + } ); + + spec.addTextListener( new TextListener() { + public void textValueChanged(TextEvent e) { + fileName = spec.getText(); + } + } ); + + dir.addActionListener( new ActionListener() { + public void actionPerformed(ActionEvent e) { + dirName = dir.getText(); + generate(); + } + } ); + + dir.addTextListener( new TextListener() { + public void textValueChanged(TextEvent e) { + dirName = dir.getText(); + } + } ); + + GridPanel north = new GridPanel(5,4,10,10); + north.setInsets( new Insets(10,5,5,10) ); + + north.add( 4,0, quit); + north.add( 4,1, generate); + north.add( 4,2, options); + north.add( 4,3, stop); + + north.add( 0,0, BOTTOM, new Label("Lexical specification:")); + north.add( 0,1, 2,1, spec); + north.add( 2,1, specChoose); + + north.add( 0,2, BOTTOM, new Label("Output directory:")); + north.add( 0,3, 2,1, dir); + north.add( 2,3, dirChoose); + + Panel center = new Panel(new BorderLayout()); + center.add("North", new Label("Messages:")); + center.add("Center", messages); + + add("North", north); + add("Center", center); + + setEnabledAll(false); + } + + protected void showOptions() { + if (dialog == null) { + dialog = new OptionsDialog(this); + } + dialog.show(); + } + + + public Dimension getPreferredSize() { + Dimension d = super.getPreferredSize(); + d.width = messages.getPreferredSize().width; + return d; + } + + private void setEnabledAll(boolean generating) { + stop.setEnabled( generating ); + quit.setEnabled( !generating ); + generate.setEnabled( !generating ); + dirChoose.setEnabled( !generating ); + dir.setEnabled( !generating ); + specChoose.setEnabled( !generating ); + spec.setEnabled( !generating ); + } + + private void generate() { + // workaround for a weird AWT bug + if (choosing) return; + + setEnabledAll(true); + + thread = new GeneratorThread(this, fileName, dirName); + thread.start(); + } + + public void generationFinished(boolean success) { + setEnabledAll(false); + + if (success) + messages.append(Out.NL+"Generation finished successfully."+Out.NL); + else + messages.append(Out.NL+"Generation aborted."+Out.NL); + } + + private void stop() { + if (thread != null) { + /* stop ok here despite deprecation (?) + I don't know any good way to abort generation without changing the + generator code */ + thread.stop(); + thread = null; + } + generationFinished(false); + } + + private void quit() { + setVisible(false); + System.exit(0); + } + + private void dirChoose() { + choosing = true; + + FileDialog d = new FileDialog(this, "Choose directory", FileDialog.LOAD); + + d.show(); + + if (d.getDirectory() != null) { + dir.setText( (new File(d.getDirectory())).getAbsolutePath() ); + } + + choosing = false; + } + + private void specChoose() { + choosing = true; + + FileDialog d = new FileDialog(this, "Choose file", FileDialog.LOAD); + + d.setFile("*.flex"); + d.show(); + + if (d.getFile() != null) { + fileName = d.getDirectory()+d.getFile(); + dir.setText(d.getDirectory()); + spec.setText(fileName); + } + + choosing = false; + } + +} diff --git a/tools/lexer/jflex-1.4/src/JFlex/gui/OptionsDialog.java b/tools/lexer/jflex-1.4/src/JFlex/gui/OptionsDialog.java new file mode 100644 index 000000000000..5338f7c5a8b7 --- /dev/null +++ b/tools/lexer/jflex-1.4/src/JFlex/gui/OptionsDialog.java @@ -0,0 +1,258 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * JFlex 1.4.1 * + * Copyright (C) 1998-2004 Gerwin Klein * + * All rights reserved. * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License. See the file * + * COPYRIGHT for more information. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License along * + * with this program; if not, write to the Free Software Foundation, Inc., * + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +package JFlex.gui; + +import JFlex.GeneratorException; +import JFlex.Options; +import JFlex.Skeleton; + +import java.awt.*; +import java.awt.event.*; +import java.io.File; + +/** + * A dialog for setting JFlex options + * + * @author Gerwin Klein + * @version $Revision: 1.7 $, $Date: 2004/11/06 23:03:33 $ + */ +public class OptionsDialog extends Dialog { + + private Frame owner; + + private Button skelBrowse; + private TextField skelFile; + + private Button ok; + private Button defaults; + + private Checkbox dump; + private Checkbox verbose; + private Checkbox jlex; + private Checkbox no_minimize; + private Checkbox no_backup; + private Checkbox time; + private Checkbox dot; + + private Checkbox tableG; + private Checkbox switchG; + private Checkbox packG; + + + /** + * Create a new options dialog + * + * @param owner + */ + public OptionsDialog(Frame owner) { + super(owner, "Options"); + + this.owner = owner; + + setup(); + pack(); + + addWindowListener( new WindowAdapter() { + public void windowClosing(WindowEvent e) { + close(); + } + }); + } + + public void setup() { + // create components + ok = new Button("Ok"); + defaults = new Button("Defaults"); + skelBrowse = new Button(" Browse"); + skelFile = new TextField(); + skelFile.setEditable(false); + dump = new Checkbox(" dump"); + verbose = new Checkbox(" verbose"); + + jlex = new Checkbox(" JLex compatibility"); + no_minimize = new Checkbox(" skip minimization"); + no_backup = new Checkbox(" no backup file"); + time = new Checkbox(" time statistics"); + dot = new Checkbox(" dot graph files"); + + CheckboxGroup codeG = new CheckboxGroup(); + tableG = new Checkbox(" table",Options.gen_method == Options.TABLE, codeG); + switchG = new Checkbox(" switch",Options.gen_method == Options.SWITCH, codeG); + packG = new Checkbox(" pack",Options.gen_method == Options.PACK, codeG); + + // setup interaction + ok.addActionListener( new ActionListener() { + public void actionPerformed(ActionEvent e) { + close(); + } + } ); + + defaults.addActionListener( new ActionListener() { + public void actionPerformed(ActionEvent e) { + setDefaults(); + } + } ); + + skelBrowse.addActionListener( new ActionListener() { + public void actionPerformed(ActionEvent e) { + skelBrowse(); + } + } ); + + tableG.addItemListener( new ItemListener() { + public void itemStateChanged(ItemEvent e) { + setGenMethod(); + } + } ); + + verbose.addItemListener( new ItemListener() { + public void itemStateChanged(ItemEvent e) { + Options.verbose = verbose.getState(); + } + } ); + + dump.addItemListener( new ItemListener() { + public void itemStateChanged(ItemEvent e) { + Options.dump = dump.getState(); + } + } ); + + jlex.addItemListener( new ItemListener() { + public void itemStateChanged(ItemEvent e) { + Options.jlex = jlex.getState(); + } + } ); + + no_minimize.addItemListener( new ItemListener() { + public void itemStateChanged(ItemEvent e) { + Options.no_minimize = no_minimize.getState(); + } + } ); + + no_backup.addItemListener( new ItemListener() { + public void itemStateChanged(ItemEvent e) { + Options.no_backup = no_backup.getState(); + } + } ); + + dot.addItemListener( new ItemListener() { + public void itemStateChanged(ItemEvent e) { + Options.dot = dot.getState(); + } + } ); + + time.addItemListener( new ItemListener() { + public void itemStateChanged(ItemEvent e) { + Options.time = time.getState(); + } + } ); + + // setup layout + GridPanel panel = new GridPanel(4,7,10,10); + panel.setInsets( new Insets(10,5,5,10) ); + + panel.add(3,0,ok); + panel.add(3,1,defaults); + + panel.add(0,0,2,1,Handles.BOTTOM,new Label("skeleton file:")); + panel.add(0,1,2,1,skelFile); + panel.add(2,1,1,1,Handles.TOP, skelBrowse); + + panel.add(0,2,1,1,Handles.BOTTOM,new Label("code:")); + panel.add(0,3,1,1,tableG); + panel.add(0,4,1,1,switchG); + panel.add(0,5,1,1,packG); + + panel.add(1,3,1,1,dump); + panel.add(1,4,1,1,verbose); + panel.add(1,5,1,1,time); + + + panel.add(2,3,1,1,no_minimize); + panel.add(2,4,1,1,no_backup); + + panel.add(3,3,1,1,jlex); + panel.add(3,4,1,1,dot); + + add("Center",panel); + + updateState(); + } + + private void skelBrowse() { + FileDialog d = new FileDialog(owner , "Choose file", FileDialog.LOAD); + d.show(); + + if (d.getFile() != null) { + File skel = new File(d.getDirectory()+d.getFile()); + try { + Skeleton.readSkelFile(skel); + skelFile.setText(skel.toString()); + } + catch (GeneratorException e) { + // do nothing + } + } + } + + private void setGenMethod() { + if ( tableG.getState() ) { + Options.gen_method = Options.TABLE; + return; + } + + if ( switchG.getState() ) { + Options.gen_method = Options.SWITCH; + return; + } + + if ( packG.getState() ) { + Options.gen_method = Options.PACK; + return; + } + } + + private void updateState() { + dump.setState(Options.dump); + verbose.setState(Options.verbose); + jlex.setState(Options.jlex); + no_minimize.setState(Options.no_minimize); + no_backup.setState(Options.no_backup); + time.setState(Options.time); + dot.setState(Options.dot); + + tableG.setState(Options.gen_method == Options.TABLE); + switchG.setState(Options.gen_method == Options.SWITCH); + packG.setState(Options.gen_method == Options.PACK); + } + + private void setDefaults() { + Options.setDefaults(); + Skeleton.readDefault(); + skelFile.setText(""); + updateState(); + } + + public void close() { + hide(); + } + +} diff --git a/tools/lexer/jflex-1.4/src/JFlex/skeleton.default b/tools/lexer/jflex-1.4/src/JFlex/skeleton.default new file mode 100644 index 000000000000..c2a807820775 --- /dev/null +++ b/tools/lexer/jflex-1.4/src/JFlex/skeleton.default @@ -0,0 +1,317 @@ + + /** This character denotes the end of file */ + public static final int YYEOF = -1; + + /** initial size of the lookahead buffer */ +--- private static final int ZZ_BUFFERSIZE = ...; + + /** lexical states */ +--- lexical states, charmap + + /* error codes */ + private static final int ZZ_UNKNOWN_ERROR = 0; + private static final int ZZ_NO_MATCH = 1; + private static final int ZZ_PUSHBACK_2BIG = 2; + + /* error messages for the codes above */ + private static final String ZZ_ERROR_MSG[] = { + "Unkown internal scanner error", + "Error: could not match input", + "Error: pushback value was too large" + }; + +--- isFinal list + /** the input device */ + private java.io.Reader zzReader; + + /** the current state of the DFA */ + private int zzState; + + /** the current lexical state */ + private int zzLexicalState = YYINITIAL; + + /** this buffer contains the current text to be matched and is + the source of the yytext() string */ + private char zzBuffer[] = new char[ZZ_BUFFERSIZE]; + + /** the textposition at the last accepting state */ + private int zzMarkedPos; + + /** the textposition at the last state to be included in yytext */ + private int zzPushbackPos; + + /** the current text position in the buffer */ + private int zzCurrentPos; + + /** startRead marks the beginning of the yytext() string in the buffer */ + private int zzStartRead; + + /** endRead marks the last character in the buffer, that has been read + from input */ + private int zzEndRead; + + /** number of newlines encountered up to the start of the matched text */ + private int yyline; + + /** the number of characters up to the start of the matched text */ + private int yychar; + + /** + * the number of characters from the last newline up to the start of the + * matched text + */ + private int yycolumn; + + /** + * zzAtBOL == true <=> the scanner is currently at the beginning of a line + */ + private boolean zzAtBOL = true; + + /** zzAtEOF == true <=> the scanner is at the EOF */ + private boolean zzAtEOF; + +--- user class code + + /** + * Creates a new scanner + * There is also a java.io.InputStream version of this constructor. + * + * @param in the java.io.Reader to read input from. + */ +--- constructor declaration + + + /** + * Refills the input buffer. + * + * @return false, iff there was new input. + * + * @exception java.io.IOException if any I/O-Error occurs + */ + private boolean zzRefill() throws java.io.IOException { + + /* first: make room (if you can) */ + if (zzStartRead > 0) { + System.arraycopy(zzBuffer, zzStartRead, + zzBuffer, 0, + zzEndRead-zzStartRead); + + /* translate stored positions */ + zzEndRead-= zzStartRead; + zzCurrentPos-= zzStartRead; + zzMarkedPos-= zzStartRead; + zzPushbackPos-= zzStartRead; + zzStartRead = 0; + } + + /* is the buffer big enough? */ + if (zzCurrentPos >= zzBuffer.length) { + /* if not: blow it up */ + char newBuffer[] = new char[zzCurrentPos*2]; + System.arraycopy(zzBuffer, 0, newBuffer, 0, zzBuffer.length); + zzBuffer = newBuffer; + } + + /* finally: fill the buffer with new input */ + int numRead = zzReader.read(zzBuffer, zzEndRead, + zzBuffer.length-zzEndRead); + + if (numRead < 0) { + return true; + } + else { + zzEndRead+= numRead; + return false; + } + } + + + /** + * Closes the input stream. + */ + public final void yyclose() throws java.io.IOException { + zzAtEOF = true; /* indicate end of file */ + zzEndRead = zzStartRead; /* invalidate buffer */ + + if (zzReader != null) + zzReader.close(); + } + + + /** + * Resets the scanner to read from a new input stream. + * Does not close the old reader. + * + * All internal variables are reset, the old input stream + * cannot be reused (internal buffer is discarded and lost). + * Lexical state is set to ZZ_INITIAL. + * + * @param reader the new input stream + */ + public final void yyreset(java.io.Reader reader) { + zzReader = reader; + zzAtBOL = true; + zzAtEOF = false; + zzEndRead = zzStartRead = 0; + zzCurrentPos = zzMarkedPos = zzPushbackPos = 0; + yyline = yychar = yycolumn = 0; + zzLexicalState = YYINITIAL; + } + + + /** + * Returns the current lexical state. + */ + public final int yystate() { + return zzLexicalState; + } + + + /** + * Enters a new lexical state + * + * @param newState the new lexical state + */ + public final void yybegin(int newState) { + zzLexicalState = newState; + } + + + /** + * Returns the text matched by the current regular expression. + */ + public final String yytext() { + return new String( zzBuffer, zzStartRead, zzMarkedPos-zzStartRead ); + } + + + /** + * Returns the character at position pos from the + * matched text. + * + * It is equivalent to yytext().charAt(pos), but faster + * + * @param pos the position of the character to fetch. + * A value from 0 to yylength()-1. + * + * @return the character at position pos + */ + public final char yycharat(int pos) { + return zzBuffer[zzStartRead+pos]; + } + + + /** + * Returns the length of the matched text region. + */ + public final int yylength() { + return zzMarkedPos-zzStartRead; + } + + + /** + * Reports an error that occured while scanning. + * + * In a wellformed scanner (no or only correct usage of + * yypushback(int) and a match-all fallback rule) this method + * will only be called with things that "Can't Possibly Happen". + * If this method is called, something is seriously wrong + * (e.g. a JFlex bug producing a faulty scanner etc.). + * + * Usual syntax/scanner level error handling should be done + * in error fallback rules. + * + * @param errorCode the code of the errormessage to display + */ +--- zzScanError declaration + String message; + try { + message = ZZ_ERROR_MSG[errorCode]; + } + catch (ArrayIndexOutOfBoundsException e) { + message = ZZ_ERROR_MSG[ZZ_UNKNOWN_ERROR]; + } + +--- throws clause + } + + + /** + * Pushes the specified amount of characters back into the input stream. + * + * They will be read again by then next call of the scanning method + * + * @param number the number of characters to be read again. + * This number must not be greater than yylength()! + */ +--- yypushback decl (contains zzScanError exception) + if ( number > yylength() ) + zzScanError(ZZ_PUSHBACK_2BIG); + + zzMarkedPos -= number; + } + + +--- zzDoEOF + /** + * Resumes scanning until the next regular expression is matched, + * the end of input is encountered or an I/O-Error occurs. + * + * @return the next token + * @exception java.io.IOException if any I/O-Error occurs + */ +--- yylex declaration + int zzInput; + int zzAction; + + // cached fields: + int zzCurrentPosL; + int zzMarkedPosL; + int zzEndReadL = zzEndRead; + char [] zzBufferL = zzBuffer; + char [] zzCMapL = ZZ_CMAP; + +--- local declarations + + while (true) { + zzMarkedPosL = zzMarkedPos; + +--- start admin (line, char, col count) + zzAction = -1; + + zzCurrentPosL = zzCurrentPos = zzStartRead = zzMarkedPosL; + +--- start admin (lexstate etc) + + zzForAction: { + while (true) { + +--- next input, line, col, char count, next transition, isFinal action + zzAction = zzState; + zzMarkedPosL = zzCurrentPosL; +--- line count update + } + + } + } + + // store back cached position + zzMarkedPos = zzMarkedPosL; +--- char count update + +--- actions + default: + if (zzInput == YYEOF && zzStartRead == zzCurrentPos) { + zzAtEOF = true; +--- eofvalue + } + else { +--- no match + } + } + } + } + +--- main + +} diff --git a/tools/lexer/jflex-1.4/src/JFlex/sym.java b/tools/lexer/jflex-1.4/src/JFlex/sym.java new file mode 100644 index 000000000000..f53d732ba5b6 --- /dev/null +++ b/tools/lexer/jflex-1.4/src/JFlex/sym.java @@ -0,0 +1,60 @@ + +//---------------------------------------------------- +// The following code was generated by CUP v0.10k +// Sun Nov 07 14:07:52 GMT+10:00 2004 +//---------------------------------------------------- + +package JFlex; + +/** CUP generated interface containing symbol constants. */ +public interface sym { + /* terminals */ + public static final int DELIMITER = 9; + public static final int EOFRULE = 25; + public static final int STRING_I = 45; + public static final int CHAR = 39; + public static final int CONCAT = 44; + public static final int MACROUSE = 41; + public static final int LOWERCLASS = 24; + public static final int EQUALS = 10; + public static final int CCLASSNOT = 43; + public static final int REPEAT = 31; + public static final int TILDE = 38; + public static final int CHAR_I = 46; + public static final int STAR = 32; + public static final int BAR = 34; + public static final int FULL = 16; + public static final int LOOKAHEAD = 27; + public static final int LESSTHAN = 12; + public static final int BANG = 37; + public static final int COMMA = 11; + public static final int JLETTERDIGITCLASS = 20; + public static final int PLUS = 33; + public static final int USERCODE = 30; + public static final int EOF = 0; + public static final int error = 1; + public static final int DASH = 8; + public static final int CLOSEBRACKET = 3; + public static final int HAT = 4; + public static final int JLETTERCLASS = 19; + public static final int IDENT = 29; + public static final int ACTION = 28; + public static final int CLOSECLASS = 7; + public static final int DIGITCLASS = 22; + public static final int LBRACE = 14; + public static final int REGEXPEND = 18; + public static final int OPENCLASS = 6; + public static final int OPENBRACKET = 2; + public static final int POINT = 36; + public static final int LETTERCLASS = 21; + public static final int MORETHAN = 13; + public static final int DOLLAR = 5; + public static final int RBRACE = 15; + public static final int STRING = 40; + public static final int QUESTION = 35; + public static final int UPPERCLASS = 23; + public static final int NOACTION = 26; + public static final int CCLASS = 42; + public static final int UNICODE = 17; +} + diff --git a/tools/lexer/jflex-1.4/src/JFlex/tests/AllTests.java b/tools/lexer/jflex-1.4/src/JFlex/tests/AllTests.java new file mode 100644 index 000000000000..4d765234916f --- /dev/null +++ b/tools/lexer/jflex-1.4/src/JFlex/tests/AllTests.java @@ -0,0 +1,50 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * jflex * + * Copyright (C) 1998-2004 Gerwin Klein * + * All rights reserved. * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License. See the file * + * COPYRIGHT for more information. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License along * + * with this program; if not, write to the Free Software Foundation, Inc., * + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +package JFlex.tests; + +import junit.framework.Test; +import junit.framework.TestSuite; + +/** + * AllTests + * + * @author Gerwin Klein + * @version $Revision: 1.4 $, $Date: 2004/04/12 10:07:48 $ + */ +public class AllTests { + + public static void main(String[] args) { + junit.textui.TestRunner.run(AllTests.class); + } + + public static Test suite() { + TestSuite suite = new TestSuite("JFlex tests"); + //$JUnit-BEGIN$ + suite.addTest(new TestSuite(AntTaskTests.class)); + suite.addTest(new TestSuite(CharClassesTest.class)); + suite.addTest(new TestSuite(EmitterTest.class)); + suite.addTest(new TestSuite(RegExpTests.class)); + suite.addTest(new TestSuite(SkeletonTest.class)); + suite.addTest(new TestSuite(PackEmitterTest.class)); + //$JUnit-END$ + return suite; + } +} diff --git a/tools/lexer/jflex-1.4/src/JFlex/tests/AntTaskTests.java b/tools/lexer/jflex-1.4/src/JFlex/tests/AntTaskTests.java new file mode 100644 index 000000000000..0be2cd20891f --- /dev/null +++ b/tools/lexer/jflex-1.4/src/JFlex/tests/AntTaskTests.java @@ -0,0 +1,166 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * JFlex 1.4.1 * + * Copyright (C) 1998-2004 Gerwin Klein * + * All rights reserved. * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License. See the file * + * COPYRIGHT for more information. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License along * + * with this program; if not, write to the Free Software Foundation, Inc., * + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ +package JFlex.tests; + +import JFlex.Options; +import JFlex.anttask.JFlexTask; +import junit.framework.TestCase; + +import java.io.File; +import java.io.IOException; + +/** + * Unit tests for the jflex ant task. + * + * @author Gerwin Klein + * @version $Revision: 1.12 $, $Date: 2004/11/06 23:03:30 $ + */ +public class AntTaskTests extends TestCase { + + private JFlexTask task; + + /** + * Constructor for AntTaskTests. + * + * @param name test case name + */ + public AntTaskTests(String name) { + super(name); + } + + /* + * @see TestCase#setUp() + */ + protected void setUp() throws Exception { + super.setUp(); + Options.setDefaults(); + task = new JFlexTask(); + } + + public void testPackageAndClass() throws IOException { + task.setFile(new File("src/JFlex/LexScan.flex")); + task.findPackageAndClass(); + assertEquals(task.getPackage(), "JFlex"); + assertEquals(task.getClassName(), "LexScan"); + } + + public void testPackageAndClassDefaults() throws IOException { + task.setFile(new File("examples/simple/simple.flex")); + task.findPackageAndClass(); + assertEquals(task.getPackage(), null); + assertEquals(task.getClassName(), "Yylex"); + } + + public void testDestdir() throws IOException { + task.setFile(new File("src/JFlex/LexScan.flex")); + File dir = new File("src"); + task.setDestdir(dir); + task.findPackageAndClass(); + task.normalizeOutdir(); + // not default jflex logic, but javac (uses package name) + assertEquals(Options.getDir(), new File(dir, "JFlex")); + } + + public void testOutdir() throws IOException { + task.setFile(new File("src/JFlex/LexScan.flex")); + File dir = new File("src"); + task.setOutdir(dir); + task.findPackageAndClass(); + task.normalizeOutdir(); + // this should be default jflex logic + assertEquals(Options.getDir(), dir); + } + + public void testDefaultDir() throws IOException { + task.setFile(new File("src/JFlex/LexScan.flex")); + task.findPackageAndClass(); + task.normalizeOutdir(); + // this should be default jflex logic + assertEquals(Options.getDir(), new File("src/JFlex")); + } + + public void testNomin() { + assertTrue(!Options.no_minimize); + task.setNomin(true); + assertTrue(Options.no_minimize); + } + + public void testSkipMinimization() { + assertTrue(!Options.no_minimize); + task.setSkipMinimization(true); + assertTrue(Options.no_minimize); + } + + public void testNobak() { + assertTrue(!Options.no_backup); + task.setNobak(true); + assertTrue(Options.no_backup); + } + + public void testCodeGen() { + task.setSwitch(true); + assertEquals(Options.gen_method, Options.SWITCH); + task.setTable(true); + assertEquals(Options.gen_method, Options.TABLE); + task.setPack(true); + assertEquals(Options.gen_method, Options.PACK); + } + + public void testSkel() { + task.setVerbose(false); // avoid to java console pop up + task.setSkeleton(new File("src/skeleton.nested")); + assertTrue(JFlex.Skeleton.line[3].indexOf("java.util.Stack") > 0); + } + + public void testVerbose() { + task.setVerbose(false); + assertTrue(!Options.verbose); + task.setVerbose(true); + assertTrue(Options.verbose); + } + + public void testTime() { + assertTrue(!Options.time); + task.setTimeStatistics(true); + assertTrue(Options.time); + task.setTime(false); + assertTrue(!Options.time); + } + + public void testDot() { + assertTrue(!Options.dot); + task.setDot(true); + assertTrue(Options.dot); + task.setGenerateDot(false); + assertTrue(!Options.dot); + } + + public void testDump() { + assertTrue(!Options.dump); + task.setDump(true); + assertTrue(Options.dump); + } + + public void testJlex() { + assertTrue(!Options.jlex); + task.setJLex(true); + assertTrue(Options.jlex); + } +} diff --git a/tools/lexer/jflex-1.4/src/JFlex/tests/CharClassesTest.java b/tools/lexer/jflex-1.4/src/JFlex/tests/CharClassesTest.java new file mode 100644 index 000000000000..a3c283d572b2 --- /dev/null +++ b/tools/lexer/jflex-1.4/src/JFlex/tests/CharClassesTest.java @@ -0,0 +1,103 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * JFlex 1.4.1 * + * Copyright (C) 1998-2004 Gerwin Klein * + * All rights reserved. * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License. See the file * + * COPYRIGHT for more information. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License along * + * with this program; if not, write to the Free Software Foundation, Inc., * + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +package JFlex.tests; + +import JFlex.IntCharSet; +import JFlex.Interval; +import junit.framework.TestCase; + +/** + * CharClassesTest + * + * @author Gerwin Klein + * @version $Revision: 1.6 $, $Date: 2004/11/06 23:03:30 $ + */ +public class CharClassesTest extends TestCase { + + /** + * Constructor for CharClassesTest. + * @param arg0 + */ + public CharClassesTest(String arg0) { + super(arg0); + } + + public void testAdd1() { + IntCharSet set = new IntCharSet(new Interval('a','h')); + set.add(new Interval('o','z')); + set.add(new Interval('A','Z')); + set.add(new Interval('h','o')); + assertEquals("{ ['A'-'Z']['a'-'z'] }", set.toString()); + } + + public void testAdd2() { + IntCharSet set = new IntCharSet(new Interval('a','h')); + set.add(new Interval('o','z')); + set.add(new Interval('A','Z')); + set.add(new Interval('i','n')); + assertEquals("{ ['A'-'Z']['a'-'z'] }", set.toString()); + } + + public void testAdd3() { + IntCharSet set = new IntCharSet(new Interval('a','h')); + set.add(new Interval('o','z')); + set.add(new Interval('A','Z')); + set.add(new Interval('a','n')); + assertEquals("{ ['A'-'Z']['a'-'z'] }", set.toString()); + } + + public void testMergeLast() { + IntCharSet set = new IntCharSet(new Interval('a','k')); + assertEquals("{ ['a'-'k'] }", set.toString()); + set.add('l'); + assertEquals("{ ['a'-'l'] }", set.toString()); + } + + public void testAddChar() { + IntCharSet set = new IntCharSet(new Interval('a','h')); + set.add(new Interval('o','z')); + set.add('n'); + set.add('k'); + assertEquals("{ ['a'-'h']['k']['n'-'z'] }", set.toString()); + set.add('i'); + assertEquals("{ ['a'-'i']['k']['n'-'z'] }", set.toString()); + set.add('j'); + assertEquals("{ ['a'-'k']['n'-'z'] }", set.toString()); + set.add(new Interval('l','m')); + assertEquals("{ ['a'-'z'] }", set.toString()); + } + + public void testCopy() { + IntCharSet set = new IntCharSet(new Interval('a','z')); + IntCharSet copy = set.copy(); + Interval i = set.getNext(); + i.end = 'h'; + assertEquals("{ ['a'-'h'] }", set.toString()); + assertEquals("{ ['a'-'z'] }", copy.toString()); + } + + public void testCaseless() { + IntCharSet set = new IntCharSet(new Interval('a','c')); + set.add(new Interval('h','o')); + assertEquals("{ ['A'-'C']['H'-'O']['a'-'c']['h'-'o'] }", + set.getCaseless().toString()); + } +} diff --git a/tools/lexer/jflex-1.4/src/JFlex/tests/EmitterTest.java b/tools/lexer/jflex-1.4/src/JFlex/tests/EmitterTest.java new file mode 100644 index 000000000000..61fe03fb737a --- /dev/null +++ b/tools/lexer/jflex-1.4/src/JFlex/tests/EmitterTest.java @@ -0,0 +1,50 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * JFlex 1.4.1 * + * Copyright (C) 1998-2004 Gerwin Klein * + * All rights reserved. * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License. See the file * + * COPYRIGHT for more information. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License along * + * with this program; if not, write to the Free Software Foundation, Inc., * + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +package JFlex.tests; + +import JFlex.Emitter; +import junit.framework.TestCase; + +/** + * Some unit tests for the jflex Emitter class + * + * @author Gerwin Klein + * @version $Revision: 1.5 $, $Date: 2004/11/06 23:03:30 $ + */ +public class EmitterTest extends TestCase { + + /** + * Constructor for EmitterTest. + * @param name the test name + */ + public EmitterTest(String name) { + super(name); + } + + public void testJavadoc() { + StringBuffer usercode = new StringBuffer("/* some *** comment */"); + assertTrue(!Emitter.endsWithJavadoc(usercode)); + usercode.append("import bla; /** javadoc /* */ "); + assertTrue(Emitter.endsWithJavadoc(usercode)); + usercode.append("bla"); + assertTrue(!Emitter.endsWithJavadoc(usercode)); + } +} diff --git a/tools/lexer/jflex-1.4/src/JFlex/tests/PackEmitterTest.java b/tools/lexer/jflex-1.4/src/JFlex/tests/PackEmitterTest.java new file mode 100644 index 000000000000..9329c7026c84 --- /dev/null +++ b/tools/lexer/jflex-1.4/src/JFlex/tests/PackEmitterTest.java @@ -0,0 +1,80 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * jflex * + * Copyright (C) 1998-2004 Gerwin Klein * + * All rights reserved. * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License. See the file * + * COPYRIGHT for more information. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License along * + * with this program; if not, write to the Free Software Foundation, Inc., * + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +package JFlex.tests; + +import JFlex.Out; +import JFlex.PackEmitter; +import junit.framework.TestCase; + +/** + * PackEmitterTest + * + * @author Gerwin Klein + * @version $Revision: 1.7 $, $Date: 2004/04/12 10:07:48 $ + */ +public class PackEmitterTest extends TestCase { + + private PackEmitter p; + + + /** + * Constructor for PackEmitterTest. + */ + public PackEmitterTest() { + super("PackEmitter test"); + } + + public void setUp() { + p = new PackEmitter("Bla") { + public void emitUnpack() { } + }; + } + + public void testInit() { + p.emitInit(); + assertEquals( + " private static final int [] ZZ_BLA = zzUnpackBla();" + Out.NL + + Out.NL + + " private static final String ZZ_BLA_PACKED_0 =" + Out.NL + + " \"", + p.toString()); + } + + public void testEmitUCplain() { + p.emitUC(8); + p.emitUC(0xFF00); + + assertEquals("\\10\\uff00", p.toString()); + } + + public void testLineBreak() { + for (int i = 0; i < 36; i++) { + p.breaks(); + p.emitUC(i); + } + System.out.println(p); + assertEquals( + "\\0\\1\\2\\3\\4\\5\\6\\7\\10\\11\\12\\13\\14\\15\\16\\17\"+"+Out.NL+ + " \"\\20\\21\\22\\23\\24\\25\\26\\27\\30\\31\\32\\33\\34\\35\\36\\37\"+"+Out.NL+ + " \"\\40\\41\\42\\43", + p.toString()); + } +} diff --git a/tools/lexer/jflex-1.4/src/JFlex/tests/RegExpTests.java b/tools/lexer/jflex-1.4/src/JFlex/tests/RegExpTests.java new file mode 100644 index 000000000000..652b9bfd7d47 --- /dev/null +++ b/tools/lexer/jflex-1.4/src/JFlex/tests/RegExpTests.java @@ -0,0 +1,58 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * JFlex 1.4.1 * + * Copyright (C) 1998-2004 Gerwin Klein * + * All rights reserved. * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License. See the file * + * COPYRIGHT for more information. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License along * + * with this program; if not, write to the Free Software Foundation, Inc., * + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +package JFlex.tests; + +import JFlex.*; +import junit.framework.TestCase; + +/** + * Unit tests for JFlex.RegExp + * + * @author Gerwin Klein + * @version $Revision: 1.5 $, $Date: 2004/11/06 23:03:30 $ + */ +public class RegExpTests extends TestCase implements sym { + + /** + * Constructor for RegExpTests. + * + * @param name the test name + */ + public RegExpTests(String name) { + super(name); + } + + public void testCharClass() { + Macros m = new Macros(); + RegExp e1 = new RegExp1(CCLASS, new Interval('a','z')); + RegExp e2 = new RegExp1(CHAR, new Character('Z')); + RegExp e3 = new RegExp1(CCLASS, new Interval('0','9')); + m.insert("macro", e3); + RegExp s = new RegExp1(STAR, e1); + RegExp u = new RegExp1(MACROUSE, "macro"); + RegExp b = new RegExp2(BAR, e2, u); + assertTrue(e1.isCharClass(m)); + assertTrue(e2.isCharClass(m)); + assertTrue(b.isCharClass(m)); + assertTrue(!s.isCharClass(m)); + assertTrue(u.isCharClass(m)); + } +} diff --git a/tools/lexer/jflex-1.4/src/JFlex/tests/SkeletonTest.java b/tools/lexer/jflex-1.4/src/JFlex/tests/SkeletonTest.java new file mode 100644 index 000000000000..f09837275bf0 --- /dev/null +++ b/tools/lexer/jflex-1.4/src/JFlex/tests/SkeletonTest.java @@ -0,0 +1,63 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * JFlex 1.4.1 * + * Copyright (C) 1998-2004 Gerwin Klein * + * All rights reserved. * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License. See the file * + * COPYRIGHT for more information. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License along * + * with this program; if not, write to the Free Software Foundation, Inc., * + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +package JFlex.tests; + + +import JFlex.Skeleton; +import junit.framework.TestCase; + +import java.io.File; + +/** + * SkeletonTest + * + * @author Gerwin Klein + * @version $Revision: 1.4 $, $Date: 2004/11/06 23:03:30 $ + */ +public class SkeletonTest extends TestCase { + + /** + * Constructor for SkeletonTest. + * @param arg0 test name + */ + public SkeletonTest(String arg0) { + super(arg0); + } + + public void testReplace() { + assertEquals(Skeleton.replace("bla ", "blub", "bla blub bla "), + "blubblub blub"); + } + + public void testMakePrivate() { + Skeleton.makePrivate(); + for (int i=0; i < Skeleton.line.length; i++) { + assertEquals(Skeleton.line[i].indexOf("public"), -1); + } + } + + public void testDefault() { + Skeleton.readSkelFile(new File("src/skeleton.nested")); + assertTrue(JFlex.Skeleton.line[3].indexOf("java.util.Stack") > 0); + Skeleton.readDefault(); + assertEquals(JFlex.Skeleton.line[3].indexOf("java.util.Stack"), -1); + } +} diff --git a/tools/lexer/jflex-1.4/src/README b/tools/lexer/jflex-1.4/src/README new file mode 100644 index 000000000000..84ec73be8826 --- /dev/null +++ b/tools/lexer/jflex-1.4/src/README @@ -0,0 +1,63 @@ +This directory contains the source code for JFlex. + +For your convenience, the following generated lexer and parser files +are included in the distribution: + +JFlex/LexScan.java (lexer, generated from src/LexScan.flex) +JFlex/LexParse.java (parser, generated from src/LexParse.cup) +JFlex/sym.java (parser symbols, generated from src/LexParse.cup) + + +Dependencies: +If you just want to compile the JFlex sources, no further tools are +necessary. If you want to compile the ant task, you need the ant +classes in you class path, if you want to compile the unit tests, you +need the junit classes in yor class path. + +To build everything from scratch: +In class path: +junit.jar >= 3.8.1 [http://www.junit.org/] +ant.jar >= 1.4 [optional, http://ant.apache.org/] +In ant lib dir: +java_cup.jar >= 0.10l [http://www.cs.princeton.edu/~appel/modern/java/CUP/] +JFlex.jar >= 1.4pre1 [http://www.jflex.de/] + + +Dir contents: +build.xml: + for use with the ant build tool [http://ant.apache.org/] + + Useful targets are: + jar: recompiles all JFlex classes, generates lexer+parser + only if necessary, zips up all compiled classes in + ../lib/JFlex.jar + + build: cleans up everything and does a completely new build + + realclean: deletes generated, temporary and *.class files + +manifest: + jar manifest file for JFlex.jar + +skeleton: + a skeleton file matching exactly the precompiled scanner skeleton. + Can be used together with the --skel option + +skeleton.nested: + a skeleton file that supports nested input streams (see the manual + for the API). Can be used together with the --skel option + +JFlex: + source files of package JFlex + +JFlex/gui: + source files of package JFlex.gui + +JFlex/anttask + source files of the JFlex Ant task (contributed by Rafal Mantiuk) + +JFlex/test + unit tests for JFlex + +java_cup/runtime: + CUP v0.10k runtime classes, used by JFlex \ No newline at end of file diff --git a/tools/lexer/jflex-1.4/src/build.xml b/tools/lexer/jflex-1.4/src/build.xml new file mode 100644 index 000000000000..047cf4138d90 --- /dev/null +++ b/tools/lexer/jflex-1.4/src/build.xml @@ -0,0 +1,108 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tools/lexer/jflex-1.4/src/changelog b/tools/lexer/jflex-1.4/src/changelog new file mode 100644 index 000000000000..fafbbea8f8de --- /dev/null +++ b/tools/lexer/jflex-1.4/src/changelog @@ -0,0 +1,255 @@ +* JFlex 1.4.1 (November 7, 2004) +- merged in patch by Don Brown (fixes #1049791 Uses Old JUnit method assertFalse) +- merged in patch by Don Brown (fixes #887821 buffer expansion bug in yy_refill()) + Thanks to Binesh Bannerjee for providing a simpler test case for this problem. +- fixed bug #1035407 (ArrayIndexOutOfBounds in IntCharSet) +- fixed bug #1003569 (Cannot use lookahead with ignorecase) +- converted dangerous lookahead error to warning +- print info for EOF actions as well in %debug mode +- fixed line number count for EOF actions +- internal: removed unused methods in LexScan.flex and IntCharSet + +* JFlex 1.4 (April 12, 2004) +- new, very fast minimization algorithm (also fixes memory issues) +- new --jlex option for strict compatibility to JLex. Currently it + changes %ignorecase to JLex semantics, that is, character classes + are interpreted in a caseless way, too. + (fixes bus #751757, %ignorecase ignored by char classes). + Thanks to Edward D. Willink for spotting the incompatibility. +- support for even larger scanners (up to 64K DFA states). + Thanks to Karin Vespoor. +- removed eclipse compiler warnings for generated classes + (feature request #778747) +- implemented faster character classes (feature request #604589). + Expressions like [a-z] | [A-Z] are interpreted as one atomic class + [a-zA-Z], reducing NFA states and generation time significantly + for some specifications. This affects the generation process only, + generated scanners remain the same. +- new %apiprivate switch (feature request #513500/1) that causes all + generated and skeleton methods to be made private. Exceptions to this + are user defined functions and the constructor. Thanks to Stephen + Ostermiller for the suggestion. +- allow user defined javadoc class comments (feature request #513500/2) + If the user code section ends with a javadoc comment, JFlex takes this + instead of the generated comment. Thanks to Stephen Ostermiller for + the suggestion. +- fixed bug #491095 (undefined macros in complement expressions do + not throw exception in generator). Thanks to Stephen Ostermiller + for the bug report. +- fixed bug #495422 (yypushStream/yypopStream in skeleton.nested + work as advertised) +- fixed bug #611118 (no wrong macro warnings on regexp negation) +- fixed bug #655528 (%cupsym now also affects %cupdebug) + Thanks to Eric Schweitz for the fix. +- fixed bug #510010 (single-line %initthrow works now + in case of extra whitespace before newline) +- yyreset() does no longer close the associated reader (use yyclose() + explicitly for that). Makes some reader objects reusable (feature + request #513492). Thanks to Stephen Ostermiller for the suggestion. +- fixed modifier order in generated code, removes jikes compiler warnings + Thanks to Michael Wildpaner for the fix. +- ant task now also works with ant >= 1.4 (fixes bug #526905) +- yyreset() does not declare an execption any more (fixes bug #913132) +- %cup does not include %eofclose in JLex mode (--jlex). (Fixes bug #910562) +- optional parameter to %eofclose: "%eofclose false" turns off %eofclose if + it was turned on previously (e.g. by %cup). (Fixes bug #910562) +- jflex build script switched to ant +- internal: central Options class for better integration with + build tools and IDEs +- internal: change naming scheme for generated internal variables from + yy_ to zz to comply with Java naming standard. Thanks to Max Gilead + for the patch. + + +* JFlex 1.3.5 (October 8, 2001) +- fixed all bugs reported for version 1.3.4. Thanks to + Amin Ahmad and Fred Wehrhahn for their excellent bug reports. +- implemented feature request #459014: vim syntax file. + Thanks to Michael Brailsford for his help and suggestions. +- JFlex should run with JDK 1.1 out-of-the-box again. + + +* JFlex 1.3.4 (October 1, 2001) +- fixed all bugs reported for version 1.3.3. Thanks to Mike Akerman + for his excellent bug reports and his help. +- implemented feature request #459355: exclusive start states. + Thanks to Ed Beroset for the suggestion. +- introduced %s and %x shorthands for state declarations + + +* JFlex 1.3.3 (September 21, 2001) +- fixed all reported bugs except #39 (lookahead check at generation + time may fail). Thanks to Axel Schwolow, Karl Meissner, Angelo + Borsotti, and Paolo Di Francesco for their excellent bug reports. +- enhanced %debug output. JFlex scanners in debug mode now print line, + column, matched text, and executed action (with line number in spec) + for each processed token. Thanks to + Karl Meissner for the + suggestion. +- introduced %cupdebug directive for readable CUP debugging. Generated + scanners print line, column, matched text, and CUP symbol name for + each returned token. Again thanks to Karl Meissner for tips and + contributed Java reflection code. +- new %cupsym to customize CUP generated symbols class name. Thanks + to Karl Meissner and Paolo Di Francesco. +- new %throws as shorthand for %yylexthrow +- code generation now customizable at command line with --table, + --pack, and --switch +- command line switch --info prints system and JVM information (useful + for bug reports) +- command line switch --nobak for not generating backup files +- an Ant task for the Ant build tool http://jakarta.apache.org/ant/ + contributed by Rafal Mantiuk. Many thanks to him. +- better error message for missing ] in char class. Thanks to Karl + Meissner. +- performance enhancements in the runtime system. The engine is now + 10%-50% faster. These are only the first implementations of a few of + the many suggestions from Angelo Borsotti. Thanks to Angelo for many + insights, tips, and fruitful discussions. +- a new warning if a rule can never be matched +- macros and regular expression can now span multiple lines (note + that | at the end of a line in a rule is a special action, + not the | operator) +- updated the manual to contain more information about the generated + class, clarified the description of lexical states. Thanks to Michael + Binz, Angelo Borsotti, Vasily Karyaev and for the suggestions. +- Simplified java example lexer, and allow // style comments at EOF. + Thanks to Thomas Mulcahy. +- Byacc/J example updated to version 1.1 +- New interpreter example using CUP. Thanks to Bernhard Rumpe for + the code. + + +* JFlex 1.3.2 (February 24, 2001) +- fixed bug #32 (this time for real). Thanks to Thilo Goetz for + his quick report. +- updated the binary scanning example with the more comprehensive and + usable class StraightStreamReader by Stephen Ostermiller. Thanks go to + him for his contribution. The original version of this class is at + http://www.smo.f2s.com/utils/ +- added a link to a Japanese translation of the JFlex manual (it's in Japanese + Shift_JIS encoding). The translation is for an older release (1.1.2), but + most of the text still applies to the current version. See the change log + for the differences between 1.1.2 and the current version. Many thanks to + Yuichi Nakajima, Yukio Ikeda, Katsuhiko Yamazaki, and Koji Ooya for + their efforts. + If you would like to translate the JFlex manual into another language, or + if you already have done so, please let me know. I will include a link to + it on the documentation page. I can also give you access to the latex + sources of the manual, so that printable versions of your translation can + be generated, too. + + +* JFlex 1.3.1 (February 20, 2001) +- fixed all JFlex bugs reported for 1.3 (bugs #32-#36) + Thanks to Hans Kratz, Vasily Karyaev, Alexey Yakovets, and Tom Moog for + their excellent reports. +- added two new example scanners: + . a demonstration how to scan binary files + . a small calculator example for Cup, based on the example in the Linux + Gazette by Richard A. Sevenich and Christopher Lopes. See also + http://www.linuxgazette.com/issue39/sevenich.html + http://www.linuxgazette.com/issue41/sevenich.html + http://www.linuxgazette.com/issue41/lopes/lopes.html +- manual section about encodings, platforms and Unicode. + Thanks to Stephen Ostermiller for his valuable input. +- switch for skipping the minimization step in DFA generation (--nomin). + This feature is still in alpha status and not yet extensively tested. It + might be useful when you have very large scanners and not much memory + available. +- switch for generating graphviz dot files for graphical representation (ps + or gif) of generated NFA, DFA and minimized DFA (--dot). Might be useful for + teaching. This feature is also still in alpha status and not fully finished + yet. It is included as preview, comments are welcome, please try it out and + tell me what you think. For information on graphviz see + http://www.research.att.com:80/sw/tools/graphviz/ +- changed to --style long command line switches (single - still recognized). +- moved part of the project to http://sourceforge.net/projects/jflex/ + + +* JFlex 1.3 (October 21, 2000) + +- Fixed all bugs reported for 1.2.2 (bugs #23-#27). +- Better start script for Linux. +- Customize for internal error handling in yy_ScanError. +- Empty charclass [], and any (=negated empty) charclass [^]. +- New negation operator ! for regexps. +- New upto operator ~ for regexps. +- Customizable buffer size (%buffer). +- New char yycharat(int) for efficient access to single characters in matched text. +- Split up of too large lex tables for even larger scanner sizes. +- New additional external skeleton with support for nested input streams. +- JLex compatibility: BOL ^ and EOL $ use unicode line separators as in + http://www.unicode.org/unicode/reports/tr18/tr18-5.1.html. +- New resetStream method for reusing scanner objects. +_ BYacc/J support (%byaccj) + BYacc/J example. +- Include files in lexer specs (%include). +- New --dump switch for a dump of the generated charclasses, NFA, DFA, and minimized DFA tables. + + +* JFlex 1.2.2 (August 23, 1999) +- Updated JFlex to the new CUP version 0.10j. +- Eliminated some remaining platform dependent newlines in the generated source code + (affecting the readabilty of the generated code only, no functional changes). +- Minor improvements in error reporting (out of memory). +- Added a --version command line option for printing the current jflex version. +- Updated the Java 1.2 lexer/parser example to CUP 0.10j. + + +* JFlex 1.2.1 (June 25, 1999) +- Fixed all bugs reported for version 1.2 (#19-#22). +- Webpage redesigned and moved to http://www.jflex.de. +- Example java lexer/parser switched to Java 1.2. + + +* JFlex 1.2 (March 21, 1999) +- Fixed all bugs for 1.1.2. +- JFlex now works again with Solaris JIT. +- Significant Unicode optimizations in scanning and generation performance, +- changed the empty string match wrt. EOF behavior to the one that is commonly expected. +- added command line switches for more customization +- external skeleton files +- new GUI without any console output +- <> as in lex/flex +- better error messages +- better generation speed +- better generation memory efficiency +- | Action, trailing context (/ operator) +- new %final, %abstract and %extends directives +- uses jar file +- included makefile for JFlex, +- %pack now uses string packing, +- %pack now default code generation method, +- new %switch directive for old default code generation method, +- more convenient declaration of exceptions, +- new %int switch, +- manual now written in latex, available as html and in printable .ps.gz and pdf file formats. + + +* JFlex 1.1.2 +- All bugs reported for version 1.1.1 (#8-#10) have been fixed. + + +* JFlex 1.1.1 +- All bugs reported for version 1.1 (i.e. bug #7 and feature request #6) have been fixed. +- Scanning speed was optimized further. + + +* JFlex 1.1 adds new features and fixes all known bugs of 1.0 +- Revised directory structure. +- Fixed all reported bugs (#1-#5 and some unreported ones). +- Fixed thousands of typos in the manual. +- whitespace characters in regular expressions, +- flex style repeat expressions, +- %caseless switch, +- %eofclose switch, +- method for closing the input stream, +- method for the current lexical state, +- method for rereading matched text, +- backup of files that are overwitten in the generation process, +- improved error reporting, +- graphical UI when no filename is provided on the commandline + + +* JFlex 1.0 (May 1998) was the first public release of JFlex. + It was developed using Sun's JDK 1.1, JFlex (bootstrapped) and the parser generator CUP \ No newline at end of file diff --git a/tools/lexer/jflex-1.4/src/java_cup/runtime/Scanner.java b/tools/lexer/jflex-1.4/src/java_cup/runtime/Scanner.java new file mode 100644 index 000000000000..32335516f082 --- /dev/null +++ b/tools/lexer/jflex-1.4/src/java_cup/runtime/Scanner.java @@ -0,0 +1,25 @@ +package java_cup.runtime; + +/** + * Defines the Scanner interface, which CUP uses in the default + * implementation of lr_parser.scan(). Integration + * of scanners implementing Scanner is facilitated. + * + * @version last updated 23-Jul-1999 + * @author David MacMahon + */ + +/* ************************************************* + Interface Scanner + + Declares the next_token() method that should be + implemented by scanners. This method is typically + called by lr_parser.scan(). End-of-file can be + indicated either by returning + new Symbol(lr_parser.EOF_sym()) or + null. + ***************************************************/ +public interface Scanner { + /** Return the next token, or null on end-of-file. */ + public Symbol next_token() throws java.lang.Exception; +} diff --git a/tools/lexer/jflex-1.4/src/java_cup/runtime/Symbol.java b/tools/lexer/jflex-1.4/src/java_cup/runtime/Symbol.java new file mode 100644 index 000000000000..eeb6a0b4c6d6 --- /dev/null +++ b/tools/lexer/jflex-1.4/src/java_cup/runtime/Symbol.java @@ -0,0 +1,105 @@ +package java_cup.runtime; + +/** + * Defines the Symbol class, which is used to represent all terminals + * and nonterminals while parsing. The lexer should pass CUP Symbols + * and CUP returns a Symbol. + * + * @version last updated: 7/3/96 + * @author Frank Flannery + */ + +/* **************************************************************** + Class Symbol + what the parser expects to receive from the lexer. + the token is identified as follows: + sym: the symbol type + parse_state: the parse state. + value: is the lexical value of type Object + left : is the left position in the original input file + right: is the right position in the original input file +******************************************************************/ + +public class Symbol { + +/******************************* + Constructor for l,r values + *******************************/ + + public Symbol(int id, int l, int r, Object o) { + this(id); + left = l; + right = r; + value = o; + } + +/******************************* + Constructor for no l,r values +********************************/ + + public Symbol(int id, Object o) { + this(id, -1, -1, o); + } + +/***************************** + Constructor for no value + ***************************/ + + public Symbol(int id, int l, int r) { + this(id, l, r, null); + } + +/*********************************** + Constructor for no value or l,r +***********************************/ + + public Symbol(int sym_num) { + this(sym_num, -1); + left = -1; + right = -1; + value = null; + } + +/*********************************** + Constructor to give a start state +***********************************/ + Symbol(int sym_num, int state) + { + sym = sym_num; + parse_state = state; + } + +/*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ + + /** The symbol number of the terminal or non terminal being represented */ + public int sym; + + /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ + + /** The parse state to be recorded on the parse stack with this symbol. + * This field is for the convenience of the parser and shouldn't be + * modified except by the parser. + */ + public int parse_state; + /** This allows us to catch some errors caused by scanners recycling + * symbols. For the use of the parser only. [CSA, 23-Jul-1999] */ + boolean used_by_parser = false; + +/******************************* + The data passed to parser + *******************************/ + + public int left, right; + public Object value; + + /***************************** + Printing this token out. (Override for pretty-print). + ****************************/ + public String toString() { return "#"+sym; } +} + + + + + + diff --git a/tools/lexer/jflex-1.4/src/java_cup/runtime/lr_parser.java b/tools/lexer/jflex-1.4/src/java_cup/runtime/lr_parser.java new file mode 100644 index 000000000000..3c8335cb2524 --- /dev/null +++ b/tools/lexer/jflex-1.4/src/java_cup/runtime/lr_parser.java @@ -0,0 +1,1238 @@ + +package java_cup.runtime; + +import java.util.Stack; + +/** This class implements a skeleton table driven LR parser. In general, + * LR parsers are a form of bottom up shift-reduce parsers. Shift-reduce + * parsers act by shifting input onto a parse stack until the Symbols + * matching the right hand side of a production appear on the top of the + * stack. Once this occurs, a reduce is performed. This involves removing + * the Symbols corresponding to the right hand side of the production + * (the so called "handle") and replacing them with the non-terminal from + * the left hand side of the production.

+ * + * To control the decision of whether to shift or reduce at any given point, + * the parser uses a state machine (the "viable prefix recognition machine" + * built by the parser generator). The current state of the machine is placed + * on top of the parse stack (stored as part of a Symbol object representing + * a terminal or non terminal). The parse action table is consulted + * (using the current state and the current lookahead Symbol as indexes) to + * determine whether to shift or to reduce. When the parser shifts, it + * changes to a new state by pushing a new Symbol (containing a new state) + * onto the stack. When the parser reduces, it pops the handle (right hand + * side of a production) off the stack. This leaves the parser in the state + * it was in before any of those Symbols were matched. Next the reduce-goto + * table is consulted (using the new state and current lookahead Symbol as + * indexes) to determine a new state to go to. The parser then shifts to + * this goto state by pushing the left hand side Symbol of the production + * (also containing the new state) onto the stack.

+ * + * This class actually provides four LR parsers. The methods parse() and + * debug_parse() provide two versions of the main parser (the only difference + * being that debug_parse() emits debugging trace messages as it parses). + * In addition to these main parsers, the error recovery mechanism uses two + * more. One of these is used to simulate "parsing ahead" in the input + * without carrying out actions (to verify that a potential error recovery + * has worked), and the other is used to parse through buffered "parse ahead" + * input in order to execute all actions and re-synchronize the actual parser + * configuration.

+ * + * This is an abstract class which is normally filled out by a subclass + * generated by the JavaCup parser generator. In addition to supplying + * the actual parse tables, generated code also supplies methods which + * invoke various pieces of user supplied code, provide access to certain + * special Symbols (e.g., EOF and error), etc. Specifically, the following + * abstract methods are normally supplied by generated code: + *

+ *
short[][] production_table() + *
Provides a reference to the production table (indicating the index of + * the left hand side non terminal and the length of the right hand side + * for each production in the grammar). + *
short[][] action_table() + *
Provides a reference to the parse action table. + *
short[][] reduce_table() + *
Provides a reference to the reduce-goto table. + *
int start_state() + *
Indicates the index of the start state. + *
int start_production() + *
Indicates the index of the starting production. + *
int EOF_sym() + *
Indicates the index of the EOF Symbol. + *
int error_sym() + *
Indicates the index of the error Symbol. + *
Symbol do_action() + *
Executes a piece of user supplied action code. This always comes at + * the point of a reduce in the parse, so this code also allocates and + * fills in the left hand side non terminal Symbol object that is to be + * pushed onto the stack for the reduce. + *
void init_actions() + *
Code to initialize a special object that encapsulates user supplied + * actions (this object is used by do_action() to actually carry out the + * actions). + *
+ * + * In addition to these routines that must be supplied by the + * generated subclass there are also a series of routines that may + * be supplied. These include: + *
+ *
Symbol scan() + *
Used to get the next input Symbol from the scanner. + *
Scanner getScanner() + *
Used to provide a scanner for the default implementation of + * scan(). + *
int error_sync_size() + *
This determines how many Symbols past the point of an error + * must be parsed without error in order to consider a recovery to + * be valid. This defaults to 3. Values less than 2 are not + * recommended. + *
void report_error(String message, Object info) + *
This method is called to report an error. The default implementation + * simply prints a message to System.err and where the error occurred. + * This method is often replaced in order to provide a more sophisticated + * error reporting mechanism. + *
void report_fatal_error(String message, Object info) + *
This method is called when a fatal error that cannot be recovered from + * is encountered. In the default implementation, it calls + * report_error() to emit a message, then throws an exception. + *
void syntax_error(Symbol cur_token) + *
This method is called as soon as syntax error is detected (but + * before recovery is attempted). In the default implementation it + * invokes: report_error("Syntax error", null); + *
void unrecovered_syntax_error(Symbol cur_token) + *
This method is called if syntax error recovery fails. In the default + * implementation it invokes:
+ * report_fatal_error("Couldn't repair and continue parse", null); + *
+ * + * @see java_cup.runtime.Symbol + * @see java_cup.runtime.Symbol + * @see java_cup.runtime.virtual_parse_stack + * @version last updated: 7/3/96 + * @author Frank Flannery + */ + +public abstract class lr_parser { + + /*-----------------------------------------------------------*/ + /*--- Constructor(s) ----------------------------------------*/ + /*-----------------------------------------------------------*/ + + /** Simple constructor. */ + public lr_parser() + { + /* nothing to do here */ + } + + /** Constructor that sets the default scanner. [CSA/davidm] */ + public lr_parser(Scanner s) { + this(); /* in case default constructor someday does something */ + setScanner(s); + } + + /*-----------------------------------------------------------*/ + /*--- (Access to) Static (Class) Variables ------------------*/ + /*-----------------------------------------------------------*/ + + /** The default number of Symbols after an error we much match to consider + * it recovered from. + */ + protected final static int _error_sync_size = 3; + + /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ + + /** The number of Symbols after an error we much match to consider it + * recovered from. + */ + protected int error_sync_size() {return _error_sync_size; } + + /*-----------------------------------------------------------*/ + /*--- (Access to) Instance Variables ------------------------*/ + /*-----------------------------------------------------------*/ + + /** Table of production information (supplied by generated subclass). + * This table contains one entry per production and is indexed by + * the negative-encoded values (reduce actions) in the action_table. + * Each entry has two parts, the index of the non-terminal on the + * left hand side of the production, and the number of Symbols + * on the right hand side. + */ + public abstract short[][] production_table(); + + /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ + + /** The action table (supplied by generated subclass). This table is + * indexed by state and terminal number indicating what action is to + * be taken when the parser is in the given state (i.e., the given state + * is on top of the stack) and the given terminal is next on the input. + * States are indexed using the first dimension, however, the entries for + * a given state are compacted and stored in adjacent index, value pairs + * which are searched for rather than accessed directly (see get_action()). + * The actions stored in the table will be either shifts, reduces, or + * errors. Shifts are encoded as positive values (one greater than the + * state shifted to). Reduces are encoded as negative values (one less + * than the production reduced by). Error entries are denoted by zero. + * + * @see java_cup.runtime.lr_parser#get_action + */ + public abstract short[][] action_table(); + + /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ + + /** The reduce-goto table (supplied by generated subclass). This + * table is indexed by state and non-terminal number and contains + * state numbers. States are indexed using the first dimension, however, + * the entries for a given state are compacted and stored in adjacent + * index, value pairs which are searched for rather than accessed + * directly (see get_reduce()). When a reduce occurs, the handle + * (corresponding to the RHS of the matched production) is popped off + * the stack. The new top of stack indicates a state. This table is + * then indexed by that state and the LHS of the reducing production to + * indicate where to "shift" to. + * + * @see java_cup.runtime.lr_parser#get_reduce + */ + public abstract short[][] reduce_table(); + + /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ + + /** The index of the start state (supplied by generated subclass). */ + public abstract int start_state(); + + /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ + + /** The index of the start production (supplied by generated subclass). */ + public abstract int start_production(); + + /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ + + /** The index of the end of file terminal Symbol (supplied by generated + * subclass). + */ + public abstract int EOF_sym(); + + /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ + + /** The index of the special error Symbol (supplied by generated subclass). */ + public abstract int error_sym(); + + /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ + + /** Internal flag to indicate when parser should quit. */ + protected boolean _done_parsing = false; + + /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ + + /** This method is called to indicate that the parser should quit. This is + * normally called by an accept action, but can be used to cancel parsing + * early in other circumstances if desired. + */ + public void done_parsing() + { + _done_parsing = true; + } + + /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ + /* Global parse state shared by parse(), error recovery, and + * debugging routines */ + /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ + + /** Indication of the index for top of stack (for use by actions). */ + protected int tos; + + /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ + + /** The current lookahead Symbol. */ + protected Symbol cur_token; + + /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ + + /** The parse stack itself. */ + protected Stack stack = new Stack(); + + /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ + + /** Direct reference to the production table. */ + protected short[][] production_tab; + + /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ + + /** Direct reference to the action table. */ + protected short[][] action_tab; + + /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ + + /** Direct reference to the reduce-goto table. */ + protected short[][] reduce_tab; + + /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ + + /** This is the scanner object used by the default implementation + * of scan() to get Symbols. To avoid name conflicts with existing + * code, this field is private. [CSA/davidm] */ + private Scanner _scanner; + + /** + * Simple accessor method to set the default scanner. + */ + public void setScanner(Scanner s) { _scanner = s; } + + /** + * Simple accessor method to get the default scanner. + */ + public Scanner getScanner() { return _scanner; } + + /*-----------------------------------------------------------*/ + /*--- General Methods ---------------------------------------*/ + /*-----------------------------------------------------------*/ + + /** Perform a bit of user supplied action code (supplied by generated + * subclass). Actions are indexed by an internal action number assigned + * at parser generation time. + * + * @param act_num the internal index of the action to be performed. + * @param parser the parser object we are acting for. + * @param stack the parse stack of that object. + * @param top the index of the top element of the parse stack. + */ + public abstract Symbol do_action( + int act_num, + lr_parser parser, + Stack stack, + int top) + throws java.lang.Exception; + + /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ + + /** User code for initialization inside the parser. Typically this + * initializes the scanner. This is called before the parser requests + * the first Symbol. Here this is just a placeholder for subclasses that + * might need this and we perform no action. This method is normally + * overridden by the generated code using this contents of the "init with" + * clause as its body. + */ + public void user_init() throws java.lang.Exception { } + + /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ + + /** Initialize the action object. This is called before the parser does + * any parse actions. This is filled in by generated code to create + * an object that encapsulates all action code. + */ + protected abstract void init_actions() throws java.lang.Exception; + + /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ + + /** Get the next Symbol from the input (supplied by generated subclass). + * Once end of file has been reached, all subsequent calls to scan + * should return an EOF Symbol (which is Symbol number 0). By default + * this method returns getScanner().next_token(); this implementation + * can be overriden by the generated parser using the code declared in + * the "scan with" clause. Do not recycle objects; every call to + * scan() should return a fresh object. + */ + public Symbol scan() throws java.lang.Exception { + Symbol sym = getScanner().next_token(); + return (sym!=null) ? sym : new Symbol(EOF_sym()); + } + + /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ + + /** Report a fatal error. This method takes a message string and an + * additional object (to be used by specializations implemented in + * subclasses). Here in the base class a very simple implementation + * is provided which reports the error then throws an exception. + * + * @param message an error message. + * @param info an extra object reserved for use by specialized subclasses. + */ + public void report_fatal_error( + String message, + Object info) + throws java.lang.Exception + { + /* stop parsing (not really necessary since we throw an exception, but) */ + done_parsing(); + + /* use the normal error message reporting to put out the message */ + report_error(message, info); + + /* throw an exception */ + throw new Exception("Can't recover from previous error(s)"); + } + + /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ + + /** Report a non fatal error (or warning). This method takes a message + * string and an additional object (to be used by specializations + * implemented in subclasses). Here in the base class a very simple + * implementation is provided which simply prints the message to + * System.err. + * + * @param message an error message. + * @param info an extra object reserved for use by specialized subclasses. + */ + public void report_error(String message, Object info) + { + System.err.print(message); + if (info instanceof Symbol) + if (((Symbol)info).left != -1) + System.err.println(" at character " + ((Symbol)info).left + + " of input"); + else System.err.println(""); + else System.err.println(""); + } + + /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ + + /** This method is called when a syntax error has been detected and recovery + * is about to be invoked. Here in the base class we just emit a + * "Syntax error" error message. + * + * @param cur_token the current lookahead Symbol. + */ + public void syntax_error(Symbol cur_token) + { + report_error("Syntax error", cur_token); + } + + /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ + + /** This method is called if it is determined that syntax error recovery + * has been unsuccessful. Here in the base class we report a fatal error. + * + * @param cur_token the current lookahead Symbol. + */ + public void unrecovered_syntax_error(Symbol cur_token) + throws java.lang.Exception + { + report_fatal_error("Couldn't repair and continue parse", cur_token); + } + + /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ + + /** Fetch an action from the action table. The table is broken up into + * rows, one per state (rows are indexed directly by state number). + * Within each row, a list of index, value pairs are given (as sequential + * entries in the table), and the list is terminated by a default entry + * (denoted with a Symbol index of -1). To find the proper entry in a row + * we do a linear or binary search (depending on the size of the row). + * + * @param state the state index of the action being accessed. + * @param sym the Symbol index of the action being accessed. + */ + protected final short get_action(int state, int sym) + { + short tag; + int first, last, probe; + short[] row = action_tab[state]; + + /* linear search if we are < 10 entries */ + if (row.length < 20) + for (probe = 0; probe < row.length; probe++) + { + /* is this entry labeled with our Symbol or the default? */ + tag = row[probe++]; + if (tag == sym || tag == -1) + { + /* return the next entry */ + return row[probe]; + } + } + /* otherwise binary search */ + else + { + first = 0; + last = (row.length-1)/2 - 1; /* leave out trailing default entry */ + while (first <= last) + { + probe = (first+last)/2; + if (sym == row[probe*2]) + return row[probe*2+1]; + else if (sym > row[probe*2]) + first = probe+1; + else + last = probe-1; + } + + /* not found, use the default at the end */ + return row[row.length-1]; + } + + /* shouldn't happened, but if we run off the end we return the + default (error == 0) */ + return 0; + } + + /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ + + /** Fetch a state from the reduce-goto table. The table is broken up into + * rows, one per state (rows are indexed directly by state number). + * Within each row, a list of index, value pairs are given (as sequential + * entries in the table), and the list is terminated by a default entry + * (denoted with a Symbol index of -1). To find the proper entry in a row + * we do a linear search. + * + * @param state the state index of the entry being accessed. + * @param sym the Symbol index of the entry being accessed. + */ + protected final short get_reduce(int state, int sym) + { + short tag; + short[] row = reduce_tab[state]; + + /* if we have a null row we go with the default */ + if (row == null) + return -1; + + for (int probe = 0; probe < row.length; probe++) + { + /* is this entry labeled with our Symbol or the default? */ + tag = row[probe++]; + if (tag == sym || tag == -1) + { + /* return the next entry */ + return row[probe]; + } + } + /* if we run off the end we return the default (error == -1) */ + return -1; + } + + /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ + + /** This method provides the main parsing routine. It returns only when + * done_parsing() has been called (typically because the parser has + * accepted, or a fatal error has been reported). See the header + * documentation for the class regarding how shift/reduce parsers operate + * and how the various tables are used. + */ + public Symbol parse() throws java.lang.Exception + { + /* the current action code */ + int act; + + /* the Symbol/stack element returned by a reduce */ + Symbol lhs_sym = null; + + /* information about production being reduced with */ + short handle_size, lhs_sym_num; + + /* set up direct reference to tables to drive the parser */ + + production_tab = production_table(); + action_tab = action_table(); + reduce_tab = reduce_table(); + + /* initialize the action encapsulation object */ + init_actions(); + + /* do user initialization */ + user_init(); + + /* get the first token */ + cur_token = scan(); + + /* push dummy Symbol with start state to get us underway */ + stack.removeAllElements(); + stack.push(new Symbol(0, start_state())); + tos = 0; + + /* continue until we are told to stop */ + for (_done_parsing = false; !_done_parsing; ) + { + /* Check current token for freshness. */ + if (cur_token.used_by_parser) + throw new Error("Symbol recycling detected (fix your scanner)."); + + /* current state is always on the top of the stack */ + + /* look up action out of the current state with the current input */ + act = get_action(((Symbol)stack.peek()).parse_state, cur_token.sym); + + /* decode the action -- > 0 encodes shift */ + if (act > 0) + { + /* shift to the encoded state by pushing it on the stack */ + cur_token.parse_state = act-1; + cur_token.used_by_parser = true; + stack.push(cur_token); + tos++; + + /* advance to the next Symbol */ + cur_token = scan(); + } + /* if its less than zero, then it encodes a reduce action */ + else if (act < 0) + { + /* perform the action for the reduce */ + lhs_sym = do_action((-act)-1, this, stack, tos); + + /* look up information about the production */ + lhs_sym_num = production_tab[(-act)-1][0]; + handle_size = production_tab[(-act)-1][1]; + + /* pop the handle off the stack */ + for (int i = 0; i < handle_size; i++) + { + stack.pop(); + tos--; + } + + /* look up the state to go to from the one popped back to */ + act = get_reduce(((Symbol)stack.peek()).parse_state, lhs_sym_num); + + /* shift to that state */ + lhs_sym.parse_state = act; + lhs_sym.used_by_parser = true; + stack.push(lhs_sym); + tos++; + } + /* finally if the entry is zero, we have an error */ + else if (act == 0) + { + /* call user syntax error reporting routine */ + syntax_error(cur_token); + + /* try to error recover */ + if (!error_recovery(false)) + { + /* if that fails give up with a fatal syntax error */ + unrecovered_syntax_error(cur_token); + + /* just in case that wasn't fatal enough, end parse */ + done_parsing(); + } else { + lhs_sym = (Symbol)stack.peek(); + } + } + } + return lhs_sym; + } + + /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ + + /** Write a debugging message to System.err for the debugging version + * of the parser. + * + * @param mess the text of the debugging message. + */ + public void debug_message(String mess) + { + System.err.println(mess); + } + + /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ + + /** Dump the parse stack for debugging purposes. */ + public void dump_stack() + { + if (stack == null) + { + debug_message("# Stack dump requested, but stack is null"); + return; + } + + debug_message("============ Parse Stack Dump ============"); + + /* dump the stack */ + for (int i=0; i"); + if ((i%3)==2 || (i==(stack.size()-1))) { + debug_message(sb.toString()); + sb = new StringBuffer(" "); + } + } + } + + /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ + + /** Perform a parse with debugging output. This does exactly the + * same things as parse(), except that it calls debug_shift() and + * debug_reduce() when shift and reduce moves are taken by the parser + * and produces various other debugging messages. + */ + public Symbol debug_parse() + throws java.lang.Exception + { + /* the current action code */ + int act; + + /* the Symbol/stack element returned by a reduce */ + Symbol lhs_sym = null; + + /* information about production being reduced with */ + short handle_size, lhs_sym_num; + + /* set up direct reference to tables to drive the parser */ + production_tab = production_table(); + action_tab = action_table(); + reduce_tab = reduce_table(); + + debug_message("# Initializing parser"); + + /* initialize the action encapsulation object */ + init_actions(); + + /* do user initialization */ + user_init(); + + /* the current Symbol */ + cur_token = scan(); + + debug_message("# Current Symbol is #" + cur_token.sym); + + /* push dummy Symbol with start state to get us underway */ + stack.removeAllElements(); + stack.push(new Symbol(0, start_state())); + tos = 0; + + /* continue until we are told to stop */ + for (_done_parsing = false; !_done_parsing; ) + { + /* Check current token for freshness. */ + if (cur_token.used_by_parser) + throw new Error("Symbol recycling detected (fix your scanner)."); + + /* current state is always on the top of the stack */ + //debug_stack(); + + /* look up action out of the current state with the current input */ + act = get_action(((Symbol)stack.peek()).parse_state, cur_token.sym); + + /* decode the action -- > 0 encodes shift */ + if (act > 0) + { + /* shift to the encoded state by pushing it on the stack */ + cur_token.parse_state = act-1; + cur_token.used_by_parser = true; + debug_shift(cur_token); + stack.push(cur_token); + tos++; + + /* advance to the next Symbol */ + cur_token = scan(); + debug_message("# Current token is " + cur_token); + } + /* if its less than zero, then it encodes a reduce action */ + else if (act < 0) + { + /* perform the action for the reduce */ + lhs_sym = do_action((-act)-1, this, stack, tos); + + /* look up information about the production */ + lhs_sym_num = production_tab[(-act)-1][0]; + handle_size = production_tab[(-act)-1][1]; + + debug_reduce((-act)-1, lhs_sym_num, handle_size); + + /* pop the handle off the stack */ + for (int i = 0; i < handle_size; i++) + { + stack.pop(); + tos--; + } + + /* look up the state to go to from the one popped back to */ + act = get_reduce(((Symbol)stack.peek()).parse_state, lhs_sym_num); + debug_message("# Reduce rule: top state " + + ((Symbol)stack.peek()).parse_state + + ", lhs sym " + lhs_sym_num + " -> state " + act); + + /* shift to that state */ + lhs_sym.parse_state = act; + lhs_sym.used_by_parser = true; + stack.push(lhs_sym); + tos++; + + debug_message("# Goto state #" + act); + } + /* finally if the entry is zero, we have an error */ + else if (act == 0) + { + /* call user syntax error reporting routine */ + syntax_error(cur_token); + + /* try to error recover */ + if (!error_recovery(true)) + { + /* if that fails give up with a fatal syntax error */ + unrecovered_syntax_error(cur_token); + + /* just in case that wasn't fatal enough, end parse */ + done_parsing(); + } else { + lhs_sym = (Symbol)stack.peek(); + } + } + } + return lhs_sym; + } + + /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ + /* Error recovery code */ + /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ + + /** Attempt to recover from a syntax error. This returns false if recovery + * fails, true if it succeeds. Recovery happens in 4 steps. First we + * pop the parse stack down to a point at which we have a shift out + * of the top-most state on the error Symbol. This represents the + * initial error recovery configuration. If no such configuration is + * found, then we fail. Next a small number of "lookahead" or "parse + * ahead" Symbols are read into a buffer. The size of this buffer is + * determined by error_sync_size() and determines how many Symbols beyond + * the error must be matched to consider the recovery a success. Next, + * we begin to discard Symbols in attempt to get past the point of error + * to a point where we can continue parsing. After each Symbol, we attempt + * to "parse ahead" though the buffered lookahead Symbols. The "parse ahead" + * process simulates that actual parse, but does not modify the real + * parser's configuration, nor execute any actions. If we can parse all + * the stored Symbols without error, then the recovery is considered a + * success. Once a successful recovery point is determined, we do an + * actual parse over the stored input -- modifying the real parse + * configuration and executing all actions. Finally, we return the the + * normal parser to continue with the overall parse. + * + * @param debug should we produce debugging messages as we parse. + */ + protected boolean error_recovery(boolean debug) + throws java.lang.Exception + { + if (debug) debug_message("# Attempting error recovery"); + + /* first pop the stack back into a state that can shift on error and + do that shift (if that fails, we fail) */ + if (!find_recovery_config(debug)) + { + if (debug) debug_message("# Error recovery fails"); + return false; + } + + /* read ahead to create lookahead we can parse multiple times */ + read_lookahead(); + + /* repeatedly try to parse forward until we make it the required dist */ + for (;;) + { + /* try to parse forward, if it makes it, bail out of loop */ + if (debug) debug_message("# Trying to parse ahead"); + if (try_parse_ahead(debug)) + { + break; + } + + /* if we are now at EOF, we have failed */ + if (lookahead[0].sym == EOF_sym()) + { + if (debug) debug_message("# Error recovery fails at EOF"); + return false; + } + + /* otherwise, we consume another Symbol and try again */ + // BUG FIX by Bruce Hutton + // Computer Science Department, University of Auckland, + // Auckland, New Zealand. + // It is the first token that is being consumed, not the one + // we were up to parsing + if (debug) + debug_message("# Consuming Symbol #" + lookahead[ 0 ].sym); + restart_lookahead(); + } + + /* we have consumed to a point where we can parse forward */ + if (debug) debug_message("# Parse-ahead ok, going back to normal parse"); + + /* do the real parse (including actions) across the lookahead */ + parse_lookahead(debug); + + /* we have success */ + return true; + } + + /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ + + /** Determine if we can shift under the special error Symbol out of the + * state currently on the top of the (real) parse stack. + */ + protected boolean shift_under_error() + { + /* is there a shift under error Symbol */ + return get_action(((Symbol)stack.peek()).parse_state, error_sym()) > 0; + } + + /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ + + /** Put the (real) parse stack into error recovery configuration by + * popping the stack down to a state that can shift on the special + * error Symbol, then doing the shift. If no suitable state exists on + * the stack we return false + * + * @param debug should we produce debugging messages as we parse. + */ + protected boolean find_recovery_config(boolean debug) + { + Symbol error_token; + int act; + + if (debug) debug_message("# Finding recovery state on stack"); + + /* Remember the right-position of the top symbol on the stack */ + int right_pos = ((Symbol)stack.peek()).right; + int left_pos = ((Symbol)stack.peek()).left; + + /* pop down until we can shift under error Symbol */ + while (!shift_under_error()) + { + /* pop the stack */ + if (debug) + debug_message("# Pop stack by one, state was # " + + ((Symbol)stack.peek()).parse_state); + left_pos = ((Symbol)stack.pop()).left; + tos--; + + /* if we have hit bottom, we fail */ + if (stack.empty()) + { + if (debug) debug_message("# No recovery state found on stack"); + return false; + } + } + + /* state on top of the stack can shift under error, find the shift */ + act = get_action(((Symbol)stack.peek()).parse_state, error_sym()); + if (debug) + { + debug_message("# Recover state found (#" + + ((Symbol)stack.peek()).parse_state + ")"); + debug_message("# Shifting on error to state #" + (act-1)); + } + + /* build and shift a special error Symbol */ + error_token = new Symbol(error_sym(), left_pos, right_pos); + error_token.parse_state = act-1; + error_token.used_by_parser = true; + stack.push(error_token); + tos++; + + return true; + } + + /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ + + /** Lookahead Symbols used for attempting error recovery "parse aheads". */ + protected Symbol lookahead[]; + + /** Position in lookahead input buffer used for "parse ahead". */ + protected int lookahead_pos; + + /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ + + /** Read from input to establish our buffer of "parse ahead" lookahead + * Symbols. + */ + protected void read_lookahead() throws java.lang.Exception + { + /* create the lookahead array */ + lookahead = new Symbol[error_sync_size()]; + + /* fill in the array */ + for (int i = 0; i < error_sync_size(); i++) + { + lookahead[i] = cur_token; + cur_token = scan(); + } + + /* start at the beginning */ + lookahead_pos = 0; + } + + /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ + + /** Return the current lookahead in our error "parse ahead" buffer. */ + protected Symbol cur_err_token() { return lookahead[lookahead_pos]; } + + /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ + + /** Advance to next "parse ahead" input Symbol. Return true if we have + * input to advance to, false otherwise. + */ + protected boolean advance_lookahead() + { + /* advance the input location */ + lookahead_pos++; + + /* return true if we didn't go off the end */ + return lookahead_pos < error_sync_size(); + } + + /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ + + /** Reset the parse ahead input to one Symbol past where we started error + * recovery (this consumes one new Symbol from the real input). + */ + protected void restart_lookahead() throws java.lang.Exception + { + /* move all the existing input over */ + for (int i = 1; i < error_sync_size(); i++) + lookahead[i-1] = lookahead[i]; + + /* read a new Symbol into the last spot */ + // BUG Fix by Bruce Hutton + // Computer Science Department, University of Auckland, + // Auckland, New Zealand. [applied 5-sep-1999 by csa] + // The following two lines were out of order!! + lookahead[error_sync_size()-1] = cur_token; + cur_token = scan(); + + /* reset our internal position marker */ + lookahead_pos = 0; + } + + /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ + + /** Do a simulated parse forward (a "parse ahead") from the current + * stack configuration using stored lookahead input and a virtual parse + * stack. Return true if we make it all the way through the stored + * lookahead input without error. This basically simulates the action of + * parse() using only our saved "parse ahead" input, and not executing any + * actions. + * + * @param debug should we produce debugging messages as we parse. + */ + protected boolean try_parse_ahead(boolean debug) + throws java.lang.Exception + { + int act; + short lhs, rhs_size; + + /* create a virtual stack from the real parse stack */ + virtual_parse_stack vstack = new virtual_parse_stack(stack); + + /* parse until we fail or get past the lookahead input */ + for (;;) + { + /* look up the action from the current state (on top of stack) */ + act = get_action(vstack.top(), cur_err_token().sym); + + /* if its an error, we fail */ + if (act == 0) return false; + + /* > 0 encodes a shift */ + if (act > 0) + { + /* push the new state on the stack */ + vstack.push(act-1); + + if (debug) debug_message("# Parse-ahead shifts Symbol #" + + cur_err_token().sym + " into state #" + (act-1)); + + /* advance simulated input, if we run off the end, we are done */ + if (!advance_lookahead()) return true; + } + /* < 0 encodes a reduce */ + else + { + /* if this is a reduce with the start production we are done */ + if ((-act)-1 == start_production()) + { + if (debug) debug_message("# Parse-ahead accepts"); + return true; + } + + /* get the lhs Symbol and the rhs size */ + lhs = production_tab[(-act)-1][0]; + rhs_size = production_tab[(-act)-1][1]; + + /* pop handle off the stack */ + for (int i = 0; i < rhs_size; i++) + vstack.pop(); + + if (debug) + debug_message("# Parse-ahead reduces: handle size = " + + rhs_size + " lhs = #" + lhs + " from state #" + vstack.top()); + + /* look up goto and push it onto the stack */ + vstack.push(get_reduce(vstack.top(), lhs)); + if (debug) + debug_message("# Goto state #" + vstack.top()); + } + } + } + + /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ + + /** Parse forward using stored lookahead Symbols. In this case we have + * already verified that parsing will make it through the stored lookahead + * Symbols and we are now getting back to the point at which we can hand + * control back to the normal parser. Consequently, this version of the + * parser performs all actions and modifies the real parse configuration. + * This returns once we have consumed all the stored input or we accept. + * + * @param debug should we produce debugging messages as we parse. + */ + protected void parse_lookahead(boolean debug) + throws java.lang.Exception + { + /* the current action code */ + int act; + + /* the Symbol/stack element returned by a reduce */ + Symbol lhs_sym = null; + + /* information about production being reduced with */ + short handle_size, lhs_sym_num; + + /* restart the saved input at the beginning */ + lookahead_pos = 0; + + if (debug) + { + debug_message("# Reparsing saved input with actions"); + debug_message("# Current Symbol is #" + cur_err_token().sym); + debug_message("# Current state is #" + + ((Symbol)stack.peek()).parse_state); + } + + /* continue until we accept or have read all lookahead input */ + while(!_done_parsing) + { + /* current state is always on the top of the stack */ + + /* look up action out of the current state with the current input */ + act = + get_action(((Symbol)stack.peek()).parse_state, cur_err_token().sym); + + /* decode the action -- > 0 encodes shift */ + if (act > 0) + { + /* shift to the encoded state by pushing it on the stack */ + cur_err_token().parse_state = act-1; + cur_err_token().used_by_parser = true; + if (debug) debug_shift(cur_err_token()); + stack.push(cur_err_token()); + tos++; + + /* advance to the next Symbol, if there is none, we are done */ + if (!advance_lookahead()) + { + if (debug) debug_message("# Completed reparse"); + + /* scan next Symbol so we can continue parse */ + // BUGFIX by Chris Harris : + // correct a one-off error by commenting out + // this next line. + /*cur_token = scan();*/ + + /* go back to normal parser */ + return; + } + + if (debug) + debug_message("# Current Symbol is #" + cur_err_token().sym); + } + /* if its less than zero, then it encodes a reduce action */ + else if (act < 0) + { + /* perform the action for the reduce */ + lhs_sym = do_action((-act)-1, this, stack, tos); + + /* look up information about the production */ + lhs_sym_num = production_tab[(-act)-1][0]; + handle_size = production_tab[(-act)-1][1]; + + if (debug) debug_reduce((-act)-1, lhs_sym_num, handle_size); + + /* pop the handle off the stack */ + for (int i = 0; i < handle_size; i++) + { + stack.pop(); + tos--; + } + + /* look up the state to go to from the one popped back to */ + act = get_reduce(((Symbol)stack.peek()).parse_state, lhs_sym_num); + + /* shift to that state */ + lhs_sym.parse_state = act; + lhs_sym.used_by_parser = true; + stack.push(lhs_sym); + tos++; + + if (debug) debug_message("# Goto state #" + act); + + } + /* finally if the entry is zero, we have an error + (shouldn't happen here, but...)*/ + else if (act == 0) + { + report_fatal_error("Syntax error", lhs_sym); + return; + } + } + + + } + + /*-----------------------------------------------------------*/ + + /** Utility function: unpacks parse tables from strings */ + protected static short[][] unpackFromStrings(String[] sa) + { + // Concatanate initialization strings. + StringBuffer sb = new StringBuffer(sa[0]); + for (int i=1; i= real_stack.size()) return; + + /* get a copy of the first Symbol we have not transfered */ + stack_sym = (Symbol)real_stack.elementAt(real_stack.size()-1-real_next); + + /* record the transfer */ + real_next++; + + /* put the state number from the Symbol onto the virtual stack */ + vstack.push(new Integer(stack_sym.parse_state)); + } + + /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ + + /** Indicate whether the stack is empty. */ + public boolean empty() + { + /* if vstack is empty then we were unable to transfer onto it and + the whole thing is empty. */ + return vstack.empty(); + } + + /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ + + /** Return value on the top of the stack (without popping it). */ + public int top() throws java.lang.Exception + { + if (vstack.empty()) + throw new Exception( + "Internal parser error: top() called on empty virtual stack"); + + return ((Integer)vstack.peek()).intValue(); + } + + /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ + + /** Pop the stack. */ + public void pop() throws java.lang.Exception + { + if (vstack.empty()) + throw new Exception( + "Internal parser error: pop from empty virtual stack"); + + /* pop it */ + vstack.pop(); + + /* if we are now empty transfer an element (if there is one) */ + if (vstack.empty()) + get_from_real(); + } + + /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ + + /** Push a state number onto the stack. */ + public void push(int state_num) + { + vstack.push(new Integer(state_num)); + } + + /*-----------------------------------------------------------*/ + +} diff --git a/tools/lexer/jflex-1.4/src/manifest b/tools/lexer/jflex-1.4/src/manifest new file mode 100644 index 000000000000..1e139295c20c --- /dev/null +++ b/tools/lexer/jflex-1.4/src/manifest @@ -0,0 +1 @@ +Main-Class: JFlex.Main diff --git a/tools/lexer/jflex-1.4/src/skeleton.default b/tools/lexer/jflex-1.4/src/skeleton.default new file mode 100644 index 000000000000..c2a807820775 --- /dev/null +++ b/tools/lexer/jflex-1.4/src/skeleton.default @@ -0,0 +1,317 @@ + + /** This character denotes the end of file */ + public static final int YYEOF = -1; + + /** initial size of the lookahead buffer */ +--- private static final int ZZ_BUFFERSIZE = ...; + + /** lexical states */ +--- lexical states, charmap + + /* error codes */ + private static final int ZZ_UNKNOWN_ERROR = 0; + private static final int ZZ_NO_MATCH = 1; + private static final int ZZ_PUSHBACK_2BIG = 2; + + /* error messages for the codes above */ + private static final String ZZ_ERROR_MSG[] = { + "Unkown internal scanner error", + "Error: could not match input", + "Error: pushback value was too large" + }; + +--- isFinal list + /** the input device */ + private java.io.Reader zzReader; + + /** the current state of the DFA */ + private int zzState; + + /** the current lexical state */ + private int zzLexicalState = YYINITIAL; + + /** this buffer contains the current text to be matched and is + the source of the yytext() string */ + private char zzBuffer[] = new char[ZZ_BUFFERSIZE]; + + /** the textposition at the last accepting state */ + private int zzMarkedPos; + + /** the textposition at the last state to be included in yytext */ + private int zzPushbackPos; + + /** the current text position in the buffer */ + private int zzCurrentPos; + + /** startRead marks the beginning of the yytext() string in the buffer */ + private int zzStartRead; + + /** endRead marks the last character in the buffer, that has been read + from input */ + private int zzEndRead; + + /** number of newlines encountered up to the start of the matched text */ + private int yyline; + + /** the number of characters up to the start of the matched text */ + private int yychar; + + /** + * the number of characters from the last newline up to the start of the + * matched text + */ + private int yycolumn; + + /** + * zzAtBOL == true <=> the scanner is currently at the beginning of a line + */ + private boolean zzAtBOL = true; + + /** zzAtEOF == true <=> the scanner is at the EOF */ + private boolean zzAtEOF; + +--- user class code + + /** + * Creates a new scanner + * There is also a java.io.InputStream version of this constructor. + * + * @param in the java.io.Reader to read input from. + */ +--- constructor declaration + + + /** + * Refills the input buffer. + * + * @return false, iff there was new input. + * + * @exception java.io.IOException if any I/O-Error occurs + */ + private boolean zzRefill() throws java.io.IOException { + + /* first: make room (if you can) */ + if (zzStartRead > 0) { + System.arraycopy(zzBuffer, zzStartRead, + zzBuffer, 0, + zzEndRead-zzStartRead); + + /* translate stored positions */ + zzEndRead-= zzStartRead; + zzCurrentPos-= zzStartRead; + zzMarkedPos-= zzStartRead; + zzPushbackPos-= zzStartRead; + zzStartRead = 0; + } + + /* is the buffer big enough? */ + if (zzCurrentPos >= zzBuffer.length) { + /* if not: blow it up */ + char newBuffer[] = new char[zzCurrentPos*2]; + System.arraycopy(zzBuffer, 0, newBuffer, 0, zzBuffer.length); + zzBuffer = newBuffer; + } + + /* finally: fill the buffer with new input */ + int numRead = zzReader.read(zzBuffer, zzEndRead, + zzBuffer.length-zzEndRead); + + if (numRead < 0) { + return true; + } + else { + zzEndRead+= numRead; + return false; + } + } + + + /** + * Closes the input stream. + */ + public final void yyclose() throws java.io.IOException { + zzAtEOF = true; /* indicate end of file */ + zzEndRead = zzStartRead; /* invalidate buffer */ + + if (zzReader != null) + zzReader.close(); + } + + + /** + * Resets the scanner to read from a new input stream. + * Does not close the old reader. + * + * All internal variables are reset, the old input stream + * cannot be reused (internal buffer is discarded and lost). + * Lexical state is set to ZZ_INITIAL. + * + * @param reader the new input stream + */ + public final void yyreset(java.io.Reader reader) { + zzReader = reader; + zzAtBOL = true; + zzAtEOF = false; + zzEndRead = zzStartRead = 0; + zzCurrentPos = zzMarkedPos = zzPushbackPos = 0; + yyline = yychar = yycolumn = 0; + zzLexicalState = YYINITIAL; + } + + + /** + * Returns the current lexical state. + */ + public final int yystate() { + return zzLexicalState; + } + + + /** + * Enters a new lexical state + * + * @param newState the new lexical state + */ + public final void yybegin(int newState) { + zzLexicalState = newState; + } + + + /** + * Returns the text matched by the current regular expression. + */ + public final String yytext() { + return new String( zzBuffer, zzStartRead, zzMarkedPos-zzStartRead ); + } + + + /** + * Returns the character at position pos from the + * matched text. + * + * It is equivalent to yytext().charAt(pos), but faster + * + * @param pos the position of the character to fetch. + * A value from 0 to yylength()-1. + * + * @return the character at position pos + */ + public final char yycharat(int pos) { + return zzBuffer[zzStartRead+pos]; + } + + + /** + * Returns the length of the matched text region. + */ + public final int yylength() { + return zzMarkedPos-zzStartRead; + } + + + /** + * Reports an error that occured while scanning. + * + * In a wellformed scanner (no or only correct usage of + * yypushback(int) and a match-all fallback rule) this method + * will only be called with things that "Can't Possibly Happen". + * If this method is called, something is seriously wrong + * (e.g. a JFlex bug producing a faulty scanner etc.). + * + * Usual syntax/scanner level error handling should be done + * in error fallback rules. + * + * @param errorCode the code of the errormessage to display + */ +--- zzScanError declaration + String message; + try { + message = ZZ_ERROR_MSG[errorCode]; + } + catch (ArrayIndexOutOfBoundsException e) { + message = ZZ_ERROR_MSG[ZZ_UNKNOWN_ERROR]; + } + +--- throws clause + } + + + /** + * Pushes the specified amount of characters back into the input stream. + * + * They will be read again by then next call of the scanning method + * + * @param number the number of characters to be read again. + * This number must not be greater than yylength()! + */ +--- yypushback decl (contains zzScanError exception) + if ( number > yylength() ) + zzScanError(ZZ_PUSHBACK_2BIG); + + zzMarkedPos -= number; + } + + +--- zzDoEOF + /** + * Resumes scanning until the next regular expression is matched, + * the end of input is encountered or an I/O-Error occurs. + * + * @return the next token + * @exception java.io.IOException if any I/O-Error occurs + */ +--- yylex declaration + int zzInput; + int zzAction; + + // cached fields: + int zzCurrentPosL; + int zzMarkedPosL; + int zzEndReadL = zzEndRead; + char [] zzBufferL = zzBuffer; + char [] zzCMapL = ZZ_CMAP; + +--- local declarations + + while (true) { + zzMarkedPosL = zzMarkedPos; + +--- start admin (line, char, col count) + zzAction = -1; + + zzCurrentPosL = zzCurrentPos = zzStartRead = zzMarkedPosL; + +--- start admin (lexstate etc) + + zzForAction: { + while (true) { + +--- next input, line, col, char count, next transition, isFinal action + zzAction = zzState; + zzMarkedPosL = zzCurrentPosL; +--- line count update + } + + } + } + + // store back cached position + zzMarkedPos = zzMarkedPosL; +--- char count update + +--- actions + default: + if (zzInput == YYEOF && zzStartRead == zzCurrentPos) { + zzAtEOF = true; +--- eofvalue + } + else { +--- no match + } + } + } + } + +--- main + +} diff --git a/tools/lexer/jflex-1.4/src/skeleton.nested b/tools/lexer/jflex-1.4/src/skeleton.nested new file mode 100644 index 000000000000..08350f14c353 --- /dev/null +++ b/tools/lexer/jflex-1.4/src/skeleton.nested @@ -0,0 +1,419 @@ + + /** This character denotes the end of file */ + public static final int YYEOF = -1; + + /** initial size of the lookahead buffer */ +--- private static final int ZZ_BUFFERSIZE = ...; + + /** lexical states */ +--- lexical states, charmap + + /* error codes */ + private static final int ZZ_UNKNOWN_ERROR = 0; + private static final int ZZ_NO_MATCH = 1; + private static final int ZZ_PUSHBACK_2BIG = 2; + + /* error messages for the codes above */ + private static final String ZZ_ERROR_MSG[] = { + "Unkown internal scanner error", + "Error: could not match input", + "Error: pushback value was too large" + }; + +--- isFinal list + /** the input device */ + private java.io.Reader zzReader; + + /** the current state of the DFA */ + private int zzState; + + /** the current lexical state */ + private int zzLexicalState = YYINITIAL; + + /** this buffer contains the current text to be matched and is + the source of the yytext() string */ + private char zzBuffer[] = new char[ZZ_BUFFERSIZE]; + + /** the textposition at the last accepting state */ + private int zzMarkedPos; + + /** the textposition at the last state to be included in yytext */ + private int zzPushbackPos; + + /** the current text position in the buffer */ + private int zzCurrentPos; + + /** startRead marks the beginning of the yytext() string in the buffer */ + private int zzStartRead; + + /** endRead marks the last character in the buffer, that has been read + from input */ + private int zzEndRead; + + /** number of newlines encountered up to the start of the matched text */ + private int yyline; + + /** the number of characters up to the start of the matched text */ + private int yychar; + + /** + * the number of characters from the last newline up to the start of the + * matched text + */ + private int yycolumn; + + /** + * zzAtBOL == true <=> the scanner is currently at the beginning of a line + */ + private boolean zzAtBOL = true; + + /** zzAtEOF == true <=> the scanner is at the EOF */ + private boolean zzAtEOF; + + + /** the stack of open (nested) input streams to read from */ + private java.util.Stack zzStreams = new java.util.Stack(); + + /** + * inner class used to store info for nested + * input streams + */ + private static final class ZzFlexStreamInfo { + java.io.Reader zzReader; + int zzEndRead; + int zzStartRead; + int zzCurrentPos; + int zzMarkedPos; + int zzPushbackPos; + int yyline; + int yycolumn; + char [] zzBuffer; + boolean zzAtEOF; + + /** sets all values stored in this class */ + ZzFlexStreamInfo(java.io.Reader zzReader, int zzEndRead, int zzStartRead, + int zzCurrentPos, int zzMarkedPos, int zzPushbackPos, + char [] zzBuffer, boolean zzAtEOF, int yyline, int yycolumn) { + this.zzReader = zzReader; + this.zzEndRead = zzEndRead; + this.zzStartRead = zzStartRead; + this.zzCurrentPos = zzCurrentPos; + this.zzMarkedPos = zzMarkedPos; + this.zzPushbackPos = zzPushbackPos; + this.zzBuffer = zzBuffer; + this.zzAtEOF = zzAtEOF; + this.yyline = yyline; + this.yycolumn = yycolumn; + } + } + +--- user class code + + /** + * Creates a new scanner + * There is also a java.io.InputStream version of this constructor. + * + * @param in the java.io.Reader to read input from. + */ +--- constructor declaration + + + /** + * Refills the input buffer. + * + * @return false, iff there was new input. + * + * @exception java.io.IOException if any I/O-Error occurs + */ + private boolean zzRefill() throws java.io.IOException { + + /* first: make room (if you can) */ + if (zzStartRead > 0) { + System.arraycopy(zzBuffer, zzStartRead, + zzBuffer, 0, + zzEndRead-zzStartRead); + + /* translate stored positions */ + zzEndRead-= zzStartRead; + zzCurrentPos-= zzStartRead; + zzMarkedPos-= zzStartRead; + zzPushbackPos-= zzStartRead; + zzStartRead = 0; + } + + /* is the buffer big enough? */ + if (zzCurrentPos >= zzBuffer.length) { + /* if not: blow it up */ + char newBuffer[] = new char[zzCurrentPos*2]; + System.arraycopy(zzBuffer, 0, newBuffer, 0, zzBuffer.length); + zzBuffer = newBuffer; + } + + /* finally: fill the buffer with new input */ + int numRead = zzReader.read(zzBuffer, zzEndRead, + zzBuffer.length-zzEndRead); + + if (numRead < 0) { + return true; + } + else { + zzEndRead+= numRead; + return false; + } + } + + + /** + * Closes the input stream. + */ + public final void yyclose() throws java.io.IOException { + zzAtEOF = true; /* indicate end of file */ + zzEndRead = zzStartRead; /* invalidate buffer */ + + if (zzReader != null) + zzReader.close(); + } + + + /** + * Stores the current input stream on a stack, and + * reads from a new stream. Lexical state, line, + * char, and column counting remain untouched. + * + * The current input stream can be restored with + * yypopstream (usually in an <> action). + * + * @param reader the new input stream to read from + * + * @see #yypopStream() + */ + public final void yypushStream(java.io.Reader reader) { + zzStreams.push( + new ZzFlexStreamInfo(zzReader, zzEndRead, zzStartRead, zzCurrentPos, + zzMarkedPos, zzPushbackPos, zzBuffer, zzAtEOF, + yyline, yycolumn) + ); + zzAtEOF = false; + zzBuffer = new char[ZZ_BUFFERSIZE]; + zzReader = reader; + zzEndRead = zzStartRead = 0; + zzCurrentPos = zzMarkedPos = zzPushbackPos = 0; + yyline = yycolumn = 0; + } + + + /** + * Closes the current input stream and continues to + * read from the one on top of the stream stack. + * + * @throws java.util.EmptyStackException + * if there is no further stream to read from. + * + * @throws java.io.IOException + * if there was an error in closing the stream. + * + * @see #yypushStream(java.io.Reader) + */ + public final void yypopStream() throws java.io.IOException { + zzReader.close(); + ZzFlexStreamInfo s = (ZzFlexStreamInfo) zzStreams.pop(); + zzBuffer = s.zzBuffer; + zzReader = s.zzReader; + zzEndRead = s.zzEndRead; + zzStartRead = s.zzStartRead; + zzCurrentPos = s.zzCurrentPos; + zzMarkedPos = s.zzMarkedPos ; + zzPushbackPos = s.zzPushbackPos; + zzAtEOF = s.zzAtEOF; + yyline = s.yyline; + yycolumn = s.yycolumn; + } + + + /** + * Returns true iff there are still streams left + * to read from on the stream stack. + */ + public final boolean yymoreStreams() { + return !zzStreams.isEmpty(); + } + + + /** + * Resets the scanner to read from a new input stream. + * Does not close the old reader. + * + * All internal variables are reset, the old input stream + * cannot be reused (internal buffer is discarded and lost). + * Lexical state is set to ZZ_INITIAL. + * + * @param reader the new input stream + * + * @see #yypushStream(java.io.Reader) + * @see #yypopStream() + */ + public final void yyreset(java.io.Reader reader) { + zzReader = reader; + zzAtBOL = true; + zzAtEOF = false; + zzEndRead = zzStartRead = 0; + zzCurrentPos = zzMarkedPos = zzPushbackPos = 0; + yyline = yychar = yycolumn = 0; + zzLexicalState = YYINITIAL; + } + + + /** + * Returns the current lexical state. + */ + public final int yystate() { + return zzLexicalState; + } + + + /** + * Enters a new lexical state + * + * @param newState the new lexical state + */ + public final void yybegin(int newState) { + zzLexicalState = newState; + } + + + /** + * Returns the text matched by the current regular expression. + */ + public final String yytext() { + return new String( zzBuffer, zzStartRead, zzMarkedPos-zzStartRead ); + } + + + /** + * Returns the character at position pos from the + * matched text. + * + * It is equivalent to yytext().charAt(pos), but faster + * + * @param pos the position of the character to fetch. + * A value from 0 to yylength()-1. + * + * @return the character at position pos + */ + public final char yycharat(int pos) { + return zzBuffer[zzStartRead+pos]; + } + + + /** + * Returns the length of the matched text region. + */ + public final int yylength() { + return zzMarkedPos-zzStartRead; + } + + + /** + * Reports an error that occured while scanning. + * + * In a wellformed scanner (no or only correct usage of + * yypushback(int) and a match-all fallback rule) this method + * will only be called with things that "Can't Possibly Happen". + * If this method is called, something is seriously wrong + * (e.g. a JFlex bug producing a faulty scanner etc.). + * + * Usual syntax/scanner level error handling should be done + * in error fallback rules. + * + * @param errorCode the code of the errormessage to display + */ +--- zzScanError declaration + String message; + try { + message = ZZ_ERROR_MSG[errorCode]; + } + catch (ArrayIndexOutOfBoundsException e) { + message = ZZ_ERROR_MSG[ZZ_UNKNOWN_ERROR]; + } + +--- throws clause + } + + + /** + * Pushes the specified amount of characters back into the input stream. + * + * They will be read again by then next call of the scanning method + * + * @param number the number of characters to be read again. + * This number must not be greater than yylength()! + */ +--- yypushback decl (contains zzScanError exception) + if ( number > yylength() ) + zzScanError(ZZ_PUSHBACK_2BIG); + + zzMarkedPos -= number; + } + + +--- zzDoEOF + /** + * Resumes scanning until the next regular expression is matched, + * the end of input is encountered or an I/O-Error occurs. + * + * @return the next token + * @exception java.io.IOException if any I/O-Error occurs + */ +--- yylex declaration + int zzInput; + int zzAction; + +--- local declarations + + while (true) { + // cached fields: + int zzCurrentPosL; + int zzMarkedPosL = zzMarkedPos; + int zzEndReadL = zzEndRead; + char [] zzBufferL = zzBuffer; + char [] zzCMapL = ZZ_CMAP; + +--- start admin (line, char, col count) + zzAction = -1; + + zzCurrentPosL = zzCurrentPos = zzStartRead = zzMarkedPosL; + +--- start admin (lexstate etc) + + zzForAction: { + while (true) { + +--- next input, line, col, char count, next transition, isFinal action + zzAction = zzState; + zzMarkedPosL = zzCurrentPosL; +--- line count update + } + + } + } + + // store back cached position + zzMarkedPos = zzMarkedPosL; +--- char count update + +--- actions + default: + if (zzInput == YYEOF && zzStartRead == zzCurrentPos) { + zzAtEOF = true; +--- eofvalue + } + else { +--- no match + } + } + } + } + +--- main + +} From e867fa469ac84099e83e290bdbefa6c2d4becf3d Mon Sep 17 00:00:00 2001 From: Alexey Kudravtsev Date: Fri, 25 Dec 2009 18:31:41 +0300 Subject: [PATCH 19/67] diagnostics --- .../intellij/testFramework/LightPlatformTestCase.java | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/platform/testFramework/src/com/intellij/testFramework/LightPlatformTestCase.java b/platform/testFramework/src/com/intellij/testFramework/LightPlatformTestCase.java index e2f2c7094f4c..757081f6d7c4 100644 --- a/platform/testFramework/src/com/intellij/testFramework/LightPlatformTestCase.java +++ b/platform/testFramework/src/com/intellij/testFramework/LightPlatformTestCase.java @@ -84,8 +84,10 @@ import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import javax.swing.*; +import java.io.ByteArrayOutputStream; import java.io.File; import java.io.IOException; +import java.io.PrintStream; import java.lang.reflect.InvocationTargetException; import java.util.ArrayList; import java.util.Collection; @@ -189,7 +191,12 @@ public abstract class LightPlatformTestCase extends UsefulTestCase implements Da } LocalFileSystem.getInstance().refreshAndFindFileByIoFile(projectFile); - ourProject = ProjectManagerEx.getInstanceEx().newProject(FileUtil.getNameWithoutExtension(projectFile), projectFile.getPath(), false, false); + + ByteArrayOutputStream buffer = new ByteArrayOutputStream(); + new Throwable(projectFile.getPath()).printStackTrace(new PrintStream(buffer)); + + ourProject = PlatformTestCase.createProject(projectFile, buffer.toString()); + if (!ourHaveShutdownHook) { ourHaveShutdownHook = true; registerShutdownHook(); From 4dcc4a28e28776bac5190a36d7c5866ffc992cdc Mon Sep 17 00:00:00 2001 From: Alexey Kudravtsev Date: Fri, 25 Dec 2009 18:39:08 +0300 Subject: [PATCH 20/67] autoimport in injected context is visible --- .../codeInsight/daemon/impl/GeneralHighlightingPass.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/GeneralHighlightingPass.java b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/GeneralHighlightingPass.java index f51eb7287c5b..7a4390553b18 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/GeneralHighlightingPass.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/GeneralHighlightingPass.java @@ -285,7 +285,8 @@ public class GeneralHighlightingPass extends ProgressableTextEditorHighlightingP HighlightInfo patched = new HighlightInfo(info.forcedTextAttributes, info.type, hostRange.getStartOffset(), hostRange.getEndOffset(), info.description, info.toolTip, info.type.getSeverity(null), info.isAfterEndOfLine, null, false); - + patched.setHint(info.hasHint()); + if (info.quickFixActionRanges != null) { for (Pair pair : info.quickFixActionRanges) { TextRange quickfixTextRange = pair.getSecond(); From 5912e046c7bb46b7a873ad84ae91de4ac5198bf1 Mon Sep 17 00:00:00 2001 From: Dmitry Jemerov Date: Fri, 25 Dec 2009 17:59:43 +0300 Subject: [PATCH 21/67] tests for forthcoming functionality, cleanup and refactoring --- .../testFramework/fixtures/CodeInsightTestFixture.java | 2 ++ .../fixtures/impl/CodeInsightTestFixtureImpl.java | 10 ++++++++-- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/platform/testFramework/src/com/intellij/testFramework/fixtures/CodeInsightTestFixture.java b/platform/testFramework/src/com/intellij/testFramework/fixtures/CodeInsightTestFixture.java index 3e68bd591d53..68aab0659315 100644 --- a/platform/testFramework/src/com/intellij/testFramework/fixtures/CodeInsightTestFixture.java +++ b/platform/testFramework/src/com/intellij/testFramework/fixtures/CodeInsightTestFixture.java @@ -320,5 +320,7 @@ public interface CodeInsightTestFixture extends IdeaProjectTestFixture { void renameElementAtCaret(String newName) throws Exception; + void renameElement(PsiElement element, String newName) throws Exception; + void allowTreeAccessForFile(VirtualFile file); } diff --git a/platform/testFramework/src/com/intellij/testFramework/fixtures/impl/CodeInsightTestFixtureImpl.java b/platform/testFramework/src/com/intellij/testFramework/fixtures/impl/CodeInsightTestFixtureImpl.java index 3205bf938fe1..f427e38eff25 100644 --- a/platform/testFramework/src/com/intellij/testFramework/fixtures/impl/CodeInsightTestFixtureImpl.java +++ b/platform/testFramework/src/com/intellij/testFramework/fixtures/impl/CodeInsightTestFixtureImpl.java @@ -501,10 +501,16 @@ public class CodeInsightTestFixtureImpl extends BaseFixture implements CodeInsig public void renameElementAtCaret(final String newName) throws Exception { assertInitialized(); + final PsiElement element = TargetElementUtilBase.findTargetElement(getCompletionEditor(), TargetElementUtilBase.REFERENCED_ELEMENT_ACCEPTED | + TargetElementUtilBase.ELEMENT_NAME_ACCEPTED); + assert element != null : "element not found in file " + myFile.getName() + " at caret position, offset " + + myEditor.getCaretModel().getOffset(); + renameElement(element, newName); + } + + public void renameElement(final PsiElement element, final String newName) throws Exception { new WriteCommandAction.Simple(myProjectFixture.getProject()) { protected void run() throws Exception { - PsiElement element = TargetElementUtilBase.findTargetElement(getCompletionEditor(), TargetElementUtilBase.REFERENCED_ELEMENT_ACCEPTED | TargetElementUtilBase.ELEMENT_NAME_ACCEPTED); - assert element != null: "element not found in file " + myFile.getName() + " at caret position, offset " + myEditor.getCaretModel().getOffset(); final PsiElement substitution = RenamePsiElementProcessor.forElement(element).substituteElementToRename(element, myEditor); new RenameProcessor(myProjectFixture.getProject(), substitution, newName, false, false).run(); } From df02432118044188a5b95f84a89fe267f37f1064 Mon Sep 17 00:00:00 2001 From: Dmitry Jemerov Date: Fri, 25 Dec 2009 19:44:48 +0300 Subject: [PATCH 22/67] reference from render_to_response to template file --- .../fixtures/impl/LightTempDirTestFixtureImpl.java | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/platform/testFramework/src/com/intellij/testFramework/fixtures/impl/LightTempDirTestFixtureImpl.java b/platform/testFramework/src/com/intellij/testFramework/fixtures/impl/LightTempDirTestFixtureImpl.java index cc417c15cc66..818e59c3a2c3 100644 --- a/platform/testFramework/src/com/intellij/testFramework/fixtures/impl/LightTempDirTestFixtureImpl.java +++ b/platform/testFramework/src/com/intellij/testFramework/fixtures/impl/LightTempDirTestFixtureImpl.java @@ -134,7 +134,13 @@ public class LightTempDirTestFixtureImpl extends BaseFixture implements TempDirT } public VirtualFile getFile(@NonNls String path) { - return getSourceRoot().findFileByRelativePath(path); + final VirtualFile sourceRoot = getSourceRoot(); + final VirtualFile result = sourceRoot.findFileByRelativePath(path); + if (result == null) { + sourceRoot.refresh(false, true); + return sourceRoot.findFileByRelativePath(path); + } + return result; } @NotNull From 70c505b519a5463bcf31ee6577fa99a074514d01 Mon Sep 17 00:00:00 2001 From: Dmitry Jemerov Date: Fri, 25 Dec 2009 20:14:42 +0300 Subject: [PATCH 23/67] correct filtering of goto file model when language substitutors are used (PY-269) --- .../intellij/ide/util/gotoByName/GotoFileModel.java | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/platform/lang-impl/src/com/intellij/ide/util/gotoByName/GotoFileModel.java b/platform/lang-impl/src/com/intellij/ide/util/gotoByName/GotoFileModel.java index bd0a6194bd77..b0f23436c123 100644 --- a/platform/lang-impl/src/com/intellij/ide/util/gotoByName/GotoFileModel.java +++ b/platform/lang-impl/src/com/intellij/ide/util/gotoByName/GotoFileModel.java @@ -70,7 +70,15 @@ public class GotoFileModel extends ContributorsBasedGotoByModel{ if (item instanceof PsiFile) { final PsiFile file = (PsiFile)item; final Set types = getFileTypes(); - return types == null || types.contains(file.getFileType()); + // if language substitutors are used, PsiFile.getFileType() can be different from + // PsiFile.getVirtualFile().getFileType() + if (types != null) { + if (types.contains(file.getFileType())) return true; + VirtualFile vFile = file.getVirtualFile(); + if (vFile != null && types.contains(vFile.getFileType())) return true; + return false; + } + return true; } else { return super.acceptItem(item); From cc842765e833e577ec3ed22f7363bc076bff4f8f Mon Sep 17 00:00:00 2001 From: nik Date: Mon, 28 Dec 2009 11:08:26 +0300 Subject: [PATCH 24/67] editor remote file improved: refresh and jump to source actions added, url field added --- .../http/JumpFromRemoteFileToLocalAction.java | 102 +++++++++++++++ .../LangRemoteFileEditorActionProvider.java | 32 +++++ .../ide/actions/OpenRemoteFileAction.java | 5 +- .../openapi/editor/impl/ContextMenuImpl.java | 3 +- .../fileEditor/impl/http/HttpFileEditor.java | 88 ++++++++++--- .../impl/http/HttpFileEditorProvider.java | 9 +- .../fileEditor/impl/http/LocalFileFinder.java | 32 +++++ .../impl/http/RefreshRemoteFileAction.java | 45 +++++++ .../http/RemoteFileEditorActionProvider.java | 33 +++++ ...oteFilePanel.form => RemoteFilePanel.form} | 69 ++++++++-- ...oteFilePanel.java => RemoteFilePanel.java} | 120 ++++++++++++++---- .../http/DefaultRemoteContentProvider.java | 3 +- .../vfs/impl/http/FileDownloadingAdapter.java | 8 +- .../impl/http/FileDownloadingListener.java | 6 +- .../vfs/impl/http/HttpFileSystemImpl.java | 11 +- .../vfs/impl/http/RemoteContentProvider.java | 2 +- .../openapi/vfs/impl/http/RemoteFileInfo.java | 89 ++++++++----- .../vfs/impl/http/RemoteFileManager.java | 15 +-- .../vfs/impl/http/RemoteFileState.java | 23 ++++ .../src/META-INF/LangExtensions.xml | 2 + .../src/META-INF/PlatformExtensionPoints.xml | 3 + 21 files changed, 591 insertions(+), 109 deletions(-) create mode 100644 platform/lang-impl/src/com/intellij/openapi/fileEditor/impl/http/JumpFromRemoteFileToLocalAction.java create mode 100644 platform/lang-impl/src/com/intellij/openapi/fileEditor/impl/http/LangRemoteFileEditorActionProvider.java create mode 100644 platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/http/LocalFileFinder.java create mode 100644 platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/http/RefreshRemoteFileAction.java create mode 100644 platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/http/RemoteFileEditorActionProvider.java rename platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/http/{DownloadRemoteFilePanel.form => RemoteFilePanel.form} (68%) rename platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/http/{DownloadRemoteFilePanel.java => RemoteFilePanel.java} (56%) create mode 100644 platform/platform-impl/src/com/intellij/openapi/vfs/impl/http/RemoteFileState.java diff --git a/platform/lang-impl/src/com/intellij/openapi/fileEditor/impl/http/JumpFromRemoteFileToLocalAction.java b/platform/lang-impl/src/com/intellij/openapi/fileEditor/impl/http/JumpFromRemoteFileToLocalAction.java new file mode 100644 index 000000000000..c1a5969a8f11 --- /dev/null +++ b/platform/lang-impl/src/com/intellij/openapi/fileEditor/impl/http/JumpFromRemoteFileToLocalAction.java @@ -0,0 +1,102 @@ +/* + * Copyright 2000-2009 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 com.intellij.openapi.fileEditor.impl.http; + +import com.intellij.CommonBundle; +import com.intellij.openapi.actionSystem.AnAction; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.fileEditor.OpenFileDescriptor; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.roots.ui.util.CellAppearanceUtils; +import com.intellij.openapi.ui.Messages; +import com.intellij.openapi.ui.popup.PopupChooserBuilder; +import com.intellij.openapi.util.IconLoader; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.openapi.vfs.impl.http.HttpVirtualFile; +import com.intellij.openapi.vfs.impl.http.RemoteFileState; +import com.intellij.psi.search.FilenameIndex; +import com.intellij.psi.search.GlobalSearchScope; +import com.intellij.ui.ColoredListCellRenderer; +import com.intellij.util.containers.ContainerUtil; +import org.jetbrains.annotations.NotNull; + +import javax.swing.*; +import java.util.Collection; + +/** + * @author nik + */ +public class JumpFromRemoteFileToLocalAction extends AnAction { + private HttpVirtualFile myFile; + private final Project myProject; + + public JumpFromRemoteFileToLocalAction(HttpVirtualFile file, Project project) { + super("Find Local File", "", IconLoader.findIcon("/general/autoscrollToSource.png")); + myFile = file; + myProject = project; + } + + @Override + public void update(AnActionEvent e) { + final RemoteFileState state = myFile.getFileInfo().getState(); + e.getPresentation().setEnabled(state == RemoteFileState.DOWNLOADED); + } + + @Override + public void actionPerformed(AnActionEvent e) { + final String url = myFile.getUrl(); + for (LocalFileFinder finder : LocalFileFinder.EP_NAME.getExtensions()) { + final VirtualFile file = finder.findLocalFile(url, myProject); + if (file != null) { + navigateToFile(myProject, file); + } + } + + final Collection files = + FilenameIndex.getVirtualFilesByName(myProject, myFile.getName(), GlobalSearchScope.allScope(myProject)); + if (files.isEmpty()) { + Messages.showErrorDialog(myProject, "Cannot find local file for '" + url + "'", CommonBundle.getErrorTitle()); + return; + } + + if (files.size() == 1) { + navigateToFile(myProject, ContainerUtil.getFirstItem(files, null)); + } + else { + final JList list = new JList(files.toArray(new VirtualFile[files.size()])); + list.setCellRenderer(new ColoredListCellRenderer() { + @Override + protected void customizeCellRenderer(JList list, Object value, int index, boolean selected, boolean hasFocus) { + CellAppearanceUtils.forVirtualFile((VirtualFile)value).customize(this); + } + }); + new PopupChooserBuilder(list) + .setTitle("Select Target File") + .setMovable(true) + .setItemChoosenCallback(new Runnable() { + public void run() { + for (Object value : list.getSelectedValues()) { + navigateToFile(myProject, (VirtualFile)value); + } + } + }).createPopup().showUnderneathOf(e.getInputEvent().getComponent()); + } + } + + private static void navigateToFile(Project project, @NotNull VirtualFile file) { + new OpenFileDescriptor(project, file).navigate(true); + } +} diff --git a/platform/lang-impl/src/com/intellij/openapi/fileEditor/impl/http/LangRemoteFileEditorActionProvider.java b/platform/lang-impl/src/com/intellij/openapi/fileEditor/impl/http/LangRemoteFileEditorActionProvider.java new file mode 100644 index 000000000000..766c6e2563bb --- /dev/null +++ b/platform/lang-impl/src/com/intellij/openapi/fileEditor/impl/http/LangRemoteFileEditorActionProvider.java @@ -0,0 +1,32 @@ +/* + * Copyright 2000-2009 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 com.intellij.openapi.fileEditor.impl.http; + +import com.intellij.openapi.actionSystem.AnAction; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.vfs.impl.http.HttpVirtualFile; +import org.jetbrains.annotations.NotNull; + +/** + * @author nik + */ +public class LangRemoteFileEditorActionProvider extends RemoteFileEditorActionProvider { + @NotNull + @Override + public AnAction[] createToolbarActions(@NotNull Project project, @NotNull HttpVirtualFile file) { + return new AnAction[] {new JumpFromRemoteFileToLocalAction(file, project)}; + } +} diff --git a/platform/platform-impl/src/com/intellij/ide/actions/OpenRemoteFileAction.java b/platform/platform-impl/src/com/intellij/ide/actions/OpenRemoteFileAction.java index c0062276e84f..548159d1c7e6 100644 --- a/platform/platform-impl/src/com/intellij/ide/actions/OpenRemoteFileAction.java +++ b/platform/platform-impl/src/com/intellij/ide/actions/OpenRemoteFileAction.java @@ -15,6 +15,7 @@ */ package com.intellij.ide.actions; +import com.intellij.CommonBundle; import com.intellij.openapi.actionSystem.AnAction; import com.intellij.openapi.actionSystem.AnActionEvent; import com.intellij.openapi.actionSystem.PlatformDataKeys; @@ -40,11 +41,11 @@ public class OpenRemoteFileAction extends AnAction implements DumbAware { public void actionPerformed(final AnActionEvent e) { Project project = e.getData(PlatformDataKeys.PROJECT); String defaultUrl = "http://localhost:8080/index.html"; - String url = Messages.showInputDialog(project, "URL", "Open Remote File", null, defaultUrl, null); + String url = Messages.showInputDialog(project, "URL:", "Open Remote File", null, defaultUrl, null); if (url != null) { VirtualFile file = VirtualFileManager.getInstance().findFileByUrl(url); if (file == null) { - Messages.showErrorDialog(project, "Cannot find file '" + url + "'", "Cannot Open File"); + Messages.showErrorDialog(project, "Cannot find file '" + url + "'", CommonBundle.getErrorTitle()); } else { FileEditorManager.getInstance(project).openFile(file, true); diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/impl/ContextMenuImpl.java b/platform/platform-impl/src/com/intellij/openapi/editor/impl/ContextMenuImpl.java index 23f8cc51db44..708f5ef2808f 100644 --- a/platform/platform-impl/src/com/intellij/openapi/editor/impl/ContextMenuImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/editor/impl/ContextMenuImpl.java @@ -30,6 +30,7 @@ import com.intellij.openapi.fileEditor.FileDocumentManager; import com.intellij.openapi.keymap.ex.KeymapManagerEx; import com.intellij.openapi.vfs.LocalFileSystem; import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.openapi.vfs.impl.http.HttpVirtualFile; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -201,7 +202,7 @@ public class ContextMenuImpl extends JPanel implements Disposable { } final VirtualFile file = FileDocumentManager.getInstance().getFile(document); - return file != null && file.isValid() && file.getFileSystem() == LocalFileSystem.getInstance(); + return file != null && file.isValid() && (file.getFileSystem() == LocalFileSystem.getInstance() || file instanceof HttpVirtualFile); } private void scheduleHide() { diff --git a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/http/HttpFileEditor.java b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/http/HttpFileEditor.java index 2f8ba7ba9759..0cb520b7d42c 100644 --- a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/http/HttpFileEditor.java +++ b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/http/HttpFileEditor.java @@ -17,15 +17,15 @@ package com.intellij.openapi.fileEditor.impl.http; import com.intellij.codeHighlighting.BackgroundEditorHighlighter; import com.intellij.ide.structureView.StructureViewBuilder; -import com.intellij.openapi.fileEditor.FileEditor; -import com.intellij.openapi.fileEditor.FileEditorLocation; -import com.intellij.openapi.fileEditor.FileEditorState; -import com.intellij.openapi.fileEditor.FileEditorStateLevel; +import com.intellij.openapi.fileEditor.*; import com.intellij.openapi.fileEditor.impl.text.TextEditorState; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.Key; import com.intellij.openapi.util.UserDataHolderBase; import com.intellij.openapi.vfs.impl.http.HttpVirtualFile; -import com.intellij.openapi.project.Project; +import com.intellij.pom.Navigatable; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import javax.swing.*; import java.beans.PropertyChangeListener; @@ -33,22 +33,25 @@ import java.beans.PropertyChangeListener; /** * @author nik */ -public class HttpFileEditor extends UserDataHolderBase implements FileEditor { - private final HttpVirtualFile myVirtualFile; - private final DownloadRemoteFilePanel myDownloadPanel; +public class HttpFileEditor implements NavigatableFileEditor { + private final UserDataHolderBase myUserDataHolder = new UserDataHolderBase(); + private final RemoteFilePanel myPanel; public HttpFileEditor(final Project project, final HttpVirtualFile virtualFile) { - myVirtualFile = virtualFile; - myDownloadPanel = new DownloadRemoteFilePanel(project, virtualFile); + myPanel = new RemoteFilePanel(project, virtualFile); } @NotNull public JComponent getComponent() { - return myDownloadPanel.getMainPanel(); + return myPanel.getMainPanel(); } public JComponent getPreferredFocusedComponent() { - return myDownloadPanel.getMainPanel(); + final TextEditor textEditor = myPanel.getFileEditor(); + if (textEditor != null) { + return textEditor.getPreferredFocusedComponent(); + } + return myPanel.getMainPanel(); } @NotNull @@ -58,10 +61,18 @@ public class HttpFileEditor extends UserDataHolderBase implements FileEditor { @NotNull public FileEditorState getState(@NotNull final FileEditorStateLevel level) { + final TextEditor textEditor = myPanel.getFileEditor(); + if (textEditor != null) { + return textEditor.getState(level); + } return new TextEditorState(); } public void setState(@NotNull final FileEditorState state) { + final TextEditor textEditor = myPanel.getFileEditor(); + if (textEditor != null) { + textEditor.setState(state); + } } public boolean isModified() { @@ -73,32 +84,79 @@ public class HttpFileEditor extends UserDataHolderBase implements FileEditor { } public void selectNotify() { - myDownloadPanel.showNotify(); + myPanel.selectNotify(); } public void deselectNotify() { - myDownloadPanel.hideNotify(); + myPanel.deselectNotify(); } public void addPropertyChangeListener(@NotNull final PropertyChangeListener listener) { + myPanel.addPropertyChangeListener(listener); } public void removePropertyChangeListener(@NotNull final PropertyChangeListener listener) { + myPanel.removePropertyChangeListener(listener); } public BackgroundEditorHighlighter getBackgroundHighlighter() { + final TextEditor textEditor = myPanel.getFileEditor(); + if (textEditor != null) { + return textEditor.getBackgroundHighlighter(); + } return null; } + public boolean canNavigateTo(@NotNull Navigatable navigatable) { + final TextEditor textEditor = myPanel.getFileEditor(); + if (textEditor != null) { + return textEditor.canNavigateTo(navigatable); + } + return false; + } + + public void navigateTo(@NotNull Navigatable navigatable) { + final TextEditor textEditor = myPanel.getFileEditor(); + if (textEditor != null) { + textEditor.navigateTo(navigatable); + } + } + + public T getUserData(@NotNull Key key) { + final TextEditor textEditor = myPanel.getFileEditor(); + if (textEditor != null) { + return textEditor.getUserData(key); + } + return myUserDataHolder.getUserData(key); + } + + public void putUserData(@NotNull Key key, @Nullable T value) { + final TextEditor textEditor = myPanel.getFileEditor(); + if (textEditor != null) { + textEditor.putUserData(key, value); + } + else { + myUserDataHolder.putUserData(key, value); + } + } + public FileEditorLocation getCurrentLocation() { + final TextEditor textEditor = myPanel.getFileEditor(); + if (textEditor != null) { + return textEditor.getCurrentLocation(); + } return null; } public StructureViewBuilder getStructureViewBuilder() { + final TextEditor textEditor = myPanel.getFileEditor(); + if (textEditor != null) { + return textEditor.getStructureViewBuilder(); + } return null; } public void dispose() { - myDownloadPanel.dispose(); + myPanel.dispose(); } } diff --git a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/http/HttpFileEditorProvider.java b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/http/HttpFileEditorProvider.java index dbd4ccfb0827..cfd3626b6830 100644 --- a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/http/HttpFileEditorProvider.java +++ b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/http/HttpFileEditorProvider.java @@ -19,13 +19,11 @@ import com.intellij.openapi.fileEditor.FileEditor; import com.intellij.openapi.fileEditor.FileEditorPolicy; import com.intellij.openapi.fileEditor.FileEditorProvider; import com.intellij.openapi.fileEditor.FileEditorState; -import com.intellij.openapi.fileEditor.impl.text.TextEditorProvider; import com.intellij.openapi.fileEditor.impl.text.TextEditorState; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Disposer; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.openapi.vfs.impl.http.HttpVirtualFile; -import com.intellij.openapi.vfs.impl.http.RemoteFileInfo; import org.jdom.Element; import org.jetbrains.annotations.NotNull; @@ -39,12 +37,7 @@ public class HttpFileEditorProvider implements FileEditorProvider { @NotNull public FileEditor createEditor(@NotNull final Project project, @NotNull final VirtualFile file) { - HttpVirtualFile virtualFile = (HttpVirtualFile)file; - RemoteFileInfo remoteFileInfo = virtualFile.getFileInfo(); - if (remoteFileInfo.isDownloaded()) { - return TextEditorProvider.getInstance().createEditor(project, file); - } - return new HttpFileEditor(project, virtualFile); + return new HttpFileEditor(project, (HttpVirtualFile)file); } public void disposeEditor(@NotNull final FileEditor editor) { diff --git a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/http/LocalFileFinder.java b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/http/LocalFileFinder.java new file mode 100644 index 000000000000..9137eb5245ab --- /dev/null +++ b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/http/LocalFileFinder.java @@ -0,0 +1,32 @@ +/* + * Copyright 2000-2009 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 com.intellij.openapi.fileEditor.impl.http; + +import com.intellij.openapi.extensions.ExtensionPointName; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.vfs.VirtualFile; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +/** + * @author nik + */ +public abstract class LocalFileFinder { + public static final ExtensionPointName EP_NAME = ExtensionPointName.create("com.intellij.http.localFileFinder"); + + @Nullable + public abstract VirtualFile findLocalFile(@NotNull String url, @NotNull Project project); +} diff --git a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/http/RefreshRemoteFileAction.java b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/http/RefreshRemoteFileAction.java new file mode 100644 index 000000000000..385e20476c91 --- /dev/null +++ b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/http/RefreshRemoteFileAction.java @@ -0,0 +1,45 @@ +/* + * Copyright 2000-2009 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 com.intellij.openapi.fileEditor.impl.http; + +import com.intellij.openapi.actionSystem.AnAction; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.util.IconLoader; +import com.intellij.openapi.vfs.impl.http.HttpVirtualFile; +import com.intellij.openapi.vfs.impl.http.RemoteFileState; + +/** + * @author nik + */ +public class RefreshRemoteFileAction extends AnAction { + private HttpVirtualFile myFile; + + public RefreshRemoteFileAction(HttpVirtualFile file) { + super("Reload File", "", IconLoader.findIcon("/actions/sync.png")); + myFile = file; + } + + @Override + public void update(AnActionEvent e) { + final RemoteFileState state = myFile.getFileInfo().getState(); + e.getPresentation().setEnabled(state == RemoteFileState.DOWNLOADED || state == RemoteFileState.ERROR_OCCURRED); + } + + @Override + public void actionPerformed(AnActionEvent e) { + myFile.refresh(true, false); + } +} diff --git a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/http/RemoteFileEditorActionProvider.java b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/http/RemoteFileEditorActionProvider.java new file mode 100644 index 000000000000..fea1479eaaf4 --- /dev/null +++ b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/http/RemoteFileEditorActionProvider.java @@ -0,0 +1,33 @@ +/* + * Copyright 2000-2009 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 com.intellij.openapi.fileEditor.impl.http; + +import com.intellij.openapi.actionSystem.AnAction; +import com.intellij.openapi.extensions.ExtensionPointName; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.vfs.impl.http.HttpVirtualFile; +import org.jetbrains.annotations.NotNull; + +/** + * @author nik + */ +public abstract class RemoteFileEditorActionProvider { + public static final ExtensionPointName EP_NAME = ExtensionPointName.create("com.intellij.http.fileEditorActionProvider"); + + @NotNull + public abstract AnAction[] createToolbarActions(@NotNull Project project, @NotNull HttpVirtualFile file); + +} diff --git a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/http/DownloadRemoteFilePanel.form b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/http/RemoteFilePanel.form similarity index 68% rename from platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/http/DownloadRemoteFilePanel.form rename to platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/http/RemoteFilePanel.form index 85e3e579f5a7..8d0287ec077e 100644 --- a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/http/DownloadRemoteFilePanel.form +++ b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/http/RemoteFilePanel.form @@ -1,27 +1,22 @@ -
- - + + + - - - - - - + - - + + @@ -33,7 +28,7 @@ - + @@ -62,10 +57,15 @@ + + + + + - - + + @@ -111,8 +111,49 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/http/DownloadRemoteFilePanel.java b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/http/RemoteFilePanel.java similarity index 56% rename from platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/http/DownloadRemoteFilePanel.java rename to platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/http/RemoteFilePanel.java index 0c4d0ed07b4f..03152dc8b811 100644 --- a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/http/DownloadRemoteFilePanel.java +++ b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/http/RemoteFilePanel.java @@ -15,34 +15,43 @@ */ package com.intellij.openapi.fileEditor.impl.http; +import com.intellij.openapi.actionSystem.*; import com.intellij.openapi.application.ApplicationManager; -import com.intellij.openapi.fileEditor.FileEditorManager; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.fileEditor.TextEditor; +import com.intellij.openapi.fileEditor.impl.text.TextEditorProvider; import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.Disposer; import com.intellij.openapi.util.IconLoader; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.openapi.vfs.impl.http.FileDownloadingListener; import com.intellij.openapi.vfs.impl.http.HttpVirtualFile; import com.intellij.openapi.vfs.impl.http.RemoteFileInfo; -import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.vfs.impl.http.RemoteFileState; +import com.intellij.util.EventDispatcher; +import com.intellij.util.net.HTTPProxySettingsDialog; import com.intellij.util.ui.update.MergingUpdateQueue; import com.intellij.util.ui.update.Update; -import com.intellij.util.net.HTTPProxySettingsDialog; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import javax.swing.*; import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; /** * @author nik */ -public class DownloadRemoteFilePanel { - private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.fileEditor.impl.http.DownloadRemoteFilePanel"); +public class RemoteFilePanel implements PropertyChangeListener { + private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.fileEditor.impl.http.RemoteFilePanel"); private static final Icon ERROR_ICON = IconLoader.getIcon("/runConfigurations/configurationWarning.png"); @NonNls private static final String ERROR_CARD = "error"; @NonNls private static final String DOWNLOADING_CARD = "downloading"; + @NonNls private static final String EDITOR_CARD = "editor"; private JPanel myMainPanel; private JLabel myProgressLabel; private JProgressBar myProgressBar; @@ -51,16 +60,23 @@ public class DownloadRemoteFilePanel { private JLabel myErrorLabel; private JButton myTryAgainButton; private JButton myChangeProxySettingsButton; + private JPanel myEditorPanel; + private JTextField myUrlTextField; + private JPanel myToolbarPanel; private final Project myProject; private final HttpVirtualFile myVirtualFile; private final MergingUpdateQueue myProgressUpdatesQueue; private final MyDownloadingListener myDownloadingListener; + private final EventDispatcher myDispatcher = EventDispatcher.create(PropertyChangeListener.class); + private @Nullable TextEditor myFileEditor; - public DownloadRemoteFilePanel(final Project project, final HttpVirtualFile virtualFile) { + public RemoteFilePanel(final Project project, final HttpVirtualFile virtualFile) { myProject = project; myVirtualFile = virtualFile; myErrorLabel.setIcon(ERROR_ICON); + myUrlTextField.setText(virtualFile.getUrl()); myProgressUpdatesQueue = new MergingUpdateQueue("downloading progress updates", 300, false, myMainPanel); + initToolbar(project); final RemoteFileInfo remoteFileInfo = virtualFile.getFileInfo(); myDownloadingListener = new MyDownloadingListener(); @@ -84,17 +100,27 @@ public class DownloadRemoteFilePanel { }); showCard(DOWNLOADING_CARD); remoteFileInfo.startDownloading(); - if (remoteFileInfo.isDownloaded()) { + if (remoteFileInfo.getState() == RemoteFileState.DOWNLOADED) { switchEditor(); } else { String errorMessage = remoteFileInfo.getErrorMessage(); if (errorMessage != null) { - myDownloadingListener.errorOccured(errorMessage); + myDownloadingListener.errorOccurred(errorMessage); } } } + private void initToolbar(Project project) { + DefaultActionGroup group = new DefaultActionGroup(); + group.add(new RefreshRemoteFileAction(myVirtualFile)); + for (RemoteFileEditorActionProvider actionProvider : RemoteFileEditorActionProvider.EP_NAME.getExtensions()) { + group.addAll(actionProvider.createToolbarActions(project, myVirtualFile)); + } + final ActionToolbar actionToolbar = ActionManager.getInstance().createActionToolbar(ActionPlaces.UNKNOWN, group, true); + myToolbarPanel.add(actionToolbar.getComponent(), BorderLayout.CENTER); + } + private void showCard(final String name) { ((CardLayout)myContentPanel.getLayout()).show(myContentPanel, name); } @@ -103,34 +129,58 @@ public class DownloadRemoteFilePanel { LOG.debug("Switching editor..."); ApplicationManager.getApplication().invokeLater(new Runnable() { public void run() { - final FileEditorManager fileEditorManager = FileEditorManager.getInstance(myProject); - fileEditorManager.closeFile(myVirtualFile); - ApplicationManager.getApplication().invokeLater(new Runnable() { - public void run() { - //todo[nik] use ActionCallback - fileEditorManager.openFile(myVirtualFile, true); - LOG.debug("Editor for downloaded file opened."); - } - }); + final TextEditor textEditor = (TextEditor)TextEditorProvider.getInstance().createEditor(myProject, myVirtualFile); + textEditor.addPropertyChangeListener(RemoteFilePanel.this); + myEditorPanel.removeAll(); + myEditorPanel.add(textEditor.getComponent(), BorderLayout.CENTER); + myFileEditor = textEditor; + showCard(EDITOR_CARD); + LOG.debug("Editor for downloaded file opened."); } }); } + @Nullable + public TextEditor getFileEditor() { + return myFileEditor; + } + public JPanel getMainPanel() { return myMainPanel; } - public void showNotify() { + public void selectNotify() { myProgressUpdatesQueue.showNotify(); + if (myFileEditor != null) { + myFileEditor.selectNotify(); + } } - public void hideNotify() { + public void deselectNotify() { myProgressUpdatesQueue.hideNotify(); + if (myFileEditor != null) { + myFileEditor.deselectNotify(); + } } public void dispose() { myVirtualFile.getFileInfo().removeDownloadingListener(myDownloadingListener); myProgressUpdatesQueue.dispose(); + if (myFileEditor != null) { + Disposer.dispose(myFileEditor); + } + } + + public void addPropertyChangeListener(PropertyChangeListener listener) { + myDispatcher.addListener(listener); + } + + public void removePropertyChangeListener(PropertyChangeListener listener) { + myDispatcher.removeListener(listener); + } + + public void propertyChange(PropertyChangeEvent evt) { + myDispatcher.getMulticaster().propertyChange(evt); } private class MyDownloadingListener implements FileDownloadingListener { @@ -138,9 +188,35 @@ public class DownloadRemoteFilePanel { switchEditor(); } - public void errorOccured(@NotNull final String errorMessage) { - myErrorLabel.setText(errorMessage); - showCard(ERROR_CARD); + public void downloadingCancelled() { + ApplicationManager.getApplication().invokeLater(new Runnable() { + public void run() { + if (myFileEditor != null) { + showCard(EDITOR_CARD); + } + else { + myErrorLabel.setText("Downloading cancelled"); + showCard(ERROR_CARD); + } + } + }); + } + + public void downloadingStarted() { + ApplicationManager.getApplication().invokeLater(new Runnable() { + public void run() { + showCard(DOWNLOADING_CARD); + } + }); + } + + public void errorOccurred(@NotNull final String errorMessage) { + ApplicationManager.getApplication().invokeLater(new Runnable() { + public void run() { + myErrorLabel.setText(errorMessage); + showCard(ERROR_CARD); + } + }); } public void progressMessageChanged(final boolean indeterminate, @NotNull final String message) { diff --git a/platform/platform-impl/src/com/intellij/openapi/vfs/impl/http/DefaultRemoteContentProvider.java b/platform/platform-impl/src/com/intellij/openapi/vfs/impl/http/DefaultRemoteContentProvider.java index 0119a63fac69..58c275d5a60d 100644 --- a/platform/platform-impl/src/com/intellij/openapi/vfs/impl/http/DefaultRemoteContentProvider.java +++ b/platform/platform-impl/src/com/intellij/openapi/vfs/impl/http/DefaultRemoteContentProvider.java @@ -81,7 +81,6 @@ public class DefaultRemoteContentProvider extends RemoteContentProvider { int count = 0; while ((len = input.read(buf)) > 0) { if (callback.isCancelled()) { - callback.errorOccured(VfsBundle.message("downloading.cancelled.message")); return; } count += len; @@ -97,7 +96,7 @@ public class DefaultRemoteContentProvider extends RemoteContentProvider { } catch (IOException e) { LOG.info(e); - callback.errorOccured(VfsBundle.message("cannot.load.remote.file", url, e.getMessage())); + callback.errorOccurred(VfsBundle.message("cannot.load.remote.file", url, e.getMessage()), false); } finally { if (input != null) { diff --git a/platform/platform-impl/src/com/intellij/openapi/vfs/impl/http/FileDownloadingAdapter.java b/platform/platform-impl/src/com/intellij/openapi/vfs/impl/http/FileDownloadingAdapter.java index 45112d1e0306..ae35127de09e 100644 --- a/platform/platform-impl/src/com/intellij/openapi/vfs/impl/http/FileDownloadingAdapter.java +++ b/platform/platform-impl/src/com/intellij/openapi/vfs/impl/http/FileDownloadingAdapter.java @@ -25,7 +25,13 @@ public class FileDownloadingAdapter implements FileDownloadingListener { public void fileDownloaded(final VirtualFile localFile) { } - public void errorOccured(@NotNull final String errorMessage) { + public void errorOccurred(@NotNull final String errorMessage) { + } + + public void downloadingStarted() { + } + + public void downloadingCancelled() { } public void progressMessageChanged(final boolean indeterminate, @NotNull final String message) { diff --git a/platform/platform-impl/src/com/intellij/openapi/vfs/impl/http/FileDownloadingListener.java b/platform/platform-impl/src/com/intellij/openapi/vfs/impl/http/FileDownloadingListener.java index 8d734627ba31..ac04de59b9ca 100644 --- a/platform/platform-impl/src/com/intellij/openapi/vfs/impl/http/FileDownloadingListener.java +++ b/platform/platform-impl/src/com/intellij/openapi/vfs/impl/http/FileDownloadingListener.java @@ -25,7 +25,11 @@ public interface FileDownloadingListener { void fileDownloaded(final VirtualFile localFile); - void errorOccured(@NotNull String errorMessage); + void errorOccurred(@NotNull String errorMessage); + + void downloadingStarted(); + + void downloadingCancelled(); void progressMessageChanged(final boolean indeterminate, @NotNull String message); diff --git a/platform/platform-impl/src/com/intellij/openapi/vfs/impl/http/HttpFileSystemImpl.java b/platform/platform-impl/src/com/intellij/openapi/vfs/impl/http/HttpFileSystemImpl.java index 2479abbe3c80..6d6077e18255 100644 --- a/platform/platform-impl/src/com/intellij/openapi/vfs/impl/http/HttpFileSystemImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/vfs/impl/http/HttpFileSystemImpl.java @@ -42,6 +42,10 @@ public class HttpFileSystemImpl extends HttpFileSystem { myDefaultRemoteContentProvider = new DefaultRemoteContentProvider(); } + public static HttpFileSystemImpl getInstanceImpl() { + return (HttpFileSystemImpl)getInstance(); + } + public VirtualFile findFileByPath(@NotNull String path) { return findFileByPath(path, false); } @@ -49,8 +53,7 @@ public class HttpFileSystemImpl extends HttpFileSystem { public VirtualFile findFileByPath(@NotNull String path, boolean isDirectory) { try { String url = VirtualFileManager.constructUrl(PROTOCOL, path); - RemoteContentProvider provider = findContentProvider(url); - return myRemoteFileManager.getOrCreateFile(url, path, isDirectory, provider); + return myRemoteFileManager.getOrCreateFile(url, path, isDirectory); } catch (IOException e) { return null; @@ -58,7 +61,7 @@ public class HttpFileSystemImpl extends HttpFileSystem { } @NotNull - private RemoteContentProvider findContentProvider(final @NotNull String url) { + public RemoteContentProvider findContentProvider(final @NotNull String url) { for (RemoteContentProvider provider : myProviders) { if (provider.canProvideContent(url)) { return provider; @@ -68,7 +71,7 @@ public class HttpFileSystemImpl extends HttpFileSystem { } public boolean isFileDownloaded(@NotNull final VirtualFile file) { - return file instanceof HttpVirtualFile && ((HttpVirtualFile)file).getFileInfo().isDownloaded(); + return file instanceof HttpVirtualFile && ((HttpVirtualFile)file).getFileInfo().getState() == RemoteFileState.DOWNLOADED; } public void addRemoteContentProvider(@NotNull final RemoteContentProvider provider, @NotNull Disposable parentDisposable) { diff --git a/platform/platform-impl/src/com/intellij/openapi/vfs/impl/http/RemoteContentProvider.java b/platform/platform-impl/src/com/intellij/openapi/vfs/impl/http/RemoteContentProvider.java index 4cae591f347e..7e12941b373b 100644 --- a/platform/platform-impl/src/com/intellij/openapi/vfs/impl/http/RemoteContentProvider.java +++ b/platform/platform-impl/src/com/intellij/openapi/vfs/impl/http/RemoteContentProvider.java @@ -37,7 +37,7 @@ public abstract class RemoteContentProvider { public interface DownloadingCallback { void finished(@Nullable FileType fileType); - void errorOccured(@NotNull String errorMessage); + void errorOccurred(@NotNull String errorMessage, boolean cancelled); void setProgressText(@NotNull String text, boolean indeterminate); diff --git a/platform/platform-impl/src/com/intellij/openapi/vfs/impl/http/RemoteFileInfo.java b/platform/platform-impl/src/com/intellij/openapi/vfs/impl/http/RemoteFileInfo.java index 5d64d7dfa2c7..3eee3b1584a0 100644 --- a/platform/platform-impl/src/com/intellij/openapi/vfs/impl/http/RemoteFileInfo.java +++ b/platform/platform-impl/src/com/intellij/openapi/vfs/impl/http/RemoteFileInfo.java @@ -22,6 +22,7 @@ import com.intellij.openapi.fileTypes.FileType; import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.vfs.LocalFileSystem; import com.intellij.openapi.vfs.VfsBundle; +import com.intellij.openapi.vfs.VfsUtil; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.util.SmartList; import org.jetbrains.annotations.NotNull; @@ -30,6 +31,7 @@ import org.jetbrains.annotations.Nullable; import java.io.File; import java.io.IOException; import java.util.List; +import java.util.concurrent.atomic.AtomicBoolean; /** * @author nik @@ -39,18 +41,18 @@ public class RemoteFileInfo implements RemoteContentProvider.DownloadingCallback private final Object myLock = new Object(); private final String myUrl; private final RemoteFileManager myManager; - private final RemoteContentProvider myContentProvider; + private @Nullable RemoteContentProvider myContentProvider; private File myLocalFile; private VirtualFile myLocalVirtualFile; - private boolean myDownloaded; + private VirtualFile myPrevLocalFile; + private RemoteFileState myState = RemoteFileState.DOWNLOADING_NOT_STARTED; private String myErrorMessage; - private volatile boolean myCancelled; + private final AtomicBoolean myCancelled = new AtomicBoolean(); private final List myListeners = new SmartList(); - public RemoteFileInfo(final @NotNull String url, final @NotNull RemoteFileManager manager, final @NotNull RemoteContentProvider provider) { + public RemoteFileInfo(final @NotNull String url, final @NotNull RemoteFileManager manager) { myUrl = url; myManager = manager; - myContentProvider = provider; } public void addDownloadingListener(@NotNull FileDownloadingListener listener) { @@ -72,8 +74,9 @@ public class RemoteFileInfo implements RemoteContentProvider.DownloadingCallback public void restartDownloading() { synchronized (myLock) { myErrorMessage = null; + myPrevLocalFile = myLocalVirtualFile; myLocalVirtualFile = null; - myDownloaded = false; + myState = RemoteFileState.DOWNLOADING_NOT_STARTED; myLocalFile = null; startDownloading(); } @@ -83,20 +86,13 @@ public class RemoteFileInfo implements RemoteContentProvider.DownloadingCallback LOG.debug("Downloading requested"); File localFile; + FileDownloadingListener[] listeners; synchronized (myLock) { - if (myDownloaded) { - LOG.debug("File already downloaded: " + myLocalVirtualFile); - return; - } - if (myErrorMessage != null) { - LOG.debug("Error occured: " + myErrorMessage); - return; - } - - if (myLocalFile != null) { - LOG.debug("Downloading in progress"); + if (myState != RemoteFileState.DOWNLOADING_NOT_STARTED) { + LOG.debug("File already downloaded: file = " + myLocalVirtualFile + ", state = " + myState); return; } + myState = RemoteFileState.DOWNLOADING_IN_PROGRESS; try { myLocalFile = myManager.getStorage().createLocalFile(myUrl); @@ -104,13 +100,20 @@ public class RemoteFileInfo implements RemoteContentProvider.DownloadingCallback } catch (IOException e) { LOG.info(e); - errorOccured(VfsBundle.message("cannot.create.local.file", e.getMessage())); + errorOccurred(VfsBundle.message("cannot.create.local.file", e.getMessage()), false); return; } - myCancelled = false; + myCancelled.set(false); localFile = myLocalFile; + listeners = myListeners.toArray(new FileDownloadingListener[myListeners.size()]); + } + for (FileDownloadingListener listener : listeners) { + listener.downloadingStarted(); } + if (myContentProvider == null) { + myContentProvider = HttpFileSystemImpl.getInstanceImpl().findContentProvider(myUrl); + } myContentProvider.saveContent(myUrl, localFile, this); } @@ -152,7 +155,8 @@ public class RemoteFileInfo implements RemoteContentProvider.DownloadingCallback FileDownloadingListener[] listeners; synchronized (myLock) { myLocalVirtualFile = localFile; - myDownloaded = true; + myPrevLocalFile = null; + myState = RemoteFileState.DOWNLOADED; myErrorMessage = null; listeners = myListeners.toArray(new FileDownloadingListener[myListeners.size()]); } @@ -162,7 +166,7 @@ public class RemoteFileInfo implements RemoteContentProvider.DownloadingCallback } public boolean isCancelled() { - return myCancelled; + return myCancelled.get(); } public String getErrorMessage() { @@ -171,16 +175,20 @@ public class RemoteFileInfo implements RemoteContentProvider.DownloadingCallback } } - public void errorOccured(@NotNull final String errorMessage) { + public void errorOccurred(@NotNull final String errorMessage, boolean cancelled) { LOG.debug("Error: " + errorMessage); FileDownloadingListener[] listeners; synchronized (myLock) { myLocalVirtualFile = null; + myPrevLocalFile = null; + myState = RemoteFileState.ERROR_OCCURRED; myErrorMessage = errorMessage; listeners = myListeners.toArray(new FileDownloadingListener[myListeners.size()]); } for (FileDownloadingListener listener : listeners) { - listener.errorOccured(errorMessage); + if (!cancelled) { + listener.errorOccurred(errorMessage); + } } } @@ -210,15 +218,29 @@ public class RemoteFileInfo implements RemoteContentProvider.DownloadingCallback } } - public boolean isDownloaded() { + public RemoteFileState getState() { synchronized (myLock) { - return myDownloaded; + return myState; } } public void cancelDownloading() { + FileDownloadingListener[] listeners; synchronized (myLock) { - myCancelled = true; + myCancelled.set(true); + if (myPrevLocalFile != null) { + myLocalVirtualFile = myPrevLocalFile; + myLocalFile = VfsUtil.virtualToIoFile(myLocalVirtualFile); + myState = RemoteFileState.DOWNLOADED; + myErrorMessage = null; + } + else { + myState = RemoteFileState.ERROR_OCCURRED; + } + listeners = myListeners.toArray(new FileDownloadingListener[myListeners.size()]); + } + for (FileDownloadingListener listener : listeners) { + listener.downloadingCancelled(); } } @@ -227,7 +249,9 @@ public class RemoteFileInfo implements RemoteContentProvider.DownloadingCallback synchronized (myLock) { localVirtualFile = myLocalVirtualFile; } - if ((localVirtualFile == null || !myContentProvider.isUpToDate(myUrl, localVirtualFile)) && myContentProvider.canProvideContent(myUrl)) { + final RemoteContentProvider contentProvider = HttpFileSystemImpl.getInstanceImpl().findContentProvider(myUrl); + if ((localVirtualFile == null || !contentProvider.equals(myContentProvider) || !contentProvider.isUpToDate(myUrl, localVirtualFile))) { + myContentProvider = contentProvider; addDownloadingListener(new MyRefreshingDownloadingListener(postRunnable)); restartDownloading(); } @@ -240,6 +264,14 @@ public class RemoteFileInfo implements RemoteContentProvider.DownloadingCallback myPostRunnable = postRunnable; } + @Override + public void downloadingCancelled() { + removeDownloadingListener(this); + if (myPostRunnable != null) { + myPostRunnable.run(); + } + } + @Override public void fileDownloaded(final VirtualFile localFile) { removeDownloadingListener(this); @@ -249,12 +281,11 @@ public class RemoteFileInfo implements RemoteContentProvider.DownloadingCallback } @Override - public void errorOccured(@NotNull final String errorMessage) { + public void errorOccurred(@NotNull final String errorMessage) { removeDownloadingListener(this); if (myPostRunnable != null) { myPostRunnable.run(); } } } - } diff --git a/platform/platform-impl/src/com/intellij/openapi/vfs/impl/http/RemoteFileManager.java b/platform/platform-impl/src/com/intellij/openapi/vfs/impl/http/RemoteFileManager.java index 3304003de6b3..4600082ad765 100644 --- a/platform/platform-impl/src/com/intellij/openapi/vfs/impl/http/RemoteFileManager.java +++ b/platform/platform-impl/src/com/intellij/openapi/vfs/impl/http/RemoteFileManager.java @@ -15,9 +15,8 @@ */ package com.intellij.openapi.vfs.impl.http; -import com.intellij.openapi.util.Trinity; +import com.intellij.openapi.util.Pair; import com.intellij.openapi.vfs.VirtualFile; -import com.intellij.openapi.diagnostic.Logger; import gnu.trove.THashMap; import org.jetbrains.annotations.NotNull; @@ -28,26 +27,24 @@ import java.util.Map; * @author nik */ public class RemoteFileManager { - private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.vfs.impl.http.RemoteFileManager"); private final LocalFileStorage myStorage; private final HttpFileSystemImpl myHttpFileSystem; - private final Map, VirtualFileImpl> myRemoteFiles; + private final Map, VirtualFileImpl> myRemoteFiles; public RemoteFileManager(final HttpFileSystemImpl httpFileSystem) { myHttpFileSystem = httpFileSystem; myStorage = new LocalFileStorage(); - myRemoteFiles = new THashMap, VirtualFileImpl>(); + myRemoteFiles = new THashMap, VirtualFileImpl>(); } - public synchronized VirtualFileImpl getOrCreateFile(final @NotNull String url, final @NotNull String path, final boolean directory, - final @NotNull RemoteContentProvider provider) throws IOException { - Trinity key = Trinity.create(directory, provider, url); + public synchronized VirtualFileImpl getOrCreateFile(final @NotNull String url, final @NotNull String path, final boolean directory) throws IOException { + Pair key = Pair.create(directory, url); VirtualFileImpl file = myRemoteFiles.get(key); if (file == null) { if (!directory) { - RemoteFileInfo fileInfo = new RemoteFileInfo(url, this, provider); + RemoteFileInfo fileInfo = new RemoteFileInfo(url, this); file = new VirtualFileImpl(myHttpFileSystem, path, fileInfo); fileInfo.addDownloadingListener(new MyDownloadingListener(myHttpFileSystem, file)); } diff --git a/platform/platform-impl/src/com/intellij/openapi/vfs/impl/http/RemoteFileState.java b/platform/platform-impl/src/com/intellij/openapi/vfs/impl/http/RemoteFileState.java new file mode 100644 index 000000000000..688a2169aa48 --- /dev/null +++ b/platform/platform-impl/src/com/intellij/openapi/vfs/impl/http/RemoteFileState.java @@ -0,0 +1,23 @@ +/* + * Copyright 2000-2009 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 com.intellij.openapi.vfs.impl.http; + +/** + * @author nik + */ +public enum RemoteFileState { + DOWNLOADING_NOT_STARTED, DOWNLOADING_IN_PROGRESS, DOWNLOADED, ERROR_OCCURRED +} diff --git a/platform/platform-resources/src/META-INF/LangExtensions.xml b/platform/platform-resources/src/META-INF/LangExtensions.xml index fdfec4697e14..f1f4b2be2e18 100644 --- a/platform/platform-resources/src/META-INF/LangExtensions.xml +++ b/platform/platform-resources/src/META-INF/LangExtensions.xml @@ -491,6 +491,8 @@ + + + + + From 14e0087f620032a50c433b13328cb3f7419e48d7 Mon Sep 17 00:00:00 2001 From: Alexey Kudravtsev Date: Mon, 28 Dec 2009 12:41:41 +0300 Subject: [PATCH 25/67] IDEADEV-42118 --- .../impl/analysis/HighlightMethodUtil.java | 57 +++++++++++-------- 1 file changed, 34 insertions(+), 23 deletions(-) diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightMethodUtil.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightMethodUtil.java index 5ad495a6360b..46680732f465 100644 --- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightMethodUtil.java +++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightMethodUtil.java @@ -186,24 +186,29 @@ public class HighlightMethodUtil { PsiMethod method = methodSignature.getMethod(); for (MethodSignatureBackedByPsiMethod superMethodSignature : superMethodSignatures) { PsiMethod superMethod = superMethodSignature.getMethod(); - // strange things happen when super method is from Object and method from interface - if (superMethod.hasModifierProperty(PsiModifier.FINAL)) { - String message = JavaErrorMessages.message("final.method.override", - HighlightUtil.formatMethod(method), - HighlightUtil.formatMethod(superMethod), - HighlightUtil.formatClass(superMethod.getContainingClass())); - TextRange textRange = HighlightNamesUtil.getMethodDeclarationTextRange(method); - HighlightInfo errorResult = HighlightInfo.createHighlightInfo(HighlightInfoType.ERROR, - textRange, - message); - IntentionAction fix = QUICK_FIX_FACTORY.createModifierListFix(superMethod, PsiModifier.FINAL, false, true); - QuickFixAction.registerQuickFixAction(errorResult, fix); - return errorResult; - } + HighlightInfo info = checkSuperMethodIsFinal(method, superMethod); + if (info != null) return info; } return null; } + private static HighlightInfo checkSuperMethodIsFinal(PsiMethod method, PsiMethod superMethod) { + // strange things happen when super method is from Object and method from interface + if (superMethod.hasModifierProperty(PsiModifier.FINAL)) { + String message = JavaErrorMessages.message("final.method.override", + HighlightUtil.formatMethod(method), + HighlightUtil.formatMethod(superMethod), + HighlightUtil.formatClass(superMethod.getContainingClass())); + TextRange textRange = HighlightNamesUtil.getMethodDeclarationTextRange(method); + HighlightInfo errorResult = HighlightInfo.createHighlightInfo(HighlightInfoType.ERROR, + textRange, + message); + IntentionAction fix = QUICK_FIX_FACTORY.createModifierListFix(superMethod, PsiModifier.FINAL, false, true); + QuickFixAction.registerQuickFixAction(errorResult, fix); + return errorResult; + } + return null; + } public static HighlightInfo checkMethodIncompatibleThrows(MethodSignatureBackedByPsiMethod methodSignature, List superMethodSignatures, @@ -822,19 +827,24 @@ public class HighlightMethodUtil { ? null : MethodSignatureUtil.findMethodBySignature(superClass, method, true); - HighlightInfo highlightInfo = checkStaticMethodOverride(aClass, method, superClass, superMethod); + boolean isStatic = method.hasModifierProperty(PsiModifier.STATIC); + HighlightInfo highlightInfo = checkStaticMethodOverride(aClass, method, isStatic,superClass, superMethod); if (highlightInfo != null) return highlightInfo; + if (!isStatic) { + // all methods in interface are instance, so no possible errors in this case + return null; + } PsiClass[] interfaces = aClass.getInterfaces(); for (PsiClass aInterfaces : interfaces) { - superClass = aInterfaces; - superMethod = MethodSignatureUtil.findMethodBySignature(superClass, method, true); - highlightInfo = checkStaticMethodOverride(aClass, method, superClass, superMethod); - if (highlightInfo != null) return highlightInfo; - } - return highlightInfo; + superClass = aInterfaces; + superMethod = MethodSignatureUtil.findMethodBySignature(superClass, method, true); + highlightInfo = checkStaticMethodOverride(aClass, method, true, superClass, superMethod); + if (highlightInfo != null) return highlightInfo; + } + return null; } - private static HighlightInfo checkStaticMethodOverride(PsiClass aClass, PsiMethod method, PsiClass superClass, PsiMethod superMethod) { + private static HighlightInfo checkStaticMethodOverride(PsiClass aClass, PsiMethod method, boolean isMethodStatic, PsiClass superClass, PsiMethod superMethod) { if (superMethod == null) return null; PsiManager manager = superMethod.getManager(); PsiModifierList superModifierList = superMethod.getModifierList(); @@ -844,7 +854,6 @@ public class HighlightMethodUtil { && !JavaPsiFacade.getInstance(manager.getProject()).arePackagesTheSame(aClass, superClass)) { return null; } - boolean isMethodStatic = modifierList.hasModifierProperty(PsiModifier.STATIC); boolean isSuperMethodStatic = superModifierList.hasModifierProperty(PsiModifier.STATIC); if (isMethodStatic != isSuperMethodStatic) { TextRange textRange = HighlightNamesUtil.getMethodDeclarationTextRange(method); @@ -876,6 +885,8 @@ public class HighlightMethodUtil { String accessModifier = PsiUtil.getAccessModifier(accessLevel); HighlightInfo info = isWeaker(method, modifierList, accessModifier, accessLevel, superMethod, true); if (info != null) return info; + info = checkSuperMethodIsFinal(method, superMethod); + if (info != null) return info; } return null; } From f3b503cd41f3efe49e2d319c304de283bc588b0a Mon Sep 17 00:00:00 2001 From: anna Date: Mon, 28 Dec 2009 13:53:51 +0300 Subject: [PATCH 26/67] fill the tests progress if 0 tests were found (IDEABKL-5681) --- .../com/intellij/openapi/progress/util/ColorProgressBar.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/platform/platform-impl/src/com/intellij/openapi/progress/util/ColorProgressBar.java b/platform/platform-impl/src/com/intellij/openapi/progress/util/ColorProgressBar.java index b93d42c055a8..1772ddeedce0 100644 --- a/platform/platform-impl/src/com/intellij/openapi/progress/util/ColorProgressBar.java +++ b/platform/platform-impl/src/com/intellij/openapi/progress/util/ColorProgressBar.java @@ -73,6 +73,10 @@ public class ColorProgressBar extends JComponent { } public void setFraction(double fraction) { + if (Double.isNaN(fraction)) { + fraction = 1.0; + } + if (myIndeterminate) { if (myFraction >= 1.0) { myIndeterminateInc = -INDETERMINATE_INC_OFFSET; From 7b603c6f92de97f441f1b1804b85c8e9693446df Mon Sep 17 00:00:00 2001 From: anna Date: Mon, 28 Dec 2009 14:17:24 +0300 Subject: [PATCH 27/67] presetup coverage patterns for package configurations --- .../execution/junit/AllInPackageConfigurationProducer.java | 2 ++ .../configuration/TestNGPackageConfigurationProducer.java | 2 ++ 2 files changed, 4 insertions(+) diff --git a/plugins/junit/src/com/intellij/execution/junit/AllInPackageConfigurationProducer.java b/plugins/junit/src/com/intellij/execution/junit/AllInPackageConfigurationProducer.java index d105dc397a51..637c647097d0 100644 --- a/plugins/junit/src/com/intellij/execution/junit/AllInPackageConfigurationProducer.java +++ b/plugins/junit/src/com/intellij/execution/junit/AllInPackageConfigurationProducer.java @@ -17,6 +17,7 @@ package com.intellij.execution.junit; import com.intellij.execution.Location; +import com.intellij.execution.RunConfigurationExtension; import com.intellij.execution.actions.ConfigurationContext; import com.intellij.execution.impl.RunnerAndConfigurationSettingsImpl; import com.intellij.openapi.project.Project; @@ -38,6 +39,7 @@ public class AllInPackageConfigurationProducer extends JUnitConfigurationProduce data.TEST_OBJECT = JUnitConfiguration.TEST_PACKAGE; data.setScope(setupPackageConfiguration(context, project, configuration, data.getScope())); configuration.setGeneratedName(); + RunConfigurationExtension.patchCreatedConfiguration(configuration); return settings; } diff --git a/plugins/testng/src/com/theoryinpractice/testng/configuration/TestNGPackageConfigurationProducer.java b/plugins/testng/src/com/theoryinpractice/testng/configuration/TestNGPackageConfigurationProducer.java index 44334d190bfb..4fb822e25f3d 100644 --- a/plugins/testng/src/com/theoryinpractice/testng/configuration/TestNGPackageConfigurationProducer.java +++ b/plugins/testng/src/com/theoryinpractice/testng/configuration/TestNGPackageConfigurationProducer.java @@ -16,6 +16,7 @@ package com.theoryinpractice.testng.configuration; import com.intellij.execution.Location; +import com.intellij.execution.RunConfigurationExtension; import com.intellij.execution.actions.ConfigurationContext; import com.intellij.execution.impl.RunnerAndConfigurationSettingsImpl; import com.intellij.openapi.project.Project; @@ -39,6 +40,7 @@ public class TestNGPackageConfigurationProducer extends TestNGConfigurationProdu data.TEST_OBJECT = TestType.PACKAGE.getType(); data.setScope(setupPackageConfiguration(context, project, configuration, data.getScope())); configuration.setGeneratedName(); + RunConfigurationExtension.patchCreatedConfiguration(configuration); return settings; } From e48335a074690eb406d0a1c912718cce2a343700 Mon Sep 17 00:00:00 2001 From: Maas van den Berg Date: Mon, 28 Dec 2009 16:23:30 +0300 Subject: [PATCH 28/67] TODO doesn't highlight highlighting block comment end pattern (IDEADEV-42132) --- .../psi/impl/search/JavaIndexPatternBuilder.java | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/java/java-impl/src/com/intellij/psi/impl/search/JavaIndexPatternBuilder.java b/java/java-impl/src/com/intellij/psi/impl/search/JavaIndexPatternBuilder.java index 84725cb0b3a3..3b1780d23b77 100644 --- a/java/java-impl/src/com/intellij/psi/impl/search/JavaIndexPatternBuilder.java +++ b/java/java-impl/src/com/intellij/psi/impl/search/JavaIndexPatternBuilder.java @@ -15,17 +15,18 @@ */ package com.intellij.psi.impl.search; -import com.intellij.lexer.Lexer; import com.intellij.lexer.JavaLexer; +import com.intellij.lexer.Lexer; +import com.intellij.psi.JavaDocTokenType; +import com.intellij.psi.JavaTokenType; import com.intellij.psi.PsiFile; import com.intellij.psi.PsiJavaFile; -import com.intellij.psi.JavaDocTokenType; -import com.intellij.psi.xml.XmlTokenType; -import com.intellij.psi.xml.XmlElementType; import com.intellij.psi.impl.source.tree.StdTokenSets; import com.intellij.psi.jsp.JspFile; -import com.intellij.psi.tree.TokenSet; import com.intellij.psi.tree.IElementType; +import com.intellij.psi.tree.TokenSet; +import com.intellij.psi.xml.XmlElementType; +import com.intellij.psi.xml.XmlTokenType; import org.jetbrains.annotations.Nullable; /** @@ -56,6 +57,6 @@ public class JavaIndexPatternBuilder implements IndexPatternBuilder { } public int getCommentEndDelta(final IElementType tokenType) { - return 0; + return tokenType == JavaTokenType.C_STYLE_COMMENT ? "*/".length() : 0; } } From ccca71259f5c6c21e857ab6d3e13815b456e8afc Mon Sep 17 00:00:00 2001 From: Maas van den Berg Date: Mon, 28 Dec 2009 16:50:33 +0300 Subject: [PATCH 29/67] do not use deprecated findClass() method --- .../template/macro/AnnotatedMacro.java | 19 ++++++++------- .../usageInfo/MergeMethodArguments.java | 3 ++- .../refactoring/migration/MigrationUtil.java | 5 +++- .../WrapReturnValueProcessor.java | 5 ++-- .../refactoring/InlineSuperClassTest.java | 19 ++++++++------- .../IntroduceVariableMultifileTest.java | 3 ++- .../refactoring/PushDownMultifileTest.java | 11 +++++---- .../refactoring/TurnRefsToSuperTest.java | 7 +++--- .../intellij/refactoring/TypeCookTest.java | 19 +++++++++++---- .../codeInsight/CreateClassFixTest.java | 9 ++++--- .../refactoring/copy/GroovyCopyClassTest.java | 6 +++-- .../refactoring/move/GroovyMoveClassTest.java | 24 +++++++++++-------- .../configuration/ConfigurationsTest.java | 9 +++---- 13 files changed, 85 insertions(+), 54 deletions(-) diff --git a/java/java-impl/src/com/intellij/codeInsight/template/macro/AnnotatedMacro.java b/java/java-impl/src/com/intellij/codeInsight/template/macro/AnnotatedMacro.java index eca2fae104ec..48b968b3eae1 100644 --- a/java/java-impl/src/com/intellij/codeInsight/template/macro/AnnotatedMacro.java +++ b/java/java-impl/src/com/intellij/codeInsight/template/macro/AnnotatedMacro.java @@ -19,6 +19,7 @@ package com.intellij.codeInsight.template.macro; import com.intellij.codeInsight.lookup.LookupElement; import com.intellij.codeInsight.lookup.LookupElementBuilder; import com.intellij.codeInsight.template.*; +import com.intellij.openapi.project.Project; import com.intellij.psi.JavaPsiFacade; import com.intellij.psi.PsiClass; import com.intellij.psi.PsiManager; @@ -28,17 +29,14 @@ import com.intellij.psi.search.searches.AnnotatedMembersSearch; import com.intellij.util.Query; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.util.LinkedHashSet; import java.util.Set; /** -* Created by IntelliJ IDEA. -* User: Maxim.Mossienko -* Date: 11.06.2009 -* Time: 0:20:54 -* To change this template use File | Settings | File Templates. -*/ + * @author Maxim.Mossienko + */ public class AnnotatedMacro implements Macro { @NonNls @@ -55,7 +53,8 @@ public class AnnotatedMacro implements Macro { return ""; } - private Query findAnnotated(ExpressionContext context, Expression[] params) { + @Nullable + private static Query findAnnotated(ExpressionContext context, Expression[] params) { if (params == null || params.length == 0) return null; PsiManager instance = PsiManager.getInstance(context.getProject()); @@ -94,8 +93,10 @@ public class AnnotatedMacro implements Macro { Set set = new LinkedHashSet(); final String secondParamValue = params.length > 1 ? params[1].calculateResult(context).toString() : null; final boolean isShortName = secondParamValue != null && !Boolean.valueOf(secondParamValue); - final PsiClass findInClass = - secondParamValue != null ? JavaPsiFacade.getInstance(context.getProject()).findClass(secondParamValue) : null; + final Project project = context.getProject(); + final PsiClass findInClass = secondParamValue != null + ? JavaPsiFacade.getInstance(project).findClass(secondParamValue, GlobalSearchScope.allScope(project)) + : null; for (PsiMember object : query.findAll()) { if (findInClass != null && !object.getContainingClass().equals(findInClass)) continue; diff --git a/java/java-impl/src/com/intellij/refactoring/introduceparameterobject/usageInfo/MergeMethodArguments.java b/java/java-impl/src/com/intellij/refactoring/introduceparameterobject/usageInfo/MergeMethodArguments.java index fa6313aeeff0..79a5f6047c33 100644 --- a/java/java-impl/src/com/intellij/refactoring/introduceparameterobject/usageInfo/MergeMethodArguments.java +++ b/java/java-impl/src/com/intellij/refactoring/introduceparameterobject/usageInfo/MergeMethodArguments.java @@ -20,6 +20,7 @@ import com.intellij.openapi.util.text.StringUtil; import com.intellij.psi.*; import com.intellij.psi.codeStyle.JavaCodeStyleManager; import com.intellij.psi.impl.source.PsiImmediateClassType; +import com.intellij.psi.search.GlobalSearchScope; import com.intellij.psi.util.TypeConversionUtil; import com.intellij.refactoring.changeSignature.ChangeSignatureProcessor; import com.intellij.refactoring.changeSignature.ParameterInfoImpl; @@ -71,7 +72,7 @@ public class MergeMethodArguments extends FixableUsageInfo { psiClass = myContainingClass.findInnerClassByName(className, false); } else { - psiClass = psiFacade.findClass(StringUtil.getQualifiedName(packageName, className)); + psiClass = psiFacade.findClass(StringUtil.getQualifiedName(packageName, className), GlobalSearchScope.allScope(getProject())); } PsiSubstitutor subst = PsiSubstitutor.EMPTY; if (deepestSuperMethod != null) { diff --git a/java/java-impl/src/com/intellij/refactoring/migration/MigrationUtil.java b/java/java-impl/src/com/intellij/refactoring/migration/MigrationUtil.java index e357e06da225..a77ad19d6818 100644 --- a/java/java-impl/src/com/intellij/refactoring/migration/MigrationUtil.java +++ b/java/java-impl/src/com/intellij/refactoring/migration/MigrationUtil.java @@ -34,6 +34,9 @@ import java.util.ArrayList; public class MigrationUtil { private static final Logger LOG = Logger.getInstance("#com.intellij.refactoring.migration.MigrationUtil"); + private MigrationUtil() { + } + public static UsageInfo[] findPackageUsages(PsiManager manager, PsiMigration migration, String qName) { PsiPackage aPackage = findOrCreatePackage(manager, migration, qName); @@ -129,7 +132,7 @@ public class MigrationUtil { } static PsiClass findOrCreateClass(PsiManager manager, final PsiMigration migration, final String qName) { - PsiClass aClass = JavaPsiFacade.getInstance(manager.getProject()).findClass(qName); + PsiClass aClass = JavaPsiFacade.getInstance(manager.getProject()).findClass(qName, GlobalSearchScope.allScope(manager.getProject())); if (aClass == null) { aClass = ApplicationManager.getApplication().runWriteAction(new Computable() { public PsiClass compute() { diff --git a/java/java-impl/src/com/intellij/refactoring/wrapreturnvalue/WrapReturnValueProcessor.java b/java/java-impl/src/com/intellij/refactoring/wrapreturnvalue/WrapReturnValueProcessor.java index 6a852cf4106c..aabf2ac3eed0 100644 --- a/java/java-impl/src/com/intellij/refactoring/wrapreturnvalue/WrapReturnValueProcessor.java +++ b/java/java-impl/src/com/intellij/refactoring/wrapreturnvalue/WrapReturnValueProcessor.java @@ -26,6 +26,7 @@ import com.intellij.openapi.util.text.StringUtil; import com.intellij.psi.*; import com.intellij.psi.codeStyle.CodeStyleManager; import com.intellij.psi.codeStyle.JavaCodeStyleManager; +import com.intellij.psi.search.GlobalSearchScope; import com.intellij.psi.search.searches.OverridingMethodsSearch; import com.intellij.psi.search.searches.ReferencesSearch; import com.intellij.psi.util.PsiTreeUtil; @@ -97,7 +98,7 @@ public class WrapReturnValueProcessor extends FixableUsagesRefactoringProcessor } private String calculateUnwrapMethodName() { - final PsiClass existingClass = JavaPsiFacade.getInstance(myProject).findClass(myQualifiedName); + final PsiClass existingClass = JavaPsiFacade.getInstance(myProject).findClass(myQualifiedName, GlobalSearchScope.allScope(myProject)); if (existingClass != null) { if (TypeConversionUtil.isPrimitiveWrapper(myQualifiedName)) { final PsiPrimitiveType unboxedType = @@ -156,7 +157,7 @@ public class WrapReturnValueProcessor extends FixableUsagesRefactoringProcessor @Override protected boolean preprocessUsages(final Ref refUsages) { MultiMap conflicts = new MultiMap(); - final PsiClass existingClass = JavaPsiFacade.getInstance(myProject).findClass(myQualifiedName); + final PsiClass existingClass = JavaPsiFacade.getInstance(myProject).findClass(myQualifiedName, GlobalSearchScope.allScope(myProject)); if (myUseExistingClass) { if (existingClass == null) { conflicts.putValue(existingClass, RefactorJBundle.message("could.not.find.selected.wrapping.class")); diff --git a/java/java-tests/testSrc/com/intellij/refactoring/InlineSuperClassTest.java b/java/java-tests/testSrc/com/intellij/refactoring/InlineSuperClassTest.java index 024738cd8b0d..42106d67c43b 100644 --- a/java/java-tests/testSrc/com/intellij/refactoring/InlineSuperClassTest.java +++ b/java/java-tests/testSrc/com/intellij/refactoring/InlineSuperClassTest.java @@ -9,6 +9,7 @@ import com.intellij.openapi.projectRoots.Sdk; import com.intellij.openapi.projectRoots.impl.JavaSdkImpl; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.PsiClass; +import com.intellij.psi.search.GlobalSearchScope; import com.intellij.refactoring.inlineSuperClass.InlineSuperClassRefactoringProcessor; public class InlineSuperClassTest extends MultiFileTestCase { @@ -33,14 +34,14 @@ public class InlineSuperClassTest extends MultiFileTestCase { try { doTest(new PerformAction() { public void performAction(final VirtualFile rootDir, final VirtualFile rootAfter) throws Exception { - PsiClass aClass = myJavaFacade.findClass("Test"); + PsiClass aClass = myJavaFacade.findClass("Test", GlobalSearchScope.allScope(myProject)); - if (aClass == null) aClass = myJavaFacade.findClass("p.Test"); + if (aClass == null) aClass = myJavaFacade.findClass("p.Test", GlobalSearchScope.allScope(myProject)); assertNotNull("Class Test not found", aClass); - PsiClass superClass = myJavaFacade.findClass("Super"); + PsiClass superClass = myJavaFacade.findClass("Super", GlobalSearchScope.allScope(myProject)); - if (superClass == null) superClass = myJavaFacade.findClass("p1.Super"); + if (superClass == null) superClass = myJavaFacade.findClass("p1.Super", GlobalSearchScope.allScope(myProject)); assertNotNull("Class Super not found", superClass); new InlineSuperClassRefactoringProcessor(getProject(), superClass, aClass).run(); @@ -162,11 +163,13 @@ public class InlineSuperClassTest extends MultiFileTestCase { public void testMultipleSubclasses() throws Exception { doTest(new PerformAction() { public void performAction(final VirtualFile rootDir, final VirtualFile rootAfter) throws Exception { - PsiClass superClass = myJavaFacade.findClass("Super"); - if (superClass == null) superClass = myJavaFacade.findClass("p1.Super"); + PsiClass superClass = myJavaFacade.findClass("Super", GlobalSearchScope.allScope(myProject)); + if (superClass == null) superClass = myJavaFacade.findClass("p1.Super", GlobalSearchScope.allScope(myProject)); assertNotNull("Class Super not found", superClass); - new InlineSuperClassRefactoringProcessor(getProject(), superClass, myJavaFacade.findClass("Test"), myJavaFacade.findClass("Test1")).run(); + new InlineSuperClassRefactoringProcessor(getProject(), superClass, + myJavaFacade.findClass("Test", GlobalSearchScope.allScope(myProject)), + myJavaFacade.findClass("Test1", GlobalSearchScope.allScope(myProject))).run(); } }); } -} \ No newline at end of file +} diff --git a/java/java-tests/testSrc/com/intellij/refactoring/IntroduceVariableMultifileTest.java b/java/java-tests/testSrc/com/intellij/refactoring/IntroduceVariableMultifileTest.java index 6b90f6b2ca96..a93dec2ec651 100644 --- a/java/java-tests/testSrc/com/intellij/refactoring/IntroduceVariableMultifileTest.java +++ b/java/java-tests/testSrc/com/intellij/refactoring/IntroduceVariableMultifileTest.java @@ -9,6 +9,7 @@ import com.intellij.pom.java.LanguageLevel; import com.intellij.psi.JavaPsiFacade; import com.intellij.psi.PsiClass; import com.intellij.psi.PsiFile; +import com.intellij.psi.search.GlobalSearchScope; import com.intellij.refactoring.introduceVariable.IntroduceVariableBase; /** @@ -80,7 +81,7 @@ public class IntroduceVariableMultifileTest extends MultiFileTestCase { return new PerformAction() { public void performAction(VirtualFile vroot, VirtualFile rootAfter) { final JavaPsiFacade psiManager = getJavaFacade(); - final PsiClass aClass = psiManager.findClass(className); + final PsiClass aClass = psiManager.findClass(className, GlobalSearchScope.allScope(myProject)); assertTrue(aClass != null); final PsiFile containingFile = aClass.getContainingFile(); final VirtualFile virtualFile = containingFile.getVirtualFile(); diff --git a/java/java-tests/testSrc/com/intellij/refactoring/PushDownMultifileTest.java b/java/java-tests/testSrc/com/intellij/refactoring/PushDownMultifileTest.java index 4f6777090767..50b381ea2885 100644 --- a/java/java-tests/testSrc/com/intellij/refactoring/PushDownMultifileTest.java +++ b/java/java-tests/testSrc/com/intellij/refactoring/PushDownMultifileTest.java @@ -11,6 +11,7 @@ import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.PsiClass; import com.intellij.psi.PsiField; import com.intellij.psi.PsiMethod; +import com.intellij.psi.search.GlobalSearchScope; import com.intellij.refactoring.memberPushDown.PushDownProcessor; import com.intellij.refactoring.util.DocCommentPolicy; import com.intellij.refactoring.util.classMembers.MemberInfo; @@ -38,10 +39,10 @@ public class PushDownMultifileTest extends MultiFileTestCase { try { doTest(new PerformAction() { public void performAction(final VirtualFile rootDir, final VirtualFile rootAfter) throws Exception { - final PsiClass srcClass = myJavaFacade.findClass("a.A"); + final PsiClass srcClass = myJavaFacade.findClass("a.A", GlobalSearchScope.allScope(myProject)); assertTrue("Source class not found", srcClass != null); - final PsiClass targetClass = myJavaFacade.findClass("b.B"); + final PsiClass targetClass = myJavaFacade.findClass("b.B", GlobalSearchScope.allScope(myProject)); assertTrue("Target class not found", targetClass != null); final PsiMethod[] methods = srcClass.getMethods(); @@ -85,10 +86,10 @@ public class PushDownMultifileTest extends MultiFileTestCase { try { doTest(new PerformAction() { public void performAction(final VirtualFile rootDir, final VirtualFile rootAfter) throws Exception { - final PsiClass srcClass = myJavaFacade.findClass("a.A"); + final PsiClass srcClass = myJavaFacade.findClass("a.A", GlobalSearchScope.allScope(myProject)); assertTrue("Source class not found", srcClass != null); - final PsiClass targetClass = myJavaFacade.findClass("b.B"); + final PsiClass targetClass = myJavaFacade.findClass("b.B", GlobalSearchScope.allScope(myProject)); assertTrue("Target class not found", targetClass != null); final PsiField[] fields = srcClass.getFields(); @@ -112,4 +113,4 @@ public class PushDownMultifileTest extends MultiFileTestCase { } fail("Conflict was not detected"); } -} \ No newline at end of file +} diff --git a/java/java-tests/testSrc/com/intellij/refactoring/TurnRefsToSuperTest.java b/java/java-tests/testSrc/com/intellij/refactoring/TurnRefsToSuperTest.java index d8963fdf20a9..a9a0e9302462 100644 --- a/java/java-tests/testSrc/com/intellij/refactoring/TurnRefsToSuperTest.java +++ b/java/java-tests/testSrc/com/intellij/refactoring/TurnRefsToSuperTest.java @@ -4,6 +4,7 @@ import com.intellij.JavaTestUtil; import com.intellij.openapi.fileEditor.FileDocumentManager; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.PsiClass; +import com.intellij.psi.search.GlobalSearchScope; import com.intellij.refactoring.turnRefsToSuper.TurnRefsToSuperProcessor; import org.jetbrains.annotations.NonNls; @@ -138,12 +139,12 @@ public class TurnRefsToSuperTest extends MultiFileTestCase { } private void performAction(final String className, final String superClassName, boolean replaceInstanceOf) { - final PsiClass aClass = myJavaFacade.findClass(className); + final PsiClass aClass = myJavaFacade.findClass(className, GlobalSearchScope.allScope(myProject)); assertNotNull("Class " + className + " not found", aClass); - PsiClass superClass = myJavaFacade.findClass(superClassName); + PsiClass superClass = myJavaFacade.findClass(superClassName, GlobalSearchScope.allScope(myProject)); assertNotNull("Class " + superClassName + " not found", superClass); new TurnRefsToSuperProcessor(myProject, aClass, superClass, replaceInstanceOf).run(); FileDocumentManager.getInstance().saveAllDocuments(); } -} \ No newline at end of file +} diff --git a/java/java-tests/testSrc/com/intellij/refactoring/TypeCookTest.java b/java/java-tests/testSrc/com/intellij/refactoring/TypeCookTest.java index 516cc5d5f252..968375b7afa2 100644 --- a/java/java-tests/testSrc/com/intellij/refactoring/TypeCookTest.java +++ b/java/java-tests/testSrc/com/intellij/refactoring/TypeCookTest.java @@ -8,6 +8,7 @@ import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.vfs.LocalFileSystem; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.PsiClass; +import com.intellij.psi.search.GlobalSearchScope; import com.intellij.refactoring.typeCook.Settings; import com.intellij.refactoring.typeCook.deductive.builder.ReductionSystem; import com.intellij.refactoring.typeCook.deductive.builder.SystemBuilder; @@ -663,7 +664,7 @@ public class TypeCookTest extends MultiFileTestCase { } private void performAction(String className, String rootDir, final boolean cookObjects) throws Exception { - PsiClass aClass = myJavaFacade.findClass(className); + PsiClass aClass = myJavaFacade.findClass(className, GlobalSearchScope.allScope(myProject)); assertNotNull("Class " + className + " not found", aClass); @@ -736,8 +737,12 @@ public class TypeCookTest extends MultiFileTestCase { PrintWriter writer; if (!patternFile.exists()) { writer = new PrintWriter(new FileOutputStream(patternFile)); - writer.print(itemRepr); - writer.close(); + try { + writer.print(itemRepr); + } + finally { + writer.close(); + } System.out.println("Pattern not found, file " + patternName + " created."); @@ -747,10 +752,14 @@ public class TypeCookTest extends MultiFileTestCase { File graFile = new File(FileUtil.getTempDirectory() + File.separator + rootDir + File.separator + itemName); writer = new PrintWriter(new FileOutputStream(graFile)); + try { + writer.print(itemRepr); + } + finally { + writer.close(); + } - writer.print(itemRepr); - writer.close(); LocalFileSystem.getInstance().refreshAndFindFileByIoFile(graFile); FileDocumentManager.getInstance().saveAllDocuments(); diff --git a/plugins/devkit/testSources/codeInsight/CreateClassFixTest.java b/plugins/devkit/testSources/codeInsight/CreateClassFixTest.java index ff1e102bd087..9c2a51a9346b 100644 --- a/plugins/devkit/testSources/codeInsight/CreateClassFixTest.java +++ b/plugins/devkit/testSources/codeInsight/CreateClassFixTest.java @@ -23,8 +23,10 @@ package org.jetbrains.idea.devkit.codeInsight; import com.intellij.codeInsight.daemon.QuickFixBundle; import com.intellij.codeInsight.intention.IntentionAction; import com.intellij.openapi.application.PluginPathManager; +import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Comparing; import com.intellij.psi.JavaPsiFacade; +import com.intellij.psi.search.GlobalSearchScope; import com.intellij.testFramework.builders.JavaModuleFixtureBuilder; import com.intellij.testFramework.fixtures.CodeInsightTestFixture; import com.intellij.testFramework.fixtures.IdeaProjectTestFixture; @@ -55,7 +57,7 @@ public class CreateClassFixTest { myFixture.setUp(); } - private String getSourceRoot() { + private static String getSourceRoot() { return "codeInsight"; } @@ -77,7 +79,8 @@ public class CreateClassFixTest { } Assert.assertNotNull(resultAction); myFixture.launchAction(resultAction); - Assert.assertNotNull(JavaPsiFacade.getInstance(myFixture.getProject()).findClass(testName)); + final Project project = myFixture.getProject(); + Assert.assertNotNull(JavaPsiFacade.getInstance(project).findClass(testName, GlobalSearchScope.allScope(project))); } @@ -86,4 +89,4 @@ public class CreateClassFixTest { myFixture.tearDown(); myFixture = null; } -} \ No newline at end of file +} diff --git a/plugins/groovy/test/org/jetbrains/plugins/groovy/refactoring/copy/GroovyCopyClassTest.java b/plugins/groovy/test/org/jetbrains/plugins/groovy/refactoring/copy/GroovyCopyClassTest.java index 3639626de718..0a84c31df9f9 100644 --- a/plugins/groovy/test/org/jetbrains/plugins/groovy/refactoring/copy/GroovyCopyClassTest.java +++ b/plugins/groovy/test/org/jetbrains/plugins/groovy/refactoring/copy/GroovyCopyClassTest.java @@ -18,6 +18,7 @@ package org.jetbrains.plugins.groovy.refactoring.copy; import com.intellij.openapi.application.Result; import com.intellij.openapi.command.WriteCommandAction; import com.intellij.psi.PsiClass; +import com.intellij.psi.search.GlobalSearchScope; import com.intellij.refactoring.copy.CopyClassesHandler; import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase; import org.jetbrains.plugins.groovy.util.TestUtils; @@ -37,7 +38,7 @@ public class GroovyCopyClassTest extends LightCodeInsightFixtureTestCase { myFixture.addClass("package foo; public class Bar {}"); myFixture.addClass("package bar; public class Bar {}"); - final PsiClass srcClass = myFixture.getJavaFacade().findClass("foo." + testName); + final PsiClass srcClass = myFixture.getJavaFacade().findClass("foo." + testName, GlobalSearchScope.allScope(getProject())); assertTrue(CopyClassesHandler.canCopyClass(srcClass)); new WriteCommandAction(getProject()) { protected void run(Result result) throws Throwable { @@ -52,7 +53,8 @@ public class GroovyCopyClassTest extends LightCodeInsightFixtureTestCase { final String testName = getTestName(false); myFixture.copyFileToProject(testName + ".groovy", "/foo/" + testName + ".groovy"); - assertFalse(CopyClassesHandler.canCopyClass(myFixture.getJavaFacade().findClass("foo." + testName))); + assertFalse( + CopyClassesHandler.canCopyClass(myFixture.getJavaFacade().findClass("foo." + testName, GlobalSearchScope.allScope(getProject())))); } } diff --git a/plugins/groovy/test/org/jetbrains/plugins/groovy/refactoring/move/GroovyMoveClassTest.java b/plugins/groovy/test/org/jetbrains/plugins/groovy/refactoring/move/GroovyMoveClassTest.java index 415ef440e132..de94d472dfbf 100644 --- a/plugins/groovy/test/org/jetbrains/plugins/groovy/refactoring/move/GroovyMoveClassTest.java +++ b/plugins/groovy/test/org/jetbrains/plugins/groovy/refactoring/move/GroovyMoveClassTest.java @@ -27,6 +27,7 @@ import com.intellij.openapi.vfs.VirtualFile; import com.intellij.openapi.vfs.VirtualFileManager; import com.intellij.psi.*; import com.intellij.psi.impl.source.PostprocessReformattingAspect; +import com.intellij.psi.search.GlobalSearchScope; import com.intellij.refactoring.PackageWrapper; import com.intellij.refactoring.move.moveClassesOrPackages.MoveClassesOrPackagesProcessor; import com.intellij.refactoring.move.moveClassesOrPackages.SingleSourceRootMoveDestination; @@ -124,7 +125,7 @@ public class GroovyMoveClassTest extends LightCodeInsightFixtureTestCase { final PsiClass[] classes = new PsiClass[classNames.length]; for (int i = 0; i < classes.length; i++) { String className = classNames[i]; - classes[i] = JavaPsiFacade.getInstance(getProject()).findClass(className); + classes[i] = JavaPsiFacade.getInstance(getProject()).findClass(className, GlobalSearchScope.allScope(getProject())); assertNotNull("Class " + className + " not found", classes[i]); } @@ -216,16 +217,19 @@ public class GroovyMoveClassTest extends LightCodeInsightFixtureTestCase { private static byte[] contentsToByteArray(File f) throws IOException { int b; final FileReader fileReader = new FileReader(f); - ArrayList bytes = new ArrayList(); - while ((b = fileReader.read()) >= 0) { - bytes.add((byte)b); + try { + ArrayList bytes = new ArrayList(); + while ((b = fileReader.read()) >= 0) { + bytes.add((byte)b); + } + final byte[] res = new byte[bytes.size()]; + for (int i = 0; i < res.length; i++) { + res[i] = bytes.get(i); + } + return res; } - final byte[] res = new byte[bytes.size()]; - for (int i = 0; i < res.length; i++) { - res[i] = bytes.get(i); + finally { + fileReader.close(); } - return res; } - - } diff --git a/plugins/testng/testSources/com/theoryinpractice/testng/configuration/ConfigurationsTest.java b/plugins/testng/testSources/com/theoryinpractice/testng/configuration/ConfigurationsTest.java index 2ef4e890ef66..28b54b26abca 100644 --- a/plugins/testng/testSources/com/theoryinpractice/testng/configuration/ConfigurationsTest.java +++ b/plugins/testng/testSources/com/theoryinpractice/testng/configuration/ConfigurationsTest.java @@ -33,6 +33,7 @@ import com.intellij.openapi.util.io.FileUtil; import com.intellij.psi.JavaPsiFacade; import com.intellij.psi.PsiClass; import com.intellij.psi.PsiMethod; +import com.intellij.psi.search.GlobalSearchScope; import com.intellij.refactoring.RefactoringFactory; import com.intellij.refactoring.RenameRefactoring; import com.intellij.testFramework.builders.JavaModuleFixtureBuilder; @@ -185,19 +186,19 @@ public class ConfigurationsTest { Assert.assertTrue(t.isConfigurationByLocation(runConfiguration, new PsiLocation(project, psiClass))); } - private PsiClass findTestClass(final Project project) { - final PsiClass psiClass = JavaPsiFacade.getInstance(project).findClass("Testt"); + private static PsiClass findTestClass(final Project project) { + final PsiClass psiClass = JavaPsiFacade.getInstance(project).findClass("Testt", GlobalSearchScope.allScope(project)); assert psiClass != null; return psiClass; } - private PsiMethod findNotATestMethod(final PsiClass psiClass) { + private static PsiMethod findNotATestMethod(final PsiClass psiClass) { final PsiMethod[] notATestMethods = psiClass.findMethodsByName("notATest", false); assert notATestMethods.length == 1; return notATestMethods[0]; } - private TestNGConfiguration createConfiguration(final Project project) { + private static TestNGConfiguration createConfiguration(final Project project) { final RunManagerEx manager = RunManagerEx.getInstanceEx(project); final RunnerAndConfigurationSettings settings = manager.createRunConfiguration("testt", TestNGConfigurationType.getInstance().getConfigurationFactories()[0]); From 723deace3522425f519912e1b15f332925a5c858 Mon Sep 17 00:00:00 2001 From: Maas van den Berg Date: Mon, 28 Dec 2009 17:44:12 +0300 Subject: [PATCH 30/67] remove usages of default file template; some related cleanup --- .../regexp/RegExpCompletionContributor.java | 9 +- .../regexp/RegExpDocumentationProvider.java | 6 +- .../compiler/InsetsPropertyCodeGenerator.java | 10 +- .../uiDesigner/core/GridBagConverterTest.java | 8 +- .../actions/EditFrameSourceAction.java | 6 +- .../debugger/actions/FreezeThreadAction.java | 37 +++--- .../actions/GotoFrameSourceAction.java | 6 +- .../debugger/actions/HotSwapAction.java | 6 +- .../engine/DebugProcessAdapterImpl.java | 7 +- .../debugger/engine/DebugProcessEvents.java | 6 +- .../com/intellij/debugger/engine/JVMName.java | 11 +- .../debugger/engine/PositionManagerImpl.java | 6 +- .../debugger/engine/RemoteStateState.java | 6 +- .../debugger/engine/SuspendContextImpl.java | 6 +- .../debugger/engine/SuspendManagerImpl.java | 12 +- .../evaluation/EvaluateRuntimeException.java | 10 +- .../engine/evaluation/EvaluationListener.java | 13 +- .../expression/AssignmentEvaluator.java | 6 +- .../expression/BlockStatementEvaluator.java | 16 +-- .../BreakContinueStatementEvaluator.java | 11 +- .../evaluation/expression/BreakException.java | 8 +- .../expression/CodeFragmentEvaluator.java | 8 +- .../expression/ContinueException.java | 8 +- .../expression/ForStatementEvaluator.java | 41 +++--- .../expression/IfStatementEvaluator.java | 11 +- .../evaluation/expression/MapStack.java | 74 ----------- .../expression/PostfixOperationEvaluator.java | 6 +- .../SyntheticVariableEvaluator.java | 7 +- .../expression/WhileStatementEvaluator.java | 26 ++-- .../engine/events/DebuggerCommandImpl.java | 6 +- .../impl/CloseWorkerThreadException.java | 26 ---- .../intellij/debugger/impl/DebuggerTask.java | 10 +- .../debugger/impl/DebuggerTaskImpl.java | 6 +- .../impl/EventQueueClosedException.java | 8 +- .../debugger/impl/InvokeAndWaitThread.java | 16 +-- .../intellij/debugger/impl/InvokeThread.java | 8 +- .../debugger/impl/ReloadClassesWorker.java | 13 +- .../debugger/ui/CompletedInputTextField.java | 26 ---- .../debugger/ui/DebuggerEditorImpl.java | 10 +- .../debugger/ui/DebuggerStatementEditor.java | 6 +- .../ui/StatementEvaluationDialog.java | 13 +- .../intellij/debugger/ui/impl/TipManager.java | 12 +- .../ui/impl/watch/EvaluationDescriptor.java | 6 +- .../intellij/debugger/DebuggerManager.java | 25 ++-- .../debugger/engine/DebugProcess.java | 6 +- .../evaluation/EvaluateExceptionUtil.java | 9 +- .../engine/jdi/VirtualMachineProxy.java | 6 +- .../codeInsight/ExpectedTypeInfo.java | 14 +- .../smartEnter/MissingForeachBodyFixer.java | 10 +- .../impls/AnnotationParameterInfoHandler.java | 10 +- .../impls/ReferenceParameterInfoHandler.java | 8 +- .../template/impl/TextExpression.java | 6 +- .../com/intellij/javadoc/JavadocBundle.java | 8 +- .../lang/java/JavaDocumentationProvider.java | 10 +- .../com/intellij/lang/java/JavaLanguage.java | 9 +- .../lang/java/JavaParserDefinition.java | 6 +- .../source/codeStyle/ImportsFormatter.java | 13 +- .../impl/source/javadoc/ValueDocTagInfo.java | 10 +- .../source/parsing/JavaParsingContext.java | 8 +- .../deductive/PsiExtendedTypeVisitor.java | 8 +- .../deductive/PsiTypeVariableFactory.java | 122 +++++++++--------- .../deductive/builder/Constraint.java | 8 +- .../typeCook/deductive/builder/Subtype.java | 6 +- .../deductive/util/VictimCollector.java | 6 +- .../typeCook/deductive/util/Visitor.java | 16 +-- .../CustomFileTypeCompletionTest.java | 6 +- .../completion/WordCompletionTest.java | 6 +- .../intellij/lang/jsp/IBaseJspManager.java | 12 +- .../lang/jsp/JspFileViewProvider.java | 7 +- .../lang/jsp/JspxFileViewProvider.java | 10 +- .../src/com/intellij/lexer/ELHostLexer.java | 8 +- .../jsp/impl/TldAttributeDescriptor.java | 9 +- .../smartEnter/SmartEnterProcessor.java | 6 +- .../logging/IndependentLogFilter.java | 6 +- .../intellij/execution/ExecutionBundle.java | 6 +- .../src/com/intellij/pom/PomTransaction.java | 11 +- .../intellij/pom/tree/events/TreeChange.java | 10 +- .../pom/tree/events/TreeChangeEvent.java | 11 +- .../psi/meta/PsiWritableMetaData.java | 6 +- .../intellij/usageView/UsageViewBundle.java | 6 +- .../src/com/intellij/util/CharTable.java | 8 +- .../options/colors/ColorSettingsUtil.java | 15 +-- .../editor/EditorTabsConfigurable.java | 19 ++- .../codeEditor/printing/CodeEditorBundle.java | 6 +- .../intellij/codeEditor/printing/HelpID.java | 6 +- .../completion/CompletionVariant.java | 7 +- .../completion/KeywordChooser.java | 6 +- .../completion/SyntaxTableCompletionData.java | 6 +- .../actions/HippieWordCompletionHandler.java | 6 +- .../codeInsight/daemon/Validator.java | 6 +- .../impl/CollapseSelectionHandler.java | 6 +- .../impl/actions/CollapseSelectionAction.java | 8 +- .../lookup/DeferredUserLookupValue.java | 8 +- .../lookup/LookupValueWithPriority.java | 8 +- .../lookup/LookupValueWithPsiElement.java | 6 +- .../lookup/LookupValueWithUIHint.java | 8 +- .../lookup/PresentableLookupValue.java | 8 +- .../template/FileTypeBasedContextType.java | 8 +- .../template/impl/TemplateImplUtil.java | 9 +- .../src/com/intellij/find/FindBundle.java | 6 +- .../findUsages/CommonFindUsagesDialog.java | 8 +- .../formatting/AbstractBlockWrapper.java | 6 +- .../impl/CustomFileTypeBraceMatcher.java | 6 +- .../impl/CustomFileTypeQuoteHandler.java | 6 +- .../custom/tokens/BraceTokenParser.java | 6 +- .../structureView/StructureViewWrapper.java | 6 +- .../src/com/intellij/lang/LangBundle.java | 6 +- .../tree/events/impl/TreeChangeEventImpl.java | 6 +- .../AbstractPostFormatProcessor.java | 6 +- .../source/codeStyle/AffectedTextRange.java | 43 ------ .../impl/source/parsing/ParseUtilBase.java | 12 +- .../CustomizingReferenceProvider.java | 12 +- .../src/com/intellij/tools/ToolsBundle.java | 6 +- .../ide/AutoScrollToSourceOptionProvider.java | 7 +- .../src/com/intellij/ide/IdeBundle.java | 6 +- .../actions/TreeCollapseAllActionBase.java | 14 +- .../ide/actions/TreeExpandAllActionBase.java | 6 +- .../intellij/ide/plugins/PluginManager.java | 8 +- .../com/intellij/openapi/diff/DiffBundle.java | 6 +- .../intellij/openapi/editor/EditorBundle.java | 6 +- .../openapi/options/OptionsBundle.java | 6 +- .../com/intellij/openapi/vcs/VcsBundle.java | 6 +- .../com/intellij/openapi/vfs/VfsBundle.java | 6 +- .../com/intellij/ui/ScrollPaneFactory.java | 9 +- .../platform-api/src/com/intellij/ui/UI.java | 15 +-- .../intellij/util/ui/AsyncProcessIcon.java | 6 +- .../hint/DocumentFragmentTooltipRenderer.java | 6 +- .../intellij/diagnostic/DiagnosticBundle.java | 6 +- .../ide/plugins/ActionInstallPlugin.java | 8 +- .../ide/plugins/ActionUninstallPlugin.java | 9 +- .../src/com/intellij/idea/Launcher.java | 11 +- .../editor/textarea/TextComponentEditor.java | 2 +- .../openapi/fileTypes/FileTypesBundle.java | 6 +- .../openapi/fileTypes/PlainTextLanguage.java | 6 +- .../util/ProgressIndicatorListener.java | 10 +- .../ProgressIndicatorListenerAdapter.java | 16 +-- .../util/ProgressWindowWithNotification.java | 15 +-- .../updateSettings/impl/NoUpdatesDialog.java | 7 +- .../impl/UpdateSettingsConfigurable.java | 7 +- .../wm/impl/welcomeScreen/WelcomeScreen.java | 20 ++- .../welcomeScreen/WelcomeScrollablePanel.java | 6 +- .../io/WriteableTIntObjectMapAdapter.java | 6 +- .../testFramework/FileTreeAccessFilter.java | 9 +- .../MockCreateParameterInfoContext.java | 8 +- .../MockParameterInfoUIContext.java | 8 +- .../usages/actions/IncludeUsageAction.java | 6 +- .../usages/impl/ExporterToTextFile.java | 8 +- .../impl/rules/UsageTypeGroupingRule.java | 6 +- .../usages/rules/PsiElementUsage.java | 7 +- .../intellij/usages/rules/UsageInFile.java | 6 +- .../intellij/usages/rules/UsageInFiles.java | 6 +- .../intellij/usages/rules/UsageInLibrary.java | 6 +- .../intellij/usages/rules/UsageInModule.java | 6 +- .../usages/impl/UsageNodeTreeBuilderTest.java | 10 +- .../util/src/com/intellij/CommonBundle.java | 22 ++-- .../openapi/util/text/StringHash.java | 6 +- .../containers/VariableWidthIntArray.java | 18 +-- .../util/text/CharSequenceBackedByArray.java | 7 +- .../util/text/MergingCharSequence.java | 6 +- .../util/ui/MappingListCellRenderer.java | 14 +- .../util/containers/ObjectCacheTest.java | 8 +- .../ChangeListFilteringStrategy.java | 4 +- .../intellij/openapi/vcs/merge/MergeData.java | 6 +- ...tAndCompareWithSelectedRevisionAction.java | 11 +- .../vcs/impl/LineStatusTrackerManager.java | 2 - .../vcs/impl/projectlevelman/AllVcsesI.java | 6 +- .../PsiBackedSmartStepIntoVariant.java | 6 +- .../actions/merge/CvsConflictsParser.java | 8 +- .../actions/merge/CvsMergeProvider.java | 16 +-- .../actions/merge/MergeDataProvider.java | 7 +- .../cvsSupport2/actions/merge/MergeInfo.java | 6 +- .../connections/ssh/ui/SshPasswordDialog.java | 1 - .../cvsSupport2/cvsBrowser/LoadingNode.java | 10 +- .../lib/cvsclient/JavaCvsSrcBundle.java | 9 +- .../lib/cvsclient/SmartCvsSrcBundle.java | 6 +- .../GitCommittedChangeListProvider.java | 17 ++- .../GroovyUnresolvedAccessInspection.java | 9 +- .../GroovyUntypedAccessInspection.java | 9 +- .../GroovyCommentBreakerEnterProcessor.java | 4 +- .../api/statements/GrTupleDeclaration.java | 6 +- .../statements/GrTupleDeclarationImpl.java | 6 +- .../lang/resolve/NonCodeMembersProcessor.java | 6 +- .../groovy/structure/GroovyInheritFilter.java | 6 +- .../JavaInspectionToolProvider.java | 6 +- .../i18n/JavaCreatePropertyFix.java | 6 +- .../properties/PropertiesFileTypeFactory.java | 6 +- .../PropertiesInspectionToolsProvider.java | 12 +- .../PropertiesGroupingStructureViewModel.java | 6 +- .../ResourceBundleStructureViewModel.java | 6 +- .../parsing/PropertiesElementTypes.java | 6 +- .../PropertiesFileStructureViewElement.java | 17 +-- .../PropertiesStructureViewElement.java | 6 +- .../impl/idCache/PropertiesIdIndexer.java | 8 +- .../impl/idCache/PropertiesTodoIndexer.java | 13 +- .../idea/svn/SvnAuthenticationManager.java | 10 +- .../idea/svn/SvnEditFileProvider.java | 6 +- .../jetbrains/idea/svn/SvnRevisionNumber.java | 7 +- .../jetbrains/idea/svn/SvnWCRootCrawler.java | 6 +- .../idea/svn/dialogs/LockDialog.java | 6 +- .../dialogs/RepositoryBrowserComponent.java | 6 +- .../svn/dialogs/SSHCredentialsDialog.java | 6 +- .../idea/svn/dialogs/SelectFilesDialog.java | 47 ++++--- .../svn/dialogs/SelectLocationDialog.java | 6 +- .../idea/svn/dialogs/ServerSSLDialog.java | 10 +- .../idea/svn/dialogs/SetPropertyDialog.java | 6 +- .../svn/dialogs/SimpleCredentialsDialog.java | 13 +- .../dialogs/SvnAuthenticationProvider.java | 7 +- .../intellij/uiDesigner/GridBuildUtil.java | 23 ++-- .../uiDesigner/binding/BoundIconRenderer.java | 11 +- .../designSurface/FeedbackPainter.java | 6 +- .../designSurface/GridInsertProcessor.java | 10 +- .../radComponents/RadSplitPane.java | 9 +- .../SnapShooterConfigurationExtension.java | 15 ++- .../snapShooter/SnapShotTreeModel.java | 2 - .../completion/HtmlCompletionData.java | 12 +- .../completion/XHtmlCompletionData.java | 6 +- .../CreateNSDeclarationIntentionFix.java | 12 +- .../analysis/RemoveAttributeIntentionFix.java | 20 ++- .../api/impls/XmlParameterInfoHandler.java | 10 +- ...dHtmlTagOrAttributeToCustomsIntention.java | 8 +- .../com/intellij/lang/dtd/DTDLanguage.java | 6 +- .../lang/dtd/DTDParserDefinition.java | 6 +- .../com/intellij/lang/html/HTMLLanguage.java | 10 +- .../lang/html/HTMLParserDefinition.java | 6 +- .../intellij/lang/xhtml/XHTMLLanguage.java | 8 +- .../lang/xhtml/XHTMLParserDefinition.java | 12 +- .../com/intellij/lang/xml/XMLLanguage.java | 11 +- .../lang/xml/XMLParserDefinition.java | 6 +- .../intellij/lang/xml/XmlFoldingBuilder.java | 6 +- .../src/com/intellij/lexer/BaseHtmlLexer.java | 6 +- .../src/com/intellij/lexer/HtmlLexer.java | 12 +- .../src/com/intellij/lexer/OldXmlLexer.java | 14 +- .../src/com/intellij/lexer/XHtmlLexer.java | 8 +- .../psi/impl/source/html/HtmlFileImpl.java | 8 +- .../impl/source/html/ScriptSupportUtil.java | 9 +- .../impl/providers/DtdReferencesProvider.java | 8 +- .../source/xml/XmlConditionalSectionImpl.java | 6 +- .../xml/impl/ExternalDocumentValidator.java | 6 +- .../impl/schema/NamedObjectDescriptor.java | 6 +- .../xml/impl/schema/SchemaNSDescriptor.java | 6 +- .../intellij/xml/util/AnchorReference.java | 9 +- .../xml/util/ColorSampleLookupValue.java | 6 +- .../intellij/xml/util/UserColorLookup.java | 40 +++--- .../xml/util/XmlResourceResolver.java | 18 +-- .../CompositeAttributeTagDescriptor.java | 14 +- .../util/documentation/EntityDescriptor.java | 6 +- .../HtmlAttributeDescriptor.java | 6 +- .../documentation/HtmlDescriptorsTable.java | 57 ++++---- .../HtmlDocumentationProvider.java | 15 +-- .../util/documentation/HtmlTagDescriptor.java | 6 +- .../XHtmlDocumentationProvider.java | 15 +-- .../XmlDocumentationProvider.java | 6 +- .../src/com/intellij/psi/html/HtmlTag.java | 6 +- .../psi/tree/xml/IDTDElementType.java | 8 +- .../psi/tree/xml/IXmlElementType.java | 8 +- .../psi/xml/XmlConditionalSection.java | 7 +- .../src/com/intellij/xml/XmlBundle.java | 8 +- 257 files changed, 768 insertions(+), 1855 deletions(-) delete mode 100644 java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/MapStack.java delete mode 100644 java/debugger/impl/src/com/intellij/debugger/impl/CloseWorkerThreadException.java delete mode 100644 java/debugger/impl/src/com/intellij/debugger/ui/CompletedInputTextField.java delete mode 100644 platform/lang-impl/src/com/intellij/psi/impl/source/codeStyle/AffectedTextRange.java diff --git a/RegExpSupport/src/org/intellij/lang/regexp/RegExpCompletionContributor.java b/RegExpSupport/src/org/intellij/lang/regexp/RegExpCompletionContributor.java index 4e7f6929b5bf..9330f028a553 100644 --- a/RegExpSupport/src/org/intellij/lang/regexp/RegExpCompletionContributor.java +++ b/RegExpSupport/src/org/intellij/lang/regexp/RegExpCompletionContributor.java @@ -21,7 +21,6 @@ import com.intellij.codeInsight.lookup.LookupElement; import com.intellij.codeInsight.lookup.LookupElementBuilder; import com.intellij.codeInsight.lookup.TailTypeDecorator; import com.intellij.patterns.ElementPattern; -import static com.intellij.patterns.PlatformPatterns.psiElement; import com.intellij.psi.PsiElement; import com.intellij.util.Icons; import com.intellij.util.ProcessingContext; @@ -32,12 +31,10 @@ import org.jetbrains.annotations.NotNull; import javax.swing.*; +import static com.intellij.patterns.PlatformPatterns.psiElement; + /** - * Created by IntelliJ IDEA. - * User: vnikolaenko - * Date: 22.09.2008 - * Time: 12:14:14 - * To change this template use File | Settings | File Templates. + * @author vnikolaenko */ public class RegExpCompletionContributor extends CompletionContributor { private static final Icon emptyIcon = new EmptyIcon(Icons.PROPERTY_ICON.getIconWidth(), Icons.PROPERTY_ICON.getIconHeight()); diff --git a/RegExpSupport/src/org/intellij/lang/regexp/RegExpDocumentationProvider.java b/RegExpSupport/src/org/intellij/lang/regexp/RegExpDocumentationProvider.java index 1106b4805b08..eba87b3c1383 100644 --- a/RegExpSupport/src/org/intellij/lang/regexp/RegExpDocumentationProvider.java +++ b/RegExpSupport/src/org/intellij/lang/regexp/RegExpDocumentationProvider.java @@ -26,11 +26,7 @@ import org.intellij.lang.regexp.psi.impl.RegExpPropertyImpl; import org.jetbrains.annotations.Nullable; /** - * Created by IntelliJ IDEA. - * User: vnikolaenko - * Date: 17.09.2008 - * Time: 19:24:29 - * To change this template use File | Settings | File Templates. + * @author vnikolaenko */ public class RegExpDocumentationProvider extends QuickDocumentationProvider { @Override diff --git a/java/compiler/forms-compiler/src/com/intellij/uiDesigner/compiler/InsetsPropertyCodeGenerator.java b/java/compiler/forms-compiler/src/com/intellij/uiDesigner/compiler/InsetsPropertyCodeGenerator.java index dbc93a94cb3f..3ecabe8118fe 100644 --- a/java/compiler/forms-compiler/src/com/intellij/uiDesigner/compiler/InsetsPropertyCodeGenerator.java +++ b/java/compiler/forms-compiler/src/com/intellij/uiDesigner/compiler/InsetsPropertyCodeGenerator.java @@ -15,24 +15,20 @@ */ package com.intellij.uiDesigner.compiler; +import org.objectweb.asm.Type; import org.objectweb.asm.commons.GeneratorAdapter; import org.objectweb.asm.commons.Method; -import org.objectweb.asm.Type; import java.awt.*; /** - * Created by IntelliJ IDEA. - * User: yole - * Date: 22.11.2005 - * Time: 17:46:41 - * To change this template use File | Settings | File Templates. + * @author yole */ public class InsetsPropertyCodeGenerator extends PropertyCodeGenerator { private final Type myInsetsType = Type.getType(Insets.class); public void generatePushValue(final GeneratorAdapter generator, final Object value) { - final Insets insets = (Insets) value; + final Insets insets = (Insets)value; generator.newInstance(myInsetsType); generator.dup(); generator.push(insets.top); diff --git a/java/compiler/forms-compiler/testSrc/com/intellij/uiDesigner/core/GridBagConverterTest.java b/java/compiler/forms-compiler/testSrc/com/intellij/uiDesigner/core/GridBagConverterTest.java index 65cd0c6e523f..1785247b0763 100644 --- a/java/compiler/forms-compiler/testSrc/com/intellij/uiDesigner/core/GridBagConverterTest.java +++ b/java/compiler/forms-compiler/testSrc/com/intellij/uiDesigner/core/GridBagConverterTest.java @@ -22,11 +22,7 @@ import javax.swing.*; import java.awt.*; /** - * Created by IntelliJ IDEA. - * User: yole - * Date: 23.11.2005 - * Time: 13:47:38 - * To change this template use File | Settings | File Templates. + * @author yole */ public class GridBagConverterTest extends TestCase { /** @@ -892,7 +888,7 @@ public class GridBagConverterTest extends TestCase { assertEquals(100, field3.getHeight()); } - private void applyConversionResults(final JPanel panel, final GridBagConverter converter) { + private static void applyConversionResults(final JPanel panel, final GridBagConverter converter) { GridBagConverter.Result[] results = converter.convert(); for(int i=0; i myEventContexts = new LinkedList(); - // contexts, paused at breakpoint or another debugger event requests. Note that thread, explicitly paused by user is not considered as - // "paused at breakpoint" and JDI prohibits data queries on its stackframes + /** + * contexts, paused at breakpoint or another debugger event requests. Note that thread, explicitly paused by user is not considered as + * "paused at breakpoint" and JDI prohibits data queries on its stackframes + */ private final LinkedList myPausedContexts = new LinkedList(); private final Set myFrozenThreads = Collections.synchronizedSet(new HashSet()); diff --git a/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/EvaluateRuntimeException.java b/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/EvaluateRuntimeException.java index 2a83a82ae8cd..a5b460cebc5d 100644 --- a/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/EvaluateRuntimeException.java +++ b/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/EvaluateRuntimeException.java @@ -15,16 +15,10 @@ */ package com.intellij.debugger.engine.evaluation; -import com.intellij.debugger.engine.evaluation.EvaluateException; - /** - * Created by IntelliJ IDEA. - * User: lex - * Date: Jan 14, 2004 - * Time: 2:18:59 PM - * To change this template use File | Settings | File Templates. + * @author lex */ -public class EvaluateRuntimeException extends RuntimeException{ +public class EvaluateRuntimeException extends RuntimeException { public EvaluateRuntimeException(EvaluateException e) { super(e); } diff --git a/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/EvaluationListener.java b/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/EvaluationListener.java index f6144f3142af..a9bfa83fdade 100644 --- a/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/EvaluationListener.java +++ b/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/EvaluationListener.java @@ -20,13 +20,10 @@ import com.intellij.debugger.engine.SuspendContextImpl; import java.util.EventListener; /** - * Created by IntelliJ IDEA. - * User: lex - * Date: Feb 3, 2004 - * Time: 7:19:30 PM - * To change this template use File | Settings | File Templates. + * @author lex */ -public interface EvaluationListener extends EventListener{ - public void evaluationStarted(SuspendContextImpl context); - public void evaluationFinished(SuspendContextImpl context); +public interface EvaluationListener extends EventListener { + void evaluationStarted(SuspendContextImpl context); + + void evaluationFinished(SuspendContextImpl context); } diff --git a/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/AssignmentEvaluator.java b/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/AssignmentEvaluator.java index b1cbe2534eab..9bbdf1a0f89a 100644 --- a/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/AssignmentEvaluator.java +++ b/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/AssignmentEvaluator.java @@ -22,11 +22,7 @@ import com.intellij.debugger.engine.evaluation.EvaluationContextImpl; import com.sun.jdi.*; /** - * Created by IntelliJ IDEA. - * User: lex - * Date: Mar 24, 2004 - * Time: 11:10:41 PM - * To change this template use File | Settings | File Templates. + * @author lex */ public class AssignmentEvaluator implements Evaluator{ private final Evaluator myLeftEvaluator; diff --git a/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/BlockStatementEvaluator.java b/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/BlockStatementEvaluator.java index d68eb235063e..464aa6ea4f35 100644 --- a/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/BlockStatementEvaluator.java +++ b/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/BlockStatementEvaluator.java @@ -15,19 +15,14 @@ */ package com.intellij.debugger.engine.evaluation.expression; +import com.intellij.debugger.engine.evaluation.EvaluateException; import com.intellij.debugger.engine.evaluation.EvaluationContextImpl; -import com.intellij.debugger.engine.evaluation.EvaluateException; -import com.intellij.debugger.engine.evaluation.EvaluateException; /** - * Created by IntelliJ IDEA. - * User: lex - * Date: Apr 20, 2004 - * Time: 5:21:10 PM - * To change this template use File | Settings | File Templates. + * @author lex */ -public class BlockStatementEvaluator implements Evaluator{ - protected Evaluator [] myStatements; +public class BlockStatementEvaluator implements Evaluator { + protected Evaluator[] myStatements; public BlockStatementEvaluator(Evaluator[] statements) { myStatements = statements; @@ -35,8 +30,7 @@ public class BlockStatementEvaluator implements Evaluator{ public Object evaluate(EvaluationContextImpl context) throws EvaluateException { Object result = context.getSuspendContext().getDebugProcess().getVirtualMachineProxy().mirrorOf(); - for (int i = 0; i < myStatements.length; i++) { - Evaluator statement = myStatements[i]; + for (Evaluator statement : myStatements) { result = statement.evaluate(context); } return result; diff --git a/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/BreakContinueStatementEvaluator.java b/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/BreakContinueStatementEvaluator.java index 40df7ed7189a..e65a3225d2ae 100644 --- a/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/BreakContinueStatementEvaluator.java +++ b/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/BreakContinueStatementEvaluator.java @@ -18,13 +18,12 @@ package com.intellij.debugger.engine.evaluation.expression; import com.intellij.debugger.engine.evaluation.EvaluationContextImpl; /** - * Created by IntelliJ IDEA. - * User: lex - * Date: Apr 20, 2004 - * Time: 7:27:10 PM - * To change this template use File | Settings | File Templates. + * @author lex */ -public abstract class BreakContinueStatementEvaluator implements Evaluator{ +public class BreakContinueStatementEvaluator { + private BreakContinueStatementEvaluator() { + } + public static Evaluator createBreakEvaluator(final String labelName) { return new Evaluator() { public Object evaluate(EvaluationContextImpl context) throws BreakException { diff --git a/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/BreakException.java b/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/BreakException.java index 337a9468eca4..24a7fe5f502c 100644 --- a/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/BreakException.java +++ b/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/BreakException.java @@ -15,15 +15,11 @@ */ package com.intellij.debugger.engine.evaluation.expression; -import com.intellij.debugger.engine.evaluation.EvaluateException; import com.intellij.debugger.DebuggerBundle; +import com.intellij.debugger.engine.evaluation.EvaluateException; /** - * Created by IntelliJ IDEA. - * User: lex - * Date: Apr 20, 2004 - * Time: 7:12:47 PM - * To change this template use File | Settings | File Templates. + * @author lex */ public class BreakException extends EvaluateException{ private final String myLabelName; diff --git a/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/CodeFragmentEvaluator.java b/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/CodeFragmentEvaluator.java index 9597b31ee08b..5fb1e8b2823a 100644 --- a/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/CodeFragmentEvaluator.java +++ b/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/CodeFragmentEvaluator.java @@ -15,10 +15,10 @@ */ package com.intellij.debugger.engine.evaluation.expression; +import com.intellij.debugger.DebuggerBundle; import com.intellij.debugger.engine.evaluation.EvaluateException; import com.intellij.debugger.engine.evaluation.EvaluateExceptionUtil; import com.intellij.debugger.jdi.VirtualMachineProxyImpl; -import com.intellij.debugger.DebuggerBundle; import com.intellij.openapi.diagnostic.Logger; import com.intellij.util.containers.HashMap; import com.sun.jdi.Value; @@ -26,11 +26,7 @@ import com.sun.jdi.Value; import java.util.Map; /** - * Created by IntelliJ IDEA. - * User: lex - * Date: Mar 24, 2004 - * Time: 10:45:50 PM - * To change this template use File | Settings | File Templates. + * @author lex */ public class CodeFragmentEvaluator extends BlockStatementEvaluator{ private static final Logger LOG = Logger.getInstance("#com.intellij.debugger.engine.evaluation.expression.CodeFragmentEvaluator"); diff --git a/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/ContinueException.java b/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/ContinueException.java index 80caa8d746dc..fd0dff311816 100644 --- a/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/ContinueException.java +++ b/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/ContinueException.java @@ -15,15 +15,11 @@ */ package com.intellij.debugger.engine.evaluation.expression; -import com.intellij.debugger.engine.evaluation.EvaluateException; import com.intellij.debugger.DebuggerBundle; +import com.intellij.debugger.engine.evaluation.EvaluateException; /** - * Created by IntelliJ IDEA. - * User: lex - * Date: Apr 20, 2004 - * Time: 7:12:47 PM - * To change this template use File | Settings | File Templates. + * @authorlex */ public class ContinueException extends EvaluateException{ private final String myLabelName; diff --git a/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/ForStatementEvaluator.java b/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/ForStatementEvaluator.java index e97072509714..be074474777b 100644 --- a/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/ForStatementEvaluator.java +++ b/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/ForStatementEvaluator.java @@ -22,11 +22,7 @@ import com.intellij.openapi.util.Comparing; import com.sun.jdi.BooleanValue; /** - * Created by IntelliJ IDEA. - * User: lex - * Date: Apr 20, 2004 - * Time: 5:03:47 PM - * To change this template use File | Settings | File Templates. + * @author lex */ public class ForStatementEvaluator implements Evaluator { private final Evaluator myInitializationEvaluator; @@ -35,9 +31,13 @@ public class ForStatementEvaluator implements Evaluator { private final Evaluator myBodyEvaluator; private Modifier myModifier; - private final String myLabelName; + private final String myLabelName; - public ForStatementEvaluator(Evaluator initializationEvaluator, Evaluator conditionEvaluator, Evaluator updateEvaluator, Evaluator bodyEvaluator, String labelName) { + public ForStatementEvaluator(Evaluator initializationEvaluator, + Evaluator conditionEvaluator, + Evaluator updateEvaluator, + Evaluator bodyEvaluator, + String labelName) { myInitializationEvaluator = initializationEvaluator; myConditionEvaluator = conditionEvaluator; myUpdateEvaluator = updateEvaluator; @@ -51,19 +51,20 @@ public class ForStatementEvaluator implements Evaluator { public Object evaluate(EvaluationContextImpl context) throws EvaluateException { Object value = context.getDebugProcess().getVirtualMachineProxy().mirrorOf(); - if(myInitializationEvaluator != null) { + if (myInitializationEvaluator != null) { value = myInitializationEvaluator.evaluate(context); myModifier = myInitializationEvaluator.getModifier(); } - for (;;) { - if(myConditionEvaluator != null) { + while (true) { + if (myConditionEvaluator != null) { value = myConditionEvaluator.evaluate(context); myModifier = myConditionEvaluator.getModifier(); - if(!(value instanceof BooleanValue)) { + if (!(value instanceof BooleanValue)) { throw EvaluateExceptionUtil.BOOLEAN_EXPECTED; - } else { - if(!((BooleanValue)value).booleanValue()) { + } + else { + if (!((BooleanValue)value).booleanValue()) { break; } } @@ -73,19 +74,23 @@ public class ForStatementEvaluator implements Evaluator { myBodyEvaluator.evaluate(context); } catch (BreakException e) { - if(Comparing.equal(e.getLabelName(), myLabelName)) { + if (Comparing.equal(e.getLabelName(), myLabelName)) { break; - } else + } + else { throw e; + } } catch (ContinueException e) { - if(Comparing.equal(e.getLabelName(), myLabelName)) { + if (Comparing.equal(e.getLabelName(), myLabelName)) { //continue; - } else + } + else { throw e; + } } - if(myUpdateEvaluator != null) { + if (myUpdateEvaluator != null) { value = myUpdateEvaluator.evaluate(context); myModifier = myUpdateEvaluator.getModifier(); } diff --git a/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/IfStatementEvaluator.java b/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/IfStatementEvaluator.java index 8a73bf6c1c34..a13cdd432e1c 100644 --- a/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/IfStatementEvaluator.java +++ b/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/IfStatementEvaluator.java @@ -15,18 +15,13 @@ */ package com.intellij.debugger.engine.evaluation.expression; -import com.intellij.debugger.engine.evaluation.EvaluationContextImpl; +import com.intellij.debugger.engine.evaluation.EvaluateException; import com.intellij.debugger.engine.evaluation.EvaluateExceptionUtil; -import com.intellij.debugger.engine.evaluation.EvaluateException; -import com.intellij.debugger.engine.evaluation.EvaluateException; +import com.intellij.debugger.engine.evaluation.EvaluationContextImpl; import com.sun.jdi.BooleanValue; /** - * Created by IntelliJ IDEA. - * User: lex - * Date: Apr 20, 2004 - * Time: 5:03:47 PM - * To change this template use File | Settings | File Templates. + * @author lex */ public class IfStatementEvaluator implements Evaluator { private final Evaluator myConditionEvaluator; diff --git a/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/MapStack.java b/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/MapStack.java deleted file mode 100644 index 4e35e79dd24e..000000000000 --- a/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/MapStack.java +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright 2000-2009 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 com.intellij.debugger.engine.evaluation.expression; - -import com.intellij.openapi.diagnostic.Logger; - -import java.util.HashMap; -import java.util.Iterator; -import java.util.LinkedList; - -/** - * Created by IntelliJ IDEA. - * User: lex - * Date: Mar 24, 2004 - * Time: 10:36:12 PM - * To change this template use File | Settings | File Templates. - */ -public class MapStack { - private static final Logger LOG = Logger.getInstance("#com.intellij.debugger.engine.evaluation.expression.MapStack"); - - private final LinkedList> myStack; - - public MapStack() { - myStack = new LinkedList>(); - push(); - } - - public void push(){ - myStack.addFirst(new HashMap()); - } - - public void pop(){ - myStack.removeFirst(); - LOG.assertTrue(myStack.size() > 0); - } - - private HashMap current() { - return myStack.getFirst(); - } - - public void put(Key key, Value value) { - current().put(key, value); - } - - public boolean containsKey(Key key){ - for (Iterator> iterator = myStack.iterator(); iterator.hasNext();) { - HashMap hashMap = iterator.next(); - if(hashMap.containsKey(key))return true; - } - return false; - } - - public Value get(Key key) { - for (Iterator> iterator = myStack.iterator(); iterator.hasNext();) { - HashMap hashMap = iterator.next(); - Value value = hashMap.get(key); - if(value != null) return value; - } - return null; - } -} diff --git a/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/PostfixOperationEvaluator.java b/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/PostfixOperationEvaluator.java index f5e0fa3d2304..e4ee8c5a0d3e 100644 --- a/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/PostfixOperationEvaluator.java +++ b/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/PostfixOperationEvaluator.java @@ -23,11 +23,7 @@ import com.sun.jdi.Value; import org.jetbrains.annotations.NonNls; /** - * Created by IntelliJ IDEA. - * User: lex - * Date: Apr 20, 2004 - * Time: 5:34:50 PM - * To change this template use File | Settings | File Templates. + * @author lex */ public class PostfixOperationEvaluator implements Evaluator{ private final Evaluator myOperandEvaluator; diff --git a/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/SyntheticVariableEvaluator.java b/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/SyntheticVariableEvaluator.java index 23bd6df7555e..e96884cd0398 100644 --- a/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/SyntheticVariableEvaluator.java +++ b/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/SyntheticVariableEvaluator.java @@ -18,18 +18,13 @@ package com.intellij.debugger.engine.evaluation.expression; import com.intellij.debugger.engine.evaluation.EvaluateException; import com.intellij.debugger.engine.evaluation.EvaluationContextImpl; import com.intellij.debugger.ui.impl.watch.NodeDescriptorImpl; -import com.intellij.debugger.ui.impl.watch.NodeManagerImpl; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.project.Project; import com.sun.jdi.Type; import com.sun.jdi.Value; /** - * Created by IntelliJ IDEA. - * User: lex - * Date: Mar 25, 2004 - * Time: 2:53:29 PM - * To change this template use File | Settings | File Templates. + * @author lex */ public class SyntheticVariableEvaluator implements Evaluator{ private static final Logger LOG = Logger.getInstance("#com.intellij.debugger.engine.evaluation.expression.SyntheticVariableEvaluator"); diff --git a/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/WhileStatementEvaluator.java b/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/WhileStatementEvaluator.java index a9bc631f79e6..73a143ce1148 100644 --- a/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/WhileStatementEvaluator.java +++ b/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/WhileStatementEvaluator.java @@ -22,11 +22,7 @@ import com.intellij.openapi.util.Comparing; import com.sun.jdi.BooleanValue; /** - * Created by IntelliJ IDEA. - * User: lex - * Date: Apr 20, 2004 - * Time: 5:03:47 PM - * To change this template use File | Settings | File Templates. + * @author lex */ public class WhileStatementEvaluator implements Evaluator { private final Evaluator myConditionEvaluator; @@ -45,12 +41,13 @@ public class WhileStatementEvaluator implements Evaluator { public Object evaluate(EvaluationContextImpl context) throws EvaluateException { Object value; - for (;;) { + while (true) { value = myConditionEvaluator.evaluate(context); - if(!(value instanceof BooleanValue)) { + if (!(value instanceof BooleanValue)) { throw EvaluateExceptionUtil.BOOLEAN_EXPECTED; - } else { - if(!((BooleanValue)value).booleanValue()) { + } + else { + if (!((BooleanValue)value).booleanValue()) { break; } } @@ -58,16 +55,17 @@ public class WhileStatementEvaluator implements Evaluator { myBodyEvaluator.evaluate(context); } catch (BreakException e) { - if(Comparing.equal(e.getLabelName(), myLabelName)) { + if (Comparing.equal(e.getLabelName(), myLabelName)) { break; - } else + } + else { throw e; + } } catch (ContinueException e) { - if(Comparing.equal(e.getLabelName(), myLabelName)) { - continue; - } else + if (!Comparing.equal(e.getLabelName(), myLabelName)) { throw e; + } } } diff --git a/java/debugger/impl/src/com/intellij/debugger/engine/events/DebuggerCommandImpl.java b/java/debugger/impl/src/com/intellij/debugger/engine/events/DebuggerCommandImpl.java index d0ce0c115b67..038ff6db1b2a 100644 --- a/java/debugger/impl/src/com/intellij/debugger/engine/events/DebuggerCommandImpl.java +++ b/java/debugger/impl/src/com/intellij/debugger/engine/events/DebuggerCommandImpl.java @@ -18,11 +18,7 @@ package com.intellij.debugger.engine.events; import com.intellij.debugger.impl.DebuggerTaskImpl; /** - * Created by IntelliJ IDEA. - * User: lex - * Date: Mar 5, 2004 - * Time: 6:04:07 PM - * To change this template use File | Settings | File Templates. + * @author lex */ public abstract class DebuggerCommandImpl extends DebuggerTaskImpl { protected abstract void action() throws Exception; diff --git a/java/debugger/impl/src/com/intellij/debugger/impl/CloseWorkerThreadException.java b/java/debugger/impl/src/com/intellij/debugger/impl/CloseWorkerThreadException.java deleted file mode 100644 index 31e956f7cbc0..000000000000 --- a/java/debugger/impl/src/com/intellij/debugger/impl/CloseWorkerThreadException.java +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright 2000-2009 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 com.intellij.debugger.impl; - -/** - * Created by IntelliJ IDEA. - * User: lex - * Date: Mar 31, 2004 - * Time: 4:58:01 PM - * To change this template use File | Settings | File Templates. - */ -public class CloseWorkerThreadException extends RuntimeException { -} diff --git a/java/debugger/impl/src/com/intellij/debugger/impl/DebuggerTask.java b/java/debugger/impl/src/com/intellij/debugger/impl/DebuggerTask.java index 6467c4373f55..81639f2003c5 100644 --- a/java/debugger/impl/src/com/intellij/debugger/impl/DebuggerTask.java +++ b/java/debugger/impl/src/com/intellij/debugger/impl/DebuggerTask.java @@ -16,14 +16,12 @@ package com.intellij.debugger.impl; /** - * Created by IntelliJ IDEA. - * User: lex - * Date: Apr 7, 2004 - * Time: 2:40:47 PM - * To change this template use File | Settings | File Templates. + * @author lex */ -public interface DebuggerTask extends PrioritizedTask{ +public interface DebuggerTask extends PrioritizedTask { void release(); + void hold(); + void waitFor(); } diff --git a/java/debugger/impl/src/com/intellij/debugger/impl/DebuggerTaskImpl.java b/java/debugger/impl/src/com/intellij/debugger/impl/DebuggerTaskImpl.java index 7a0efd894d07..03cda8d8e839 100644 --- a/java/debugger/impl/src/com/intellij/debugger/impl/DebuggerTaskImpl.java +++ b/java/debugger/impl/src/com/intellij/debugger/impl/DebuggerTaskImpl.java @@ -16,11 +16,7 @@ package com.intellij.debugger.impl; /** - * Created by IntelliJ IDEA. - * User: lex - * Date: Feb 27, 2004 - * Time: 12:56:52 PM - * To change this template use File | Settings | File Templates. + * @author lex */ public abstract class DebuggerTaskImpl implements DebuggerTask { private boolean myOnHold = false; diff --git a/java/debugger/impl/src/com/intellij/debugger/impl/EventQueueClosedException.java b/java/debugger/impl/src/com/intellij/debugger/impl/EventQueueClosedException.java index 6410b7ee49db..be0cd485b30b 100644 --- a/java/debugger/impl/src/com/intellij/debugger/impl/EventQueueClosedException.java +++ b/java/debugger/impl/src/com/intellij/debugger/impl/EventQueueClosedException.java @@ -16,11 +16,7 @@ package com.intellij.debugger.impl; /** - * Created by IntelliJ IDEA. - * User: lex - * Date: Feb 19, 2004 - * Time: 8:48:37 PM - * To change this template use File | Settings | File Templates. + * @author lex */ -public class EventQueueClosedException extends Exception{ +public class EventQueueClosedException extends Exception { } diff --git a/java/debugger/impl/src/com/intellij/debugger/impl/InvokeAndWaitThread.java b/java/debugger/impl/src/com/intellij/debugger/impl/InvokeAndWaitThread.java index d88a62adb425..3278e59f1764 100644 --- a/java/debugger/impl/src/com/intellij/debugger/impl/InvokeAndWaitThread.java +++ b/java/debugger/impl/src/com/intellij/debugger/impl/InvokeAndWaitThread.java @@ -15,23 +15,19 @@ */ package com.intellij.debugger.impl; - - /** - * Created by IntelliJ IDEA. - * User: lex - * Date: Feb 24, 2004 - * Time: 3:27:55 PM - * To change this template use File | Settings | File Templates. + * @author lex */ -public abstract class InvokeAndWaitThread extends InvokeThread{ +public abstract class InvokeAndWaitThread extends InvokeThread { public InvokeAndWaitThread() { super(); } - //Do not remove this code - //Otherwise it will be impossible to override schedule method + /** + * !!! Do not remove this code !!! + * Otherwise it will be impossible to override schedule method + */ public void schedule(E e) { super.schedule(e); } diff --git a/java/debugger/impl/src/com/intellij/debugger/impl/InvokeThread.java b/java/debugger/impl/src/com/intellij/debugger/impl/InvokeThread.java index d17f14a45e76..b041959ed403 100644 --- a/java/debugger/impl/src/com/intellij/debugger/impl/InvokeThread.java +++ b/java/debugger/impl/src/com/intellij/debugger/impl/InvokeThread.java @@ -22,11 +22,7 @@ import com.sun.jdi.VMDisconnectedException; import java.util.concurrent.*; /** - * Created by IntelliJ IDEA. - * User: lex - * Date: Mar 19, 2004 - * Time: 11:42:03 AM - * To change this template use File | Settings | File Templates. + * @author lex */ public abstract class InvokeThread { private static final Logger LOG = Logger.getInstance("#com.intellij.debugger.impl.InvokeThread"); @@ -47,7 +43,7 @@ public abstract class InvokeThread { try { wait(); } - catch (InterruptedException e) { + catch (InterruptedException ignore) { } } } diff --git a/java/debugger/impl/src/com/intellij/debugger/impl/ReloadClassesWorker.java b/java/debugger/impl/src/com/intellij/debugger/impl/ReloadClassesWorker.java index 350fc81ebc30..7145ea99a359 100644 --- a/java/debugger/impl/src/com/intellij/debugger/impl/ReloadClassesWorker.java +++ b/java/debugger/impl/src/com/intellij/debugger/impl/ReloadClassesWorker.java @@ -33,15 +33,12 @@ import org.jetbrains.annotations.Nullable; import javax.swing.*; import java.io.IOException; +import java.util.HashMap; import java.util.List; import java.util.Map; /** - * Created by IntelliJ IDEA. - * User: lex - * Date: Mar 10, 2004 - * Time: 7:12:57 PM - * To change this template use File | Settings | File Templates. + * @author lex */ class ReloadClassesWorker { private static final Logger LOG = Logger.getInstance("#com.intellij.debugger.impl.ReloadClassesWorker"); @@ -62,10 +59,6 @@ class ReloadClassesWorker { return myDebuggerSession.getProcess(); } - private Project getProject() { - return myDebuggerSession.getProject(); - } - private void processException(Throwable e) { if (e.getMessage() != null) { myProgress.addMessage(myDebuggerSession, MessageCategory.ERROR, e.getMessage()); @@ -120,7 +113,7 @@ class ReloadClassesWorker { virtualMachineProxy.suspend(); try { - final Map redefineMap = new java.util.HashMap(); + final Map redefineMap = new HashMap(); int processedClassesCount = 0; final IOException[] _ex = new IOException[] {null}; for (final String qualifiedName : modifiedClasses.keySet()) { diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/CompletedInputTextField.java b/java/debugger/impl/src/com/intellij/debugger/ui/CompletedInputTextField.java deleted file mode 100644 index 587c19275a3d..000000000000 --- a/java/debugger/impl/src/com/intellij/debugger/ui/CompletedInputTextField.java +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright 2000-2009 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 com.intellij.debugger.ui; - -/** - * Created by IntelliJ IDEA. - * User: lex - * Date: Mar 31, 2004 - * Time: 7:48:44 PM - * To change this template use File | Settings | File Templates. - */ -public interface CompletedInputTextField { -} diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/DebuggerEditorImpl.java b/java/debugger/impl/src/com/intellij/debugger/ui/DebuggerEditorImpl.java index ca8cb5167e5d..a5329014a881 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/DebuggerEditorImpl.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/DebuggerEditorImpl.java @@ -34,11 +34,7 @@ import java.util.ArrayList; import java.util.List; /** - * Created by IntelliJ IDEA. - * User: lex - * Date: Apr 12, 2004 - * Time: 2:46:02 PM - * To change this template use File | Settings | File Templates. + * @author lex */ public abstract class DebuggerEditorImpl extends CompletionEditor{ private static final Logger LOG = Logger.getInstance("#com.intellij.debugger.ui.DebuggerEditorImpl"); @@ -86,7 +82,9 @@ public abstract class DebuggerEditorImpl extends CompletionEditor{ if (document != null) { PsiDocumentManager.getInstance(project).commitDocument(document); PsiFile psiFile = PsiDocumentManager.getInstance(project).getPsiFile(document); - return createText(psiFile.getText(), ((JavaCodeFragment)psiFile).importsToString()); + if (psiFile != null) { + return createText(psiFile.getText(), ((JavaCodeFragment)psiFile).importsToString()); + } } return createText(""); diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/DebuggerStatementEditor.java b/java/debugger/impl/src/com/intellij/debugger/ui/DebuggerStatementEditor.java index 54f25204b1a9..4b5d2c73cd27 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/DebuggerStatementEditor.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/DebuggerStatementEditor.java @@ -37,11 +37,7 @@ import java.util.List; import java.util.ListIterator; /** - * Created by IntelliJ IDEA. - * User: lex - * Date: Apr 12, 2004 - * Time: 2:39:17 PM - * To change this template use File | Settings | File Templates. + * @author lex */ public class DebuggerStatementEditor extends DebuggerEditorImpl { private static final Logger LOG = Logger.getInstance("#com.intellij.debugger.ui.DebuggerStatementEditor"); diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/StatementEvaluationDialog.java b/java/debugger/impl/src/com/intellij/debugger/ui/StatementEvaluationDialog.java index fe35ba2a7306..f90764a55b30 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/StatementEvaluationDialog.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/StatementEvaluationDialog.java @@ -46,11 +46,7 @@ import java.awt.event.ActionEvent; import java.awt.event.KeyEvent; /** - * Created by IntelliJ IDEA. - * User: lex - * Date: Apr 12, 2004 - * Time: 4:28:52 PM - * To change this template use File | Settings | File Templates. + * @author lex */ public class StatementEvaluationDialog extends EvaluationDialog{ private final JPanel myPanel; @@ -79,7 +75,7 @@ public class StatementEvaluationDialog extends EvaluationDialog{ splitter.setFirstComponent(editorPanel); - final EvaluationDialog.MyEvaluationPanel evaluationPanel = getEvaluationPanel(); + final MyEvaluationPanel evaluationPanel = getEvaluationPanel(); final JPanel ep = new JPanel(new BorderLayout()); final JLabel resultLabel = new JLabel(DebuggerBundle.message("label.evaluate.dialog.result")); ep.add(resultLabel, BorderLayout.NORTH); @@ -166,6 +162,9 @@ public class StatementEvaluationDialog extends EvaluationDialog{ private void updateSwitchButton(Document document) { PsiDocumentManager.getInstance(getProject()).commitDocument(document); PsiFile psiFile = PsiDocumentManager.getInstance(getProject()).getPsiFile(document); + if (psiFile == null) { + return; + } PsiElement[] children = psiFile.getChildren(); int nonWhite = 0; for (PsiElement child : children) { @@ -215,7 +214,7 @@ public class StatementEvaluationDialog extends EvaluationDialog{ private class SwitchAction extends AbstractAction { public SwitchAction() { - putValue(Action.NAME, DebuggerBundle.message("action.evaluate.statement.dialog.switch.mode.description")); + putValue(NAME, DebuggerBundle.message("action.evaluate.statement.dialog.switch.mode.description")); } public void actionPerformed(ActionEvent e) { diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/impl/TipManager.java b/java/debugger/impl/src/com/intellij/debugger/ui/impl/TipManager.java index fec8ee4b2583..721d287833db 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/impl/TipManager.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/impl/TipManager.java @@ -38,11 +38,7 @@ import java.awt.*; import java.awt.event.*; /** - * Created by IntelliJ IDEA. - * User: lex - * Date: Jan 29, 2004 - * Time: 4:23:11 PM - * To change this template use File | Settings | File Templates. + * @author lex */ public class TipManager implements Disposable, PopupMenuListener { @@ -53,7 +49,7 @@ public class TipManager implements Disposable, PopupMenuListener { private MouseEvent myLastMouseEvent; - public static interface TipFactory { + public interface TipFactory { JComponent createToolTip (MouseEvent e); MouseEvent createTooltipEvent(MouseEvent candiateEvent); boolean isFocusOwner(); @@ -152,8 +148,8 @@ public class TipManager implements Disposable, PopupMenuListener { private boolean isInsideComponent(final MouseEvent e) { final Rectangle compBounds = myComponent.getBounds(); final Point compPoint = SwingUtilities.convertPoint(e.getComponent(), e.getPoint(), myComponent); - final boolean insideCoponent = compBounds.contains(compPoint); - return insideCoponent; + + return compBounds.contains(compPoint); } diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/EvaluationDescriptor.java b/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/EvaluationDescriptor.java index 20905ce4a113..da78e13ce48e 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/EvaluationDescriptor.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/EvaluationDescriptor.java @@ -42,11 +42,7 @@ import org.jetbrains.annotations.Nullable; import java.util.List; /** - * Created by IntelliJ IDEA. - * User: lex - * Date: Apr 12, 2004 - * Time: 5:24:17 PM - * To change this template use File | Settings | File Templates. + * @author lex */ public abstract class EvaluationDescriptor extends ValueDescriptorImpl{ private Modifier myModifier; diff --git a/java/debugger/openapi/src/com/intellij/debugger/DebuggerManager.java b/java/debugger/openapi/src/com/intellij/debugger/DebuggerManager.java index 3ee119ab1f7a..c0f0bfede608 100644 --- a/java/debugger/openapi/src/com/intellij/debugger/DebuggerManager.java +++ b/java/debugger/openapi/src/com/intellij/debugger/DebuggerManager.java @@ -25,30 +25,29 @@ import com.intellij.psi.PsiClass; import com.intellij.util.Function; /** - * Created by IntelliJ IDEA. - * User: lex - * Date: Apr 29, 2004 - * Time: 6:33:26 PM - * To change this template use File | Settings | File Templates. + * @author lex */ -public abstract class DebuggerManager implements ProjectComponent, JDOMExternalizable{ +public abstract class DebuggerManager implements ProjectComponent, JDOMExternalizable { public static DebuggerManager getInstance(Project project) { return project.getComponent(DebuggerManager.class); } public abstract DebugProcess getDebugProcess(ProcessHandler processHandler); - public abstract void addDebugProcessListener (ProcessHandler processHandler, DebugProcessListener listener); + public abstract void addDebugProcessListener(ProcessHandler processHandler, DebugProcessListener listener); + public abstract void removeDebugProcessListener(ProcessHandler processHandler, DebugProcessListener listener); public abstract boolean isDebuggerManagerThread(); - + public abstract void addClassNameMapper(NameMapper mapper); + public abstract void removeClassNameMapper(NameMapper mapper); - - public abstract String getVMClassQualifiedName(PsiClass aClass); - - public abstract void registerPositionManagerFactory(Function factory); + + public abstract String getVMClassQualifiedName(PsiClass aClass); + + public abstract void registerPositionManagerFactory(Function factory); + public abstract void unregisterPositionManagerFactory(Function factory); - + } diff --git a/java/debugger/openapi/src/com/intellij/debugger/engine/DebugProcess.java b/java/debugger/openapi/src/com/intellij/debugger/engine/DebugProcess.java index 7d15ce9c419a..bca8159ee988 100644 --- a/java/debugger/openapi/src/com/intellij/debugger/engine/DebugProcess.java +++ b/java/debugger/openapi/src/com/intellij/debugger/engine/DebugProcess.java @@ -32,11 +32,7 @@ import org.jetbrains.annotations.NotNull; import java.util.List; /** - * Created by IntelliJ IDEA. - * User: lex - * Date: Apr 2, 2004 - * Time: 7:17:18 PM - * To change this template use File | Settings | File Templates. + * @author lex */ public interface DebugProcess { @NonNls String JAVA_STRATUM = "Java"; diff --git a/java/debugger/openapi/src/com/intellij/debugger/engine/evaluation/EvaluateExceptionUtil.java b/java/debugger/openapi/src/com/intellij/debugger/engine/evaluation/EvaluateExceptionUtil.java index ad3a6590e408..dff6dc30575b 100644 --- a/java/debugger/openapi/src/com/intellij/debugger/engine/evaluation/EvaluateExceptionUtil.java +++ b/java/debugger/openapi/src/com/intellij/debugger/engine/evaluation/EvaluateExceptionUtil.java @@ -19,11 +19,7 @@ import com.intellij.debugger.DebuggerBundle; import com.sun.jdi.*; /** - * Created by IntelliJ IDEA. - * User: lex - * Date: Apr 8, 2004 - * Time: 4:38:36 PM - * To change this template use File | Settings | File Templates. + * @author lex */ public class EvaluateExceptionUtil { public static final EvaluateException INCONSISTEND_DEBUG_INFO = createEvaluateException(DebuggerBundle.message("evaluation.error.inconsistent.debug.info")); @@ -38,6 +34,9 @@ public class EvaluateExceptionUtil { public static final EvaluateException THREAD_WAS_RESUMED = createEvaluateException(DebuggerBundle.message("evaluation.error.thread.resumed")); public static final EvaluateException DEBUG_INFO_UNAVAILABLE = createEvaluateException(DebuggerBundle.message("evaluation.error.debug.info.unavailable")); + private EvaluateExceptionUtil() { + } + public static EvaluateException createEvaluateException(Throwable th) { return createEvaluateException(null, th); } diff --git a/java/debugger/openapi/src/com/intellij/debugger/engine/jdi/VirtualMachineProxy.java b/java/debugger/openapi/src/com/intellij/debugger/engine/jdi/VirtualMachineProxy.java index 04031f70dc20..4f4cb8243652 100644 --- a/java/debugger/openapi/src/com/intellij/debugger/engine/jdi/VirtualMachineProxy.java +++ b/java/debugger/openapi/src/com/intellij/debugger/engine/jdi/VirtualMachineProxy.java @@ -21,11 +21,7 @@ import com.sun.jdi.ReferenceType; import java.util.List; /** - * Created by IntelliJ IDEA. - * User: lex - * Date: Apr 2, 2004 - * Time: 8:49:42 PM - * To change this template use File | Settings | File Templates. + * @author lex */ public interface VirtualMachineProxy { List allClasses(); diff --git a/java/java-impl/src/com/intellij/codeInsight/ExpectedTypeInfo.java b/java/java-impl/src/com/intellij/codeInsight/ExpectedTypeInfo.java index e425e7040821..457ef1fc6c33 100644 --- a/java/java-impl/src/com/intellij/codeInsight/ExpectedTypeInfo.java +++ b/java/java-impl/src/com/intellij/codeInsight/ExpectedTypeInfo.java @@ -20,11 +20,7 @@ import com.intellij.psi.PsiType; import org.jetbrains.annotations.NotNull; /** - * Created by IntelliJ IDEA. - * User: ven - * Date: Jul 14, 2004 - * Time: 4:45:46 PM - * To change this template use File | Settings | File Templates. + * @author ven */ public interface ExpectedTypeInfo { int TYPE_STRICTLY = 0; @@ -35,19 +31,19 @@ public interface ExpectedTypeInfo { PsiMethod getCalledMethod(); @NotNull - PsiType getType (); + PsiType getType(); - PsiType getDefaultType (); + PsiType getDefaultType(); int getKind(); - boolean equals (ExpectedTypeInfo info); + boolean equals(ExpectedTypeInfo info); String toString(); ExpectedTypeInfo[] intersect(ExpectedTypeInfo info); - boolean isArrayTypeInfo (); + boolean isArrayTypeInfo(); TailType getTailType(); diff --git a/java/java-impl/src/com/intellij/codeInsight/editorActions/smartEnter/MissingForeachBodyFixer.java b/java/java-impl/src/com/intellij/codeInsight/editorActions/smartEnter/MissingForeachBodyFixer.java index 5ca384ec26a4..807043331c77 100644 --- a/java/java-impl/src/com/intellij/codeInsight/editorActions/smartEnter/MissingForeachBodyFixer.java +++ b/java/java-impl/src/com/intellij/codeInsight/editorActions/smartEnter/MissingForeachBodyFixer.java @@ -15,18 +15,14 @@ */ package com.intellij.codeInsight.editorActions.smartEnter; -import com.intellij.psi.*; -import com.intellij.psi.util.PsiTreeUtil; import com.intellij.openapi.editor.Document; import com.intellij.openapi.editor.Editor; +import com.intellij.psi.*; +import com.intellij.psi.util.PsiTreeUtil; import com.intellij.util.IncorrectOperationException; /** - * Created by IntelliJ IDEA. - * User: Maxim.Mossienko - * Date: Jul 5, 2004 - * Time: 8:44:32 PM - * To change this template use File | Settings | File Templates. + * @author Maxim.Mossienko */ public class MissingForeachBodyFixer implements Fixer { public void apply(Editor editor, JavaSmartEnterProcessor processor, PsiElement psiElement) throws IncorrectOperationException { diff --git a/java/java-impl/src/com/intellij/codeInsight/hint/api/impls/AnnotationParameterInfoHandler.java b/java/java-impl/src/com/intellij/codeInsight/hint/api/impls/AnnotationParameterInfoHandler.java index 7ff5fe9cb4ac..bbd0c485137d 100644 --- a/java/java-impl/src/com/intellij/codeInsight/hint/api/impls/AnnotationParameterInfoHandler.java +++ b/java/java-impl/src/com/intellij/codeInsight/hint/api/impls/AnnotationParameterInfoHandler.java @@ -15,20 +15,16 @@ */ package com.intellij.codeInsight.hint.api.impls; +import com.intellij.codeInsight.lookup.LookupElement; import com.intellij.lang.parameterInfo.*; import com.intellij.psi.*; import com.intellij.util.text.CharArrayUtil; -import com.intellij.codeInsight.lookup.LookupElement; import org.jetbrains.annotations.NonNls; -import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; /** - * Created by IntelliJ IDEA. - * User: Maxim.Mossienko - * Date: Feb 1, 2006 - * Time: 3:16:16 PM - * To change this template use File | Settings | File Templates. + * @author Maxim.Mossienko */ public class AnnotationParameterInfoHandler implements ParameterInfoHandler { public @Nullable Object[] getParametersForLookup(LookupElement item, ParameterInfoContext context) { diff --git a/java/java-impl/src/com/intellij/codeInsight/hint/api/impls/ReferenceParameterInfoHandler.java b/java/java-impl/src/com/intellij/codeInsight/hint/api/impls/ReferenceParameterInfoHandler.java index 6df6a9bc418d..301d74869396 100644 --- a/java/java-impl/src/com/intellij/codeInsight/hint/api/impls/ReferenceParameterInfoHandler.java +++ b/java/java-impl/src/com/intellij/codeInsight/hint/api/impls/ReferenceParameterInfoHandler.java @@ -15,22 +15,18 @@ */ package com.intellij.codeInsight.hint.api.impls; +import com.intellij.codeInsight.lookup.LookupElement; import com.intellij.lang.parameterInfo.*; import com.intellij.openapi.util.text.StringUtil; import com.intellij.psi.*; import com.intellij.util.Function; -import com.intellij.codeInsight.lookup.LookupElement; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import java.util.Arrays; /** - * Created by IntelliJ IDEA. - * User: Maxim.Mossienko - * Date: Feb 1, 2006 - * Time: 3:16:09 PM - * To change this template use File | Settings | File Templates. + * @author Maxim.Mossienko */ public class ReferenceParameterInfoHandler implements ParameterInfoHandler { public Object[] getParametersForLookup(final LookupElement item, final ParameterInfoContext context) { diff --git a/java/java-impl/src/com/intellij/codeInsight/template/impl/TextExpression.java b/java/java-impl/src/com/intellij/codeInsight/template/impl/TextExpression.java index 982c3a680d11..78055b3dc7a8 100644 --- a/java/java-impl/src/com/intellij/codeInsight/template/impl/TextExpression.java +++ b/java/java-impl/src/com/intellij/codeInsight/template/impl/TextExpression.java @@ -22,11 +22,7 @@ import com.intellij.codeInsight.template.Result; import com.intellij.codeInsight.template.TextResult; /** - * Created by IntelliJ IDEA. - * User: Maxim - * Date: Nov 7, 2006 - * Time: 12:17:39 AM - * To change this template use File | Settings | File Templates. + * @author Maxim */ public class TextExpression extends Expression { private final String myString; diff --git a/java/java-impl/src/com/intellij/javadoc/JavadocBundle.java b/java/java-impl/src/com/intellij/javadoc/JavadocBundle.java index 3e4c0a155ece..b59c698e5954 100644 --- a/java/java-impl/src/com/intellij/javadoc/JavadocBundle.java +++ b/java/java-impl/src/com/intellij/javadoc/JavadocBundle.java @@ -24,11 +24,7 @@ import java.lang.ref.SoftReference; import java.util.ResourceBundle; /** - * Created by IntelliJ IDEA. - * User: yole - * Date: 01.09.2005 - * Time: 14:37:13 - * To change this template use File | Settings | File Templates. + * @author yole */ public class JavadocBundle { private static Reference ourBundle; @@ -38,7 +34,7 @@ public class JavadocBundle { private JavadocBundle() { } - public static String message(@PropertyKey(resourceBundle = BUNDLE)String key, Object... params) { + public static String message(@PropertyKey(resourceBundle = BUNDLE) String key, Object... params) { return CommonBundle.message(getBundle(), key, params); } diff --git a/java/java-impl/src/com/intellij/lang/java/JavaDocumentationProvider.java b/java/java-impl/src/com/intellij/lang/java/JavaDocumentationProvider.java index 26745d57a7bb..a9656cdafa26 100644 --- a/java/java-impl/src/com/intellij/lang/java/JavaDocumentationProvider.java +++ b/java/java-impl/src/com/intellij/lang/java/JavaDocumentationProvider.java @@ -61,11 +61,7 @@ import org.jetbrains.annotations.Nullable; import java.util.*; /** - * Created by IntelliJ IDEA. - * User: Maxim.Mossienko - * Date: Apr 11, 2006 - * Time: 7:45:12 PM - * To change this template use File | Settings | File Templates. + * @author Maxim.Mossienko */ public class JavaDocumentationProvider implements CodeDocumentationProvider { private static final String LINE_SEPARATOR = "\n"; @@ -608,7 +604,7 @@ public class JavaDocumentationProvider implements CodeDocumentationProvider { return CodeInsightBundle.message("javadoc.candidates.not.found", text); } - private void createElementLink(@NonNls final StringBuffer sb, final PsiElement element, final String str) { + private static void createElementLink(@NonNls final StringBuffer sb, final PsiElement element, final String str) { sb.append("  "); @@ -649,7 +645,7 @@ public class JavaDocumentationProvider implements CodeDocumentationProvider { JBPopupFactory.getInstance().createListPopup(new BaseListPopupStep("Choose javadoc root", ArrayUtil.toStringArray(set)) { public PopupStep onChosen(final String selectedValue, final boolean finalChoice) { BrowserUtil.launchBrowser(selectedValue); - return PopupStep.FINAL_CHOICE; + return FINAL_CHOICE; } }).showInBestPositionFor(DataManager.getInstance().getDataContext()); } diff --git a/java/java-impl/src/com/intellij/lang/java/JavaLanguage.java b/java/java-impl/src/com/intellij/lang/java/JavaLanguage.java index 1e05e1d4f774..5282be171fe4 100644 --- a/java/java-impl/src/com/intellij/lang/java/JavaLanguage.java +++ b/java/java-impl/src/com/intellij/lang/java/JavaLanguage.java @@ -26,11 +26,7 @@ import com.intellij.pom.java.LanguageLevel; import org.jetbrains.annotations.NotNull; /** - * Created by IntelliJ IDEA. - * User: max - * Date: Jan 22, 2005 - * Time: 11:16:59 PM - * To change this template use File | Settings | File Templates. + * @author max */ public class JavaLanguage extends Language { public JavaLanguage() { @@ -38,7 +34,8 @@ public class JavaLanguage extends Language { SyntaxHighlighterFactory.LANGUAGE_FACTORY.addExplicitExtension(this, new SyntaxHighlighterFactory() { @NotNull public SyntaxHighlighter getSyntaxHighlighter(final Project project, final VirtualFile virtualFile) { - return new JavaFileHighlighter(virtualFile != null ? LanguageLevelUtil.getLanguageLevelForFile(virtualFile) : LanguageLevel.HIGHEST); + return new JavaFileHighlighter( + virtualFile != null ? LanguageLevelUtil.getLanguageLevelForFile(virtualFile) : LanguageLevel.HIGHEST); } }); } diff --git a/java/java-impl/src/com/intellij/lang/java/JavaParserDefinition.java b/java/java-impl/src/com/intellij/lang/java/JavaParserDefinition.java index 17558301ca28..c69bef5561b5 100644 --- a/java/java-impl/src/com/intellij/lang/java/JavaParserDefinition.java +++ b/java/java-impl/src/com/intellij/lang/java/JavaParserDefinition.java @@ -35,11 +35,7 @@ import com.intellij.psi.util.PsiUtil; import org.jetbrains.annotations.NotNull; /** - * Created by IntelliJ IDEA. - * User: max - * Date: Jan 26, 2005 - * Time: 12:40:22 PM - * To change this template use File | Settings | File Templates. + * @author max */ public class JavaParserDefinition implements ParserDefinition { private final TokenSet myStringLiteralElementSet = TokenSet.create(JavaElementType.LITERAL_EXPRESSION); diff --git a/java/java-impl/src/com/intellij/psi/impl/source/codeStyle/ImportsFormatter.java b/java/java-impl/src/com/intellij/psi/impl/source/codeStyle/ImportsFormatter.java index f60e452428f1..35531343cec7 100644 --- a/java/java-impl/src/com/intellij/psi/impl/source/codeStyle/ImportsFormatter.java +++ b/java/java-impl/src/com/intellij/psi/impl/source/codeStyle/ImportsFormatter.java @@ -30,13 +30,8 @@ import com.intellij.util.text.CharArrayUtil; import org.jetbrains.annotations.NonNls; /** - * Created by IntelliJ IDEA. - * User: lesya - * Date: Jul 21, 2005 - * Time: 7:42:23 PM - * To change this template use File | Settings | File Templates. + * @author lesya */ - public class ImportsFormatter extends XmlRecursiveElementVisitor { private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.source.codeStyle.ImportsFormatter"); @@ -59,7 +54,7 @@ public class ImportsFormatter extends XmlRecursiveElementVisitor { } } - private boolean isPageDirectiveTag(final XmlTag tag) { + private static boolean isPageDirectiveTag(final XmlTag tag) { return PAGE_DIRECTIVE.equals(tag.getName()); } @@ -134,7 +129,7 @@ public class ImportsFormatter extends XmlRecursiveElementVisitor { } } - private ASTNode findValueToken(final ASTNode node) { + private static ASTNode findValueToken(final ASTNode node) { ASTNode child = node.getFirstChildNode(); while (child != null){ if (child.getElementType() == XmlElementType.XML_ATTRIBUTE_VALUE_TOKEN) return child; @@ -143,7 +138,7 @@ public class ImportsFormatter extends XmlRecursiveElementVisitor { return null; } - private boolean isImportAttribute(final XmlAttribute attribute) { + private static boolean isImportAttribute(final XmlAttribute attribute) { return IMPORT_ATT.equals(attribute.getName()); } diff --git a/java/java-impl/src/com/intellij/psi/impl/source/javadoc/ValueDocTagInfo.java b/java/java-impl/src/com/intellij/psi/impl/source/javadoc/ValueDocTagInfo.java index 595ef8c5b9d6..d8932ff1783c 100644 --- a/java/java-impl/src/com/intellij/psi/impl/source/javadoc/ValueDocTagInfo.java +++ b/java/java-impl/src/com/intellij/psi/impl/source/javadoc/ValueDocTagInfo.java @@ -20,17 +20,13 @@ import com.intellij.psi.PsiElement; import com.intellij.psi.PsiField; import com.intellij.psi.PsiModifier; import com.intellij.psi.PsiReference; -import com.intellij.psi.util.PsiUtil; import com.intellij.psi.impl.JavaConstantExpressionEvaluator; import com.intellij.psi.javadoc.JavadocTagInfo; import com.intellij.psi.javadoc.PsiDocTagValue; +import com.intellij.psi.util.PsiUtil; /** - * Created by IntelliJ IDEA. - * User: yole - * Date: 10.08.2005 - * Time: 18:25:51 - * To change this template use File | Settings | File Templates. + * @author yole */ public class ValueDocTagInfo implements JavadocTagInfo { public String getName() { @@ -81,6 +77,6 @@ public class ValueDocTagInfo implements JavadocTagInfo { } public PsiReference getReference(PsiDocTagValue value) { - return null; //To change body of implemented methods use File | Settings | File Templates. + return null; } } diff --git a/java/java-impl/src/com/intellij/psi/impl/source/parsing/JavaParsingContext.java b/java/java-impl/src/com/intellij/psi/impl/source/parsing/JavaParsingContext.java index 856f0c4dfe28..e1cec1c88e36 100644 --- a/java/java-impl/src/com/intellij/psi/impl/source/parsing/JavaParsingContext.java +++ b/java/java-impl/src/com/intellij/psi/impl/source/parsing/JavaParsingContext.java @@ -15,16 +15,12 @@ */ package com.intellij.psi.impl.source.parsing; +import com.intellij.pom.java.LanguageLevel; import com.intellij.psi.impl.source.ParsingContext; import com.intellij.util.CharTable; -import com.intellij.pom.java.LanguageLevel; /** - * Created by IntelliJ IDEA. - * User: ik - * Date: 07.06.2004 - * Time: 18:45:17 - * To change this template use File | Settings | File Templates. + * @author ik */ public class JavaParsingContext extends ParsingContext { private final DeclarationParsing myDeclarationParsing; diff --git a/java/java-impl/src/com/intellij/refactoring/typeCook/deductive/PsiExtendedTypeVisitor.java b/java/java-impl/src/com/intellij/refactoring/typeCook/deductive/PsiExtendedTypeVisitor.java index e9f7f4d77a71..264face31401 100644 --- a/java/java-impl/src/com/intellij/refactoring/typeCook/deductive/PsiExtendedTypeVisitor.java +++ b/java/java-impl/src/com/intellij/refactoring/typeCook/deductive/PsiExtendedTypeVisitor.java @@ -20,13 +20,9 @@ import com.intellij.psi.PsiType; import com.intellij.psi.PsiTypeVisitorEx; /** - * Created by IntelliJ IDEA. - * User: db - * Date: Dec 27, 2004 - * Time: 7:20:09 PM - * To change this template use File | Settings | File Templates. + * @author db */ -public abstract class PsiExtendedTypeVisitor extends PsiTypeVisitorEx { +public abstract class PsiExtendedTypeVisitor extends PsiTypeVisitorEx { public X visitClassType(final PsiClassType classType) { super.visitClassType(classType); final PsiClassType.ClassResolveResult result = classType.resolveGenerics(); diff --git a/java/java-impl/src/com/intellij/refactoring/typeCook/deductive/PsiTypeVariableFactory.java b/java/java-impl/src/com/intellij/refactoring/typeCook/deductive/PsiTypeVariableFactory.java index 0a3b33895584..35c5d72b3083 100644 --- a/java/java-impl/src/com/intellij/refactoring/typeCook/deductive/PsiTypeVariableFactory.java +++ b/java/java-impl/src/com/intellij/refactoring/typeCook/deductive/PsiTypeVariableFactory.java @@ -23,15 +23,10 @@ import org.jetbrains.annotations.NotNull; import java.util.HashMap; import java.util.HashSet; -import java.util.Iterator; import java.util.LinkedList; /** - * Created by IntelliJ IDEA. - * User: db - * Date: Jan 12, 2005 - * Time: 9:41:45 PM - * To change this template use File | Settings | File Templates. + * @author db */ public class PsiTypeVariableFactory { private int myCurrent = 0; @@ -45,8 +40,8 @@ public class PsiTypeVariableFactory { public final void registerCluster(final HashSet cluster) { myClusters.add(cluster); - for (final Iterator v = cluster.iterator(); v.hasNext();) { - myVarCluster.put(new Integer(v.next().getIndex()), cluster); + for (final PsiTypeVariable aCluster : cluster) { + myVarCluster.put(new Integer(aCluster.getIndex()), cluster); } } @@ -77,76 +72,75 @@ public class PsiTypeVariableFactory { } return type.accept(new PsiTypeVisitor() { - public Boolean visitType(final PsiType type) { - return Boolean.TRUE; - } + public Boolean visitType(final PsiType type) { + return Boolean.TRUE; + } - public Boolean visitArrayType(final PsiArrayType arrayType) { - return arrayType.getDeepComponentType().accept(this); - } + public Boolean visitArrayType(final PsiArrayType arrayType) { + return arrayType.getDeepComponentType().accept(this); + } - public Boolean visitWildcardType(final PsiWildcardType wildcardType) { - final PsiType bound = wildcardType.getBound(); + public Boolean visitWildcardType(final PsiWildcardType wildcardType) { + final PsiType bound = wildcardType.getBound(); - if (bound != null) { - bound.accept(this); - } + if (bound != null) { + bound.accept(this); + } - return Boolean.TRUE; - } + return Boolean.TRUE; + } - public Boolean visitClassType(final PsiClassType classType) { - final PsiClassType.ClassResolveResult result = classType.resolveGenerics(); - final PsiClass aClass = result.getElement(); - final PsiSubstitutor aSubst = result.getSubstitutor(); + public Boolean visitClassType(final PsiClassType classType) { + final PsiClassType.ClassResolveResult result = classType.resolveGenerics(); + final PsiClass aClass = result.getElement(); + final PsiSubstitutor aSubst = result.getSubstitutor(); - if (aClass != null) { - final PsiManager manager = aClass.getManager(); - final JavaPsiFacade facade = JavaPsiFacade.getInstance(manager.getProject()); + if (aClass != null) { + final PsiManager manager = aClass.getManager(); + final JavaPsiFacade facade = JavaPsiFacade.getInstance(manager.getProject()); - if (aClass instanceof PsiTypeParameter) { - final PsiTypeParameterListOwner owner = - PsiTreeUtil.getParentOfType(myContext, PsiTypeParameterListOwner.class); + if (aClass instanceof PsiTypeParameter) { + final PsiTypeParameterListOwner owner = PsiTreeUtil.getParentOfType(myContext, PsiTypeParameterListOwner.class); - if (owner != null) { - boolean found = false; + if (owner != null) { + boolean found = false; - for (PsiTypeParameter typeParameter : PsiUtil.typeParametersIterable(owner)) { - found = manager.areElementsEquivalent(typeParameter, aClass); - if (found) break; - } + for (PsiTypeParameter typeParameter : PsiUtil.typeParametersIterable(owner)) { + found = manager.areElementsEquivalent(typeParameter, aClass); + if (found) break; + } - if (!found) { - return Boolean.FALSE; - } - } - else { - return Boolean.FALSE; - } - } - else if (!facade.getResolveHelper().isAccessible(aClass, myContext, null)) { - return Boolean.FALSE; - } + if (!found) { + return Boolean.FALSE; + } + } + else { + return Boolean.FALSE; + } + } + else if (!facade.getResolveHelper().isAccessible(aClass, myContext, null)) { + return Boolean.FALSE; + } - for (PsiTypeParameter parm : PsiUtil.typeParametersIterable(aClass)) { - final PsiType type = aSubst.substitute(parm); + for (PsiTypeParameter parm : PsiUtil.typeParametersIterable(aClass)) { + final PsiType type = aSubst.substitute(parm); - if (type != null){ - final Boolean b = type.accept(this); + if (type != null) { + final Boolean b = type.accept(this); - if (! b.booleanValue()){ - return Boolean.FALSE; - } - } - } + if (!b.booleanValue()) { + return Boolean.FALSE; + } + } + } - return Boolean.TRUE; - } - else { - return Boolean.FALSE; - } - } - }).booleanValue(); + return Boolean.TRUE; + } + else { + return Boolean.FALSE; + } + } + }).booleanValue(); } public String getPresentableText() { diff --git a/java/java-impl/src/com/intellij/refactoring/typeCook/deductive/builder/Constraint.java b/java/java-impl/src/com/intellij/refactoring/typeCook/deductive/builder/Constraint.java index b987e2d9d887..afb4691c2ad9 100644 --- a/java/java-impl/src/com/intellij/refactoring/typeCook/deductive/builder/Constraint.java +++ b/java/java-impl/src/com/intellij/refactoring/typeCook/deductive/builder/Constraint.java @@ -15,16 +15,12 @@ */ package com.intellij.refactoring.typeCook.deductive.builder; -import com.intellij.psi.PsiType; import com.intellij.openapi.diagnostic.Logger; +import com.intellij.psi.PsiType; import com.intellij.refactoring.typeCook.deductive.resolver.Binding; /** - * Created by IntelliJ IDEA. - * User: db - * Date: Jul 20, 2004 - * Time: 6:00:28 PM - * To change this template use File | Settings | File Templates. + * @author db */ public abstract class Constraint { private static final Logger LOG = Logger.getInstance("#com.intellij.refactoring.typeCook.deductive.builder.Constraint"); diff --git a/java/java-impl/src/com/intellij/refactoring/typeCook/deductive/builder/Subtype.java b/java/java-impl/src/com/intellij/refactoring/typeCook/deductive/builder/Subtype.java index e60951413694..754b7453bd8b 100644 --- a/java/java-impl/src/com/intellij/refactoring/typeCook/deductive/builder/Subtype.java +++ b/java/java-impl/src/com/intellij/refactoring/typeCook/deductive/builder/Subtype.java @@ -19,11 +19,7 @@ import com.intellij.psi.PsiType; import com.intellij.refactoring.typeCook.deductive.resolver.Binding; /** - * Created by IntelliJ IDEA. - * User: db - * Date: Jul 20, 2004 - * Time: 6:02:29 PM - * To change this template use File | Settings | File Templates. + * @author db */ public class Subtype extends Constraint { public Subtype(PsiType left, PsiType right) { diff --git a/java/java-impl/src/com/intellij/refactoring/typeCook/deductive/util/VictimCollector.java b/java/java-impl/src/com/intellij/refactoring/typeCook/deductive/util/VictimCollector.java index 5ea95ae5e86b..370c2d2b2989 100644 --- a/java/java-impl/src/com/intellij/refactoring/typeCook/deductive/util/VictimCollector.java +++ b/java/java-impl/src/com/intellij/refactoring/typeCook/deductive/util/VictimCollector.java @@ -22,11 +22,7 @@ import com.intellij.refactoring.typeCook.Util; import java.util.HashSet; /** - * Created by IntelliJ IDEA. - * User: db - * Date: Jul 5, 2004 - * Time: 6:45:51 PM - * To change this template use File | Settings | File Templates. + * @author db */ public class VictimCollector extends Visitor { final HashSet myVictims = new HashSet(); diff --git a/java/java-impl/src/com/intellij/refactoring/typeCook/deductive/util/Visitor.java b/java/java-impl/src/com/intellij/refactoring/typeCook/deductive/util/Visitor.java index 5b11bc030ee3..1838ae91cb2e 100644 --- a/java/java-impl/src/com/intellij/refactoring/typeCook/deductive/util/Visitor.java +++ b/java/java-impl/src/com/intellij/refactoring/typeCook/deductive/util/Visitor.java @@ -18,26 +18,20 @@ package com.intellij.refactoring.typeCook.deductive.util; import com.intellij.psi.*; /** - * Created by IntelliJ IDEA. - * User: db - * Date: Jul 5, 2004 - * Time: 6:44:49 PM - * To change this template use File | Settings | File Templates. + * @author db */ public abstract class Visitor extends JavaRecursiveElementWalkingVisitor { @Override public void visitPackage(final PsiPackage aPackage) { final PsiDirectory[] dirs = aPackage.getDirectories(); - for (int i = 0; i < dirs.length; i++) { - final PsiFile[] files = dirs[i].getFiles(); - - for (int j = 0; j < files.length; j++) { - final PsiFile file = files[j]; + for (PsiDirectory dir : dirs) { + final PsiFile[] files = dir.getFiles(); + for (final PsiFile file : files) { if (file instanceof PsiJavaFile) { super.visitJavaFile(((PsiJavaFile)file)); } } } } -} \ No newline at end of file +} diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/completion/CustomFileTypeCompletionTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/completion/CustomFileTypeCompletionTest.java index 384f491b7e65..ef35e95fd909 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/completion/CustomFileTypeCompletionTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/completion/CustomFileTypeCompletionTest.java @@ -3,11 +3,7 @@ package com.intellij.codeInsight.completion; import com.intellij.JavaTestUtil; /** - * Created by IntelliJ IDEA. - * User: Maxim.Mossienko - * Date: Oct 14, 2004 - * Time: 4:39:37 PM - * To change this template use File | Settings | File Templates. + * @author Maxim.Mossienko */ public class CustomFileTypeCompletionTest extends LightCompletionTestCase { private static final String BASE_PATH = "/codeInsight/completion/customFileType/"; diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/completion/WordCompletionTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/completion/WordCompletionTest.java index 22613915de80..772d769a79ab 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/completion/WordCompletionTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/completion/WordCompletionTest.java @@ -11,11 +11,7 @@ import com.intellij.util.ProcessingContext; import org.jetbrains.annotations.NotNull; /** - * Created by IntelliJ IDEA. - * User: Maxim.Mossienko - * Date: Oct 14, 2004 - * Time: 4:39:37 PM - * To change this template use File | Settings | File Templates. + * @author Maxim.Mossienko */ public class WordCompletionTest extends CompletionTestCase { private static final String BASE_PATH = "/codeInsight/completion/word/"; diff --git a/java/jsp-base-openapi/src/com/intellij/lang/jsp/IBaseJspManager.java b/java/jsp-base-openapi/src/com/intellij/lang/jsp/IBaseJspManager.java index 52ac367ed5fe..a7fabc4e3bf5 100644 --- a/java/jsp-base-openapi/src/com/intellij/lang/jsp/IBaseJspManager.java +++ b/java/jsp-base-openapi/src/com/intellij/lang/jsp/IBaseJspManager.java @@ -15,18 +15,14 @@ */ package com.intellij.lang.jsp; -import org.jetbrains.annotations.Nullable; -import org.jetbrains.annotations.NotNull; +import com.intellij.psi.PsiFile; import com.intellij.xml.XmlElementDescriptor; import com.intellij.xml.XmlNSDescriptor; -import com.intellij.psi.PsiFile; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; /** - * Created by IntelliJ IDEA. - * User: Maxim.Mossienko - * Date: 20.04.2009 - * Time: 17:07:57 - * To change this template use File | Settings | File Templates. + * @author Maxim.Mossienko */ public interface IBaseJspManager { XmlNSDescriptor getActionsLibrary(@NotNull PsiFile containingFile); diff --git a/java/jsp-base-openapi/src/com/intellij/lang/jsp/JspFileViewProvider.java b/java/jsp-base-openapi/src/com/intellij/lang/jsp/JspFileViewProvider.java index f1bb9cf5b460..d0bb429508c0 100644 --- a/java/jsp-base-openapi/src/com/intellij/lang/jsp/JspFileViewProvider.java +++ b/java/jsp-base-openapi/src/com/intellij/lang/jsp/JspFileViewProvider.java @@ -22,14 +22,11 @@ import org.jetbrains.annotations.NotNull; import java.util.Set; /** - * Created by IntelliJ IDEA. - * User: ik - * Date: Dec 12, 2005 - * Time: 3:28:22 PM - * To change this template use File | Settings | File Templates. + * @author ik */ public interface JspFileViewProvider extends JspxFileViewProvider { @NotNull Language getTemplateDataLanguage(); + Set getKnownTaglibPrefixes(); } diff --git a/java/jsp-base-openapi/src/com/intellij/lang/jsp/JspxFileViewProvider.java b/java/jsp-base-openapi/src/com/intellij/lang/jsp/JspxFileViewProvider.java index 3c960d432bb0..31784036be6f 100644 --- a/java/jsp-base-openapi/src/com/intellij/lang/jsp/JspxFileViewProvider.java +++ b/java/jsp-base-openapi/src/com/intellij/lang/jsp/JspxFileViewProvider.java @@ -16,21 +16,17 @@ package com.intellij.lang.jsp; -import com.intellij.lang.Language; import com.intellij.lang.DependentLanguage; +import com.intellij.lang.Language; import com.intellij.psi.templateLanguages.TemplateLanguageFileViewProvider; /** - * Created by IntelliJ IDEA. - * User: ik - * Date: Dec 12, 2005 - * Time: 7:40:40 PM - * To change this template use File | Settings | File Templates. + * @author ik */ public interface JspxFileViewProvider extends TemplateLanguageFileViewProvider { Language JAVA_HOLDER_METHOD_TREE_LANGUAGE = new JavaHolderMethodTreeLanguage(); - public static class JavaHolderMethodTreeLanguage extends Language implements DependentLanguage{ + class JavaHolderMethodTreeLanguage extends Language implements DependentLanguage{ public JavaHolderMethodTreeLanguage() { super("JAVA_HOLDER_METHOD_TREE", ""); } diff --git a/java/jsp-base-openapi/src/com/intellij/lexer/ELHostLexer.java b/java/jsp-base-openapi/src/com/intellij/lexer/ELHostLexer.java index 6c0bbe95dde1..9a8c60220781 100644 --- a/java/jsp-base-openapi/src/com/intellij/lexer/ELHostLexer.java +++ b/java/jsp-base-openapi/src/com/intellij/lexer/ELHostLexer.java @@ -18,12 +18,8 @@ package com.intellij.lexer; import com.intellij.psi.tree.IElementType; /** - * Created by IntelliJ IDEA. - * User: Maxim.Mossienko - * Date: May 13, 2005 - * Time: 1:34:29 PM - * To change this template use File | Settings | File Templates. + * @author Maxim.Mossienko */ public interface ELHostLexer { - void setElTypes(IElementType elTokenTypeForContent,IElementType elTokenTypeForAttribute); + void setElTypes(IElementType elTokenTypeForContent, IElementType elTokenTypeForAttribute); } diff --git a/java/jsp-spi/src/com/intellij/jsp/impl/TldAttributeDescriptor.java b/java/jsp-spi/src/com/intellij/jsp/impl/TldAttributeDescriptor.java index 781d05524941..5dbc7024806a 100644 --- a/java/jsp-spi/src/com/intellij/jsp/impl/TldAttributeDescriptor.java +++ b/java/jsp-spi/src/com/intellij/jsp/impl/TldAttributeDescriptor.java @@ -19,22 +19,20 @@ import com.intellij.xml.XmlAttributeDescriptor; import org.jetbrains.annotations.Nullable; /** - * Created by IntelliJ IDEA. - * User: Maxim.Mossienko - * Date: Jan 26, 2007 - * Time: 7:03:23 PM - * To change this template use File | Settings | File Templates. + * @author Maxim.Mossienko */ public interface TldAttributeDescriptor extends XmlAttributeDescriptor { /** * Indicates that attribute is a fragment + * * @return */ boolean isIndirectSyntax(); /** * Returns method signature for deferred methods + * * @return */ @Nullable @@ -42,6 +40,7 @@ public interface TldAttributeDescriptor extends XmlAttributeDescriptor { /** * Returns value of "type" subtag + * * @return */ @Nullable diff --git a/platform/lang-api/src/com/intellij/codeInsight/editorActions/smartEnter/SmartEnterProcessor.java b/platform/lang-api/src/com/intellij/codeInsight/editorActions/smartEnter/SmartEnterProcessor.java index 416750fafc9e..4c88a5aede99 100644 --- a/platform/lang-api/src/com/intellij/codeInsight/editorActions/smartEnter/SmartEnterProcessor.java +++ b/platform/lang-api/src/com/intellij/codeInsight/editorActions/smartEnter/SmartEnterProcessor.java @@ -31,11 +31,7 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; /** - * Created by IntelliJ IDEA. - * User: max - * Date: Sep 5, 2003 - * Time: 3:31:23 PM - * To change this template use Options | File Templates. + * @author max */ public abstract class SmartEnterProcessor { public abstract boolean process(@NotNull final Project project, @NotNull final Editor editor, @NotNull final PsiFile psiFile); diff --git a/platform/lang-api/src/com/intellij/diagnostic/logging/IndependentLogFilter.java b/platform/lang-api/src/com/intellij/diagnostic/logging/IndependentLogFilter.java index f3a99a13781b..b4ffe858df94 100644 --- a/platform/lang-api/src/com/intellij/diagnostic/logging/IndependentLogFilter.java +++ b/platform/lang-api/src/com/intellij/diagnostic/logging/IndependentLogFilter.java @@ -17,11 +17,7 @@ package com.intellij.diagnostic.logging; /** - * Created by IntelliJ IDEA. - * User: Eugene.Kudelevsky - * Date: Sep 11, 2009 - * Time: 2:34:25 PM - * To change this template use File | Settings | File Templates. + * @author Eugene.Kudelevsky */ public abstract class IndependentLogFilter extends LogFilter { protected IndependentLogFilter(String name) { diff --git a/platform/lang-api/src/com/intellij/execution/ExecutionBundle.java b/platform/lang-api/src/com/intellij/execution/ExecutionBundle.java index af072abc1c3e..a9f20c7be1f3 100644 --- a/platform/lang-api/src/com/intellij/execution/ExecutionBundle.java +++ b/platform/lang-api/src/com/intellij/execution/ExecutionBundle.java @@ -24,11 +24,7 @@ import java.lang.ref.SoftReference; import java.util.ResourceBundle; /** - * Created by IntelliJ IDEA. - * User: lesya - * Date: Aug 29, 2005 - * Time: 11:45:48 PM - * To change this template use File | Settings | File Templates. + * @author lesya */ public class ExecutionBundle { private static Reference ourBundle; diff --git a/platform/lang-api/src/com/intellij/pom/PomTransaction.java b/platform/lang-api/src/com/intellij/pom/PomTransaction.java index b8ff3c90802f..679b00a45050 100644 --- a/platform/lang-api/src/com/intellij/pom/PomTransaction.java +++ b/platform/lang-api/src/com/intellij/pom/PomTransaction.java @@ -20,15 +20,14 @@ import com.intellij.psi.PsiElement; import com.intellij.util.IncorrectOperationException; /** - * Created by IntelliJ IDEA. - * User: ik - * Date: Oct 6, 2004 - * Time: 9:48:15 PM - * To change this template use File | Settings | File Templates. + * @author ik */ -public interface PomTransaction{ +public interface PomTransaction { PomModelEvent getAccumulatedEvent(); + void run() throws IncorrectOperationException; + PsiElement getChangeScope(); + PomModelAspect getTransactionAspect(); } diff --git a/platform/lang-api/src/com/intellij/pom/tree/events/TreeChange.java b/platform/lang-api/src/com/intellij/pom/tree/events/TreeChange.java index 904497e1855d..ab2cd838c742 100644 --- a/platform/lang-api/src/com/intellij/pom/tree/events/TreeChange.java +++ b/platform/lang-api/src/com/intellij/pom/tree/events/TreeChange.java @@ -18,21 +18,19 @@ package com.intellij.pom.tree.events; import com.intellij.lang.ASTNode; /** - * Created by IntelliJ IDEA. - * User: ik - * Date: Oct 6, 2004 - * Time: 11:00:28 PM - * To change this template use File | Settings | File Templates. + * @author ik */ - public interface TreeChange { void addChange(ASTNode child, ChangeInfo changeInfo); ASTNode[] getAffectedChildren(); + ChangeInfo getChangeByChild(ASTNode child); + int getChildOffsetInNewTree(ASTNode child); void composite(TreeChange treeChange); + boolean isEmpty(); void removeChange(ASTNode beforeEqualDepth); diff --git a/platform/lang-api/src/com/intellij/pom/tree/events/TreeChangeEvent.java b/platform/lang-api/src/com/intellij/pom/tree/events/TreeChangeEvent.java index 8cc8097a10fb..4485fe63e7ff 100644 --- a/platform/lang-api/src/com/intellij/pom/tree/events/TreeChangeEvent.java +++ b/platform/lang-api/src/com/intellij/pom/tree/events/TreeChangeEvent.java @@ -19,17 +19,16 @@ import com.intellij.lang.ASTNode; import com.intellij.pom.event.PomChangeSet; /** - * Created by IntelliJ IDEA. - * User: ik - * Date: Oct 6, 2004 - * Time: 10:56:52 PM - * To change this template use File | Settings | File Templates. + * @author ik */ -public interface TreeChangeEvent extends PomChangeSet{ +public interface TreeChangeEvent extends PomChangeSet { ASTNode getRootElement(); + ASTNode[] getChangedElements(); + TreeChange getChangesByElement(ASTNode element); void addElementaryChange(ASTNode child, ChangeInfo change); + void clear(); } diff --git a/platform/lang-api/src/com/intellij/psi/meta/PsiWritableMetaData.java b/platform/lang-api/src/com/intellij/psi/meta/PsiWritableMetaData.java index e5c58507f1d0..223efe6be092 100644 --- a/platform/lang-api/src/com/intellij/psi/meta/PsiWritableMetaData.java +++ b/platform/lang-api/src/com/intellij/psi/meta/PsiWritableMetaData.java @@ -18,11 +18,7 @@ package com.intellij.psi.meta; import com.intellij.util.IncorrectOperationException; /** - * Created by IntelliJ IDEA. - * User: Maxim.Mossienko - * Date: Apr 18, 2005 - * Time: 2:41:47 PM - * To change this template use File | Settings | File Templates. + * @author Maxim.Mossienko */ public interface PsiWritableMetaData extends PsiMetaData { void setName(String name) throws IncorrectOperationException; diff --git a/platform/lang-api/src/com/intellij/usageView/UsageViewBundle.java b/platform/lang-api/src/com/intellij/usageView/UsageViewBundle.java index 799cec328b11..ebbff1026939 100644 --- a/platform/lang-api/src/com/intellij/usageView/UsageViewBundle.java +++ b/platform/lang-api/src/com/intellij/usageView/UsageViewBundle.java @@ -25,11 +25,7 @@ import java.lang.ref.SoftReference; import java.util.ResourceBundle; /** - * Created by IntelliJ IDEA. - * User: yole - * Date: 11.08.2005 - * Time: 16:04:31 - * To change this template use File | Settings | File Templates. + * @author yole */ public class UsageViewBundle { private static Reference ourBundle; diff --git a/platform/lang-api/src/com/intellij/util/CharTable.java b/platform/lang-api/src/com/intellij/util/CharTable.java index a54730d6645a..3355e1bdce49 100644 --- a/platform/lang-api/src/com/intellij/util/CharTable.java +++ b/platform/lang-api/src/com/intellij/util/CharTable.java @@ -18,13 +18,9 @@ package com.intellij.util; import com.intellij.openapi.util.Key; /** - * Created by IntelliJ IDEA. - * User: ik - * Date: 07.06.2004 - * Time: 15:28:03 - * To change this template use File | Settings | File Templates. + * @author ik */ -public interface CharTable{ +public interface CharTable { int PAGE_SIZE = 256; Key CHAR_TABLE_KEY = new Key("Char table"); diff --git a/platform/lang-impl/src/com/intellij/application/options/colors/ColorSettingsUtil.java b/platform/lang-impl/src/com/intellij/application/options/colors/ColorSettingsUtil.java index 4dce0422bb92..4bdca9d42a14 100644 --- a/platform/lang-impl/src/com/intellij/application/options/colors/ColorSettingsUtil.java +++ b/platform/lang-impl/src/com/intellij/application/options/colors/ColorSettingsUtil.java @@ -16,24 +16,23 @@ package com.intellij.application.options.colors; -import com.intellij.openapi.editor.colors.TextAttributesKey; -import com.intellij.openapi.editor.colors.EditorColorsScheme; import com.intellij.openapi.editor.colors.EditorColorsManager; +import com.intellij.openapi.editor.colors.EditorColorsScheme; +import com.intellij.openapi.editor.colors.TextAttributesKey; import com.intellij.openapi.editor.colors.impl.EditorColorsManagerImpl; -import com.intellij.openapi.options.colors.ColorSettingsPage; import com.intellij.openapi.options.colors.AttributesDescriptor; +import com.intellij.openapi.options.colors.ColorSettingsPage; import com.intellij.util.containers.HashMap; import java.util.Map; /** - * Created by IntelliJ IDEA. - * User: lesya - * Date: Oct 23, 2008 - * Time: 4:28:18 PM - * To change this template use File | Settings | File Templates. + * @author lesya */ public class ColorSettingsUtil { + private ColorSettingsUtil() { + } + public static Map keyToDisplayTextMap(final ColorSettingsPage page) { final AttributesDescriptor[] attributeDescriptors = page.getAttributeDescriptors(); final Map displayText = new HashMap(); diff --git a/platform/lang-impl/src/com/intellij/application/options/editor/EditorTabsConfigurable.java b/platform/lang-impl/src/com/intellij/application/options/editor/EditorTabsConfigurable.java index cbd28327db47..ac87af126244 100644 --- a/platform/lang-impl/src/com/intellij/application/options/editor/EditorTabsConfigurable.java +++ b/platform/lang-impl/src/com/intellij/application/options/editor/EditorTabsConfigurable.java @@ -16,15 +16,15 @@ package com.intellij.application.options.editor; -import com.intellij.openapi.options.ConfigurationException; -import com.intellij.openapi.application.ApplicationBundle; import com.intellij.ide.ui.UISettings; +import com.intellij.openapi.application.ApplicationBundle; +import com.intellij.openapi.options.ConfigurationException; import org.jetbrains.annotations.Nls; import javax.swing.*; import java.awt.*; -import java.awt.event.ItemListener; import java.awt.event.ItemEvent; +import java.awt.event.ItemListener; /** * @author yole @@ -76,7 +76,7 @@ public class EditorTabsConfigurable implements EditorOptionsProvider { } public Icon getIcon() { - return null; //To change body of implemented methods use File | Settings | File Templates. + return null; } public String getHelpTopic() { @@ -151,7 +151,7 @@ public class EditorTabsConfigurable implements EditorOptionsProvider { public boolean isModified() { final UISettings uiSettings = UISettings.getInstance(); - boolean isModified = isModified(myCbModifiedTabsMarkedWithAsterisk, uiSettings.MARK_MODIFIED_TABS_WITH_ASTERISK);; + boolean isModified = isModified(myCbModifiedTabsMarkedWithAsterisk, uiSettings.MARK_MODIFIED_TABS_WITH_ASTERISK); isModified |= isModified(myEditorTabLimitField, uiSettings.EDITOR_TAB_LIMIT); int tabPlacement = ((Integer)myEditorTabPlacement.getSelectedItem()).intValue(); isModified |= tabPlacement != uiSettings.EDITOR_TAB_PLACEMENT; @@ -167,7 +167,6 @@ public class EditorTabsConfigurable implements EditorOptionsProvider { } public void disposeUIResources() { - //To change body of implemented methods use File | Settings | File Templates. } @@ -196,16 +195,16 @@ public class EditorTabsConfigurable implements EditorOptionsProvider { if (UISettings.TABS_NONE == tabPlacement) { text = ApplicationBundle.message("combobox.tab.placement.none"); } - else if (SwingConstants.TOP == tabPlacement) { + else if (TOP == tabPlacement) { text = ApplicationBundle.message("combobox.tab.placement.top"); } - else if (SwingConstants.LEFT == tabPlacement) { + else if (LEFT == tabPlacement) { text = ApplicationBundle.message("combobox.tab.placement.left"); } - else if (SwingConstants.BOTTOM == tabPlacement) { + else if (BOTTOM == tabPlacement) { text = ApplicationBundle.message("combobox.tab.placement.bottom"); } - else if (SwingConstants.RIGHT == tabPlacement) { + else if (RIGHT == tabPlacement) { text = ApplicationBundle.message("combobox.tab.placement.right"); } else { diff --git a/platform/lang-impl/src/com/intellij/codeEditor/printing/CodeEditorBundle.java b/platform/lang-impl/src/com/intellij/codeEditor/printing/CodeEditorBundle.java index 0655833eaacf..ab636b1f9fd4 100644 --- a/platform/lang-impl/src/com/intellij/codeEditor/printing/CodeEditorBundle.java +++ b/platform/lang-impl/src/com/intellij/codeEditor/printing/CodeEditorBundle.java @@ -25,11 +25,7 @@ import java.lang.ref.SoftReference; import java.util.ResourceBundle; /** - * Created by IntelliJ IDEA. - * User: yole - * Date: 30.08.2005 - * Time: 18:49:13 - * To change this template use File | Settings | File Templates. + * @author yole */ public class CodeEditorBundle { private static Reference ourBundle; diff --git a/platform/lang-impl/src/com/intellij/codeEditor/printing/HelpID.java b/platform/lang-impl/src/com/intellij/codeEditor/printing/HelpID.java index f85b5654ec1f..973825c47c49 100644 --- a/platform/lang-impl/src/com/intellij/codeEditor/printing/HelpID.java +++ b/platform/lang-impl/src/com/intellij/codeEditor/printing/HelpID.java @@ -19,11 +19,7 @@ package com.intellij.codeEditor.printing; import org.jetbrains.annotations.NonNls; /** - * Created by IntelliJ IDEA. - * User: Alexander.Chernikov - * Date: 20.10.2006 - * Time: 18:55:05 - * To change this template use File | Settings | File Templates. + * @author Alexander.Chernikov */ public interface HelpID { @NonNls String EXPORT_TO_HTML = "reference.file.exportToHtml"; diff --git a/platform/lang-impl/src/com/intellij/codeInsight/completion/CompletionVariant.java b/platform/lang-impl/src/com/intellij/codeInsight/completion/CompletionVariant.java index a0f643b15c08..ab9607da4ab8 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/completion/CompletionVariant.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/completion/CompletionVariant.java @@ -34,13 +34,8 @@ import org.jetbrains.annotations.NonNls; import java.util.*; /** - * Created by IntelliJ IDEA. - * User: ik - * Date: 31.01.2003 - * Time: 17:38:14 - * To change this template use Options | File Templates. + * @author ik */ - public class CompletionVariant { protected static final TailType DEFAULT_TAIL_TYPE = TailType.SPACE; diff --git a/platform/lang-impl/src/com/intellij/codeInsight/completion/KeywordChooser.java b/platform/lang-impl/src/com/intellij/codeInsight/completion/KeywordChooser.java index 8a330e8cbf0d..7f5bbfb79333 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/completion/KeywordChooser.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/completion/KeywordChooser.java @@ -19,11 +19,7 @@ package com.intellij.codeInsight.completion; import com.intellij.psi.PsiElement; /** - * Created by IntelliJ IDEA. - * User: ik - * Date: 17.02.2003 - * Time: 16:53:09 - * To change this template use Options | File Templates. + * @author ik */ public interface KeywordChooser{ String[] getKeywords(CompletionContext context, PsiElement position); diff --git a/platform/lang-impl/src/com/intellij/codeInsight/completion/SyntaxTableCompletionData.java b/platform/lang-impl/src/com/intellij/codeInsight/completion/SyntaxTableCompletionData.java index 7f2c4e5d76b8..3ab6579593ab 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/completion/SyntaxTableCompletionData.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/completion/SyntaxTableCompletionData.java @@ -22,11 +22,7 @@ import com.intellij.psi.PsiElement; import com.intellij.psi.filters.TrueFilter; /** - * Created by IntelliJ IDEA. - * User: Maxim.Mossienko - * Date: Oct 14, 2004 - * Time: 4:28:39 PM - * To change this template use File | Settings | File Templates. + * @author Maxim.Mossienko */ public class SyntaxTableCompletionData extends CompletionData{ private final SyntaxTable mySyntaxTable; diff --git a/platform/lang-impl/src/com/intellij/codeInsight/completion/actions/HippieWordCompletionHandler.java b/platform/lang-impl/src/com/intellij/codeInsight/completion/actions/HippieWordCompletionHandler.java index 888c1b770006..5207f8d26456 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/completion/actions/HippieWordCompletionHandler.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/completion/actions/HippieWordCompletionHandler.java @@ -35,11 +35,7 @@ import org.jetbrains.annotations.Nullable; import java.util.*; /** - * Created by IntelliJ IDEA. - * User: mike - * Date: May 11, 2006 - * Time: 3:48:48 PM - * To change this template use File | Settings | File Templates. + * @author mike */ public class HippieWordCompletionHandler implements CodeInsightActionHandler { private static final Key KEY_STATE = new Key("HIPPIE_COMPLETION_STATE"); diff --git a/platform/lang-impl/src/com/intellij/codeInsight/daemon/Validator.java b/platform/lang-impl/src/com/intellij/codeInsight/daemon/Validator.java index 73572efff971..2b208430901a 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/daemon/Validator.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/daemon/Validator.java @@ -21,11 +21,7 @@ import com.intellij.psi.PsiElement; import org.jetbrains.annotations.NotNull; /** - * Created by IntelliJ IDEA. - * User: Maxim.Mossienko - * Date: Jan 14, 2005 - * Time: 10:53:20 PM - * To change this template use File | Settings | File Templates. + * @author Maxim.Mossienko */ public interface Validator { interface ValidationHost { diff --git a/platform/lang-impl/src/com/intellij/codeInsight/folding/impl/CollapseSelectionHandler.java b/platform/lang-impl/src/com/intellij/codeInsight/folding/impl/CollapseSelectionHandler.java index 4f6a575093da..fcf6e1cf7361 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/folding/impl/CollapseSelectionHandler.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/folding/impl/CollapseSelectionHandler.java @@ -27,11 +27,7 @@ import com.intellij.psi.PsiFile; import org.jetbrains.annotations.NotNull; /** - * Created by IntelliJ IDEA. - * User: ven - * Date: Apr 10, 2003 - * Time: 8:52:53 PM - * To change this template use Options | File Templates. + * @author ven */ public class CollapseSelectionHandler implements CodeInsightActionHandler { private static final String ourPlaceHolderText = "..."; diff --git a/platform/lang-impl/src/com/intellij/codeInsight/folding/impl/actions/CollapseSelectionAction.java b/platform/lang-impl/src/com/intellij/codeInsight/folding/impl/actions/CollapseSelectionAction.java index 056a160ea5c5..66d877fdea6d 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/folding/impl/actions/CollapseSelectionAction.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/folding/impl/actions/CollapseSelectionAction.java @@ -16,17 +16,13 @@ package com.intellij.codeInsight.folding.impl.actions; -import com.intellij.codeInsight.actions.BaseCodeInsightAction; import com.intellij.codeInsight.CodeInsightActionHandler; +import com.intellij.codeInsight.actions.BaseCodeInsightAction; import com.intellij.codeInsight.folding.impl.CollapseSelectionHandler; import com.intellij.openapi.project.DumbAware; /** - * Created by IntelliJ IDEA. - * User: ven - * Date: Apr 10, 2003 - * Time: 9:59:35 PM - * To change this template use Options | File Templates. + * @author ven */ public class CollapseSelectionAction extends BaseCodeInsightAction implements DumbAware { protected CodeInsightActionHandler getHandler() { diff --git a/platform/lang-impl/src/com/intellij/codeInsight/lookup/DeferredUserLookupValue.java b/platform/lang-impl/src/com/intellij/codeInsight/lookup/DeferredUserLookupValue.java index 2c9d2ab01ad6..f2a4f3c5dd5e 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/lookup/DeferredUserLookupValue.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/lookup/DeferredUserLookupValue.java @@ -19,13 +19,9 @@ package com.intellij.codeInsight.lookup; import com.intellij.openapi.project.Project; /** - * Created by IntelliJ IDEA. - * User: Maxim.Mossienko - * Date: Sep 29, 2004 - * Time: 7:38:32 PM - * To change this template use File | Settings | File Templates. + * @author Maxim.Mossienko * @deprecated use InsertHandler */ public interface DeferredUserLookupValue extends PresentableLookupValue { - boolean handleUserSelection(LookupItem item,Project project); + boolean handleUserSelection(LookupItem item, Project project); } diff --git a/platform/lang-impl/src/com/intellij/codeInsight/lookup/LookupValueWithPriority.java b/platform/lang-impl/src/com/intellij/codeInsight/lookup/LookupValueWithPriority.java index e28fe445fb07..ab5b1b80d326 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/lookup/LookupValueWithPriority.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/lookup/LookupValueWithPriority.java @@ -17,16 +17,12 @@ package com.intellij.codeInsight.lookup; /** - * Created by IntelliJ IDEA. - * User: Maxim.Mossienko - * Date: Jun 20, 2005 - * Time: 8:12:52 PM - * To change this template use File | Settings | File Templates. + * @author Maxim.Mossienko */ public interface LookupValueWithPriority { int NORMAL = 0; int HIGHER = 1; int HIGH = 2; - + int getPriority(); } diff --git a/platform/lang-impl/src/com/intellij/codeInsight/lookup/LookupValueWithPsiElement.java b/platform/lang-impl/src/com/intellij/codeInsight/lookup/LookupValueWithPsiElement.java index 325a9e807367..62f892cc5843 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/lookup/LookupValueWithPsiElement.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/lookup/LookupValueWithPsiElement.java @@ -19,11 +19,7 @@ package com.intellij.codeInsight.lookup; import com.intellij.psi.PsiElement; /** - * Created by IntelliJ IDEA. - * User: Maxim.Mossienko - * Date: Jun 20, 2005 - * Time: 8:12:52 PM - * To change this template use File | Settings | File Templates. + * @author Maxim.Mossienko */ public interface LookupValueWithPsiElement { PsiElement getElement(); diff --git a/platform/lang-impl/src/com/intellij/codeInsight/lookup/LookupValueWithUIHint.java b/platform/lang-impl/src/com/intellij/codeInsight/lookup/LookupValueWithUIHint.java index 41099f43d338..883067a81c4b 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/lookup/LookupValueWithUIHint.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/lookup/LookupValueWithUIHint.java @@ -19,15 +19,13 @@ package com.intellij.codeInsight.lookup; import java.awt.*; /** - * Created by IntelliJ IDEA. - * User: maxim - * Date: 10.12.2004 - * Time: 13:25:56 - * To change this template use File | Settings | File Templates. + * @author maxim * @deprecated use InsertHandler */ public interface LookupValueWithUIHint extends PresentableLookupValue { String getTypeHint(); + Color getColorHint(); + boolean isBold(); } diff --git a/platform/lang-impl/src/com/intellij/codeInsight/lookup/PresentableLookupValue.java b/platform/lang-impl/src/com/intellij/codeInsight/lookup/PresentableLookupValue.java index b19d5279876a..ccb253b00c0f 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/lookup/PresentableLookupValue.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/lookup/PresentableLookupValue.java @@ -17,13 +17,9 @@ package com.intellij.codeInsight.lookup; /** - * Created by IntelliJ IDEA. - * User: maxim - * Date: 10.12.2004 - * Time: 13:38:25 - * To change this template use File | Settings | File Templates. + * @author maxim * @deprecated use LookupElementBuilder */ public interface PresentableLookupValue { - String getPresentation(); + String getPresentation(); } diff --git a/platform/lang-impl/src/com/intellij/codeInsight/template/FileTypeBasedContextType.java b/platform/lang-impl/src/com/intellij/codeInsight/template/FileTypeBasedContextType.java index 523257895803..d88aea4facb0 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/template/FileTypeBasedContextType.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/template/FileTypeBasedContextType.java @@ -20,15 +20,11 @@ import com.intellij.openapi.fileTypes.FileType; import com.intellij.openapi.fileTypes.LanguageFileType; import com.intellij.openapi.fileTypes.SyntaxHighlighter; import com.intellij.psi.PsiFile; -import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NonNls; +import org.jetbrains.annotations.NotNull; /** - * Created by IntelliJ IDEA. - * User: lesya - * Date: Jul 28, 2008 - * Time: 4:53:26 PM - * To change this template use File | Settings | File Templates. + * @author lesya */ public abstract class FileTypeBasedContextType extends TemplateContextType { private final LanguageFileType myFileType; diff --git a/platform/lang-impl/src/com/intellij/codeInsight/template/impl/TemplateImplUtil.java b/platform/lang-impl/src/com/intellij/codeInsight/template/impl/TemplateImplUtil.java index 34114bfb0d60..d4261d2855ac 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/template/impl/TemplateImplUtil.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/template/impl/TemplateImplUtil.java @@ -24,13 +24,12 @@ import java.util.ArrayList; import java.util.Set; /** - * Created by IntelliJ IDEA. - * User: Maxim.Mossienko - * Date: Mar 19, 2004 - * Time: 1:28:54 PM - * To change this template use File | Settings | File Templates. + * @author Maxim.Mossienko */ public class TemplateImplUtil { + private TemplateImplUtil() { + } + public static boolean validateTemplateText(String s) { TemplateTextLexer lexer = new TemplateTextLexer(); lexer.start(s); diff --git a/platform/lang-impl/src/com/intellij/find/FindBundle.java b/platform/lang-impl/src/com/intellij/find/FindBundle.java index 3d3a2ecf03a2..ea7e68cc8472 100644 --- a/platform/lang-impl/src/com/intellij/find/FindBundle.java +++ b/platform/lang-impl/src/com/intellij/find/FindBundle.java @@ -25,11 +25,7 @@ import java.lang.ref.SoftReference; import java.util.ResourceBundle; /** - * Created by IntelliJ IDEA. - * User: yole - * Date: 31.08.2005 - * Time: 13:20:15 - * To change this template use File | Settings | File Templates. + * @author yole */ public class FindBundle { private static Reference ourBundle; diff --git a/platform/lang-impl/src/com/intellij/find/findUsages/CommonFindUsagesDialog.java b/platform/lang-impl/src/com/intellij/find/findUsages/CommonFindUsagesDialog.java index bf96889a8275..f0346d309ea0 100644 --- a/platform/lang-impl/src/com/intellij/find/findUsages/CommonFindUsagesDialog.java +++ b/platform/lang-impl/src/com/intellij/find/findUsages/CommonFindUsagesDialog.java @@ -16,9 +16,9 @@ package com.intellij.find.findUsages; +import com.intellij.openapi.help.HelpManager; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.text.StringUtil; -import com.intellij.openapi.help.HelpManager; import com.intellij.psi.PsiElement; import com.intellij.psi.search.LocalSearchScope; import com.intellij.usageView.UsageViewUtil; @@ -26,11 +26,7 @@ import com.intellij.usageView.UsageViewUtil; import javax.swing.*; /** - * Created by IntelliJ IDEA. - * User: max - * Date: Feb 14, 2005 - * Time: 5:40:05 PM - * To change this template use File | Settings | File Templates. + * @author max */ public class CommonFindUsagesDialog extends AbstractFindUsagesDialog { private final PsiElement myPsiElement; diff --git a/platform/lang-impl/src/com/intellij/formatting/AbstractBlockWrapper.java b/platform/lang-impl/src/com/intellij/formatting/AbstractBlockWrapper.java index 87003242f15f..ee3a329a2295 100644 --- a/platform/lang-impl/src/com/intellij/formatting/AbstractBlockWrapper.java +++ b/platform/lang-impl/src/com/intellij/formatting/AbstractBlockWrapper.java @@ -22,11 +22,7 @@ import com.intellij.psi.codeStyle.CodeStyleSettings; import java.util.ArrayList; /** - * Created by IntelliJ IDEA. - * User: lesya - * Date: Apr 14, 2005 - * Time: 9:40:01 PM - * To change this template use File | Settings | File Templates. + * @author lesya */ public abstract class AbstractBlockWrapper { protected WhiteSpace myWhiteSpace; diff --git a/platform/lang-impl/src/com/intellij/ide/highlighter/custom/impl/CustomFileTypeBraceMatcher.java b/platform/lang-impl/src/com/intellij/ide/highlighter/custom/impl/CustomFileTypeBraceMatcher.java index 1c7c996e2810..a33cd28629f0 100644 --- a/platform/lang-impl/src/com/intellij/ide/highlighter/custom/impl/CustomFileTypeBraceMatcher.java +++ b/platform/lang-impl/src/com/intellij/ide/highlighter/custom/impl/CustomFileTypeBraceMatcher.java @@ -26,11 +26,7 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; /** - * Created by IntelliJ IDEA. - * User: Maxim.Mossienko - * Date: Dec 6, 2004 - * Time: 8:36:58 PM - * To change this template use File | Settings | File Templates. + * @author Maxim.Mossienko */ class CustomFileTypeBraceMatcher implements BraceMatcher { public int getBraceTokenGroupId(IElementType tokenType) { diff --git a/platform/lang-impl/src/com/intellij/ide/highlighter/custom/impl/CustomFileTypeQuoteHandler.java b/platform/lang-impl/src/com/intellij/ide/highlighter/custom/impl/CustomFileTypeQuoteHandler.java index 7507656cdc6f..2c9c64c8550b 100644 --- a/platform/lang-impl/src/com/intellij/ide/highlighter/custom/impl/CustomFileTypeQuoteHandler.java +++ b/platform/lang-impl/src/com/intellij/ide/highlighter/custom/impl/CustomFileTypeQuoteHandler.java @@ -24,11 +24,7 @@ import com.intellij.psi.CustomHighlighterTokenType; import com.intellij.psi.tree.IElementType; /** - * Created by IntelliJ IDEA. - * User: Maxim.Mossienko - * Date: Dec 6, 2004 - * Time: 8:34:21 PM - * To change this template use File | Settings | File Templates. + * @author Maxim.Mossienko */ class CustomFileTypeQuoteHandler implements QuoteHandler { public boolean isClosingQuote(HighlighterIterator iterator, int offset) { diff --git a/platform/lang-impl/src/com/intellij/ide/highlighter/custom/tokens/BraceTokenParser.java b/platform/lang-impl/src/com/intellij/ide/highlighter/custom/tokens/BraceTokenParser.java index d40d7693dc62..dea3904e99a7 100644 --- a/platform/lang-impl/src/com/intellij/ide/highlighter/custom/tokens/BraceTokenParser.java +++ b/platform/lang-impl/src/com/intellij/ide/highlighter/custom/tokens/BraceTokenParser.java @@ -19,11 +19,7 @@ package com.intellij.ide.highlighter.custom.tokens; import com.intellij.psi.tree.IElementType; /** - * Created by IntelliJ IDEA. - * User: Maxim.Mossienko - * Date: Dec 6, 2004 - * Time: 7:40:12 PM - * To change this template use File | Settings | File Templates. + * @author Maxim.Mossienko */ public class BraceTokenParser extends PrefixedTokenParser { public BraceTokenParser(String prefix, IElementType tokenType) { diff --git a/platform/lang-impl/src/com/intellij/ide/structureView/StructureViewWrapper.java b/platform/lang-impl/src/com/intellij/ide/structureView/StructureViewWrapper.java index 78bdb6f9288b..17edcf03b9e1 100644 --- a/platform/lang-impl/src/com/intellij/ide/structureView/StructureViewWrapper.java +++ b/platform/lang-impl/src/com/intellij/ide/structureView/StructureViewWrapper.java @@ -20,11 +20,7 @@ import com.intellij.openapi.fileEditor.FileEditor; import com.intellij.openapi.vfs.VirtualFile; /** - * Created by IntelliJ IDEA. - * User: lesya - * Date: Feb 23, 2005 - * Time: 7:19:02 PM - * To change this template use File | Settings | File Templates. + * @author lesya */ public interface StructureViewWrapper { boolean selectCurrentElement(FileEditor fileEditor, VirtualFile file, boolean requestFocus); diff --git a/platform/lang-impl/src/com/intellij/lang/LangBundle.java b/platform/lang-impl/src/com/intellij/lang/LangBundle.java index 3dc2b2aecbf6..ceab51505f01 100644 --- a/platform/lang-impl/src/com/intellij/lang/LangBundle.java +++ b/platform/lang-impl/src/com/intellij/lang/LangBundle.java @@ -25,11 +25,7 @@ import java.lang.ref.SoftReference; import java.util.ResourceBundle; /** - * Created by IntelliJ IDEA. - * User: yole - * Date: 12.09.2005 - * Time: 18:03:21 - * To change this template use File | Settings | File Templates. + * @author yole */ public class LangBundle { private static Reference ourBundle; diff --git a/platform/lang-impl/src/com/intellij/pom/tree/events/impl/TreeChangeEventImpl.java b/platform/lang-impl/src/com/intellij/pom/tree/events/impl/TreeChangeEventImpl.java index def3b1dbc4b8..e36accb9a054 100644 --- a/platform/lang-impl/src/com/intellij/pom/tree/events/impl/TreeChangeEventImpl.java +++ b/platform/lang-impl/src/com/intellij/pom/tree/events/impl/TreeChangeEventImpl.java @@ -31,11 +31,7 @@ import gnu.trove.THashMap; import java.util.*; /** - * Created by IntelliJ IDEA. - * User: ik - * Date: Oct 6, 2004 - * Time: 11:11:40 PM - * To change this template use File | Settings | File Templates. + * @author ik */ public class TreeChangeEventImpl implements TreeChangeEvent{ private final Map myChangedElements = new THashMap(); diff --git a/platform/lang-impl/src/com/intellij/psi/impl/source/codeStyle/AbstractPostFormatProcessor.java b/platform/lang-impl/src/com/intellij/psi/impl/source/codeStyle/AbstractPostFormatProcessor.java index 3957018cfaeb..5d1cb0e7f039 100644 --- a/platform/lang-impl/src/com/intellij/psi/impl/source/codeStyle/AbstractPostFormatProcessor.java +++ b/platform/lang-impl/src/com/intellij/psi/impl/source/codeStyle/AbstractPostFormatProcessor.java @@ -21,11 +21,7 @@ import com.intellij.psi.codeStyle.CodeStyleSettings; import org.jetbrains.annotations.Nullable; /** - * Created by IntelliJ IDEA. - * User: lesya - * Date: Jul 21, 2005 - * Time: 7:53:12 PM - * To change this template use File | Settings | File Templates. + * @author lesya */ public class AbstractPostFormatProcessor { protected final CodeStyleSettings mySettings; diff --git a/platform/lang-impl/src/com/intellij/psi/impl/source/codeStyle/AffectedTextRange.java b/platform/lang-impl/src/com/intellij/psi/impl/source/codeStyle/AffectedTextRange.java deleted file mode 100644 index f192707dcde2..000000000000 --- a/platform/lang-impl/src/com/intellij/psi/impl/source/codeStyle/AffectedTextRange.java +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright 2000-2009 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 com.intellij.psi.impl.source.codeStyle; - -import com.intellij.openapi.util.TextRange; - -/** - * Created by IntelliJ IDEA. - * User: lesya - * Date: Nov 26, 2008 - * Time: 6:26:45 PM - * To change this template use File | Settings | File Templates. - */ -public class AffectedTextRange extends TextRange { - private final boolean myProcessHeadingWhiteSpace; - - public AffectedTextRange(final int startOffset, final int endOffset, final boolean processHeadingWhiteSpace) { - super(startOffset, endOffset); - myProcessHeadingWhiteSpace = processHeadingWhiteSpace; - } - - public AffectedTextRange(final TextRange affectedRange, final boolean processHeadingWhitespace) { - this(affectedRange.getStartOffset(), affectedRange.getEndOffset(), processHeadingWhitespace); - } - - public boolean isProcessHeadingWhiteSpace() { - return myProcessHeadingWhiteSpace; - } -} diff --git a/platform/lang-impl/src/com/intellij/psi/impl/source/parsing/ParseUtilBase.java b/platform/lang-impl/src/com/intellij/psi/impl/source/parsing/ParseUtilBase.java index b9603a9bda6f..e5592643e0c8 100644 --- a/platform/lang-impl/src/com/intellij/psi/impl/source/parsing/ParseUtilBase.java +++ b/platform/lang-impl/src/com/intellij/psi/impl/source/parsing/ParseUtilBase.java @@ -16,19 +16,15 @@ package com.intellij.psi.impl.source.parsing; -import com.intellij.psi.impl.source.tree.TreeElement; -import com.intellij.psi.tree.IElementType; +import com.intellij.lang.ASTFactory; import com.intellij.lexer.Lexer; import com.intellij.lexer.LexerUtil; +import com.intellij.psi.impl.source.tree.TreeElement; +import com.intellij.psi.tree.IElementType; import com.intellij.util.CharTable; -import com.intellij.lang.ASTFactory; /** - * Created by IntelliJ IDEA. - * User: Maxim.Mossienko - * Date: 20.04.2009 - * Time: 15:02:52 - * To change this template use File | Settings | File Templates. + * @author Maxim.Mossienko */ public class ParseUtilBase { public static TreeElement createTokenElement(Lexer lexer, CharTable table) { diff --git a/platform/lang-impl/src/com/intellij/psi/impl/source/resolve/reference/impl/providers/CustomizingReferenceProvider.java b/platform/lang-impl/src/com/intellij/psi/impl/source/resolve/reference/impl/providers/CustomizingReferenceProvider.java index 41aa37b3dc07..ad10402686e8 100644 --- a/platform/lang-impl/src/com/intellij/psi/impl/source/resolve/reference/impl/providers/CustomizingReferenceProvider.java +++ b/platform/lang-impl/src/com/intellij/psi/impl/source/resolve/reference/impl/providers/CustomizingReferenceProvider.java @@ -27,15 +27,11 @@ import java.util.HashMap; import java.util.Map; /** - * Created by IntelliJ IDEA. - * User: Maxim.Mossienko - * Date: Nov 9, 2005 - * Time: 8:10:06 PM - * To change this template use File | Settings | File Templates. + * @author Maxim.Mossienko */ public class CustomizingReferenceProvider extends PsiReferenceProvider implements CustomizableReferenceProvider { private final CustomizableReferenceProvider myProvider; - private @Nullable Map myOptions; + private @Nullable Map myOptions; public CustomizingReferenceProvider(@NotNull CustomizableReferenceProvider provider) { myProvider = provider; @@ -43,7 +39,7 @@ public class CustomizingReferenceProvider extends PsiReferenceProvider implement public Alexey Efimov */ public interface ThumbnailView extends Disposable, ImageComponentDecorator { - String TOOLWINDOW_ID = ImagesBundle.message("thumbnails.toolwindow.name"); + DataKey DATA_KEY = DataKey.create(ThumbnailView.class.getName()); - @NotNull - Project getProject(); + String TOOLWINDOW_ID = ImagesBundle.message("thumbnails.toolwindow.name"); - /** - * Add virtual files to view - * - * @param root Root - */ - void setRoot(@NotNull VirtualFile root); + @NotNull + Project getProject(); - /** - * Return current root - * - * @return Current root - */ - VirtualFile getRoot(); + /** + * Add virtual files to view + * + * @param root Root + */ + void setRoot(@NotNull VirtualFile root); - boolean isRecursive(); + /** + * Return current root + * + * @return Current root + */ + VirtualFile getRoot(); - void setRecursive(boolean recursive); + boolean isRecursive(); - void setSelected(@NotNull VirtualFile file, boolean selected); + void setRecursive(boolean recursive); - boolean isSelected(@NotNull VirtualFile file); + void setSelected(@NotNull VirtualFile file, boolean selected); - @NotNull - VirtualFile[] getSelection(); + boolean isSelected(@NotNull VirtualFile file); - /** - * Scroll to selection. If ToolWindow is not active, then - * it will perform activatation before scroll. - */ - void scrollToSelection(); + @NotNull + VirtualFile[] getSelection(); - void setVisible(boolean visible); + /** + * Scroll to selection. If ToolWindow is not active, then + * it will perform activatation before scroll. + */ + void scrollToSelection(); - boolean isVisible(); + void setVisible(boolean visible); - void activate(); + boolean isVisible(); + + void activate(); } diff --git a/images/src/org/intellij/images/thumbnail/actionSystem/ThumbnailViewActionUtil.java b/images/src/org/intellij/images/thumbnail/actionSystem/ThumbnailViewActionUtil.java index b53040ab543a..bf381dff43ee 100644 --- a/images/src/org/intellij/images/thumbnail/actionSystem/ThumbnailViewActionUtil.java +++ b/images/src/org/intellij/images/thumbnail/actionSystem/ThumbnailViewActionUtil.java @@ -16,7 +16,6 @@ package org.intellij.images.thumbnail.actionSystem; import com.intellij.openapi.actionSystem.AnActionEvent; -import com.intellij.openapi.actionSystem.DataContext; import com.intellij.openapi.actionSystem.Presentation; import org.intellij.images.thumbnail.ThumbnailView; @@ -44,8 +43,7 @@ public final class ThumbnailViewActionUtil { } public static ThumbnailView getThumbnailView(AnActionEvent e) { - DataContext dataContext = e.getDataContext(); - return (ThumbnailView) dataContext.getData(ThumbnailView.class.getName()); + return ThumbnailView.DATA_KEY.getData(e.getDataContext()); } /** diff --git a/images/src/org/intellij/images/thumbnail/impl/ThumbnailViewUI.java b/images/src/org/intellij/images/thumbnail/impl/ThumbnailViewUI.java index 490e742fe47f..2de28dd40660 100644 --- a/images/src/org/intellij/images/thumbnail/impl/ThumbnailViewUI.java +++ b/images/src/org/intellij/images/thumbnail/impl/ThumbnailViewUI.java @@ -90,7 +90,7 @@ final class ThumbnailViewUI extends JPanel implements DataProvider, Disposable { final PsiActionSupportFactory factory = PsiActionSupportFactory.getInstance(); copyPasteSupport = factory.createPsiBasedCopyPasteSupport(thumbnailView.getProject(), this, new PsiActionSupportFactory.PsiElementSelector() { public PsiElement[] getSelectedElements() { - return (PsiElement[]) getData(DataConstants.PSI_ELEMENT_ARRAY); + return (PsiElement[]) getData(LangDataKeys.PSI_ELEMENT_ARRAY.getName()); } }); @@ -410,32 +410,32 @@ final class ThumbnailViewUI extends JPanel implements DataProvider, Disposable { @Nullable public Object getData(String dataId) { - if (DataConstants.PROJECT.equals(dataId)) { + if (PlatformDataKeys.PROJECT.is(dataId)) { return thumbnailView.getProject(); - } else if (DataConstants.VIRTUAL_FILE.equals(dataId)) { + } else if (PlatformDataKeys.VIRTUAL_FILE.is(dataId)) { VirtualFile[] selectedFiles = getSelectedFiles(); return selectedFiles.length > 0 ? selectedFiles[0] : null; - } else if (DataConstants.VIRTUAL_FILE_ARRAY.equals(dataId)) { + } else if (PlatformDataKeys.VIRTUAL_FILE_ARRAY.is(dataId)) { return getSelectedFiles(); - } else if (DataConstants.PSI_FILE.equals(dataId)) { - return getData(DataConstants.PSI_ELEMENT); - } else if (DataConstants.PSI_ELEMENT.equals(dataId)) { + } else if (LangDataKeys.PSI_FILE.is(dataId)) { + return getData(LangDataKeys.PSI_ELEMENT.getName()); + } else if (LangDataKeys.PSI_ELEMENT.is(dataId)) { VirtualFile[] selectedFiles = getSelectedFiles(); return selectedFiles.length > 0 ? PsiManager.getInstance(thumbnailView.getProject()).findFile(selectedFiles[0]) : null; - } else if (DataConstants.PSI_ELEMENT_ARRAY.equals(dataId)) { + } else if (LangDataKeys.PSI_ELEMENT_ARRAY.is(dataId)) { return getSelectedElements(); - } else if (DataConstants.NAVIGATABLE.equals(dataId)) { + } else if (PlatformDataKeys.NAVIGATABLE.is(dataId)) { VirtualFile[] selectedFiles = getSelectedFiles(); return new ThumbnailNavigatable(selectedFiles.length > 0 ? selectedFiles[0] : null); - } else if (DataConstants.COPY_PROVIDER.equals(dataId)) { + } else if (PlatformDataKeys.COPY_PROVIDER.is(dataId)) { return copyPasteSupport.getCopyProvider(); - } else if (DataConstants.CUT_PROVIDER.equals(dataId)) { + } else if (PlatformDataKeys.CUT_PROVIDER.is(dataId)) { return copyPasteSupport.getCutProvider(); - } else if (DataConstants.PASTE_PROVIDER.equals(dataId)) { + } else if (PlatformDataKeys.PASTE_PROVIDER.is(dataId)) { return copyPasteSupport.getPasteProvider(); - } else if (DataConstants.DELETE_ELEMENT_PROVIDER.equals(dataId)) { + } else if (PlatformDataKeys.DELETE_ELEMENT_PROVIDER.is(dataId)) { return deleteProvider; - } else if (DataConstants.NAVIGATABLE_ARRAY.equals(dataId)) { + } else if (PlatformDataKeys.NAVIGATABLE_ARRAY.is(dataId)) { VirtualFile[] selectedFiles = getSelectedFiles(); Set navigatables = new HashSet(selectedFiles.length); for (VirtualFile selectedFile : selectedFiles) { @@ -444,9 +444,9 @@ final class ThumbnailViewUI extends JPanel implements DataProvider, Disposable { } } return navigatables.toArray(EMPTY_NAVIGATABLE_ARRAY); - } else if (ThumbnailView.class.getName().equals(dataId)) { + } else if (ThumbnailView.DATA_KEY.is(dataId)) { return thumbnailView; - } else if (ImageComponentDecorator.class.getName().equals(dataId)) { + } else if (ImageComponentDecorator.DATA_KEY.is(dataId)) { return thumbnailView; } @@ -466,7 +466,7 @@ final class ThumbnailViewUI extends JPanel implements DataProvider, Disposable { psiElements.add(element); } } - return psiElements.toArray(PsiElement.EMPTY_ARRAY); + return psiElements.toArray(new PsiElement[psiElements.size()]); } @NotNull diff --git a/images/src/org/intellij/images/ui/ImageComponentDecorator.java b/images/src/org/intellij/images/ui/ImageComponentDecorator.java index a0a711b62c5f..da9ef9215b3a 100644 --- a/images/src/org/intellij/images/ui/ImageComponentDecorator.java +++ b/images/src/org/intellij/images/ui/ImageComponentDecorator.java @@ -15,21 +15,25 @@ */ package org.intellij.images.ui; +import com.intellij.openapi.actionSystem.DataKey; + /** * Image Component manager. It can toggle backround transparency, grid, etc. * * @author Alexey Efimov */ public interface ImageComponentDecorator { - void setTransparencyChessboardVisible(boolean visible); + DataKey DATA_KEY = DataKey.create(ImageComponentDecorator.class.getName()); - boolean isTransparencyChessboardVisible(); + void setTransparencyChessboardVisible(boolean visible); - /** - * Return true if this decorator is enabled for this action place. - * - * @param place Action place - * @return true is decorator is enabled - */ - boolean isEnabledForActionPlace(String place); + boolean isTransparencyChessboardVisible(); + + /** + * Return true if this decorator is enabled for this action place. + * + * @param place Action place + * @return true is decorator is enabled + */ + boolean isEnabledForActionPlace(String place); } diff --git a/java/compiler/impl/src/com/intellij/compiler/actions/CompileDirtyAction.java b/java/compiler/impl/src/com/intellij/compiler/actions/CompileDirtyAction.java index 0cfcab780c11..8bea2886c3da 100644 --- a/java/compiler/impl/src/com/intellij/compiler/actions/CompileDirtyAction.java +++ b/java/compiler/impl/src/com/intellij/compiler/actions/CompileDirtyAction.java @@ -16,8 +16,8 @@ package com.intellij.compiler.actions; import com.intellij.openapi.actionSystem.AnActionEvent; -import com.intellij.openapi.actionSystem.DataConstants; import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.actionSystem.PlatformDataKeys; import com.intellij.openapi.actionSystem.Presentation; import com.intellij.openapi.compiler.CompilerManager; import com.intellij.openapi.project.Project; @@ -34,6 +34,6 @@ public class CompileDirtyAction extends CompileActionBase { if (!presentation.isEnabled()) { return; } - presentation.setEnabled(event.getDataContext().getData(DataConstants.PROJECT) != null); + presentation.setEnabled(PlatformDataKeys.PROJECT.getData(event.getDataContext()) != null); } } \ No newline at end of file diff --git a/java/compiler/impl/src/com/intellij/compiler/actions/MakeModuleAction.java b/java/compiler/impl/src/com/intellij/compiler/actions/MakeModuleAction.java index 7698a151e483..08b85a8c7021 100644 --- a/java/compiler/impl/src/com/intellij/compiler/actions/MakeModuleAction.java +++ b/java/compiler/impl/src/com/intellij/compiler/actions/MakeModuleAction.java @@ -26,7 +26,7 @@ public class MakeModuleAction extends CompileActionBase { private static final Logger LOG = Logger.getInstance("#com.intellij.compiler.actions.MakeModuleAction"); protected void doAction(DataContext dataContext, Project project) { - Module[] modules = (Module[])dataContext.getData(DataConstants.MODULE_CONTEXT_ARRAY); + Module[] modules = LangDataKeys.MODULE_CONTEXT_ARRAY.getData(dataContext); Module module; if (modules == null) { module = LangDataKeys.MODULE.getData(dataContext); @@ -51,7 +51,7 @@ public class MakeModuleAction extends CompileActionBase { } final DataContext dataContext = event.getDataContext(); final Module module = LangDataKeys.MODULE.getData(dataContext); - Module[] modules = (Module[])dataContext.getData(DataConstants.MODULE_CONTEXT_ARRAY); + Module[] modules = LangDataKeys.MODULE_CONTEXT_ARRAY.getData(dataContext); final boolean isEnabled = module != null || modules != null; presentation.setEnabled(isEnabled); final String actionName = getTemplatePresentation().getTextWithMnemonic(); @@ -81,4 +81,4 @@ public class MakeModuleAction extends CompileActionBase { presentation.setText(presentationText); presentation.setVisible(isEnabled || !ActionPlaces.PROJECT_VIEW_POPUP.equals(event.getPlace())); } -} \ No newline at end of file +} diff --git a/java/debugger/impl/src/com/intellij/debugger/actions/AddToWatchAction.java b/java/debugger/impl/src/com/intellij/debugger/actions/AddToWatchAction.java index d3521284f6df..a94a2c09ada1 100644 --- a/java/debugger/impl/src/com/intellij/debugger/actions/AddToWatchAction.java +++ b/java/debugger/impl/src/com/intellij/debugger/actions/AddToWatchAction.java @@ -66,7 +66,7 @@ public class AddToWatchAction extends DebuggerAction { } } else { - final Editor editor = (Editor)context.getData(PlatformDataKeys.EDITOR.getName()); + final Editor editor = e.getData(PlatformDataKeys.EDITOR); enabled = DebuggerUtilsEx.getEditorText(editor) != null; } e.getPresentation().setEnabled(enabled); @@ -99,7 +99,7 @@ public class AddToWatchAction extends DebuggerAction { addFromNodes(debuggerContext, watchPanel, selectedNodes); } else { - final Editor editor = (Editor)context.getData(PlatformDataKeys.EDITOR.getName()); + final Editor editor = e.getData(PlatformDataKeys.EDITOR); if (editor != null) { final TextWithImports editorText = DebuggerUtilsEx.getEditorText(editor); if (editorText != null) { @@ -176,4 +176,4 @@ public class AddToWatchAction extends DebuggerAction { } } -} \ No newline at end of file +} diff --git a/java/debugger/impl/src/com/intellij/debugger/actions/DebuggerAction.java b/java/debugger/impl/src/com/intellij/debugger/actions/DebuggerAction.java index def5c3aead4b..d149e8c388f0 100644 --- a/java/debugger/impl/src/com/intellij/debugger/actions/DebuggerAction.java +++ b/java/debugger/impl/src/com/intellij/debugger/actions/DebuggerAction.java @@ -45,12 +45,12 @@ public abstract class DebuggerAction extends AnAction { @Nullable public static DebuggerTree getTree(DataContext dataContext){ - return (DebuggerTree)dataContext.getData(DebuggerActions.DEBUGGER_TREE); + return DebuggerTree.DATA_KEY.getData(dataContext); } @Nullable public static DebuggerTreePanel getPanel(DataContext dataContext){ - return (DebuggerTreePanel)dataContext.getData(DebuggerActions.DEBUGGER_TREE_PANEL); + return DebuggerTreePanel.DATA_KEY.getData(dataContext); } @Nullable @@ -80,11 +80,11 @@ public abstract class DebuggerAction extends AnAction { if (paths == null || paths.length == 0) { return EMPTY_TREE_NODE_ARRAY; } - List nodes = new ArrayList(paths.length); + List nodes = new ArrayList(paths.length); for (TreePath path : paths) { Object component = path.getLastPathComponent(); if (component instanceof DebuggerTreeNodeImpl) { - nodes.add(component); + nodes.add((DebuggerTreeNodeImpl) component); } } return nodes.toArray(new DebuggerTreeNodeImpl[nodes.size()]); diff --git a/java/debugger/impl/src/com/intellij/debugger/actions/DebuggerActions.java b/java/debugger/impl/src/com/intellij/debugger/actions/DebuggerActions.java index b8186a2426c1..1220f5c9682b 100644 --- a/java/debugger/impl/src/com/intellij/debugger/actions/DebuggerActions.java +++ b/java/debugger/impl/src/com/intellij/debugger/actions/DebuggerActions.java @@ -20,6 +20,8 @@ */ package com.intellij.debugger.actions; +import com.intellij.debugger.ui.impl.DebuggerTreePanel; +import com.intellij.debugger.ui.impl.watch.DebuggerTree; import com.intellij.xdebugger.impl.actions.XDebuggerActions; import org.jetbrains.annotations.NonNls; @@ -30,8 +32,8 @@ public interface DebuggerActions extends XDebuggerActions { @NonNls String INSPECT_PANEL_POPUP = "Debugger.InspectPanelPopup"; @NonNls String THREADS_PANEL_POPUP = "Debugger.ThreadsPanelPopup"; @NonNls String WATCH_PANEL_POPUP = "Debugger.WatchesPanelPopup"; - @NonNls String DEBUGGER_TREE = "DebuggerTree"; - @NonNls String DEBUGGER_TREE_PANEL = "DebuggerPanel"; + @Deprecated @NonNls String DEBUGGER_TREE = DebuggerTree.DATA_KEY.getName(); + @Deprecated @NonNls String DEBUGGER_TREE_PANEL = DebuggerTreePanel.DATA_KEY.getName(); @NonNls String REMOVE_WATCH = "Debugger.RemoveWatch"; @NonNls String NEW_WATCH = "Debugger.NewWatch"; @NonNls String ADD_TO_WATCH = "Debugger.AddToWatch"; @@ -47,4 +49,4 @@ public interface DebuggerActions extends XDebuggerActions { @NonNls String EXPORT_THREADS = "ExportThreads"; @NonNls String DUMP_THREADS = "DumpThreads"; -} \ No newline at end of file +} diff --git a/java/debugger/impl/src/com/intellij/debugger/actions/ToggleFieldBreakpointAction.java b/java/debugger/impl/src/com/intellij/debugger/actions/ToggleFieldBreakpointAction.java index 5900b31b6271..dc3449921fc5 100644 --- a/java/debugger/impl/src/com/intellij/debugger/actions/ToggleFieldBreakpointAction.java +++ b/java/debugger/impl/src/com/intellij/debugger/actions/ToggleFieldBreakpointAction.java @@ -107,12 +107,12 @@ public class ToggleFieldBreakpointAction extends AnAction { else if(DebuggerAction.isContextView(event)) { presentation.setText(DebuggerBundle.message("action.add.field.watchpoint.text")); Project project = event.getData(PlatformDataKeys.PROJECT); - if(place != null) { + if(project != null && place != null) { Document document = PsiDocumentManager.getInstance(project).getDocument(place.getFile()); if (document != null) { final int offset = place.getOffset(); final BreakpointManager breakpointManager = (DebuggerManagerEx.getInstanceEx(project)).getBreakpointManager(); - final Breakpoint fieldBreakpoint = offset >= 0 ? (FieldBreakpoint)breakpointManager.findBreakpoint(document, offset, FieldBreakpoint.CATEGORY) : null; + final Breakpoint fieldBreakpoint = offset >= 0 ? breakpointManager.findBreakpoint(document, offset, FieldBreakpoint.CATEGORY) : null; if (fieldBreakpoint != null) { presentation.setEnabled(false); return; @@ -147,7 +147,7 @@ public class ToggleFieldBreakpointAction extends AnAction { } if(DebuggerAction.isContextView(event)) { - DebuggerTree tree = (DebuggerTree)dataContext.getData(DebuggerActions.DEBUGGER_TREE); + DebuggerTree tree = DebuggerTree.DATA_KEY.getData(dataContext); if(tree != null && tree.getSelectionPath() != null) { DebuggerTreeNodeImpl node = ((DebuggerTreeNodeImpl)tree.getSelectionPath().getLastPathComponent()); if(node != null && node.getDescriptor() instanceof FieldDescriptorImpl) { @@ -188,4 +188,4 @@ public class ToggleFieldBreakpointAction extends AnAction { return null; } -} \ No newline at end of file +} diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/impl/DebuggerTreePanel.java b/java/debugger/impl/src/com/intellij/debugger/ui/impl/DebuggerTreePanel.java index 269d8ce89e18..2e140372077c 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/impl/DebuggerTreePanel.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/impl/DebuggerTreePanel.java @@ -24,10 +24,7 @@ import com.intellij.debugger.impl.DebuggerSession; import com.intellij.debugger.impl.DebuggerStateManager; import com.intellij.debugger.ui.impl.watch.DebuggerTree; import com.intellij.openapi.Disposable; -import com.intellij.openapi.actionSystem.ActionPopupMenu; -import com.intellij.openapi.actionSystem.CustomShortcutSet; -import com.intellij.openapi.actionSystem.DataProvider; -import com.intellij.openapi.actionSystem.Shortcut; +import com.intellij.openapi.actionSystem.*; import com.intellij.openapi.keymap.KeymapManager; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Disposer; @@ -39,6 +36,8 @@ import java.awt.*; import java.awt.event.KeyEvent; public abstract class DebuggerTreePanel extends UpdatableDebuggerView implements DataProvider { + public static final DataKey DATA_KEY = DataKey.create("DebuggerPanel"); + protected final DebuggerTree myTree; public DebuggerTreePanel(Project project, DebuggerStateManager stateManager) { @@ -101,7 +100,7 @@ public abstract class DebuggerTreePanel extends UpdatableDebuggerView implements } public Object getData(String dataId) { - if (DebuggerActions.DEBUGGER_TREE_PANEL.equals(dataId)) { + if (DebuggerTreePanel.DATA_KEY.is(dataId)) { return this; } return null; diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/impl/ThreadsPanel.java b/java/debugger/impl/src/com/intellij/debugger/ui/impl/ThreadsPanel.java index c4a08b26e6a0..e63cd8f42886 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/impl/ThreadsPanel.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/impl/ThreadsPanel.java @@ -28,7 +28,7 @@ import com.intellij.openapi.Disposable; import com.intellij.openapi.actionSystem.ActionManager; import com.intellij.openapi.actionSystem.ActionPopupMenu; import com.intellij.openapi.actionSystem.DefaultActionGroup; -import com.intellij.openapi.actionSystem.ex.DataConstantsEx; +import com.intellij.openapi.actionSystem.PlatformDataKeys; import com.intellij.openapi.project.Project; import org.jetbrains.annotations.NonNls; @@ -72,7 +72,7 @@ public class ThreadsPanel extends DebuggerTreePanel{ } public Object getData(String dataId) { - if (DataConstantsEx.HELP_ID.equals(dataId)) { + if (PlatformDataKeys.HELP_ID.is(dataId)) { return HELP_ID; } return super.getData(dataId); @@ -86,4 +86,4 @@ public class ThreadsPanel extends DebuggerTreePanel{ public ThreadsDebuggerTree getThreadsTree() { return (ThreadsDebuggerTree) getTree(); } -} \ No newline at end of file +} diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/impl/VariablesPanel.java b/java/debugger/impl/src/com/intellij/debugger/ui/impl/VariablesPanel.java index 26972b427535..5250b408d575 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/impl/VariablesPanel.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/impl/VariablesPanel.java @@ -58,7 +58,7 @@ public class VariablesPanel extends DebuggerTreePanel implements DataProvider{ } public Object getData(String dataId) { - if (DataConstants.HELP_ID.equals(dataId)) { + if (PlatformDataKeys.HELP_ID.is(dataId)) { return HELP_ID; } return super.getData(dataId); @@ -69,4 +69,4 @@ public class VariablesPanel extends DebuggerTreePanel implements DataProvider{ return (FrameDebuggerTree) getTree(); } -} \ No newline at end of file +} diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/impl/WatchPanel.java b/java/debugger/impl/src/com/intellij/debugger/ui/impl/WatchPanel.java index 60e2f35d1bae..e0564ac1c7be 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/impl/WatchPanel.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/impl/WatchPanel.java @@ -30,7 +30,7 @@ import com.intellij.debugger.ui.impl.watch.DebuggerTreeNodeImpl; import com.intellij.debugger.ui.impl.watch.WatchItemDescriptor; import com.intellij.openapi.Disposable; import com.intellij.openapi.actionSystem.ActionPopupMenu; -import com.intellij.openapi.actionSystem.DataConstants; +import com.intellij.openapi.actionSystem.PlatformDataKeys; import com.intellij.openapi.project.Project; import org.jetbrains.annotations.NonNls; @@ -71,7 +71,7 @@ public abstract class WatchPanel extends DebuggerTreePanel { } public Object getData(String dataId) { - if (DataConstants.HELP_ID.equals(dataId)) { + if (PlatformDataKeys.HELP_ID.is(dataId)) { return HELP_ID; } return super.getData(dataId); @@ -80,4 +80,4 @@ public abstract class WatchPanel extends DebuggerTreePanel { public WatchDebuggerTree getWatchTree() { return (WatchDebuggerTree) getTree(); } -} \ No newline at end of file +} diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/DebuggerTree.java b/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/DebuggerTree.java index b3f3393156ea..c2a42eb2e3fb 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/DebuggerTree.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/DebuggerTree.java @@ -22,7 +22,6 @@ package com.intellij.debugger.ui.impl.watch; import com.intellij.debugger.DebuggerBundle; import com.intellij.debugger.DebuggerInvocationUtil; -import com.intellij.debugger.actions.DebuggerActions; import com.intellij.debugger.engine.DebugProcessImpl; import com.intellij.debugger.engine.evaluation.EvaluateException; import com.intellij.debugger.engine.evaluation.EvaluationContextImpl; @@ -44,6 +43,7 @@ import com.intellij.debugger.ui.tree.NodeDescriptor; import com.intellij.debugger.ui.tree.render.ChildrenBuilder; import com.intellij.debugger.ui.tree.render.NodeRenderer; import com.intellij.debugger.ui.tree.render.NodeRendererSettingsListener; +import com.intellij.openapi.actionSystem.DataKey; import com.intellij.openapi.actionSystem.DataProvider; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.diagnostic.Logger; @@ -67,6 +67,8 @@ public abstract class DebuggerTree extends DebuggerTreeBase implements DataProvi private static final Logger LOG = Logger.getInstance("#com.intellij.debugger.ui.impl.watch.DebuggerTree"); protected static final Key VISIBLE_RECT = Key.create("VISIBLE_RECT"); + public static final DataKey DATA_KEY = DataKey.create("DebuggerTree"); + private final Project myProject; protected final NodeManagerImpl myNodeManager; @@ -182,7 +184,7 @@ public abstract class DebuggerTree extends DebuggerTreeBase implements DataProvi } public Object getData(String dataId) { - if (DebuggerActions.DEBUGGER_TREE.equals(dataId)) { + if (DebuggerTree.DATA_KEY.is(dataId)) { return this; } return null; @@ -705,4 +707,4 @@ public abstract class DebuggerTree extends DebuggerTreeBase implements DataProvi public void hideTooltip() { myTipManager.hideTooltip(); } -} \ No newline at end of file +} diff --git a/java/idea-ui/src/com/intellij/ide/actions/ShowModulePropertiesAction.java b/java/idea-ui/src/com/intellij/ide/actions/ShowModulePropertiesAction.java index 75a5c584770e..1fa86ffb55f9 100644 --- a/java/idea-ui/src/com/intellij/ide/actions/ShowModulePropertiesAction.java +++ b/java/idea-ui/src/com/intellij/ide/actions/ShowModulePropertiesAction.java @@ -15,10 +15,7 @@ */ package com.intellij.ide.actions; -import com.intellij.openapi.actionSystem.AnAction; -import com.intellij.openapi.actionSystem.AnActionEvent; -import com.intellij.openapi.actionSystem.DataConstants; -import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.actionSystem.*; import com.intellij.openapi.module.Module; import com.intellij.openapi.project.Project; import com.intellij.openapi.roots.ui.configuration.ModulesConfigurator; @@ -31,11 +28,11 @@ public class ShowModulePropertiesAction extends AnAction{ public void actionPerformed(AnActionEvent e) { final DataContext dataContext = e.getDataContext(); - final Project project = (Project)dataContext.getData(DataConstants.PROJECT); + final Project project = PlatformDataKeys.PROJECT.getData(dataContext); if (project == null) { return; } - final Module module = (Module)dataContext.getData(DataConstants.MODULE_CONTEXT); + final Module module = LangDataKeys.MODULE_CONTEXT.getData(dataContext); if (module == null) { return; } @@ -45,8 +42,8 @@ public class ShowModulePropertiesAction extends AnAction{ public void update(AnActionEvent e) { super.update(e); final DataContext dataContext = e.getDataContext(); - final Project project = (Project)dataContext.getData(DataConstants.PROJECT); - final Module module = (Module)dataContext.getData(DataConstants.MODULE_CONTEXT); + final Project project = PlatformDataKeys.PROJECT.getData(dataContext); + final Module module = LangDataKeys.MODULE_CONTEXT.getData(dataContext); e.getPresentation().setVisible(project != null && module != null); } } diff --git a/java/idea-ui/src/com/intellij/ide/palette/impl/PaletteGroupHeader.java b/java/idea-ui/src/com/intellij/ide/palette/impl/PaletteGroupHeader.java index d97140aec6ac..4640d69bbb59 100644 --- a/java/idea-ui/src/com/intellij/ide/palette/impl/PaletteGroupHeader.java +++ b/java/idea-ui/src/com/intellij/ide/palette/impl/PaletteGroupHeader.java @@ -158,7 +158,7 @@ public class PaletteGroupHeader extends JCheckBox implements DataProvider { @Nullable public Object getData(String dataId) { Object data = myPaletteWindow.getData(dataId); if (data != null) return data; - Project project = (Project)myPaletteWindow.getData(DataConstants.PROJECT); + Project project = PlatformDataKeys.PROJECT.getData(myPaletteWindow); return myGroup.getData(project, dataId); } diff --git a/java/idea-ui/src/com/intellij/ide/palette/impl/PaletteWindow.java b/java/idea-ui/src/com/intellij/ide/palette/impl/PaletteWindow.java index ccaf067a6b06..7ee8a74ec77a 100644 --- a/java/idea-ui/src/com/intellij/ide/palette/impl/PaletteWindow.java +++ b/java/idea-ui/src/com/intellij/ide/palette/impl/PaletteWindow.java @@ -45,7 +45,7 @@ public class PaletteWindow extends JPanel implements DataProvider { private final Project myProject; private final ArrayList myGroupHeaders = new ArrayList(); private final PaletteItemProvider[] myProviders; - private final PaletteWindow.MyPropertyChangeListener myPropertyChangeListener = new MyPropertyChangeListener(); + private final MyPropertyChangeListener myPropertyChangeListener = new MyPropertyChangeListener(); private final Set myGroups = new HashSet(); private final JTabbedPane myTabbedPane = new JTabbedPane(); private final JScrollPane myScrollPane = new JScrollPane(); @@ -190,10 +190,10 @@ public class PaletteWindow extends JPanel implements DataProvider { } @Nullable public Object getData(String dataId) { - if (dataId.equals(DataConstants.HELP_ID)) { + if (PlatformDataKeys.HELP_ID.is(dataId)) { return ourHelpID; } - if (dataId.equals(DataConstants.PROJECT)) { + if (PlatformDataKeys.PROJECT.is(dataId)) { return myProject; } PaletteItem item = getActiveItem(); diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/ClasspathPanel.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/ClasspathPanel.java index 1ccc733676aa..45e052fe2d02 100644 --- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/ClasspathPanel.java +++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/ClasspathPanel.java @@ -1065,7 +1065,7 @@ public class ClasspathPanel extends JPanel { private static FileChooserDescriptor createFileChooserDescriptor(Component parent) { final FileChooserDescriptor descriptor = new FileChooserDescriptor(false, true, true, false, false, true); - final Module contextModule = (Module)DataManager.getInstance().getDataContext(parent).getData(DataConstants.MODULE_CONTEXT); + final Module contextModule = LangDataKeys.MODULE_CONTEXT.getData(DataManager.getInstance().getDataContext(parent)); descriptor.putUserData(LangDataKeys.MODULE_CONTEXT, contextModule); return descriptor; } diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/ModuleEditor.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/ModuleEditor.java index 02a10416ee55..57d9f5fdaa31 100644 --- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/ModuleEditor.java +++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/ModuleEditor.java @@ -17,8 +17,8 @@ package com.intellij.openapi.roots.ui.configuration; import com.intellij.facet.impl.ProjectFacetsConfigurator; import com.intellij.openapi.Disposable; -import com.intellij.openapi.actionSystem.DataConstants; import com.intellij.openapi.actionSystem.DataProvider; +import com.intellij.openapi.actionSystem.LangDataKeys; import com.intellij.openapi.extensions.Extensions; import com.intellij.openapi.module.Module; import com.intellij.openapi.module.ModuleConfigurationEditor; @@ -556,7 +556,7 @@ public abstract class ModuleEditor implements Place.Navigator, Disposable { } public Object getData(String dataId) { - if (dataId.equals(DataConstants.MODULE_CONTEXT)) { + if (LangDataKeys.MODULE_CONTEXT.is(dataId)) { return getModule(); } return null; diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/actions/NewModuleInGroupAction.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/actions/NewModuleInGroupAction.java index ed54db5fa713..68f24603774e 100644 --- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/actions/NewModuleInGroupAction.java +++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/actions/NewModuleInGroupAction.java @@ -18,7 +18,6 @@ package com.intellij.openapi.roots.ui.configuration.actions; import com.intellij.ide.projectView.impl.ModuleGroup; import com.intellij.openapi.actionSystem.AnActionEvent; import com.intellij.openapi.actionSystem.DataKeys; -import com.intellij.openapi.actionSystem.ex.DataConstantsEx; import com.intellij.openapi.module.Module; import com.intellij.openapi.module.impl.ModuleManagerImpl; @@ -29,7 +28,7 @@ public class NewModuleInGroupAction extends NewModuleAction { @Override public void update(final AnActionEvent e) { super.update(e); - final ModuleGroup[] moduleGroups = (ModuleGroup[])e.getDataContext().getData(DataConstantsEx.MODULE_GROUP_ARRAY); + final ModuleGroup[] moduleGroups = ModuleGroup.ARRAY_DATA_KEY.getData(e.getDataContext()); final Module[] modules = e.getData(DataKeys.MODULE_CONTEXT_ARRAY); e.getPresentation().setVisible((moduleGroups != null && moduleGroups.length > 0) || (modules != null && modules.length > 0)); @@ -37,7 +36,7 @@ public class NewModuleInGroupAction extends NewModuleAction { @Override protected Object prepareDataFromContext(final AnActionEvent e) { - final ModuleGroup[] moduleGroups = (ModuleGroup[])e.getDataContext().getData(DataConstantsEx.MODULE_GROUP_ARRAY); + final ModuleGroup[] moduleGroups = ModuleGroup.ARRAY_DATA_KEY.getData(e.getDataContext()); if (moduleGroups != null && moduleGroups.length > 0) { return moduleGroups [0]; } diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/FacetStructureConfigurable.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/FacetStructureConfigurable.java index 16f9c4c26676..625b217f6458 100644 --- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/FacetStructureConfigurable.java +++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/FacetStructureConfigurable.java @@ -43,7 +43,9 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import javax.swing.*; +import java.awt.*; import java.util.*; +import java.util.List; /** * @author nik @@ -238,7 +240,7 @@ public class FacetStructureConfigurable extends BaseStructureConfigurable { } public String getHelpTopic() { - final Object component = DataManager.getInstance().getDataContext().getData(DataKeys.CONTEXT_COMPONENT.getName()); + final Component component = DataKeys.CONTEXT_COMPONENT.getData(DataManager.getInstance().getDataContext()); if (myTree.equals(component)) { final NamedConfigurable selectedConfugurable = getSelectedConfugurable(); if (selectedConfugurable instanceof FacetTypeConfigurable) { diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/ModuleStructureConfigurable.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/ModuleStructureConfigurable.java index c1c07dd69cc2..bc784b5e00a8 100644 --- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/ModuleStructureConfigurable.java +++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/ModuleStructureConfigurable.java @@ -28,7 +28,6 @@ import com.intellij.ide.util.projectWizard.ModuleBuilder; import com.intellij.ide.util.projectWizard.NamePathComponent; import com.intellij.ide.util.projectWizard.ProjectWizardUtil; import com.intellij.openapi.actionSystem.*; -import com.intellij.openapi.actionSystem.ex.DataConstantsEx; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.components.State; import com.intellij.openapi.components.Storage; @@ -47,7 +46,10 @@ import com.intellij.openapi.roots.ui.configuration.ClasspathEditor; import com.intellij.openapi.roots.ui.configuration.ModuleEditor; import com.intellij.openapi.roots.ui.configuration.ModulesConfigurator; import com.intellij.openapi.roots.ui.configuration.ProjectStructureConfigurable; -import com.intellij.openapi.roots.ui.configuration.projectRoot.daemon.*; +import com.intellij.openapi.roots.ui.configuration.projectRoot.daemon.LibraryProjectStructureElement; +import com.intellij.openapi.roots.ui.configuration.projectRoot.daemon.ModuleProjectStructureElement; +import com.intellij.openapi.roots.ui.configuration.projectRoot.daemon.ProjectStructureDaemonAnalyzer; +import com.intellij.openapi.roots.ui.configuration.projectRoot.daemon.ProjectStructureElement; import com.intellij.openapi.ui.DialogWrapper; import com.intellij.openapi.ui.Messages; import com.intellij.openapi.ui.NamedConfigurable; @@ -565,7 +567,7 @@ public class ModuleStructureConfigurable extends BaseStructureConfigurable imple if (DataKeys.MODULE_CONTEXT.is(dataId)){ return getSelectedModule(); } - if (DataConstantsEx.MODIFIABLE_MODULE_MODEL.equals(dataId)){ + if (LangDataKeys.MODIFIABLE_MODULE_MODEL.is(dataId)){ return myContext.myModulesConfigurator.getModuleModel(); } diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/MoveClassToModuleFix.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/MoveClassToModuleFix.java index 66b378c368d5..354685a58b6b 100644 --- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/MoveClassToModuleFix.java +++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/MoveClassToModuleFix.java @@ -22,7 +22,7 @@ import com.intellij.codeInsight.intention.IntentionAction; import com.intellij.ide.DataManager; import com.intellij.ide.util.PackageUtil; import com.intellij.openapi.actionSystem.DataContext; -import com.intellij.openapi.actionSystem.ex.DataConstantsEx; +import com.intellij.openapi.actionSystem.LangDataKeys; import com.intellij.openapi.actionSystem.impl.SimpleDataContext; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.module.Module; @@ -43,6 +43,9 @@ import org.jetbrains.annotations.NotNull; * @author cdr */ public class MoveClassToModuleFix { + private MoveClassToModuleFix() { + } + public static void registerFixes(QuickFixActionRegistrar registrar, final PsiJavaCodeReferenceElement reference) { final PsiElement psiElement = reference.getElement(); @NonNls final String referenceName = reference.getRangeInElement().substring(psiElement.getText()); @@ -102,8 +105,11 @@ public class MoveClassToModuleFix { DataManager dataManager = DataManager.getInstance(); DataContext dataContext = dataManager.getDataContext(); PsiDirectory directory = PackageUtil.findOrCreateDirectoryForPackage(currentModule, packageName, sourceRoot, true); - DataContext context = SimpleDataContext.getSimpleContext(DataConstantsEx.TARGET_PSI_ELEMENT, directory, dataContext); + DataContext context = SimpleDataContext.getSimpleContext(LangDataKeys.TARGET_PSI_ELEMENT.getName(), directory, dataContext); String qualifiedName = aClass.getQualifiedName(); + if (qualifiedName == null) { + return; + } moveHandler.invoke(project, new PsiElement[]{aClass}, context); PsiReference reference = file.findReferenceAt(editor.getCaretModel().getOffset()); PsiClass newClass = JavaPsiFacade.getInstance(project).findClass(qualifiedName, GlobalSearchScope.moduleScope(currentModule)); diff --git a/java/java-impl/src/com/intellij/cyclicDependencies/actions/CyclicDependenciesAction.java b/java/java-impl/src/com/intellij/cyclicDependencies/actions/CyclicDependenciesAction.java index 880e2f57027a..b1765a431d5c 100644 --- a/java/java-impl/src/com/intellij/cyclicDependencies/actions/CyclicDependenciesAction.java +++ b/java/java-impl/src/com/intellij/cyclicDependencies/actions/CyclicDependenciesAction.java @@ -48,7 +48,7 @@ public class CyclicDependenciesAction extends AnAction{ public void update(AnActionEvent event) { Presentation presentation = event.getPresentation(); presentation.setEnabled( - getInspectionScope(event.getDataContext()) != null || event.getDataContext().getData(DataConstants.PSI_FILE) != null); + getInspectionScope(event.getDataContext()) != null || event.getData(LangDataKeys.PSI_FILE) != null); } public void actionPerformed(AnActionEvent e) { @@ -82,7 +82,7 @@ public class CyclicDependenciesAction extends AnAction{ } - private AnalysisScope getInspectionScope(final DataContext dataContext) { + private static AnalysisScope getInspectionScope(final DataContext dataContext) { final Project project = PlatformDataKeys.PROJECT.getData(dataContext); if (project == null) return null; @@ -91,19 +91,19 @@ public class CyclicDependenciesAction extends AnAction{ return scope != null && scope.getScopeType() != AnalysisScope.INVALID ? scope : null; } - private AnalysisScope getInspectionScopeImpl(DataContext dataContext) { + private static AnalysisScope getInspectionScopeImpl(DataContext dataContext) { //Possible scopes: package, project, module. Project projectContext = PlatformDataKeys.PROJECT_CONTEXT.getData(dataContext); if (projectContext != null) { return new AnalysisScope(projectContext); } - Module moduleContext = (Module)dataContext.getData(DataConstants.MODULE_CONTEXT); + Module moduleContext = LangDataKeys.MODULE_CONTEXT.getData(dataContext); if (moduleContext != null) { return new AnalysisScope(moduleContext); } - Module [] modulesArray = (Module[])dataContext.getData(DataConstants.MODULE_CONTEXT_ARRAY); + Module [] modulesArray = LangDataKeys.MODULE_CONTEXT_ARRAY.getData(dataContext); if (modulesArray != null) { return new AnalysisScope(modulesArray); } @@ -117,7 +117,7 @@ public class CyclicDependenciesAction extends AnAction{ else if (psiTarget instanceof PsiPackage) { PsiPackage pack = (PsiPackage)psiTarget; PsiDirectory[] dirs = pack.getDirectories(GlobalSearchScope.projectScope(pack.getProject())); - if (dirs == null || dirs.length == 0) return null; + if (dirs.length == 0) return null; return new JavaAnalysisScope(pack, LangDataKeys.MODULE.getData(dataContext)); } else if (psiTarget != null){ return null; @@ -127,12 +127,20 @@ public class CyclicDependenciesAction extends AnAction{ return getProjectScope(dataContext); } - private AnalysisScope getProjectScope(DataContext dataContext) { - return new AnalysisScope(PlatformDataKeys.PROJECT.getData(dataContext)); + private static AnalysisScope getProjectScope(DataContext dataContext) { + final Project data = PlatformDataKeys.PROJECT.getData(dataContext); + if (data == null) { + return null; + } + return new AnalysisScope(data); } - private AnalysisScope getModuleScope(DataContext dataContext) { - return new AnalysisScope(LangDataKeys.MODULE.getData(dataContext)); + private static AnalysisScope getModuleScope(DataContext dataContext) { + final Module data = LangDataKeys.MODULE.getData(dataContext); + if (data == null) { + return null; + } + return new AnalysisScope(data); } private class ProjectModuleOrPackageDialog extends DialogWrapper { diff --git a/java/java-impl/src/com/intellij/cyclicDependencies/ui/CyclicDependenciesPanel.java b/java/java-impl/src/com/intellij/cyclicDependencies/ui/CyclicDependenciesPanel.java index 8b0856484f3a..f9539ab1a8a0 100644 --- a/java/java-impl/src/com/intellij/cyclicDependencies/ui/CyclicDependenciesPanel.java +++ b/java/java-impl/src/com/intellij/cyclicDependencies/ui/CyclicDependenciesPanel.java @@ -388,7 +388,7 @@ public class CyclicDependenciesPanel extends JPanel implements Disposable, DataP @Nullable @NonNls public Object getData(@NonNls String dataId) { - if (dataId.equals(DataConstants.HELP_ID)) { + if (PlatformDataKeys.HELP_ID.is(dataId)) { return "dependency.viewer.tool.window"; } return null; @@ -497,7 +497,7 @@ public class CyclicDependenciesPanel extends JPanel implements Disposable, DataP private static class MyTree extends Tree implements DataProvider { public Object getData(String dataId) { PackageDependenciesNode node = getSelectedNode(); - if (DataConstants.NAVIGATABLE.equals(dataId)) { + if (PlatformDataKeys.NAVIGATABLE.is(dataId)) { return node; } return null; diff --git a/java/java-impl/src/com/intellij/ide/JavaDataAccessors.java b/java/java-impl/src/com/intellij/ide/JavaDataAccessors.java index c6835e9d2c6f..fabee57027f7 100644 --- a/java/java-impl/src/com/intellij/ide/JavaDataAccessors.java +++ b/java/java-impl/src/com/intellij/ide/JavaDataAccessors.java @@ -15,8 +15,11 @@ */ package com.intellij.ide; -import com.intellij.psi.*; import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.psi.JavaDirectoryService; +import com.intellij.psi.PsiDirectory; +import com.intellij.psi.PsiFile; +import com.intellij.psi.PsiPackage; public class JavaDataAccessors { public static final DataAccessor FILE_PACKAGE = new DataAccessor() { @@ -27,7 +30,6 @@ public class JavaDataAccessors { return JavaDirectoryService.getInstance().getPackage(containingDirectory); } }; - public static final DataAccessor PSI_JAVA_FILE = DataAccessor.SubClassDataAccessor.create(DataAccessors.PSI_FILE, PsiJavaFile.class); private JavaDataAccessors() { } diff --git a/java/java-impl/src/com/intellij/ide/favoritesTreeView/PsiPackageFavoriteNodeProvider.java b/java/java-impl/src/com/intellij/ide/favoritesTreeView/PsiPackageFavoriteNodeProvider.java index 38fd94258880..df799d33f8b5 100644 --- a/java/java-impl/src/com/intellij/ide/favoritesTreeView/PsiPackageFavoriteNodeProvider.java +++ b/java/java-impl/src/com/intellij/ide/favoritesTreeView/PsiPackageFavoriteNodeProvider.java @@ -30,7 +30,6 @@ import com.intellij.ide.util.treeView.AbstractTreeNode; import com.intellij.openapi.actionSystem.DataContext; import com.intellij.openapi.actionSystem.LangDataKeys; import com.intellij.openapi.actionSystem.PlatformDataKeys; -import com.intellij.openapi.actionSystem.ex.DataConstantsEx; import com.intellij.openapi.module.Module; import com.intellij.openapi.module.ModuleManager; import com.intellij.openapi.project.Project; @@ -89,9 +88,9 @@ public class PsiPackageFavoriteNodeProvider extends FavoriteNodeProvider { } } } else { - final Object data = context.getData(DataConstantsEx.MODULE_GROUP_ARRAY); - if (data instanceof ModuleGroup[]) { - for (ModuleGroup moduleGroup : ((ModuleGroup[])data)) { + final ModuleGroup[] data = ModuleGroup.ARRAY_DATA_KEY.getData(context); + if (data != null) { + for (ModuleGroup moduleGroup : data) { if (currentViewId.equals(ProjectViewPane.ID)) { result.add(new ProjectViewModuleGroupNode(project, moduleGroup, viewSettings)); } @@ -198,4 +197,4 @@ public class PsiPackageFavoriteNodeProvider extends FavoriteNodeProvider { } return super.getPsiElement(element); } -} \ No newline at end of file +} diff --git a/java/java-impl/src/com/intellij/ide/hierarchy/method/OverrideImplementMethodAction.java b/java/java-impl/src/com/intellij/ide/hierarchy/method/OverrideImplementMethodAction.java index b2148fadb7de..1bc9f6fb4b5e 100644 --- a/java/java-impl/src/com/intellij/ide/hierarchy/method/OverrideImplementMethodAction.java +++ b/java/java-impl/src/com/intellij/ide/hierarchy/method/OverrideImplementMethodAction.java @@ -45,7 +45,7 @@ abstract class OverrideImplementMethodAction extends AnAction { public final void actionPerformed(final AnActionEvent event) { final DataContext dataContext = event.getDataContext(); - final MethodHierarchyBrowser methodHierarchyBrowser = (MethodHierarchyBrowser)dataContext.getData(MethodHierarchyBrowserBase.METHOD_HIERARCHY_BROWSER_DATA_KEY); + final MethodHierarchyBrowser methodHierarchyBrowser = (MethodHierarchyBrowser)MethodHierarchyBrowserBase.DATA_KEY.getData(dataContext); if (methodHierarchyBrowser == null) return; final Project project = PlatformDataKeys.PROJECT.getData(dataContext); if (project == null) return; @@ -98,7 +98,7 @@ abstract class OverrideImplementMethodAction extends AnAction { final Presentation presentation = e.getPresentation(); final DataContext dataContext = e.getDataContext(); - final MethodHierarchyBrowser methodHierarchyBrowser = (MethodHierarchyBrowser)dataContext.getData(MethodHierarchyBrowser.METHOD_HIERARCHY_BROWSER_DATA_KEY); + final MethodHierarchyBrowser methodHierarchyBrowser = (MethodHierarchyBrowser)MethodHierarchyBrowserBase.DATA_KEY.getData(dataContext); if (methodHierarchyBrowser == null) { presentation.setEnabled(false); presentation.setVisible(false); diff --git a/java/java-impl/src/com/intellij/ide/macro/FileClassMacro.java b/java/java-impl/src/com/intellij/ide/macro/FileClassMacro.java index 13306519d8cd..3bcf55015e28 100644 --- a/java/java-impl/src/com/intellij/ide/macro/FileClassMacro.java +++ b/java/java-impl/src/com/intellij/ide/macro/FileClassMacro.java @@ -15,11 +15,12 @@ */ package com.intellij.ide.macro; -import com.intellij.openapi.actionSystem.DataContext; -import com.intellij.psi.PsiClass; -import com.intellij.psi.PsiJavaFile; import com.intellij.ide.IdeBundle; -import com.intellij.ide.JavaDataAccessors; +import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.actionSystem.LangDataKeys; +import com.intellij.psi.PsiClass; +import com.intellij.psi.PsiFile; +import com.intellij.psi.PsiJavaFile; public final class FileClassMacro extends Macro { public String getName() { @@ -43,15 +44,14 @@ public final class FileClassMacro extends Macro { //if (!(psiFile instanceof PsiJavaFile)) { // return null; //} - final PsiJavaFile javaFile = JavaDataAccessors.PSI_JAVA_FILE.from(dataContext); - if (javaFile == null) return null; - PsiClass[] classes = javaFile.getClasses(); + final PsiFile javaFile = LangDataKeys.PSI_FILE.getData(dataContext); + if (!(javaFile instanceof PsiJavaFile)) return null; + PsiClass[] classes = ((PsiJavaFile) javaFile).getClasses(); if (classes.length == 1) { return classes[0].getQualifiedName(); } String fileName = javaFile.getVirtualFile().getNameWithoutExtension(); - for (int i = 0; i < classes.length; i++) { - PsiClass aClass = classes[i]; + for (PsiClass aClass : classes) { String name = aClass.getName(); if (fileName.equals(name)) { return aClass.getQualifiedName(); diff --git a/java/java-impl/src/com/intellij/ide/projectView/impl/PackageViewPane.java b/java/java-impl/src/com/intellij/ide/projectView/impl/PackageViewPane.java index 23789a9067b4..3069e3852d43 100644 --- a/java/java-impl/src/com/intellij/ide/projectView/impl/PackageViewPane.java +++ b/java/java-impl/src/com/intellij/ide/projectView/impl/PackageViewPane.java @@ -32,7 +32,6 @@ import com.intellij.ide.util.treeView.AbstractTreeNode; import com.intellij.ide.util.treeView.AbstractTreeStructure; import com.intellij.ide.util.treeView.AbstractTreeUpdater; import com.intellij.openapi.actionSystem.*; -import com.intellij.openapi.actionSystem.ex.DataConstantsEx; import com.intellij.openapi.module.Module; import com.intellij.openapi.project.Project; import com.intellij.openapi.roots.OrderEntry; @@ -40,7 +39,10 @@ import com.intellij.openapi.roots.ProjectFileIndex; import com.intellij.openapi.roots.ProjectRootManager; import com.intellij.openapi.util.IconLoader; import com.intellij.openapi.vfs.VirtualFile; -import com.intellij.psi.*; +import com.intellij.psi.JavaDirectoryService; +import com.intellij.psi.PsiDirectory; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiPackage; import com.intellij.psi.search.GlobalSearchScope; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; @@ -89,10 +91,10 @@ public final class PackageViewPane extends AbstractProjectViewPSIPane { @Override public Object getData(final String dataId) { - if (DataConstantsEx.PACKAGE_ELEMENT.equals(dataId)) { + if (PackageElement.DATA_KEY.is(dataId)) { final PackageElement packageElement = getSelectedPackageElement(); } - if (DataConstants.MODULE.equals(dataId)) { + if (LangDataKeys.MODULE.is(dataId)) { final PackageElement packageElement = getSelectedPackageElement(); if (packageElement != null) { return packageElement.getModule(); @@ -288,4 +290,4 @@ public final class PackageViewPane extends AbstractProjectViewPSIPane { return modules.toArray(new Module[modules.size()]); } } -} \ No newline at end of file +} diff --git a/java/java-impl/src/com/intellij/ide/projectView/impl/nodes/PackageElement.java b/java/java-impl/src/com/intellij/ide/projectView/impl/nodes/PackageElement.java index f2a5b129c8e0..a89076455542 100644 --- a/java/java-impl/src/com/intellij/ide/projectView/impl/nodes/PackageElement.java +++ b/java/java-impl/src/com/intellij/ide/projectView/impl/nodes/PackageElement.java @@ -15,6 +15,7 @@ */ package com.intellij.ide.projectView.impl.nodes; +import com.intellij.openapi.actionSystem.DataKey; import com.intellij.openapi.module.Module; import com.intellij.psi.PsiPackage; @@ -24,6 +25,8 @@ import com.intellij.psi.PsiPackage; * Time: 3:51:02 PM */ public final class PackageElement { + public static final DataKey DATA_KEY = DataKey.create("package.element"); + private final Module myModule; private final PsiPackage myElement; private final boolean myIsLibraryElement; diff --git a/java/java-impl/src/com/intellij/javadoc/JavadocGenerationManager.java b/java/java-impl/src/com/intellij/javadoc/JavadocGenerationManager.java index 008a04259f39..897ab67f3cbd 100644 --- a/java/java-impl/src/com/intellij/javadoc/JavadocGenerationManager.java +++ b/java/java-impl/src/com/intellij/javadoc/JavadocGenerationManager.java @@ -23,8 +23,8 @@ import com.intellij.execution.runners.ExecutionEnvironment; import com.intellij.execution.runners.ProgramRunner; import com.intellij.execution.util.ExecutionErrorDialog; import com.intellij.ide.DataManager; -import com.intellij.openapi.actionSystem.DataConstants; import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.actionSystem.PlatformDataKeys; import com.intellij.openapi.actionSystem.impl.SimpleDataContext; import com.intellij.openapi.components.AbstractProjectComponent; import com.intellij.openapi.module.Module; @@ -57,7 +57,7 @@ public final class JavadocGenerationManager extends AbstractProjectComponent imp } public void generateJavadoc(final PsiDirectory directory, DataContext dataContext) { - Component component = (Component)dataContext.getData(DataConstants.CONTEXT_COMPONENT); + Component component = PlatformDataKeys.CONTEXT_COMPONENT.getData(dataContext); final PsiPackage aPackage = directory != null ? JavaDirectoryService.getInstance().getPackage(directory) : null; String packageFQName = aPackage != null ? aPackage.getQualifiedName() : null; @@ -126,4 +126,4 @@ public final class JavadocGenerationManager extends AbstractProjectComponent imp return myConfiguration; } -} \ No newline at end of file +} diff --git a/java/java-impl/src/com/intellij/javadoc/actions/GenerateJavadocAction.java b/java/java-impl/src/com/intellij/javadoc/actions/GenerateJavadocAction.java index 888ea53bdc7c..ba13e2366309 100644 --- a/java/java-impl/src/com/intellij/javadoc/actions/GenerateJavadocAction.java +++ b/java/java-impl/src/com/intellij/javadoc/actions/GenerateJavadocAction.java @@ -33,7 +33,7 @@ public final class GenerateJavadocAction extends AnAction{ public void update(AnActionEvent event){ final Presentation presentation = event.getPresentation(); - presentation.setEnabled(event.getDataContext().getData(DataConstants.PROJECT) != null); + presentation.setEnabled(PlatformDataKeys.PROJECT.getData(event.getDataContext()) != null); } private static PsiDirectory getDirectoryFromContext(final DataContext dataContext) { @@ -63,4 +63,4 @@ public final class GenerateJavadocAction extends AnAction{ return null; } -} \ No newline at end of file +} diff --git a/java/java-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/MoveClassesHandler.java b/java/java-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/MoveClassesHandler.java index a69084c8921c..67bac1d6d09e 100644 --- a/java/java-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/MoveClassesHandler.java +++ b/java/java-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/MoveClassesHandler.java @@ -15,13 +15,13 @@ */ package com.intellij.refactoring.move.moveClassesOrPackages; +import com.intellij.codeInsight.daemon.impl.CollectHighlightsUtil; +import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.actionSystem.LangDataKeys; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.project.Project; import com.intellij.psi.*; import com.intellij.psi.impl.source.jsp.jspJava.JspClass; -import com.intellij.openapi.project.Project; -import com.intellij.openapi.actionSystem.DataContext; -import com.intellij.openapi.actionSystem.ex.DataConstantsEx; -import com.intellij.openapi.editor.Editor; -import com.intellij.codeInsight.daemon.impl.CollectHighlightsUtil; import org.jetbrains.annotations.Nullable; public class MoveClassesHandler extends MoveClassesOrPackagesHandlerBase { @@ -54,7 +54,7 @@ public class MoveClassesHandler extends MoveClassesOrPackagesHandlerBase { if (element instanceof PsiClass && !(element instanceof PsiAnonymousClass) && element.getParent() instanceof PsiFile) { MoveClassesOrPackagesImpl.doMove(project, new PsiElement[]{element}, - (PsiElement)dataContext.getData(DataConstantsEx.TARGET_PSI_ELEMENT), null); + LangDataKeys.TARGET_PSI_ELEMENT.getData(dataContext), null); return true; } return false; diff --git a/java/java-impl/src/com/intellij/refactoring/wrapreturnvalue/WrapReturnValueHandler.java b/java/java-impl/src/com/intellij/refactoring/wrapreturnvalue/WrapReturnValueHandler.java index 8624ac7cf6fc..6eb04548bfbc 100644 --- a/java/java-impl/src/com/intellij/refactoring/wrapreturnvalue/WrapReturnValueHandler.java +++ b/java/java-impl/src/com/intellij/refactoring/wrapreturnvalue/WrapReturnValueHandler.java @@ -16,8 +16,8 @@ package com.intellij.refactoring.wrapreturnvalue; import com.intellij.ide.util.SuperMethodWarningUtil; -import com.intellij.openapi.actionSystem.DataConstants; import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.actionSystem.LangDataKeys; import com.intellij.openapi.actionSystem.PlatformDataKeys; import com.intellij.openapi.editor.CaretModel; import com.intellij.openapi.editor.Editor; @@ -42,7 +42,7 @@ class WrapReturnValueHandler implements RefactoringActionHandler { DataContext dataContext){ final ScrollingModel scrollingModel = editor.getScrollingModel(); scrollingModel.scrollToCaret(ScrollType.MAKE_VISIBLE); - final PsiElement element = (PsiElement) dataContext.getData(DataConstants.PSI_ELEMENT); + final PsiElement element = LangDataKeys.PSI_ELEMENT.getData(dataContext); PsiMethod selectedMethod = null; if(element instanceof PsiMethod){ selectedMethod = (PsiMethod) element; diff --git a/java/openapi/src/com/intellij/ide/palette/PaletteGroup.java b/java/openapi/src/com/intellij/ide/palette/PaletteGroup.java index 56c4deda0b76..a19c1ab8e60d 100644 --- a/java/openapi/src/com/intellij/ide/palette/PaletteGroup.java +++ b/java/openapi/src/com/intellij/ide/palette/PaletteGroup.java @@ -49,7 +49,7 @@ public interface PaletteGroup { * Returns the data for the specified data constant. * * @param project the project in the context of which data is requested. - * @param dataId the data constant id (see {@link com.intellij.openapi.actionSystem.DataConstants}). + * @param dataId the data constant id (see {@link com.intellij.openapi.actionSystem.PlatformDataKeys}). * @return the data item, or null if no data is available for this constant. */ @Nullable Object getData(Project project, String dataId); diff --git a/java/openapi/src/com/intellij/ide/palette/PaletteItem.java b/java/openapi/src/com/intellij/ide/palette/PaletteItem.java index 8180cceb722c..372839d67266 100644 --- a/java/openapi/src/com/intellij/ide/palette/PaletteItem.java +++ b/java/openapi/src/com/intellij/ide/palette/PaletteItem.java @@ -16,14 +16,12 @@ package com.intellij.ide.palette; +import com.intellij.ide.dnd.DnDDragStartBean; import com.intellij.openapi.actionSystem.ActionGroup; import com.intellij.openapi.project.Project; import com.intellij.ui.ColoredListCellRenderer; -import com.intellij.ide.dnd.DnDDragStartBean; import org.jetbrains.annotations.Nullable; -import java.awt.datatransfer.Transferable; - /** * @author yole */ @@ -51,7 +49,7 @@ public interface PaletteItem { * Returns the data for the specified data constant. * * @param project the project in the context of which data is requested. - * @param dataId the data constant id (see {@link com.intellij.openapi.actionSystem.DataConstants}). + * @param dataId the data constant id (see {@link com.intellij.openapi.actionSystem.PlatformDataKeys}). * @return the data item, or null if no data is available for this constant. */ @Nullable Object getData(Project project, String dataId); diff --git a/java/openapi/src/com/intellij/openapi/actionSystem/DataKeys.java b/java/openapi/src/com/intellij/openapi/actionSystem/DataKeys.java index bf48dca0f1c7..da0409405697 100644 --- a/java/openapi/src/com/intellij/openapi/actionSystem/DataKeys.java +++ b/java/openapi/src/com/intellij/openapi/actionSystem/DataKeys.java @@ -31,9 +31,9 @@ public final class DataKeys extends LangDataKeys { } @Deprecated - public static final DataKey CHANGE_LISTS = DataKey.create(DataConstants.CHANGE_LISTS); + public static final DataKey CHANGE_LISTS = DataKey.create("vcs.ChangeList"); @Deprecated - public static final DataKey CHANGES = DataKey.create(DataConstants.CHANGES); + public static final DataKey CHANGES = DataKey.create("vcs.Change"); } diff --git a/java/testFramework/src/com/intellij/codeInsight/CodeInsightTestCase.java b/java/testFramework/src/com/intellij/codeInsight/CodeInsightTestCase.java index c7909d2ad700..c1aa5428a17f 100644 --- a/java/testFramework/src/com/intellij/codeInsight/CodeInsightTestCase.java +++ b/java/testFramework/src/com/intellij/codeInsight/CodeInsightTestCase.java @@ -555,7 +555,7 @@ public abstract class CodeInsightTestCase extends PsiTestCase { } public Object getData(String dataId) { - return dataId.equals(DataConstants.EDITOR) ? myEditor : super.getData(dataId); + return PlatformDataKeys.EDITOR.is(dataId) ? myEditor : super.getData(dataId); } protected VirtualFile getVirtualFile(@NonNls String filePath) { diff --git a/platform/lang-api/src/com/intellij/execution/Location.java b/platform/lang-api/src/com/intellij/execution/Location.java index 8babfe7f402b..5c8afd642955 100644 --- a/platform/lang-api/src/com/intellij/execution/Location.java +++ b/platform/lang-api/src/com/intellij/execution/Location.java @@ -15,6 +15,7 @@ */ package com.intellij.execution; +import com.intellij.openapi.actionSystem.DataKey; import com.intellij.openapi.fileEditor.OpenFileDescriptor; import com.intellij.openapi.module.Module; import com.intellij.openapi.project.Project; @@ -28,7 +29,8 @@ import org.jetbrains.annotations.Nullable; import java.util.Iterator; public abstract class Location { - @NonNls public static final String LOCATION = "Location"; + public static final DataKey> DATA_KEY = DataKey.create("Location"); + @Deprecated @NonNls public static final String LOCATION = DATA_KEY.getName(); @NotNull public abstract E getPsiElement(); @NotNull public abstract Project getProject(); diff --git a/platform/lang-api/src/com/intellij/execution/configurations/RuntimeConfiguration.java b/platform/lang-api/src/com/intellij/execution/configurations/RuntimeConfiguration.java index cdaa7ecd26eb..8d9aab064172 100644 --- a/platform/lang-api/src/com/intellij/execution/configurations/RuntimeConfiguration.java +++ b/platform/lang-api/src/com/intellij/execution/configurations/RuntimeConfiguration.java @@ -17,6 +17,7 @@ package com.intellij.execution.configurations; import com.intellij.execution.runners.ProgramRunner; +import com.intellij.openapi.actionSystem.DataKey; import com.intellij.openapi.module.Module; import com.intellij.openapi.options.SettingsEditor; import com.intellij.openapi.project.Project; @@ -24,9 +25,9 @@ import com.intellij.openapi.util.JDOMExternalizable; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; -import javax.swing.*; - public abstract class RuntimeConfiguration extends RunConfigurationBase implements LocatableConfiguration, Cloneable, ModuleRunConfiguration { + public static final DataKey DATA_KEY = DataKey.create("runtimeConfiguration"); + protected RuntimeConfiguration(final String name, final Project project, final ConfigurationFactory factory) { super(project, factory, name); } @@ -59,4 +60,4 @@ public abstract class RuntimeConfiguration extends RunConfigurationBase implemen @NonNls public String suggestedName() { return null; } -} \ No newline at end of file +} diff --git a/platform/lang-api/src/com/intellij/execution/runners/GenericProgramRunner.java b/platform/lang-api/src/com/intellij/execution/runners/GenericProgramRunner.java index 287bbeec0fdb..82eb66b03cc0 100644 --- a/platform/lang-api/src/com/intellij/execution/runners/GenericProgramRunner.java +++ b/platform/lang-api/src/com/intellij/execution/runners/GenericProgramRunner.java @@ -27,6 +27,7 @@ import com.intellij.history.LocalHistory; import com.intellij.history.LocalHistoryConfiguration; import com.intellij.openapi.actionSystem.AnAction; import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.actionSystem.DataKey; import com.intellij.openapi.actionSystem.PlatformDataKeys; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.options.SettingsEditor; @@ -40,10 +41,12 @@ import org.jetbrains.annotations.Nullable; * @author spleaner */ public abstract class GenericProgramRunner implements ProgramRunner { + /** * @see com.intellij.execution.ui.RunContentDescriptor#myContent */ - @NonNls public static final String CONTENT_TO_REUSE = "contentToReuse"; + public static final DataKey CONTENT_TO_REUSE_DATA_KEY = DataKey.create("contentToReuse"); + @Deprecated @NonNls public static final String CONTENT_TO_REUSE = CONTENT_TO_REUSE_DATA_KEY.getName(); @Nullable public Settings createConfigurationData(final ConfigurationInfoProvider settingsProvider) { diff --git a/platform/lang-api/src/com/intellij/ide/IdeView.java b/platform/lang-api/src/com/intellij/ide/IdeView.java index 7e201996a295..7ee910f0925f 100644 --- a/platform/lang-api/src/com/intellij/ide/IdeView.java +++ b/platform/lang-api/src/com/intellij/ide/IdeView.java @@ -25,7 +25,7 @@ import org.jetbrains.annotations.Nullable; * favorites or commander). * * @since 5.1 - * @see com.intellij.openapi.actionSystem.DataConstants#IDE_VIEW + * @see com.intellij.openapi.actionSystem.PlatformDataKeys#IDE_VIEW */ public interface IdeView { /** diff --git a/platform/lang-api/src/com/intellij/ide/projectView/TreeStructureProvider.java b/platform/lang-api/src/com/intellij/ide/projectView/TreeStructureProvider.java index b922e3eac386..058d0e1392ef 100644 --- a/platform/lang-api/src/com/intellij/ide/projectView/TreeStructureProvider.java +++ b/platform/lang-api/src/com/intellij/ide/projectView/TreeStructureProvider.java @@ -49,7 +49,7 @@ public interface TreeStructureProvider { * * @param selected the list of nodes currently selected in the project view. * @param dataName the identifier of the requested data object (for example, as defined in - * {@link com.intellij.openapi.actionSystem.DataConstants}) + * {@link com.intellij.openapi.actionSystem.PlatformDataKeys}) * @return the data object, or null if no data object can be returned by this provider. * @see com.intellij.openapi.actionSystem.DataProvider */ diff --git a/platform/lang-api/src/com/intellij/openapi/actionSystem/LangDataKeys.java b/platform/lang-api/src/com/intellij/openapi/actionSystem/LangDataKeys.java index 83bcba4adec0..80bb6c7ad69c 100644 --- a/platform/lang-api/src/com/intellij/openapi/actionSystem/LangDataKeys.java +++ b/platform/lang-api/src/com/intellij/openapi/actionSystem/LangDataKeys.java @@ -18,6 +18,7 @@ package com.intellij.openapi.actionSystem; import com.intellij.ide.IdeView; import com.intellij.lang.Language; +import com.intellij.openapi.module.ModifiableModuleModel; import com.intellij.openapi.module.Module; import com.intellij.openapi.util.Condition; import com.intellij.psi.PsiElement; @@ -27,13 +28,25 @@ import com.intellij.psi.PsiFile; * @author yole */ public class LangDataKeys extends PlatformDataKeys { - public static final DataKey MODULE = DataKey.create(DataConstants.MODULE); - public static final DataKey MODULE_CONTEXT = DataKey.create(DataConstants.MODULE_CONTEXT); - public static final DataKey MODULE_CONTEXT_ARRAY = DataKey.create(DataConstants.MODULE_CONTEXT_ARRAY); - public static final DataKey PSI_ELEMENT = DataKey.create(DataConstants.PSI_ELEMENT); - public static final DataKey PSI_FILE = DataKey.create(DataConstants.PSI_FILE); - public static final DataKey LANGUAGE = DataKey.create(DataConstants.LANGUAGE); - public static final DataKey PSI_ELEMENT_ARRAY = DataKey.create(DataConstants.PSI_ELEMENT_ARRAY); - public static final DataKey IDE_VIEW = DataKey.create(DataConstants.IDE_VIEW); + public static final DataKey MODULE = DataKey.create("module"); + /** + * Returns module if module node is selected (in module view) + */ + public static final DataKey MODULE_CONTEXT = DataKey.create("context.Module"); + public static final DataKey MODULE_CONTEXT_ARRAY = DataKey.create("context.Module.Array"); + public static final DataKey MODIFIABLE_MODULE_MODEL = DataKey.create("modifiable.module.model"); + + public static final DataKey PSI_ELEMENT = DataKey.create("psi.Element"); + public static final DataKey PSI_FILE = DataKey.create("psi.File"); + public static final DataKey LANGUAGE = DataKey.create("Language"); + public static final DataKey PSI_ELEMENT_ARRAY = DataKey.create("psi.Element.array"); + + /** + * Returns {@link com.intellij.ide.IdeView} (one of project, packages, commander or favorites view). + */ + public static final DataKey IDE_VIEW = DataKey.create("IDEView"); public static final DataKey> PRESELECT_NEW_ACTION_CONDITION = DataKey.create("newElementAction.preselect.id"); + + public static final DataKey TARGET_PSI_ELEMENT = DataKey.create("psi.TargetElement"); + public static final DataKey PASTE_TARGET_PSI_ELEMENT = DataKey.create("psi.pasteTargetElement"); } diff --git a/platform/lang-impl/src/com/intellij/codeInsight/actions/OptimizeImportsAction.java b/platform/lang-impl/src/com/intellij/codeInsight/actions/OptimizeImportsAction.java index 2238bfa77176..66a1e3b4b98b 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/actions/OptimizeImportsAction.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/actions/OptimizeImportsAction.java @@ -37,10 +37,16 @@ public class OptimizeImportsAction extends AnAction { public static void actionPerformedImpl(final DataContext dataContext) { final Project project = PlatformDataKeys.PROJECT.getData(dataContext); + if (project == null) { + return; + } PsiDocumentManager.getInstance(project).commitAllDocuments(); final Editor editor = BaseCodeInsightAction.getInjectedEditor(project, PlatformDataKeys.EDITOR.getData(dataContext)); - final VirtualFile[] files = (VirtualFile[])dataContext.getData(DataConstants.VIRTUAL_FILE_ARRAY); + final VirtualFile[] files = PlatformDataKeys.VIRTUAL_FILE_ARRAY.getData(dataContext); + if (files == null) { + return; + } PsiFile file = null; PsiDirectory dir; @@ -59,7 +65,7 @@ public class OptimizeImportsAction extends AnAction { } else{ Project projectContext = PlatformDataKeys.PROJECT_CONTEXT.getData(dataContext); - Module moduleContext = (Module)dataContext.getData(DataConstants.MODULE_CONTEXT); + Module moduleContext = LangDataKeys.MODULE_CONTEXT.getData(dataContext); if (projectContext != null || moduleContext != null) { final String text; @@ -131,7 +137,7 @@ public class OptimizeImportsAction extends AnAction { return; } - final VirtualFile[] files = (VirtualFile[])dataContext.getData(DataConstants.VIRTUAL_FILE_ARRAY); + final VirtualFile[] files = PlatformDataKeys.VIRTUAL_FILE_ARRAY.getData(dataContext); final Editor editor = BaseCodeInsightAction.getInjectedEditor(project, PlatformDataKeys.EDITOR.getData(dataContext), false); if (editor != null){ @@ -161,8 +167,8 @@ public class OptimizeImportsAction extends AnAction { else if (files != null && files.length == 1) { // skip. Both directories and single files are supported. } - else if (dataContext.getData(DataConstants.MODULE_CONTEXT) == null && - dataContext.getData(DataConstants.PROJECT_CONTEXT) == null) { + else if (LangDataKeys.MODULE_CONTEXT.getData(dataContext) == null && + PlatformDataKeys.PROJECT_CONTEXT.getData(dataContext) == null) { PsiElement element = LangDataKeys.PSI_ELEMENT.getData(dataContext); if (element == null){ presentation.setEnabled(false); diff --git a/platform/lang-impl/src/com/intellij/codeInsight/actions/ReformatCodeAction.java b/platform/lang-impl/src/com/intellij/codeInsight/actions/ReformatCodeAction.java index 06d435059446..7518be0a4efc 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/actions/ReformatCodeAction.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/actions/ReformatCodeAction.java @@ -23,8 +23,8 @@ import com.intellij.openapi.actionSystem.*; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.module.Module; import com.intellij.openapi.project.DumbAware; -import com.intellij.openapi.project.Project; import com.intellij.openapi.project.DumbService; +import com.intellij.openapi.project.Project; import com.intellij.openapi.util.TextRange; import com.intellij.openapi.vfs.ReadonlyStatusHandler; import com.intellij.openapi.vfs.VirtualFile; @@ -39,9 +39,15 @@ public class ReformatCodeAction extends AnAction implements DumbAware { public void actionPerformed(AnActionEvent event) { DataContext dataContext = event.getDataContext(); final Project project = PlatformDataKeys.PROJECT.getData(dataContext); + if (project == null) { + return; + } PsiDocumentManager.getInstance(project).commitAllDocuments(); final Editor editor = PlatformDataKeys.EDITOR.getData(dataContext); - final VirtualFile[] files = (VirtualFile[])dataContext.getData(DataConstants.VIRTUAL_FILE_ARRAY); + final VirtualFile[] files = PlatformDataKeys.VIRTUAL_FILE_ARRAY.getData(dataContext); + if (files == null) { + return; + } PsiFile file = null; final PsiDirectory dir; @@ -71,7 +77,7 @@ public class ReformatCodeAction extends AnAction implements DumbAware { } else{ Project projectContext = PlatformDataKeys.PROJECT_CONTEXT.getData(dataContext); - Module moduleContext = (Module)dataContext.getData(DataConstants.MODULE_CONTEXT); + Module moduleContext = LangDataKeys.MODULE_CONTEXT.getData(dataContext); if (projectContext != null || moduleContext != null) { final String text; @@ -172,7 +178,7 @@ public class ReformatCodeAction extends AnAction implements DumbAware { Editor editor = PlatformDataKeys.EDITOR.getData(dataContext); - final VirtualFile[] files = (VirtualFile[])dataContext.getData(DataConstants.VIRTUAL_FILE_ARRAY); + final VirtualFile[] files = PlatformDataKeys.VIRTUAL_FILE_ARRAY.getData(dataContext); if (editor != null){ PsiFile file = PsiDocumentManager.getInstance(project).getPsiFile(editor.getDocument()); @@ -211,8 +217,8 @@ public class ReformatCodeAction extends AnAction implements DumbAware { else if (files != null && files.length == 1) { // skip. Both directories and single files are supported. } - else if (dataContext.getData(DataConstants.MODULE_CONTEXT) == null && - dataContext.getData(DataConstants.PROJECT_CONTEXT) == null) { + else if (LangDataKeys.MODULE_CONTEXT.getData(dataContext) == null && + PlatformDataKeys.PROJECT_CONTEXT.getData(dataContext) == null) { PsiElement element = LangDataKeys.PSI_ELEMENT.getData(dataContext); if (element == null) { presentation.setEnabled(false); diff --git a/platform/lang-impl/src/com/intellij/codeInsight/highlighting/actions/HighlightUsagesAction.java b/platform/lang-impl/src/com/intellij/codeInsight/highlighting/actions/HighlightUsagesAction.java index ceddf431a73c..9c775e3c0bf0 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/highlighting/actions/HighlightUsagesAction.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/highlighting/actions/HighlightUsagesAction.java @@ -21,9 +21,9 @@ import com.intellij.openapi.actionSystem.*; import com.intellij.openapi.command.CommandProcessor; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.project.DumbAware; -import com.intellij.openapi.project.Project; -import com.intellij.openapi.project.IndexNotReadyException; import com.intellij.openapi.project.DumbService; +import com.intellij.openapi.project.IndexNotReadyException; +import com.intellij.openapi.project.Project; import com.intellij.psi.PsiDocumentManager; import com.intellij.psi.PsiFile; @@ -37,8 +37,8 @@ public class HighlightUsagesAction extends AnAction implements DumbAware { final Presentation presentation = event.getPresentation(); final DataContext dataContext = event.getDataContext(); - presentation.setEnabled(dataContext.getData(DataConstants.PROJECT) != null && - dataContext.getData(DataConstants.EDITOR) != null); + presentation.setEnabled(PlatformDataKeys.PROJECT.getData(dataContext) != null && + PlatformDataKeys.EDITOR.getData(dataContext) != null); } public void actionPerformed(AnActionEvent e) { @@ -65,4 +65,4 @@ public class HighlightUsagesAction extends AnAction implements DumbAware { null ); } -} \ No newline at end of file +} diff --git a/platform/lang-impl/src/com/intellij/codeInspection/ex/QuickFixAction.java b/platform/lang-impl/src/com/intellij/codeInspection/ex/QuickFixAction.java index 5cc7598cf2f7..6ffed4812658 100644 --- a/platform/lang-impl/src/com/intellij/codeInspection/ex/QuickFixAction.java +++ b/platform/lang-impl/src/com/intellij/codeInspection/ex/QuickFixAction.java @@ -29,7 +29,6 @@ import com.intellij.codeInspection.ui.InspectionTree; import com.intellij.openapi.actionSystem.AnAction; import com.intellij.openapi.actionSystem.AnActionEvent; import com.intellij.openapi.actionSystem.CustomShortcutSet; -import com.intellij.openapi.actionSystem.ex.DataConstantsEx; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.command.CommandProcessor; import com.intellij.openapi.project.Project; @@ -54,7 +53,7 @@ public class QuickFixAction extends AnAction { protected InspectionTool myTool; public static InspectionResultsView getInvoker(AnActionEvent e) { - return (InspectionResultsView)e.getDataContext().getData(DataConstantsEx.INSPECTION_VIEW); + return InspectionResultsView.DATA_KEY.getData(e.getDataContext()); } protected QuickFixAction(String text, InspectionTool tool) { diff --git a/platform/lang-impl/src/com/intellij/codeInspection/ui/InspectionResultsView.java b/platform/lang-impl/src/com/intellij/codeInspection/ui/InspectionResultsView.java index 4c78d9fee44c..5980a99f166a 100644 --- a/platform/lang-impl/src/com/intellij/codeInspection/ui/InspectionResultsView.java +++ b/platform/lang-impl/src/com/intellij/codeInspection/ui/InspectionResultsView.java @@ -17,7 +17,6 @@ package com.intellij.codeInspection.ui; import com.intellij.CommonBundle; -import com.intellij.injected.editor.VirtualFileWindow; import com.intellij.analysis.AnalysisScope; import com.intellij.analysis.AnalysisUIOptions; import com.intellij.codeHighlighting.HighlightDisplayLevel; @@ -31,9 +30,9 @@ import com.intellij.codeInspection.ui.actions.ExportHTMLAction; import com.intellij.codeInspection.ui.actions.InspectionsOptionsToolbarAction; import com.intellij.codeInspection.ui.actions.InvokeQuickFixAction; import com.intellij.ide.*; +import com.intellij.injected.editor.VirtualFileWindow; import com.intellij.openapi.Disposable; import com.intellij.openapi.actionSystem.*; -import com.intellij.openapi.actionSystem.ex.DataConstantsEx; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.editor.colors.EditorColors; @@ -80,6 +79,8 @@ import java.util.List; * @author max */ public class InspectionResultsView extends JPanel implements Disposable, OccurenceNavigator, DataProvider { + public static final DataKey DATA_KEY = DataKey.create("inspectionView"); + private final Project myProject; private InspectionTree myTree; private final Browser myBrowser; @@ -566,15 +567,15 @@ public class InspectionResultsView extends JPanel implements Disposable, Occuren } public Object getData(String dataId) { - if (dataId.equals(DataConstants.HELP_ID)) return HELP_ID; - if (dataId.equals(DataConstantsEx.INSPECTION_VIEW)) return this; + if (PlatformDataKeys.HELP_ID.is(dataId)) return HELP_ID; + if (InspectionResultsView.DATA_KEY.is(dataId)) return this; if (myTree == null) return null; TreePath[] paths = myTree.getSelectionPaths(); if (paths == null) return null; if (paths.length > 1) { - if (DataConstants.PSI_ELEMENT_ARRAY.equals(dataId)) { + if (LangDataKeys.PSI_ELEMENT_ARRAY.is(dataId)) { return collectPsiElements(); } else { @@ -608,14 +609,14 @@ public class InspectionResultsView extends JPanel implements Disposable, Occuren } } - if (DataConstants.NAVIGATABLE.equals(dataId)) { + if (PlatformDataKeys.NAVIGATABLE.is(dataId)) { return getSelectedNavigatable(problem, psiElement); } - else if (DataConstants.PSI_ELEMENT.equals(dataId)) { + else if (LangDataKeys.PSI_ELEMENT.is(dataId)) { return psiElement.isValid() ? psiElement : null; } } - else if (selectedNode instanceof ProblemDescriptionNode && DataConstants.NAVIGATABLE.equals(dataId)) { + else if (selectedNode instanceof ProblemDescriptionNode && PlatformDataKeys.NAVIGATABLE.is(dataId)) { return getSelectedNavigatable(((ProblemDescriptionNode)selectedNode).getDescriptor()); } diff --git a/platform/lang-impl/src/com/intellij/diagnostic/logging/LogConsoleBase.java b/platform/lang-impl/src/com/intellij/diagnostic/logging/LogConsoleBase.java index 88cca8865674..aaa609a2f7b8 100644 --- a/platform/lang-impl/src/com/intellij/diagnostic/logging/LogConsoleBase.java +++ b/platform/lang-impl/src/com/intellij/diagnostic/logging/LogConsoleBase.java @@ -48,11 +48,7 @@ import java.io.*; import java.util.List; /** - * Created by IntelliJ IDEA. - * User: Eugene.Kudelevsky - * Date: Sep 11, 2009 - * Time: 9:26:11 PM - * To change this template use File | Settings | File Templates. + * @author Eugene.Kudelevsky */ public abstract class LogConsoleBase extends AdditionalTabComponent implements LogConsole, LogFilterListener { private static final Logger LOG = Logger.getInstance("com.intellij.diagnostic.logging.LogConsoleImpl"); @@ -340,7 +336,7 @@ public abstract class LogConsoleBase extends AdditionalTabComponent implements L @Nullable private Editor getEditor() { - return myConsole != null ? (Editor)((DataProvider)myConsole).getData(DataConstants.EDITOR) : null; + return myConsole != null ? PlatformDataKeys.EDITOR.getData((DataProvider) myConsole) : null; } private synchronized void filterConsoleOutput(Condition isApplicable) { diff --git a/platform/lang-impl/src/com/intellij/execution/actions/ConfigurationContext.java b/platform/lang-impl/src/com/intellij/execution/actions/ConfigurationContext.java index 5cc0e0137d47..cf7c494deac1 100644 --- a/platform/lang-impl/src/com/intellij/execution/actions/ConfigurationContext.java +++ b/platform/lang-impl/src/com/intellij/execution/actions/ConfigurationContext.java @@ -22,11 +22,9 @@ import com.intellij.execution.configurations.RuntimeConfiguration; import com.intellij.execution.impl.RunnerAndConfigurationSettingsImpl; import com.intellij.execution.junit.RuntimeConfigurationProducer; import com.intellij.ide.DataManager; -import com.intellij.openapi.actionSystem.DataConstants; import com.intellij.openapi.actionSystem.DataContext; import com.intellij.openapi.actionSystem.LangDataKeys; import com.intellij.openapi.actionSystem.PlatformDataKeys; -import com.intellij.openapi.actionSystem.ex.DataConstantsEx; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.module.Module; @@ -53,12 +51,13 @@ public class ConfigurationContext { private final Component myContextComponent; public ConfigurationContext(final DataContext dataContext) { - myRuntimeConfiguration = (RuntimeConfiguration)dataContext.getData(DataConstantsEx.RUNTIME_CONFIGURATION); - myContextComponent = (Component)dataContext.getData(DataConstants.CONTEXT_COMPONENT); + myRuntimeConfiguration = RuntimeConfiguration.DATA_KEY.getData(dataContext); + myContextComponent = PlatformDataKeys.CONTEXT_COMPONENT.getData(dataContext); myModule = LangDataKeys.MODULE.getData(dataContext); - final Object location = dataContext.getData(Location.LOCATION); + @SuppressWarnings({"unchecked"}) + final Location location = (Location)Location.DATA_KEY.getData(dataContext); if (location != null) { - myLocation = (Location)location; + myLocation = location; return; } final Project project = PlatformDataKeys.PROJECT.getData(dataContext); diff --git a/platform/lang-impl/src/com/intellij/execution/impl/ConsoleViewImpl.java b/platform/lang-impl/src/com/intellij/execution/impl/ConsoleViewImpl.java index ec9dcfa0b827..26296a354797 100644 --- a/platform/lang-impl/src/com/intellij/execution/impl/ConsoleViewImpl.java +++ b/platform/lang-impl/src/com/intellij/execution/impl/ConsoleViewImpl.java @@ -24,8 +24,6 @@ import com.intellij.execution.ui.ConsoleView; import com.intellij.execution.ui.ConsoleViewContentType; import com.intellij.execution.ui.ObservableConsoleView; import com.intellij.ide.CommonActionsManager; -import com.intellij.ide.DataAccessor; -import com.intellij.ide.DataAccessors; import com.intellij.ide.OccurenceNavigator; import com.intellij.openapi.Disposable; import com.intellij.openapi.actionSystem.*; @@ -60,7 +58,6 @@ import com.intellij.openapi.keymap.KeymapManager; import com.intellij.openapi.project.DumbAware; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Computable; -import com.intellij.openapi.util.Condition; import com.intellij.openapi.util.Disposer; import com.intellij.openapi.util.Key; import com.intellij.openapi.util.text.LineTokenizer; @@ -75,6 +72,7 @@ import com.intellij.util.EditorPopupHandler; import com.intellij.util.LocalTimeCounter; import com.intellij.util.containers.HashMap; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.TestOnly; import javax.swing.*; @@ -506,7 +504,7 @@ public final class ConsoleViewImpl extends JPanel implements ConsoleView, Observ } public Object getData(final String dataId) { - if (DataConstants.NAVIGATABLE.equals(dataId)){ + if (PlatformDataKeys.NAVIGATABLE.is(dataId)){ if (myEditor == null) { return null; } @@ -519,10 +517,10 @@ public final class ConsoleViewImpl extends JPanel implements ConsoleView, Observ return openFileDescriptor; } - if (DataConstants.EDITOR.equals(dataId)) { + if (PlatformDataKeys.EDITOR.is(dataId)) { return myEditor; } - if (DataConstants.HELP_ID.equals(dataId)) { + if (PlatformDataKeys.HELP_ID.is(dataId)) { return myHelpId; } return null; @@ -953,33 +951,31 @@ public final class ConsoleViewImpl extends JPanel implements ConsoleView, Observ } } - private static final DataAccessor CONSOLE = new DataAccessor() { - public ConsoleViewImpl getImpl(final DataContext dataContext) throws NoDataException { - return DataAccessors.EDITOR.getNotNull(dataContext).getUserData(CONSOLE_VIEW_IN_EDITOR_VIEW); - } - }; - - private static final Condition CONSOLE_IS_RUNNING = new Condition() { - public boolean value(final ConsoleViewImpl consoleView) { - return consoleView.myState.isRunning(); - } - }; - - private static final DataAccessor RUNNINT_CONSOLE =DataAccessor.createConditionalAccessor(CONSOLE, CONSOLE_IS_RUNNING); - private abstract static class ConsoleAction extends AnAction implements DumbAware { public void actionPerformed(final AnActionEvent e) { final DataContext context = e.getDataContext(); - final ConsoleViewImpl console = RUNNINT_CONSOLE.from(context); + final ConsoleViewImpl console = getRunningConsole(context); execute(console, context); } protected abstract void execute(ConsoleViewImpl console, final DataContext context); public void update(final AnActionEvent e) { - final ConsoleViewImpl console = RUNNINT_CONSOLE.from(e.getDataContext()); + final ConsoleViewImpl console = getRunningConsole(e.getDataContext()); e.getPresentation().setEnabled(console != null); } + + @Nullable + private static ConsoleViewImpl getRunningConsole(final DataContext context) { + final Editor editor = PlatformDataKeys.EDITOR.getData(context); + if (editor != null) { + final ConsoleViewImpl console = editor.getUserData(CONSOLE_VIEW_IN_EDITOR_VIEW); + if (console != null && console.myState.isRunning()) { + return console; + } + } + return null; + } } private static class EnterHandler extends ConsoleAction { diff --git a/platform/lang-impl/src/com/intellij/execution/runners/RestartAction.java b/platform/lang-impl/src/com/intellij/execution/runners/RestartAction.java index 040aa845623a..134513e65ff2 100644 --- a/platform/lang-impl/src/com/intellij/execution/runners/RestartAction.java +++ b/platform/lang-impl/src/com/intellij/execution/runners/RestartAction.java @@ -62,12 +62,12 @@ public class RestartAction extends AnAction implements DumbAware { final ExecutionEnvironment old = myEnvironment; myRunner.execute(myExecutor, new ExecutionEnvironment(old.getRunProfile(), old.getRunnerSettings(), old.getConfigurationSettings(), new DataContext() { public Object getData(final String dataId) { - if (GenericProgramRunner.CONTENT_TO_REUSE.equals(dataId)) return myDescriptor; + if (GenericProgramRunner.CONTENT_TO_REUSE_DATA_KEY.is(dataId)) return myDescriptor; return dataContext.getData(dataId); } })); } - catch (RunCanceledByUserException e1) { + catch (RunCanceledByUserException ignore) { } catch (ExecutionException e1) { Messages.showErrorDialog(project, e1.getMessage(), ExecutionBundle.message("restart.error.message.title")); diff --git a/platform/lang-impl/src/com/intellij/execution/ui/RunContentManagerImpl.java b/platform/lang-impl/src/com/intellij/execution/ui/RunContentManagerImpl.java index 0d98f59dd3d3..eafb3e3485d5 100644 --- a/platform/lang-impl/src/com/intellij/execution/ui/RunContentManagerImpl.java +++ b/platform/lang-impl/src/com/intellij/execution/ui/RunContentManagerImpl.java @@ -15,7 +15,10 @@ */ package com.intellij.execution.ui; -import com.intellij.execution.*; +import com.intellij.execution.ExecutionBundle; +import com.intellij.execution.Executor; +import com.intellij.execution.ExecutorRegistry; +import com.intellij.execution.TerminateRemoteProcessDialog; import com.intellij.execution.process.ProcessAdapter; import com.intellij.execution.process.ProcessEvent; import com.intellij.execution.process.ProcessHandler; @@ -23,9 +26,9 @@ import com.intellij.execution.runners.GenericProgramRunner; import com.intellij.ide.DataManager; import com.intellij.ide.impl.ContentManagerWatcher; import com.intellij.openapi.Disposable; -import com.intellij.openapi.actionSystem.DataConstants; import com.intellij.openapi.actionSystem.DataContext; import com.intellij.openapi.actionSystem.DataProvider; +import com.intellij.openapi.actionSystem.PlatformDataKeys; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.application.impl.LaterInvocator; import com.intellij.openapi.diagnostic.Logger; @@ -45,7 +48,6 @@ import com.intellij.openapi.wm.ex.ToolWindowManagerAdapter; import com.intellij.openapi.wm.ex.ToolWindowManagerEx; import com.intellij.ui.content.*; import com.intellij.util.EventDispatcher; -import com.intellij.util.IconUtil; import com.intellij.util.concurrency.Semaphore; import com.intellij.util.containers.HashMap; import org.jetbrains.annotations.NotNull; @@ -132,7 +134,7 @@ public class RunContentManagerImpl implements RunContentManager, Disposable { public Object getData(String dataId) { myInsideGetData ++; try { - if(DataConstants.HELP_ID.equals(dataId)) { + if(PlatformDataKeys.HELP_ID.is(dataId)) { return executor.getHelpId(); } else { @@ -182,10 +184,8 @@ public class RunContentManagerImpl implements RunContentManager, Disposable { if (contentManager != null && content != null) { contentManager.setSelectedContent(content); - if (content != null) { - final ToolWindow toolWindow = ToolWindowManager.getInstance(myProject).getToolWindow(requestor.getToolWindowId()); - toolWindow.show(null); - } + final ToolWindow toolWindow = ToolWindowManager.getInstance(myProject).getToolWindow(requestor.getToolWindowId()); + toolWindow.show(null); } } }); @@ -312,7 +312,7 @@ public class RunContentManagerImpl implements RunContentManager, Disposable { @Nullable public RunContentDescriptor getReuseContent(final Executor requestor, DataContext dataContext) { if(ApplicationManager.getApplication().isUnitTestMode()) return null; - RunContentDescriptor runContentDescriptor = (RunContentDescriptor)dataContext.getData(GenericProgramRunner.CONTENT_TO_REUSE); + RunContentDescriptor runContentDescriptor = GenericProgramRunner.CONTENT_TO_REUSE_DATA_KEY.getData(dataContext); if(runContentDescriptor != null) return runContentDescriptor; @@ -594,7 +594,7 @@ public class RunContentManagerImpl implements RunContentManager, Disposable { wait(2000); } } - catch (InterruptedException e) { + catch (InterruptedException ignore) { } } } diff --git a/platform/lang-impl/src/com/intellij/find/EditorSearchComponent.java b/platform/lang-impl/src/com/intellij/find/EditorSearchComponent.java index 61f52f2ea074..2c25d1895ef1 100644 --- a/platform/lang-impl/src/com/intellij/find/EditorSearchComponent.java +++ b/platform/lang-impl/src/com/intellij/find/EditorSearchComponent.java @@ -26,7 +26,6 @@ import com.intellij.find.impl.FindManagerImpl; import com.intellij.ide.ui.LafManager; import com.intellij.ide.ui.UISettings; import com.intellij.openapi.actionSystem.*; -import com.intellij.openapi.application.ex.ApplicationManagerEx; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.editor.ScrollType; import com.intellij.openapi.editor.SelectionModel; @@ -88,7 +87,7 @@ public class EditorSearchComponent extends JPanel implements DataProvider { @Nullable public Object getData(@NonNls final String dataId) { - if (DataConstants.EDITOR_EVEN_IF_INACTIVE.equals(dataId)) { + if (PlatformDataKeys.EDITOR_EVEN_IF_INACTIVE.is(dataId)) { return myEditor; } return null; diff --git a/platform/lang-impl/src/com/intellij/find/actions/FindUsagesInFileAction.java b/platform/lang-impl/src/com/intellij/find/actions/FindUsagesInFileAction.java index 21b599f96fbd..18e0a0c3071d 100644 --- a/platform/lang-impl/src/com/intellij/find/actions/FindUsagesInFileAction.java +++ b/platform/lang-impl/src/com/intellij/find/actions/FindUsagesInFileAction.java @@ -44,7 +44,7 @@ public class FindUsagesInFileAction extends AnAction { PsiDocumentManager.getInstance(project).commitAllDocuments(); Editor editor = PlatformDataKeys.EDITOR.getData(dataContext); - UsageTarget[] usageTargets = (UsageTarget[])dataContext.getData(UsageView.USAGE_TARGETS); + UsageTarget[] usageTargets = UsageView.USAGE_TARGETS_KEY.getData(dataContext); if (usageTargets != null) { FileEditor fileEditor = PlatformDataKeys.FILE_EDITOR.getData(dataContext); if (fileEditor != null) { @@ -76,7 +76,7 @@ public class FindUsagesInFileAction extends AnAction { Editor editor = PlatformDataKeys.EDITOR.getData(dataContext); if (editor == null) { - UsageTarget[] target = (UsageTarget[])dataContext.getData(UsageView.USAGE_TARGETS); + UsageTarget[] target = UsageView.USAGE_TARGETS_KEY.getData(dataContext); return target != null && target.length > 0; } else { diff --git a/platform/lang-impl/src/com/intellij/ide/CopyPasteDelegator.java b/platform/lang-impl/src/com/intellij/ide/CopyPasteDelegator.java index ce61ecc3ac31..cfd449c6a4b9 100644 --- a/platform/lang-impl/src/com/intellij/ide/CopyPasteDelegator.java +++ b/platform/lang-impl/src/com/intellij/ide/CopyPasteDelegator.java @@ -17,8 +17,8 @@ package com.intellij.ide; import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.actionSystem.LangDataKeys; import com.intellij.openapi.actionSystem.PlatformDataKeys; -import com.intellij.openapi.actionSystem.ex.DataConstantsEx; import com.intellij.openapi.extensions.ExtensionPointName; import com.intellij.openapi.extensions.Extensions; import com.intellij.openapi.project.Project; @@ -128,7 +128,7 @@ public abstract class CopyPasteDelegator implements CopyPasteSupport { final PsiElement[] elements = PsiCopyPasteManager.getInstance().getElements(isCopied); if (elements == null) return false; try { - PsiElement target = (PsiElement)dataContext.getData(DataConstantsEx.PASTE_TARGET_PSI_ELEMENT); + PsiElement target = LangDataKeys.PASTE_TARGET_PSI_ELEMENT.getData(dataContext); if (isCopied[0]) { PsiDirectory targetDirectory = target instanceof PsiDirectory ? (PsiDirectory)target : null; if (targetDirectory == null && target instanceof PsiDirectoryContainer) { @@ -180,7 +180,7 @@ public abstract class CopyPasteDelegator implements CopyPasteSupport { return false; } - Object target = dataContext.getData(DataConstantsEx.PASTE_TARGET_PSI_ELEMENT); + Object target = LangDataKeys.PASTE_TARGET_PSI_ELEMENT.getData(dataContext); if (target == null) { return false; } @@ -200,4 +200,4 @@ public abstract class CopyPasteDelegator implements CopyPasteSupport { return true; } } -} \ No newline at end of file +} diff --git a/platform/lang-impl/src/com/intellij/ide/DataAccessors.java b/platform/lang-impl/src/com/intellij/ide/DataAccessors.java index 5ab2b63001de..ecd2b61169e0 100644 --- a/platform/lang-impl/src/com/intellij/ide/DataAccessors.java +++ b/platform/lang-impl/src/com/intellij/ide/DataAccessors.java @@ -16,57 +16,40 @@ package com.intellij.ide; -import com.intellij.openapi.actionSystem.DataConstants; import com.intellij.openapi.actionSystem.DataContext; -import com.intellij.openapi.editor.Editor; -import com.intellij.openapi.fileEditor.FileEditorManager; +import com.intellij.openapi.actionSystem.LangDataKeys; +import com.intellij.openapi.actionSystem.PlatformDataKeys; import com.intellij.openapi.module.Module; import com.intellij.openapi.project.Project; -import com.intellij.openapi.project.ex.ProjectEx; import com.intellij.openapi.vfs.VirtualFile; -import com.intellij.psi.*; +import com.intellij.psi.PsiFile; +import com.intellij.psi.PsiManager; /** * @author yole */ public class DataAccessors { - public static final DataAccessor PROJECT = new DataAccessor.SimpleDataAccessor(DataConstants.PROJECT); - public static final DataAccessor MODULE = new DataAccessor.SimpleDataAccessor(DataConstants.MODULE); - public static final DataAccessor EDITOR = new DataAccessor.SimpleDataAccessor(DataConstants.EDITOR); + @Deprecated + public static final DataAccessor PROJECT = new DataAccessor.SimpleDataAccessor(PlatformDataKeys.PROJECT.getName()); + @Deprecated + public static final DataAccessor MODULE = new DataAccessor.SimpleDataAccessor(LangDataKeys.MODULE.getName()); public static final DataAccessor PSI_MANAGER = new DataAccessor() { public PsiManager getImpl(DataContext dataContext) throws NoDataException { return PsiManager.getInstance(PROJECT.getNotNull(dataContext)); } }; - public static final DataAccessor FILE_EDITOR_MANAGER = new DataAccessor() { - public FileEditorManager getImpl(DataContext dataContext) throws NoDataException { - return FileEditorManager.getInstance(PROJECT.getNotNull(dataContext)); - } - }; public static final DataAccessor PSI_FILE = new DataAccessor() { public PsiFile getImpl(DataContext dataContext) throws NoDataException { return PSI_MANAGER.getNotNull(dataContext).findFile(VIRTUAL_FILE.getNotNull(dataContext)); } }; - public static final DataAccessor PSI_ELEMENT = new DataAccessor.SimpleDataAccessor(DataConstants.PSI_ELEMENT); - public static final DataAccessor PSI_ELEMENT_ARRAY = new DataAccessor.SimpleDataAccessor(DataConstants.PSI_ELEMENT_ARRAY); - public static final DataAccessor VIRTUAL_FILE = new DataAccessor.SimpleDataAccessor(DataConstants.VIRTUAL_FILE); - public static final DataAccessor VIRTUAL_FILE_ARRAY = new DataAccessor.SimpleDataAccessor(DataConstants.VIRTUAL_FILE_ARRAY); + public static final DataAccessor VIRTUAL_FILE = new DataAccessor.SimpleDataAccessor(PlatformDataKeys.VIRTUAL_FILE.getName()); public static final DataAccessor VIRTUAL_DIR_OR_PARENT = new DataAccessor() { public VirtualFile getImpl(DataContext dataContext) throws NoDataException { VirtualFile virtualFile = VIRTUAL_FILE.getNotNull(dataContext); return virtualFile.isDirectory() ? virtualFile : virtualFile.getParent(); } }; - /** - * @deprecated - */ - public static final DataAccessor PROJECT_FILE_PATH = new DataAccessor() { - public String getImpl(DataContext dataContext) throws NoDataException { - Project project = PROJECT.getNotNull(dataContext); - return project.getProjectFilePath(); - } - }; public static final DataAccessor PROJECT_BASE_DIR = new DataAccessor() { public VirtualFile getImpl(DataContext dataContext) throws NoDataException { Project project = PROJECT.getNotNull(dataContext); @@ -79,5 +62,7 @@ public class DataAccessors { return module.getModuleFilePath(); } }; - public static final DataAccessor PROJECT_EX = new DataAccessor.SubClassDataAccessor(PROJECT, ProjectEx.class); + + private DataAccessors() { + } } \ No newline at end of file diff --git a/platform/lang-impl/src/com/intellij/ide/actions/CopyElementAction.java b/platform/lang-impl/src/com/intellij/ide/actions/CopyElementAction.java index c784b92e0ea2..15031051deb2 100644 --- a/platform/lang-impl/src/com/intellij/ide/actions/CopyElementAction.java +++ b/platform/lang-impl/src/com/intellij/ide/actions/CopyElementAction.java @@ -17,7 +17,6 @@ package com.intellij.ide.actions; import com.intellij.openapi.actionSystem.*; -import com.intellij.openapi.actionSystem.ex.DataConstantsEx; import com.intellij.openapi.command.CommandProcessor; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.project.Project; @@ -32,6 +31,9 @@ public class CopyElementAction extends AnAction { public void actionPerformed(AnActionEvent e) { final DataContext dataContext = e.getDataContext(); final Project project = PlatformDataKeys.PROJECT.getData(dataContext); + if (project == null) { + return; + } CommandProcessor.getInstance().executeCommand(project, new Runnable() { public void run() { @@ -41,7 +43,7 @@ public class CopyElementAction extends AnAction { final Editor editor = PlatformDataKeys.EDITOR.getData(dataContext); PsiElement[] elements; - PsiDirectory defaultTargetDirectory = null; + PsiDirectory defaultTargetDirectory; if (editor != null) { PsiElement aElement = getTargetElement(editor, project); PsiFile file = PsiDocumentManager.getInstance(project).getPsiFile(editor.getDocument()); @@ -52,7 +54,7 @@ public class CopyElementAction extends AnAction { } defaultTargetDirectory = file.getContainingDirectory(); } else { - Object element = dataContext.getData(DataConstantsEx.TARGET_PSI_ELEMENT); + PsiElement element = LangDataKeys.TARGET_PSI_ELEMENT.getData(dataContext); defaultTargetDirectory = element instanceof PsiDirectory ? (PsiDirectory)element : null; elements = LangDataKeys.PSI_ELEMENT_ARRAY.getData(dataContext); } @@ -90,6 +92,10 @@ public class CopyElementAction extends AnAction { } Project project = PlatformDataKeys.PROJECT.getData(dataContext); + if (project == null) { + return; + + } PsiFile file = PsiDocumentManager.getInstance(project).getPsiFile(editor.getDocument()); PsiElement element = getTargetElement(editor, project); diff --git a/platform/lang-impl/src/com/intellij/ide/actions/QuickChangeCodeStyleSchemeAction.java b/platform/lang-impl/src/com/intellij/ide/actions/QuickChangeCodeStyleSchemeAction.java index f7d76fe8b777..72fd2900a2e4 100644 --- a/platform/lang-impl/src/com/intellij/ide/actions/QuickChangeCodeStyleSchemeAction.java +++ b/platform/lang-impl/src/com/intellij/ide/actions/QuickChangeCodeStyleSchemeAction.java @@ -64,8 +64,11 @@ public class QuickChangeCodeStyleSchemeAction extends QuickSwitchSchemeAction { } } - private void addScheme(final DefaultActionGroup group, final CodeStyleSettingsManager manager, final CodeStyleScheme currentScheme, - final CodeStyleScheme scheme, final boolean addScheme) { + private static void addScheme(final DefaultActionGroup group, + final CodeStyleSettingsManager manager, + final CodeStyleScheme currentScheme, + final CodeStyleScheme scheme, + final boolean addScheme) { group.add(new AnAction(scheme.getName(), "", scheme == currentScheme && !manager.USE_PER_PROJECT_SETTINGS ? ourCurrentAction : ourNotCurrentAction) { public void actionPerformed(AnActionEvent e) { @@ -85,6 +88,6 @@ public class QuickChangeCodeStyleSchemeAction extends QuickSwitchSchemeAction { public void update(AnActionEvent e) { super.update(e); - e.getPresentation().setEnabled(e.getDataContext().getData(DataConstants.PROJECT) != null); + e.getPresentation().setEnabled(PlatformDataKeys.PROJECT.getData(e.getDataContext()) != null); } } diff --git a/platform/lang-impl/src/com/intellij/ide/actions/SelectInContextImpl.java b/platform/lang-impl/src/com/intellij/ide/actions/SelectInContextImpl.java index a1d620ff0b2c..233b04226433 100644 --- a/platform/lang-impl/src/com/intellij/ide/actions/SelectInContextImpl.java +++ b/platform/lang-impl/src/com/intellij/ide/actions/SelectInContextImpl.java @@ -18,7 +18,10 @@ package com.intellij.ide.actions; import com.intellij.ide.FileEditorProvider; import com.intellij.ide.SelectInContext; -import com.intellij.openapi.actionSystem.*; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.actionSystem.LangDataKeys; +import com.intellij.openapi.actionSystem.PlatformDataKeys; import com.intellij.openapi.editor.Document; import com.intellij.openapi.fileEditor.*; import com.intellij.openapi.fileEditor.ex.FileEditorManagerEx; @@ -74,7 +77,7 @@ abstract class SelectInContextImpl implements SelectInContext { return null; } - SelectInContext selectInContext = (SelectInContext)dataContext.getData(SelectInContext.DATA_CONTEXT_ID); + SelectInContext selectInContext = SelectInContext.DATA_KEY.getData(dataContext); if (selectInContext == null) { selectInContext = createPsiContext(event); } @@ -146,7 +149,7 @@ abstract class SelectInContextImpl implements SelectInContext { return (JComponent)source; } else { - return safeCast(event.getDataContext().getData(DataConstants.CONTEXT_COMPONENT), JComponent.class); + return safeCast(PlatformDataKeys.CONTEXT_COMPONENT.getData(event.getDataContext()), JComponent.class); } } @@ -220,8 +223,11 @@ abstract class SelectInContextImpl implements SelectInContext { public FileEditorProvider getFileEditorProvider() { return new FileEditorProvider() { public FileEditor openFileEditor() { - final FileEditor[] fileEditors = - FileEditorManager.getInstance(getProject()).openFile(myElementToSelect.getContainingFile().getVirtualFile(), false); + final VirtualFile file = myElementToSelect.getContainingFile().getVirtualFile(); + if (file == null) { + return null; + } + final FileEditor[] fileEditors = FileEditorManager.getInstance(getProject()).openFile(file, false); return fileEditors.length > 0 ? fileEditors[0] : null; } }; diff --git a/platform/lang-impl/src/com/intellij/ide/commander/CommanderPanel.java b/platform/lang-impl/src/com/intellij/ide/commander/CommanderPanel.java index 63e2451e8fe9..b7a4bd8b7d69 100644 --- a/platform/lang-impl/src/com/intellij/ide/commander/CommanderPanel.java +++ b/platform/lang-impl/src/com/intellij/ide/commander/CommanderPanel.java @@ -18,7 +18,10 @@ package com.intellij.ide.commander; import com.intellij.history.LocalHistory; import com.intellij.history.LocalHistoryAction; -import com.intellij.ide.*; +import com.intellij.ide.CopyPasteDelegator; +import com.intellij.ide.DeleteProvider; +import com.intellij.ide.IdeBundle; +import com.intellij.ide.IdeView; import com.intellij.ide.projectView.ProjectViewNode; import com.intellij.ide.projectView.impl.ModuleGroup; import com.intellij.ide.projectView.impl.ProjectAbstractTreeStructureBase; @@ -31,9 +34,7 @@ import com.intellij.ide.util.DirectoryChooserUtil; import com.intellij.ide.util.EditSourceUtil; import com.intellij.ide.util.EditorHelper; import com.intellij.ide.util.treeView.AbstractTreeNode; -import com.intellij.ide.util.treeView.smartTree.TreeElement; import com.intellij.openapi.actionSystem.*; -import com.intellij.openapi.actionSystem.ex.DataConstantsEx; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.application.ModalityState; import com.intellij.openapi.diagnostic.Logger; @@ -117,8 +118,8 @@ public class CommanderPanel extends JPanel { } }, KeyStroke.getKeyStroke(KeyEvent.VK_BACK_SLASH, SystemInfo.isMac ? KeyEvent.META_MASK : KeyEvent.CTRL_MASK), JComponent.WHEN_FOCUSED); - myList.getInputMap(JComponent.WHEN_FOCUSED).put(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0), ACTION_DRILL_DOWN); - myList.getInputMap(JComponent.WHEN_FOCUSED) + myList.getInputMap(WHEN_FOCUSED).put(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0), ACTION_DRILL_DOWN); + myList.getInputMap(WHEN_FOCUSED) .put(KeyStroke.getKeyStroke(KeyEvent.VK_PAGE_DOWN, SystemInfo.isMac ? KeyEvent.META_MASK : KeyEvent.CTRL_MASK), ACTION_DRILL_DOWN); myList.getActionMap().put(ACTION_DRILL_DOWN, new AbstractAction() { public void actionPerformed(final ActionEvent e) { @@ -132,9 +133,9 @@ public class CommanderPanel extends JPanel { } } }); - myList.getInputMap(JComponent.WHEN_FOCUSED) + myList.getInputMap(WHEN_FOCUSED) .put(KeyStroke.getKeyStroke(KeyEvent.VK_PAGE_UP, SystemInfo.isMac ? KeyEvent.META_MASK : KeyEvent.CTRL_MASK), ACTION_GO_UP); - myList.getInputMap(JComponent.WHEN_FOCUSED).put(KeyStroke.getKeyStroke(KeyEvent.VK_BACK_SPACE, 0), ACTION_GO_UP); + myList.getInputMap(WHEN_FOCUSED).put(KeyStroke.getKeyStroke(KeyEvent.VK_BACK_SPACE, 0), ACTION_GO_UP); myList.getActionMap().put(ACTION_GO_UP, new AbstractAction() { public void actionPerformed(final ActionEvent e) { goUp(); @@ -351,7 +352,7 @@ public class CommanderPanel extends JPanel { private static Object getValueAtIndex(AbstractTreeNode node) { if (node == null) return null; Object value = node.getValue(); - if (value instanceof TreeElement) { + if (value instanceof StructureViewTreeElement) { return ((StructureViewTreeElement)value).getValue(); } return value; @@ -419,46 +420,46 @@ public class CommanderPanel extends JPanel { public final Object getDataImpl(final String dataId) { if (myBuilder == null) return null; final Object selectedValue = getSelectedValue(); - if (DataConstants.PSI_ELEMENT.equals(dataId)) { + if (LangDataKeys.PSI_ELEMENT.is(dataId)) { final PsiElement selectedElement = getSelectedElement(); return selectedElement != null && selectedElement.isValid() ? selectedElement : null; } - if (DataConstants.PSI_ELEMENT_ARRAY.equals(dataId)) { + if (LangDataKeys.PSI_ELEMENT_ARRAY.is(dataId)) { return filterInvalidElements(getSelectedElements()); } - else if (DataConstantsEx.PASTE_TARGET_PSI_ELEMENT.equals(dataId)) { + else if (LangDataKeys.PASTE_TARGET_PSI_ELEMENT.is(dataId)) { final AbstractTreeNode parentNode = myBuilder.getParentNode(); final Object element = parentNode != null ? parentNode.getValue() : null; return element instanceof PsiElement && ((PsiElement)element).isValid() ? element : null; } - else if (DataConstants.NAVIGATABLE_ARRAY.equals(dataId)) { + else if (PlatformDataKeys.NAVIGATABLE_ARRAY.is(dataId)) { return getNavigatables(); } - else if (DataConstants.COPY_PROVIDER.equals(dataId)) { + else if (PlatformDataKeys.COPY_PROVIDER.is(dataId)) { return myCopyPasteDelegator != null ? myCopyPasteDelegator.getCopyProvider() : null; } - else if (DataConstants.CUT_PROVIDER.equals(dataId)) { + else if (PlatformDataKeys.CUT_PROVIDER.is(dataId)) { return myCopyPasteDelegator != null ? myCopyPasteDelegator.getCutProvider() : null; } - else if (DataConstants.PASTE_PROVIDER.equals(dataId)) { + else if (PlatformDataKeys.PASTE_PROVIDER.is(dataId)) { return myCopyPasteDelegator != null ? myCopyPasteDelegator.getPasteProvider() : null; } - else if (DataConstants.IDE_VIEW.equals(dataId)) { + else if (LangDataKeys.IDE_VIEW.is(dataId)) { return myIdeView; } - else if (DataConstants.DELETE_ELEMENT_PROVIDER.equals(dataId)) { + else if (PlatformDataKeys.DELETE_ELEMENT_PROVIDER.is(dataId)) { return myDeleteElementProvider; } - else if (DataConstants.MODULE.equals(dataId)) { + else if (LangDataKeys.MODULE.is(dataId)) { return selectedValue instanceof Module ? selectedValue : null; } - else if (DataConstantsEx.MODULE_GROUP_ARRAY.equals(dataId)) { + else if (ModuleGroup.ARRAY_DATA_KEY.is(dataId)) { return selectedValue instanceof ModuleGroup ? new ModuleGroup[]{(ModuleGroup)selectedValue} : null; } - else if (DataConstantsEx.LIBRARY_GROUP_ARRAY.equals(dataId)) { + else if (LibraryGroupElement.ARRAY_DATA_KEY.is(dataId)) { return selectedValue instanceof LibraryGroupElement ? new LibraryGroupElement[]{(LibraryGroupElement)selectedValue} : null; } - else if (DataConstantsEx.NAMED_LIBRARY_ARRAY.equals(dataId)) { + else if (NamedLibraryElement.ARRAY_DATA_KEY.is(dataId)) { return selectedValue instanceof NamedLibraryElement ? new NamedLibraryElement[]{(NamedLibraryElement)selectedValue} : null; } diff --git a/platform/lang-impl/src/com/intellij/ide/favoritesTreeView/FavoritesTreeViewPanel.java b/platform/lang-impl/src/com/intellij/ide/favoritesTreeView/FavoritesTreeViewPanel.java index 93daef04a2ca..846cc7cd2462 100644 --- a/platform/lang-impl/src/com/intellij/ide/favoritesTreeView/FavoritesTreeViewPanel.java +++ b/platform/lang-impl/src/com/intellij/ide/favoritesTreeView/FavoritesTreeViewPanel.java @@ -35,7 +35,6 @@ import com.intellij.ide.util.treeView.NodeDescriptor; import com.intellij.ide.util.treeView.NodeRenderer; import com.intellij.navigation.ItemPresentation; import com.intellij.openapi.actionSystem.*; -import com.intellij.openapi.actionSystem.ex.DataConstantsEx; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.extensions.Extensions; import com.intellij.openapi.module.Module; @@ -74,8 +73,12 @@ public class FavoritesTreeViewPanel extends JPanel implements DataProvider { private FavoritesViewTreeBuilder myBuilder; private final CopyPasteDelegator myCopyPasteDelegator; private MouseListener myTreePopupHandler; - @NonNls public static final String CONTEXT_FAVORITES_ROOTS = "FavoritesRoot"; - @NonNls public static final String FAVORITES_LIST_NAME = "FavoritesListName"; + + public static final DataKey CONTEXT_FAVORITES_ROOTS_DATA_KEY = DataKey.create("FavoritesRoot"); + @Deprecated public static final String CONTEXT_FAVORITES_ROOTS = CONTEXT_FAVORITES_ROOTS_DATA_KEY.getName(); + + public static final DataKey FAVORITES_LIST_NAME_DATA_KEY = DataKey.create("FavoritesListName"); + @Deprecated public static final String FAVORITES_LIST_NAME = FAVORITES_LIST_NAME_DATA_KEY.getName(); protected Project myProject; private final String myHelpId; @@ -125,7 +128,7 @@ public class FavoritesTreeViewPanel extends JPanel implements DataProvider { final FavoritesTreeNodeDescriptor favoritesTreeNodeDescriptor = (FavoritesTreeNodeDescriptor)userObject; AbstractTreeNode treeNode = favoritesTreeNodeDescriptor.getElement(); final ItemPresentation presentation = treeNode.getPresentation(); - String locationString = presentation != null ? presentation.getLocationString() : null; + String locationString = presentation.getLocationString(); if (locationString != null && locationString.length() > 0) { append(" (" + locationString + ")", SimpleTextAttributes.GRAY_ATTRIBUTES); } @@ -209,38 +212,38 @@ public class FavoritesTreeViewPanel extends JPanel implements DataProvider { } public Object getData(String dataId) { - if (DataConstants.PROJECT.equals(dataId)) { + if (PlatformDataKeys.PROJECT.is(dataId)) { return myProject; } - if (DataConstants.NAVIGATABLE.equals(dataId)) { + if (PlatformDataKeys.NAVIGATABLE.is(dataId)) { final FavoritesTreeNodeDescriptor[] selectedNodeDescriptors = getSelectedNodeDescriptors(); return selectedNodeDescriptors.length == 1 ? selectedNodeDescriptors[0].getElement() : null; } - if (DataConstants.NAVIGATABLE_ARRAY.equals(dataId)) { + if (PlatformDataKeys.NAVIGATABLE_ARRAY.is(dataId)) { final List selectedElements = getSelectedElements(Navigatable.class); return selectedElements.toArray(new Navigatable[selectedElements.size()]); } - if (DataConstants.CUT_PROVIDER.equals(dataId)) { + if (PlatformDataKeys.CUT_PROVIDER.is(dataId)) { return myCopyPasteDelegator.getCutProvider(); } - if (DataConstants.COPY_PROVIDER.equals(dataId)) { + if (PlatformDataKeys.COPY_PROVIDER.is(dataId)) { return myCopyPasteDelegator.getCopyProvider(); } - if (DataConstants.PASTE_PROVIDER.equals(dataId)) { + if (PlatformDataKeys.PASTE_PROVIDER.is(dataId)) { return myCopyPasteDelegator.getPasteProvider(); } - if (DataConstants.HELP_ID.equals(dataId)) { + if (PlatformDataKeys.HELP_ID.is(dataId)) { return myHelpId; } - if (DataConstants.PSI_ELEMENT.equals(dataId)) { + if (LangDataKeys.PSI_ELEMENT.is(dataId)) { PsiElement[] elements = getSelectedPsiElements(); if (elements.length != 1) { return null; } return elements[0] != null && elements[0].isValid() ? elements[0] : null; } - if (DataConstants.PSI_ELEMENT_ARRAY.equals(dataId)) { + if (LangDataKeys.PSI_ELEMENT_ARRAY.is(dataId)) { final PsiElement[] elements = getSelectedPsiElements(); ArrayList result = new ArrayList(); for (PsiElement element : elements) { @@ -251,42 +254,42 @@ public class FavoritesTreeViewPanel extends JPanel implements DataProvider { return result.isEmpty() ? null : result.toArray(new PsiElement[result.size()]); } - if (DataConstants.IDE_VIEW.equals(dataId)) { + if (LangDataKeys.IDE_VIEW.is(dataId)) { return myIdeView; } - if (DataConstantsEx.TARGET_PSI_ELEMENT.equals(dataId)) { + if (LangDataKeys.TARGET_PSI_ELEMENT.is(dataId)) { return null; } - if (DataConstants.MODULE_CONTEXT.equals(dataId)) { + if (LangDataKeys.MODULE_CONTEXT.is(dataId)) { Module[] selected = getSelectedModules(); return selected != null && selected.length == 1 ? selected[0] : null; } - if (DataConstants.MODULE_CONTEXT_ARRAY.equals(dataId)) { + if (LangDataKeys.MODULE_CONTEXT_ARRAY.is(dataId)) { return getSelectedModules(); } - if (DataConstants.DELETE_ELEMENT_PROVIDER.equals(dataId)) { + if (PlatformDataKeys.DELETE_ELEMENT_PROVIDER.is(dataId)) { final Object[] elements = getSelectedNodeElements(); return elements != null && elements.length >= 1 && elements[0] instanceof Module ? myDeleteModuleProvider : myDeletePSIElementProvider; } - if (DataConstantsEx.MODULE_GROUP_ARRAY.equals(dataId)) { + if (ModuleGroup.ARRAY_DATA_KEY.is(dataId)) { final List selectedElements = getSelectedElements(ModuleGroup.class); return selectedElements.isEmpty() ? null : selectedElements.toArray(new ModuleGroup[selectedElements.size()]); } - if (DataConstantsEx.LIBRARY_GROUP_ARRAY.equals(dataId)) { + if (LibraryGroupElement.ARRAY_DATA_KEY.is(dataId)) { final List selectedElements = getSelectedElements(LibraryGroupElement.class); return selectedElements.isEmpty() ? null : selectedElements.toArray(new LibraryGroupElement[selectedElements.size()]); } - if (DataConstantsEx.NAMED_LIBRARY_ARRAY.equals(dataId)) { + if (NamedLibraryElement.ARRAY_DATA_KEY.is(dataId)) { final List selectedElements = getSelectedElements(NamedLibraryElement.class); return selectedElements.isEmpty() ? null : selectedElements.toArray(new NamedLibraryElement[selectedElements.size()]); } - if (CONTEXT_FAVORITES_ROOTS.equals(dataId)) { + if (CONTEXT_FAVORITES_ROOTS_DATA_KEY.is(dataId)) { List result = new ArrayList(); FavoritesTreeNodeDescriptor[] selectedNodeDescriptors = getSelectedNodeDescriptors(); for (FavoritesTreeNodeDescriptor selectedNodeDescriptor : selectedNodeDescriptors) { @@ -297,7 +300,7 @@ public class FavoritesTreeViewPanel extends JPanel implements DataProvider { } return result.toArray(new FavoritesTreeNodeDescriptor[result.size()]); } - if (FAVORITES_LIST_NAME.equals(dataId)) { + if (FAVORITES_LIST_NAME_DATA_KEY.is(dataId)) { return myListName; } FavoritesTreeNodeDescriptor[] descriptors = getSelectedNodeDescriptors(); diff --git a/platform/lang-impl/src/com/intellij/ide/favoritesTreeView/actions/AddToFavoritesAction.java b/platform/lang-impl/src/com/intellij/ide/favoritesTreeView/actions/AddToFavoritesAction.java index 069a6063f829..c9a0f8cd8ed3 100644 --- a/platform/lang-impl/src/com/intellij/ide/favoritesTreeView/actions/AddToFavoritesAction.java +++ b/platform/lang-impl/src/com/intellij/ide/favoritesTreeView/actions/AddToFavoritesAction.java @@ -26,7 +26,6 @@ import com.intellij.ide.projectView.impl.ModuleGroup; import com.intellij.ide.projectView.impl.nodes.*; import com.intellij.ide.util.treeView.AbstractTreeNode; import com.intellij.openapi.actionSystem.*; -import com.intellij.openapi.actionSystem.ex.DataConstantsEx; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.extensions.Extensions; import com.intellij.openapi.module.Module; @@ -118,10 +117,10 @@ public class AddToFavoritesAction extends AnAction { Object elements = retrieveData(null, LangDataKeys.PSI_ELEMENT.getData(dataContext)); elements = retrieveData(elements, LangDataKeys.PSI_ELEMENT_ARRAY.getData(dataContext)); elements = retrieveData(elements, LangDataKeys.PSI_FILE.getData(dataContext)); - elements = retrieveData(elements, dataContext.getData(DataConstantsEx.MODULE_GROUP_ARRAY)); + elements = retrieveData(elements, ModuleGroup.ARRAY_DATA_KEY.getData(dataContext)); elements = retrieveData(elements, LangDataKeys.MODULE_CONTEXT_ARRAY.getData(dataContext)); - elements = retrieveData(elements, dataContext.getData(DataConstantsEx.LIBRARY_GROUP_ARRAY)); - elements = retrieveData(elements, dataContext.getData(DataConstantsEx.NAMED_LIBRARY_ARRAY)); + elements = retrieveData(elements, LibraryGroupElement.ARRAY_DATA_KEY.getData(dataContext)); + elements = retrieveData(elements, NamedLibraryElement.ARRAY_DATA_KEY.getData(dataContext)); elements = retrieveData(elements, PlatformDataKeys.VIRTUAL_FILE.getData(dataContext)); elements = retrieveData(elements, PlatformDataKeys.VIRTUAL_FILE_ARRAY.getData(dataContext)); return elements; diff --git a/platform/lang-impl/src/com/intellij/ide/favoritesTreeView/actions/DeleteAllFavoritesListsButThisAction.java b/platform/lang-impl/src/com/intellij/ide/favoritesTreeView/actions/DeleteAllFavoritesListsButThisAction.java index fb6085893dbc..cc2634acbba2 100644 --- a/platform/lang-impl/src/com/intellij/ide/favoritesTreeView/actions/DeleteAllFavoritesListsButThisAction.java +++ b/platform/lang-impl/src/com/intellij/ide/favoritesTreeView/actions/DeleteAllFavoritesListsButThisAction.java @@ -23,8 +23,8 @@ import com.intellij.openapi.actionSystem.AnAction; import com.intellij.openapi.actionSystem.AnActionEvent; import com.intellij.openapi.actionSystem.DataContext; import com.intellij.openapi.actionSystem.PlatformDataKeys; -import com.intellij.openapi.project.Project; import com.intellij.openapi.project.DumbAware; +import com.intellij.openapi.project.Project; /** * User: anna @@ -42,7 +42,7 @@ public class DeleteAllFavoritesListsButThisAction extends AnAction implements Du return; } FavoritesManager favoritesManager = FavoritesManager.getInstance(project); - String listName = (String)dataContext.getData(FavoritesTreeViewPanel.FAVORITES_LIST_NAME); + String listName = FavoritesTreeViewPanel.FAVORITES_LIST_NAME_DATA_KEY.getData(dataContext); String[] lists = favoritesManager.getAvailableFavoritesLists(); for (String list : lists) { if (!list.equals(listName)) { @@ -58,7 +58,7 @@ public class DeleteAllFavoritesListsButThisAction extends AnAction implements Du e.getPresentation().setEnabled(false); return; } - String listName = (String)dataContext.getData(FavoritesTreeViewPanel.FAVORITES_LIST_NAME); + String listName = FavoritesTreeViewPanel.FAVORITES_LIST_NAME_DATA_KEY.getData(dataContext); e.getPresentation().setEnabled(listName != null); if (listName != null) { e.getPresentation().setText(IdeBundle.message("action.delete.all.favorites.lists.but.this",listName)); diff --git a/platform/lang-impl/src/com/intellij/ide/favoritesTreeView/actions/DeleteFavoritesListAction.java b/platform/lang-impl/src/com/intellij/ide/favoritesTreeView/actions/DeleteFavoritesListAction.java index 699bf45c822f..4e04afe19e45 100644 --- a/platform/lang-impl/src/com/intellij/ide/favoritesTreeView/actions/DeleteFavoritesListAction.java +++ b/platform/lang-impl/src/com/intellij/ide/favoritesTreeView/actions/DeleteFavoritesListAction.java @@ -23,8 +23,8 @@ import com.intellij.openapi.actionSystem.AnAction; import com.intellij.openapi.actionSystem.AnActionEvent; import com.intellij.openapi.actionSystem.DataContext; import com.intellij.openapi.actionSystem.PlatformDataKeys; -import com.intellij.openapi.project.Project; import com.intellij.openapi.project.DumbAware; +import com.intellij.openapi.project.Project; /** * User: anna @@ -32,7 +32,7 @@ import com.intellij.openapi.project.DumbAware; */ public class DeleteFavoritesListAction extends AnAction implements DumbAware { public DeleteFavoritesListAction() { - super(IdeBundle.message("action.delete.favorites.list","")); + super(IdeBundle.message("action.delete.favorites.list", "")); } public void actionPerformed(AnActionEvent e) { @@ -42,22 +42,24 @@ public class DeleteFavoritesListAction extends AnAction implements DumbAware { return; } FavoritesManager favoritesManager = FavoritesManager.getInstance(project); - String listName = (String)dataContext.getData(FavoritesTreeViewPanel.FAVORITES_LIST_NAME); - favoritesManager.removeFavoritesList(listName); + String listName = FavoritesTreeViewPanel.FAVORITES_LIST_NAME_DATA_KEY.getData(dataContext); + if (listName != null) { + favoritesManager.removeFavoritesList(listName); + } } public void update(AnActionEvent e) { final DataContext dataContext = e.getDataContext(); Project project = PlatformDataKeys.PROJECT.getData(dataContext); - if (project == null){ + if (project == null) { e.getPresentation().setEnabled(false); return; } - String listName = (String)dataContext.getData(FavoritesTreeViewPanel.FAVORITES_LIST_NAME); + String listName = FavoritesTreeViewPanel.FAVORITES_LIST_NAME_DATA_KEY.getData(dataContext); e.getPresentation().setEnabled(listName != null && !listName.equals(project.getName())); if (listName != null) { - e.getPresentation().setText(IdeBundle.message("action.delete.favorites.list",listName)); - e.getPresentation().setDescription(IdeBundle.message("action.delete.favorites.list",listName)); + e.getPresentation().setText(IdeBundle.message("action.delete.favorites.list", listName)); + e.getPresentation().setDescription(IdeBundle.message("action.delete.favorites.list", listName)); } } } diff --git a/platform/lang-impl/src/com/intellij/ide/favoritesTreeView/actions/DeleteFromFavoritesAction.java b/platform/lang-impl/src/com/intellij/ide/favoritesTreeView/actions/DeleteFromFavoritesAction.java index 2c357f19a231..ede6f68f4a7e 100644 --- a/platform/lang-impl/src/com/intellij/ide/favoritesTreeView/actions/DeleteFromFavoritesAction.java +++ b/platform/lang-impl/src/com/intellij/ide/favoritesTreeView/actions/DeleteFromFavoritesAction.java @@ -46,8 +46,8 @@ public class DeleteFromFavoritesAction extends AnAction implements DumbAware { return; } FavoritesManager favoritesManager = FavoritesManager.getInstance(project); - FavoritesTreeNodeDescriptor[] roots = (FavoritesTreeNodeDescriptor[])dataContext.getData(FavoritesTreeViewPanel.CONTEXT_FAVORITES_ROOTS); - String listName = (String)dataContext.getData(FavoritesTreeViewPanel.FAVORITES_LIST_NAME); + FavoritesTreeNodeDescriptor[] roots = FavoritesTreeViewPanel.CONTEXT_FAVORITES_ROOTS_DATA_KEY.getData(dataContext); + String listName = FavoritesTreeViewPanel.FAVORITES_LIST_NAME_DATA_KEY.getData(dataContext); assert roots != null; assert listName != null; for (FavoritesTreeNodeDescriptor root : roots) { @@ -64,8 +64,8 @@ public class DeleteFromFavoritesAction extends AnAction implements DumbAware { e.getPresentation().setEnabled(false); return; } - final String listName = (String)dataContext.getData(FavoritesTreeViewPanel.FAVORITES_LIST_NAME); - FavoritesTreeNodeDescriptor[] roots = (FavoritesTreeNodeDescriptor[])dataContext.getData(FavoritesTreeViewPanel.CONTEXT_FAVORITES_ROOTS); + final String listName = FavoritesTreeViewPanel.FAVORITES_LIST_NAME_DATA_KEY.getData(dataContext); + FavoritesTreeNodeDescriptor[] roots = FavoritesTreeViewPanel.CONTEXT_FAVORITES_ROOTS_DATA_KEY.getData(dataContext); e.getPresentation().setEnabled(listName != null && roots != null && roots.length != 0); } } diff --git a/platform/lang-impl/src/com/intellij/ide/favoritesTreeView/actions/RenameFavoritesListAction.java b/platform/lang-impl/src/com/intellij/ide/favoritesTreeView/actions/RenameFavoritesListAction.java index 4e9ff70f6b5e..0c80f8a030f2 100644 --- a/platform/lang-impl/src/com/intellij/ide/favoritesTreeView/actions/RenameFavoritesListAction.java +++ b/platform/lang-impl/src/com/intellij/ide/favoritesTreeView/actions/RenameFavoritesListAction.java @@ -23,8 +23,8 @@ import com.intellij.openapi.actionSystem.AnAction; import com.intellij.openapi.actionSystem.AnActionEvent; import com.intellij.openapi.actionSystem.DataContext; import com.intellij.openapi.actionSystem.PlatformDataKeys; -import com.intellij.openapi.project.Project; import com.intellij.openapi.project.DumbAware; +import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.InputValidator; import com.intellij.openapi.ui.Messages; import com.intellij.openapi.util.IconLoader; @@ -36,8 +36,8 @@ import com.intellij.util.ArrayUtil; */ public class RenameFavoritesListAction extends AnAction implements DumbAware { public RenameFavoritesListAction() { - super(IdeBundle.message("action.rename.favorites.list"), - IdeBundle.message("action.rename.favorites.list"), IconLoader.getIcon("/actions/menu-replace.png")); + super(IdeBundle.message("action.rename.favorites.list"), IdeBundle.message("action.rename.favorites.list"), + IconLoader.getIcon("/actions/menu-replace.png")); } public void actionPerformed(AnActionEvent e) { @@ -47,26 +47,25 @@ public class RenameFavoritesListAction extends AnAction implements DumbAware { return; } final FavoritesManager favoritesManager = FavoritesManager.getInstance(project); - String listName = (String)dataContext.getData(FavoritesTreeViewPanel.FAVORITES_LIST_NAME); - final String newName = Messages.showInputDialog(project, IdeBundle.message("prompt.input.favorites.list.new.name"), - IdeBundle.message("title.rename.favorites.list"), Messages.getInformationIcon(), listName, - new InputValidator() { - public boolean checkInput(String inputString) { - return inputString != null && inputString.trim().length() > 0; - } + String listName = FavoritesTreeViewPanel.FAVORITES_LIST_NAME_DATA_KEY.getData(dataContext); + final String newName = Messages + .showInputDialog(project, IdeBundle.message("prompt.input.favorites.list.new.name"), IdeBundle.message("title.rename.favorites.list"), + Messages.getInformationIcon(), listName, new InputValidator() { + public boolean checkInput(String inputString) { + return inputString != null && inputString.trim().length() > 0; + } - public boolean canClose(String inputString) { - String[] lists = favoritesManager.getAvailableFavoritesLists(); - final boolean isNew = ArrayUtil.find(lists, inputString.trim()) == -1; - if (!isNew) { - Messages.showErrorDialog(project, IdeBundle.message( - "error.favorites.list.already.exists", inputString.trim()), IdeBundle.message( - "title.unable.to.add.favorites.list")); - return false; - } - return inputString.trim().length() > 0; - } - }); + public boolean canClose(String inputString) { + String[] lists = favoritesManager.getAvailableFavoritesLists(); + final boolean isNew = ArrayUtil.find(lists, inputString.trim()) == -1; + if (!isNew) { + Messages.showErrorDialog(project, IdeBundle.message("error.favorites.list.already.exists", inputString.trim()), + IdeBundle.message("title.unable.to.add.favorites.list")); + return false; + } + return inputString.trim().length() > 0; + } + }); if (listName != null && newName != null) { favoritesManager.renameFavoritesList(listName, newName); @@ -76,11 +75,11 @@ public class RenameFavoritesListAction extends AnAction implements DumbAware { public void update(AnActionEvent e) { final DataContext dataContext = e.getDataContext(); Project project = PlatformDataKeys.PROJECT.getData(dataContext); - if (project == null){ + if (project == null) { e.getPresentation().setEnabled(false); return; } - String listName = (String)dataContext.getData(FavoritesTreeViewPanel.FAVORITES_LIST_NAME); + String listName = FavoritesTreeViewPanel.FAVORITES_LIST_NAME_DATA_KEY.getData(dataContext); e.getPresentation().setEnabled(listName != null && !listName.equals(project.getName())); } } diff --git a/platform/lang-impl/src/com/intellij/ide/favoritesTreeView/actions/SendToFavoritesAction.java b/platform/lang-impl/src/com/intellij/ide/favoritesTreeView/actions/SendToFavoritesAction.java index 108f386e2e30..2397b874fd3e 100644 --- a/platform/lang-impl/src/com/intellij/ide/favoritesTreeView/actions/SendToFavoritesAction.java +++ b/platform/lang-impl/src/com/intellij/ide/favoritesTreeView/actions/SendToFavoritesAction.java @@ -44,8 +44,8 @@ public class SendToFavoritesAction extends AnAction{ Project project = PlatformDataKeys.PROJECT.getData(dataContext); final FavoritesManager favoritesManager = FavoritesManager.getInstance(project); - FavoritesTreeNodeDescriptor[] roots = (FavoritesTreeNodeDescriptor[])dataContext.getData(FavoritesTreeViewPanel.CONTEXT_FAVORITES_ROOTS); - String listName = (String)dataContext.getData(FavoritesTreeViewPanel.FAVORITES_LIST_NAME); + FavoritesTreeNodeDescriptor[] roots = FavoritesTreeViewPanel.CONTEXT_FAVORITES_ROOTS_DATA_KEY.getData(dataContext); + String listName = FavoritesTreeViewPanel.FAVORITES_LIST_NAME_DATA_KEY.getData(dataContext); doSend(favoritesManager, roots, listName); } @@ -66,13 +66,13 @@ public class SendToFavoritesAction extends AnAction{ e.getPresentation().setEnabled(false); return; } - FavoritesTreeNodeDescriptor[] roots = (FavoritesTreeNodeDescriptor[])dataContext.getData(FavoritesTreeViewPanel.CONTEXT_FAVORITES_ROOTS); + FavoritesTreeNodeDescriptor[] roots = FavoritesTreeViewPanel.CONTEXT_FAVORITES_ROOTS_DATA_KEY.getData(dataContext); if (roots == null || roots.length == 0) { e.getPresentation().setEnabled(false); return; } - String listName = (String)dataContext.getData(FavoritesTreeViewPanel.FAVORITES_LIST_NAME); + String listName = FavoritesTreeViewPanel.FAVORITES_LIST_NAME_DATA_KEY.getData(dataContext); e.getPresentation().setEnabled(listName != null); } } diff --git a/platform/lang-impl/src/com/intellij/ide/favoritesTreeView/actions/SendToFavoritesGroup.java b/platform/lang-impl/src/com/intellij/ide/favoritesTreeView/actions/SendToFavoritesGroup.java index 3d45c87ef31b..3f00e755e1fa 100644 --- a/platform/lang-impl/src/com/intellij/ide/favoritesTreeView/actions/SendToFavoritesGroup.java +++ b/platform/lang-impl/src/com/intellij/ide/favoritesTreeView/actions/SendToFavoritesGroup.java @@ -22,6 +22,7 @@ import com.intellij.ide.favoritesTreeView.FavoritesTreeNodeDescriptor; import com.intellij.ide.favoritesTreeView.FavoritesTreeViewPanel; import com.intellij.openapi.actionSystem.*; import com.intellij.openapi.project.Project; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.util.ArrayList; @@ -32,19 +33,19 @@ import java.util.List; * Date: Feb 24, 2005 */ public class SendToFavoritesGroup extends ActionGroup{ - + @NotNull public AnAction[] getChildren(@Nullable AnActionEvent e) { - if (e == null) return AnAction.EMPTY_ARRAY; + if (e == null) return EMPTY_ARRAY; final Project project = PlatformDataKeys.PROJECT.getData(e.getDataContext()); if (project == null){ - return AnAction.EMPTY_ARRAY; + return EMPTY_ARRAY; } final FavoritesManager favoritesManager = FavoritesManager.getInstance(project); final DataContext dataContext = e.getDataContext(); - FavoritesTreeNodeDescriptor[] roots = (FavoritesTreeNodeDescriptor[])dataContext.getData(FavoritesTreeViewPanel.CONTEXT_FAVORITES_ROOTS); - String listName = (String)dataContext.getData(FavoritesTreeViewPanel.FAVORITES_LIST_NAME); + FavoritesTreeNodeDescriptor[] roots = FavoritesTreeViewPanel.CONTEXT_FAVORITES_ROOTS_DATA_KEY.getData(dataContext); + String listName = FavoritesTreeViewPanel.FAVORITES_LIST_NAME_DATA_KEY.getData(dataContext); if (roots == null || roots.length == 0 || listName == null) { - return AnAction.EMPTY_ARRAY; + return EMPTY_ARRAY; } final String[] allLists = favoritesManager.getAvailableFavoritesLists(); @@ -70,8 +71,8 @@ public class SendToFavoritesGroup extends ActionGroup{ public void actionPerformed(AnActionEvent e) { final DataContext dataContext = e.getDataContext(); Project project = PlatformDataKeys.PROJECT.getData(dataContext); - FavoritesTreeNodeDescriptor[] roots = (FavoritesTreeNodeDescriptor[])dataContext.getData(FavoritesTreeViewPanel.CONTEXT_FAVORITES_ROOTS); - String listName = (String)dataContext.getData(FavoritesTreeViewPanel.FAVORITES_LIST_NAME); + FavoritesTreeNodeDescriptor[] roots = FavoritesTreeViewPanel.CONTEXT_FAVORITES_ROOTS_DATA_KEY.getData(dataContext); + String listName = FavoritesTreeViewPanel.FAVORITES_LIST_NAME_DATA_KEY.getData(dataContext); String newName = AddNewFavoritesListAction.doAddNewFavoritesList(project); if (newName != null) { diff --git a/platform/lang-impl/src/com/intellij/ide/hierarchy/ChangeViewTypeActionBase.java b/platform/lang-impl/src/com/intellij/ide/hierarchy/ChangeViewTypeActionBase.java index 33a5c77e99f6..7aef0d2d3275 100644 --- a/platform/lang-impl/src/com/intellij/ide/hierarchy/ChangeViewTypeActionBase.java +++ b/platform/lang-impl/src/com/intellij/ide/hierarchy/ChangeViewTypeActionBase.java @@ -62,6 +62,6 @@ abstract class ChangeViewTypeActionBase extends ToggleAction { } protected static TypeHierarchyBrowserBase getTypeHierarchyBrowser(final DataContext context) { - return (TypeHierarchyBrowserBase)context.getData(TypeHierarchyBrowserBase.TYPE_HIERARCHY_BROWSER_DATA_KEY); + return TypeHierarchyBrowserBase.DATA_KEY.getData(context); } } diff --git a/platform/lang-impl/src/com/intellij/ide/hierarchy/HierarchyBrowserBase.java b/platform/lang-impl/src/com/intellij/ide/hierarchy/HierarchyBrowserBase.java index bdf841406801..704a3c3f9077 100644 --- a/platform/lang-impl/src/com/intellij/ide/hierarchy/HierarchyBrowserBase.java +++ b/platform/lang-impl/src/com/intellij/ide/hierarchy/HierarchyBrowserBase.java @@ -19,17 +19,17 @@ package com.intellij.ide.hierarchy; import com.intellij.ide.actions.CloseTabToolbarAction; import com.intellij.ide.actions.ContextHelpAction; import com.intellij.openapi.Disposable; -import com.intellij.openapi.project.Project; import com.intellij.openapi.actionSystem.*; +import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.SimpleToolWindowPanel; import com.intellij.pom.Navigatable; import com.intellij.psi.NavigatablePsiElement; import com.intellij.psi.PsiElement; -import com.intellij.ui.content.Content; -import com.intellij.ui.content.tabs.PinToolwindowTabAction; import com.intellij.ui.AutoScrollToSourceHandler; import com.intellij.ui.TreeSpeedSearch; import com.intellij.ui.TreeToolTipHandler; +import com.intellij.ui.content.Content; +import com.intellij.ui.content.tabs.PinToolwindowTabAction; import com.intellij.ui.treeStructure.Tree; import com.intellij.util.ui.UIUtil; import com.intellij.util.ui.tree.TreeUtil; @@ -194,24 +194,24 @@ public abstract class HierarchyBrowserBase extends SimpleToolWindowPanel impleme @Nullable public Object getData(@NonNls final String dataId) { - if (DataConstants.PSI_ELEMENT.equals(dataId)) { + if (LangDataKeys.PSI_ELEMENT.is(dataId)) { final PsiElement anElement = getSelectedElement(); return anElement != null && anElement.isValid() ? anElement : null; } - if (DataConstants.PSI_ELEMENT_ARRAY.equals(dataId)) { + if (LangDataKeys.PSI_ELEMENT_ARRAY.is(dataId)) { return getSelectedElements(); } - if (DataConstants.DELETE_ELEMENT_PROVIDER.equals(dataId)) { + if (PlatformDataKeys.DELETE_ELEMENT_PROVIDER.is(dataId)) { return null; } - if (DataConstants.NAVIGATABLE.equals(dataId)) { + if (PlatformDataKeys.NAVIGATABLE.is(dataId)) { final DefaultMutableTreeNode selectedNode = getSelectedNode(); if (selectedNode == null) return null; final HierarchyNodeDescriptor descriptor = getDescriptor(selectedNode); if (descriptor == null) return null; return getNavigatable(descriptor); } - if (DataConstants.NAVIGATABLE_ARRAY.equals(dataId)) { + if (PlatformDataKeys.NAVIGATABLE_ARRAY.is(dataId)) { return getNavigatables(); } return null; diff --git a/platform/lang-impl/src/com/intellij/ide/hierarchy/HierarchyBrowserBaseEx.java b/platform/lang-impl/src/com/intellij/ide/hierarchy/HierarchyBrowserBaseEx.java index ecaa852c2ac4..849f76b32721 100644 --- a/platform/lang-impl/src/com/intellij/ide/hierarchy/HierarchyBrowserBaseEx.java +++ b/platform/lang-impl/src/com/intellij/ide/hierarchy/HierarchyBrowserBaseEx.java @@ -55,6 +55,7 @@ import javax.swing.tree.TreeNode; import java.awt.*; import java.text.MessageFormat; import java.util.*; +import java.util.List; public abstract class HierarchyBrowserBaseEx extends HierarchyBrowserBase implements OccurenceNavigator { @@ -74,7 +75,7 @@ public abstract class HierarchyBrowserBaseEx extends HierarchyBrowserBase implem private boolean myCachedIsValidBase = false; - private final java.util.List myRunOnDisposeList = new ArrayList(); + private final List myRunOnDisposeList = new ArrayList(); private final HashMap myOccurrenceNavigators = new HashMap(); private static final OccurenceNavigator EMPTY_NAVIGATOR = new OccurenceNavigator() { @@ -401,7 +402,7 @@ public abstract class HierarchyBrowserBaseEx extends HierarchyBrowserBase implem if (getBrowserDataKey().equals(dataId)) { return this; } - else if (DataConstants.HELP_ID.equals(dataId)) { + else if (PlatformDataKeys.HELP_ID.is(dataId)) { return HELP_ID; } return super.getData(dataId); diff --git a/platform/lang-impl/src/com/intellij/ide/hierarchy/MethodHierarchyBrowserBase.java b/platform/lang-impl/src/com/intellij/ide/hierarchy/MethodHierarchyBrowserBase.java index 435090347d35..2602895c0b20 100644 --- a/platform/lang-impl/src/com/intellij/ide/hierarchy/MethodHierarchyBrowserBase.java +++ b/platform/lang-impl/src/com/intellij/ide/hierarchy/MethodHierarchyBrowserBase.java @@ -34,7 +34,8 @@ public abstract class MethodHierarchyBrowserBase extends HierarchyBrowserBaseEx @SuppressWarnings({"UnresolvedPropertyKey"}) public static final String METHOD_TYPE = IdeBundle.message("title.hierarchy.method"); - @NonNls public static final String METHOD_HIERARCHY_BROWSER_DATA_KEY = "com.intellij.ide.hierarchy.MethodHierarchyBrowserBase"; + public static final DataKey DATA_KEY = DataKey.create("com.intellij.ide.hierarchy.MethodHierarchyBrowserBase"); + @Deprecated @NonNls public static final String METHOD_HIERARCHY_BROWSER_DATA_KEY = DATA_KEY.getName(); public MethodHierarchyBrowserBase(final Project project, final PsiElement method) { super(project, method); @@ -87,7 +88,7 @@ public abstract class MethodHierarchyBrowserBase extends HierarchyBrowserBaseEx @NotNull protected String getBrowserDataKey() { - return METHOD_HIERARCHY_BROWSER_DATA_KEY; + return DATA_KEY.getName(); } @NotNull @@ -125,7 +126,7 @@ public abstract class MethodHierarchyBrowserBase extends HierarchyBrowserBaseEx public static class BaseOnThisMethodAction extends BaseOnThisElementAction { public BaseOnThisMethodAction() { - super(IdeBundle.message("action.base.on.this.method"), IdeActions.ACTION_METHOD_HIERARCHY, METHOD_HIERARCHY_BROWSER_DATA_KEY); + super(IdeBundle.message("action.base.on.this.method"), IdeActions.ACTION_METHOD_HIERARCHY, DATA_KEY.getName()); } } diff --git a/platform/lang-impl/src/com/intellij/ide/hierarchy/TypeHierarchyBrowserBase.java b/platform/lang-impl/src/com/intellij/ide/hierarchy/TypeHierarchyBrowserBase.java index c2ac2c194a74..ae4f8b9eba5a 100644 --- a/platform/lang-impl/src/com/intellij/ide/hierarchy/TypeHierarchyBrowserBase.java +++ b/platform/lang-impl/src/com/intellij/ide/hierarchy/TypeHierarchyBrowserBase.java @@ -39,7 +39,8 @@ public abstract class TypeHierarchyBrowserBase extends HierarchyBrowserBaseEx { private final MyDeleteProvider myDeleteElementProvider = new MyDeleteProvider(); - public static final String TYPE_HIERARCHY_BROWSER_DATA_KEY = "com.intellij.ide.hierarchy.TypeHierarchyBrowserBase"; + public static final DataKey DATA_KEY = DataKey.create("com.intellij.ide.hierarchy.TypeHierarchyBrowserBase"); + @Deprecated public static final String TYPE_HIERARCHY_BROWSER_DATA_KEY = DATA_KEY.getName(); public TypeHierarchyBrowserBase(final Project project, final PsiElement element) { super(project, element); @@ -70,7 +71,7 @@ public abstract class TypeHierarchyBrowserBase extends HierarchyBrowserBaseEx { @NotNull protected String getBrowserDataKey() { - return TYPE_HIERARCHY_BROWSER_DATA_KEY; + return DATA_KEY.getName(); } @NotNull @@ -79,7 +80,7 @@ public abstract class TypeHierarchyBrowserBase extends HierarchyBrowserBaseEx { } public final Object getData(final String dataId) { - if (DataConstants.DELETE_ELEMENT_PROVIDER.equals(dataId)) { + if (PlatformDataKeys.DELETE_ELEMENT_PROVIDER.is(dataId)) { return myDeleteElementProvider; } return super.getData(dataId); @@ -123,7 +124,7 @@ public abstract class TypeHierarchyBrowserBase extends HierarchyBrowserBaseEx { protected static class BaseOnThisTypeAction extends BaseOnThisElementAction { public BaseOnThisTypeAction() { - super("", IdeActions.ACTION_TYPE_HIERARCHY, TYPE_HIERARCHY_BROWSER_DATA_KEY); + super("", IdeActions.ACTION_TYPE_HIERARCHY, DATA_KEY.getName()); } @Override diff --git a/platform/lang-impl/src/com/intellij/ide/impl/dataRules/ModuleRule.java b/platform/lang-impl/src/com/intellij/ide/impl/dataRules/ModuleRule.java index 991f34c4cac2..50b9803f90d9 100644 --- a/platform/lang-impl/src/com/intellij/ide/impl/dataRules/ModuleRule.java +++ b/platform/lang-impl/src/com/intellij/ide/impl/dataRules/ModuleRule.java @@ -18,8 +18,9 @@ package com.intellij.ide.impl.dataRules; import com.intellij.ide.DataManager; import com.intellij.ide.impl.DataManagerImpl; -import com.intellij.openapi.actionSystem.DataConstants; import com.intellij.openapi.actionSystem.DataProvider; +import com.intellij.openapi.actionSystem.LangDataKeys; +import com.intellij.openapi.actionSystem.PlatformDataKeys; import com.intellij.openapi.module.ModuleUtil; import com.intellij.openapi.project.Project; import com.intellij.openapi.vfs.VirtualFile; @@ -31,20 +32,20 @@ import com.intellij.psi.PsiElement; */ public class ModuleRule implements GetDataRule { public Object getData(DataProvider dataProvider) { - Object moduleContext = dataProvider.getData(DataConstants.MODULE_CONTEXT); + Object moduleContext = LangDataKeys.MODULE_CONTEXT.getData(dataProvider); if (moduleContext != null) { return moduleContext; } - Project project = (Project)dataProvider.getData(DataConstants.PROJECT); + Project project = PlatformDataKeys.PROJECT.getData(dataProvider); if (project == null) { - PsiElement element = (PsiElement)dataProvider.getData(DataConstants.PSI_ELEMENT); + PsiElement element = LangDataKeys.PSI_ELEMENT.getData(dataProvider); if (element == null || !element.isValid()) return null; project = element.getProject(); } - VirtualFile virtualFile = (VirtualFile)dataProvider.getData(DataConstants.VIRTUAL_FILE); + VirtualFile virtualFile = PlatformDataKeys.VIRTUAL_FILE.getData(dataProvider); if (virtualFile == null) { - GetDataRule dataRule = ((DataManagerImpl)DataManager.getInstance()).getDataRule(DataConstants.VIRTUAL_FILE); + GetDataRule dataRule = ((DataManagerImpl)DataManager.getInstance()).getDataRule(PlatformDataKeys.VIRTUAL_FILE.getName()); if (dataRule != null) { virtualFile = (VirtualFile)dataRule.getData(dataProvider); } diff --git a/platform/lang-impl/src/com/intellij/ide/impl/dataRules/NavigatableRule.java b/platform/lang-impl/src/com/intellij/ide/impl/dataRules/NavigatableRule.java index 2d604a21caf0..91daabb008c9 100644 --- a/platform/lang-impl/src/com/intellij/ide/impl/dataRules/NavigatableRule.java +++ b/platform/lang-impl/src/com/intellij/ide/impl/dataRules/NavigatableRule.java @@ -17,25 +17,30 @@ package com.intellij.ide.impl.dataRules; import com.intellij.ide.util.EditSourceUtil; -import com.intellij.openapi.actionSystem.DataConstants; import com.intellij.openapi.actionSystem.DataProvider; +import com.intellij.openapi.actionSystem.LangDataKeys; +import com.intellij.openapi.actionSystem.PlatformDataKeys; import com.intellij.openapi.fileEditor.OpenFileDescriptor; import com.intellij.pom.Navigatable; import com.intellij.psi.PsiElement; public class NavigatableRule implements GetDataRule { public Object getData(DataProvider dataProvider) { - final OpenFileDescriptor openFileDescriptor = (OpenFileDescriptor)dataProvider.getData(DataConstants.OPEN_FILE_DESCRIPTOR); - if (openFileDescriptor != null && openFileDescriptor.getFile().isValid()) { - return openFileDescriptor; + final Navigatable navigatable = PlatformDataKeys.NAVIGATABLE.getData(dataProvider); + if (navigatable != null && navigatable instanceof OpenFileDescriptor) { + final OpenFileDescriptor openFileDescriptor = (OpenFileDescriptor)navigatable; + + if (openFileDescriptor.getFile().isValid()) { + return openFileDescriptor; + } } - final PsiElement element = (PsiElement)dataProvider.getData(DataConstants.PSI_ELEMENT); + final PsiElement element = LangDataKeys.PSI_ELEMENT.getData(dataProvider); if (element != null) { return EditSourceUtil.getDescriptor(element); } - final Object selection = dataProvider.getData(DataConstants.SELECTED_ITEM); + final Object selection = PlatformDataKeys.SELECTED_ITEM.getData(dataProvider); if (selection instanceof Navigatable) { return selection; } diff --git a/platform/lang-impl/src/com/intellij/ide/impl/dataRules/PasteTargetRule.java b/platform/lang-impl/src/com/intellij/ide/impl/dataRules/PasteTargetRule.java index d171a3e6734d..edd827fc64b8 100644 --- a/platform/lang-impl/src/com/intellij/ide/impl/dataRules/PasteTargetRule.java +++ b/platform/lang-impl/src/com/intellij/ide/impl/dataRules/PasteTargetRule.java @@ -16,12 +16,11 @@ package com.intellij.ide.impl.dataRules; -import com.intellij.openapi.actionSystem.DataConstants; import com.intellij.openapi.actionSystem.DataProvider; +import com.intellij.openapi.actionSystem.LangDataKeys; public class PasteTargetRule implements GetDataRule { public Object getData(DataProvider dataProvider) { - Object data = dataProvider.getData(DataConstants.PSI_ELEMENT); - return data; + return LangDataKeys.PSI_ELEMENT.getData(dataProvider); } } diff --git a/platform/lang-impl/src/com/intellij/ide/impl/dataRules/PsiElementFromSelectionRule.java b/platform/lang-impl/src/com/intellij/ide/impl/dataRules/PsiElementFromSelectionRule.java index 10177a2cb6ae..66290683fbda 100644 --- a/platform/lang-impl/src/com/intellij/ide/impl/dataRules/PsiElementFromSelectionRule.java +++ b/platform/lang-impl/src/com/intellij/ide/impl/dataRules/PsiElementFromSelectionRule.java @@ -16,13 +16,13 @@ package com.intellij.ide.impl.dataRules; -import com.intellij.openapi.actionSystem.DataConstants; import com.intellij.openapi.actionSystem.DataProvider; +import com.intellij.openapi.actionSystem.PlatformDataKeys; import com.intellij.psi.PsiElement; public class PsiElementFromSelectionRule implements GetDataRule { public Object getData(DataProvider dataProvider) { - final Object element = dataProvider.getData(DataConstants.SELECTED_ITEM); + final Object element = dataProvider.getData(PlatformDataKeys.SELECTED_ITEM.getName()); if (element instanceof PsiElement) { PsiElement psiElement = (PsiElement)element; if (psiElement.isValid()) { @@ -32,4 +32,4 @@ public class PsiElementFromSelectionRule implements GetDataRule { return null; } -} \ No newline at end of file +} diff --git a/platform/lang-impl/src/com/intellij/ide/impl/dataRules/PsiFileRule.java b/platform/lang-impl/src/com/intellij/ide/impl/dataRules/PsiFileRule.java index b9a969eb4c82..198908f7d1c1 100644 --- a/platform/lang-impl/src/com/intellij/ide/impl/dataRules/PsiFileRule.java +++ b/platform/lang-impl/src/com/intellij/ide/impl/dataRules/PsiFileRule.java @@ -16,8 +16,9 @@ package com.intellij.ide.impl.dataRules; -import com.intellij.openapi.actionSystem.DataConstants; import com.intellij.openapi.actionSystem.DataProvider; +import com.intellij.openapi.actionSystem.LangDataKeys; +import com.intellij.openapi.actionSystem.PlatformDataKeys; import com.intellij.openapi.project.Project; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.PsiElement; @@ -25,14 +26,14 @@ import com.intellij.psi.PsiManager; public class PsiFileRule implements GetDataRule { public Object getData(DataProvider dataProvider) { - final PsiElement element = (PsiElement)dataProvider.getData(DataConstants.PSI_ELEMENT); - if (element != null){ + final PsiElement element = LangDataKeys.PSI_ELEMENT.getData(dataProvider); + if (element != null) { return element.getContainingFile(); } - Project project = (Project)dataProvider.getData(DataConstants.PROJECT); - if (project != null){ - VirtualFile vFile = (VirtualFile)dataProvider.getData(DataConstants.VIRTUAL_FILE); - if (vFile != null){ + Project project = PlatformDataKeys.PROJECT.getData(dataProvider); + if (project != null) { + VirtualFile vFile = PlatformDataKeys.VIRTUAL_FILE.getData(dataProvider); + if (vFile != null) { return PsiManager.getInstance(project).findFile(vFile); } } diff --git a/platform/lang-impl/src/com/intellij/ide/impl/dataRules/VirtualFileArrayRule.java b/platform/lang-impl/src/com/intellij/ide/impl/dataRules/VirtualFileArrayRule.java index e37cb5dc9351..f124f54e4491 100644 --- a/platform/lang-impl/src/com/intellij/ide/impl/dataRules/VirtualFileArrayRule.java +++ b/platform/lang-impl/src/com/intellij/ide/impl/dataRules/VirtualFileArrayRule.java @@ -16,15 +16,19 @@ package com.intellij.ide.impl.dataRules; -import com.intellij.openapi.actionSystem.DataConstants; import com.intellij.openapi.actionSystem.DataProvider; +import com.intellij.openapi.actionSystem.LangDataKeys; +import com.intellij.openapi.actionSystem.PlatformDataKeys; import com.intellij.openapi.module.Module; import com.intellij.openapi.project.Project; import com.intellij.openapi.roots.ModuleRootManager; import com.intellij.openapi.roots.ProjectRootManager; import com.intellij.openapi.vfs.VfsUtil; import com.intellij.openapi.vfs.VirtualFile; -import com.intellij.psi.*; +import com.intellij.psi.PsiDirectory; +import com.intellij.psi.PsiDirectoryContainer; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiFile; import com.intellij.usages.Usage; import com.intellij.usages.UsageTarget; import com.intellij.usages.UsageView; @@ -40,46 +44,46 @@ public class VirtualFileArrayRule implements GetDataRule { public Object getData(final DataProvider dataProvider) { // Try to detect multiselection. - Project project = (Project)dataProvider.getData(DataConstants.PROJECT_CONTEXT); + Project project = PlatformDataKeys.PROJECT_CONTEXT.getData(dataProvider); if (project != null && !project.isDisposed()) { return ProjectRootManager.getInstance(project).getContentRoots(); } - Module[] selectedModules = (Module[])dataProvider.getData(DataConstants.MODULE_CONTEXT_ARRAY); + Module[] selectedModules = LangDataKeys.MODULE_CONTEXT_ARRAY.getData(dataProvider); if (selectedModules != null && selectedModules.length > 0) { return getFilesFromModules(selectedModules); } - Module selectedModule = (Module)dataProvider.getData(DataConstants.MODULE_CONTEXT); + Module selectedModule = LangDataKeys.MODULE_CONTEXT.getData(dataProvider); if (selectedModule != null && !selectedModule.isDisposed()) { return ModuleRootManager.getInstance(selectedModule).getContentRoots(); } - PsiElement[] psiElements = (PsiElement[])dataProvider.getData(DataConstants.PSI_ELEMENT_ARRAY); + PsiElement[] psiElements = LangDataKeys.PSI_ELEMENT_ARRAY.getData(dataProvider); if (psiElements != null && psiElements.length != 0) { return getFilesFromPsiElements(psiElements); } // VirtualFile -> VirtualFile[] - VirtualFile vFile = (VirtualFile)dataProvider.getData(DataConstants.VIRTUAL_FILE); + VirtualFile vFile = PlatformDataKeys.VIRTUAL_FILE.getData(dataProvider); if (vFile != null) { return new VirtualFile[]{vFile}; } // - PsiFile psiFile = (PsiFile)dataProvider.getData(DataConstants.PSI_FILE); + PsiFile psiFile = LangDataKeys.PSI_FILE.getData(dataProvider); if (psiFile != null && psiFile.getVirtualFile() != null) { return new VirtualFile[]{psiFile.getVirtualFile()}; } - PsiElement elem = (PsiElement)dataProvider.getData(DataConstants.PSI_ELEMENT); + PsiElement elem = LangDataKeys.PSI_ELEMENT.getData(dataProvider); if (elem != null) { return getFilesFromPsiElement(elem); } - Usage[] usages = (Usage[])dataProvider.getData(UsageView.USAGES); - UsageTarget[] usageTargets = (UsageTarget[])dataProvider.getData(UsageView.USAGE_TARGETS); + Usage[] usages = UsageView.USAGES_KEY.getData(dataProvider); + UsageTarget[] usageTargets = UsageView.USAGE_TARGETS_KEY.getData(dataProvider); if (usages != null || usageTargets != null) { return getFilesFromUsages(usages, usageTargets); } diff --git a/platform/lang-impl/src/com/intellij/ide/impl/dataRules/VirtualFileRule.java b/platform/lang-impl/src/com/intellij/ide/impl/dataRules/VirtualFileRule.java index e3e8fbb3a71f..95d4eeb78349 100644 --- a/platform/lang-impl/src/com/intellij/ide/impl/dataRules/VirtualFileRule.java +++ b/platform/lang-impl/src/com/intellij/ide/impl/dataRules/VirtualFileRule.java @@ -16,8 +16,9 @@ package com.intellij.ide.impl.dataRules; -import com.intellij.openapi.actionSystem.DataConstants; import com.intellij.openapi.actionSystem.DataProvider; +import com.intellij.openapi.actionSystem.LangDataKeys; +import com.intellij.openapi.actionSystem.PlatformDataKeys; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiFile; @@ -26,7 +27,7 @@ import com.intellij.psi.util.PsiUtilBase; public class VirtualFileRule implements GetDataRule { public Object getData(final DataProvider dataProvider) { // Try to detect multiselection. - PsiElement[] psiElements = (PsiElement[])dataProvider.getData(DataConstants.PSI_ELEMENT_ARRAY); + PsiElement[] psiElements = LangDataKeys.PSI_ELEMENT_ARRAY.getData(dataProvider); if (psiElements != null) { for (PsiElement elem : psiElements) { VirtualFile virtualFile = PsiUtilBase.getVirtualFile(elem); @@ -34,16 +35,16 @@ public class VirtualFileRule implements GetDataRule { } } - VirtualFile[] virtualFiles = (VirtualFile[])dataProvider.getData(DataConstants.VIRTUAL_FILE_ARRAY); + VirtualFile[] virtualFiles = PlatformDataKeys.VIRTUAL_FILE_ARRAY.getData(dataProvider); if (virtualFiles != null && virtualFiles.length == 1) { return virtualFiles[0]; } - PsiFile psiFile = (PsiFile)dataProvider.getData(DataConstants.PSI_FILE); + PsiFile psiFile = LangDataKeys.PSI_FILE.getData(dataProvider); if (psiFile != null) { return psiFile.getVirtualFile(); } - PsiElement elem = (PsiElement)dataProvider.getData(DataConstants.PSI_ELEMENT); + PsiElement elem = LangDataKeys.PSI_ELEMENT.getData(dataProvider); if (elem == null) { return null; } diff --git a/platform/lang-impl/src/com/intellij/ide/macro/FileDirRelativeToProjectRootMacro.java b/platform/lang-impl/src/com/intellij/ide/macro/FileDirRelativeToProjectRootMacro.java index 45db0fe1bb0c..50e67ae8e975 100644 --- a/platform/lang-impl/src/com/intellij/ide/macro/FileDirRelativeToProjectRootMacro.java +++ b/platform/lang-impl/src/com/intellij/ide/macro/FileDirRelativeToProjectRootMacro.java @@ -17,7 +17,6 @@ package com.intellij.ide.macro; import com.intellij.ide.IdeBundle; -import com.intellij.openapi.actionSystem.DataConstants; import com.intellij.openapi.actionSystem.DataContext; import com.intellij.openapi.actionSystem.PlatformDataKeys; import com.intellij.openapi.project.Project; @@ -36,16 +35,24 @@ public class FileDirRelativeToProjectRootMacro extends Macro { public String expand(final DataContext dataContext) { final Project project = PlatformDataKeys.PROJECT.getData(dataContext); - if (project == null) return null; - VirtualFile file = (VirtualFile)dataContext.getData(DataConstants.VIRTUAL_FILE); - if (file == null) return null; + if (project == null) { + return null; + } + VirtualFile file = PlatformDataKeys.VIRTUAL_FILE.getData(dataContext); + if (file == null) { + return null; + } if (!file.isDirectory()) { file = file.getParent(); - if (file == null) return null; + if (file == null) { + return null; + } } final VirtualFile contentRoot = ProjectRootManager.getInstance(project).getFileIndex().getContentRootForFile(file); - if (contentRoot == null) return null; + if (contentRoot == null) { + return null; + } return FileUtil.getRelativePath(getIOFile(contentRoot), getIOFile(file)); } } diff --git a/platform/lang-impl/src/com/intellij/ide/macro/FileDirRelativeToSourcepathMacro.java b/platform/lang-impl/src/com/intellij/ide/macro/FileDirRelativeToSourcepathMacro.java index d3dcb9dbe36d..9bc235915a8e 100644 --- a/platform/lang-impl/src/com/intellij/ide/macro/FileDirRelativeToSourcepathMacro.java +++ b/platform/lang-impl/src/com/intellij/ide/macro/FileDirRelativeToSourcepathMacro.java @@ -17,7 +17,6 @@ package com.intellij.ide.macro; import com.intellij.ide.IdeBundle; -import com.intellij.openapi.actionSystem.DataConstants; import com.intellij.openapi.actionSystem.DataContext; import com.intellij.openapi.actionSystem.PlatformDataKeys; import com.intellij.openapi.project.Project; @@ -36,12 +35,18 @@ public class FileDirRelativeToSourcepathMacro extends Macro { public String expand(final DataContext dataContext) { final Project project = PlatformDataKeys.PROJECT.getData(dataContext); - if (project == null) return null; - VirtualFile file = (VirtualFile)dataContext.getData(DataConstants.VIRTUAL_FILE); - if (file == null) return null; + if (project == null) { + return null; + } + VirtualFile file = PlatformDataKeys.VIRTUAL_FILE.getData(dataContext); + if (file == null) { + return null; + } if (!file.isDirectory()) { file = file.getParent(); - if (file == null) return null; + if (file == null) { + return null; + } } final VirtualFile sourceRoot = ProjectRootManager.getInstance(project).getFileIndex().getSourceRootForFile(file); if (sourceRoot == null) return null; diff --git a/platform/lang-impl/src/com/intellij/ide/macro/FileExtMacro.java b/platform/lang-impl/src/com/intellij/ide/macro/FileExtMacro.java index dc267fa37a13..a875a40fd717 100644 --- a/platform/lang-impl/src/com/intellij/ide/macro/FileExtMacro.java +++ b/platform/lang-impl/src/com/intellij/ide/macro/FileExtMacro.java @@ -17,8 +17,8 @@ package com.intellij.ide.macro; import com.intellij.ide.IdeBundle; -import com.intellij.openapi.actionSystem.DataConstants; import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.actionSystem.PlatformDataKeys; import com.intellij.openapi.vfs.VirtualFile; public final class FileExtMacro extends Macro { @@ -31,8 +31,10 @@ public final class FileExtMacro extends Macro { } public String expand(DataContext dataContext) { - VirtualFile file = (VirtualFile)dataContext.getData(DataConstants.VIRTUAL_FILE); - if (file == null ) return null; + VirtualFile file = PlatformDataKeys.VIRTUAL_FILE.getData(dataContext); + if (file == null) { + return null; + } return file.getExtension(); } } diff --git a/platform/lang-impl/src/com/intellij/ide/macro/FileNameWithoutExtension.java b/platform/lang-impl/src/com/intellij/ide/macro/FileNameWithoutExtension.java index cdf97136a2f0..c880d25e6901 100644 --- a/platform/lang-impl/src/com/intellij/ide/macro/FileNameWithoutExtension.java +++ b/platform/lang-impl/src/com/intellij/ide/macro/FileNameWithoutExtension.java @@ -17,8 +17,8 @@ package com.intellij.ide.macro; import com.intellij.ide.IdeBundle; -import com.intellij.openapi.actionSystem.DataConstants; import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.actionSystem.PlatformDataKeys; import com.intellij.openapi.vfs.VirtualFile; @@ -32,8 +32,10 @@ public final class FileNameWithoutExtension extends FileNameMacro { } public String expand(DataContext dataContext) { - VirtualFile file = (VirtualFile)dataContext.getData(DataConstants.VIRTUAL_FILE); - if (file == null) return null; + VirtualFile file = PlatformDataKeys.VIRTUAL_FILE.getData(dataContext); + if (file == null) { + return null; + } return file.getNameWithoutExtension(); } } \ No newline at end of file diff --git a/platform/lang-impl/src/com/intellij/ide/macro/FilePathRelativeToProjectRootMacro.java b/platform/lang-impl/src/com/intellij/ide/macro/FilePathRelativeToProjectRootMacro.java index 357140e7504f..6b8cb6d5b7e4 100644 --- a/platform/lang-impl/src/com/intellij/ide/macro/FilePathRelativeToProjectRootMacro.java +++ b/platform/lang-impl/src/com/intellij/ide/macro/FilePathRelativeToProjectRootMacro.java @@ -17,7 +17,6 @@ package com.intellij.ide.macro; import com.intellij.ide.IdeBundle; -import com.intellij.openapi.actionSystem.DataConstants; import com.intellij.openapi.actionSystem.DataContext; import com.intellij.openapi.actionSystem.PlatformDataKeys; import com.intellij.openapi.project.Project; @@ -36,11 +35,17 @@ public class FilePathRelativeToProjectRootMacro extends Macro { public String expand(final DataContext dataContext) { final Project project = PlatformDataKeys.PROJECT.getData(dataContext); - if (project == null) return null; - VirtualFile file = (VirtualFile)dataContext.getData(DataConstants.VIRTUAL_FILE); - if (file == null) return null; + if (project == null) { + return null; + } + VirtualFile file = PlatformDataKeys.VIRTUAL_FILE.getData(dataContext); + if (file == null) { + return null; + } final VirtualFile contentRoot = ProjectRootManager.getInstance(project).getFileIndex().getContentRootForFile(file); - if (contentRoot == null) return null; + if (contentRoot == null) { + return null; + } return FileUtil.getRelativePath(getIOFile(contentRoot), getIOFile(file)); } } diff --git a/platform/lang-impl/src/com/intellij/ide/macro/FilePathRelativeToSourcepathMacro.java b/platform/lang-impl/src/com/intellij/ide/macro/FilePathRelativeToSourcepathMacro.java index 3b0e4d06477a..3c72e9dff462 100644 --- a/platform/lang-impl/src/com/intellij/ide/macro/FilePathRelativeToSourcepathMacro.java +++ b/platform/lang-impl/src/com/intellij/ide/macro/FilePathRelativeToSourcepathMacro.java @@ -17,7 +17,6 @@ package com.intellij.ide.macro; import com.intellij.ide.IdeBundle; -import com.intellij.openapi.actionSystem.DataConstants; import com.intellij.openapi.actionSystem.DataContext; import com.intellij.openapi.actionSystem.PlatformDataKeys; import com.intellij.openapi.project.Project; @@ -36,11 +35,17 @@ public class FilePathRelativeToSourcepathMacro extends Macro { public String expand(final DataContext dataContext) { final Project project = PlatformDataKeys.PROJECT.getData(dataContext); - if (project == null) return null; - VirtualFile file = (VirtualFile)dataContext.getData(DataConstants.VIRTUAL_FILE); - if (file == null) return null; + if (project == null) { + return null; + } + VirtualFile file = PlatformDataKeys.VIRTUAL_FILE.getData(dataContext); + if (file == null) { + return null; + } final VirtualFile sourceRoot = ProjectRootManager.getInstance(project).getFileIndex().getSourceRootForFile(file); - if (sourceRoot == null) return null; + if (sourceRoot == null) { + return null; + } return FileUtil.getRelativePath(getIOFile(sourceRoot), getIOFile(file)); } } diff --git a/platform/lang-impl/src/com/intellij/ide/macro/FileRelativePathMacro.java b/platform/lang-impl/src/com/intellij/ide/macro/FileRelativePathMacro.java index 87c605489e71..9d8230f1ed11 100644 --- a/platform/lang-impl/src/com/intellij/ide/macro/FileRelativePathMacro.java +++ b/platform/lang-impl/src/com/intellij/ide/macro/FileRelativePathMacro.java @@ -16,9 +16,10 @@ package com.intellij.ide.macro; -import com.intellij.ide.DataAccessors; import com.intellij.ide.IdeBundle; import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.actionSystem.PlatformDataKeys; +import com.intellij.openapi.project.Project; import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.vfs.VfsUtil; import com.intellij.openapi.vfs.VirtualFile; @@ -33,12 +34,13 @@ public class FileRelativePathMacro extends Macro { } public String expand(DataContext dataContext) { - final VirtualFile baseDir = DataAccessors.PROJECT_BASE_DIR.from(dataContext); + Project project = PlatformDataKeys.PROJECT.getData(dataContext); + final VirtualFile baseDir = project == null ? null : project.getBaseDir(); if (baseDir == null) { return null; } - VirtualFile file = DataAccessors.VIRTUAL_FILE.from(dataContext); + VirtualFile file = PlatformDataKeys.VIRTUAL_FILE.getData(dataContext); if (file == null) return null; return FileUtil.getRelativePath(VfsUtil.virtualToIoFile(baseDir), VfsUtil.virtualToIoFile(file)); } diff --git a/platform/lang-impl/src/com/intellij/ide/macro/MacroManager.java b/platform/lang-impl/src/com/intellij/ide/macro/MacroManager.java index 60c17cdcb0d3..ceeffa3c7da2 100644 --- a/platform/lang-impl/src/com/intellij/ide/macro/MacroManager.java +++ b/platform/lang-impl/src/com/intellij/ide/macro/MacroManager.java @@ -19,7 +19,6 @@ package com.intellij.ide.macro; import com.intellij.ide.DataManager; import com.intellij.ide.IdeEventQueue; import com.intellij.ide.impl.DataManagerImpl; -import com.intellij.openapi.actionSystem.DataConstants; import com.intellij.openapi.actionSystem.DataContext; import com.intellij.openapi.actionSystem.PlatformDataKeys; import com.intellij.openapi.components.ServiceManager; @@ -58,7 +57,6 @@ public final class MacroManager { registerMacro(new JdkPathMacro()); registerMacro(new PromptMacro()); registerMacro(new SourcepathEntryMacro()); - //registerMacro(new ProjectFilePathMacro()); registerMacro(new ProjectFileDirMacro()); registerMacro(new ProjectNameMacro()); registerMacro(new ProjectPathMacro()); @@ -101,15 +99,20 @@ public final class MacroManager { } private static DataContext getCorrectContext(DataContext dataContext) { - if (dataContext.getData(DataConstants.FILE_EDITOR) != null) return dataContext; + if (PlatformDataKeys.FILE_EDITOR.getData(dataContext) != null) { + return dataContext; + } Project project = PlatformDataKeys.PROJECT.getData(dataContext); - if (project == null) return dataContext; + if (project == null) { + return dataContext; + } FileEditorManager editorManager = FileEditorManager.getInstance(project); VirtualFile[] files = editorManager.getSelectedFiles(); - if (files.length == 0) return dataContext; + if (files.length == 0) { + return dataContext; + } FileEditor fileEditor = editorManager.getSelectedEditor(files[0]); - return fileEditor == null ? dataContext : - DataManager.getInstance().getDataContext(fileEditor.getComponent()); + return fileEditor == null ? dataContext : DataManager.getInstance().getDataContext(fileEditor.getComponent()); } /** diff --git a/platform/lang-impl/src/com/intellij/ide/macro/ModulePathMacro.java b/platform/lang-impl/src/com/intellij/ide/macro/ModulePathMacro.java index 3d27521a17c4..f40aaf4eb37a 100644 --- a/platform/lang-impl/src/com/intellij/ide/macro/ModulePathMacro.java +++ b/platform/lang-impl/src/com/intellij/ide/macro/ModulePathMacro.java @@ -16,9 +16,9 @@ package com.intellij.ide.macro; -import com.intellij.ide.DataAccessors; import com.intellij.ide.IdeBundle; import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.actionSystem.LangDataKeys; import com.intellij.openapi.module.Module; import com.intellij.openapi.roots.ProjectRootsTraversing; @@ -32,7 +32,7 @@ public final class ModulePathMacro extends Macro { } public String expand(DataContext dataContext) { - final Module module = DataAccessors.MODULE.from(dataContext); + final Module module = LangDataKeys.MODULE.getData(dataContext); if (module == null) { return null; } diff --git a/platform/lang-impl/src/com/intellij/ide/macro/ProjectFilePathMacro.java b/platform/lang-impl/src/com/intellij/ide/macro/ProjectFilePathMacro.java deleted file mode 100644 index bd5e58600f6a..000000000000 --- a/platform/lang-impl/src/com/intellij/ide/macro/ProjectFilePathMacro.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright 2000-2009 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 com.intellij.ide.macro; - -import com.intellij.ide.DataAccessors; -import com.intellij.ide.IdeBundle; -import com.intellij.openapi.actionSystem.DataContext; - -public final class ProjectFilePathMacro extends Macro { - public String getName() { - return "ProjectFilePath"; - } - - public String getDescription() { - return IdeBundle.message("macro.project.file.path"); - } - - public String expand(DataContext dataContext) { - return DataAccessors.PROJECT_FILE_PATH.from(dataContext); - } -} \ No newline at end of file diff --git a/platform/lang-impl/src/com/intellij/ide/macro/SourcepathEntryMacro.java b/platform/lang-impl/src/com/intellij/ide/macro/SourcepathEntryMacro.java index 0c89c4895fce..18b110297982 100644 --- a/platform/lang-impl/src/com/intellij/ide/macro/SourcepathEntryMacro.java +++ b/platform/lang-impl/src/com/intellij/ide/macro/SourcepathEntryMacro.java @@ -17,7 +17,6 @@ package com.intellij.ide.macro; import com.intellij.ide.IdeBundle; -import com.intellij.openapi.actionSystem.DataConstants; import com.intellij.openapi.actionSystem.DataContext; import com.intellij.openapi.actionSystem.PlatformDataKeys; import com.intellij.openapi.project.Project; @@ -38,11 +37,17 @@ public final class SourcepathEntryMacro extends Macro { public String expand(final DataContext dataContext) { final Project project = PlatformDataKeys.PROJECT.getData(dataContext); - if (project == null) return null; - VirtualFile file = (VirtualFile)dataContext.getData(DataConstants.VIRTUAL_FILE); - if (file == null) return null; + if (project == null) { + return null; + } + VirtualFile file = PlatformDataKeys.VIRTUAL_FILE.getData(dataContext); + if (file == null) { + return null; + } final VirtualFile sourceRoot = ProjectRootManager.getInstance(project).getFileIndex().getSourceRootForFile(file); - if (sourceRoot == null) return null; + if (sourceRoot == null) { + return null; + } return getPath(sourceRoot); } -} \ No newline at end of file +} diff --git a/platform/lang-impl/src/com/intellij/ide/navigationToolbar/NavBarPanel.java b/platform/lang-impl/src/com/intellij/ide/navigationToolbar/NavBarPanel.java index a93266fcf866..f6543b068f60 100644 --- a/platform/lang-impl/src/com/intellij/ide/navigationToolbar/NavBarPanel.java +++ b/platform/lang-impl/src/com/intellij/ide/navigationToolbar/NavBarPanel.java @@ -286,7 +286,7 @@ public class NavBarPanel extends JPanel implements DataProvider, PopupOwner { private void updateModel() { DataContext context = DataManager.getInstance().getDataContext(); - if (context.getData(DataConstants.IDE_VIEW) == myIdeView || context.getData(DataConstants.PROJECT) != myProject || isNodePopupShowing()) { + if (LangDataKeys.IDE_VIEW.getData(context) == myIdeView || PlatformDataKeys.PROJECT.getData(context) != myProject || isNodePopupShowing()) { scheduleModelUpdate(); return; } @@ -617,10 +617,10 @@ public class NavBarPanel extends JPanel implements DataProvider, PopupOwner { @Nullable public Object getData(String dataId) { - if (dataId.equals(DataConstants.PROJECT)) { + if (PlatformDataKeys.PROJECT.is(dataId)) { return !myProject.isDisposed() ? myProject : null; } - if (dataId.equals(DataConstants.MODULE)) { + if (LangDataKeys.MODULE.is(dataId)) { final Module module = getSelectedElement(Module.class); if (module != null && !module.isDisposed()) return module; final PsiElement element = getSelectedElement(PsiElement.class); @@ -629,7 +629,7 @@ public class NavBarPanel extends JPanel implements DataProvider, PopupOwner { } return null; } - if (dataId.equals(DataConstants.MODULE_CONTEXT)) { + if (LangDataKeys.MODULE_CONTEXT.is(dataId)) { final PsiDirectory directory = getSelectedElement(PsiDirectory.class); if (directory != null) { final VirtualFile dir = directory.getVirtualFile(); @@ -639,17 +639,17 @@ public class NavBarPanel extends JPanel implements DataProvider, PopupOwner { } return null; } - if (dataId.equals(DataConstants.PSI_ELEMENT)) { + if (LangDataKeys.PSI_ELEMENT.is(dataId)) { final PsiElement element = getSelectedElement(PsiElement.class); return element != null && element.isValid() ? element : null; } - if (dataId.equals(DataConstants.PSI_ELEMENT_ARRAY)) { + if (LangDataKeys.PSI_ELEMENT_ARRAY.is(dataId)) { final PsiElement element = getSelectedElement(PsiElement.class); return element != null && element.isValid() ? new PsiElement[]{element} : null; } - if (dataId.equals(DataConstants.VIRTUAL_FILE_ARRAY)) { - PsiElement[] psiElements = (PsiElement[])getData(DataConstants.PSI_ELEMENT_ARRAY); + if (PlatformDataKeys.VIRTUAL_FILE_ARRAY.is(dataId)) { + PsiElement[] psiElements = (PsiElement[])getData(LangDataKeys.PSI_ELEMENT_ARRAY.getName()); if (psiElements == null) return null; Set files = new LinkedHashSet(); for (PsiElement element : psiElements) { @@ -660,23 +660,23 @@ public class NavBarPanel extends JPanel implements DataProvider, PopupOwner { return files.size() > 0 ? VfsUtil.toVirtualFileArray(files) : null; } - if (dataId.equals(DataConstants.CONTEXT_COMPONENT)) { + if (PlatformDataKeys.CONTEXT_COMPONENT.is(dataId)) { return this; } - if (DataConstants.CUT_PROVIDER.equals(dataId)) { + if (PlatformDataKeys.CUT_PROVIDER.is(dataId)) { return myCopyPasteDelegator.getCutProvider(); } - if (DataConstants.COPY_PROVIDER.equals(dataId)) { + if (PlatformDataKeys.COPY_PROVIDER.is(dataId)) { return myCopyPasteDelegator.getCopyProvider(); } - if (DataConstants.PASTE_PROVIDER.equals(dataId)) { + if (PlatformDataKeys.PASTE_PROVIDER.is(dataId)) { return myCopyPasteDelegator.getPasteProvider(); } - if (DataConstants.DELETE_ELEMENT_PROVIDER.equals(dataId)) { + if (PlatformDataKeys.DELETE_ELEMENT_PROVIDER.is(dataId)) { return getSelectedElement(Module.class) != null ? myDeleteModuleProvider : new DeleteHandler.DefaultDeleteProvider(); } - if (DataConstants.IDE_VIEW.equals(dataId)) { + if (LangDataKeys.IDE_VIEW.is(dataId)) { return myIdeView; } diff --git a/platform/lang-impl/src/com/intellij/ide/projectView/actions/MoveModulesOutsideGroupAction.java b/platform/lang-impl/src/com/intellij/ide/projectView/actions/MoveModulesOutsideGroupAction.java index bd0c4a27972e..da639e23a87e 100644 --- a/platform/lang-impl/src/com/intellij/ide/projectView/actions/MoveModulesOutsideGroupAction.java +++ b/platform/lang-impl/src/com/intellij/ide/projectView/actions/MoveModulesOutsideGroupAction.java @@ -22,8 +22,8 @@ package com.intellij.ide.projectView.actions; import com.intellij.ide.IdeBundle; import com.intellij.openapi.actionSystem.AnAction; import com.intellij.openapi.actionSystem.AnActionEvent; -import com.intellij.openapi.actionSystem.DataConstants; import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.actionSystem.LangDataKeys; import com.intellij.openapi.module.Module; public class MoveModulesOutsideGroupAction extends AnAction { @@ -34,7 +34,7 @@ public class MoveModulesOutsideGroupAction extends AnAction { public void actionPerformed(AnActionEvent e) { final DataContext dataContext = e.getDataContext(); - final Module[] modules = (Module[])dataContext.getData(DataConstants.MODULE_CONTEXT_ARRAY); + final Module[] modules = LangDataKeys.MODULE_CONTEXT_ARRAY.getData(dataContext); MoveModulesToGroupAction.doMove(modules, null, dataContext); } } \ No newline at end of file diff --git a/platform/lang-impl/src/com/intellij/ide/projectView/actions/MoveModulesToGroupAction.java b/platform/lang-impl/src/com/intellij/ide/projectView/actions/MoveModulesToGroupAction.java index cda91de0d205..68616eeedefa 100644 --- a/platform/lang-impl/src/com/intellij/ide/projectView/actions/MoveModulesToGroupAction.java +++ b/platform/lang-impl/src/com/intellij/ide/projectView/actions/MoveModulesToGroupAction.java @@ -24,7 +24,6 @@ import com.intellij.ide.projectView.ProjectView; import com.intellij.ide.projectView.impl.AbstractProjectViewPane; import com.intellij.ide.projectView.impl.ModuleGroup; import com.intellij.openapi.actionSystem.*; -import com.intellij.openapi.actionSystem.ex.DataConstantsEx; import com.intellij.openapi.module.ModifiableModuleModel; import com.intellij.openapi.module.Module; import com.intellij.openapi.module.impl.ModuleManagerImpl; @@ -43,7 +42,7 @@ public class MoveModulesToGroupAction extends AnAction { public void update(AnActionEvent e) { Presentation presentation = getTemplatePresentation(); final DataContext dataContext = e.getDataContext(); - final Module[] modules = (Module[])dataContext.getData(DataConstants.MODULE_CONTEXT_ARRAY); + final Module[] modules = LangDataKeys.MODULE_CONTEXT_ARRAY.getData(dataContext); String description = IdeBundle.message("message.move.modules.to.group", whatToMove(modules), myModuleGroup.presentableText()); presentation.setDescription(description); @@ -55,7 +54,7 @@ public class MoveModulesToGroupAction extends AnAction { public void actionPerformed(AnActionEvent e) { final DataContext dataContext = e.getDataContext(); - final Module[] modules = (Module[])dataContext.getData(DataConstants.MODULE_CONTEXT_ARRAY); + final Module[] modules = LangDataKeys.MODULE_CONTEXT_ARRAY.getData(dataContext); doMove(modules, myModuleGroup, dataContext); } @@ -63,7 +62,7 @@ public class MoveModulesToGroupAction extends AnAction { Project project = modules[0].getProject(); for (final Module module : modules) { ModifiableModuleModel model = dataContext != null - ? (ModifiableModuleModel)dataContext.getData(DataConstantsEx.MODIFIABLE_MODULE_MODEL) + ? LangDataKeys.MODIFIABLE_MODULE_MODEL.getData(dataContext) : null; if (model != null){ model.setModuleGroupPath(module, group == null ? null : group.getGroupPath()); @@ -86,4 +85,4 @@ public class MoveModulesToGroupAction extends AnAction { } } } -} \ No newline at end of file +} diff --git a/platform/lang-impl/src/com/intellij/ide/projectView/actions/MoveModulesToSubGroupAction.java b/platform/lang-impl/src/com/intellij/ide/projectView/actions/MoveModulesToSubGroupAction.java index dd2443ceaf53..d44e47b60329 100644 --- a/platform/lang-impl/src/com/intellij/ide/projectView/actions/MoveModulesToSubGroupAction.java +++ b/platform/lang-impl/src/com/intellij/ide/projectView/actions/MoveModulesToSubGroupAction.java @@ -22,8 +22,8 @@ package com.intellij.ide.projectView.actions; import com.intellij.ide.IdeBundle; import com.intellij.ide.projectView.impl.ModuleGroup; import com.intellij.openapi.actionSystem.AnActionEvent; -import com.intellij.openapi.actionSystem.DataConstants; import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.actionSystem.LangDataKeys; import com.intellij.openapi.actionSystem.Presentation; import com.intellij.openapi.module.Module; import com.intellij.openapi.ui.Messages; @@ -42,7 +42,7 @@ public class MoveModulesToSubGroupAction extends MoveModulesToGroupAction { public void actionPerformed(AnActionEvent e) { final DataContext dataContext = e.getDataContext(); - final Module[] modules = (Module[])dataContext.getData(DataConstants.MODULE_CONTEXT_ARRAY); + final Module[] modules = LangDataKeys.MODULE_CONTEXT_ARRAY.getData(dataContext); final String[] newGroup; if (myModuleGroup != null) { String message = IdeBundle.message("prompt.specify.name.of.module.subgroup", myModuleGroup.presentableText(), whatToMove(modules)); @@ -59,4 +59,4 @@ public class MoveModulesToSubGroupAction extends MoveModulesToGroupAction { doMove(modules, new ModuleGroup(newGroup), dataContext); } -} \ No newline at end of file +} diff --git a/platform/lang-impl/src/com/intellij/ide/projectView/impl/AbstractProjectViewPane.java b/platform/lang-impl/src/com/intellij/ide/projectView/impl/AbstractProjectViewPane.java index 16117dabf43c..ee435d453f58 100644 --- a/platform/lang-impl/src/com/intellij/ide/projectView/impl/AbstractProjectViewPane.java +++ b/platform/lang-impl/src/com/intellij/ide/projectView/impl/AbstractProjectViewPane.java @@ -31,10 +31,10 @@ import com.intellij.ide.projectView.impl.nodes.AbstractProjectNode; import com.intellij.ide.projectView.impl.nodes.ModuleGroupNode; import com.intellij.ide.util.treeView.*; import com.intellij.openapi.Disposable; -import com.intellij.openapi.actionSystem.DataConstants; import com.intellij.openapi.actionSystem.DataContext; import com.intellij.openapi.actionSystem.DataProvider; import com.intellij.openapi.actionSystem.DefaultActionGroup; +import com.intellij.openapi.actionSystem.PlatformDataKeys; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.extensions.ExtensionPointName; @@ -212,7 +212,7 @@ public abstract class AbstractProjectViewPane implements DataProvider, Disposabl } public Object getData(String dataId) { - if (DataConstants.NAVIGATABLE_ARRAY.equals(dataId)) { + if (PlatformDataKeys.NAVIGATABLE_ARRAY.is(dataId)) { TreePath[] paths = getSelectionPaths(); if (paths == null) return null; final ArrayList navigatables = new ArrayList(); @@ -545,7 +545,7 @@ public abstract class AbstractProjectViewPane implements DataProvider, Disposabl public void dragGestureRecognized(DragGestureEvent dge) { if ((dge.getDragAction() & DnDConstants.ACTION_COPY_OR_MOVE) == 0) return; DataContext dataContext = DataManager.getInstance().getDataContext(); - ProjectView projectView = (ProjectView)dataContext.getData(ProjectViewImpl.PROJECT_VIEW_DATA_CONSTANT); + ProjectView projectView = ProjectViewImpl.DATA_KEY.getData(dataContext); if (projectView == null) return; final AbstractProjectViewPane currentPane = projectView.getCurrentProjectViewPane(); diff --git a/platform/lang-impl/src/com/intellij/ide/projectView/impl/ModuleGroup.java b/platform/lang-impl/src/com/intellij/ide/projectView/impl/ModuleGroup.java index 1429492d9b2f..a3b388180205 100644 --- a/platform/lang-impl/src/com/intellij/ide/projectView/impl/ModuleGroup.java +++ b/platform/lang-impl/src/com/intellij/ide/projectView/impl/ModuleGroup.java @@ -19,9 +19,10 @@ */ package com.intellij.ide.projectView.impl; -import com.intellij.openapi.actionSystem.DataConstants; import com.intellij.openapi.actionSystem.DataContext; -import com.intellij.openapi.actionSystem.ex.DataConstantsEx; +import com.intellij.openapi.actionSystem.DataKey; +import com.intellij.openapi.actionSystem.LangDataKeys; +import com.intellij.openapi.actionSystem.PlatformDataKeys; import com.intellij.openapi.module.ModifiableModuleModel; import com.intellij.openapi.module.Module; import com.intellij.openapi.module.ModuleManager; @@ -33,6 +34,8 @@ import org.jetbrains.annotations.NotNull; import java.util.*; public class ModuleGroup { + public static final DataKey ARRAY_DATA_KEY = DataKey.create("moduleGroup.array"); + private final String[] myGroupPath; public ModuleGroup(@NotNull String[] groupPath) { @@ -77,8 +80,7 @@ public class ModuleGroup { } public Collection childGroups(DataContext dataContext) { - return childGroups((ModifiableModuleModel)dataContext.getData(DataConstantsEx.MODIFIABLE_MODULE_MODEL), - (Project)dataContext.getData(DataConstants.PROJECT)); + return childGroups(LangDataKeys.MODIFIABLE_MODULE_MODEL.getData(dataContext), PlatformDataKeys.PROJECT.getData(dataContext)); } public Collection childGroups(ModifiableModuleModel model, Project project) { diff --git a/platform/lang-impl/src/com/intellij/ide/projectView/impl/MoveDropTargetListener.java b/platform/lang-impl/src/com/intellij/ide/projectView/impl/MoveDropTargetListener.java index 72dd63f40d3a..dda8641229a5 100644 --- a/platform/lang-impl/src/com/intellij/ide/projectView/impl/MoveDropTargetListener.java +++ b/platform/lang-impl/src/com/intellij/ide/projectView/impl/MoveDropTargetListener.java @@ -19,7 +19,7 @@ package com.intellij.ide.projectView.impl; import com.intellij.ide.DataManager; import com.intellij.ide.projectView.impl.nodes.DropTargetNode; import com.intellij.openapi.actionSystem.DataContext; -import com.intellij.openapi.actionSystem.ex.DataConstantsEx; +import com.intellij.openapi.actionSystem.LangDataKeys; import com.intellij.openapi.project.Project; import com.intellij.openapi.vfs.LocalFileSystem; import com.intellij.openapi.vfs.VirtualFile; @@ -311,7 +311,7 @@ class MoveDropTargetListener implements DropTargetListener { getActionHandler(dataContext).invoke(myProject, sourceElements, new DataContext() { @Nullable public Object getData(@NonNls String dataId) { - if (dataId.equals(DataConstantsEx.TARGET_PSI_ELEMENT)) { + if (LangDataKeys.TARGET_PSI_ELEMENT.is(dataId)) { return targetElement; } else { @@ -322,7 +322,7 @@ class MoveDropTargetListener implements DropTargetListener { } private RefactoringActionHandler getActionHandler(final DataContext dataContext) { - final MoveAction.MoveProvider moveProvider = (MoveAction.MoveProvider)dataContext.getData(MoveAction.MOVE_PROVIDER); + final MoveAction.MoveProvider moveProvider = MoveAction.MoveProvider.DATA_KEY.getData(dataContext); if (moveProvider != null) { return moveProvider.getHandler(dataContext); } diff --git a/platform/lang-impl/src/com/intellij/ide/projectView/impl/MoveModuleToGroup.java b/platform/lang-impl/src/com/intellij/ide/projectView/impl/MoveModuleToGroup.java index eff896acedd5..70752bf5c459 100644 --- a/platform/lang-impl/src/com/intellij/ide/projectView/impl/MoveModuleToGroup.java +++ b/platform/lang-impl/src/com/intellij/ide/projectView/impl/MoveModuleToGroup.java @@ -25,6 +25,7 @@ import com.intellij.ide.projectView.actions.MoveModulesToSubGroupAction; import com.intellij.openapi.actionSystem.*; import com.intellij.openapi.module.Module; import com.intellij.openapi.project.Project; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.util.ArrayList; @@ -42,16 +43,17 @@ public class MoveModuleToGroup extends ActionGroup { public void update(AnActionEvent e){ final DataContext dataContext = e.getDataContext(); - final Project project = (Project)dataContext.getData(DataConstants.PROJECT); - final Module[] modules = (Module[])dataContext.getData(DataConstants.MODULE_CONTEXT_ARRAY); + final Project project = PlatformDataKeys.PROJECT.getData(dataContext); + final Module[] modules = LangDataKeys.MODULE_CONTEXT_ARRAY.getData(dataContext); boolean active = project != null && modules != null && modules.length != 0; final Presentation presentation = e.getPresentation(); presentation.setVisible(active); presentation.setText(myModuleGroup.presentableText()); } + @NotNull public AnAction[] getChildren(@Nullable AnActionEvent e) { - if (e == null) return AnAction.EMPTY_ARRAY; + if (e == null) return EMPTY_ARRAY; List children = new ArrayList(myModuleGroup.childGroups(e.getDataContext())); Collections.sort ( children, new Comparator() { diff --git a/platform/lang-impl/src/com/intellij/ide/projectView/impl/MoveModuleToGroupTopLevel.java b/platform/lang-impl/src/com/intellij/ide/projectView/impl/MoveModuleToGroupTopLevel.java index 6377e583e3f7..3b529b5d33af 100644 --- a/platform/lang-impl/src/com/intellij/ide/projectView/impl/MoveModuleToGroupTopLevel.java +++ b/platform/lang-impl/src/com/intellij/ide/projectView/impl/MoveModuleToGroupTopLevel.java @@ -22,11 +22,11 @@ package com.intellij.ide.projectView.impl; import com.intellij.ide.projectView.actions.MoveModulesOutsideGroupAction; import com.intellij.ide.projectView.actions.MoveModulesToSubGroupAction; import com.intellij.openapi.actionSystem.*; -import com.intellij.openapi.actionSystem.ex.DataConstantsEx; import com.intellij.openapi.module.ModifiableModuleModel; import com.intellij.openapi.module.Module; import com.intellij.openapi.module.ModuleManager; import com.intellij.openapi.project.Project; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.util.*; @@ -34,14 +34,17 @@ import java.util.*; public class MoveModuleToGroupTopLevel extends ActionGroup { public void update(AnActionEvent e){ final DataContext dataContext = e.getDataContext(); - final Project project = (Project)dataContext.getData(DataConstants.PROJECT); - final Module[] modules = (Module[])dataContext.getData(DataConstants.MODULE_CONTEXT_ARRAY); + final Project project = PlatformDataKeys.PROJECT.getData(dataContext); + final Module[] modules = LangDataKeys.MODULE_CONTEXT_ARRAY.getData(dataContext); boolean active = project != null && modules != null && modules.length != 0; e.getPresentation().setVisible(active); } + @NotNull public AnAction[] getChildren(@Nullable AnActionEvent e) { - if (e == null) return AnAction.EMPTY_ARRAY; + if (e == null) { + return EMPTY_ARRAY; + } List topLevelGroupNames = new ArrayList (getTopLevelGroupNames(e.getDataContext())); Collections.sort ( topLevelGroupNames ); @@ -56,9 +59,9 @@ public class MoveModuleToGroupTopLevel extends ActionGroup { } private static Collection getTopLevelGroupNames(final DataContext dataContext) { - final Project project = (Project)dataContext.getData(DataConstants.PROJECT); + final Project project =PlatformDataKeys.PROJECT.getData(dataContext); - final ModifiableModuleModel model = (ModifiableModuleModel)dataContext.getData(DataConstantsEx.MODIFIABLE_MODULE_MODEL); + final ModifiableModuleModel model = LangDataKeys.MODIFIABLE_MODULE_MODEL.getData(dataContext); Module[] allModules; if ( model != null ) { @@ -81,4 +84,4 @@ public class MoveModuleToGroupTopLevel extends ActionGroup { } return topLevelGroupNames; } -} \ No newline at end of file +} diff --git a/platform/lang-impl/src/com/intellij/ide/projectView/impl/ProjectViewImpl.java b/platform/lang-impl/src/com/intellij/ide/projectView/impl/ProjectViewImpl.java index 18f27794c287..2ae075af88a4 100644 --- a/platform/lang-impl/src/com/intellij/ide/projectView/impl/ProjectViewImpl.java +++ b/platform/lang-impl/src/com/intellij/ide/projectView/impl/ProjectViewImpl.java @@ -36,7 +36,6 @@ import com.intellij.ide.util.treeView.AbstractTreeNode; import com.intellij.ide.util.treeView.NodeDescriptor; import com.intellij.openapi.Disposable; import com.intellij.openapi.actionSystem.*; -import com.intellij.openapi.actionSystem.ex.DataConstantsEx; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.application.ModalityState; import com.intellij.openapi.application.ex.ApplicationInfoEx; @@ -156,7 +155,9 @@ public final class ProjectViewImpl extends ProjectView implements PersistentStat private final Map myId2Pane = new LinkedHashMap(); private final Collection myUninitializedPanes = new THashSet(); - static final String PROJECT_VIEW_DATA_CONSTANT = "com.intellij.ide.projectView.impl.ProjectViewImpl"; + static final DataKey DATA_KEY = DataKey.create("com.intellij.ide.projectView.impl.ProjectViewImpl"); + @Deprecated static final String PROJECT_VIEW_DATA_CONSTANT = DATA_KEY.getName(); + private DefaultActionGroup myActionGroup; private final Runnable myTreeChangeListener; private String mySavedPaneId = ProjectViewPane.ID; @@ -755,7 +756,7 @@ public final class ProjectViewImpl extends ProjectView implements PersistentStat } } if (title == null) { - final PsiElement element = (PsiElement)myDataProvider.getData(DataConstants.PSI_ELEMENT); + final PsiElement element = (PsiElement)myDataProvider.getData(LangDataKeys.PSI_ELEMENT.getName()); if (element != null) { PsiFile file = element.getContainingFile(); if (file != null) { @@ -977,20 +978,20 @@ public final class ProjectViewImpl extends ProjectView implements PersistentStat if (paneSpecificData != null) return paneSpecificData; } - if (DataConstants.PSI_ELEMENT.equals(dataId)) { + if (LangDataKeys.PSI_ELEMENT.is(dataId)) { if (currentProjectViewPane == null) return null; final PsiElement[] elements = currentProjectViewPane.getSelectedPSIElements(); return elements.length == 1 ? elements[0] : null; } - if (DataConstants.PSI_ELEMENT_ARRAY.equals(dataId)) { + if (LangDataKeys.PSI_ELEMENT_ARRAY.is(dataId)) { if (currentProjectViewPane == null) { return null; } PsiElement[] elements = currentProjectViewPane.getSelectedPSIElements(); return elements.length == 0 ? null : elements; } - if (DataConstants.VIRTUAL_FILE_ARRAY.equals(dataId)) { - PsiElement[] psiElements = (PsiElement[])getData(DataConstants.PSI_ELEMENT_ARRAY); + if (PlatformDataKeys.VIRTUAL_FILE_ARRAY.is(dataId)) { + PsiElement[] psiElements = (PsiElement[])getData(LangDataKeys.PSI_ELEMENT_ARRAY.getName()); if (psiElements == null) return null; Set files = new LinkedHashSet(); for (PsiElement element : psiElements) { @@ -1000,22 +1001,22 @@ public final class ProjectViewImpl extends ProjectView implements PersistentStat } return files.size() > 0 ? VfsUtil.toVirtualFileArray(files) : null; } - if (DataConstantsEx.TARGET_PSI_ELEMENT.equals(dataId)) { + if (LangDataKeys.TARGET_PSI_ELEMENT.is(dataId)) { return null; } - if (DataConstants.CUT_PROVIDER.equals(dataId)) { + if (PlatformDataKeys.CUT_PROVIDER.is(dataId)) { return myCopyPasteDelegator.getCutProvider(); } - if (DataConstants.COPY_PROVIDER.equals(dataId)) { + if (PlatformDataKeys.COPY_PROVIDER.is(dataId)) { return myCopyPasteDelegator.getCopyProvider(); } - if (DataConstants.PASTE_PROVIDER.equals(dataId)) { + if (PlatformDataKeys.PASTE_PROVIDER.is(dataId)) { return myCopyPasteDelegator.getPasteProvider(); } - if (DataConstants.IDE_VIEW.equals(dataId)) { + if (LangDataKeys.IDE_VIEW.is(dataId)) { return myIdeView; } - if (DataConstants.DELETE_ELEMENT_PROVIDER.equals(dataId)) { + if (PlatformDataKeys.DELETE_ELEMENT_PROVIDER.is(dataId)) { final List modules = getSelectedElements(Module.class); if (!modules.isEmpty()) { return myDeleteModuleProvider; @@ -1034,17 +1035,17 @@ public final class ProjectViewImpl extends ProjectView implements PersistentStat } return myDeletePSIElementProvider; } - if (DataConstants.HELP_ID.equals(dataId)) { + if (PlatformDataKeys.HELP_ID.is(dataId)) { return HelpID.PROJECT_VIEWS; } - if (PROJECT_VIEW_DATA_CONSTANT.equals(dataId)) { + if (ProjectViewImpl.DATA_KEY.is(dataId)) { return ProjectViewImpl.this; } - if (DataConstants.PROJECT_CONTEXT.equals(dataId)) { + if (PlatformDataKeys.PROJECT_CONTEXT.is(dataId)) { Object selected = getSelectedNodeElement(); return selected instanceof Project ? selected : null; } - if (DataConstants.MODULE_CONTEXT.equals(dataId)) { + if (LangDataKeys.MODULE_CONTEXT.is(dataId)) { Object selected = getSelectedNodeElement(); if (selected instanceof Module) { return !((Module)selected).isDisposed() ? selected : null; @@ -1060,18 +1061,18 @@ public final class ProjectViewImpl extends ProjectView implements PersistentStat } } - if (DataConstants.MODULE_CONTEXT_ARRAY.equals(dataId)) { + if (LangDataKeys.MODULE_CONTEXT_ARRAY.is(dataId)) { return getSelectedModules(); } - if (DataConstantsEx.MODULE_GROUP_ARRAY.equals(dataId)) { + if (ModuleGroup.ARRAY_DATA_KEY.is(dataId)) { final List selectedElements = getSelectedElements(ModuleGroup.class); return selectedElements.isEmpty() ? null : selectedElements.toArray(new ModuleGroup[selectedElements.size()]); } - if (DataConstantsEx.LIBRARY_GROUP_ARRAY.equals(dataId)) { + if (LibraryGroupElement.ARRAY_DATA_KEY.is(dataId)) { final List selectedElements = getSelectedElements(LibraryGroupElement.class); return selectedElements.isEmpty() ? null : selectedElements.toArray(new LibraryGroupElement[selectedElements.size()]); } - if (DataConstantsEx.NAMED_LIBRARY_ARRAY.equals(dataId)) { + if (NamedLibraryElement.ARRAY_DATA_KEY.is(dataId)) { final List selectedElements = getSelectedElements(NamedLibraryElement.class); return selectedElements.isEmpty() ? null : selectedElements.toArray(new NamedLibraryElement[selectedElements.size()]); } diff --git a/platform/lang-impl/src/com/intellij/ide/projectView/impl/nodes/LibraryGroupElement.java b/platform/lang-impl/src/com/intellij/ide/projectView/impl/nodes/LibraryGroupElement.java index 6e8b415c8118..23331c1e5702 100644 --- a/platform/lang-impl/src/com/intellij/ide/projectView/impl/nodes/LibraryGroupElement.java +++ b/platform/lang-impl/src/com/intellij/ide/projectView/impl/nodes/LibraryGroupElement.java @@ -16,6 +16,7 @@ package com.intellij.ide.projectView.impl.nodes; +import com.intellij.openapi.actionSystem.DataKey; import com.intellij.openapi.module.Module; /** @@ -24,6 +25,8 @@ import com.intellij.openapi.module.Module; * Time: 7:08:03 PM */ public final class LibraryGroupElement { + public static final DataKey ARRAY_DATA_KEY = DataKey.create("libraryGroup.array"); + private final Module myModule; public LibraryGroupElement(Module module) { diff --git a/platform/lang-impl/src/com/intellij/ide/projectView/impl/nodes/NamedLibraryElement.java b/platform/lang-impl/src/com/intellij/ide/projectView/impl/nodes/NamedLibraryElement.java index c95d5ef98d75..f315552d32cf 100644 --- a/platform/lang-impl/src/com/intellij/ide/projectView/impl/nodes/NamedLibraryElement.java +++ b/platform/lang-impl/src/com/intellij/ide/projectView/impl/nodes/NamedLibraryElement.java @@ -16,6 +16,7 @@ package com.intellij.ide.projectView.impl.nodes; +import com.intellij.openapi.actionSystem.DataKey; import com.intellij.openapi.module.Module; import com.intellij.openapi.roots.OrderEntry; import com.intellij.openapi.util.Comparing; @@ -26,6 +27,8 @@ import com.intellij.openapi.util.Comparing; * Time: 7:08:30 PM */ public final class NamedLibraryElement { + public static final DataKey ARRAY_DATA_KEY = DataKey.create("namedLibrary.array"); + private final Module myContextModule; private final OrderEntry myEntry; diff --git a/platform/lang-impl/src/com/intellij/ide/scopeView/ScopeTreeViewPanel.java b/platform/lang-impl/src/com/intellij/ide/scopeView/ScopeTreeViewPanel.java index 33d283c8da7d..84474567797c 100644 --- a/platform/lang-impl/src/com/intellij/ide/scopeView/ScopeTreeViewPanel.java +++ b/platform/lang-impl/src/com/intellij/ide/scopeView/ScopeTreeViewPanel.java @@ -34,8 +34,9 @@ import com.intellij.ide.util.DeleteHandler; import com.intellij.ide.util.DirectoryChooserUtil; import com.intellij.ide.util.EditorHelper; import com.intellij.openapi.Disposable; -import com.intellij.openapi.actionSystem.DataConstants; import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.actionSystem.LangDataKeys; +import com.intellij.openapi.actionSystem.PlatformDataKeys; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.editor.colors.CodeInsightColors; @@ -230,7 +231,7 @@ public class ScopeTreeViewPanel extends JPanel implements JDOMExternalizable, Di settings.UI_COMPACT_EMPTY_MIDDLE_PACKAGES = projectView.isHideEmptyMiddlePackages(ScopeViewPane.ID); myBuilder = new FileTreeModelBuilder(myProject, new Marker() { public boolean isMarked(PsiFile file) { - return packageSet.contains(file, holder); + return packageSet != null && packageSet.contains(file, holder); } }, settings); myTree.setModel(myBuilder.build(myProject, showProgress, projectView.isSortByType(ScopeViewPane.ID))); @@ -258,7 +259,7 @@ public class ScopeTreeViewPanel extends JPanel implements JDOMExternalizable, Di @Nullable public Object getData(String dataId) { - if (dataId.equals(DataConstants.MODULE_CONTEXT)) { + if (LangDataKeys.MODULE_CONTEXT.is(dataId)) { final TreePath selectionPath = myTree.getSelectionPath(); if (selectionPath != null) { PackageDependenciesNode node = (PackageDependenciesNode)selectionPath.getLastPathComponent(); @@ -267,7 +268,7 @@ public class ScopeTreeViewPanel extends JPanel implements JDOMExternalizable, Di } } } - if (dataId.equals(DataConstants.PSI_ELEMENT)) { + if (LangDataKeys.PSI_ELEMENT.is(dataId)) { final TreePath selectionPath = myTree.getSelectionPath(); if (selectionPath != null) { PackageDependenciesNode node = (PackageDependenciesNode)selectionPath.getLastPathComponent(); @@ -276,7 +277,7 @@ public class ScopeTreeViewPanel extends JPanel implements JDOMExternalizable, Di } final TreePath[] treePaths = myTree.getSelectionPaths(); if (treePaths != null) { - if (dataId.equals(DataConstants.PSI_ELEMENT_ARRAY)) { + if (LangDataKeys.PSI_ELEMENT_ARRAY.is(dataId)) { Set psiElements = new HashSet(); for (TreePath treePath : treePaths) { final PackageDependenciesNode node = (PackageDependenciesNode)treePath.getLastPathComponent(); @@ -290,19 +291,19 @@ public class ScopeTreeViewPanel extends JPanel implements JDOMExternalizable, Di return psiElements.isEmpty() ? null : psiElements.toArray(new PsiElement[psiElements.size()]); } } - if (dataId.equals(DataConstants.IDE_VIEW)) { + if (LangDataKeys.IDE_VIEW.is(dataId)) { return myIdeView; } - if (DataConstants.CUT_PROVIDER.equals(dataId)) { + if (PlatformDataKeys.CUT_PROVIDER.is(dataId)) { return myCopyPasteDelegator.getCutProvider(); } - if (DataConstants.COPY_PROVIDER.equals(dataId)) { + if (PlatformDataKeys.COPY_PROVIDER.is(dataId)) { return myCopyPasteDelegator.getCopyProvider(); } - if (DataConstants.PASTE_PROVIDER.equals(dataId)) { + if (PlatformDataKeys.PASTE_PROVIDER.is(dataId)) { return myCopyPasteDelegator.getPasteProvider(); } - if (DataConstants.DELETE_ELEMENT_PROVIDER.equals(dataId)) { + if (PlatformDataKeys.DELETE_ELEMENT_PROVIDER.is(dataId)) { if (getSelectedModules() != null) { return myDeleteModuleProvider; } @@ -372,7 +373,7 @@ public class ScopeTreeViewPanel extends JPanel implements JDOMExternalizable, Di setIcon(node.getClosedIcon()); } } - catch (IndexNotReadyException e) { + catch (IndexNotReadyException ignore) { } final SimpleTextAttributes regularAttributes = SimpleTextAttributes.REGULAR_ATTRIBUTES; TextAttributes textAttributes = regularAttributes.toTextAttributes(); diff --git a/platform/lang-impl/src/com/intellij/ide/structureView/newStructureView/StructureViewComponent.java b/platform/lang-impl/src/com/intellij/ide/structureView/newStructureView/StructureViewComponent.java index dd41672744ea..b524239f198f 100644 --- a/platform/lang-impl/src/com/intellij/ide/structureView/newStructureView/StructureViewComponent.java +++ b/platform/lang-impl/src/com/intellij/ide/structureView/newStructureView/StructureViewComponent.java @@ -657,7 +657,7 @@ public class StructureViewComponent extends SimpleToolWindowPanel implements Tre } public Object getData(String dataId) { - if (DataConstants.PSI_ELEMENT.equals(dataId)) { + if (LangDataKeys.PSI_ELEMENT.is(dataId)) { TreePath path = getSelectedUniquePath(); if (path == null) return null; DefaultMutableTreeNode node = (DefaultMutableTreeNode)path.getLastPathComponent(); @@ -672,29 +672,29 @@ public class StructureViewComponent extends SimpleToolWindowPanel implements Tre if (!((PsiElement)element).isValid()) return null; return element; } - if (DataConstants.PSI_ELEMENT_ARRAY.equals(dataId)) { + if (LangDataKeys.PSI_ELEMENT_ARRAY.is(dataId)) { return convertToPsiElementsArray(getSelectedElements()); } - if (DataConstants.FILE_EDITOR.equals(dataId)) { + if (PlatformDataKeys.FILE_EDITOR.is(dataId)) { return myFileEditor; } - if (DataConstants.CUT_PROVIDER.equals(dataId)) { + if (PlatformDataKeys.CUT_PROVIDER.is(dataId)) { return myCopyPasteDelegator.getCutProvider(); } - if (DataConstants.COPY_PROVIDER.equals(dataId)) { + if (PlatformDataKeys.COPY_PROVIDER.is(dataId)) { return myCopyPasteDelegator.getCopyProvider(); } - if (DataConstants.PASTE_PROVIDER.equals(dataId)) { + if (PlatformDataKeys.PASTE_PROVIDER.is(dataId)) { return myCopyPasteDelegator.getPasteProvider(); } - if (DataConstants.NAVIGATABLE.equals(dataId)) { + if (PlatformDataKeys.NAVIGATABLE.is(dataId)) { Object[] selectedElements = getSelectedTreeElements(); if (selectedElements == null || selectedElements.length == 0) return null; if (selectedElements[0] instanceof Navigatable) { return selectedElements[0]; } } - if (DataConstants.HELP_ID.equals(dataId)) { + if (PlatformDataKeys.HELP_ID.is(dataId)) { return getHelpID(); } return null; diff --git a/platform/lang-impl/src/com/intellij/ide/todo/TodoPanel.java b/platform/lang-impl/src/com/intellij/ide/todo/TodoPanel.java index 6d271e1d72c0..b778441ef42f 100644 --- a/platform/lang-impl/src/com/intellij/ide/todo/TodoPanel.java +++ b/platform/lang-impl/src/com/intellij/ide/todo/TodoPanel.java @@ -282,7 +282,7 @@ abstract class TodoPanel extends SimpleToolWindowPanel implements OccurenceNavig } public Object getData(String dataId) { - if (DataConstants.NAVIGATABLE.equals(dataId)) { + if (PlatformDataKeys.NAVIGATABLE.is(dataId)) { TreePath path = myTree.getSelectionPath(); if (path == null) { return null; @@ -306,14 +306,14 @@ abstract class TodoPanel extends SimpleToolWindowPanel implements OccurenceNavig return null; } } - else if (DataConstants.VIRTUAL_FILE.equals(dataId)) { + else if (PlatformDataKeys.VIRTUAL_FILE.is(dataId)) { final PsiFile file = getSelectedFile(); return file != null ? file.getVirtualFile() : null; } - else if (DataConstants.PSI_ELEMENT.equals(dataId)) { + else if (LangDataKeys.PSI_ELEMENT.is(dataId)) { return getSelectedElement(); } - else if (DataConstants.VIRTUAL_FILE_ARRAY.equals(dataId)) { + else if (PlatformDataKeys.VIRTUAL_FILE_ARRAY.is(dataId)) { PsiFile file = getSelectedFile(); if (file != null) { return new VirtualFile[]{file.getVirtualFile()}; @@ -322,7 +322,7 @@ abstract class TodoPanel extends SimpleToolWindowPanel implements OccurenceNavig return VirtualFile.EMPTY_ARRAY; } } - else if (DataConstants.HELP_ID.equals(dataId)) { + else if (PlatformDataKeys.HELP_ID.is(dataId)) { //noinspection HardCodedStringLiteral return "find.todoList"; } diff --git a/platform/lang-impl/src/com/intellij/ide/util/DeleteHandler.java b/platform/lang-impl/src/com/intellij/ide/util/DeleteHandler.java index bc6793aa0b51..f40c7bd3b437 100644 --- a/platform/lang-impl/src/com/intellij/ide/util/DeleteHandler.java +++ b/platform/lang-impl/src/com/intellij/ide/util/DeleteHandler.java @@ -22,8 +22,8 @@ import com.intellij.history.LocalHistoryAction; import com.intellij.ide.DataManager; import com.intellij.ide.DeleteProvider; import com.intellij.ide.IdeBundle; -import com.intellij.openapi.actionSystem.DataConstants; import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.actionSystem.LangDataKeys; import com.intellij.openapi.actionSystem.PlatformDataKeys; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.command.CommandProcessor; @@ -51,23 +51,28 @@ import java.util.ArrayList; import java.util.Arrays; public class DeleteHandler { + private DeleteHandler() { + } + public static class DefaultDeleteProvider implements DeleteProvider { public boolean canDeleteElement(DataContext dataContext) { - if (dataContext.getData(DataConstants.PROJECT) == null) return false; + if (PlatformDataKeys.PROJECT.getData(dataContext) == null) { + return false; + } final PsiElement[] elements = getPsiElements(dataContext); - return elements != null && DeleteHandler.shouldEnableDeleteAction(elements); + return elements != null && shouldEnableDeleteAction(elements); } @Nullable - private PsiElement[] getPsiElements(DataContext dataContext) { - PsiElement[] elements = (PsiElement[])dataContext.getData(DataConstants.PSI_ELEMENT_ARRAY); + private static PsiElement[] getPsiElements(DataContext dataContext) { + PsiElement[] elements = LangDataKeys.PSI_ELEMENT_ARRAY.getData(dataContext); if (elements == null) { - final Object data = dataContext.getData(DataConstants.PSI_ELEMENT); + final Object data = LangDataKeys.PSI_ELEMENT.getData(dataContext); if (data != null) { elements = new PsiElement[]{(PsiElement)data}; } else { - final Object data1 = dataContext.getData(DataConstants.PSI_FILE); + final Object data1 = LangDataKeys.PSI_FILE.getData(dataContext); if (data1 != null) { elements = new PsiElement[]{(PsiFile)data1}; } diff --git a/platform/lang-impl/src/com/intellij/ide/util/FileStructureDialog.java b/platform/lang-impl/src/com/intellij/ide/util/FileStructureDialog.java index a202dc7125fe..7d8d9e16f075 100644 --- a/platform/lang-impl/src/com/intellij/ide/util/FileStructureDialog.java +++ b/platform/lang-impl/src/com/intellij/ide/util/FileStructureDialog.java @@ -50,8 +50,8 @@ import com.intellij.psi.PsiFile; import com.intellij.psi.util.PsiUtilBase; import com.intellij.ui.ListScrollingUtil; import com.intellij.ui.SpeedSearchBase; -import com.intellij.util.containers.HashSet; import com.intellij.util.ArrayUtil; +import com.intellij.util.containers.HashSet; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -337,7 +337,7 @@ public class FileStructureDialog extends DialogWrapper { if (selectedElement instanceof TreeElement) selectedElement = ((StructureViewTreeElement)selectedElement).getValue(); - if (DataConstants.NAVIGATABLE.equals(dataId)) { + if (PlatformDataKeys.NAVIGATABLE.is(dataId)) { return selectedElement instanceof Navigatable ? selectedElement : myNavigatable; } diff --git a/platform/lang-impl/src/com/intellij/ide/util/NavigationItemListCellRenderer.java b/platform/lang-impl/src/com/intellij/ide/util/NavigationItemListCellRenderer.java index 3cf8e5eaaf61..e283c158399f 100644 --- a/platform/lang-impl/src/com/intellij/ide/util/NavigationItemListCellRenderer.java +++ b/platform/lang-impl/src/com/intellij/ide/util/NavigationItemListCellRenderer.java @@ -19,8 +19,8 @@ import com.intellij.ide.ui.UISettings; import com.intellij.ide.util.treeView.NodeRenderer; import com.intellij.navigation.ItemPresentation; import com.intellij.navigation.NavigationItem; -import com.intellij.openapi.actionSystem.DataConstants; import com.intellij.openapi.actionSystem.DataProvider; +import com.intellij.openapi.actionSystem.LangDataKeys; import com.intellij.openapi.editor.colors.EditorColorsManager; import com.intellij.openapi.editor.colors.EditorColorsScheme; import com.intellij.openapi.editor.markup.EffectType; @@ -97,8 +97,9 @@ public class NavigationItemListCellRenderer extends JPanel implements ListCellRe .isProblemFile(PsiUtilBase.getVirtualFile((PsiElement)element)); if (element instanceof PsiElement || element instanceof DataProvider) { - final PsiElement psiElement = element instanceof PsiElement ? (PsiElement)element : (PsiElement) ((DataProvider)element).getData( - DataConstants.PSI_ELEMENT); + final PsiElement psiElement = element instanceof PsiElement + ? (PsiElement)element + : LangDataKeys.PSI_ELEMENT.getData((DataProvider) element); if (psiElement != null) { final Project project = psiElement.getProject(); diff --git a/platform/lang-impl/src/com/intellij/ide/util/gotoByName/ChooseByNameBase.java b/platform/lang-impl/src/com/intellij/ide/util/gotoByName/ChooseByNameBase.java index 99ded366c539..9d3099bd757d 100644 --- a/platform/lang-impl/src/com/intellij/ide/util/gotoByName/ChooseByNameBase.java +++ b/platform/lang-impl/src/com/intellij/ide/util/gotoByName/ChooseByNameBase.java @@ -164,13 +164,13 @@ public abstract class ChooseByNameBase{ } public Object getData(String dataId) { - if (dataId.equals(DataConstants.HELP_ID)) { + if (PlatformDataKeys.HELP_ID.is(dataId)) { return myModel.getHelpId(); } if (!myListIsUpToDate) { return null; } - if (dataId.equals(DataConstants.PSI_ELEMENT)) { + if (LangDataKeys.PSI_ELEMENT.is(dataId)) { Object element = getChosenElement(); if (element instanceof PsiElement) { @@ -181,7 +181,7 @@ public abstract class ChooseByNameBase{ return ((DataProvider)element).getData(dataId); } } - else if (dataId.equals(DataConstants.PSI_ELEMENT_ARRAY)) { + else if (LangDataKeys.PSI_ELEMENT_ARRAY.is(dataId)) { final List chosenElements = getChosenElements(); if (chosenElements != null) { List result = new ArrayList(); @@ -193,7 +193,7 @@ public abstract class ChooseByNameBase{ return result.toArray(new PsiElement[result.size()]); } } - else if (dataId.equals(DataConstants.DOMINANT_HINT_AREA_RECTANGLE)) { + else if (PlatformDataKeys.DOMINANT_HINT_AREA_RECTANGLE.is(dataId)) { return getBounds(); } return null; @@ -470,7 +470,7 @@ public abstract class ChooseByNameBase{ if (element instanceof PsiElement) { myTextFieldPanel.updateHint((PsiElement)element); } else if (element instanceof DataProvider) { - final Object o = ((DataProvider)element).getData(DataConstants.PSI_ELEMENT); + final Object o = ((DataProvider)element).getData(LangDataKeys.PSI_ELEMENT.getName()); if (o instanceof PsiElement) { myTextFieldPanel.updateHint((PsiElement)o); } diff --git a/platform/lang-impl/src/com/intellij/moduleDependencies/ModulesDependenciesPanel.java b/platform/lang-impl/src/com/intellij/moduleDependencies/ModulesDependenciesPanel.java index 38557bac2fac..8a622b3883fb 100644 --- a/platform/lang-impl/src/com/intellij/moduleDependencies/ModulesDependenciesPanel.java +++ b/platform/lang-impl/src/com/intellij/moduleDependencies/ModulesDependenciesPanel.java @@ -36,8 +36,8 @@ import com.intellij.openapi.roots.ModuleRootListener; import com.intellij.openapi.ui.Splitter; import com.intellij.openapi.util.IconLoader; import com.intellij.ui.*; -import com.intellij.ui.treeStructure.Tree; import com.intellij.ui.content.Content; +import com.intellij.ui.treeStructure.Tree; import com.intellij.util.containers.HashMap; import com.intellij.util.graph.DFSTBuilder; import com.intellij.util.graph.Graph; @@ -451,10 +451,10 @@ public class ModulesDependenciesPanel extends JPanel implements ModuleRootListen } public Object getData(String dataId) { - if (DataConstants.PROJECT.equals(dataId)){ + if (PlatformDataKeys.PROJECT.is(dataId)){ return myProject; } - if (DataConstants.MODULE_CONTEXT.equals(dataId)){ + if (LangDataKeys.MODULE_CONTEXT.is(dataId)){ final TreePath selectionPath = myTree.getLeadSelectionPath(); if (selectionPath != null && selectionPath.getLastPathComponent() instanceof DefaultMutableTreeNode){ DefaultMutableTreeNode node = (DefaultMutableTreeNode)selectionPath.getLastPathComponent(); @@ -463,8 +463,8 @@ public class ModulesDependenciesPanel extends JPanel implements ModuleRootListen } } } - if (DataConstants.HELP_ID.equals(dataId)) { - return ModulesDependenciesPanel.ourHelpID; + if (PlatformDataKeys.HELP_ID.is(dataId)) { + return ourHelpID; } return null; } diff --git a/platform/lang-impl/src/com/intellij/moduleDependencies/ShowModuleDependenciesAction.java b/platform/lang-impl/src/com/intellij/moduleDependencies/ShowModuleDependenciesAction.java index d8f10e85681e..5e7fc4a2806c 100644 --- a/platform/lang-impl/src/com/intellij/moduleDependencies/ShowModuleDependenciesAction.java +++ b/platform/lang-impl/src/com/intellij/moduleDependencies/ShowModuleDependenciesAction.java @@ -45,12 +45,12 @@ public class ShowModuleDependenciesAction extends AnAction{ } ModulesDependenciesPanel panel; AnalysisScope scope = new AnalysisScope(project); - final Module[] modules = (Module[])dataContext.getData(DataConstants.MODULE_CONTEXT_ARRAY); + final Module[] modules = LangDataKeys.MODULE_CONTEXT_ARRAY.getData(dataContext); if (modules != null){ panel = new ModulesDependenciesPanel(project, modules); scope = new AnalysisScope(modules); } else { - final PsiElement element = (PsiElement)dataContext.getData(DataConstants.PSI_FILE); + final PsiElement element = LangDataKeys.PSI_FILE.getData(dataContext); final Module module = element != null ? ModuleUtil.findModuleForPsiElement(element) : null; if (module != null && ModuleManager.getInstance(project).getModules().length > 1){ MyModuleOrProjectScope dlg = new MyModuleOrProjectScope(module.getName()); diff --git a/platform/lang-impl/src/com/intellij/openapi/fileEditor/impl/text/PsiAwareTextEditorImpl.java b/platform/lang-impl/src/com/intellij/openapi/fileEditor/impl/text/PsiAwareTextEditorImpl.java index 97f62e5156e1..62c7b2a93c88 100644 --- a/platform/lang-impl/src/com/intellij/openapi/fileEditor/impl/text/PsiAwareTextEditorImpl.java +++ b/platform/lang-impl/src/com/intellij/openapi/fileEditor/impl/text/PsiAwareTextEditorImpl.java @@ -24,7 +24,8 @@ import com.intellij.codeInsight.daemon.impl.TextEditorBackgroundHighlighter; import com.intellij.codeInsight.folding.CodeFoldingManager; import com.intellij.codeInsight.lookup.LookupManager; import com.intellij.codeInsight.lookup.impl.LookupImpl; -import com.intellij.openapi.actionSystem.DataConstants; +import com.intellij.openapi.actionSystem.LangDataKeys; +import com.intellij.openapi.actionSystem.PlatformDataKeys; import com.intellij.openapi.module.ModuleUtil; import com.intellij.openapi.project.Project; import com.intellij.openapi.vfs.VirtualFile; @@ -71,13 +72,13 @@ public class PsiAwareTextEditorImpl extends TextEditorImpl { } public Object getData(final String dataId) { - if (DataConstants.DOMINANT_HINT_AREA_RECTANGLE.equals(dataId)) { + if (PlatformDataKeys.DOMINANT_HINT_AREA_RECTANGLE.is(dataId)) { final LookupImpl lookup = (LookupImpl)LookupManager.getInstance(myProject).getActiveLookup(); if (lookup != null && lookup.isVisible()) { return lookup.getBounds(); } } - if (DataConstants.MODULE.equals(dataId)) { + if (LangDataKeys.MODULE.is(dataId)) { return ModuleUtil.findModuleForFile(myFile, myProject); } return super.getData(dataId); diff --git a/platform/lang-impl/src/com/intellij/openapi/fileEditor/impl/text/TextEditorPsiDataProvider.java b/platform/lang-impl/src/com/intellij/openapi/fileEditor/impl/text/TextEditorPsiDataProvider.java index 3f741c3cbd85..ef263c58b789 100644 --- a/platform/lang-impl/src/com/intellij/openapi/fileEditor/impl/text/TextEditorPsiDataProvider.java +++ b/platform/lang-impl/src/com/intellij/openapi/fileEditor/impl/text/TextEditorPsiDataProvider.java @@ -21,12 +21,13 @@ import com.intellij.ide.IdeView; import com.intellij.ide.util.EditorHelper; import com.intellij.lang.Language; import com.intellij.openapi.actionSystem.AnActionEvent; -import com.intellij.openapi.actionSystem.DataConstants; import com.intellij.openapi.actionSystem.LangDataKeys; +import com.intellij.openapi.actionSystem.PlatformDataKeys; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.editor.SelectionModel; import com.intellij.openapi.fileEditor.EditorDataProvider; import com.intellij.openapi.project.IndexNotReadyException; +import com.intellij.openapi.project.Project; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.openapi.wm.ToolWindowManager; import com.intellij.psi.*; @@ -39,7 +40,7 @@ public class TextEditorPsiDataProvider implements EditorDataProvider { public Object getData(final String dataId, final Editor e, final VirtualFile file) { if (!file.isValid()) return null; - if (dataId.equals(AnActionEvent.injectedId(DataConstants.EDITOR))) { + if (dataId.equals(AnActionEvent.injectedId(PlatformDataKeys.EDITOR.getName()))) { if (PsiDocumentManager.getInstance(e.getProject()).isUncommited(e.getDocument())) { return e; } @@ -47,34 +48,40 @@ public class TextEditorPsiDataProvider implements EditorDataProvider { return InjectedLanguageUtil.getEditorForInjectedLanguageNoCommit(e, getPsiFile(e, file)); } } - if (dataId.equals(AnActionEvent.injectedId(DataConstants.PSI_ELEMENT))) { - return getPsiElementIn((Editor)getData(AnActionEvent.injectedId(DataConstants.EDITOR), e, file), file); + if (dataId.equals(AnActionEvent.injectedId(LangDataKeys.PSI_ELEMENT.getName()))) { + return getPsiElementIn((Editor)getData(AnActionEvent.injectedId(PlatformDataKeys.EDITOR.getName()), e, file), file); } - if (DataConstants.PSI_ELEMENT.equals(dataId)){ + if (LangDataKeys.PSI_ELEMENT.is(dataId)){ return getPsiElementIn(e, file); } - if (dataId.equals(AnActionEvent.injectedId(DataConstants.LANGUAGE))) { - PsiFile psiFile = (PsiFile)getData(AnActionEvent.injectedId(DataConstants.PSI_FILE), e, file); - Editor editor = (Editor)getData(AnActionEvent.injectedId(DataConstants.EDITOR), e, file); + if (dataId.equals(AnActionEvent.injectedId(LangDataKeys.LANGUAGE.getName()))) { + PsiFile psiFile = (PsiFile)getData(AnActionEvent.injectedId(LangDataKeys.PSI_FILE.getName()), e, file); + Editor editor = (Editor)getData(AnActionEvent.injectedId(PlatformDataKeys.EDITOR.getName()), e, file); if (psiFile == null || editor == null) return null; return getLanguageAtCurrentPositionInEditor(editor, psiFile); } - if (DataConstants.LANGUAGE.equals(dataId)) { + if (LangDataKeys.LANGUAGE.is(dataId)) { final PsiFile psiFile = getPsiFile(e, file); if (psiFile == null) return null; return getLanguageAtCurrentPositionInEditor(e, psiFile); } - if (dataId.equals(AnActionEvent.injectedId(DataConstants.VIRTUAL_FILE))) { - PsiFile psiFile = (PsiFile)getData(AnActionEvent.injectedId(DataConstants.PSI_FILE), e, file); + if (dataId.equals(AnActionEvent.injectedId(PlatformDataKeys.VIRTUAL_FILE.getName()))) { + PsiFile psiFile = (PsiFile)getData(AnActionEvent.injectedId(LangDataKeys.PSI_FILE.getName()), e, file); if (psiFile == null) return null; return psiFile.getVirtualFile(); } - if (dataId.equals(AnActionEvent.injectedId(DataConstants.PSI_FILE))) { - Editor editor = (Editor)getData(AnActionEvent.injectedId(DataConstants.EDITOR), e, file); - if (editor == null) return null; - return PsiDocumentManager.getInstance(editor.getProject()).getPsiFile(editor.getDocument()); + if (dataId.equals(AnActionEvent.injectedId(LangDataKeys.PSI_FILE.getName()))) { + Editor editor = (Editor)getData(AnActionEvent.injectedId(PlatformDataKeys.EDITOR.getName()), e, file); + if (editor == null) { + return null; + } + final Project project = editor.getProject(); + if (project == null) { + return null; + } + return PsiDocumentManager.getInstance(project).getPsiFile(editor.getDocument()); } - if (dataId.equals(DataConstants.PSI_FILE)) { + if (LangDataKeys.PSI_FILE.is(dataId)) { return getPsiFile(e, file); } if (LangDataKeys.IDE_VIEW.is(dataId)) { @@ -131,7 +138,11 @@ public class TextEditorPsiDataProvider implements EditorDataProvider { if (!file.isValid()) { return null; // fix for SCR 40329 } - PsiFile psiFile = PsiManager.getInstance(e.getProject()).findFile(file); + final Project project = e.getProject(); + if (project == null) { + return null; + } + PsiFile psiFile = PsiManager.getInstance(project).findFile(file); return psiFile != null && psiFile.isValid() ? psiFile : null; } } diff --git a/platform/lang-impl/src/com/intellij/openapi/roots/ui/configuration/ContentEntryTreeEditor.java b/platform/lang-impl/src/com/intellij/openapi/roots/ui/configuration/ContentEntryTreeEditor.java index 85f89a22200e..487fed85fe48 100644 --- a/platform/lang-impl/src/com/intellij/openapi/roots/ui/configuration/ContentEntryTreeEditor.java +++ b/platform/lang-impl/src/com/intellij/openapi/roots/ui/configuration/ContentEntryTreeEditor.java @@ -20,10 +20,10 @@ import com.intellij.ide.util.treeView.AbstractTreeBuilder; import com.intellij.ide.util.treeView.AbstractTreeStructure; import com.intellij.ide.util.treeView.NodeDescriptor; import com.intellij.idea.ActionsBundle; +import com.intellij.openapi.actionSystem.CustomShortcutSet; import com.intellij.openapi.actionSystem.DataProvider; import com.intellij.openapi.actionSystem.DefaultActionGroup; import com.intellij.openapi.actionSystem.Presentation; -import com.intellij.openapi.actionSystem.CustomShortcutSet; import com.intellij.openapi.actionSystem.ex.CustomComponentAction; import com.intellij.openapi.fileChooser.FileChooserDescriptor; import com.intellij.openapi.fileChooser.FileSystemTree; @@ -34,8 +34,8 @@ import com.intellij.openapi.project.Project; import com.intellij.openapi.project.ProjectBundle; import com.intellij.openapi.roots.SourceFolder; import com.intellij.openapi.roots.ui.configuration.actions.IconWithTextAction; -import com.intellij.openapi.roots.ui.configuration.actions.ToggleSourcesStateAction; import com.intellij.openapi.roots.ui.configuration.actions.ToggleExcludedStateAction; +import com.intellij.openapi.roots.ui.configuration.actions.ToggleSourcesStateAction; import com.intellij.openapi.util.Disposer; import com.intellij.openapi.util.IconLoader; import com.intellij.openapi.vfs.VirtualFile; @@ -256,7 +256,7 @@ public abstract class ContentEntryTreeEditor { @Nullable public Object getData(@NonNls final String dataId) { - if (dataId.equals(FileSystemTree.DATA_KEY.getName())) { + if (FileSystemTree.DATA_KEY.is(dataId)) { return myFileSystemTree; } return null; diff --git a/platform/lang-impl/src/com/intellij/openapi/vfs/encoding/FileTreeTable.java b/platform/lang-impl/src/com/intellij/openapi/vfs/encoding/FileTreeTable.java index 5741dd17fdd8..1aaf4bfc588a 100644 --- a/platform/lang-impl/src/com/intellij/openapi/vfs/encoding/FileTreeTable.java +++ b/platform/lang-impl/src/com/intellij/openapi/vfs/encoding/FileTreeTable.java @@ -102,8 +102,10 @@ public class FileTreeTable extends AbstractFileTreeTable { Presentation templatePresentation = changeAction.getTemplatePresentation(); final JComponent comboComponent = changeAction.createCustomComponent(templatePresentation); - DataContext dataContext = SimpleDataContext.getSimpleContext(DataConstants.VIRTUAL_FILE, myVirtualFile, SimpleDataContext.getProjectContext(getProject())); - AnActionEvent event = new AnActionEvent(null, dataContext, ActionPlaces.UNKNOWN, templatePresentation, ActionManager.getInstance(), 0); + DataContext dataContext = SimpleDataContext + .getSimpleContext(PlatformDataKeys.VIRTUAL_FILE.getName(), myVirtualFile, SimpleDataContext.getProjectContext(getProject())); + AnActionEvent event = + new AnActionEvent(null, dataContext, ActionPlaces.UNKNOWN, templatePresentation, ActionManager.getInstance(), 0); changeAction.update(event); editorComponent = comboComponent; comboComponent.addComponentListener(new ComponentAdapter() { diff --git a/platform/lang-impl/src/com/intellij/packageDependencies/ui/DependenciesPanel.java b/platform/lang-impl/src/com/intellij/packageDependencies/ui/DependenciesPanel.java index aa8bf14a6d00..eed46ceb4939 100644 --- a/platform/lang-impl/src/com/intellij/packageDependencies/ui/DependenciesPanel.java +++ b/platform/lang-impl/src/com/intellij/packageDependencies/ui/DependenciesPanel.java @@ -436,14 +436,14 @@ public class DependenciesPanel extends JPanel implements Disposable, DataProvide @Nullable @NonNls public Object getData(@NonNls String dataId) { - if (dataId.equals(DataConstants.PSI_ELEMENT)) { + if (LangDataKeys.PSI_ELEMENT.is(dataId)) { final PackageDependenciesNode selectedNode = myRightTree.getSelectedNode(); if (selectedNode != null) { final PsiElement element = selectedNode.getPsiElement(); return element != null && element.isValid() ? element : null; } } - if (dataId.equals(DataConstants.HELP_ID)) { + if (PlatformDataKeys.HELP_ID.is(dataId)) { return "dependency.viewer.tool.window"; } return null; @@ -675,10 +675,10 @@ public class DependenciesPanel extends JPanel implements Disposable, DataProvide private static class MyTree extends Tree implements DataProvider { public Object getData(String dataId) { PackageDependenciesNode node = getSelectedNode(); - if (DataConstants.NAVIGATABLE.equals(dataId)) { + if (PlatformDataKeys.NAVIGATABLE.is(dataId)) { return node; } - if (DataConstants.PSI_ELEMENT.equals(dataId) && node != null) { + if (LangDataKeys.PSI_ELEMENT.is(dataId) && node != null) { final PsiElement element = node.getPsiElement(); return element != null && element.isValid() ? element : null; } diff --git a/platform/lang-impl/src/com/intellij/packageDependencies/ui/UsagesPanel.java b/platform/lang-impl/src/com/intellij/packageDependencies/ui/UsagesPanel.java index 2323eee43809..89733f8fc511 100644 --- a/platform/lang-impl/src/com/intellij/packageDependencies/ui/UsagesPanel.java +++ b/platform/lang-impl/src/com/intellij/packageDependencies/ui/UsagesPanel.java @@ -18,8 +18,8 @@ package com.intellij.packageDependencies.ui; import com.intellij.analysis.AnalysisScopeBundle; import com.intellij.openapi.Disposable; -import com.intellij.openapi.actionSystem.DataConstants; import com.intellij.openapi.actionSystem.DataProvider; +import com.intellij.openapi.actionSystem.PlatformDataKeys; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.progress.ProcessCanceledException; import com.intellij.openapi.progress.ProgressIndicator; @@ -114,7 +114,7 @@ public abstract class UsagesPanel extends JPanel implements Disposable, DataProv @Nullable @NonNls public Object getData(@NonNls String dataId) { - if (dataId.equals(DataConstants.HELP_ID)) { + if (PlatformDataKeys.HELP_ID.is(dataId)) { return "ideaInterface.find"; } return null; diff --git a/platform/lang-impl/src/com/intellij/refactoring/actions/MoveAction.java b/platform/lang-impl/src/com/intellij/refactoring/actions/MoveAction.java index bbe74dab4170..579e73f9ab61 100644 --- a/platform/lang-impl/src/com/intellij/refactoring/actions/MoveAction.java +++ b/platform/lang-impl/src/com/intellij/refactoring/actions/MoveAction.java @@ -18,13 +18,13 @@ package com.intellij.refactoring.actions; import com.intellij.lang.Language; import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.actionSystem.DataKey; import com.intellij.psi.PsiElement; import com.intellij.refactoring.RefactoringActionHandler; import com.intellij.refactoring.move.MoveHandler; -import org.jetbrains.annotations.NonNls; public class MoveAction extends BaseRefactoringAction { - @NonNls public static final String MOVE_PROVIDER = "MoveProvider"; + @Deprecated public static final String MOVE_PROVIDER = MoveProvider.DATA_KEY.getName(); private final MoveProvider myDefaultMoveProvider = new MoveProvider() { public boolean isEnabledOnDataContext(DataContext dataContext) { @@ -58,7 +58,7 @@ public class MoveAction extends BaseRefactoringAction { } private MoveProvider getMoveProvider(DataContext dataContext) { - final MoveProvider moveProvider = (MoveProvider)dataContext.getData(MOVE_PROVIDER); + final MoveProvider moveProvider = MoveProvider.DATA_KEY.getData(dataContext); if (moveProvider != null) { return moveProvider; } @@ -71,7 +71,10 @@ public class MoveAction extends BaseRefactoringAction { } public interface MoveProvider { + DataKey DATA_KEY = DataKey.create("MoveProvider"); + boolean isEnabledOnDataContext(DataContext dataContext); + RefactoringActionHandler getHandler(DataContext dataContext); } } \ No newline at end of file diff --git a/platform/lang-impl/src/com/intellij/refactoring/move/MoveHandler.java b/platform/lang-impl/src/com/intellij/refactoring/move/MoveHandler.java index 251122d0c454..d78608c0d5ba 100644 --- a/platform/lang-impl/src/com/intellij/refactoring/move/MoveHandler.java +++ b/platform/lang-impl/src/com/intellij/refactoring/move/MoveHandler.java @@ -21,7 +21,7 @@ package com.intellij.refactoring.move; import com.intellij.openapi.actionSystem.DataContext; -import com.intellij.openapi.actionSystem.ex.DataConstantsEx; +import com.intellij.openapi.actionSystem.LangDataKeys; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.editor.ScrollType; import com.intellij.openapi.extensions.Extensions; @@ -85,7 +85,7 @@ public class MoveHandler implements RefactoringActionHandler { * called by an Action in AtomicAction */ public void invoke(@NotNull Project project, @NotNull PsiElement[] elements, DataContext dataContext) { - doMove(project, elements, dataContext == null ? null : (PsiElement)dataContext.getData(DataConstantsEx.TARGET_PSI_ELEMENT), null); + doMove(project, elements, dataContext == null ? null : LangDataKeys.TARGET_PSI_ELEMENT.getData(dataContext), null); } /** diff --git a/platform/lang-impl/src/com/intellij/refactoring/move/moveFilesOrDirectories/MoveFilesOrDirectoriesHandler.java b/platform/lang-impl/src/com/intellij/refactoring/move/moveFilesOrDirectories/MoveFilesOrDirectoriesHandler.java index 8860f2f43189..b15a75bdd130 100644 --- a/platform/lang-impl/src/com/intellij/refactoring/move/moveFilesOrDirectories/MoveFilesOrDirectoriesHandler.java +++ b/platform/lang-impl/src/com/intellij/refactoring/move/moveFilesOrDirectories/MoveFilesOrDirectoriesHandler.java @@ -17,7 +17,7 @@ package com.intellij.refactoring.move.moveFilesOrDirectories; import com.intellij.openapi.actionSystem.DataContext; -import com.intellij.openapi.actionSystem.ex.DataConstantsEx; +import com.intellij.openapi.actionSystem.LangDataKeys; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.project.Project; @@ -70,7 +70,7 @@ public class MoveFilesOrDirectoriesHandler extends MoveHandlerDelegate { final Editor editor) { if ((element instanceof PsiFile && ((PsiFile)element).getVirtualFile() != null) || element instanceof PsiDirectory) { - doMove(project, new PsiElement[]{element}, (PsiElement)dataContext.getData(DataConstantsEx.TARGET_PSI_ELEMENT), null); + doMove(project, new PsiElement[]{element}, LangDataKeys.TARGET_PSI_ELEMENT.getData(dataContext), null); return true; } if (element instanceof PsiPlainText) { diff --git a/platform/lang-impl/src/com/intellij/unscramble/AnalyzeStacktraceUtil.java b/platform/lang-impl/src/com/intellij/unscramble/AnalyzeStacktraceUtil.java index 2854e95149c6..4c724bb46fd1 100644 --- a/platform/lang-impl/src/com/intellij/unscramble/AnalyzeStacktraceUtil.java +++ b/platform/lang-impl/src/com/intellij/unscramble/AnalyzeStacktraceUtil.java @@ -72,7 +72,7 @@ public class AnalyzeStacktraceUtil { text = (String)contents.getTransferData(DataFlavor.stringFlavor); } } - catch (Exception ex) { + catch (Exception ignore) { } return text; } @@ -141,7 +141,7 @@ public class AnalyzeStacktraceUtil { } public Object getData(String dataId) { - if (DataConstants.EDITOR.equals(dataId)) { + if (PlatformDataKeys.EDITOR.is(dataId)) { return myEditor; } return null; diff --git a/platform/lang-impl/src/com/intellij/util/ui/tree/LanguagePerFileConfigurable.java b/platform/lang-impl/src/com/intellij/util/ui/tree/LanguagePerFileConfigurable.java index 6d7a461d011a..18132e22267f 100644 --- a/platform/lang-impl/src/com/intellij/util/ui/tree/LanguagePerFileConfigurable.java +++ b/platform/lang-impl/src/com/intellij/util/ui/tree/LanguagePerFileConfigurable.java @@ -152,8 +152,9 @@ public abstract class LanguagePerFileConfigurable implements SearchableConfig final JComponent comboComponent = changeAction.createCustomComponent(templatePresentation); DataContext dataContext = SimpleDataContext - .getSimpleContext(DataConstants.VIRTUAL_FILE, myVirtualFile, SimpleDataContext.getProjectContext(getProject())); - AnActionEvent event = new AnActionEvent(null, dataContext, ActionPlaces.UNKNOWN, templatePresentation, ActionManager.getInstance(), 0); + .getSimpleContext(PlatformDataKeys.VIRTUAL_FILE.getName(), myVirtualFile, SimpleDataContext.getProjectContext(getProject())); + AnActionEvent event = + new AnActionEvent(null, dataContext, ActionPlaces.UNKNOWN, templatePresentation, ActionManager.getInstance(), 0); changeAction.update(event); editorComponent = comboComponent; comboComponent.addComponentListener(new ComponentAdapter() { diff --git a/platform/lvcs-impl/testSrc/com/intellij/historyIntegrTests/ui/LocalHistoryActionsTest.java b/platform/lvcs-impl/testSrc/com/intellij/historyIntegrTests/ui/LocalHistoryActionsTest.java index 8cdd5476dd03..20491bd9ba2c 100644 --- a/platform/lvcs-impl/testSrc/com/intellij/historyIntegrTests/ui/LocalHistoryActionsTest.java +++ b/platform/lvcs-impl/testSrc/com/intellij/historyIntegrTests/ui/LocalHistoryActionsTest.java @@ -56,7 +56,7 @@ public class LocalHistoryActionsTest extends LocalHistoryUITestCase { super.tearDown(); } - private EditorFactory getEditorFactory() { + private static EditorFactory getEditorFactory() { return EditorFactory.getInstance(); } @@ -129,12 +129,12 @@ public class LocalHistoryActionsTest extends LocalHistoryUITestCase { DataContext dc = new DataContext() { @Nullable public Object getData(String id) { - if (id.equals(PlatformDataKeys.VIRTUAL_FILE_ARRAY.getName())) return files; - if (id.equals(PlatformDataKeys.EDITOR.getName())) return editor; - if (id.equals(PlatformDataKeys.PROJECT.getName())) return p; + if (PlatformDataKeys.VIRTUAL_FILE_ARRAY.is(id)) return files; + if (PlatformDataKeys.EDITOR.is(id)) return editor; + if (PlatformDataKeys.PROJECT.is(id)) return p; return null; } }; return new AnActionEvent(null, dc, "", a.getTemplatePresentation(), null, -1); } -} \ No newline at end of file +} diff --git a/platform/platform-api/src/com/intellij/ide/SelectInContext.java b/platform/platform-api/src/com/intellij/ide/SelectInContext.java index a3cde4b242ae..2568e95ed1c9 100644 --- a/platform/platform-api/src/com/intellij/ide/SelectInContext.java +++ b/platform/platform-api/src/com/intellij/ide/SelectInContext.java @@ -15,9 +15,9 @@ */ package com.intellij.ide; +import com.intellij.openapi.actionSystem.DataKey; import com.intellij.openapi.project.Project; import com.intellij.openapi.vfs.VirtualFile; -import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -25,8 +25,9 @@ import org.jetbrains.annotations.Nullable; * @author kir */ public interface SelectInContext { + DataKey DATA_KEY = DataKey.create("SelectInContext"); - @NonNls String DATA_CONTEXT_ID = "SelectInContext"; + @Deprecated String DATA_CONTEXT_ID = DATA_KEY.getName(); @NotNull Project getProject(); diff --git a/platform/platform-api/src/com/intellij/ide/actions/ContextHelpAction.java b/platform/platform-api/src/com/intellij/ide/actions/ContextHelpAction.java index 239555c5fe22..2ef76979a9c0 100644 --- a/platform/platform-api/src/com/intellij/ide/actions/ContextHelpAction.java +++ b/platform/platform-api/src/com/intellij/ide/actions/ContextHelpAction.java @@ -18,8 +18,8 @@ package com.intellij.ide.actions; import com.intellij.CommonBundle; import com.intellij.openapi.actionSystem.*; import com.intellij.openapi.help.HelpManager; -import com.intellij.openapi.util.IconLoader; import com.intellij.openapi.project.DumbAware; +import com.intellij.openapi.util.IconLoader; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.Nullable; @@ -47,14 +47,7 @@ public class ContextHelpAction extends AnAction implements DumbAware { @Nullable protected String getHelpId(DataContext dataContext) { - if (myHelpID != null) { - return myHelpID; - } - Object helpIDObj = dataContext.getData(DataConstants.HELP_ID); - if (helpIDObj != null) { - return helpIDObj.toString(); - } - return null; + return myHelpID != null ? myHelpID : PlatformDataKeys.HELP_ID.getData(dataContext); } public void update(AnActionEvent event){ diff --git a/platform/platform-api/src/com/intellij/openapi/actionSystem/DataConstants.java b/platform/platform-api/src/com/intellij/openapi/actionSystem/DataConstants.java index b5859e613039..776b2e9f8673 100644 --- a/platform/platform-api/src/com/intellij/openapi/actionSystem/DataConstants.java +++ b/platform/platform-api/src/com/intellij/openapi/actionSystem/DataConstants.java @@ -20,159 +20,231 @@ import org.jetbrains.annotations.NonNls; /** * Identifiers for data items which can be returned from {@link DataContext#getData(String)} and * {@link DataProvider#getData(String)}. + * * @deprecated {@link DataKeys} and {@link DataKey#getData} should be used instead */ - -@SuppressWarnings({"HardCodedStringLiteral"}) +@SuppressWarnings({"HardCodedStringLiteral", "JavadocReference", "UnusedDeclaration"}) public interface DataConstants { /** * Returns {@link com.intellij.openapi.project.Project} + * + * @deprecated use {@link com.intellij.openapi.actionSystem.PlatformDataKeys#PROJECT} instead */ - String PROJECT = "project"; + String PROJECT = PlatformDataKeys.PROJECT.getName(); /** * Returns {@link com.intellij.openapi.module.Module} + * + * @depreacated use {@link com.intellij.openapi.actionSystem.LangDataKeys#MODULE} instead */ - String MODULE = "module"; + @NonNls String MODULE = "module"; /** * Returns {@link com.intellij.openapi.vfs.VirtualFile} + * + * @deprecated use {@link com.intellij.openapi.actionSystem.PlatformDataKeys#VIRTUAL_FILE} instead */ - String VIRTUAL_FILE = "virtualFile"; + String VIRTUAL_FILE = PlatformDataKeys.VIRTUAL_FILE.getName(); /** * Returns array of {@link com.intellij.openapi.vfs.VirtualFile} + * + * @deprecated use {@link com.intellij.openapi.actionSystem.PlatformDataKeys#VIRTUAL_FILE_ARRAY} instead */ - String VIRTUAL_FILE_ARRAY = "virtualFileArray"; + String VIRTUAL_FILE_ARRAY = PlatformDataKeys.VIRTUAL_FILE_ARRAY.getName(); /** * Returns {@link com.intellij.openapi.editor.Editor} + * + * @deprecated use {@link com.intellij.openapi.actionSystem.PlatformDataKeys#EDITOR} instead */ - String EDITOR = "editor"; + String EDITOR = PlatformDataKeys.EDITOR.getName(); /** * Returns {@link com.intellij.openapi.fileEditor.FileEditor} + * + * @deprecated use {@link com.intellij.openapi.actionSystem.PlatformDataKeys#FILE_EDITOR} instead */ - String FILE_EDITOR = "fileEditor"; + String FILE_EDITOR = PlatformDataKeys.FILE_EDITOR.getName(); /** * Returns {@link com.intellij.openapi.fileEditor.OpenFileDescriptor} - * @deprecated {@link #NAVIGATABLE} should be used instead + * + * @deprecated {@link com.intellij.openapi.actionSystem.PlatformDataKeys#NAVIGATABLE} should be used instead */ - String OPEN_FILE_DESCRIPTOR = "openFileDescriptor"; + @NonNls String OPEN_FILE_DESCRIPTOR = "openFileDescriptor"; /** * Returns the text of currently selected file/file revision + * + * @deprecated use {@link com.intellij.openapi.actionSystem.PlatformDataKey#FILE_TEXT} instead */ - String FILE_TEXT = "fileText"; + String FILE_TEXT = PlatformDataKeys.FILE_TEXT.getName(); /** * Returns Boolean.TRUE if action is executed in modal context and * Boolean.FALSE if action is executed not in modal context. If context * is unknown then the value of this data constant is null. + * + * @deprecated use {@link com.intellij.openapi.actionSystem.PlatformDataKeys#IS_MODAL_CONTEXT} instead */ - String IS_MODAL_CONTEXT = "isModalContext"; + String IS_MODAL_CONTEXT = PlatformDataKeys.IS_MODAL_CONTEXT.getName(); /** * Returns {@link com.intellij.openapi.diff.DiffViewer} + * + * @deprecated use {@link com.intellij.openapi.actionSystem.PlatformDataKeys#DIFF_VIEWER} instead */ - String DIFF_VIEWER = "diffViewer"; + String DIFF_VIEWER = PlatformDataKeys.DIFF_VIEWER.getName(); + /** * Returns help id (String) + * + * @deprecated use {@link com.intellij.openapi.actionSystem.PlatformDataKeys#HELP_ID} instead */ - String HELP_ID = "helpId"; + String HELP_ID = PlatformDataKeys.HELP_ID.getName(); + /** * Returns project if project node is selected (in project view) + * + * @deprecated use {@link com.intellij.openapi.actionSystem.PlatformDataKeys#PROJECT_CONTEXT} instead */ - String PROJECT_CONTEXT = "context.Project"; + String PROJECT_CONTEXT = PlatformDataKeys.PROJECT_CONTEXT.getName(); + /** * Returns module if module node is selected (in module view) + * + * @deprecated use {@link com.intellij.openapi.actionSystem.LangDataKeys.MODULE_CONTEXT} instead */ - String MODULE_CONTEXT = "context.Module"; - String MODULE_CONTEXT_ARRAY = "context.Module.Array"; + @NonNls String MODULE_CONTEXT = "context.Module"; + + /** + * @deprecated use {@link com.intellij.openapi.actionSystem.LangDataKeys#MODULE_CONTEXT_ARRAY} instead + */ + @NonNls String MODULE_CONTEXT_ARRAY = "context.Module.Array"; /** * Returns {@link com.intellij.pom.Navigatable} + * + * @deprecated use {@link com.intellij.openapi.actionSystem.PlatformDataKeys#NAVIGATABLE} instead */ - String NAVIGATABLE = "Navigatable"; + String NAVIGATABLE = PlatformDataKeys.NAVIGATABLE.getName(); /** * Returns an array of {@link com.intellij.pom.Navigatable} + * + * @deprecated use {@link com.intellij.openapi.actionSystem.PlatformDataKeys#NAVIGATABLE_ARRAY} instead */ - String NAVIGATABLE_ARRAY = "NavigatableArray"; + String NAVIGATABLE_ARRAY = PlatformDataKeys.NAVIGATABLE_ARRAY.getName(); /** * Returns {@link com.intellij.ide.ExporterToTextFile} + * + * @deprecated use {@link com.intellij.openapi.actionSystem.PlatformDataKeys#EXPORTER_TO_TEXT_FILE} instead */ - - String EXPORTER_TO_TEXT_FILE = "exporterToTextFile"; + String EXPORTER_TO_TEXT_FILE = PlatformDataKeys.EXPORTER_TO_TEXT_FILE.getName(); /** * Returns {@link com.intellij.psi.PsiElement} + * + * @deprecated use {@link com.intellij.openapi.actionSystem.LangDataKeys#PSI_ELEMENT} instead */ - String PSI_ELEMENT = "psi.Element"; + @NonNls String PSI_ELEMENT = "psi.Element"; /** * Returns {@link com.intellij.psi.PsiFile} + * + * @deprecated use {@link com.intellij.openapi.actionSystem.LangDataKeys.PSI_FILE} instead */ - String PSI_FILE = "psi.File"; + @NonNls String PSI_FILE = "psi.File"; /** * Returns {@link com.intellij.lang.Language} + * + * @deprecated use {@link com.intellij.openapi.actionSystem.LangDataKeys.LANGUAGE} instead */ - String LANGUAGE = "Language"; + @NonNls String LANGUAGE = "Language"; /** * Returns java.awt.Component currently in focus, DataContext should be retreived for + * + * @deprecated use {@link com.intellij.openapi.actionSystem.PlatformDataKeys#CONTEXT_COMPONENT} instead */ - @NonNls String CONTEXT_COMPONENT = "contextComponent"; + String CONTEXT_COMPONENT = PlatformDataKeys.CONTEXT_COMPONENT.getName(); /** * Returns {@link com.intellij.ide.IdeView} (one of project, packages, commander or favorites view). * * @since 5.1 + * @deprecated use {@link com.intellij.openapi.actionSystem.LangDataKeys#IDE_VIEW} instead */ @NonNls String IDE_VIEW = "IDEView"; /** * Returns array of selected {@link com.intellij.openapi.vcs.changes.ChangeList}s. + * * @since 6.0 + * @deprecated use {@link com.intellij.openapi.vcs.VcsDataKeys#CHANGE_LISTS} instead */ @NonNls String CHANGE_LISTS = "vcs.ChangeList"; /** * Returns array of selected {@link com.intellij.openapi.vcs.changes.Change}s. + * * @since 6.0 + * @deprecated use {@link com.intellij.openapi.vcs.VcsDataKeys#CHANGES} instead */ @NonNls String CHANGES = "vcs.Change"; /** * Returns com.intellij.psi.PsiElement[] + * + * @deprecated use {@link com.intellij.openapi.actionSystem.LangDataKeys#PSI_ELEMENT_ARRAY} instead */ @NonNls String PSI_ELEMENT_ARRAY = "psi.Element.array"; + /** * Returns com.intellij.ide.CopyProvider + * + * @deprecated use {@link com.intellij.openapi.actionSystem.PlatformDataKeys#COPY_PROVIDER} instead */ - @NonNls String COPY_PROVIDER = "copyProvider"; + String COPY_PROVIDER = PlatformDataKeys.COPY_PROVIDER.getName(); + /** * Returns com.intellij.ide.CutProvider + * + * @deprecated use {@link com.intellij.openapi.actionSystem.PlatformDataKeys#CUT_PROVIDER} instead */ - @NonNls String CUT_PROVIDER = "cutProvider"; + String CUT_PROVIDER = PlatformDataKeys.CUT_PROVIDER.getName(); + /** * Returns com.intellij.ide.PasteProvider + * + * @deprecated use {@link com.intellij.openapi.actionSystem.PlatformDataKeys#PASTE_PROVIDER} instead */ - @NonNls String PASTE_PROVIDER = "pasteProvider"; + String PASTE_PROVIDER = PlatformDataKeys.PASTE_PROVIDER.getName(); + /** * Returns com.intellij.ide.DeleteProvider + * + * @deprecated use {@link com.intellij.openapi.actionSystem.PlatformDataKeys#DELETE_ELEMENT_PROVIDER} instead */ - @NonNls String DELETE_ELEMENT_PROVIDER = "deleteElementProvider"; + String DELETE_ELEMENT_PROVIDER = PlatformDataKeys.DELETE_ELEMENT_PROVIDER.getName(); /** * Returns com.intellij.openapi.editor.Editor even if foces currently is in find bar + * + * @deprecated use {@link com.intellij.openapi.actionSystem.PlatformDataKeys#EDITOR} instead */ - @NonNls String EDITOR_EVEN_IF_INACTIVE = "editor.even.if.inactive"; + String EDITOR_EVEN_IF_INACTIVE = PlatformDataKeys.EDITOR_EVEN_IF_INACTIVE.getName(); - @NonNls String SELECTED_ITEM = "selectedItem"; + /** + * @deprecated use {@link com.intellij.openapi.actionSystem.PlatformDataKeys#SELECTED_ITEM} instead + */ + String SELECTED_ITEM = PlatformDataKeys.SELECTED_ITEM.getName(); - @NonNls String DOMINANT_HINT_AREA_RECTANGLE = "dominant.hint.rectangle"; + /** + * @deprecated use {@link com.intellij.openapi.actionSystem.PlatformDataKeys#DOMINANT_HINT_AREA_RECTANGLE} instead + */ + String DOMINANT_HINT_AREA_RECTANGLE = PlatformDataKeys.DOMINANT_HINT_AREA_RECTANGLE.getName(); } diff --git a/platform/platform-api/src/com/intellij/openapi/actionSystem/DataContext.java b/platform/platform-api/src/com/intellij/openapi/actionSystem/DataContext.java index a9c9b5b03e25..a28cfb91f264 100644 --- a/platform/platform-api/src/com/intellij/openapi/actionSystem/DataContext.java +++ b/platform/platform-api/src/com/intellij/openapi/actionSystem/DataContext.java @@ -22,13 +22,14 @@ import org.jetbrains.annotations.Nullable; * Allows an action to retrieve information about the context in which it was invoked. * * @see com.intellij.openapi.actionSystem.AnActionEvent#getDataContext() - * @see DataConstants + * @see com.intellij.openapi.actionSystem.PlatformDataKeys + * @see com.intellij.openapi.actionSystem.DataKey * @see DataProvider */ public interface DataContext { /** * Returns the object corresponding to the specified data identifier. Some of the supported - * data identifiers are defined in the {@link DataConstants} class. + * data identifiers are defined in the {@link com.intellij.openapi.actionSystem.PlatformDataKeys} class. * * @param dataId the data identifier for which the value is requested. * @return the value, or null if no value is available in the current context for this identifier. diff --git a/platform/platform-api/src/com/intellij/openapi/actionSystem/DataKey.java b/platform/platform-api/src/com/intellij/openapi/actionSystem/DataKey.java index b7931fa7ac14..e8f09344f49a 100644 --- a/platform/platform-api/src/com/intellij/openapi/actionSystem/DataKey.java +++ b/platform/platform-api/src/com/intellij/openapi/actionSystem/DataKey.java @@ -72,4 +72,10 @@ public class DataKey { //noinspection unchecked return (T) dataContext.getData(myName); } + + @Nullable + public T getData(DataProvider dataProvider) { + //noinspection unchecked + return (T) dataProvider.getData(myName); + } } \ No newline at end of file diff --git a/platform/platform-api/src/com/intellij/openapi/actionSystem/DataProvider.java b/platform/platform-api/src/com/intellij/openapi/actionSystem/DataProvider.java index 0d1595eff49c..53a59cb912b3 100644 --- a/platform/platform-api/src/com/intellij/openapi/actionSystem/DataProvider.java +++ b/platform/platform-api/src/com/intellij/openapi/actionSystem/DataProvider.java @@ -15,23 +15,23 @@ */ package com.intellij.openapi.actionSystem; -import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.NonNls; +import org.jetbrains.annotations.Nullable; /** * Allows a component hosting actions to provide context information to the actions. When a specific * data item is requested, the component hierarchy is walked up from the currently focused component, * and every component implementing the DataProvider interface is queried for the data * until one of them returns the data. Data items can also be mapped to each other - for example, - * if a data provider provides an item for {@link DataConstants#NAVIGATABLE}, an item for - * {@link DataConstants#NAVIGATABLE_ARRAY} can be generated from it automatically. + * if a data provider provides an item for {@link PlatformDataKeys#NAVIGATABLE}, an item for + * {@link PlatformDataKeys#NAVIGATABLE_ARRAY} can be generated from it automatically. * * @see DataContext */ public interface DataProvider { /** * Returns the object corresponding to the specified data identifier. Some of the supported - * data identifiers are defined in the {@link DataConstants} class. + * data identifiers are defined in the {@link com.intellij.openapi.actionSystem.PlatformDataKeys} class. * * @param dataId the data identifier for which the value is requested. * @return the value, or null if no value is available in the current context for this identifier. diff --git a/platform/platform-api/src/com/intellij/openapi/actionSystem/PlatformDataKeys.java b/platform/platform-api/src/com/intellij/openapi/actionSystem/PlatformDataKeys.java index 9bb9c62503c7..295375a0cccf 100644 --- a/platform/platform-api/src/com/intellij/openapi/actionSystem/PlatformDataKeys.java +++ b/platform/platform-api/src/com/intellij/openapi/actionSystem/PlatformDataKeys.java @@ -17,7 +17,7 @@ package com.intellij.openapi.actionSystem; import com.intellij.ide.*; import com.intellij.openapi.Disposable; -import com.intellij.openapi.actionSystem.ex.DataConstantsEx; +import com.intellij.openapi.application.ModalityState; import com.intellij.openapi.diff.DiffViewer; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.fileEditor.FileEditor; @@ -32,31 +32,61 @@ import java.awt.*; /** * @author yole */ -@SuppressWarnings({"deprecation"}) public class PlatformDataKeys { - public static final DataKey PROJECT = DataKey.create(DataConstants.PROJECT); - public static final DataKey EDITOR = DataKey.create(DataConstants.EDITOR); - public static final DataKey EDITOR_EVEN_IF_INACTIVE = DataKey.create(DataConstants.EDITOR_EVEN_IF_INACTIVE); - public static final DataKey NAVIGATABLE = DataKey.create(DataConstants.NAVIGATABLE); - public static final DataKey NAVIGATABLE_ARRAY = DataKey.create(DataConstants.NAVIGATABLE_ARRAY); - public static final DataKey VIRTUAL_FILE = DataKey.create(DataConstants.VIRTUAL_FILE); - public static final DataKey VIRTUAL_FILE_ARRAY = DataKey.create(DataConstants.VIRTUAL_FILE_ARRAY); - public static final DataKey FILE_EDITOR = DataKey.create(DataConstants.FILE_EDITOR); - public static final DataKey FILE_TEXT = DataKey.create(DataConstants.FILE_TEXT); - public static final DataKey IS_MODAL_CONTEXT = DataKey.create(DataConstants.IS_MODAL_CONTEXT); - public static final DataKey DIFF_VIEWER = DataKey.create(DataConstants.DIFF_VIEWER); - public static final DataKey HELP_ID = DataKey.create(DataConstants.HELP_ID); - public static final DataKey PROJECT_CONTEXT = DataKey.create(DataConstants.PROJECT_CONTEXT); - public static final DataKey CONTEXT_COMPONENT = DataKey.create(DataConstants.CONTEXT_COMPONENT); - public static final DataKey COPY_PROVIDER = DataKey.create(DataConstants.COPY_PROVIDER); - public static final DataKey CUT_PROVIDER = DataKey.create(DataConstants.CUT_PROVIDER); - public static final DataKey PASTE_PROVIDER = DataKey.create(DataConstants.PASTE_PROVIDER); - public static final DataKey DELETE_ELEMENT_PROVIDER = DataKey.create(DataConstants.DELETE_ELEMENT_PROVIDER); - public static final DataKey CONTENT_MANAGER = DataKey.create(DataConstantsEx.CONTENT_MANAGER); + public static final DataKey PROJECT = DataKey.create("project"); + public static final DataKey EDITOR = DataKey.create("editor"); + + /** + * Returns com.intellij.openapi.editor.Editor even if foces currently is in find bar + */ + public static final DataKey EDITOR_EVEN_IF_INACTIVE = DataKey.create("editor.even.if.inactive"); + public static final DataKey NAVIGATABLE = DataKey.create("Navigatable"); + public static final DataKey NAVIGATABLE_ARRAY = DataKey.create("NavigatableArray"); + public static final DataKey VIRTUAL_FILE = DataKey.create("virtualFile"); + public static final DataKey VIRTUAL_FILE_ARRAY = DataKey.create("virtualFileArray"); + public static final DataKey FILE_EDITOR = DataKey.create("fileEditor"); + + /** + * Returns the text of currently selected file/file revision + */ + public static final DataKey FILE_TEXT = DataKey.create("fileText"); + + /** + * Returns Boolean.TRUE if action is executed in modal context and + * Boolean.FALSE if action is executed not in modal context. If context + * is unknown then the value of this data constant is null. + */ + public static final DataKey IS_MODAL_CONTEXT = DataKey.create("isModalContext"); + public static final DataKey DIFF_VIEWER = DataKey.create("diffViewer"); + + /** + * Returns help id (String) + */ + public static final DataKey HELP_ID = DataKey.create("helpId"); + + /** + * Returns project if project node is selected (in project view) + */ + public static final DataKey PROJECT_CONTEXT = DataKey.create("context.Project"); + + /** + * Returns java.awt.Component currently in focus, DataContext should be retreived for + */ + public static final DataKey CONTEXT_COMPONENT = DataKey.create("contextComponent"); + public static final DataKey COPY_PROVIDER = DataKey.create("copyProvider"); + public static final DataKey CUT_PROVIDER = DataKey.create("cutProvider"); + public static final DataKey PASTE_PROVIDER = DataKey.create("pasteProvider"); + public static final DataKey DELETE_ELEMENT_PROVIDER = DataKey.create("deleteElementProvider"); + public static final DataKey SELECTED_ITEM = DataKey.create("selectedItem"); + public static final DataKey DOMINANT_HINT_AREA_RECTANGLE = DataKey.create("dominant.hint.rectangle"); + public static final DataKey CONTENT_MANAGER = DataKey.create("contentManager"); public static final DataKey TOOL_WINDOW = DataKey.create("TOOL_WINDOW"); - public static final DataKey TREE_EXPANDER = DataKey.create(DataConstantsEx.TREE_EXPANDER); - public static final DataKey EXPORTER_TO_TEXT_FILE = DataKey.create(DataConstants.EXPORTER_TO_TEXT_FILE); - public static final DataKey PROJECT_FILE_DIRECTORY = DataKey.create(DataConstantsEx.PROJECT_FILE_DIRECTORY); + public static final DataKey TREE_EXPANDER = DataKey.create("treeExpander"); + public static final DataKey EXPORTER_TO_TEXT_FILE = DataKey.create("exporterToTextFile"); + public static final DataKey PROJECT_FILE_DIRECTORY = DataKey.create("context.ProjectFileDirectory"); public static final DataKey UI_DISPOSABLE = DataKey.create("ui.disposable"); -} \ No newline at end of file + public static final DataKey NONEMPTY_CONTENT_MANAGER = DataKey.create("nonemptyContentManager"); + public static final DataKey MODALITY_STATE = DataKey.create("ModalityState"); + public static final DataKey SOURCE_NAVIGATION_LOCKED = DataKey.create("sourceNavigationLocked"); +} diff --git a/platform/platform-api/src/com/intellij/openapi/actionSystem/ex/ActionUtil.java b/platform/platform-api/src/com/intellij/openapi/actionSystem/ex/ActionUtil.java index 6f57051840a5..1872d5dbd358 100644 --- a/platform/platform-api/src/com/intellij/openapi/actionSystem/ex/ActionUtil.java +++ b/platform/platform-api/src/com/intellij/openapi/actionSystem/ex/ActionUtil.java @@ -15,10 +15,7 @@ */ package com.intellij.openapi.actionSystem.ex; -import com.intellij.openapi.actionSystem.ActionGroup; -import com.intellij.openapi.actionSystem.AnAction; -import com.intellij.openapi.actionSystem.AnActionEvent; -import com.intellij.openapi.actionSystem.Presentation; +import com.intellij.openapi.actionSystem.*; import com.intellij.openapi.application.ApplicationNamesInfo; import com.intellij.openapi.project.DumbAware; import com.intellij.openapi.project.DumbService; @@ -47,7 +44,7 @@ public class ActionUtil { actionNames.add(s); } - final Project _project = (Project)event.getDataContext().getData(DataConstantsEx.PROJECT); + final Project _project = PlatformDataKeys.PROJECT.getData(event.getDataContext()); if (_project != null && project == null) { project = _project; } @@ -82,7 +79,7 @@ public class ActionUtil { public static boolean performDumbAwareUpdate(AnAction action, AnActionEvent e, boolean beforeActionPerformed) { final Presentation presentation = e.getPresentation(); final Boolean wasEnabledBefore = (Boolean)presentation.getClientProperty(WAS_ENABLED_BEFORE_DUMB); - final Project project = (Project)e.getDataContext().getData(DataConstantsEx.PROJECT); + final Project project = PlatformDataKeys.PROJECT.getData(e.getDataContext()); final boolean dumbMode = project != null && DumbService.getInstance(project).isDumb(); if (wasEnabledBefore != null && !dumbMode) { presentation.putClientProperty(WAS_ENABLED_BEFORE_DUMB, null); @@ -124,7 +121,7 @@ public class ActionUtil { public static boolean lastUpdateAndCheckDumb(AnAction action, AnActionEvent e, boolean visibilityMatters) { performDumbAwareUpdate(action, e, true); - final Project project = (Project)e.getDataContext().getData(DataConstantsEx.PROJECT); + final Project project = PlatformDataKeys.PROJECT.getData(e.getDataContext()); if (project != null && DumbService.getInstance(project).isDumb() && !(action instanceof DumbAware)) { if (Boolean.FALSE.equals(e.getPresentation().getClientProperty(WOULD_BE_ENABLED_IF_NOT_DUMB_MODE))) { return false; @@ -147,4 +144,4 @@ public class ActionUtil { return true; } -} \ No newline at end of file +} diff --git a/platform/platform-api/src/com/intellij/openapi/actionSystem/ex/DataConstantsEx.java b/platform/platform-api/src/com/intellij/openapi/actionSystem/ex/DataConstantsEx.java index 68074f37393d..1719770e674f 100644 --- a/platform/platform-api/src/com/intellij/openapi/actionSystem/ex/DataConstantsEx.java +++ b/platform/platform-api/src/com/intellij/openapi/actionSystem/ex/DataConstantsEx.java @@ -16,10 +16,16 @@ package com.intellij.openapi.actionSystem.ex; -import com.intellij.openapi.actionSystem.DataConstants; import org.jetbrains.annotations.NonNls; -public interface DataConstantsEx extends DataConstants { + +/** + * Identifiers for data items which can be returned from {@link com.intellij.openapi.actionSystem.DataContext#getData(String)} and + * {@link com.intellij.openapi.actionSystem.DataProvider#getData(String)}. + * @deprecated {@link DataKeys} and {@link com.intellij.openapi.actionSystem.DataKey#getData} should be used instead + */ +@SuppressWarnings({"HardCodedStringLiteral", "JavadocReference", "UnusedDeclaration"}) +public interface DataConstantsEx { /** * Returns {@link com.intellij.psi.PsiElement} */ diff --git a/platform/platform-api/src/com/intellij/openapi/diff/DiffToolbar.java b/platform/platform-api/src/com/intellij/openapi/diff/DiffToolbar.java index f26547187dd6..1ad292a5e9d4 100644 --- a/platform/platform-api/src/com/intellij/openapi/diff/DiffToolbar.java +++ b/platform/platform-api/src/com/intellij/openapi/diff/DiffToolbar.java @@ -21,7 +21,7 @@ import org.jetbrains.annotations.NotNull; public interface DiffToolbar { /** * An action can access diff view via {@link com.intellij.openapi.actionSystem.DataContext}. - * @see com.intellij.openapi.actionSystem.DataConstants#DIFF_VIEWER + * @see com.intellij.openapi.actionSystem.PlatformDataKeys#DIFF_VIEWER * @see AnAction#update(com.intellij.openapi.actionSystem.AnActionEvent) * @see AnAction#actionPerformed(com.intellij.openapi.actionSystem.AnActionEvent) * @see com.intellij.openapi.actionSystem.DataContext diff --git a/platform/platform-api/src/com/intellij/openapi/editor/actionSystem/EditorAction.java b/platform/platform-api/src/com/intellij/openapi/editor/actionSystem/EditorAction.java index 8cbd5a055c99..e25fdd49b1cf 100644 --- a/platform/platform-api/src/com/intellij/openapi/editor/actionSystem/EditorAction.java +++ b/platform/platform-api/src/com/intellij/openapi/editor/actionSystem/EditorAction.java @@ -109,11 +109,13 @@ public abstract class EditorAction extends AnAction implements DumbAware { } private static DataContext getProjectAwareDataContext(final Editor editor, final DataContext original) { - if (original.getData(DataConstants.PROJECT) == editor.getProject()) return original; + if (PlatformDataKeys.PROJECT.getData(original) == editor.getProject()) { + return original; + } return new DataContext() { public Object getData(String dataId) { - if (DataConstants.PROJECT.equals(dataId)) { + if (PlatformDataKeys.PROJECT.is(dataId)) { return editor.getProject(); } return original.getData(dataId); diff --git a/platform/platform-api/src/com/intellij/openapi/ui/PanelWithActionsAndCloseButton.java b/platform/platform-api/src/com/intellij/openapi/ui/PanelWithActionsAndCloseButton.java index 4335fc6358df..dc388b16e909 100644 --- a/platform/platform-api/src/com/intellij/openapi/ui/PanelWithActionsAndCloseButton.java +++ b/platform/platform-api/src/com/intellij/openapi/ui/PanelWithActionsAndCloseButton.java @@ -17,8 +17,8 @@ package com.intellij.openapi.ui; import com.intellij.CommonBundle; import com.intellij.openapi.actionSystem.*; -import com.intellij.openapi.util.IconLoader; import com.intellij.openapi.project.DumbAware; +import com.intellij.openapi.util.IconLoader; import com.intellij.ui.content.Content; import com.intellij.ui.content.ContentManager; import com.intellij.ui.content.ContentManagerAdapter; @@ -67,7 +67,7 @@ public abstract class PanelWithActionsAndCloseButton extends JPanel implements D } public Object getData(String dataId) { - if (DataConstants.HELP_ID.equals(dataId)){ + if (PlatformDataKeys.HELP_ID.is(dataId)){ return myHelpId; } return null; diff --git a/platform/platform-api/src/com/intellij/openapi/ui/popup/PopupChooserBuilder.java b/platform/platform-api/src/com/intellij/openapi/ui/popup/PopupChooserBuilder.java index 0cd8fadbe963..0e8c6767b7dd 100644 --- a/platform/platform-api/src/com/intellij/openapi/ui/popup/PopupChooserBuilder.java +++ b/platform/platform-api/src/com/intellij/openapi/ui/popup/PopupChooserBuilder.java @@ -16,8 +16,8 @@ package com.intellij.openapi.ui.popup; -import com.intellij.openapi.actionSystem.DataConstants; import com.intellij.openapi.actionSystem.DataProvider; +import com.intellij.openapi.actionSystem.PlatformDataKeys; import com.intellij.openapi.util.Computable; import com.intellij.openapi.util.Pair; import com.intellij.ui.InplaceButton; @@ -428,7 +428,7 @@ public class PopupChooserBuilder { @Nullable public Object getData(@NonNls String dataId) { - if (dataId.equals(DataConstants.SELECTED_ITEM)){ + if (PlatformDataKeys.SELECTED_ITEM.is(dataId)){ return myList.getSelectedValue(); } return null; diff --git a/platform/platform-api/src/com/intellij/ui/ClearTextAction.java b/platform/platform-api/src/com/intellij/ui/ClearTextAction.java index 44019a2ef1c5..d98b1bfb4721 100644 --- a/platform/platform-api/src/com/intellij/ui/ClearTextAction.java +++ b/platform/platform-api/src/com/intellij/ui/ClearTextAction.java @@ -14,23 +14,19 @@ * limitations under the License. */ -/* - * Created by IntelliJ IDEA. - * User: Anna.Kozlova - * Date: 01-Sep-2006 - * Time: 21:17:18 - */ package com.intellij.ui; import com.intellij.openapi.actionSystem.AnAction; import com.intellij.openapi.actionSystem.AnActionEvent; -import com.intellij.openapi.actionSystem.DataConstants; +import com.intellij.openapi.actionSystem.PlatformDataKeys; import com.intellij.openapi.project.DumbAware; -import javax.swing.*; import javax.swing.text.JTextComponent; import java.awt.*; +/* + * @author Anna.Kozlova + */ public class ClearTextAction extends AnAction implements DumbAware { public ClearTextAction() { @@ -38,7 +34,7 @@ public class ClearTextAction extends AnAction implements DumbAware { } public void actionPerformed(AnActionEvent e) { - final JComponent component = (JComponent)e.getDataContext().getData(DataConstants.CONTEXT_COMPONENT); + final Component component = PlatformDataKeys.CONTEXT_COMPONENT.getData(e.getDataContext()); if (component instanceof JTextComponent) { final JTextComponent textComponent = (JTextComponent)component; textComponent.setText(""); @@ -47,7 +43,13 @@ public class ClearTextAction extends AnAction implements DumbAware { public void update(AnActionEvent e) { - final Component component = (Component)e.getDataContext().getData(DataConstants.CONTEXT_COMPONENT); - e.getPresentation().setEnabled(component instanceof JTextComponent && ((JTextComponent)component).getText().length() > 0 && ((JTextComponent)component).isEditable()); + final Component component = PlatformDataKeys.CONTEXT_COMPONENT.getData(e.getDataContext()); + if (component instanceof JTextComponent) { + final JTextComponent textComponent = (JTextComponent)component; + e.getPresentation().setEnabled(textComponent.getText().length() > 0 && ((JTextComponent)component).isEditable()); + } + else { + e.getPresentation().setEnabled(false); + } } } \ No newline at end of file diff --git a/platform/platform-api/src/com/intellij/ui/tabs/impl/TabLabel.java b/platform/platform-api/src/com/intellij/ui/tabs/impl/TabLabel.java index 8e2673775ae3..d4044c24d1a6 100644 --- a/platform/platform-api/src/com/intellij/ui/tabs/impl/TabLabel.java +++ b/platform/platform-api/src/com/intellij/ui/tabs/impl/TabLabel.java @@ -140,8 +140,12 @@ public class TabLabel extends JPanel { private void doPaint(Graphics g) { final JBTabsPosition pos = myTabs.getTabsPosition(); - int dX = 0, dXs = 0, dY = 0, dYs = 0; - int selected = 1, plain = 2; + int dX = 0; + int dXs = 0; + int dY = 0; + int dYs = 0; + int selected = 1; + int plain = 2; switch (pos) { case bottom: @@ -192,8 +196,7 @@ public class TabLabel extends JPanel { toShow.addSeparator(); } - Object tabs = - DataManager.getInstance().getDataContext(e.getComponent(), e.getX(), e.getY()).getData(JBTabsImpl.NAVIGATION_ACTIONS_KEY.getName()); + JBTabsImpl tabs = JBTabsImpl.NAVIGATION_ACTIONS_KEY.getData(DataManager.getInstance().getDataContext(e.getComponent(), e.getX(), e.getY())); if (tabs == myTabs && myTabs.myAddNavigationGroup) { toShow.addAll(myTabs.myNavigationActions); } @@ -265,12 +268,15 @@ public class TabLabel extends JPanel { Insets insets = decoration.getLabelInsets(); if (insets != null) { Insets current = JBTabsImpl.ourDefaultDecorator.getDecoration().getLabelInsets(); - setBorder(new EmptyBorder(getValue(current.top, insets.top), getValue(current.left, insets.left), - getValue(current.bottom, insets.bottom), getValue(current.right, insets.right))); + if (current != null) { + setBorder( + new EmptyBorder(getValue(current.top, insets.top), getValue(current.left, insets.left), getValue(current.bottom, insets.bottom), + getValue(current.right, insets.right))); + } } } - private int getValue(int curentValue, int newValue) { + private static int getValue(int curentValue, int newValue) { return newValue != -1 ? newValue : curentValue; } diff --git a/platform/platform-api/src/com/intellij/util/OpenSourceUtil.java b/platform/platform-api/src/com/intellij/util/OpenSourceUtil.java index b724104ac21b..a02c96569c0c 100644 --- a/platform/platform-api/src/com/intellij/util/OpenSourceUtil.java +++ b/platform/platform-api/src/com/intellij/util/OpenSourceUtil.java @@ -15,7 +15,6 @@ */ package com.intellij.util; -import com.intellij.openapi.actionSystem.DataConstants; import com.intellij.openapi.actionSystem.DataContext; import com.intellij.openapi.actionSystem.DataProvider; import com.intellij.openapi.actionSystem.PlatformDataKeys; @@ -31,7 +30,7 @@ public class OpenSourceUtil { } public static void openSourcesFrom(DataProvider context, boolean requestFocus) { - navigate((Navigatable[])context.getData(DataConstants.NAVIGATABLE_ARRAY), requestFocus); + navigate(PlatformDataKeys.NAVIGATABLE_ARRAY.getData(context), requestFocus); } public static void navigate(final Navigatable[] navigatables, final boolean requestFocus) { diff --git a/platform/platform-api/src/com/intellij/util/ui/ErrorTreeView.java b/platform/platform-api/src/com/intellij/util/ui/ErrorTreeView.java index dae0b2582f79..f069ba016658 100644 --- a/platform/platform-api/src/com/intellij/util/ui/ErrorTreeView.java +++ b/platform/platform-api/src/com/intellij/util/ui/ErrorTreeView.java @@ -16,14 +16,15 @@ package com.intellij.util.ui; import com.intellij.openapi.Disposable; +import com.intellij.openapi.actionSystem.DataKey; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.pom.Navigatable; -import org.jetbrains.annotations.NonNls; import javax.swing.*; public interface ErrorTreeView extends Disposable { - @NonNls String CURRENT_EXCEPTION_DATA = "CURRENT_EXCEPTION_DATA"; + DataKey CURRENT_EXCEPTION_DATA_KEY = DataKey.create("CURRENT_EXCEPTION_DATA"); + @Deprecated String CURRENT_EXCEPTION_DATA = CURRENT_EXCEPTION_DATA_KEY.getName(); /** * If file is not null, allows to navigate to this file, line, column diff --git a/platform/platform-impl/src/com/intellij/codeInsight/hint/HintManagerImpl.java b/platform/platform-impl/src/com/intellij/codeInsight/hint/HintManagerImpl.java index 2c90dfe8d348..65a9d40e030c 100644 --- a/platform/platform-impl/src/com/intellij/codeInsight/hint/HintManagerImpl.java +++ b/platform/platform-impl/src/com/intellij/codeInsight/hint/HintManagerImpl.java @@ -375,7 +375,7 @@ public class HintManagerImpl extends HintManager implements Disposable { public Point getHintPosition(LightweightHint hint, Editor editor, short constraint) { LogicalPosition pos = editor.getCaretModel().getLogicalPosition(); final DataContext dataContext = ((EditorEx)editor).getDataContext(); - final Rectangle dominantArea = (Rectangle)dataContext.getData(DataConstants.DOMINANT_HINT_AREA_RECTANGLE); + final Rectangle dominantArea = PlatformDataKeys.DOMINANT_HINT_AREA_RECTANGLE.getData(dataContext); LOG.assertTrue(SwingUtilities.isEventDispatchThread()); if (dominantArea == null) { @@ -741,6 +741,9 @@ public class HintManagerImpl extends HintManager implements Disposable { private static class EditorHintListenerHolder { private static final EditorHintListener ourEditorHintPublisher = ApplicationManager.getApplication().getMessageBus().syncPublisher(EditorHintListener.TOPIC); + + private EditorHintListenerHolder() { + } } private static EditorHintListener getPublisher() { diff --git a/platform/platform-impl/src/com/intellij/ide/actionMacro/ActionMacroManager.java b/platform/platform-impl/src/com/intellij/ide/actionMacro/ActionMacroManager.java index 4cd3ade5eaa4..00386b88f282 100644 --- a/platform/platform-impl/src/com/intellij/ide/actionMacro/ActionMacroManager.java +++ b/platform/platform-impl/src/com/intellij/ide/actionMacro/ActionMacroManager.java @@ -120,8 +120,7 @@ public class ActionMacroManager implements ExportableApplicationComponent, Named } public void writeExternal(Element element) throws WriteExternalException { - for (int i = 0; i < myMacros.size(); i++) { - ActionMacro macro = myMacros.get(i); + for (ActionMacro macro : myMacros) { Element macroElement = new Element(ELEMENT_MACRO); macro.writeExternal(macroElement); element.addContent(macroElement); @@ -132,6 +131,7 @@ public class ActionMacroManager implements ExportableApplicationComponent, Named return ApplicationManager.getApplication().getComponent(ActionMacroManager.class); } + @NotNull public String getComponentName() { return "ActionMacroManager"; } @@ -270,8 +270,7 @@ public class ActionMacroManager implements ExportableApplicationComponent, Named HashSet registeredIds = new HashSet(); // to prevent exception if 2 or more targets have the same name ActionMacro[] macros = getAllMacros(); - for (int i = 0; i < macros.length; i++) { - final ActionMacro macro = macros[i]; + for (final ActionMacro macro : macros) { String actionId = macro.getActionId(); if (!registeredIds.contains(actionId)) { @@ -285,8 +284,7 @@ public class ActionMacroManager implements ExportableApplicationComponent, Named // unregister Tool actions String[] oldIds = myActionManager.getActionIds(ActionMacro.MACRO_ACTION_PREFIX); - for (int i = 0; i < oldIds.length; i++) { - String oldId = oldIds[i]; + for (final String oldId : oldIds) { myActionManager.unregisterAction(oldId); } } @@ -330,13 +328,13 @@ public class ActionMacroManager implements ExportableApplicationComponent, Named } public void actionPerformed(AnActionEvent e) { - ActionMacroManager.getInstance().playMacro(myMacro); + getInstance().playMacro(myMacro); } public void update(AnActionEvent e) { super.update(e); - e.getPresentation().setEnabled(!ActionMacroManager.getInstance().isPlaying() && - e.getDataContext().getData(DataConstants.EDITOR) != null); + e.getPresentation().setEnabled(!getInstance().isPlaying() && + PlatformDataKeys.EDITOR.getData(e.getDataContext()) != null); } } diff --git a/platform/platform-impl/src/com/intellij/ide/actionMacro/actions/PlaybackLastMacroAction.java b/platform/platform-impl/src/com/intellij/ide/actionMacro/actions/PlaybackLastMacroAction.java index 7d0e9fcfe62d..515c91fe4ad4 100644 --- a/platform/platform-impl/src/com/intellij/ide/actionMacro/actions/PlaybackLastMacroAction.java +++ b/platform/platform-impl/src/com/intellij/ide/actionMacro/actions/PlaybackLastMacroAction.java @@ -18,7 +18,7 @@ package com.intellij.ide.actionMacro.actions; import com.intellij.ide.actionMacro.ActionMacroManager; import com.intellij.openapi.actionSystem.AnAction; import com.intellij.openapi.actionSystem.AnActionEvent; -import com.intellij.openapi.actionSystem.DataConstants; +import com.intellij.openapi.actionSystem.PlatformDataKeys; import com.intellij.openapi.project.DumbAware; /** @@ -30,8 +30,8 @@ public class PlaybackLastMacroAction extends AnAction implements DumbAware { } public void update(AnActionEvent e) { - e.getPresentation().setEnabled( - !ActionMacroManager.getInstance().isPlaying() && - ActionMacroManager.getInstance().hasRecentMacro() && e.getDataContext().getData(DataConstants.EDITOR) != null); + e.getPresentation().setEnabled(!ActionMacroManager.getInstance().isPlaying() && + ActionMacroManager.getInstance().hasRecentMacro() && + PlatformDataKeys.EDITOR.getData(e.getDataContext()) != null); } } diff --git a/platform/platform-impl/src/com/intellij/ide/actionMacro/actions/StartStopMacroRecordingAction.java b/platform/platform-impl/src/com/intellij/ide/actionMacro/actions/StartStopMacroRecordingAction.java index f750dce297dc..541e803718af 100644 --- a/platform/platform-impl/src/com/intellij/ide/actionMacro/actions/StartStopMacroRecordingAction.java +++ b/platform/platform-impl/src/com/intellij/ide/actionMacro/actions/StartStopMacroRecordingAction.java @@ -19,7 +19,6 @@ import com.intellij.ide.IdeBundle; import com.intellij.ide.actionMacro.ActionMacroManager; import com.intellij.openapi.actionSystem.AnAction; import com.intellij.openapi.actionSystem.AnActionEvent; -import com.intellij.openapi.actionSystem.DataConstants; import com.intellij.openapi.actionSystem.PlatformDataKeys; import com.intellij.openapi.project.DumbAware; @@ -28,7 +27,7 @@ import com.intellij.openapi.project.DumbAware; */ public class StartStopMacroRecordingAction extends AnAction implements DumbAware { public void update(AnActionEvent e) { - boolean editorAvailable = e.getDataContext().getData(DataConstants.EDITOR) != null; + boolean editorAvailable = PlatformDataKeys.EDITOR.getData(e.getDataContext()) != null; boolean isRecording = ActionMacroManager.getInstance().isRecording(); e.getPresentation().setEnabled(editorAvailable || isRecording); @@ -38,7 +37,7 @@ public class StartStopMacroRecordingAction extends AnAction implements DumbAware } public void actionPerformed(AnActionEvent e) { - if (!ActionMacroManager.getInstance().isRecording() ) { + if (!ActionMacroManager.getInstance().isRecording()) { final ActionMacroManager manager = ActionMacroManager.getInstance(); manager.startRecording(IdeBundle.message("macro.noname")); } diff --git a/platform/platform-impl/src/com/intellij/ide/actions/CloseAllEditorsAction.java b/platform/platform-impl/src/com/intellij/ide/actions/CloseAllEditorsAction.java index 93d011afe923..d5461ee71a6d 100644 --- a/platform/platform-impl/src/com/intellij/ide/actions/CloseAllEditorsAction.java +++ b/platform/platform-impl/src/com/intellij/ide/actions/CloseAllEditorsAction.java @@ -17,29 +17,29 @@ package com.intellij.ide.actions; import com.intellij.ide.IdeBundle; -import com.intellij.openapi.actionSystem.*; -import com.intellij.openapi.actionSystem.ex.DataConstantsEx; +import com.intellij.openapi.actionSystem.AnAction; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.PlatformDataKeys; +import com.intellij.openapi.actionSystem.Presentation; import com.intellij.openapi.command.CommandProcessor; import com.intellij.openapi.fileEditor.FileEditorManager; import com.intellij.openapi.fileEditor.ex.FileEditorManagerEx; import com.intellij.openapi.fileEditor.impl.EditorWindow; -import com.intellij.openapi.project.Project; import com.intellij.openapi.project.DumbAware; +import com.intellij.openapi.project.Project; import com.intellij.openapi.vfs.VirtualFile; public class CloseAllEditorsAction extends AnAction implements DumbAware { - public void actionPerformed(AnActionEvent e) { - final DataContext dataContext = e.getDataContext(); - final Project project = PlatformDataKeys.PROJECT.getData(dataContext); + public void actionPerformed(final AnActionEvent e) { + final Project project = e.getData(PlatformDataKeys.PROJECT); CommandProcessor commandProcessor = CommandProcessor.getInstance(); commandProcessor.executeCommand( project, new Runnable(){ public void run() { - final EditorWindow window = (EditorWindow)dataContext.getData(DataConstantsEx.EDITOR_WINDOW); + final EditorWindow window = e.getData(EditorWindow.DATA_KEY); if (window != null){ final VirtualFile[] files = window.getFiles(); - for (int i = 0; i < files.length; i++) { - VirtualFile file = files[i]; + for (final VirtualFile file : files) { window.closeFile(file); } return; @@ -47,8 +47,8 @@ public class CloseAllEditorsAction extends AnAction implements DumbAware { FileEditorManagerEx fileEditorManager = FileEditorManagerEx.getInstanceEx(project); VirtualFile selectedFile = fileEditorManager.getSelectedFiles()[0]; VirtualFile[] openFiles = fileEditorManager.getSiblings(selectedFile); - for (int i = 0; i < openFiles.length; i++) { - fileEditorManager.closeFile(openFiles[i]); + for (final VirtualFile openFile : openFiles) { + fileEditorManager.closeFile(openFile); } } }, IdeBundle.message("command.close.all.editors"), null @@ -57,15 +57,14 @@ public class CloseAllEditorsAction extends AnAction implements DumbAware { public void update(AnActionEvent event){ Presentation presentation = event.getPresentation(); - final DataContext dataContext = event.getDataContext(); - final EditorWindow editorWindow = (EditorWindow)dataContext.getData(DataConstantsEx.EDITOR_WINDOW); + final EditorWindow editorWindow = event.getData(EditorWindow.DATA_KEY); if (editorWindow != null && editorWindow.inSplitter()) { presentation.setText(IdeBundle.message("action.close.all.editors.in.tab.group")); } else { presentation.setText(IdeBundle.message("action.close.all.editors")); } - Project project = PlatformDataKeys.PROJECT.getData(dataContext); + Project project = event.getData(PlatformDataKeys.PROJECT); if (project == null) { presentation.setEnabled(false); return; diff --git a/platform/platform-impl/src/com/intellij/ide/actions/CloseAllEditorsButActiveAction.java b/platform/platform-impl/src/com/intellij/ide/actions/CloseAllEditorsButActiveAction.java index b56f43433a74..709eb1362da2 100644 --- a/platform/platform-impl/src/com/intellij/ide/actions/CloseAllEditorsButActiveAction.java +++ b/platform/platform-impl/src/com/intellij/ide/actions/CloseAllEditorsButActiveAction.java @@ -16,52 +16,51 @@ */ package com.intellij.ide.actions; -import com.intellij.openapi.actionSystem.*; -import com.intellij.openapi.actionSystem.ex.DataConstantsEx; +import com.intellij.openapi.actionSystem.AnAction; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.PlatformDataKeys; +import com.intellij.openapi.actionSystem.Presentation; import com.intellij.openapi.fileEditor.ex.FileEditorManagerEx; import com.intellij.openapi.fileEditor.impl.EditorWindow; -import com.intellij.openapi.project.Project; import com.intellij.openapi.project.DumbAware; +import com.intellij.openapi.project.Project; import com.intellij.openapi.vfs.VirtualFile; public class CloseAllEditorsButActiveAction extends AnAction implements DumbAware { public void actionPerformed(AnActionEvent e) { - final DataContext dataContext = e.getDataContext(); - Project project = PlatformDataKeys.PROJECT.getData(dataContext); + Project project = e.getData(PlatformDataKeys.PROJECT); FileEditorManagerEx fileEditorManager=FileEditorManagerEx.getInstanceEx(project); VirtualFile selectedFile; - final EditorWindow window = (EditorWindow)dataContext.getData(DataConstantsEx.EDITOR_WINDOW); + final EditorWindow window = e.getData(EditorWindow.DATA_KEY); if (window != null){ - selectedFile = (VirtualFile)dataContext.getData(DataConstants.VIRTUAL_FILE); + selectedFile = e.getData(PlatformDataKeys.VIRTUAL_FILE); final VirtualFile[] files = window.getFiles(); - for (int i = 0; i < files.length; i++) { - VirtualFile file = files[i]; - if (file != selectedFile){ + for (final VirtualFile file : files) { + if (file != selectedFile) { window.closeFile(file); } } return; } selectedFile = fileEditorManager.getSelectedFiles()[0]; - VirtualFile[] siblings = fileEditorManager.getSiblings(selectedFile); - for(int i=0;i 1); return; diff --git a/platform/platform-impl/src/com/intellij/ide/actions/CloseEditorAction.java b/platform/platform-impl/src/com/intellij/ide/actions/CloseEditorAction.java index 4e5b15db7aa0..ba95dc4ac083 100644 --- a/platform/platform-impl/src/com/intellij/ide/actions/CloseEditorAction.java +++ b/platform/platform-impl/src/com/intellij/ide/actions/CloseEditorAction.java @@ -18,28 +18,26 @@ package com.intellij.ide.actions; import com.intellij.ide.IdeBundle; import com.intellij.openapi.actionSystem.*; -import com.intellij.openapi.actionSystem.ex.DataConstantsEx; import com.intellij.openapi.fileEditor.FileEditorManager; import com.intellij.openapi.fileEditor.ex.FileEditorManagerEx; import com.intellij.openapi.fileEditor.impl.EditorWindow; -import com.intellij.openapi.project.Project; import com.intellij.openapi.project.DumbAware; +import com.intellij.openapi.project.Project; import com.intellij.openapi.vfs.VirtualFile; public class CloseEditorAction extends AnAction implements DumbAware { public void actionPerformed(AnActionEvent e) { - final DataContext dataContext = e.getDataContext(); - final Project project = PlatformDataKeys.PROJECT.getData(dataContext); + final Project project = e.getData(PlatformDataKeys.PROJECT); final FileEditorManagerEx editorManager = ((FileEditorManagerEx)FileEditorManager.getInstance(project)); - EditorWindow window = (EditorWindow)dataContext.getData(DataConstantsEx.EDITOR_WINDOW); + EditorWindow window = e.getData(EditorWindow.DATA_KEY); VirtualFile file; if (window == null) { window = editorManager.getCurrentWindow(); file = window.getSelectedFile(); } else { - file = PlatformDataKeys.VIRTUAL_FILE.getData(dataContext); + file = e.getData(PlatformDataKeys.VIRTUAL_FILE); } if (file != null) { editorManager.closeFile(file, window); @@ -48,8 +46,7 @@ public class CloseEditorAction extends AnAction implements DumbAware { public void update(final AnActionEvent event){ final Presentation presentation = event.getPresentation(); - final DataContext dataContext = event.getDataContext(); - final Project project = PlatformDataKeys.PROJECT.getData(dataContext); + final Project project = event.getData(PlatformDataKeys.PROJECT); if (project == null) { presentation.setEnabled(false); return; @@ -57,7 +54,7 @@ public class CloseEditorAction extends AnAction implements DumbAware { if (ActionPlaces.EDITOR_POPUP.equals(event.getPlace()) || ActionPlaces.EDITOR_TAB_POPUP.equals(event.getPlace())) { presentation.setText(IdeBundle.message("action.close")); } - EditorWindow window = (EditorWindow)dataContext.getData(DataConstantsEx.EDITOR_WINDOW); + EditorWindow window = event.getData(EditorWindow.DATA_KEY); if (window == null) { window = ((FileEditorManagerEx)FileEditorManager.getInstance(project)).getCurrentWindow(); } diff --git a/platform/platform-impl/src/com/intellij/ide/actions/CloseEditorsActionBase.java b/platform/platform-impl/src/com/intellij/ide/actions/CloseEditorsActionBase.java index 24c3fac911f5..de8714a15fbc 100644 --- a/platform/platform-impl/src/com/intellij/ide/actions/CloseEditorsActionBase.java +++ b/platform/platform-impl/src/com/intellij/ide/actions/CloseEditorsActionBase.java @@ -15,17 +15,16 @@ */ package com.intellij.ide.actions; +import com.intellij.ide.IdeBundle; import com.intellij.openapi.actionSystem.*; -import com.intellij.openapi.actionSystem.ex.DataConstantsEx; +import com.intellij.openapi.command.CommandProcessor; +import com.intellij.openapi.fileEditor.ex.FileEditorManagerEx; import com.intellij.openapi.fileEditor.impl.EditorComposite; import com.intellij.openapi.fileEditor.impl.EditorWindow; -import com.intellij.openapi.fileEditor.ex.FileEditorManagerEx; -import com.intellij.openapi.util.Pair; -import com.intellij.openapi.project.Project; import com.intellij.openapi.project.DumbAware; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.Pair; import com.intellij.openapi.vcs.FileStatusManager; -import com.intellij.openapi.command.CommandProcessor; -import com.intellij.ide.IdeBundle; import java.util.ArrayList; @@ -38,7 +37,7 @@ public abstract class CloseEditorsActionBase extends AnAction implements DumbAwa final DataContext dataContext = event.getDataContext(); final Project project = event.getData(PlatformDataKeys.PROJECT); final FileEditorManagerEx editorManager = FileEditorManagerEx.getInstanceEx(project); - final EditorWindow editorWindow = (EditorWindow)dataContext.getData(DataConstantsEx.EDITOR_WINDOW); + final EditorWindow editorWindow = EditorWindow.DATA_KEY.getData(dataContext); final EditorWindow[] windows; if (editorWindow != null){ windows = new EditorWindow[]{ editorWindow }; @@ -82,7 +81,7 @@ public abstract class CloseEditorsActionBase extends AnAction implements DumbAwa public void update(final AnActionEvent event){ final Presentation presentation = event.getPresentation(); final DataContext dataContext = event.getDataContext(); - final EditorWindow editorWindow = (EditorWindow)dataContext.getData(DataConstantsEx.EDITOR_WINDOW); + final EditorWindow editorWindow = EditorWindow.DATA_KEY.getData(dataContext); final boolean inSplitter = editorWindow != null && editorWindow.inSplitter(); presentation.setText(getPresentationText(inSplitter)); final Project project = event.getData(PlatformDataKeys.PROJECT); diff --git a/platform/platform-impl/src/com/intellij/ide/actions/CollapseAllAction.java b/platform/platform-impl/src/com/intellij/ide/actions/CollapseAllAction.java index 6b5bb9421387..9992dbb01a27 100644 --- a/platform/platform-impl/src/com/intellij/ide/actions/CollapseAllAction.java +++ b/platform/platform-impl/src/com/intellij/ide/actions/CollapseAllAction.java @@ -17,10 +17,10 @@ package com.intellij.ide.actions; import com.intellij.ide.TreeExpander; import com.intellij.openapi.actionSystem.DataContext; -import com.intellij.openapi.actionSystem.ex.DataConstantsEx; +import com.intellij.openapi.actionSystem.PlatformDataKeys; public class CollapseAllAction extends TreeCollapseAllActionBase { protected TreeExpander getExpander(DataContext dataContext) { - return (TreeExpander)dataContext.getData(DataConstantsEx.TREE_EXPANDER); + return PlatformDataKeys.TREE_EXPANDER.getData(dataContext); } } diff --git a/platform/platform-impl/src/com/intellij/ide/actions/CopyAction.java b/platform/platform-impl/src/com/intellij/ide/actions/CopyAction.java index 29c5ba28be5e..3a76106f733a 100644 --- a/platform/platform-impl/src/com/intellij/ide/actions/CopyAction.java +++ b/platform/platform-impl/src/com/intellij/ide/actions/CopyAction.java @@ -1,19 +1,18 @@ - /* - * Copyright 2000-2009 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. - */ +* Copyright 2000-2009 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 com.intellij.ide.actions; import com.intellij.ide.CopyProvider; @@ -23,15 +22,17 @@ import com.intellij.openapi.project.DumbAware; public class CopyAction extends AnAction implements DumbAware { public void actionPerformed(AnActionEvent e) { DataContext dataContext = e.getDataContext(); - CopyProvider provider = (CopyProvider)dataContext.getData(DataConstants.COPY_PROVIDER); - if (provider == null) return; + CopyProvider provider = PlatformDataKeys.COPY_PROVIDER.getData(dataContext); + if (provider == null) { + return; + } provider.performCopy(dataContext); } - public void update(AnActionEvent event){ + public void update(AnActionEvent event) { Presentation presentation = event.getPresentation(); DataContext dataContext = event.getDataContext(); - CopyProvider provider = (CopyProvider)dataContext.getData(DataConstants.COPY_PROVIDER); + CopyProvider provider = PlatformDataKeys.COPY_PROVIDER.getData(dataContext); presentation.setEnabled(provider != null && provider.isCopyEnabled(dataContext)); if (event.getPlace().equals(ActionPlaces.EDITOR_POPUP) && provider != null) { presentation.setVisible(provider.isCopyVisible(dataContext)); diff --git a/platform/platform-impl/src/com/intellij/ide/actions/CutAction.java b/platform/platform-impl/src/com/intellij/ide/actions/CutAction.java index d772de01d8ec..381d6afc8577 100644 --- a/platform/platform-impl/src/com/intellij/ide/actions/CutAction.java +++ b/platform/platform-impl/src/com/intellij/ide/actions/CutAction.java @@ -1,38 +1,39 @@ - /* - * Copyright 2000-2009 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. - */ +* Copyright 2000-2009 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 com.intellij.ide.actions; import com.intellij.ide.CutProvider; import com.intellij.openapi.actionSystem.*; -import com.intellij.openapi.project.Project; import com.intellij.openapi.project.DumbAware; +import com.intellij.openapi.project.Project; public class CutAction extends AnAction implements DumbAware { public void actionPerformed(AnActionEvent e) { DataContext dataContext = e.getDataContext(); - CutProvider provider = (CutProvider)dataContext.getData(DataConstants.CUT_PROVIDER); - if (provider == null) return; + CutProvider provider = PlatformDataKeys.CUT_PROVIDER.getData(dataContext); + if (provider == null) { + return; + } provider.performCut(dataContext); } - public void update(AnActionEvent event){ + public void update(AnActionEvent event) { Presentation presentation = event.getPresentation(); DataContext dataContext = event.getDataContext(); - CutProvider provider = (CutProvider)dataContext.getData(DataConstants.CUT_PROVIDER); + CutProvider provider = PlatformDataKeys.CUT_PROVIDER.getData(dataContext); Project project = PlatformDataKeys.PROJECT.getData(dataContext); presentation.setEnabled(project != null && project.isOpen() && provider != null && provider.isCutEnabled(dataContext)); if (event.getPlace().equals(ActionPlaces.EDITOR_POPUP) && provider != null) { diff --git a/platform/platform-impl/src/com/intellij/ide/actions/ExpandAllAction.java b/platform/platform-impl/src/com/intellij/ide/actions/ExpandAllAction.java index 252074c4d6bc..6648c6e21fc8 100644 --- a/platform/platform-impl/src/com/intellij/ide/actions/ExpandAllAction.java +++ b/platform/platform-impl/src/com/intellij/ide/actions/ExpandAllAction.java @@ -17,11 +17,10 @@ package com.intellij.ide.actions; import com.intellij.ide.TreeExpander; import com.intellij.openapi.actionSystem.DataContext; -import com.intellij.openapi.actionSystem.ex.DataConstantsEx; +import com.intellij.openapi.actionSystem.PlatformDataKeys; public class ExpandAllAction extends TreeExpandAllActionBase { protected TreeExpander getExpander(DataContext dataContext) { - TreeExpander treeExpander = (TreeExpander)dataContext.getData(DataConstantsEx.TREE_EXPANDER); - return treeExpander; + return PlatformDataKeys.TREE_EXPANDER.getData(dataContext); } } diff --git a/platform/platform-impl/src/com/intellij/ide/actions/ExportToTextFileAction.java b/platform/platform-impl/src/com/intellij/ide/actions/ExportToTextFileAction.java index 17069a0d8d0d..44d5e0072f5b 100644 --- a/platform/platform-impl/src/com/intellij/ide/actions/ExportToTextFileAction.java +++ b/platform/platform-impl/src/com/intellij/ide/actions/ExportToTextFileAction.java @@ -31,7 +31,7 @@ public class ExportToTextFileAction extends AnAction { export(project, exporterToTextFile); } - public void export(Project project, ExporterToTextFile exporter) { + public static void export(Project project, ExporterToTextFile exporter) { final ExportToFileUtil.ExportDialogBase dlg = new ExportToFileUtil.ExportDialogBase(project, exporter); dlg.show(); @@ -44,14 +44,13 @@ public class ExportToTextFileAction extends AnAction { } protected ExporterToTextFile getExporter(DataContext dataContext) { - ExporterToTextFile exporterToTextFile = (ExporterToTextFile)dataContext.getData(DataConstants.EXPORTER_TO_TEXT_FILE); - return exporterToTextFile; + return PlatformDataKeys.EXPORTER_TO_TEXT_FILE.getData(dataContext); } public void update(AnActionEvent event) { Presentation presentation = event.getPresentation(); DataContext dataContext = event.getDataContext(); ExporterToTextFile exporterToTextFile = getExporter(dataContext); - presentation.setEnabled(dataContext.getData(DataConstants.PROJECT) != null && exporterToTextFile != null && exporterToTextFile.canExport()); + presentation.setEnabled(PlatformDataKeys.PROJECT.getData(dataContext) != null && exporterToTextFile != null && exporterToTextFile.canExport()); } } diff --git a/platform/platform-impl/src/com/intellij/ide/actions/ImportSettingsAction.java b/platform/platform-impl/src/com/intellij/ide/actions/ImportSettingsAction.java index ed5721e00a24..9cbc8d850fd0 100644 --- a/platform/platform-impl/src/com/intellij/ide/actions/ImportSettingsAction.java +++ b/platform/platform-impl/src/com/intellij/ide/actions/ImportSettingsAction.java @@ -23,8 +23,8 @@ import com.intellij.ide.IdeBundle; import com.intellij.ide.startup.StartupActionScriptManager; import com.intellij.openapi.actionSystem.AnAction; import com.intellij.openapi.actionSystem.AnActionEvent; -import com.intellij.openapi.actionSystem.DataConstants; import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.actionSystem.PlatformDataKeys; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.application.ApplicationNamesInfo; import com.intellij.openapi.application.PathManager; @@ -46,7 +46,7 @@ import java.util.zip.ZipFile; public class ImportSettingsAction extends AnAction implements DumbAware { public void actionPerformed(AnActionEvent e) { final DataContext dataContext = e.getDataContext(); - final Component component = (Component)dataContext.getData(DataConstants.CONTEXT_COMPONENT); + final Component component = PlatformDataKeys.CONTEXT_COMPONENT.getData(dataContext); final String path = ChooseComponentsToExportDialog.chooseSettingsFile(PathManager.getConfigPath(), component, IdeBundle.message("title.import.file.location"), IdeBundle.message("prompt.choose.import.file.path")); @@ -157,4 +157,4 @@ public class ImportSettingsAction extends AnAction implements DumbAware { return components; } -} \ No newline at end of file +} diff --git a/platform/platform-impl/src/com/intellij/ide/actions/PasteAction.java b/platform/platform-impl/src/com/intellij/ide/actions/PasteAction.java index 2a76ad1262c1..7ecfffce8358 100644 --- a/platform/platform-impl/src/com/intellij/ide/actions/PasteAction.java +++ b/platform/platform-impl/src/com/intellij/ide/actions/PasteAction.java @@ -21,17 +21,19 @@ import com.intellij.openapi.project.DumbAware; public class PasteAction extends AnAction implements DumbAware { - public void update(AnActionEvent event){ + public void update(AnActionEvent event) { Presentation presentation = event.getPresentation(); DataContext dataContext = event.getDataContext(); - PasteProvider provider = (PasteProvider)dataContext.getData(DataConstants.PASTE_PROVIDER); + PasteProvider provider = PlatformDataKeys.PASTE_PROVIDER.getData(dataContext); presentation.setEnabled(provider != null && provider.isPastePossible(dataContext)); } + public void actionPerformed(AnActionEvent e) { DataContext dataContext = e.getDataContext(); - PasteProvider provider = (PasteProvider)dataContext.getData(DataConstants.PASTE_PROVIDER); - if (provider == null || !provider.isPasteEnabled(dataContext)) return; - provider.performPaste(dataContext); + PasteProvider provider = PlatformDataKeys.PASTE_PROVIDER.getData(dataContext); + if (provider != null && provider.isPasteEnabled(dataContext)) { + provider.performPaste(dataContext); + } } } \ No newline at end of file diff --git a/platform/platform-impl/src/com/intellij/ide/actions/PinActiveTabAction.java b/platform/platform-impl/src/com/intellij/ide/actions/PinActiveTabAction.java index 274582889289..8451a1dc23db 100644 --- a/platform/platform-impl/src/com/intellij/ide/actions/PinActiveTabAction.java +++ b/platform/platform-impl/src/com/intellij/ide/actions/PinActiveTabAction.java @@ -17,22 +17,23 @@ package com.intellij.ide.actions; import com.intellij.ide.IdeBundle; import com.intellij.openapi.actionSystem.*; -import com.intellij.openapi.actionSystem.ex.DataConstantsEx; import com.intellij.openapi.fileEditor.ex.FileEditorManagerEx; import com.intellij.openapi.fileEditor.impl.EditorWindow; -import com.intellij.openapi.project.Project; import com.intellij.openapi.project.DumbAware; +import com.intellij.openapi.project.Project; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.openapi.wm.ToolWindowManager; import com.intellij.ui.content.Content; import com.intellij.ui.content.ContentManager; import com.intellij.ui.content.ContentManagerUtil; +import org.jetbrains.annotations.Nullable; public class PinActiveTabAction extends ToggleAction implements DumbAware { /** * @return selected editor or null */ - private VirtualFile getFile(final DataContext context){ + @Nullable + private static VirtualFile getFile(final DataContext context){ Project project = PlatformDataKeys.PROJECT.getData(context); if(project == null){ return null; @@ -49,7 +50,8 @@ public class PinActiveTabAction extends ToggleAction implements DumbAware { /** * @return selected content or null */ - private Content getContent(final DataContext context){ + @Nullable + private static Content getContent(final DataContext context){ ContentManager contentManager = ContentManagerUtil.getContentManagerFromContext(context, true); if (contentManager == null){ return null; @@ -102,10 +104,10 @@ public class PinActiveTabAction extends ToggleAction implements DumbAware { content.setPinned(state); } - private EditorWindow getEditorWindow(DataContext context) { - final Project project = PlatformDataKeys.PROJECT.getData(context); + private static EditorWindow getEditorWindow(DataContext dataContext) { + final Project project = PlatformDataKeys.PROJECT.getData(dataContext); final FileEditorManagerEx fileEditorManager = FileEditorManagerEx.getInstanceEx(project); - EditorWindow editorWindow = (EditorWindow) context.getData(DataConstantsEx.EDITOR_WINDOW); + EditorWindow editorWindow = EditorWindow.DATA_KEY.getData(dataContext); if (editorWindow == null) { editorWindow = fileEditorManager.getCurrentWindow(); } diff --git a/platform/platform-impl/src/com/intellij/ide/actions/SplitAction.java b/platform/platform-impl/src/com/intellij/ide/actions/SplitAction.java index 8388cf114ffe..9b8c96b8d708 100644 --- a/platform/platform-impl/src/com/intellij/ide/actions/SplitAction.java +++ b/platform/platform-impl/src/com/intellij/ide/actions/SplitAction.java @@ -20,7 +20,6 @@ import com.intellij.openapi.actionSystem.AnAction; import com.intellij.openapi.actionSystem.AnActionEvent; import com.intellij.openapi.actionSystem.PlatformDataKeys; import com.intellij.openapi.actionSystem.Presentation; -import com.intellij.openapi.actionSystem.ex.DataConstantsEx; import com.intellij.openapi.fileEditor.ex.FileEditorManagerEx; import com.intellij.openapi.fileEditor.impl.EditorWindow; import com.intellij.openapi.project.DumbAware; @@ -41,7 +40,7 @@ public abstract class SplitAction extends AnAction implements DumbAware { public void actionPerformed(final AnActionEvent event) { final Project project = PlatformDataKeys.PROJECT.getData(event.getDataContext()); final FileEditorManagerEx fileEditorManager = FileEditorManagerEx.getInstanceEx(project); - final EditorWindow window = (EditorWindow)event.getDataContext().getData(DataConstantsEx.EDITOR_WINDOW); + final EditorWindow window = EditorWindow.DATA_KEY.getData(event.getDataContext()); fileEditorManager.createSplitter(myOrientation, window); } diff --git a/platform/platform-impl/src/com/intellij/ide/actions/TabNavigationActionBase.java b/platform/platform-impl/src/com/intellij/ide/actions/TabNavigationActionBase.java index 28778b29fbce..c4009a4a7fe2 100644 --- a/platform/platform-impl/src/com/intellij/ide/actions/TabNavigationActionBase.java +++ b/platform/platform-impl/src/com/intellij/ide/actions/TabNavigationActionBase.java @@ -16,12 +16,11 @@ package com.intellij.ide.actions; import com.intellij.openapi.actionSystem.*; -import com.intellij.openapi.actionSystem.ex.DataConstantsEx; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.fileEditor.ex.FileEditorManagerEx; import com.intellij.openapi.fileEditor.impl.EditorWindow; -import com.intellij.openapi.project.Project; import com.intellij.openapi.project.DumbAware; +import com.intellij.openapi.project.Project; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.openapi.wm.ToolWindowManager; import com.intellij.ui.content.ContentManager; @@ -51,7 +50,7 @@ abstract class TabNavigationActionBase extends AnAction implements DumbAware { return; } - ContentManager contentManager = (ContentManager)dataContext.getData(DataConstantsEx.NONEMPTY_CONTENT_MANAGER); + ContentManager contentManager = PlatformDataKeys.NONEMPTY_CONTENT_MANAGER.getData(dataContext); if (contentManager == null) return; doNavigate(contentManager); } @@ -67,7 +66,7 @@ abstract class TabNavigationActionBase extends AnAction implements DumbAware { final ToolWindowManager windowManager = ToolWindowManager.getInstance(project); if (windowManager.isEditorComponentActive()) { final FileEditorManagerEx editorManager = FileEditorManagerEx.getInstanceEx(project); - EditorWindow currentWindow = (EditorWindow)dataContext.getData(DataConstantsEx.EDITOR_WINDOW); + EditorWindow currentWindow = EditorWindow.DATA_KEY.getData(dataContext); if (currentWindow == null){ editorManager.getCurrentWindow (); } @@ -78,7 +77,7 @@ abstract class TabNavigationActionBase extends AnAction implements DumbAware { return; } - ContentManager contentManager = (ContentManager)dataContext.getData(DataConstantsEx.NONEMPTY_CONTENT_MANAGER); + ContentManager contentManager = PlatformDataKeys.NONEMPTY_CONTENT_MANAGER.getData(dataContext); presentation.setEnabled(contentManager != null && contentManager.getContentCount() > 1 && contentManager.isSingleSelection()); } @@ -99,7 +98,7 @@ abstract class TabNavigationActionBase extends AnAction implements DumbAware { public static void navigateImpl(final DataContext dataContext, Project project, VirtualFile selectedFile, final int dir) { LOG.assertTrue (dir == 1 || dir == -1); final FileEditorManagerEx editorManager = FileEditorManagerEx.getInstanceEx(project); - EditorWindow currentWindow = (EditorWindow)dataContext.getData(DataConstantsEx.EDITOR_WINDOW); + EditorWindow currentWindow = EditorWindow.DATA_KEY.getData(dataContext); if (currentWindow == null){ currentWindow = editorManager.getCurrentWindow (); } diff --git a/platform/platform-impl/src/com/intellij/ide/actions/UndoRedoAction.java b/platform/platform-impl/src/com/intellij/ide/actions/UndoRedoAction.java index 62b668921238..08c443ef12c3 100644 --- a/platform/platform-impl/src/com/intellij/ide/actions/UndoRedoAction.java +++ b/platform/platform-impl/src/com/intellij/ide/actions/UndoRedoAction.java @@ -16,7 +16,10 @@ package com.intellij.ide.actions; import com.intellij.idea.ActionsBundle; -import com.intellij.openapi.actionSystem.*; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.actionSystem.PlatformDataKeys; +import com.intellij.openapi.actionSystem.Presentation; import com.intellij.openapi.command.undo.UndoManager; import com.intellij.openapi.fileEditor.FileEditor; import com.intellij.openapi.fileEditor.TextEditor; @@ -53,7 +56,7 @@ public abstract class UndoRedoAction extends DumbAwareAction { FileEditor editor = PlatformDataKeys.FILE_EDITOR.getData(dataContext); // do not allow global undo in dialogs - if (editor == null && dataContext.getData(DataConstants.IS_MODAL_CONTEXT) == Boolean.TRUE) { + if (editor == null && PlatformDataKeys.IS_MODAL_CONTEXT.getData(dataContext)) { presentation.setEnabled(false); return; } diff --git a/platform/platform-impl/src/com/intellij/ide/actions/tree/BaseTreeNodeAction.java b/platform/platform-impl/src/com/intellij/ide/actions/tree/BaseTreeNodeAction.java index 5b6dd4c3bade..5d80cae1084b 100644 --- a/platform/platform-impl/src/com/intellij/ide/actions/tree/BaseTreeNodeAction.java +++ b/platform/platform-impl/src/com/intellij/ide/actions/tree/BaseTreeNodeAction.java @@ -17,7 +17,7 @@ package com.intellij.ide.actions.tree; import com.intellij.openapi.actionSystem.AnAction; import com.intellij.openapi.actionSystem.AnActionEvent; -import com.intellij.openapi.actionSystem.DataConstants; +import com.intellij.openapi.actionSystem.PlatformDataKeys; import com.intellij.ui.treeStructure.treetable.TreeTable; import javax.swing.*; @@ -29,10 +29,12 @@ abstract class BaseTreeNodeAction extends AnAction { public void actionPerformed(AnActionEvent e) { Object sourceComponent = getSourceComponent(e); - if (sourceComponent instanceof JTree) + if (sourceComponent instanceof JTree) { performOn((JTree)sourceComponent); - else if (sourceComponent instanceof TreeTable) + } + else if (sourceComponent instanceof TreeTable) { performOn(((TreeTable)sourceComponent).getTree()); + } } protected abstract void performOn(JTree tree); @@ -41,13 +43,17 @@ abstract class BaseTreeNodeAction extends AnAction { e.getPresentation().setEnabled(enabledOn(getSourceComponent(e))); } - private boolean enabledOn(Object sourceComponent) { - if (sourceComponent instanceof JTree) return true; - if (sourceComponent instanceof TreeTable) return true; + private static boolean enabledOn(Object sourceComponent) { + if (sourceComponent instanceof JTree) { + return true; + } + if (sourceComponent instanceof TreeTable) { + return true; + } return false; } private static Object getSourceComponent(AnActionEvent e) { - return e.getDataContext().getData(DataConstants.CONTEXT_COMPONENT); + return PlatformDataKeys.CONTEXT_COMPONENT.getData(e.getDataContext()); } } diff --git a/platform/platform-impl/src/com/intellij/ide/errorTreeView/NewErrorTreeViewPanel.java b/platform/platform-impl/src/com/intellij/ide/errorTreeView/NewErrorTreeViewPanel.java index 94852d9b9046..1e56ad0dc092 100644 --- a/platform/platform-impl/src/com/intellij/ide/errorTreeView/NewErrorTreeViewPanel.java +++ b/platform/platform-impl/src/com/intellij/ide/errorTreeView/NewErrorTreeViewPanel.java @@ -20,7 +20,6 @@ import com.intellij.ide.actions.*; import com.intellij.ide.errorTreeView.impl.ErrorTreeViewConfiguration; import com.intellij.ide.errorTreeView.impl.ErrorViewTextExporter; import com.intellij.openapi.actionSystem.*; -import com.intellij.openapi.actionSystem.ex.DataConstantsEx; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Disposer; @@ -54,7 +53,7 @@ public class NewErrorTreeViewPanel extends JPanel implements DataProvider, Occur private ErrorViewStructure myErrorViewStructure; private ErrorViewTreeBuilder myBuilder; - public static interface ProcessController { + public interface ProcessController { void stopProcess(); boolean isProcessStopped(); @@ -160,20 +159,20 @@ public class NewErrorTreeViewPanel extends JPanel implements DataProvider, Occur } public Object getData(String dataId) { - if (DataConstants.NAVIGATABLE.equals(dataId)) { + if (PlatformDataKeys.NAVIGATABLE.is(dataId)) { final NavigatableMessageElement selectedMessageElement = getSelectedMessageElement(); return selectedMessageElement != null? selectedMessageElement.getNavigatable() : null; } - else if (DataConstants.HELP_ID.equals(dataId)) { + else if (PlatformDataKeys.HELP_ID.is(dataId)) { return myHelpId; } - else if (DataConstantsEx.TREE_EXPANDER.equals(dataId)) { + else if (PlatformDataKeys.TREE_EXPANDER.is(dataId)) { return myTreeExpander; } - else if (DataConstants.EXPORTER_TO_TEXT_FILE.equals(dataId)) { + else if (PlatformDataKeys.EXPORTER_TO_TEXT_FILE.is(dataId)) { return myExporterToTextFile; } - else if (CURRENT_EXCEPTION_DATA.equals(dataId)) { + else if (CURRENT_EXCEPTION_DATA_KEY.is(dataId)) { NavigatableMessageElement selectedMessageElement = getSelectedMessageElement(); return selectedMessageElement != null? selectedMessageElement.getData() : null; } @@ -287,7 +286,7 @@ public class NewErrorTreeViewPanel extends JPanel implements DataProvider, Occur return; } DefaultActionGroup group = new DefaultActionGroup(); - if (getData(DataConstants.NAVIGATABLE) != null) { + if (getData(PlatformDataKeys.NAVIGATABLE.getName()) != null) { group.add(ActionManager.getInstance().getAction(IdeActions.ACTION_EDIT_SOURCE)); } addExtraPopupMenuActions(group); diff --git a/platform/platform-impl/src/com/intellij/ide/impl/DataManagerImpl.java b/platform/platform-impl/src/com/intellij/ide/impl/DataManagerImpl.java index 8a64a2cc855f..3ecc9ae676cc 100644 --- a/platform/platform-impl/src/com/intellij/ide/impl/DataManagerImpl.java +++ b/platform/platform-impl/src/com/intellij/ide/impl/DataManagerImpl.java @@ -19,7 +19,6 @@ import com.intellij.ide.DataManager; import com.intellij.ide.IdeEventQueue; import com.intellij.ide.impl.dataRules.*; import com.intellij.openapi.actionSystem.*; -import com.intellij.openapi.actionSystem.ex.DataConstantsEx; import com.intellij.openapi.application.ModalityState; import com.intellij.openapi.components.ApplicationComponent; import com.intellij.openapi.diagnostic.Logger; @@ -242,13 +241,13 @@ public class DataManagerImpl extends DataManager implements ApplicationComponent } private void registerRules() { - myDataConstantToRuleMap.put(DataConstants.COPY_PROVIDER, new CopyProviderRule()); - myDataConstantToRuleMap.put(DataConstants.CUT_PROVIDER, new CutProviderRule()); - myDataConstantToRuleMap.put(DataConstants.PASTE_PROVIDER, new PasteProviderRule()); - myDataConstantToRuleMap.put(DataConstants.FILE_TEXT, new FileTextRule()); - myDataConstantToRuleMap.put(DataConstants.FILE_EDITOR, new FileEditorRule()); - myDataConstantToRuleMap.put(DataConstants.NAVIGATABLE_ARRAY, new NavigatableArrayRule()); - myDataConstantToRuleMap.put(DataConstants.EDITOR_EVEN_IF_INACTIVE, new InactiveEditorRule()); + myDataConstantToRuleMap.put(PlatformDataKeys.COPY_PROVIDER.getName(), new CopyProviderRule()); + myDataConstantToRuleMap.put(PlatformDataKeys.CUT_PROVIDER.getName(), new CutProviderRule()); + myDataConstantToRuleMap.put(PlatformDataKeys.PASTE_PROVIDER.getName(), new PasteProviderRule()); + myDataConstantToRuleMap.put(PlatformDataKeys.FILE_TEXT.getName(), new FileTextRule()); + myDataConstantToRuleMap.put(PlatformDataKeys.FILE_EDITOR.getName(), new FileEditorRule()); + myDataConstantToRuleMap.put(PlatformDataKeys.NAVIGATABLE_ARRAY.getName(), new NavigatableArrayRule()); + myDataConstantToRuleMap.put(PlatformDataKeys.EDITOR_EVEN_IF_INACTIVE.getName(), new InactiveEditorRule()); } @NotNull @@ -286,7 +285,7 @@ public class DataManagerImpl extends DataManager implements ApplicationComponent } Component _component = myRef.get(); - if (DataConstants.IS_MODAL_CONTEXT.equals(dataId)) { + if (PlatformDataKeys.IS_MODAL_CONTEXT.is(dataId)) { if (_component != null) { return IdeKeyEventDispatcher.isModalContext(_component) ? Boolean.TRUE : Boolean.FALSE; } @@ -294,13 +293,13 @@ public class DataManagerImpl extends DataManager implements ApplicationComponent return null; } } - else if (DataConstants.CONTEXT_COMPONENT.equals(dataId)) { + else if (PlatformDataKeys.CONTEXT_COMPONENT.is(dataId)) { return _component; } - else if (DataConstantsEx.MODALITY_STATE.equals(dataId)) { + else if (PlatformDataKeys.MODALITY_STATE.is(dataId)) { return _component != null ? ModalityState.stateForComponent(_component) : ModalityState.NON_MODAL; } - else if (DataConstants.EDITOR.equals(dataId)) { + else if (PlatformDataKeys.EDITOR.is(dataId)) { Editor editor = (Editor)DataManagerImpl.this.getData(dataId, _component); return validateEditor(editor); } diff --git a/platform/platform-impl/src/com/intellij/ide/impl/DataValidator.java b/platform/platform-impl/src/com/intellij/ide/impl/DataValidator.java index f3a307bf52b2..a2e4e3f4062f 100644 --- a/platform/platform-impl/src/com/intellij/ide/impl/DataValidator.java +++ b/platform/platform-impl/src/com/intellij/ide/impl/DataValidator.java @@ -15,7 +15,7 @@ */ package com.intellij.ide.impl; -import com.intellij.openapi.actionSystem.DataConstants; +import com.intellij.openapi.actionSystem.PlatformDataKeys; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.extensions.ExtensionPointName; import com.intellij.openapi.extensions.Extensions; @@ -70,9 +70,9 @@ public abstract class DataValidator { } static { - ourValidators.put(DataConstants.VIRTUAL_FILE, VIRTUAL_FILE_VALIDATOR); - ourValidators.put(DataConstants.VIRTUAL_FILE_ARRAY, new ArrayValidator(VIRTUAL_FILE_VALIDATOR)); - ourValidators.put(DataConstants.PROJECT, PROJECT_VALIDATOR); + ourValidators.put(PlatformDataKeys.VIRTUAL_FILE.getName(), VIRTUAL_FILE_VALIDATOR); + ourValidators.put(PlatformDataKeys.VIRTUAL_FILE_ARRAY.getName(), new ArrayValidator(VIRTUAL_FILE_VALIDATOR)); + ourValidators.put(PlatformDataKeys.PROJECT.getName(), PROJECT_VALIDATOR); } public static class ArrayValidator extends DataValidator { diff --git a/platform/platform-impl/src/com/intellij/ide/impl/dataRules/CopyProviderRule.java b/platform/platform-impl/src/com/intellij/ide/impl/dataRules/CopyProviderRule.java index 5f6df26679e2..96ab24ca33da 100644 --- a/platform/platform-impl/src/com/intellij/ide/impl/dataRules/CopyProviderRule.java +++ b/platform/platform-impl/src/com/intellij/ide/impl/dataRules/CopyProviderRule.java @@ -15,16 +15,16 @@ */ package com.intellij.ide.impl.dataRules; -import com.intellij.ide.CopyProvider; -import com.intellij.openapi.actionSystem.DataConstants; import com.intellij.openapi.actionSystem.DataProvider; +import com.intellij.openapi.actionSystem.PlatformDataKeys; import com.intellij.openapi.editor.ex.EditorEx; public class CopyProviderRule implements GetDataRule { public Object getData(DataProvider dataProvider) { - EditorEx editor = (EditorEx)dataProvider.getData(DataConstants.EDITOR); - if (editor == null) return null; - CopyProvider copyProvider = editor.getCopyProvider(); - return copyProvider; + final EditorEx editor = (EditorEx)dataProvider.getData(PlatformDataKeys.EDITOR.getName()); + if (editor == null) { + return null; + } + return editor.getCopyProvider(); } } diff --git a/platform/platform-impl/src/com/intellij/ide/impl/dataRules/CutProviderRule.java b/platform/platform-impl/src/com/intellij/ide/impl/dataRules/CutProviderRule.java index ca992ec2d59e..5b38e67fc029 100644 --- a/platform/platform-impl/src/com/intellij/ide/impl/dataRules/CutProviderRule.java +++ b/platform/platform-impl/src/com/intellij/ide/impl/dataRules/CutProviderRule.java @@ -15,16 +15,16 @@ */ package com.intellij.ide.impl.dataRules; -import com.intellij.ide.CutProvider; -import com.intellij.openapi.actionSystem.DataConstants; import com.intellij.openapi.actionSystem.DataProvider; +import com.intellij.openapi.actionSystem.PlatformDataKeys; import com.intellij.openapi.editor.ex.EditorEx; public class CutProviderRule implements GetDataRule { public Object getData(DataProvider dataProvider) { - EditorEx editor = (EditorEx)dataProvider.getData(DataConstants.EDITOR); - if (editor == null) return null; - CutProvider cutProvider = editor.getCutProvider(); - return cutProvider; + final EditorEx editor = (EditorEx)dataProvider.getData(PlatformDataKeys.EDITOR.getName()); + if (editor == null) { + return null; + } + return editor.getCutProvider(); } } diff --git a/platform/platform-impl/src/com/intellij/ide/impl/dataRules/FileEditorRule.java b/platform/platform-impl/src/com/intellij/ide/impl/dataRules/FileEditorRule.java index bf48775108a0..e3dcceffb258 100644 --- a/platform/platform-impl/src/com/intellij/ide/impl/dataRules/FileEditorRule.java +++ b/platform/platform-impl/src/com/intellij/ide/impl/dataRules/FileEditorRule.java @@ -15,19 +15,23 @@ */ package com.intellij.ide.impl.dataRules; -import com.intellij.openapi.actionSystem.DataConstants; import com.intellij.openapi.actionSystem.DataProvider; +import com.intellij.openapi.actionSystem.PlatformDataKeys; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.fileEditor.impl.text.TextEditorProvider; import com.intellij.ui.EditorTextField; public class FileEditorRule implements GetDataRule { public Object getData(DataProvider dataProvider) { - final Editor editor = (Editor)dataProvider.getData(DataConstants.EDITOR); - if (editor == null) return null; + final Editor editor = (Editor)dataProvider.getData(PlatformDataKeys.EDITOR.getName()); + if (editor == null) { + return null; + } final Boolean aBoolean = editor.getUserData(EditorTextField.SUPPLEMENTARY_KEY); - if (aBoolean != null && aBoolean.booleanValue()) return null; + if (aBoolean != null && aBoolean.booleanValue()) { + return null; + } return TextEditorProvider.getInstance().getTextEditor(editor); } diff --git a/platform/platform-impl/src/com/intellij/ide/impl/dataRules/FileTextRule.java b/platform/platform-impl/src/com/intellij/ide/impl/dataRules/FileTextRule.java index abbecb38d4d4..aa5323f2675a 100644 --- a/platform/platform-impl/src/com/intellij/ide/impl/dataRules/FileTextRule.java +++ b/platform/platform-impl/src/com/intellij/ide/impl/dataRules/FileTextRule.java @@ -14,36 +14,41 @@ * limitations under the License. */ -/* - * Created by IntelliJ IDEA. - * User: mike - * Date: Aug 16, 2002 - * Time: 1:49:57 PM - * To change template for new class use - * Code Style | Class Templates options (Tools | IDE Options). - */ package com.intellij.ide.impl.dataRules; -import com.intellij.openapi.actionSystem.DataConstants; import com.intellij.openapi.actionSystem.DataProvider; +import com.intellij.openapi.actionSystem.PlatformDataKeys; import com.intellij.openapi.editor.Document; import com.intellij.openapi.fileEditor.FileDocumentManager; import com.intellij.openapi.fileTypes.FileType; import com.intellij.openapi.project.Project; import com.intellij.openapi.vfs.VirtualFile; +/** + * @author mike + */ public class FileTextRule implements GetDataRule { public Object getData(DataProvider dataProvider) { - VirtualFile virtualFile = (VirtualFile)dataProvider.getData(DataConstants.VIRTUAL_FILE); - if (virtualFile == null) return null; + final VirtualFile virtualFile = (VirtualFile)dataProvider.getData(PlatformDataKeys.VIRTUAL_FILE.getName()); + if (virtualFile == null) { + return null; + } + final FileType fileType = virtualFile.getFileType(); - if (fileType.isBinary() || fileType.isReadOnly()) return null; + if (fileType.isBinary() || fileType.isReadOnly()) { + return null; + } - Project project = (Project)dataProvider.getData(DataConstants.PROJECT); - if (project == null) return null; + final Project project = (Project)dataProvider.getData(PlatformDataKeys.PROJECT.getName()); + if (project == null) { + return null; + } + + final Document document = FileDocumentManager.getInstance().getDocument(virtualFile); + if (document == null) { + return null; + } - Document document = FileDocumentManager.getInstance().getDocument(virtualFile); - if (document == null) return null; return document.getText(); } } diff --git a/platform/platform-impl/src/com/intellij/ide/impl/dataRules/InactiveEditorRule.java b/platform/platform-impl/src/com/intellij/ide/impl/dataRules/InactiveEditorRule.java index 2839e8c36afe..c2665e55b0cc 100644 --- a/platform/platform-impl/src/com/intellij/ide/impl/dataRules/InactiveEditorRule.java +++ b/platform/platform-impl/src/com/intellij/ide/impl/dataRules/InactiveEditorRule.java @@ -19,13 +19,13 @@ */ package com.intellij.ide.impl.dataRules; -import com.intellij.openapi.actionSystem.DataConstants; import com.intellij.openapi.actionSystem.DataProvider; +import com.intellij.openapi.actionSystem.PlatformDataKeys; import org.jetbrains.annotations.Nullable; public class InactiveEditorRule implements GetDataRule { @Nullable public Object getData(final DataProvider dataProvider) { - return dataProvider.getData(DataConstants.EDITOR); + return dataProvider.getData(PlatformDataKeys.EDITOR.getName()); } } \ No newline at end of file diff --git a/platform/platform-impl/src/com/intellij/ide/impl/dataRules/NavigatableArrayRule.java b/platform/platform-impl/src/com/intellij/ide/impl/dataRules/NavigatableArrayRule.java index e755cd91fb5d..f0e0ae7de1a0 100644 --- a/platform/platform-impl/src/com/intellij/ide/impl/dataRules/NavigatableArrayRule.java +++ b/platform/platform-impl/src/com/intellij/ide/impl/dataRules/NavigatableArrayRule.java @@ -15,14 +15,17 @@ */ package com.intellij.ide.impl.dataRules; -import com.intellij.openapi.actionSystem.DataConstants; import com.intellij.openapi.actionSystem.DataProvider; +import com.intellij.openapi.actionSystem.PlatformDataKeys; import com.intellij.pom.Navigatable; public class NavigatableArrayRule implements GetDataRule { public Object getData(DataProvider dataProvider) { - final Navigatable element = (Navigatable)dataProvider.getData(DataConstants.NAVIGATABLE); - if (element == null) return null; + final Navigatable element = PlatformDataKeys.NAVIGATABLE.getData(dataProvider); + if (element == null) { + return null; + } + return new Navigatable[]{element}; } } diff --git a/platform/platform-impl/src/com/intellij/ide/impl/dataRules/PasteProviderRule.java b/platform/platform-impl/src/com/intellij/ide/impl/dataRules/PasteProviderRule.java index 6e6c7cbd8be2..646ae5adc07b 100644 --- a/platform/platform-impl/src/com/intellij/ide/impl/dataRules/PasteProviderRule.java +++ b/platform/platform-impl/src/com/intellij/ide/impl/dataRules/PasteProviderRule.java @@ -15,16 +15,17 @@ */ package com.intellij.ide.impl.dataRules; -import com.intellij.ide.PasteProvider; -import com.intellij.openapi.actionSystem.DataConstants; import com.intellij.openapi.actionSystem.DataProvider; +import com.intellij.openapi.actionSystem.PlatformDataKeys; import com.intellij.openapi.editor.ex.EditorEx; public class PasteProviderRule implements GetDataRule { public Object getData(DataProvider dataProvider) { - EditorEx editor = (EditorEx)dataProvider.getData(DataConstants.EDITOR); - if (editor == null) return null; - PasteProvider pasteProvider = editor.getPasteProvider(); - return pasteProvider; + final EditorEx editor = (EditorEx)dataProvider.getData(PlatformDataKeys.EDITOR.getName()); + if (editor == null) { + return null; + } + + return editor.getPasteProvider(); } } diff --git a/platform/platform-impl/src/com/intellij/ide/impl/dataRules/ProjectFileDirectoryRule.java b/platform/platform-impl/src/com/intellij/ide/impl/dataRules/ProjectFileDirectoryRule.java index b10f9cc68650..de5e8b992f79 100644 --- a/platform/platform-impl/src/com/intellij/ide/impl/dataRules/ProjectFileDirectoryRule.java +++ b/platform/platform-impl/src/com/intellij/ide/impl/dataRules/ProjectFileDirectoryRule.java @@ -15,9 +15,8 @@ */ package com.intellij.ide.impl.dataRules; -import com.intellij.openapi.actionSystem.DataConstants; import com.intellij.openapi.actionSystem.DataProvider; -import com.intellij.openapi.actionSystem.ex.DataConstantsEx; +import com.intellij.openapi.actionSystem.PlatformDataKeys; import com.intellij.openapi.project.Project; import com.intellij.openapi.vfs.VirtualFile; @@ -27,9 +26,9 @@ import com.intellij.openapi.vfs.VirtualFile; */ public class ProjectFileDirectoryRule implements GetDataRule { public Object getData(DataProvider dataProvider) { - VirtualFile dir = (VirtualFile)dataProvider.getData(DataConstantsEx.PROJECT_FILE_DIRECTORY); + VirtualFile dir = PlatformDataKeys.PROJECT_FILE_DIRECTORY.getData(dataProvider); if (dir == null) { - final Project project = (Project)dataProvider.getData(DataConstants.PROJECT); + final Project project = PlatformDataKeys.PROJECT.getData(dataProvider); if (project != null) { dir = project.getBaseDir(); } diff --git a/platform/platform-impl/src/com/intellij/openapi/actionSystem/impl/ActionMenuItem.java b/platform/platform-impl/src/com/intellij/openapi/actionSystem/impl/ActionMenuItem.java index b6420e24c583..3fe08af26bef 100644 --- a/platform/platform-impl/src/com/intellij/openapi/actionSystem/impl/ActionMenuItem.java +++ b/platform/platform-impl/src/com/intellij/openapi/actionSystem/impl/ActionMenuItem.java @@ -20,7 +20,6 @@ import com.intellij.openapi.Disposable; import com.intellij.openapi.actionSystem.*; import com.intellij.openapi.actionSystem.ex.ActionManagerEx; import com.intellij.openapi.actionSystem.ex.ActionUtil; -import com.intellij.openapi.actionSystem.ex.DataConstantsEx; import com.intellij.openapi.keymap.KeymapManager; import com.intellij.openapi.keymap.KeymapUtil; import com.intellij.openapi.util.Disposer; @@ -207,7 +206,7 @@ public class ActionMenuItem extends JMenuItem { if (ActionUtil.lastUpdateAndCheckDumb(myAction, event, false)) { ActionManagerEx actionManager = ActionManagerEx.getInstanceEx(); actionManager.fireBeforeActionPerformed(myAction, myContext, event); - Component component = ((Component)event.getDataContext().getData(DataConstantsEx.CONTEXT_COMPONENT)); + Component component = PlatformDataKeys.CONTEXT_COMPONENT.getData(event.getDataContext()); if (component != null && !isInTree(component)) { return; } diff --git a/platform/platform-impl/src/com/intellij/openapi/actionSystem/impl/SimpleDataContext.java b/platform/platform-impl/src/com/intellij/openapi/actionSystem/impl/SimpleDataContext.java index cd979d694758..2d5cdc81b218 100644 --- a/platform/platform-impl/src/com/intellij/openapi/actionSystem/impl/SimpleDataContext.java +++ b/platform/platform-impl/src/com/intellij/openapi/actionSystem/impl/SimpleDataContext.java @@ -15,8 +15,8 @@ */ package com.intellij.openapi.actionSystem.impl; -import com.intellij.openapi.actionSystem.DataConstants; import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.actionSystem.PlatformDataKeys; import com.intellij.openapi.project.Project; public class SimpleDataContext implements DataContext { @@ -37,11 +37,12 @@ public class SimpleDataContext implements DataContext { public static DataContext getSimpleContext(String dataId, Object data, DataContext parent) { return new SimpleDataContext(dataId, data, parent); } + public static DataContext getSimpleContext(String dataId, Object data) { return getSimpleContext(dataId, data, null); } public static DataContext getProjectContext(Project project) { - return getSimpleContext(DataConstants.PROJECT, project); + return getSimpleContext(PlatformDataKeys.PROJECT.getName(), project); } } diff --git a/platform/platform-impl/src/com/intellij/openapi/actionSystem/impl/Utils.java b/platform/platform-impl/src/com/intellij/openapi/actionSystem/impl/Utils.java index 1f2a950aff43..a9fe2bfea964 100644 --- a/platform/platform-impl/src/com/intellij/openapi/actionSystem/impl/Utils.java +++ b/platform/platform-impl/src/com/intellij/openapi/actionSystem/impl/Utils.java @@ -160,7 +160,7 @@ public class Utils{ if (anAction instanceof Separator) { continue; } - final Project project = (Project)context.getData(DataConstants.PROJECT); + final Project project = PlatformDataKeys.PROJECT.getData(context); if (project != null && DumbService.getInstance(project).isDumb() && !(anAction instanceof DumbAware) && !(anAction instanceof ActionGroup)) { continue; } diff --git a/platform/platform-impl/src/com/intellij/openapi/diff/impl/DiffPanelImpl.java b/platform/platform-impl/src/com/intellij/openapi/diff/impl/DiffPanelImpl.java index 68042341ac6f..058bae0df39b 100644 --- a/platform/platform-impl/src/com/intellij/openapi/diff/impl/DiffPanelImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/diff/impl/DiffPanelImpl.java @@ -17,8 +17,8 @@ package com.intellij.openapi.diff.impl; import com.intellij.openapi.Disposable; import com.intellij.openapi.actionSystem.ActionManager; -import com.intellij.openapi.actionSystem.DataConstants; import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.actionSystem.PlatformDataKeys; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.diff.*; import com.intellij.openapi.diff.actions.MergeActionGroup; @@ -129,7 +129,7 @@ public class DiffPanelImpl implements DiffPanelEx, ContentChangeListener, TwoSid myPanel.requestScrollEditors(); } - private DiffHighlighterFactory createHighlighter(FileType contentType, Project project) { + private static DiffHighlighterFactory createHighlighter(FileType contentType, Project project) { return new DiffHighlighterFactoryImpl(contentType, project); } @@ -187,7 +187,6 @@ public class DiffPanelImpl implements DiffPanelEx, ContentChangeListener, TwoSid private void updateStatusBar() { int differentLineBlocks = getLineBlocks().getCount(); - String text; myPanel.setStatusBarText(DiffBundle.message("diff.count.differences.status.text", differentLineBlocks)); } @@ -324,7 +323,7 @@ public class DiffPanelImpl implements DiffPanelEx, ContentChangeListener, TwoSid myPanel.setBottomComponent(newBottomComponent); } - private void setWindowTitle(Window window, String title) { + private static void setWindowTitle(Window window, String title) { if (window instanceof JDialog) { ((JDialog)window).setTitle(title); } @@ -333,7 +332,7 @@ public class DiffPanelImpl implements DiffPanelEx, ContentChangeListener, TwoSid @Nullable public static DiffPanelImpl fromDataContext(DataContext dataContext) { - DiffViewer viewer = (DiffViewer)dataContext.getData(DataConstants.DIFF_VIEWER); + DiffViewer viewer = PlatformDataKeys.DIFF_VIEWER.getData(dataContext); return viewer instanceof DiffPanelImpl ? (DiffPanelImpl)viewer : null; } @@ -378,8 +377,13 @@ public class DiffPanelImpl implements DiffPanelEx, ContentChangeListener, TwoSid @Override public Object getData(String dataId) { - if (DataConstants.DIFF_VIEWER.equals(dataId)) return myDiffPanel; - if (FocusDiffSide.FOCUSED_DIFF_SIDE.equals(dataId)) return myDiffPanel.myCurrentSide == null ? null : myFocusDiffSide; + if (PlatformDataKeys.DIFF_VIEWER.is(dataId)) { + return myDiffPanel; + } + if (FocusDiffSide.DATA_KEY.is(dataId)) { + return myDiffPanel.myCurrentSide == null ? null : myFocusDiffSide; + } + return super.getData(dataId); } } diff --git a/platform/platform-impl/src/com/intellij/openapi/diff/impl/DiffUtil.java b/platform/platform-impl/src/com/intellij/openapi/diff/impl/DiffUtil.java index d0601ba5c9c8..fab48ba838ab 100644 --- a/platform/platform-impl/src/com/intellij/openapi/diff/impl/DiffUtil.java +++ b/platform/platform-impl/src/com/intellij/openapi/diff/impl/DiffUtil.java @@ -32,6 +32,9 @@ import com.intellij.util.ImageLoader; import org.jetbrains.annotations.NotNull; public class DiffUtil { + private DiffUtil() { + } + public static void initDiffFrame(FrameWrapper frameWrapper, final DiffPanelImpl diffPanel) { Project project = diffPanel.getProject(); frameWrapper.setComponent(diffPanel.getComponent()); @@ -43,7 +46,7 @@ public class DiffUtil { } public static FocusDiffSide getFocusDiffSide(DataContext dataContext) { - return (FocusDiffSide)dataContext.getData(FocusDiffSide.FOCUSED_DIFF_SIDE); + return FocusDiffSide.DATA_KEY.getData(dataContext); } public static String[] convertToLines(@NotNull String text) { diff --git a/platform/platform-impl/src/com/intellij/openapi/diff/impl/FrameWrapper.java b/platform/platform-impl/src/com/intellij/openapi/diff/impl/FrameWrapper.java index 9205af2bd529..c9062c7b11f4 100644 --- a/platform/platform-impl/src/com/intellij/openapi/diff/impl/FrameWrapper.java +++ b/platform/platform-impl/src/com/intellij/openapi/diff/impl/FrameWrapper.java @@ -16,14 +16,16 @@ package com.intellij.openapi.diff.impl; import com.intellij.openapi.Disposable; -import com.intellij.openapi.actionSystem.DataConstants; import com.intellij.openapi.actionSystem.DataProvider; +import com.intellij.openapi.actionSystem.PlatformDataKeys; import com.intellij.openapi.application.impl.ApplicationInfoImpl; import com.intellij.openapi.project.Project; import com.intellij.openapi.project.ProjectManager; import com.intellij.openapi.project.ProjectManagerAdapter; import com.intellij.openapi.project.ProjectManagerListener; -import com.intellij.openapi.util.*; +import com.intellij.openapi.util.ActionCallback; +import com.intellij.openapi.util.DimensionService; +import com.intellij.openapi.util.Disposer; import com.intellij.openapi.wm.FocusWatcher; import com.intellij.openapi.wm.IdeFocusManager; import com.intellij.ui.FocusTrackback; @@ -63,7 +65,7 @@ public class FrameWrapper implements Disposable { public void setProject(Project project) { myProject = project; - setData(DataConstants.PROJECT, project); + setData(PlatformDataKeys.PROJECT.getName(), project); ProjectManager.getInstance().addProjectManagerListener(project, myProjectListener); } diff --git a/platform/platform-impl/src/com/intellij/openapi/diff/impl/GenericDataProvider.java b/platform/platform-impl/src/com/intellij/openapi/diff/impl/GenericDataProvider.java index 250ebf320e75..ec9da8fc2c22 100644 --- a/platform/platform-impl/src/com/intellij/openapi/diff/impl/GenericDataProvider.java +++ b/platform/platform-impl/src/com/intellij/openapi/diff/impl/GenericDataProvider.java @@ -15,10 +15,7 @@ */ package com.intellij.openapi.diff.impl; -import com.intellij.openapi.actionSystem.DataConstants; import com.intellij.openapi.actionSystem.DataProvider; -import com.intellij.openapi.diff.impl.util.FocusDiffSide; -import com.intellij.openapi.editor.Editor; import java.util.HashMap; import java.util.Map; diff --git a/platform/platform-impl/src/com/intellij/openapi/diff/impl/incrementalMerge/MergeList.java b/platform/platform-impl/src/com/intellij/openapi/diff/impl/incrementalMerge/MergeList.java index 08961b5371d9..24a24125fd66 100644 --- a/platform/platform-impl/src/com/intellij/openapi/diff/impl/incrementalMerge/MergeList.java +++ b/platform/platform-impl/src/com/intellij/openapi/diff/impl/incrementalMerge/MergeList.java @@ -18,6 +18,7 @@ package com.intellij.openapi.diff.impl.incrementalMerge; import com.intellij.openapi.actionSystem.AnAction; import com.intellij.openapi.actionSystem.AnActionEvent; import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.actionSystem.DataKey; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.diff.DiffBundle; import com.intellij.openapi.diff.DiffContent; @@ -35,8 +36,8 @@ import com.intellij.openapi.util.*; import com.intellij.util.containers.FilteringIterator; import com.intellij.util.containers.SequenceIterator; import org.jetbrains.annotations.NonNls; -import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.util.ArrayList; import java.util.Iterator; @@ -49,7 +50,9 @@ public class MergeList implements ChangeList.Parent, UserDataHolder { private final UserDataHolderBase myDataHolder = new UserDataHolderBase(); public static final FragmentSide BRANCH_SIDE = FragmentSide.SIDE2; public static final FragmentSide BASE_SIDE = FragmentSide.SIDE1; - @NonNls public static final String MERGE_LIST = "mergeList"; + + public static final DataKey DATA_KEY = DataKey.create("mergeList"); + @Deprecated public static final String MERGE_LIST = DATA_KEY.getName(); private MergeList(Project project, Document left, Document base, Document right) { myProject = project; @@ -229,7 +232,7 @@ public class MergeList implements ChangeList.Parent, UserDataHolder { @Nullable public static MergeList fromDataContext(DataContext dataContext) { - MergeList mergeList = (MergeList)dataContext.getData(MERGE_LIST); + MergeList mergeList = MergeList.DATA_KEY.getData(dataContext); if (mergeList != null) return mergeList; MergePanel2 mergePanel = MergePanel2.fromDataContext(dataContext); return mergePanel == null ? null : mergePanel.getMergeList(); diff --git a/platform/platform-impl/src/com/intellij/openapi/diff/impl/incrementalMerge/ui/MergePanel2.java b/platform/platform-impl/src/com/intellij/openapi/diff/impl/incrementalMerge/ui/MergePanel2.java index 7374181b6101..35993f9e20fc 100644 --- a/platform/platform-impl/src/com/intellij/openapi/diff/impl/incrementalMerge/ui/MergePanel2.java +++ b/platform/platform-impl/src/com/intellij/openapi/diff/impl/incrementalMerge/ui/MergePanel2.java @@ -16,7 +16,10 @@ package com.intellij.openapi.diff.impl.incrementalMerge.ui; import com.intellij.openapi.Disposable; -import com.intellij.openapi.actionSystem.*; +import com.intellij.openapi.actionSystem.ActionManager; +import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.actionSystem.IdeActions; +import com.intellij.openapi.actionSystem.PlatformDataKeys; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.diff.*; import com.intellij.openapi.diff.actions.NextDiffAction; @@ -73,7 +76,7 @@ public class MergePanel2 implements DiffViewer { private final DividersRepainter myDividersRepainter = new DividersRepainter(); private StatusUpdater myStatusUpdater; private final DialogBuilder myBuilder; - private MergePanel2.MyDataProvider myProvider; + private MyDataProvider myProvider; public MergePanel2(DialogBuilder builder, Disposable parent) { ArrayList editorPlaces = new ArrayList(); @@ -400,7 +403,7 @@ public class MergePanel2 implements DiffViewer { private class MyDataProvider extends GenericDataProvider { public Object getData(String dataId) { - if (FocusDiffSide.FOCUSED_DIFF_SIDE.equals(dataId)) { + if (FocusDiffSide.DATA_KEY.is(dataId)) { int index = getFocusedEditorIndex(); if (index < 0) return null; switch (index) { @@ -412,7 +415,7 @@ public class MergePanel2 implements DiffViewer { return new BranchFocusedSide(FragmentSide.SIDE2); } } - else if (DataConstants.DIFF_VIEWER.equals(dataId)) return MergePanel2.this; + else if (PlatformDataKeys.DIFF_VIEWER.is(dataId)) return MergePanel2.this; return super.getData(dataId); } @@ -460,7 +463,7 @@ public class MergePanel2 implements DiffViewer { } public static MergePanel2 fromDataContext(DataContext dataContext) { - DiffViewer diffComponent = (DiffViewer)dataContext.getData(DataConstants.DIFF_VIEWER); + DiffViewer diffComponent = PlatformDataKeys.DIFF_VIEWER.getData(dataContext); return diffComponent instanceof MergePanel2 ? (MergePanel2)diffComponent : null; } diff --git a/platform/platform-impl/src/com/intellij/openapi/diff/impl/mergeTool/MergeRequestImpl.java b/platform/platform-impl/src/com/intellij/openapi/diff/impl/mergeTool/MergeRequestImpl.java index ae89c270507c..55b52645b3fe 100644 --- a/platform/platform-impl/src/com/intellij/openapi/diff/impl/mergeTool/MergeRequestImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/diff/impl/mergeTool/MergeRequestImpl.java @@ -16,22 +16,23 @@ package com.intellij.openapi.diff.impl.mergeTool; import com.intellij.ide.DataManager; -import com.intellij.openapi.actionSystem.DataConstants; +import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.actionSystem.PlatformDataKeys; import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.command.CommandProcessor; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.diff.*; import com.intellij.openapi.diff.impl.incrementalMerge.ChangeCounter; import com.intellij.openapi.diff.impl.incrementalMerge.ui.MergePanel2; import com.intellij.openapi.editor.Document; -import com.intellij.openapi.fileEditor.OpenFileDescriptor; import com.intellij.openapi.fileEditor.FileDocumentManager; +import com.intellij.openapi.fileEditor.OpenFileDescriptor; import com.intellij.openapi.fileTypes.FileType; import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.DialogBuilder; import com.intellij.openapi.ui.DialogWrapper; import com.intellij.openapi.ui.Messages; import com.intellij.openapi.vfs.VirtualFile; -import com.intellij.openapi.command.CommandProcessor; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.Nullable; @@ -150,7 +151,8 @@ public class MergeRequestImpl extends MergeRequest { } builder.setOkOperation(new Runnable() { public void run() { - myActionButtonPresentation.run((DiffViewer)DataManager.getInstance().getDataContext(builder.getCenterPanel()).getData(DataConstants.DIFF_VIEWER)); + final DataContext dataContext = DataManager.getInstance().getDataContext(builder.getCenterPanel()); + myActionButtonPresentation.run(PlatformDataKeys.DIFF_VIEWER.getData(dataContext)); if (myActionButtonPresentation.closeDialog()) { builder.getDialogWrapper().close(DialogWrapper.OK_EXIT_CODE); } @@ -238,12 +240,11 @@ public class MergeRequestImpl extends MergeRequest { if (!getWholePanel().isDisplayable()) return; myWasInvoked = true; ChangeCounter.getOrCreate(myMergePanel.getMergeList()).removeListener(this); - int doApply = Messages.showDialog(getProject(), - DiffBundle.message("merge.all.changes.have.processed.save.and.finish.confirmation.text"), - DiffBundle.message("all.changes.processed.dialog.title"), - new String[]{DiffBundle.message("merge.save.and.finish.button"), - DiffBundle.message("merge.continue.button")}, 0, - Messages.getQuestionIcon()); + int doApply = Messages + .showDialog(getProject(), DiffBundle.message("merge.all.changes.have.processed.save.and.finish.confirmation.text"), + DiffBundle.message("all.changes.processed.dialog.title"), + new String[]{DiffBundle.message("merge.save.and.finish.button"), DiffBundle.message("merge.continue.button")}, 0, + Messages.getQuestionIcon()); if (doApply != 0) return; myDialogWrapper.close(DialogWrapper.OK_EXIT_CODE); } diff --git a/platform/platform-impl/src/com/intellij/openapi/diff/impl/util/DiffPanelOutterComponent.java b/platform/platform-impl/src/com/intellij/openapi/diff/impl/util/DiffPanelOutterComponent.java index e001f7518b39..373a1917dcb9 100644 --- a/platform/platform-impl/src/com/intellij/openapi/diff/impl/util/DiffPanelOutterComponent.java +++ b/platform/platform-impl/src/com/intellij/openapi/diff/impl/util/DiffPanelOutterComponent.java @@ -15,9 +15,8 @@ */ package com.intellij.openapi.diff.impl.util; -import com.intellij.openapi.actionSystem.DataConstants; import com.intellij.openapi.actionSystem.DataProvider; -import com.intellij.openapi.actionSystem.ex.DataConstantsEx; +import com.intellij.openapi.actionSystem.PlatformDataKeys; import com.intellij.openapi.diff.DiffRequest; import com.intellij.openapi.diff.DiffToolbar; import com.intellij.openapi.diff.ex.DiffStatusBar; @@ -87,9 +86,13 @@ public class DiffPanelOutterComponent extends JPanel implements DataProvider { } public Object getData(String dataId) { - if (DataConstantsEx.SOURCE_NAVIGATION_LOCKED.equals(dataId)) return Boolean.TRUE; - if (myDataProvider == null) return null; - if (dataId == DataConstants.EDITOR) { + if (PlatformDataKeys.SOURCE_NAVIGATION_LOCKED.is(dataId)) { + return Boolean.TRUE; + } + if (myDataProvider == null) { + return null; + } + if (PlatformDataKeys.EDITOR.is(dataId)) { if (myBottomComponent != null) { // we don't want editor actions to be executed when the bottom component has focus final Component focusOwner = KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner(); @@ -97,7 +100,7 @@ public class DiffPanelOutterComponent extends JPanel implements DataProvider { return null; } } - FocusDiffSide side = (FocusDiffSide)myDataProvider.getData(FocusDiffSide.FOCUSED_DIFF_SIDE); + FocusDiffSide side = (FocusDiffSide)myDataProvider.getData(FocusDiffSide.DATA_KEY.getName()); if (side != null) return side.getEditor(); } return myDataProvider.getData(dataId); @@ -156,7 +159,8 @@ public class DiffPanelOutterComponent extends JPanel implements DataProvider { return NO_SCROLL_NEEDED; } - public void deferScroll(DiffPanelOutterComponent outter) { } + public void deferScroll(DiffPanelOutterComponent outter) { + } }; private static final DeferScrollToFirstDiff SCROLL_WHEN_POSSIBLE = new DeferScrollToFirstDiff() { diff --git a/platform/platform-impl/src/com/intellij/openapi/diff/impl/util/FocusDiffSide.java b/platform/platform-impl/src/com/intellij/openapi/diff/impl/util/FocusDiffSide.java index d5fa5276e197..26e793c63f1e 100644 --- a/platform/platform-impl/src/com/intellij/openapi/diff/impl/util/FocusDiffSide.java +++ b/platform/platform-impl/src/com/intellij/openapi/diff/impl/util/FocusDiffSide.java @@ -15,11 +15,14 @@ */ package com.intellij.openapi.diff.impl.util; +import com.intellij.openapi.actionSystem.DataKey; import com.intellij.openapi.editor.Editor; -import org.jetbrains.annotations.NonNls; public interface FocusDiffSide { - @NonNls String FOCUSED_DIFF_SIDE = "focusedDiffSide"; + DataKey DATA_KEY = DataKey.create("focusedDiffSide"); + @Deprecated String FOCUSED_DIFF_SIDE = DATA_KEY.getName(); + Editor getEditor(); + int[] getFragmentStartingLines(); } diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/actions/EscapeAction.java b/platform/platform-impl/src/com/intellij/openapi/editor/actions/EscapeAction.java index c84b3e667ce2..6ffff109d4b5 100644 --- a/platform/platform-impl/src/com/intellij/openapi/editor/actions/EscapeAction.java +++ b/platform/platform-impl/src/com/intellij/openapi/editor/actions/EscapeAction.java @@ -14,23 +14,18 @@ * limitations under the License. */ -/* - * Created by IntelliJ IDEA. - * User: max - * Date: May 15, 2002 - * Time: 8:25:25 PM - * To change template for new class use - * Code Style | Class Templates options (Tools | IDE Options). - */ package com.intellij.openapi.editor.actions; -import com.intellij.openapi.actionSystem.DataConstants; import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.actionSystem.PlatformDataKeys; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.editor.SelectionModel; import com.intellij.openapi.editor.actionSystem.EditorAction; import com.intellij.openapi.editor.actionSystem.EditorActionHandler; +/** + * @author max + */ public class EscapeAction extends EditorAction { public EscapeAction() { super(new Handler()); @@ -43,7 +38,7 @@ public class EscapeAction extends EditorAction { public boolean isEnabled(Editor editor, DataContext dataContext) { SelectionModel selectionModel = editor.getSelectionModel(); - return dataContext.getData(DataConstants.IS_MODAL_CONTEXT) != Boolean.TRUE && + return PlatformDataKeys.IS_MODAL_CONTEXT.getData(dataContext) != Boolean.TRUE && (selectionModel.hasSelection() || selectionModel.hasBlockSelection()); } } diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/actions/ToggleColumnModeAction.java b/platform/platform-impl/src/com/intellij/openapi/editor/actions/ToggleColumnModeAction.java index 10e4271dbdad..9f28b4ab72ed 100644 --- a/platform/platform-impl/src/com/intellij/openapi/editor/actions/ToggleColumnModeAction.java +++ b/platform/platform-impl/src/com/intellij/openapi/editor/actions/ToggleColumnModeAction.java @@ -25,12 +25,12 @@ package com.intellij.openapi.editor.actions; import com.intellij.openapi.actionSystem.AnActionEvent; -import com.intellij.openapi.actionSystem.DataConstants; +import com.intellij.openapi.actionSystem.PlatformDataKeys; import com.intellij.openapi.actionSystem.ToggleAction; -import com.intellij.openapi.editor.ex.EditorEx; -import com.intellij.openapi.editor.SelectionModel; import com.intellij.openapi.editor.CaretModel; import com.intellij.openapi.editor.LogicalPosition; +import com.intellij.openapi.editor.SelectionModel; +import com.intellij.openapi.editor.ex.EditorEx; import com.intellij.openapi.project.DumbAware; public class ToggleColumnModeAction extends ToggleAction implements DumbAware { @@ -58,9 +58,13 @@ public class ToggleColumnModeAction extends ToggleAction implements DumbAware { } } else { - boolean hasSelection = selectionModel.hasBlockSelection(); - int selStart = hasSelection ? editor.logicalPositionToOffset(selectionModel.getBlockStart()) : 0; - int selEnd = hasSelection ? editor.logicalPositionToOffset(selectionModel.getBlockEnd()) : 0; + final boolean hasSelection = selectionModel.hasBlockSelection(); + final LogicalPosition blockStart = selectionModel.getBlockStart(); + final LogicalPosition blockEnd = selectionModel.getBlockEnd(); + + int selStart = hasSelection && blockStart != null ? editor.logicalPositionToOffset(blockStart) : 0; + int selEnd = hasSelection && blockEnd != null ? editor.logicalPositionToOffset(blockEnd) : 0; + editor.setColumnMode(false); if (hasSelection) { selectionModel.setSelection(selStart, selEnd); @@ -77,7 +81,7 @@ public class ToggleColumnModeAction extends ToggleAction implements DumbAware { } private static EditorEx getEditor(AnActionEvent e) { - return (EditorEx) e.getDataContext().getData(DataConstants.EDITOR); + return (EditorEx) PlatformDataKeys.EDITOR.getData(e.getDataContext()); } public void update(AnActionEvent e){ diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorComponentImpl.java b/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorComponentImpl.java index bc0a3fb12e2e..e6c07a9ca7ad 100644 --- a/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorComponentImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorComponentImpl.java @@ -16,12 +16,12 @@ package com.intellij.openapi.editor.impl; import com.intellij.ide.ui.UISettings; -import com.intellij.openapi.actionSystem.DataConstants; import com.intellij.openapi.actionSystem.DataProvider; +import com.intellij.openapi.actionSystem.PlatformDataKeys; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.application.impl.ApplicationImpl; -import com.intellij.openapi.ui.TestableUi; import com.intellij.openapi.editor.ex.util.EditorUtil; +import com.intellij.openapi.ui.TestableUi; import com.intellij.openapi.ui.TypingTarget; import com.intellij.openapi.util.ActionCallback; @@ -54,20 +54,20 @@ public class EditorComponentImpl extends JComponent implements Scrollable, DataP public Object getData(String dataId) { if (myEditor.isRendererMode()) return null; - if (DataConstants.EDITOR.equals(dataId)) { + if (PlatformDataKeys.EDITOR.is(dataId)) { // for 'big' editors return null to allow injected editors (see com.intellij.openapi.fileEditor.impl.text.TextEditorComponent.getData()) return myEditor.getVirtualFile() == null ? myEditor : null; } - if (DataConstants.DELETE_ELEMENT_PROVIDER.equals(dataId)) { + if (PlatformDataKeys.DELETE_ELEMENT_PROVIDER.is(dataId)) { return myEditor.getDeleteProvider(); } - if (DataConstants.CUT_PROVIDER.equals(dataId)) { + if (PlatformDataKeys.CUT_PROVIDER.is(dataId)) { return myEditor.getCutProvider(); } - if (DataConstants.COPY_PROVIDER.equals(dataId)) { + if (PlatformDataKeys.COPY_PROVIDER.is(dataId)) { return myEditor.getCopyProvider(); } - if (DataConstants.PASTE_PROVIDER.equals(dataId)) { + if (PlatformDataKeys.PASTE_PROVIDER.is(dataId)) { return myEditor.getPasteProvider(); } diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorImpl.java b/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorImpl.java index b3dd1e787bfa..60783f5aa660 100644 --- a/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorImpl.java @@ -22,7 +22,10 @@ import com.intellij.codeInsight.hint.TooltipGroup; import com.intellij.concurrency.JobScheduler; import com.intellij.ide.*; import com.intellij.ide.dnd.DnDManager; -import com.intellij.openapi.actionSystem.*; +import com.intellij.openapi.actionSystem.ActionManager; +import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.actionSystem.IdeActions; +import com.intellij.openapi.actionSystem.PlatformDataKeys; import com.intellij.openapi.actionSystem.ex.ActionManagerEx; import com.intellij.openapi.application.Application; import com.intellij.openapi.application.ApplicationManager; @@ -2356,7 +2359,7 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi return new DataContext() { public Object getData(String dataId) { - if (DataConstants.PROJECT.equals(dataId)) { + if (PlatformDataKeys.PROJECT.is(dataId)) { return myProject; } return original.getData(dataId); diff --git a/platform/platform-impl/src/com/intellij/openapi/fileChooser/ex/FileChooserDialogImpl.java b/platform/platform-impl/src/com/intellij/openapi/fileChooser/ex/FileChooserDialogImpl.java index c06cd00ccc3b..f46d15598a28 100644 --- a/platform/platform-impl/src/com/intellij/openapi/fileChooser/ex/FileChooserDialogImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/fileChooser/ex/FileChooserDialogImpl.java @@ -70,7 +70,7 @@ public class FileChooserDialogImpl extends DialogWrapper implements FileChooserD private JPanel myNorthPanel; private static boolean ourToShowTextField = true; - private FileChooserDialogImpl.TextFieldAction myTextFieldAction; + private TextFieldAction myTextFieldAction; protected FileTextFieldImpl myPathTextField; @@ -232,7 +232,8 @@ public class FileChooserDialogImpl extends DialogWrapper implements FileChooserD if (isTextFieldActive()) { final String text = myPathTextField.getTextFieldText(); - if (text == null || myPathTextField.getFile() == null || !myPathTextField.getFile().exists()) { + final LookupFile file = myPathTextField.getFile(); + if (text == null || file == null || !file.exists()) { setErrorText("Specified path cannot be found"); return; } @@ -367,7 +368,7 @@ public class FileChooserDialogImpl extends DialogWrapper implements FileChooserD } public Object getData(String dataId) { - if (DataConstants.VIRTUAL_FILE_ARRAY.equals(dataId)) { + if (PlatformDataKeys.VIRTUAL_FILE_ARRAY.is(dataId)) { return getSelectedFiles(); } else if (KEY.is(dataId)) { return FileChooserDialogImpl.this; diff --git a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/EditorComposite.java b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/EditorComposite.java index 07845e46adfc..95f57a3866dd 100644 --- a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/EditorComposite.java +++ b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/EditorComposite.java @@ -16,13 +16,13 @@ package com.intellij.openapi.fileEditor.impl; import com.intellij.openapi.Disposable; -import com.intellij.openapi.project.DumbService; -import com.intellij.openapi.actionSystem.DataConstants; import com.intellij.openapi.actionSystem.DataProvider; import com.intellij.openapi.actionSystem.IdeActions; +import com.intellij.openapi.actionSystem.PlatformDataKeys; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.fileEditor.*; import com.intellij.openapi.fileEditor.ex.FileEditorManagerEx; +import com.intellij.openapi.project.DumbService; import com.intellij.openapi.util.Comparing; import com.intellij.openapi.util.Disposer; import com.intellij.openapi.util.Pair; @@ -386,13 +386,13 @@ public abstract class EditorComposite implements Disposable { } public final Object getData(String dataId){ - if (DataConstants.FILE_EDITOR.equals(dataId)) { + if (PlatformDataKeys.FILE_EDITOR.is(dataId)) { return getSelectedEditor(); } - else if(DataConstants.VIRTUAL_FILE.equals(dataId)){ + else if(PlatformDataKeys.VIRTUAL_FILE.is(dataId)){ return myFile.isValid() ? myFile : null; } - else if(DataConstants.VIRTUAL_FILE_ARRAY.equals(dataId)){ + else if(PlatformDataKeys.VIRTUAL_FILE_ARRAY.is(dataId)){ return myFile.isValid() ? new VirtualFile[] {myFile} : null; } else{ diff --git a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/EditorTabbedContainer.java b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/EditorTabbedContainer.java index 0ee379ca3b89..4ba35866079a 100644 --- a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/EditorTabbedContainer.java +++ b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/EditorTabbedContainer.java @@ -21,7 +21,6 @@ import com.intellij.ide.ui.UISettings; import com.intellij.ide.ui.customization.CustomActionsSchema; import com.intellij.openapi.Disposable; import com.intellij.openapi.actionSystem.*; -import com.intellij.openapi.actionSystem.ex.DataConstantsEx; import com.intellij.openapi.editor.colors.EditorColorsManager; import com.intellij.openapi.extensions.Extensions; import com.intellij.openapi.fileEditor.FileEditor; @@ -315,17 +314,17 @@ final class EditorTabbedContainer implements Disposable { private class MyDataProvider implements DataProvider { public Object getData(@NonNls final String dataId) { - if (DataConstants.PROJECT.equals(dataId)) { + if (PlatformDataKeys.PROJECT.is(dataId)) { return myProject; } - if (DataConstants.VIRTUAL_FILE.equals(dataId)) { + if (PlatformDataKeys.VIRTUAL_FILE.is(dataId)) { final VirtualFile selectedFile = myWindow.getSelectedFile(); return selectedFile != null && selectedFile.isValid() ? selectedFile : null; } - if (DataConstantsEx.EDITOR_WINDOW.equals(dataId)) { + if (EditorWindow.DATA_KEY.is(dataId)) { return myWindow; } - if (DataConstants.HELP_ID.equals(dataId)) { + if (PlatformDataKeys.HELP_ID.is(dataId)) { return HELP_ID; } return null; diff --git a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/EditorWindow.java b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/EditorWindow.java index df1a03e5958b..4a2cb302ff32 100644 --- a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/EditorWindow.java +++ b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/EditorWindow.java @@ -16,9 +16,9 @@ package com.intellij.openapi.fileEditor.impl; import com.intellij.ide.ui.UISettings; -import com.intellij.openapi.actionSystem.DataConstants; +import com.intellij.openapi.actionSystem.DataKey; import com.intellij.openapi.actionSystem.DataProvider; -import com.intellij.openapi.actionSystem.ex.DataConstantsEx; +import com.intellij.openapi.actionSystem.PlatformDataKeys; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.fileEditor.FileEditorManagerListener; @@ -47,6 +47,8 @@ import java.util.Set; public class EditorWindow { private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.fileEditor.impl.EditorWindow"); + public static final DataKey DATA_KEY = DataKey.create("editorWindow"); + protected JPanel myPanel; private EditorTabbedContainer myTabbedPane; private final EditorsSplitters myOwner; @@ -307,11 +309,11 @@ public class EditorWindow { } public Object getData(String dataId) { - if (dataId.equals(DataConstants.VIRTUAL_FILE)){ + if (PlatformDataKeys.VIRTUAL_FILE.is(dataId)){ final VirtualFile virtualFile = myEditor.getFile(); return virtualFile.isValid() ? virtualFile : null; } - else if (dataId.equals(DataConstants.PROJECT)) { + else if (PlatformDataKeys.PROJECT.is(dataId)) { return myEditor.getFileEditorManager().getProject(); } return null; @@ -327,7 +329,7 @@ public class EditorWindow { } public Object getData(String dataId) { - if (dataId.equals(DataConstantsEx.EDITOR_WINDOW)){ + if (EditorWindow.DATA_KEY.is(dataId)){ // this is essintial for ability to close opened file return myWindow; } diff --git a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/MoveEditorToOppositeTabGroupAction.java b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/MoveEditorToOppositeTabGroupAction.java index 3310dc26ed75..b970a2937e09 100644 --- a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/MoveEditorToOppositeTabGroupAction.java +++ b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/MoveEditorToOppositeTabGroupAction.java @@ -16,10 +16,9 @@ package com.intellij.openapi.fileEditor.impl; import com.intellij.openapi.actionSystem.*; -import com.intellij.openapi.actionSystem.ex.DataConstantsEx; import com.intellij.openapi.fileEditor.ex.FileEditorManagerEx; -import com.intellij.openapi.project.Project; import com.intellij.openapi.project.DumbAware; +import com.intellij.openapi.project.Project; import com.intellij.openapi.vfs.VirtualFile; /** @@ -35,7 +34,7 @@ public class MoveEditorToOppositeTabGroupAction extends AnAction implements Dumb if (vFile == null || project == null){ return; } - final EditorWindow window = (EditorWindow)dataContext.getData(DataConstantsEx.EDITOR_WINDOW); + final EditorWindow window = EditorWindow.DATA_KEY.getData(dataContext); if (window != null) { final EditorWindow[] siblings = window.findSiblings (); if (siblings != null && siblings.length == 1) { @@ -50,7 +49,7 @@ public class MoveEditorToOppositeTabGroupAction extends AnAction implements Dumb final Presentation presentation = e.getPresentation(); final DataContext dataContext = e.getDataContext(); final VirtualFile vFile = PlatformDataKeys.VIRTUAL_FILE.getData(dataContext); - final EditorWindow window = (EditorWindow)dataContext.getData(DataConstantsEx.EDITOR_WINDOW); + final EditorWindow window = EditorWindow.DATA_KEY.getData(dataContext); if (ActionPlaces.isPopupPlace(e.getPlace())) { presentation.setVisible(isEnabled(vFile, window)); } diff --git a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/text/TextEditorComponent.java b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/text/TextEditorComponent.java index 6559e94d27ec..399b84762412 100644 --- a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/text/TextEditorComponent.java +++ b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/text/TextEditorComponent.java @@ -37,7 +37,10 @@ import com.intellij.openapi.fileEditor.impl.FileEditorManagerImpl; import com.intellij.openapi.fileTypes.FileTypeEvent; import com.intellij.openapi.fileTypes.FileTypeListener; import com.intellij.openapi.project.Project; -import com.intellij.openapi.vfs.*; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.openapi.vfs.VirtualFileAdapter; +import com.intellij.openapi.vfs.VirtualFileEvent; +import com.intellij.openapi.vfs.VirtualFilePropertyEvent; import com.intellij.openapi.wm.WindowManager; import com.intellij.openapi.wm.ex.StatusBarEx; import com.intellij.util.EditorPopupHandler; @@ -281,10 +284,10 @@ class TextEditorComponent extends JPanel implements DataProvider{ if (o != null) return o; } - if (dataId.equals(DataConstants.EDITOR)) { + if (PlatformDataKeys.EDITOR.is(dataId)) { return e; } - if (dataId.equals(DataConstants.VIRTUAL_FILE)) { + if (PlatformDataKeys.VIRTUAL_FILE.is(dataId)) { return myFile.isValid()? myFile : null; // fix for SCR 40329 } return null; diff --git a/platform/platform-impl/src/com/intellij/openapi/keymap/impl/IdeKeyEventDispatcher.java b/platform/platform-impl/src/com/intellij/openapi/keymap/impl/IdeKeyEventDispatcher.java index fd1910851573..3d02d028eb0f 100644 --- a/platform/platform-impl/src/com/intellij/openapi/keymap/impl/IdeKeyEventDispatcher.java +++ b/platform/platform-impl/src/com/intellij/openapi/keymap/impl/IdeKeyEventDispatcher.java @@ -22,7 +22,6 @@ import com.intellij.openapi.Disposable; import com.intellij.openapi.actionSystem.*; import com.intellij.openapi.actionSystem.ex.ActionManagerEx; import com.intellij.openapi.actionSystem.ex.ActionUtil; -import com.intellij.openapi.actionSystem.ex.DataConstantsEx; import com.intellij.openapi.actionSystem.impl.PresentationFactory; import com.intellij.openapi.application.Application; import com.intellij.openapi.application.ApplicationManager; @@ -473,7 +472,7 @@ public final class IdeKeyEventDispatcher implements Disposable { public boolean processAction(final InputEvent e, ActionProcessor processor) { ActionManagerEx actionManager = ActionManagerEx.getInstanceEx(); - final Project project = (Project)myContext.getDataContext().getData(DataConstants.PROJECT); + final Project project = PlatformDataKeys.PROJECT.getData(myContext.getDataContext()); final boolean dumb = project != null && DumbService.getInstance(project).isDumb(); List nonDumbAwareAction = new ArrayList(); for (final AnAction action : myContext.getActions()) { @@ -502,7 +501,7 @@ public final class IdeKeyEventDispatcher implements Disposable { ((DataManagerImpl.MyDataContext)myContext.getDataContext()).setEventCount(IdeEventQueue.getInstance().getEventCount()); actionManager.fireBeforeActionPerformed(action, actionEvent.getDataContext(), actionEvent); - Component component = (Component)actionEvent.getDataContext().getData(DataConstantsEx.CONTEXT_COMPONENT); + Component component = PlatformDataKeys.CONTEXT_COMPONENT.getData(actionEvent.getDataContext()); if (component != null && !component.isShowing()) { return true; } diff --git a/platform/platform-impl/src/com/intellij/openapi/keymap/impl/IdeMouseEventDispatcher.java b/platform/platform-impl/src/com/intellij/openapi/keymap/impl/IdeMouseEventDispatcher.java index 8190d2982041..397f38d26538 100644 --- a/platform/platform-impl/src/com/intellij/openapi/keymap/impl/IdeMouseEventDispatcher.java +++ b/platform/platform-impl/src/com/intellij/openapi/keymap/impl/IdeMouseEventDispatcher.java @@ -173,7 +173,7 @@ public final class IdeMouseEventDispatcher{ action.beforeActionPerformedUpdate(actionEvent); if(presentation.isEnabled()){ actionManager.fireBeforeActionPerformed(action, dataContext, actionEvent); - Component c = (Component)dataContext.getData(DataConstants.CONTEXT_COMPONENT); + Component c = PlatformDataKeys.CONTEXT_COMPONENT.getData(dataContext); if (c != null && !c.isShowing()) { continue; } diff --git a/platform/platform-impl/src/com/intellij/openapi/options/newEditor/OptionsEditor.java b/platform/platform-impl/src/com/intellij/openapi/options/newEditor/OptionsEditor.java index 0677ad79cd58..d5e4c80c1ce1 100644 --- a/platform/platform-impl/src/com/intellij/openapi/options/newEditor/OptionsEditor.java +++ b/platform/platform-impl/src/com/intellij/openapi/options/newEditor/OptionsEditor.java @@ -671,7 +671,7 @@ public class OptionsEditor extends JPanel implements DataProvider, Place.Navigat public Object getData(@NonNls final String dataId) { - if (dataId.equals(KEY.getName())) { + if (KEY.is(dataId)) { return this; } return History.KEY.is(dataId) ? myHistory : null; diff --git a/platform/platform-impl/src/com/intellij/openapi/options/newEditor/OptionsEditorDialog.java b/platform/platform-impl/src/com/intellij/openapi/options/newEditor/OptionsEditorDialog.java index c1764c8d5c6f..d8aea28d4de3 100644 --- a/platform/platform-impl/src/com/intellij/openapi/options/newEditor/OptionsEditorDialog.java +++ b/platform/platform-impl/src/com/intellij/openapi/options/newEditor/OptionsEditorDialog.java @@ -19,6 +19,7 @@ import com.intellij.CommonBundle; import com.intellij.ide.ui.search.SearchUtil; import com.intellij.ide.util.PropertiesComponent; import com.intellij.openapi.actionSystem.DataProvider; +import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.help.HelpManager; import com.intellij.openapi.options.Configurable; import com.intellij.openapi.options.ConfigurableGroup; @@ -28,7 +29,6 @@ import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.DialogWrapper; import com.intellij.openapi.util.ActionCallback; import com.intellij.openapi.util.Disposer; -import com.intellij.openapi.application.ApplicationManager; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -235,7 +235,7 @@ public class OptionsEditorDialog extends DialogWrapper implements DataProvider{ } public Object getData(@NonNls String dataId) { - if (dataId.equals(OptionsEditor.KEY.getName())) { + if (OptionsEditor.KEY.is(dataId)) { return myEditor; } return null; @@ -252,4 +252,4 @@ public class OptionsEditorDialog extends DialogWrapper implements DataProvider{ } } -} \ No newline at end of file +} diff --git a/platform/platform-impl/src/com/intellij/openapi/wm/impl/IdeFrameImpl.java b/platform/platform-impl/src/com/intellij/openapi/wm/impl/IdeFrameImpl.java index 60fc192c15ad..437798bfb912 100644 --- a/platform/platform-impl/src/com/intellij/openapi/wm/impl/IdeFrameImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/wm/impl/IdeFrameImpl.java @@ -21,8 +21,8 @@ import com.intellij.ide.impl.ProjectUtil; import com.intellij.ide.ui.UISettings; import com.intellij.openapi.MnemonicHelper; import com.intellij.openapi.actionSystem.ActionManager; -import com.intellij.openapi.actionSystem.DataConstants; import com.intellij.openapi.actionSystem.DataProvider; +import com.intellij.openapi.actionSystem.PlatformDataKeys; import com.intellij.openapi.application.Application; import com.intellij.openapi.application.ApplicationInfo; import com.intellij.openapi.application.ApplicationManager; @@ -190,7 +190,7 @@ public class IdeFrameImpl extends JFrame implements IdeFrame, DataProvider { } public Object getData(final String dataId) { - if (DataConstants.PROJECT.equals(dataId)) { + if (PlatformDataKeys.PROJECT.is(dataId)) { if (myProject != null) { return myProject.isInitialized() ? myProject : null; } diff --git a/platform/platform-impl/src/com/intellij/openapi/wm/impl/InternalDecorator.java b/platform/platform-impl/src/com/intellij/openapi/wm/impl/InternalDecorator.java index 60c0e69bd9b6..42d5ba42a933 100644 --- a/platform/platform-impl/src/com/intellij/openapi/wm/impl/InternalDecorator.java +++ b/platform/platform-impl/src/com/intellij/openapi/wm/impl/InternalDecorator.java @@ -860,7 +860,7 @@ public final class InternalDecorator extends JPanel implements TestableUi, TypeS final AnActionEvent event = new AnActionEvent(null, dataContext, ActionPlaces.UNKNOWN, myAction.getTemplatePresentation(), ActionManager.getInstance(), 0); actionManager.fireBeforeActionPerformed(myAction, dataContext, event); - final Component component = ((Component)dataContext.getData(DataConstants.CONTEXT_COMPONENT)); + final Component component = PlatformDataKeys.CONTEXT_COMPONENT.getData(dataContext); if (component != null && !component.isShowing()) { return; } diff --git a/platform/platform-impl/src/com/intellij/openapi/wm/impl/WindowWatcher.java b/platform/platform-impl/src/com/intellij/openapi/wm/impl/WindowWatcher.java index 34b546490c93..e275bacc07d5 100644 --- a/platform/platform-impl/src/com/intellij/openapi/wm/impl/WindowWatcher.java +++ b/platform/platform-impl/src/com/intellij/openapi/wm/impl/WindowWatcher.java @@ -16,7 +16,7 @@ package com.intellij.openapi.wm.impl; import com.intellij.ide.DataManager; -import com.intellij.openapi.actionSystem.DataConstants; +import com.intellij.openapi.actionSystem.DataContext; import com.intellij.openapi.actionSystem.PlatformDataKeys; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.diagnostic.Logger; @@ -87,7 +87,8 @@ public final class WindowWatcher implements PropertyChangeListener{ final Project project = PlatformDataKeys.PROJECT.getData(DataManager.getInstance().getDataContext(myFocusedWindow)); for (Iterator i = myFocusedWindows.iterator(); i.hasNext();) { final Window w = (Window)i.next(); - if (project==DataManager.getInstance().getDataContext(w).getData(DataConstants.PROJECT)) { + final DataContext dataContext = DataManager.getInstance().getDataContext(w); + if (project == PlatformDataKeys.PROJECT.getData(dataContext)) { i.remove(); } } @@ -293,7 +294,8 @@ public final class WindowWatcher implements PropertyChangeListener{ continue outer; } } - if (project==DataManager.getInstance().getDataContext(window).getData(DataConstants.PROJECT)) { + final DataContext dataContext = DataManager.getInstance().getDataContext(window); + if (project == PlatformDataKeys.PROJECT.getData(dataContext)) { return window; } } diff --git a/platform/platform-impl/src/com/intellij/openapi/wm/impl/content/ToolWindowContentUi.java b/platform/platform-impl/src/com/intellij/openapi/wm/impl/content/ToolWindowContentUi.java index 748d1cf29ace..52bb3be4d5c0 100644 --- a/platform/platform-impl/src/com/intellij/openapi/wm/impl/content/ToolWindowContentUi.java +++ b/platform/platform-impl/src/com/intellij/openapi/wm/impl/content/ToolWindowContentUi.java @@ -345,7 +345,7 @@ public class ToolWindowContentUi extends JPanel implements ContentUI, PropertyCh @Nullable public Object getData(@NonNls String dataId) { - if (dataId.equals(PlatformDataKeys.TOOL_WINDOW.getName())) return myWindow; + if (PlatformDataKeys.TOOL_WINDOW.is(dataId)) return myWindow; return null; } diff --git a/platform/platform-impl/src/com/intellij/openapi/wm/impl/status/AddTestProcessAction.java b/platform/platform-impl/src/com/intellij/openapi/wm/impl/status/AddTestProcessAction.java index 616478f24485..3662ecf17aac 100644 --- a/platform/platform-impl/src/com/intellij/openapi/wm/impl/status/AddTestProcessAction.java +++ b/platform/platform-impl/src/com/intellij/openapi/wm/impl/status/AddTestProcessAction.java @@ -17,15 +17,13 @@ package com.intellij.openapi.wm.impl.status; import com.intellij.openapi.actionSystem.AnAction; import com.intellij.openapi.actionSystem.AnActionEvent; -import com.intellij.openapi.actionSystem.DataKey; import com.intellij.openapi.actionSystem.PlatformDataKeys; -import com.intellij.openapi.actionSystem.ex.DataConstantsEx; import com.intellij.openapi.progress.PerformInBackgroundOption; import com.intellij.openapi.progress.ProcessCanceledException; import com.intellij.openapi.progress.ProgressIndicator; import com.intellij.openapi.progress.Task; -import com.intellij.openapi.project.Project; import com.intellij.openapi.project.DumbAware; +import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.MessageType; import com.intellij.openapi.wm.ToolWindowManager; import org.jetbrains.annotations.NotNull; @@ -41,7 +39,7 @@ public class AddTestProcessAction extends AnAction implements DumbAware { } public void actionPerformed(AnActionEvent e) { - final Project p = (Project)e.getData(DataKey.create(DataConstantsEx.PROJECT)); + final Project p = PlatformDataKeys.PROJECT.getData(e.getDataContext()); if (p != null) { ToolWindowManager.getInstance(p) .notifyByBalloon("TODO", MessageType.INFO, "Started. Click me!", null, new HyperlinkListener() { diff --git a/platform/platform-impl/src/com/intellij/openapi/wm/impl/status/EncodingPanel.java b/platform/platform-impl/src/com/intellij/openapi/wm/impl/status/EncodingPanel.java index cea02c107a5d..0fbc1de73614 100644 --- a/platform/platform-impl/src/com/intellij/openapi/wm/impl/status/EncodingPanel.java +++ b/platform/platform-impl/src/com/intellij/openapi/wm/impl/status/EncodingPanel.java @@ -25,11 +25,11 @@ import com.intellij.openapi.fileEditor.FileEditorManager; import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.popup.JBPopupFactory; import com.intellij.openapi.ui.popup.ListPopup; -import com.intellij.openapi.vfs.VirtualFile; -import com.intellij.openapi.vfs.encoding.ChooseFileEncodingAction; -import com.intellij.openapi.vfs.encoding.ChangeEncodingUpdateGroup; -import com.intellij.openapi.vfs.encoding.EncodingManager; import com.intellij.openapi.util.Pair; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.openapi.vfs.encoding.ChangeEncodingUpdateGroup; +import com.intellij.openapi.vfs.encoding.ChooseFileEncodingAction; +import com.intellij.openapi.vfs.encoding.EncodingManager; import javax.swing.*; import java.awt.event.MouseAdapter; @@ -112,8 +112,8 @@ public class EncodingPanel extends TextPanel implements StatusBarPatch { } }; DataContext context = DataManager.getInstance().getDataContext(statusBar); - DataContext dataContext = SimpleDataContext.getSimpleContext(DataConstants.VIRTUAL_FILE, virtualFile, - SimpleDataContext.getSimpleContext(DataConstants.PROJECT, getProject(), context)); + DataContext dataContext = SimpleDataContext.getSimpleContext(PlatformDataKeys.VIRTUAL_FILE.getName(), virtualFile, + SimpleDataContext.getSimpleContext(PlatformDataKeys.PROJECT.getName(), getProject(), context)); Presentation presentation = changeAction.getTemplatePresentation(); AnActionEvent event = new AnActionEvent(null, dataContext, ActionPlaces.UNKNOWN, presentation, ActionManager.getInstance(), 0); changeAction.update(event); diff --git a/platform/platform-impl/src/com/intellij/platform/FilesystemToolwindow.java b/platform/platform-impl/src/com/intellij/platform/FilesystemToolwindow.java index fb32a8f21b2a..a956b93cba19 100644 --- a/platform/platform-impl/src/com/intellij/platform/FilesystemToolwindow.java +++ b/platform/platform-impl/src/com/intellij/platform/FilesystemToolwindow.java @@ -19,8 +19,8 @@ */ package com.intellij.platform; -import com.intellij.openapi.actionSystem.DataConstants; import com.intellij.openapi.actionSystem.DataProvider; +import com.intellij.openapi.actionSystem.PlatformDataKeys; import com.intellij.openapi.fileChooser.FileChooserDescriptor; import com.intellij.openapi.fileChooser.FileSystemTree; import com.intellij.openapi.fileChooser.ex.FileSystemTreeImpl; @@ -76,13 +76,13 @@ public class FilesystemToolwindow { @Nullable public Object getData(@NonNls final String dataId) { - if (DataConstants.NAVIGATABLE.equals(dataId)) { + if (PlatformDataKeys.NAVIGATABLE.is(dataId)) { final VirtualFile file = myFsTree.getSelectedFile(); if (file != null) { return new OpenFileDescriptor(myProject, file); } } - else if (DataConstants.VIRTUAL_FILE.equals(dataId)) { + else if (PlatformDataKeys.VIRTUAL_FILE.is(dataId)) { return myFsTree.getSelectedFile(); } return null; diff --git a/platform/platform-impl/src/com/intellij/ui/EditorTextField.java b/platform/platform-impl/src/com/intellij/ui/EditorTextField.java index 543409e48e8d..c0a3a8a913e8 100644 --- a/platform/platform-impl/src/com/intellij/ui/EditorTextField.java +++ b/platform/platform-impl/src/com/intellij/ui/EditorTextField.java @@ -15,8 +15,8 @@ */ package com.intellij.ui; -import com.intellij.openapi.actionSystem.DataConstants; import com.intellij.openapi.actionSystem.DataProvider; +import com.intellij.openapi.actionSystem.PlatformDataKeys; import com.intellij.openapi.application.Application; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.command.CommandProcessor; @@ -497,7 +497,7 @@ public class EditorTextField extends JPanel implements DocumentListener, TextCom public Object getData(String dataId) { if (myEditor != null && myEditor.isRendererMode()) return null; - if (DataConstants.EDITOR.equals(dataId)) { + if (PlatformDataKeys.EDITOR.is(dataId)) { return myEditor; } diff --git a/platform/platform-impl/src/com/intellij/ui/FocusTrackback.java b/platform/platform-impl/src/com/intellij/ui/FocusTrackback.java index b5a7ba473eb0..16e0466639e0 100644 --- a/platform/platform-impl/src/com/intellij/ui/FocusTrackback.java +++ b/platform/platform-impl/src/com/intellij/ui/FocusTrackback.java @@ -16,8 +16,8 @@ package com.intellij.ui; import com.intellij.ide.DataManager; -import com.intellij.openapi.actionSystem.DataConstants; import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.actionSystem.PlatformDataKeys; import com.intellij.openapi.application.Application; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.diagnostic.Logger; @@ -38,7 +38,6 @@ import java.util.List; import java.util.Map; import java.util.WeakHashMap; - public class FocusTrackback { private static final Logger LOG = Logger.getInstance("#com.intellij.ui.FocusTrackback"); @@ -107,12 +106,12 @@ public class FocusTrackback { } } - private Component getFocusFor(Window parent) { + private static Component getFocusFor(Window parent) { final WeakReference ref = ourRootWindowToFocusedMap.get(parent); return ref != null ? ref.get() : null; } - private void setFocusFor(Window parent, Component focus) { + private static void setFocusFor(Window parent, Component focus) { ourRootWindowToFocusedMap.put(parent, new WeakReference(focus)); } @@ -166,7 +165,7 @@ public class FocusTrackback { DataContext context = myParentWindow == null ? DataManager.getInstance().getDataContext() : DataManager.getInstance().getDataContext(myParentWindow); if (context != null) { - project = (Project)context.getData(DataConstants.PROJECT); + project = PlatformDataKeys.PROJECT.getData(context); } mySheduledForRestore = true; @@ -355,11 +354,11 @@ public class FocusTrackback { return mySheduledForRestore; } - public static interface Provider { + public interface Provider { FocusTrackback getFocusTrackback(); } - public static interface ComponentQuery { + public interface ComponentQuery { Component getComponent(); } @@ -403,4 +402,4 @@ public class FocusTrackback { return "focus trackback"; } } -} \ No newline at end of file +} diff --git a/platform/platform-impl/src/com/intellij/ui/content/ComponentContentUI.java b/platform/platform-impl/src/com/intellij/ui/content/ComponentContentUI.java deleted file mode 100644 index e9b9440486a9..000000000000 --- a/platform/platform-impl/src/com/intellij/ui/content/ComponentContentUI.java +++ /dev/null @@ -1,89 +0,0 @@ -/* - * Copyright 2000-2009 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 com.intellij.ui.content; - - -import com.intellij.openapi.actionSystem.ex.DataConstantsEx; -import com.intellij.openapi.actionSystem.DataProvider; - -import javax.swing.*; -import java.awt.*; - -public class ComponentContentUI implements ContentUI { - private ContentManager myManager; - private final JPanel myPanel; - - public ComponentContentUI() { - myPanel = new MyPanel(); - } - - public JComponent getComponent() { - return myPanel; - } - - public void setManager(ContentManager manager) { - myManager = manager; - myManager.addContentManagerListener(new MyContentManagerListener()); - } - - private class MyContentManagerListener extends ContentManagerAdapter { - public void selectionChanged(ContentManagerEvent event) { - myPanel.removeAll(); - Content content = event.getContent(); - if (content != null) { - myPanel.add(content.getComponent(), BorderLayout.CENTER); - myPanel.validate(); - myPanel.repaint(); - } - } - } - - private class MyPanel extends JPanel implements DataProvider { - public MyPanel() { - super(new BorderLayout()); - setBorder(BorderFactory.createEmptyBorder(2, 2, 2, 2)); - } - - public Object getData(String dataId) { - if (DataConstantsEx.CONTENT_MANAGER.equals(dataId)) { - return myManager; - } - if (DataConstantsEx.NONEMPTY_CONTENT_MANAGER.equals(dataId) && myManager.getContentCount() > 1) { - return myManager; - } - return null; - } - } - - public boolean isSingleSelection() { - return true; - } - - public boolean isToSelectAddedContent() { - return true; - } - - public boolean canBeEmptySelection() { - return false; - } - - public void beforeDispose() { - } - - public void dispose() { - } -} - diff --git a/platform/platform-impl/src/com/intellij/ui/content/ContentManagerUtil.java b/platform/platform-impl/src/com/intellij/ui/content/ContentManagerUtil.java index 78008b05baa9..f8fb44179cec 100644 --- a/platform/platform-impl/src/com/intellij/ui/content/ContentManagerUtil.java +++ b/platform/platform-impl/src/com/intellij/ui/content/ContentManagerUtil.java @@ -17,12 +17,14 @@ package com.intellij.ui.content; import com.intellij.openapi.actionSystem.DataContext; import com.intellij.openapi.actionSystem.PlatformDataKeys; -import com.intellij.openapi.actionSystem.ex.DataConstantsEx; import com.intellij.openapi.project.Project; import com.intellij.openapi.wm.ex.ToolWindowEx; import com.intellij.openapi.wm.ex.ToolWindowManagerEx; public class ContentManagerUtil { + private ContentManagerUtil() { + } + /** * This is utility method. It returns ContentManager from the current context. */ @@ -49,7 +51,7 @@ public class ContentManagerUtil { return null; } - final ContentManager fromContext = (ContentManager)dataContext.getData(DataConstantsEx.CONTENT_MANAGER); + final ContentManager fromContext = PlatformDataKeys.CONTENT_MANAGER.getData(dataContext); if (fromContext != null) return fromContext; return toolWindow != null ? toolWindow.getContentManager() : null; diff --git a/platform/platform-impl/src/com/intellij/ui/content/TabbedPaneContentUI.java b/platform/platform-impl/src/com/intellij/ui/content/TabbedPaneContentUI.java index 4b48aff3b3d8..6e88467dad1f 100644 --- a/platform/platform-impl/src/com/intellij/ui/content/TabbedPaneContentUI.java +++ b/platform/platform-impl/src/com/intellij/ui/content/TabbedPaneContentUI.java @@ -16,14 +16,13 @@ package com.intellij.ui.content; import com.intellij.openapi.actionSystem.*; -import com.intellij.openapi.actionSystem.ex.DataConstantsEx; import com.intellij.openapi.util.SystemInfo; import com.intellij.ui.PopupHandler; -import com.intellij.ui.TabbedPaneWrapper; -import com.intellij.ui.TabbedPaneImpl; import com.intellij.ui.TabbedPane; -import com.intellij.ui.content.tabs.TabbedContentAction; +import com.intellij.ui.TabbedPaneImpl; +import com.intellij.ui.TabbedPaneWrapper; import com.intellij.ui.content.tabs.PinToolwindowTabAction; +import com.intellij.ui.content.tabs.TabbedContentAction; import com.intellij.util.IJSwingUtilities; import javax.swing.*; @@ -149,7 +148,7 @@ public class TabbedPaneContentUI implements ContentUI, PropertyChangeListener { return; } final Content content = myManager.getContent(index); - if (content.isCloseable()) { + if (content != null && content.isCloseable()) { myManager.removeContent(content, true); } } @@ -201,7 +200,7 @@ public class TabbedPaneContentUI implements ContentUI, PropertyChangeListener { return new MyModelListener(); } - private class MyModelListener extends JTabbedPane.ModelListener { + private class MyModelListener extends ModelListener { public void stateChanged(ChangeEvent e) { Content content = getSelectedContent(); if (content != null) { @@ -271,10 +270,10 @@ public class TabbedPaneContentUI implements ContentUI, PropertyChangeListener { } public Object getData(String dataId) { - if (DataConstantsEx.CONTENT_MANAGER.equals(dataId)) { + if (PlatformDataKeys.CONTENT_MANAGER.is(dataId)) { return myManager; } - if (DataConstantsEx.NONEMPTY_CONTENT_MANAGER.equals(dataId) && myManager.getContentCount() > 1) { + if (PlatformDataKeys.NONEMPTY_CONTENT_MANAGER.is(dataId) && myManager.getContentCount() > 1) { return myManager; } return null; diff --git a/platform/platform-impl/src/com/intellij/ui/content/impl/ContentManagerImpl.java b/platform/platform-impl/src/com/intellij/ui/content/impl/ContentManagerImpl.java index 2cfc088b64fb..bc1dd41c6607 100644 --- a/platform/platform-impl/src/com/intellij/ui/content/impl/ContentManagerImpl.java +++ b/platform/platform-impl/src/com/intellij/ui/content/impl/ContentManagerImpl.java @@ -18,7 +18,7 @@ package com.intellij.ui.content.impl; import com.intellij.openapi.Disposable; import com.intellij.openapi.actionSystem.AnAction; import com.intellij.openapi.actionSystem.DataProvider; -import com.intellij.openapi.actionSystem.ex.DataConstantsEx; +import com.intellij.openapi.actionSystem.PlatformDataKeys; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.components.ServiceManager; import com.intellij.openapi.diagnostic.Logger; @@ -116,8 +116,8 @@ public class ContentManagerImpl implements ContentManager, PropertyChangeListene @Nullable public Object getData(@NonNls final String dataId) { - if (DataConstantsEx.CONTENT_MANAGER.equals(dataId)) return ContentManagerImpl.this; - if (DataConstantsEx.NONEMPTY_CONTENT_MANAGER.equals(dataId) && getContentCount() > 1) { + if (PlatformDataKeys.CONTENT_MANAGER.is(dataId)) return ContentManagerImpl.this; + if (PlatformDataKeys.NONEMPTY_CONTENT_MANAGER.is(dataId) && getContentCount() > 1) { return ContentManagerImpl.this; } @@ -423,7 +423,11 @@ public class ContentManagerImpl implements ContentManager, PropertyChangeListene Content selectedContent = getSelectedContent(); int index = getIndexOfContent(selectedContent); index = (index - 1 + contentCount) % contentCount; - return setSelectedContentCB(getContent(index), true); + final Content content = getContent(index); + if (content == null) { + return null; + } + return setSelectedContentCB(content, true); } public ActionCallback selectNextContent() { @@ -432,7 +436,11 @@ public class ContentManagerImpl implements ContentManager, PropertyChangeListene Content selectedContent = getSelectedContent(); int index = getIndexOfContent(selectedContent); index = (index + 1) % contentCount; - return setSelectedContentCB(getContent(index), true); + final Content content = getContent(index); + if (content == null) { + return null; + } + return setSelectedContentCB(content, true); } public void addContentManagerListener(@NotNull ContentManagerListener l) { diff --git a/platform/platform-impl/src/com/intellij/ui/popup/AbstractPopup.java b/platform/platform-impl/src/com/intellij/ui/popup/AbstractPopup.java index 07c3490725e2..3c2a8d22df3c 100644 --- a/platform/platform-impl/src/com/intellij/ui/popup/AbstractPopup.java +++ b/platform/platform-impl/src/com/intellij/ui/popup/AbstractPopup.java @@ -18,7 +18,6 @@ package com.intellij.ui.popup; import com.intellij.codeInsight.hint.HintUtil; import com.intellij.ide.ui.UISettings; import com.intellij.openapi.Disposable; -import com.intellij.openapi.actionSystem.DataConstants; import com.intellij.openapi.actionSystem.DataContext; import com.intellij.openapi.actionSystem.JBAwtEventQueue; import com.intellij.openapi.actionSystem.PlatformDataKeys; @@ -365,7 +364,7 @@ public class AbstractPopup implements JBPopup { } private RelativePoint relativePointByQuickSearch(final DataContext dataContext) { - Rectangle dominantArea = (Rectangle)dataContext.getData(DataConstants.DOMINANT_HINT_AREA_RECTANGLE); + Rectangle dominantArea = PlatformDataKeys.DOMINANT_HINT_AREA_RECTANGLE.getData(dataContext); if (dominantArea != null) { final Component focusedComponent = getWndManager().getFocusedComponent(myProject); @@ -394,7 +393,7 @@ public class AbstractPopup implements JBPopup { assert editor.getComponent().isShowing() : "Editor must be showing on the screen"; DataContext context = ((EditorEx)editor).getDataContext(); - Rectangle dominantArea = (Rectangle)context.getData(DataConstants.DOMINANT_HINT_AREA_RECTANGLE); + Rectangle dominantArea = PlatformDataKeys.DOMINANT_HINT_AREA_RECTANGLE.getData(context); if (dominantArea != null && !myRequestFocus) { final JLayeredPane layeredPane = editor.getContentComponent().getRootPane().getLayeredPane(); show(relativePointWithDominantRectangle(layeredPane, dominantArea)); @@ -1108,7 +1107,7 @@ public class AbstractPopup implements JBPopup { final Window window = getPopupWindow(); if (window != null) { myRestoreWindowSize = window.getSize(); - window.hide(); + window.setVisible(true); } } } diff --git a/platform/platform-impl/src/com/intellij/ui/popup/list/ListPopupImpl.java b/platform/platform-impl/src/com/intellij/ui/popup/list/ListPopupImpl.java index 67c907e66a1e..b97170169374 100644 --- a/platform/platform-impl/src/com/intellij/ui/popup/list/ListPopupImpl.java +++ b/platform/platform-impl/src/com/intellij/ui/popup/list/ListPopupImpl.java @@ -15,8 +15,8 @@ */ package com.intellij.ui.popup.list; -import com.intellij.openapi.actionSystem.DataConstants; import com.intellij.openapi.actionSystem.DataProvider; +import com.intellij.openapi.actionSystem.PlatformDataKeys; import com.intellij.openapi.ui.popup.ListPopup; import com.intellij.openapi.ui.popup.ListPopupStep; import com.intellij.openapi.ui.popup.PopupStep; @@ -409,7 +409,7 @@ public class ListPopupImpl extends WizardPopup implements ListPopup { } public Object getData(String dataId) { - if (dataId.equals(DataConstants.SELECTED_ITEM)){ + if (PlatformDataKeys.SELECTED_ITEM.is(dataId)){ return myList.getSelectedValue(); } return null; diff --git a/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/ui/statistics/ShowStatisticsAction.java b/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/ui/statistics/ShowStatisticsAction.java index fcc57cf7ce3a..c53534853c5e 100644 --- a/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/ui/statistics/ShowStatisticsAction.java +++ b/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/ui/statistics/ShowStatisticsAction.java @@ -51,7 +51,7 @@ public class ShowStatisticsAction extends AnAction { } @Nullable - private Object getSelectedTestProxy(final AnActionEvent e) { - return e.getDataContext().getData (AbstractTestProxy.DATA_CONSTANT); + private static Object getSelectedTestProxy(final AnActionEvent e) { + return AbstractTestProxy.DATA_KEY.getData(e.getDataContext()); } } diff --git a/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/ui/statistics/ShowTestProxy.java b/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/ui/statistics/ShowTestProxy.java index a48032d53469..a4215234bc89 100644 --- a/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/ui/statistics/ShowTestProxy.java +++ b/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/ui/statistics/ShowTestProxy.java @@ -24,7 +24,7 @@ import org.jetbrains.annotations.Nullable; /** * @author Roman Chernyatchik */ -public class ShowTestProxy extends AnAction{ +public class ShowTestProxy extends AnAction { public void actionPerformed(final AnActionEvent e) { final StatisticsPanel sender = e.getData(StatisticsPanel.SM_TEST_RUNNER_STATISTICS); if (sender == null) { @@ -45,6 +45,7 @@ public class ShowTestProxy extends AnAction{ } @Nullable - private Object getSelectedTestProxy(final AnActionEvent e) { - return e.getDataContext().getData (AbstractTestProxy.DATA_CONSTANT); - }} + private static Object getSelectedTestProxy(final AnActionEvent e) { + return AbstractTestProxy.DATA_KEY.getData(e.getDataContext()); + } +} diff --git a/platform/testFramework/src/com/intellij/testFramework/LightPlatformCodeInsightTestCase.java b/platform/testFramework/src/com/intellij/testFramework/LightPlatformCodeInsightTestCase.java index ecc558628445..1f091888542d 100644 --- a/platform/testFramework/src/com/intellij/testFramework/LightPlatformCodeInsightTestCase.java +++ b/platform/testFramework/src/com/intellij/testFramework/LightPlatformCodeInsightTestCase.java @@ -15,39 +15,36 @@ */ package com.intellij.testFramework; -import com.intellij.openapi.diagnostic.Logger; -import com.intellij.openapi.editor.*; -import com.intellij.openapi.editor.actionSystem.EditorActionManager; -import com.intellij.openapi.editor.actionSystem.EditorActionHandler; -import com.intellij.openapi.editor.ex.util.EditorUtil; -import com.intellij.openapi.editor.ex.DocumentEx; -import com.intellij.openapi.editor.impl.DocumentImpl; -import com.intellij.openapi.vfs.VirtualFile; -import com.intellij.openapi.vfs.CharsetToolkit; -import com.intellij.openapi.vfs.VfsUtil; -import com.intellij.openapi.vfs.encoding.EncodingProjectManager; +import com.intellij.ide.DataManager; +import com.intellij.injected.editor.DocumentWindow; +import com.intellij.injected.editor.EditorWindow; +import com.intellij.openapi.actionSystem.*; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.application.ex.PathManagerEx; import com.intellij.openapi.command.CommandProcessor; -import com.intellij.openapi.util.io.FileUtil; -import com.intellij.openapi.util.text.StringUtil; -import com.intellij.openapi.fileTypes.StdFileTypes; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.editor.*; +import com.intellij.openapi.editor.actionSystem.EditorActionHandler; +import com.intellij.openapi.editor.actionSystem.EditorActionManager; +import com.intellij.openapi.editor.ex.DocumentEx; +import com.intellij.openapi.editor.ex.util.EditorUtil; +import com.intellij.openapi.editor.impl.DocumentImpl; +import com.intellij.openapi.fileEditor.FileDocumentManager; import com.intellij.openapi.fileEditor.FileEditorManager; import com.intellij.openapi.fileEditor.OpenFileDescriptor; -import com.intellij.openapi.fileEditor.FileDocumentManager; +import com.intellij.openapi.fileTypes.StdFileTypes; import com.intellij.openapi.project.ProjectManager; -import com.intellij.openapi.actionSystem.DataConstants; -import com.intellij.openapi.actionSystem.AnActionEvent; -import com.intellij.openapi.actionSystem.DataContext; -import com.intellij.openapi.actionSystem.IdeActions; -import com.intellij.psi.PsiFile; +import com.intellij.openapi.util.io.FileUtil; +import com.intellij.openapi.util.text.StringUtil; +import com.intellij.openapi.vfs.CharsetToolkit; +import com.intellij.openapi.vfs.VfsUtil; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.openapi.vfs.encoding.EncodingProjectManager; import com.intellij.psi.PsiDocumentManager; +import com.intellij.psi.PsiFile; +import com.intellij.psi.codeStyle.CodeStyleSettingsManager; import com.intellij.psi.impl.source.PostprocessReformattingAspect; import com.intellij.psi.impl.source.tree.injected.InjectedLanguageUtil; -import com.intellij.psi.codeStyle.CodeStyleSettingsManager; -import com.intellij.injected.editor.EditorWindow; -import com.intellij.injected.editor.DocumentWindow; -import com.intellij.ide.DataManager; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.Nullable; @@ -385,16 +382,16 @@ public abstract class LightPlatformCodeInsightTestCase extends LightPlatformTest } public Object getData(String dataId) { - if (dataId.equals(DataConstants.EDITOR)) { + if (PlatformDataKeys.EDITOR.is(dataId)) { return myEditor; } - if (dataId.equals(AnActionEvent.injectedId(DataConstants.EDITOR))) { + if (dataId.equals(AnActionEvent.injectedId(PlatformDataKeys.EDITOR.getName()))) { return InjectedLanguageUtil.getEditorForInjectedLanguageNoCommit(getEditor(), getFile()); } - if (dataId.equals(DataConstants.PSI_FILE)) { + if (LangDataKeys.PSI_FILE.is(dataId)) { return myFile; } - if (dataId.equals(AnActionEvent.injectedId(DataConstants.PSI_FILE))) { + if (dataId.equals(AnActionEvent.injectedId(LangDataKeys.PSI_FILE.getName()))) { Editor editor = InjectedLanguageUtil.getEditorForInjectedLanguageNoCommit(getEditor(), getFile()); return editor instanceof EditorWindow ? ((EditorWindow)editor).getInjectedFile() : getFile(); } @@ -464,10 +461,18 @@ public abstract class LightPlatformCodeInsightTestCase extends LightPlatformTest return new DataContext() { @Nullable public Object getData(@NonNls String dataId) { - if (dataId.equals(DataConstants.EDITOR)) return getEditor(); - if (dataId.equals(DataConstants.PROJECT)) return getProject(); - if (dataId.equals(DataConstants.PSI_FILE)) return getFile(); - if (dataId.equals(DataConstants.PSI_ELEMENT)) return getFile().findElementAt(getEditor().getCaretModel().getOffset()); + if (PlatformDataKeys.EDITOR.is(dataId)) { + return getEditor(); + } + if (PlatformDataKeys.PROJECT.is(dataId)) { + return getProject(); + } + if (LangDataKeys.PSI_FILE.is(dataId)) { + return getFile(); + } + if (LangDataKeys.PSI_ELEMENT.is(dataId)) { + return getFile().findElementAt(getEditor().getCaretModel().getOffset()); + } return defaultContext.getData(dataId); } }; diff --git a/platform/testFramework/src/com/intellij/testFramework/LightPlatformTestCase.java b/platform/testFramework/src/com/intellij/testFramework/LightPlatformTestCase.java index 757081f6d7c4..de93fbf7b0d2 100644 --- a/platform/testFramework/src/com/intellij/testFramework/LightPlatformTestCase.java +++ b/platform/testFramework/src/com/intellij/testFramework/LightPlatformTestCase.java @@ -30,8 +30,8 @@ import com.intellij.ide.startup.impl.StartupManagerImpl; import com.intellij.idea.IdeaLogger; import com.intellij.idea.IdeaTestApplication; import com.intellij.lang.injection.InjectedLanguageManager; -import com.intellij.openapi.actionSystem.DataConstants; import com.intellij.openapi.actionSystem.DataProvider; +import com.intellij.openapi.actionSystem.PlatformDataKeys; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.command.impl.UndoManagerImpl; import com.intellij.openapi.command.undo.UndoManager; @@ -515,7 +515,7 @@ public abstract class LightPlatformTestCase extends UsefulTestCase implements Da } public Object getData(String dataId) { - if (dataId.equals(DataConstants.PROJECT)) { + if (PlatformDataKeys.PROJECT.is(dataId)) { return ourProject; } return null; diff --git a/platform/testFramework/src/com/intellij/testFramework/PlatformTestCase.java b/platform/testFramework/src/com/intellij/testFramework/PlatformTestCase.java index 4b18e098963a..99078b1e60b9 100644 --- a/platform/testFramework/src/com/intellij/testFramework/PlatformTestCase.java +++ b/platform/testFramework/src/com/intellij/testFramework/PlatformTestCase.java @@ -23,8 +23,8 @@ import com.intellij.ide.startup.impl.StartupManagerImpl; import com.intellij.idea.IdeaLogger; import com.intellij.idea.IdeaTestApplication; import com.intellij.openapi.Disposable; -import com.intellij.openapi.actionSystem.DataConstants; import com.intellij.openapi.actionSystem.DataProvider; +import com.intellij.openapi.actionSystem.PlatformDataKeys; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.application.ModalityState; import com.intellij.openapi.command.CommandProcessor; @@ -614,10 +614,10 @@ public abstract class PlatformTestCase extends UsefulTestCase implements DataPro } public Object getData(String dataId) { - if (dataId.equals(DataConstants.PROJECT)) { + if (PlatformDataKeys.PROJECT.is(dataId)) { return myProject; } - else if (dataId.equals(DataConstants.EDITOR)) { + else if (PlatformDataKeys.EDITOR.is(dataId)) { return FileEditorManager.getInstance(myProject).getSelectedTextEditor(); } else { diff --git a/platform/testFramework/src/com/intellij/testFramework/fixtures/impl/HeavyIdeaTestFixtureImpl.java b/platform/testFramework/src/com/intellij/testFramework/fixtures/impl/HeavyIdeaTestFixtureImpl.java index 51889a5e3a52..8208c880c3b5 100644 --- a/platform/testFramework/src/com/intellij/testFramework/fixtures/impl/HeavyIdeaTestFixtureImpl.java +++ b/platform/testFramework/src/com/intellij/testFramework/fixtures/impl/HeavyIdeaTestFixtureImpl.java @@ -20,8 +20,8 @@ import com.intellij.codeInsight.completion.CompletionProgressIndicator; import com.intellij.ide.highlighter.ProjectFileType; import com.intellij.ide.startup.impl.StartupManagerImpl; import com.intellij.idea.IdeaTestApplication; -import com.intellij.openapi.actionSystem.DataConstants; import com.intellij.openapi.actionSystem.DataProvider; +import com.intellij.openapi.actionSystem.PlatformDataKeys; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.command.WriteCommandAction; import com.intellij.openapi.editor.Editor; @@ -186,10 +186,10 @@ class HeavyIdeaTestFixtureImpl extends BaseFixture implements HeavyIdeaTestFixtu private class MyDataProvider implements DataProvider { @Nullable public Object getData(@NonNls String dataId) { - if (dataId.equals(DataConstants.PROJECT)) { + if (PlatformDataKeys.PROJECT.is(dataId)) { return myProject; } - else if (dataId.equals(DataConstants.EDITOR) || OpenFileDescriptor.NAVIGATE_IN_EDITOR.is(dataId)) { + else if (PlatformDataKeys.EDITOR.is(dataId) || OpenFileDescriptor.NAVIGATE_IN_EDITOR.is(dataId)) { return FileEditorManager.getInstance(myProject).getSelectedTextEditor(); } else { diff --git a/platform/testFramework/src/com/intellij/testFramework/fixtures/impl/LightIdeaTestFixtureImpl.java b/platform/testFramework/src/com/intellij/testFramework/fixtures/impl/LightIdeaTestFixtureImpl.java index e4bfd9df3d66..809a44a562ed 100644 --- a/platform/testFramework/src/com/intellij/testFramework/fixtures/impl/LightIdeaTestFixtureImpl.java +++ b/platform/testFramework/src/com/intellij/testFramework/fixtures/impl/LightIdeaTestFixtureImpl.java @@ -17,8 +17,8 @@ package com.intellij.testFramework.fixtures.impl; import com.intellij.codeInspection.LocalInspectionTool; -import com.intellij.openapi.actionSystem.DataConstants; import com.intellij.openapi.actionSystem.DataProvider; +import com.intellij.openapi.actionSystem.PlatformDataKeys; import com.intellij.openapi.fileEditor.FileEditorManager; import com.intellij.openapi.fileEditor.OpenFileDescriptor; import com.intellij.openapi.module.Module; @@ -52,10 +52,10 @@ class LightIdeaTestFixtureImpl extends BaseFixture implements LightIdeaTestFixtu private class MyDataProvider implements DataProvider { @Nullable public Object getData(@NonNls String dataId) { - if (dataId.equals(DataConstants.PROJECT)) { + if (PlatformDataKeys.PROJECT.is(dataId)) { return getProject(); } - else if (dataId.equals(DataConstants.EDITOR) || OpenFileDescriptor.NAVIGATE_IN_EDITOR.is(dataId)) { + else if (PlatformDataKeys.EDITOR.is(dataId) || OpenFileDescriptor.NAVIGATE_IN_EDITOR.is(dataId)) { return FileEditorManager.getInstance(getProject()).getSelectedTextEditor(); } else { diff --git a/platform/testRunner/src/com/intellij/execution/testframework/AbstractTestProxy.java b/platform/testRunner/src/com/intellij/execution/testframework/AbstractTestProxy.java index 76c7c8563b8c..442b1876c1af 100644 --- a/platform/testRunner/src/com/intellij/execution/testframework/AbstractTestProxy.java +++ b/platform/testRunner/src/com/intellij/execution/testframework/AbstractTestProxy.java @@ -21,6 +21,7 @@ package com.intellij.execution.testframework; import com.intellij.execution.Location; +import com.intellij.openapi.actionSystem.DataKey; import com.intellij.openapi.project.Project; import com.intellij.pom.Navigatable; import org.jetbrains.annotations.NonNls; @@ -28,7 +29,8 @@ import org.jetbrains.annotations.NonNls; import java.util.List; public interface AbstractTestProxy { - @NonNls String DATA_CONSTANT = "testProxy"; + DataKey DATA_KEY = DataKey.create("testProxy"); + @Deprecated @NonNls String DATA_CONSTANT = DATA_KEY.getName(); boolean isInProgress(); @@ -54,4 +56,4 @@ public interface AbstractTestProxy { List getChildren(); List getAllTests(); -} \ No newline at end of file +} diff --git a/platform/testRunner/src/com/intellij/execution/testframework/TestsUIUtil.java b/platform/testRunner/src/com/intellij/execution/testframework/TestsUIUtil.java index 5d5df2edadfc..192f45a81cff 100644 --- a/platform/testRunner/src/com/intellij/execution/testframework/TestsUIUtil.java +++ b/platform/testRunner/src/com/intellij/execution/testframework/TestsUIUtil.java @@ -17,8 +17,9 @@ package com.intellij.execution.testframework; import com.intellij.execution.ExecutionBundle; import com.intellij.execution.Location; -import com.intellij.openapi.actionSystem.DataConstants; -import com.intellij.openapi.actionSystem.ex.DataConstantsEx; +import com.intellij.execution.configurations.RuntimeConfiguration; +import com.intellij.openapi.actionSystem.LangDataKeys; +import com.intellij.openapi.actionSystem.PlatformDataKeys; import com.intellij.openapi.application.Application; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.diagnostic.Logger; @@ -40,22 +41,25 @@ import java.awt.*; import java.awt.image.BufferedImage; public class TestsUIUtil { + @NonNls private static final String ICONS_ROOT = "/runConfigurations/"; + public static final Color PASSED_COLOR = new Color(0, 128, 0); private static final Logger LOG = Logger.getInstance("#com.intellij.execution.testframework.TestsUIUtil"); - @NonNls private static final String ICONS_ROOT = "/runConfigurations/"; + private TestsUIUtil() { + } @Nullable public static Object getData(final AbstractTestProxy testProxy, final String dataId, final TestFrameworkRunningModel model) { final Project project = model.getProperties().getProject(); if (testProxy == null) return null; - if (AbstractTestProxy.DATA_CONSTANT.equals(dataId)) return testProxy; - if (DataConstants.NAVIGATABLE.equals(dataId)) return getOpenFileDescriptor(testProxy, model); - if (DataConstants.NAVIGATABLE_ARRAY.equals(dataId)) { + if (AbstractTestProxy.DATA_KEY.is(dataId)) return testProxy; + if (PlatformDataKeys.NAVIGATABLE.is(dataId)) return getOpenFileDescriptor(testProxy, model); + if (PlatformDataKeys.NAVIGATABLE_ARRAY.is(dataId)) { final Navigatable openFileDescriptor = getOpenFileDescriptor(testProxy, model); return openFileDescriptor != null ? new Navigatable[]{openFileDescriptor} : null; } - if (DataConstants.PSI_ELEMENT.equals(dataId)) { + if (LangDataKeys.PSI_ELEMENT.is(dataId)) { final Location location = testProxy.getLocation(project); if (location != null) { final PsiElement element = location.getPsiElement(); @@ -65,15 +69,16 @@ public class TestsUIUtil { return null; } } - if (Location.LOCATION.equals(dataId)) return testProxy.getLocation(project); - if (DataConstantsEx.RUNTIME_CONFIGURATION.equals(dataId)) return model.getProperties().getConfiguration(); + if (Location.DATA_KEY.is(dataId)) return testProxy.getLocation(project); + if (RuntimeConfiguration.DATA_KEY.is(dataId)) return model.getProperties().getConfiguration(); return null; } public static Navigatable getOpenFileDescriptor(final AbstractTestProxy testProxy, final TestFrameworkRunningModel model) { - return getOpenFileDescriptor(testProxy, model.getProperties().getProject(), TestConsoleProperties.OPEN_FAILURE_LINE.value(model.getProperties())); + return getOpenFileDescriptor(testProxy, model.getProperties().getProject(), + TestConsoleProperties.OPEN_FAILURE_LINE.value(model.getProperties())); } - + private static Navigatable getOpenFileDescriptor(final AbstractTestProxy proxy, final Project project, final boolean openFailureLine) { if (proxy != null) { final Location location = proxy.getLocation(project); @@ -91,10 +96,9 @@ public class TestsUIUtil { public static Icon loadIcon(@NonNls final String iconName) { final Application application = ApplicationManager.getApplication(); if (application == null || application.isUnitTestMode()) return new ImageIcon(new BufferedImage(1, 1, BufferedImage.TYPE_3BYTE_BGR)); - @NonNls final String fullIconName = ICONS_ROOT + iconName +".png"; - final Icon icon = IconLoader.getIcon(fullIconName); - LOG.assertTrue(icon != null, fullIconName); - return icon; + @NonNls final String fullIconName = ICONS_ROOT + iconName + ".png"; + + return IconLoader.getIcon(fullIconName); } public static void notifyByBalloon(@NotNull final Project project, final AbstractTestProxy root, final TestConsoleProperties properties, diff --git a/platform/usageView/src/com/intellij/usages/UsageTargetUtil.java b/platform/usageView/src/com/intellij/usages/UsageTargetUtil.java index d16330c20aa3..9f090acc4533 100644 --- a/platform/usageView/src/com/intellij/usages/UsageTargetUtil.java +++ b/platform/usageView/src/com/intellij/usages/UsageTargetUtil.java @@ -15,8 +15,9 @@ */ package com.intellij.usages; -import com.intellij.openapi.actionSystem.DataConstants; import com.intellij.openapi.actionSystem.DataProvider; +import com.intellij.openapi.actionSystem.LangDataKeys; +import com.intellij.openapi.actionSystem.PlatformDataKeys; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.extensions.ExtensionPointName; import com.intellij.openapi.extensions.Extensions; @@ -32,18 +33,18 @@ public class UsageTargetUtil { public void foo() {} public static UsageTarget[] findUsageTargets(DataProvider dataProvider) { - Editor editor = (Editor)dataProvider.getData(DataConstants.EDITOR); - PsiFile file = (PsiFile)dataProvider.getData(DataConstants.PSI_FILE); + Editor editor = PlatformDataKeys.EDITOR.getData(dataProvider); + PsiFile file = LangDataKeys.PSI_FILE.getData(dataProvider); List result = new ArrayList(); if (file != null && editor != null) { UsageTarget[] targets = findUsageTargets(editor, file); - if (targets != null ) Collections.addAll(result, targets); + if (targets != null) Collections.addAll(result, targets); } - PsiElement psiElement = (PsiElement)dataProvider.getData(DataConstants.PSI_ELEMENT); + PsiElement psiElement = LangDataKeys.PSI_ELEMENT.getData(dataProvider); if (psiElement != null) { UsageTarget[] targets = findUsageTargets(psiElement); - if (targets != null )Collections.addAll(result, targets); + if (targets != null)Collections.addAll(result, targets); } return result.isEmpty() ? null : result.toArray(new UsageTarget[result.size()]); diff --git a/platform/usageView/src/com/intellij/usages/UsageView.java b/platform/usageView/src/com/intellij/usages/UsageView.java index ff254a75dfc3..c673859b63d3 100644 --- a/platform/usageView/src/com/intellij/usages/UsageView.java +++ b/platform/usageView/src/com/intellij/usages/UsageView.java @@ -18,7 +18,6 @@ package com.intellij.usages; import com.intellij.openapi.Disposable; import com.intellij.openapi.actionSystem.DataKey; import com.intellij.usageView.UsageInfo; -import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -33,18 +32,20 @@ public interface UsageView extends Disposable { /** * Returns {@link com.intellij.usages.UsageTarget} to look usages for */ - @NonNls String USAGE_TARGETS = "usageTarget"; - DataKey USAGE_TARGETS_KEY = DataKey.create(USAGE_TARGETS); + DataKey USAGE_TARGETS_KEY = DataKey.create("usageTarget"); + @Deprecated String USAGE_TARGETS = USAGE_TARGETS_KEY.getName(); /** * Returns {@link com.intellij.usages.Usage} which are selected in usage view */ - @NonNls String USAGES = "usages"; - DataKey USAGES_KEY = DataKey.create(USAGES); + DataKey USAGES_KEY = DataKey.create("usages"); + @Deprecated String USAGES = USAGES_KEY.getName(); + + DataKey USAGE_VIEW_KEY = DataKey.create("UsageView.new"); + @Deprecated String USAGE_VIEW = USAGE_VIEW_KEY.getName(); - @NonNls String USAGE_VIEW = "UsageView.new"; - DataKey USAGE_VIEW_KEY = DataKey.create(USAGE_VIEW); DataKey USAGE_INFO_KEY = DataKey.create("UsageInfo"); + DataKey> USAGE_INFO_LIST_KEY = DataKey.create("UsageInfo.List"); void appendUsage(@NotNull Usage usage); diff --git a/platform/usageView/src/com/intellij/usages/impl/UsageViewImpl.java b/platform/usageView/src/com/intellij/usages/impl/UsageViewImpl.java index ebc911ba5f30..72989c1e965c 100644 --- a/platform/usageView/src/com/intellij/usages/impl/UsageViewImpl.java +++ b/platform/usageView/src/com/intellij/usages/impl/UsageViewImpl.java @@ -1315,7 +1315,7 @@ public class UsageViewImpl implements UsageView, UsageModelTracker.UsageModelTra } private List getSelectedUsageInfos() { - return (List)DataManager.getInstance().getDataContext(myRootPanel).getData(USAGE_INFO_LIST_KEY.getName()); + return USAGE_INFO_LIST_KEY.getData(DataManager.getInstance().getDataContext(myRootPanel)); } public GroupNode getRoot() { diff --git a/platform/vcs-api/src/com/intellij/openapi/vcs/CheckinProjectPanel.java b/platform/vcs-api/src/com/intellij/openapi/vcs/CheckinProjectPanel.java index 30af748e8ad3..deb1dfdb0eea 100644 --- a/platform/vcs-api/src/com/intellij/openapi/vcs/CheckinProjectPanel.java +++ b/platform/vcs-api/src/com/intellij/openapi/vcs/CheckinProjectPanel.java @@ -28,8 +28,7 @@ import java.util.List; /** * Interface for working with the checkin dialog user interface (retrieving the files * included in the checkin operation, getting/setting the commit message and so on). - * The active check-in dialog can be retrieved from the - * {@link com.intellij.openapi.actionSystem.DataContext} using the {@link Refreshable#PANEL} data ID. + * The active check-in dialog can be retrieved from the using {@link Refreshable#PANEL_KEY} * * @see com.intellij.openapi.vcs.checkin.CheckinHandlerFactory#createHandler(CheckinProjectPanel) */ diff --git a/platform/vcs-api/src/com/intellij/openapi/vcs/VcsDataConstants.java b/platform/vcs-api/src/com/intellij/openapi/vcs/VcsDataConstants.java index 02b56e918aff..7de8abf6fe14 100644 --- a/platform/vcs-api/src/com/intellij/openapi/vcs/VcsDataConstants.java +++ b/platform/vcs-api/src/com/intellij/openapi/vcs/VcsDataConstants.java @@ -15,15 +15,17 @@ */ package com.intellij.openapi.vcs; -@SuppressWarnings({"HardCodedStringLiteral"}) -@Deprecated +/** + * @deprecated use {@link com.intellij.openapi.vcs.VcsDataKeys} instead + */ +@SuppressWarnings({"UnusedDeclaration"}) public interface VcsDataConstants { - String IO_FILE_ARRAY = "IO_FILE_ARRAY"; - String IO_FILE = "IO_FILE"; - String VCS_FILE_REVISION = "VCS_FILE_REVISION"; - String VCS_FILE_REVISIONS = "VCS_FILE_REVISIONS"; - String VCS_VIRTUAL_FILE = "VCS_VIRTUAL_FILE"; - String FILE_PATH = "FILE_PATH"; - String FILE_PATH_ARRAY = "FILE_PATH_ARRAY"; - String FILE_HISTORY_PANEL = "FILE_HISTORY_PANEL"; + String IO_FILE_ARRAY = VcsDataKeys.IO_FILE_ARRAY.getName(); + String IO_FILE = VcsDataKeys.IO_FILE.getName(); + String VCS_FILE_REVISION = VcsDataKeys.VCS_FILE_REVISION.getName(); + String VCS_FILE_REVISIONS = VcsDataKeys.VCS_FILE_REVISIONS.getName(); + String VCS_VIRTUAL_FILE = VcsDataKeys.VCS_VIRTUAL_FILE.getName(); + String FILE_PATH = VcsDataKeys.FILE_PATH.getName(); + String FILE_PATH_ARRAY = VcsDataKeys.FILE_PATH_ARRAY.getName(); + String FILE_HISTORY_PANEL = VcsDataKeys.FILE_HISTORY_PANEL.getName(); } diff --git a/platform/vcs-api/src/com/intellij/openapi/vcs/VcsDataKeys.java b/platform/vcs-api/src/com/intellij/openapi/vcs/VcsDataKeys.java index 910a5453c5e0..8b797ec4f3f4 100644 --- a/platform/vcs-api/src/com/intellij/openapi/vcs/VcsDataKeys.java +++ b/platform/vcs-api/src/com/intellij/openapi/vcs/VcsDataKeys.java @@ -14,15 +14,8 @@ * limitations under the License. */ -/* - * Created by IntelliJ IDEA. - * User: yole - * Date: 23.10.2006 - * Time: 18:13:58 - */ package com.intellij.openapi.vcs; -import com.intellij.openapi.actionSystem.DataConstants; import com.intellij.openapi.actionSystem.DataKey; import com.intellij.openapi.vcs.changes.Change; import com.intellij.openapi.vcs.changes.ChangeList; @@ -35,16 +28,20 @@ import org.jetbrains.annotations.NonNls; import java.io.File; import java.util.List; +/** + * @author yole + */ public interface VcsDataKeys { - DataKey IO_FILE_ARRAY = DataKey.create(VcsDataConstants.IO_FILE_ARRAY); - DataKey IO_FILE = DataKey.create(VcsDataConstants.IO_FILE); - DataKey VCS_FILE_REVISION = DataKey.create(VcsDataConstants.VCS_FILE_REVISION); - DataKey VCS_FILE_REVISIONS = DataKey.create(VcsDataConstants.VCS_FILE_REVISIONS); - DataKey VCS_VIRTUAL_FILE = DataKey.create(VcsDataConstants.VCS_VIRTUAL_FILE); - DataKey FILE_PATH = DataKey.create(VcsDataConstants.FILE_PATH); - DataKey FILE_PATH_ARRAY = DataKey.create(VcsDataConstants.FILE_PATH_ARRAY); - DataKey CHANGE_LISTS = DataKey.create(DataConstants.CHANGE_LISTS); - DataKey CHANGES = DataKey.create(DataConstants.CHANGES); + DataKey IO_FILE_ARRAY = DataKey.create("IO_FILE_ARRAY"); + DataKey IO_FILE = DataKey.create("IO_FILE"); + DataKey VCS_FILE_REVISION = DataKey.create("VCS_FILE_REVISION"); + DataKey VCS_FILE_REVISIONS = DataKey.create("VCS_FILE_REVISIONS"); + DataKey VCS_VIRTUAL_FILE = DataKey.create("VCS_VIRTUAL_FILE"); + DataKey FILE_PATH = DataKey.create("FILE_PATH"); + DataKey FILE_PATH_ARRAY = DataKey.create("FILE_PATH_ARRAY"); + DataKey FILE_HISTORY_PANEL = DataKey.create("FILE_HISTORY_PANEL"); + DataKey CHANGE_LISTS = DataKey.create("vcs.ChangeList"); + DataKey CHANGES = DataKey.create("vcs.Change"); DataKey CHANGES_WITH_MOVED_CHILDREN = DataKey.create("ChangeListView.ChangesWithDetails"); DataKey SELECTED_CHANGES_IN_DETAILS = DataKey.create("ChangeListView.SelectedChangesWithMovedSubtrees"); @NonNls DataKey> CHANGES_IN_LIST_KEY = DataKey.create("ChangeListView.ChangesInList"); @@ -56,4 +53,4 @@ public interface VcsDataKeys { DataKey> UPDATE_VIEW_FILES_ITERABLE = DataKey.create("AbstractCommonUpdateAction.UpdatedFilesIterable"); DataKey LABEL_BEFORE = DataKey.create("LABEL_BEFORE"); DataKey LABEL_AFTER = DataKey.create("LABEL_AFTER"); -} \ No newline at end of file +} diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/actions/VcsContextWrapper.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/actions/VcsContextWrapper.java index 020912ae33af..663c8601db08 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/actions/VcsContextWrapper.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/actions/VcsContextWrapper.java @@ -22,7 +22,6 @@ import com.intellij.openapi.editor.Editor; import com.intellij.openapi.project.Project; import com.intellij.openapi.vcs.FilePath; import com.intellij.openapi.vcs.FilePathImpl; -import com.intellij.openapi.vcs.VcsDataConstants; import com.intellij.openapi.vcs.VcsDataKeys; import com.intellij.openapi.vcs.changes.Change; import com.intellij.openapi.vcs.changes.ChangeList; @@ -104,16 +103,16 @@ public class VcsContextWrapper implements VcsContext { } public File getSelectedIOFile() { - File file = (File)myContext.getData(VcsDataConstants.IO_FILE); + File file = VcsDataKeys.IO_FILE.getData(myContext); if (file != null) return file; - File[] files = (File[])myContext.getData(VcsDataConstants.IO_FILE_ARRAY); + File[] files = VcsDataKeys.IO_FILE_ARRAY.getData(myContext); if (files == null) return null; if (files.length == 0) return null; return files[0]; } public File[] getSelectedIOFiles() { - File[] files = (File[])myContext.getData(VcsDataConstants.IO_FILE_ARRAY); + File[] files = VcsDataKeys.IO_FILE_ARRAY.getData(myContext); if (files != null && files.length > 0) return files; File file = getSelectedIOFile(); if (file != null) return new File[]{file}; @@ -125,11 +124,7 @@ public class VcsContextWrapper implements VcsContext { } public Refreshable getRefreshableDialog() { - final Object dataFromContext = myContext.getData(Refreshable.PANEL); - if (dataFromContext != null) { - return ((Refreshable)dataFromContext); - } - return null; + return Refreshable.PANEL_KEY.getData(myContext); } public FilePath[] getSelectedFilePaths() { diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/actions/OpenRepositoryVersionAction.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/actions/OpenRepositoryVersionAction.java index 8a9496602961..16369891a044 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/actions/OpenRepositoryVersionAction.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/actions/OpenRepositoryVersionAction.java @@ -59,7 +59,7 @@ public class OpenRepositoryVersionAction extends AnAction implements DumbAware { Project project = e.getData(PlatformDataKeys.PROJECT); Change[] changes = e.getData(VcsDataKeys.SELECTED_CHANGES); e.getPresentation().setEnabled(project != null && changes != null && - (! CommittedChangesBrowserUseCase.IN_AIR.equals(e.getDataContext().getData(CommittedChangesBrowserUseCase.CONTEXT_NAME))) && + (! CommittedChangesBrowserUseCase.IN_AIR.equals(CommittedChangesBrowserUseCase.DATA_KEY.getData(e.getDataContext()))) && hasValidChanges(changes) && ModalityState.NON_MODAL.equals(ModalityState.current())); } @@ -73,4 +73,4 @@ public class OpenRepositoryVersionAction extends AnAction implements DumbAware { } return false; } -} \ No newline at end of file +} diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/actions/ShowDiffWithLocalAction.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/actions/ShowDiffWithLocalAction.java index 6575dde997a5..5bb75761ba01 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/actions/ShowDiffWithLocalAction.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/actions/ShowDiffWithLocalAction.java @@ -48,7 +48,7 @@ public class ShowDiffWithLocalAction extends AnAction implements DumbAware { List changesToLocal = new ArrayList(); for(Change change: changes) { ContentRevision afterRevision = change.getAfterRevision(); - if (isValidAfterRevision(afterRevision)) { + if (afterRevision != null && isValidAfterRevision(afterRevision)) { changesToLocal.add(new Change(afterRevision, CurrentContentRevision.create(afterRevision.getFile()))); } } @@ -63,7 +63,7 @@ public class ShowDiffWithLocalAction extends AnAction implements DumbAware { Change[] changes = e.getData(VcsDataKeys.CHANGES); e.getPresentation().setEnabled(project != null && changes != null && - (! CommittedChangesBrowserUseCase.IN_AIR.equals(e.getDataContext().getData(CommittedChangesBrowserUseCase.CONTEXT_NAME))) && + (! CommittedChangesBrowserUseCase.IN_AIR.equals(CommittedChangesBrowserUseCase.DATA_KEY.getData(e.getDataContext()))) && anyHasAfterRevision(changes)); } @@ -79,4 +79,4 @@ public class ShowDiffWithLocalAction extends AnAction implements DumbAware { } return false; } -} \ No newline at end of file +} diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/committed/CommittedChangesBrowserUseCase.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/committed/CommittedChangesBrowserUseCase.java index ee27c3e429f0..cc21746cd4a2 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/committed/CommittedChangesBrowserUseCase.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/committed/CommittedChangesBrowserUseCase.java @@ -15,11 +15,14 @@ */ package com.intellij.openapi.vcs.changes.committed; +import com.intellij.openapi.actionSystem.DataKey; + public enum CommittedChangesBrowserUseCase { COMMITTED, INCOMING, UPDATE, IN_AIR; - public final static String CONTEXT_NAME = "COMMITTED_CHANGES_BROWSER_USE_CASE"; + public static final DataKey DATA_KEY = DataKey.create("COMMITTED_CHANGES_BROWSER_USE_CASE"); + @Deprecated public final static String CONTEXT_NAME = DATA_KEY.getName(); } diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/committed/RepositoryChangesBrowser.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/committed/RepositoryChangesBrowser.java index dc2b0cff74a4..00fe4b0da655 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/committed/RepositoryChangesBrowser.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/committed/RepositoryChangesBrowser.java @@ -78,7 +78,7 @@ public class RepositoryChangesBrowser extends ChangesBrowser implements DataProv } public Object getData(@NonNls final String dataId) { - if (CommittedChangesBrowserUseCase.CONTEXT_NAME.equals(dataId)) { + if (CommittedChangesBrowserUseCase.DATA_KEY.is(dataId)) { return myUseCase; } @@ -106,13 +106,13 @@ public class RepositoryChangesBrowser extends ChangesBrowser implements DataProv event.getPresentation().setIcon(myEditSourceIcon); event.getPresentation().setText("Edit Source"); if ((! ModalityState.NON_MODAL.equals(ModalityState.current())) || - CommittedChangesBrowserUseCase.IN_AIR.equals(event.getDataContext().getData(CommittedChangesBrowserUseCase.CONTEXT_NAME))) { + CommittedChangesBrowserUseCase.IN_AIR.equals(CommittedChangesBrowserUseCase.DATA_KEY.getData(event.getDataContext()))) { event.getPresentation().setEnabled(false); } } protected Navigatable[] getNavigatables(final DataContext dataContext) { - Change[] changes = (Change[])dataContext.getData(VcsDataKeys.SELECTED_CHANGES.getName()); + Change[] changes = VcsDataKeys.SELECTED_CHANGES.getData(dataContext); if (changes != null) { Collection changeCollection = Arrays.asList(changes); return ChangesUtil.getNavigatableArray(myProject, ChangesUtil.getFilesFromChanges(changeCollection)); diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/shelf/ShelvedChangesViewManager.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/shelf/ShelvedChangesViewManager.java index d4b9d75b46c8..cb1d6a80f8e6 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/shelf/ShelvedChangesViewManager.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/shelf/ShelvedChangesViewManager.java @@ -48,9 +48,9 @@ import com.intellij.openapi.wm.ToolWindowManager; import com.intellij.ui.ColoredTreeCellRenderer; import com.intellij.ui.PopupHandler; import com.intellij.ui.SimpleTextAttributes; -import com.intellij.ui.treeStructure.Tree; import com.intellij.ui.content.Content; import com.intellij.ui.content.ContentFactory; +import com.intellij.ui.treeStructure.Tree; import com.intellij.util.messages.MessageBus; import com.intellij.util.ui.tree.TreeUtil; import org.jetbrains.annotations.NonNls; @@ -329,7 +329,7 @@ public class ShelvedChangesViewManager implements ProjectComponent { return path1.compareToIgnoreCase(path2); } - private String getPath(final Object patch) { + private static String getPath(final Object patch) { String path = null; if (patch instanceof ShelvedBinaryFile) { final ShelvedBinaryFile binaryFile = (ShelvedBinaryFile) patch; @@ -433,8 +433,8 @@ public class ShelvedChangesViewManager implements ProjectComponent { } private List getLists(final DataContext dataContext) { - final ShelvedChangeList[] shelved = (ShelvedChangeList[])dataContext.getData(SHELVED_CHANGELIST_KEY.getName()); - final ShelvedChangeList[] recycled = (ShelvedChangeList[])dataContext.getData(SHELVED_RECYCLED_CHANGELIST_KEY.getName()); + final ShelvedChangeList[] shelved = SHELVED_CHANGELIST_KEY.getData(dataContext); + final ShelvedChangeList[] recycled = SHELVED_RECYCLED_CHANGELIST_KEY.getData(dataContext); final List shelvedChangeLists = (shelved == null && recycled == null) ? Collections.emptyList() : new ArrayList(); @@ -450,7 +450,7 @@ public class ShelvedChangesViewManager implements ProjectComponent { private class MyChangesDeleteProvider implements DeleteProvider { public void deleteElement(DataContext dataContext) { - final ShelvedChangeList[] shelved = (ShelvedChangeList[])dataContext.getData(SHELVED_CHANGELIST_KEY.getName()); + final ShelvedChangeList[] shelved = SHELVED_CHANGELIST_KEY.getData(dataContext); if (shelved == null || (shelved.length != 1)) return; final List changes = SHELVED_CHANGE_KEY.getData(dataContext); final List binaryFiles = SHELVED_BINARY_FILE_KEY.getData(dataContext); @@ -475,9 +475,11 @@ public class ShelvedChangesViewManager implements ProjectComponent { patches.add(change.loadFilePatch()); } catch (IOException e) { + //noinspection ThrowableInstanceNeverThrown exceptions.add(new VcsException(e)); } catch (PatchSyntaxException e) { + //noinspection ThrowableInstanceNeverThrown exceptions.add(new VcsException(e)); } } @@ -492,7 +494,7 @@ public class ShelvedChangesViewManager implements ProjectComponent { } public boolean canDeleteElement(DataContext dataContext) { - final ShelvedChangeList[] shelved = (ShelvedChangeList[])dataContext.getData(SHELVED_CHANGELIST_KEY.getName()); + final ShelvedChangeList[] shelved = SHELVED_CHANGELIST_KEY.getData(dataContext); if (shelved == null || (shelved.length != 1)) return false; final List changes = SHELVED_CHANGE_KEY.getData(dataContext); if (changes != null && (! changes.isEmpty())) return true; diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/history/FileHistoryPanelImpl.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/history/FileHistoryPanelImpl.java index 35fe17fa2f14..89801783d782 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/history/FileHistoryPanelImpl.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/history/FileHistoryPanelImpl.java @@ -1084,7 +1084,7 @@ public class FileHistoryPanelImpl strokes = new ArrayList(); - for (int i = 0; i < shortcuts.length; i++) { - final Shortcut shortcut = shortcuts[i]; + final List strokes = new ArrayList(); + for (final Shortcut shortcut : shortcuts) { if (shortcut instanceof KeyboardShortcut) { strokes.add(((KeyboardShortcut)shortcut).getFirstKeyStroke()); } @@ -470,13 +468,13 @@ public class Commander extends JPanel implements PersistentStateComponent fileNames = getFilesToRemove(context); if (fileNames.isEmpty()) return false; - for (Iterator iterator = fileNames.iterator(); iterator.hasNext();) { - File file = iterator.next(); + for (File file : fileNames) { if (file.isDirectory()) return false; if (file.isFile()) return false; if (!CvsUtil.fileIsUnderCvs(file)) return false; @@ -82,9 +81,7 @@ public class RemoveLocallyDeletedFilesAction extends RemoveLocallyFileOrDirector File[] files = context.getSelectedIOFiles(); ArrayList result = new ArrayList(); if (files == null) return result; - for (int i = 0; i < files.length; i++) { - result.add(files[i]); - } + result.addAll(Arrays.asList(files)); return result; } @@ -93,7 +90,7 @@ public class RemoveLocallyDeletedFilesAction extends RemoveLocallyFileOrDirector e.getPresentation().setVisible(false); return; } - if (e.getDataContext().getData(Refreshable.PANEL) == null) { + if (Refreshable.PANEL_KEY.getData(e.getDataContext()) == null) { Presentation presentation = e.getPresentation(); presentation.setEnabled(false); presentation.setVisible(false); diff --git a/plugins/cvs/cvs-plugin/src/com/intellij/cvsSupport2/actions/cvsContext/CvsContextWrapper.java b/plugins/cvs/cvs-plugin/src/com/intellij/cvsSupport2/actions/cvsContext/CvsContextWrapper.java index 9afa82ebee6d..37518f055a2c 100644 --- a/plugins/cvs/cvs-plugin/src/com/intellij/cvsSupport2/actions/cvsContext/CvsContextWrapper.java +++ b/plugins/cvs/cvs-plugin/src/com/intellij/cvsSupport2/actions/cvsContext/CvsContextWrapper.java @@ -65,11 +65,11 @@ public class CvsContextWrapper implements CvsContext { public Collection getDeletedFileNames() { - return (Collection)myContext.getData(CvsDataConstants.DELETED_FILE_NAMES); + return CvsDataKeys.DELETED_FILE_NAMES.getData(myContext); } public String getFileToRestore() { - return (String)myContext.getData(CvsDataConstants.FILE_TO_RESTORE); + return CvsDataKeys.FILE_TO_RESTORE.getData(myContext); } public File getSomeSelectedFile() { @@ -88,11 +88,11 @@ public class CvsContextWrapper implements CvsContext { } public CvsLightweightFile getCvsLightweightFile() { - return (CvsLightweightFile)myContext.getData(CvsDataConstants.CVS_LIGHT_FILE); + return CvsDataKeys.CVS_LIGHT_FILE.getData(myContext); } public CvsLightweightFile[] getSelectedLightweightFiles() { - CvsLightweightFile[] files = (CvsLightweightFile[])myContext.getData(CvsDataConstants.CVS_LIGHT_FILES); + CvsLightweightFile[] files = CvsDataKeys.CVS_LIGHT_FILES.getData(myContext); if (files != null && files.length > 0) return files; CvsLightweightFile file = getCvsLightweightFile(); if (file != null) { @@ -104,11 +104,11 @@ public class CvsContextWrapper implements CvsContext { } public CvsEnvironment getEnvironment() { - return (CvsEnvironment)myContext.getData(CvsDataConstants.CVS_ENVIRONMENT); + return CvsDataKeys.CVS_ENVIRONMENT.getData(myContext); } public Collection getAllFilesToAdd() { - return (Collection)myContext.getData(CvsDataConstants.FILES_TO_ADD); + return CvsDataKeys.FILES_TO_ADD.getData(myContext); } public Project getProject() { diff --git a/plugins/cvs/cvs-plugin/src/com/intellij/cvsSupport2/actions/cvsContext/CvsDataConstants.java b/plugins/cvs/cvs-plugin/src/com/intellij/cvsSupport2/actions/cvsContext/CvsDataConstants.java index 94368a53f6b8..7905d349566a 100644 --- a/plugins/cvs/cvs-plugin/src/com/intellij/cvsSupport2/actions/cvsContext/CvsDataConstants.java +++ b/plugins/cvs/cvs-plugin/src/com/intellij/cvsSupport2/actions/cvsContext/CvsDataConstants.java @@ -17,13 +17,15 @@ package com.intellij.cvsSupport2.actions.cvsContext; /** * author: lesya + * + * @deprecated use {@link com.intellij.cvsSupport2.actions.cvsContext.CvsDataKeys} instead */ -@SuppressWarnings({"ALL"}) +@SuppressWarnings({"UnusedDeclaration"}) public interface CvsDataConstants { - String DELETED_FILE_NAMES = "DeletedFileNames"; - String FILE_TO_RESTORE = "FileToRestore"; - String CVS_LIGHT_FILE = "CVS_LIGHT_FILE"; - String CVS_LIGHT_FILES = "CVS_LIGHT_FILES"; - String CVS_ENVIRONMENT = "CVS_ENVIRONMENT"; - String FILES_TO_ADD = "FilesToAdd"; + String DELETED_FILE_NAMES = CvsDataKeys.DELETED_FILE_NAMES.getName(); + String FILE_TO_RESTORE = CvsDataKeys.FILE_TO_RESTORE.getName(); + String CVS_LIGHT_FILE = CvsDataKeys.CVS_LIGHT_FILE.getName(); + String CVS_LIGHT_FILES = CvsDataKeys.CVS_LIGHT_FILES.getName(); + String CVS_ENVIRONMENT = CvsDataKeys.CVS_ENVIRONMENT.getName(); + String FILES_TO_ADD = CvsDataKeys.FILES_TO_ADD.getName(); } diff --git a/plugins/cvs/cvs-plugin/src/com/intellij/cvsSupport2/actions/cvsContext/CvsDataKeys.java b/plugins/cvs/cvs-plugin/src/com/intellij/cvsSupport2/actions/cvsContext/CvsDataKeys.java new file mode 100644 index 000000000000..4922c381013d --- /dev/null +++ b/plugins/cvs/cvs-plugin/src/com/intellij/cvsSupport2/actions/cvsContext/CvsDataKeys.java @@ -0,0 +1,31 @@ +/* + * Copyright 2000-2009 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 com.intellij.cvsSupport2.actions.cvsContext; + +import com.intellij.cvsSupport2.connections.CvsEnvironment; +import com.intellij.cvsSupport2.cvsoperations.cvsAdd.AddedFileInfo; +import com.intellij.openapi.actionSystem.DataKey; + +import java.util.Collection; + +public interface CvsDataKeys { + DataKey> DELETED_FILE_NAMES = DataKey.create("DeletedFileNames"); + DataKey FILE_TO_RESTORE = DataKey.create("FileToRestore"); + DataKey CVS_LIGHT_FILE = DataKey.create("CVS_LIGHT_FILE"); + DataKey CVS_LIGHT_FILES = DataKey.create("CVS_LIGHT_FILES"); + DataKey CVS_ENVIRONMENT = DataKey.create("CVS_ENVIRONMENT"); + DataKey> FILES_TO_ADD = DataKey.create("FilesToAdd"); +} diff --git a/plugins/cvs/cvs-plugin/src/com/intellij/cvsSupport2/config/ui/CvsConfigurationsListEditor.java b/plugins/cvs/cvs-plugin/src/com/intellij/cvsSupport2/config/ui/CvsConfigurationsListEditor.java index f27c5ac30f67..474997bca6ed 100644 --- a/plugins/cvs/cvs-plugin/src/com/intellij/cvsSupport2/config/ui/CvsConfigurationsListEditor.java +++ b/plugins/cvs/cvs-plugin/src/com/intellij/cvsSupport2/config/ui/CvsConfigurationsListEditor.java @@ -38,7 +38,6 @@ import java.awt.event.ActionEvent; import java.awt.event.KeyEvent; import java.util.ArrayList; import java.util.Enumeration; -import java.util.Iterator; import java.util.List; /** @@ -120,9 +119,8 @@ public class CvsConfigurationsListEditor extends DialogWrapper implements DataPr private void fillModel(List configurations) { - for (Iterator each = configurations.iterator(); each.hasNext();) { - CvsRootConfiguration obj = (CvsRootConfiguration)each.next(); - myModel.addElement(obj.getMyCopy()); + for (final CvsRootConfiguration configuration : configurations) { + myModel.addElement(configuration.getMyCopy()); } } @@ -311,7 +309,7 @@ public class CvsConfigurationsListEditor extends DialogWrapper implements DataPr @NonNls public Object getData(String dataId) { - if (DataConstants.HELP_ID.equals(dataId)){ + if (PlatformDataKeys.HELP_ID.is(dataId)){ return "reference.versionControl.cvs.options"; } return null; diff --git a/plugins/cvs/cvs-plugin/src/com/intellij/cvsSupport2/cvsBrowser/ui/BrowserPanel.java b/plugins/cvs/cvs-plugin/src/com/intellij/cvsSupport2/cvsBrowser/ui/BrowserPanel.java index 2c962a921a9d..274c8c8173d2 100644 --- a/plugins/cvs/cvs-plugin/src/com/intellij/cvsSupport2/cvsBrowser/ui/BrowserPanel.java +++ b/plugins/cvs/cvs-plugin/src/com/intellij/cvsSupport2/cvsBrowser/ui/BrowserPanel.java @@ -18,7 +18,7 @@ package com.intellij.cvsSupport2.cvsBrowser.ui; import com.intellij.CvsBundle; import com.intellij.cvsSupport2.CvsVcs2; import com.intellij.cvsSupport2.actions.cvsContext.CvsContextAdapter; -import com.intellij.cvsSupport2.actions.cvsContext.CvsDataConstants; +import com.intellij.cvsSupport2.actions.cvsContext.CvsDataKeys; import com.intellij.cvsSupport2.actions.cvsContext.CvsLightweightFile; import com.intellij.cvsSupport2.changeBrowser.CvsRepositoryLocation; import com.intellij.cvsSupport2.checkout.CheckoutAction; @@ -37,8 +37,8 @@ import com.intellij.openapi.project.Project; import com.intellij.openapi.util.IconLoader; import com.intellij.openapi.vcs.AbstractVcsHelper; import com.intellij.openapi.vcs.VcsBundle; -import com.intellij.openapi.vcs.VcsException; import com.intellij.openapi.vcs.VcsConfiguration; +import com.intellij.openapi.vcs.VcsException; import com.intellij.openapi.vcs.annotate.FileAnnotation; import com.intellij.openapi.vcs.vfs.VcsVirtualFile; import com.intellij.openapi.vfs.VirtualFile; @@ -94,7 +94,7 @@ public class BrowserPanel extends JPanel implements DataProvider, CvsTabbedWindo return result; } - private class EditSourceAction extends AnAction { + private static class EditSourceAction extends AnAction { public EditSourceAction() { super(ActionsBundle.actionText("EditSource"), ActionsBundle.actionDescription("EditSource"), @@ -205,18 +205,18 @@ public class BrowserPanel extends JPanel implements DataProvider, CvsTabbedWindo } public Object getData(String dataId) { - if (DataConstants.NAVIGATABLE.equals(dataId)) { + if (PlatformDataKeys.NAVIGATABLE.is(dataId)) { VirtualFile cvsVirtualFile = getCvsVirtualFile(); if (cvsVirtualFile == null || !cvsVirtualFile.isValid()) return null; return new OpenFileDescriptor(myProject, cvsVirtualFile); } - else if (DataConstants.PROJECT.equals(dataId)) { + else if (PlatformDataKeys.PROJECT.is(dataId)) { return myProject; } - else if (CvsDataConstants.CVS_ENVIRONMENT.equals(dataId)) { + else if (CvsDataKeys.CVS_ENVIRONMENT.is(dataId)) { return myCvsRootConfiguration; } - else if (CvsDataConstants.CVS_LIGHT_FILE.equals(dataId)) { + else if (CvsDataKeys.CVS_LIGHT_FILE.is(dataId)) { return getCvsLightFile(); } else { diff --git a/plugins/cvs/cvs-plugin/src/com/intellij/cvsSupport2/cvsExecution/CvsOperationExecutor.java b/plugins/cvs/cvs-plugin/src/com/intellij/cvsSupport2/cvsExecution/CvsOperationExecutor.java index 78a85b15646b..e0547e048523 100644 --- a/plugins/cvs/cvs-plugin/src/com/intellij/cvsSupport2/cvsExecution/CvsOperationExecutor.java +++ b/plugins/cvs/cvs-plugin/src/com/intellij/cvsSupport2/cvsExecution/CvsOperationExecutor.java @@ -323,13 +323,13 @@ public class CvsOperationExecutor { public void update(AnActionEvent e) { super.update(e); - Object data = e.getDataContext().getData(ErrorTreeView.CURRENT_EXCEPTION_DATA); + Object data = ErrorTreeView.CURRENT_EXCEPTION_DATA_KEY.getData(e.getDataContext()); e.getPresentation().setEnabled(data instanceof CvsException); } public void actionPerformed(AnActionEvent e) { - Object data = e.getDataContext().getData(ErrorTreeView.CURRENT_EXCEPTION_DATA); + Object data = ErrorTreeView.CURRENT_EXCEPTION_DATA_KEY.getData(e.getDataContext()); CvsConfigurationsListEditor.reconfigureCvsRoot(((CvsException)data).getCvsRoot(), myProject); } } diff --git a/plugins/cvs/cvs-plugin/src/com/intellij/cvsSupport2/ui/CvsTabbedWindowComponent.java b/plugins/cvs/cvs-plugin/src/com/intellij/cvsSupport2/ui/CvsTabbedWindowComponent.java index 0c4bdebf23fb..a21e414c8aa9 100644 --- a/plugins/cvs/cvs-plugin/src/com/intellij/cvsSupport2/ui/CvsTabbedWindowComponent.java +++ b/plugins/cvs/cvs-plugin/src/com/intellij/cvsSupport2/ui/CvsTabbedWindowComponent.java @@ -64,7 +64,7 @@ public class CvsTabbedWindowComponent extends JPanel implements DataProvider, Cv public Object getData(String dataId) { - if (DataConstants.HELP_ID.equals(dataId)) { + if (PlatformDataKeys.HELP_ID.is(dataId)) { return myHelpId; } return null; diff --git a/plugins/git4idea/src/git4idea/actions/BasicAction.java b/plugins/git4idea/src/git4idea/actions/BasicAction.java index ece00757b5da..d070d9238cb7 100644 --- a/plugins/git4idea/src/git4idea/actions/BasicAction.java +++ b/plugins/git4idea/src/git4idea/actions/BasicAction.java @@ -16,7 +16,6 @@ package git4idea.actions; import com.intellij.openapi.actionSystem.AnActionEvent; -import com.intellij.openapi.actionSystem.DataContext; import com.intellij.openapi.actionSystem.PlatformDataKeys; import com.intellij.openapi.actionSystem.Presentation; import com.intellij.openapi.application.ApplicationManager; @@ -155,15 +154,14 @@ public abstract class BasicAction extends DumbAwareAction { public void update(@NotNull AnActionEvent e) { super.update(e); Presentation presentation = e.getPresentation(); - DataContext dataContext = e.getDataContext(); - Project project = (Project)dataContext.getData(PlatformDataKeys.PROJECT.getName()); + Project project = e.getData(PlatformDataKeys.PROJECT); if (project == null) { presentation.setEnabled(false); presentation.setVisible(false); return; } - VirtualFile[] vFiles = (VirtualFile[])dataContext.getData(PlatformDataKeys.VIRTUAL_FILE_ARRAY.getName()); + VirtualFile[] vFiles = e.getData(PlatformDataKeys.VIRTUAL_FILE_ARRAY); if (vFiles == null || vFiles.length == 0) { presentation.setEnabled(false); presentation.setVisible(true); diff --git a/plugins/git4idea/src/git4idea/actions/GitRepositoryAction.java b/plugins/git4idea/src/git4idea/actions/GitRepositoryAction.java index 24ff03168554..a1baf54e9073 100644 --- a/plugins/git4idea/src/git4idea/actions/GitRepositoryAction.java +++ b/plugins/git4idea/src/git4idea/actions/GitRepositoryAction.java @@ -57,7 +57,7 @@ public abstract class GitRepositoryAction extends DumbAwareAction { } }); DataContext dataContext = e.getDataContext(); - final Project project = (Project)dataContext.getData(PlatformDataKeys.PROJECT.getName()); + final Project project = PlatformDataKeys.PROJECT.getData(dataContext); if (project == null) { return; } @@ -156,7 +156,7 @@ public abstract class GitRepositoryAction extends DumbAwareAction { super.update(e); Presentation presentation = e.getPresentation(); DataContext dataContext = e.getDataContext(); - Project project = (Project)dataContext.getData(PlatformDataKeys.PROJECT.getName()); + Project project = PlatformDataKeys.PROJECT.getData(dataContext); if (project == null) { presentation.setEnabled(false); presentation.setVisible(false); diff --git a/plugins/git4idea/src/git4idea/changes/TestOutgoingAction.java b/plugins/git4idea/src/git4idea/changes/TestOutgoingAction.java index 173c2f8d096f..4f5db55e24bc 100644 --- a/plugins/git4idea/src/git4idea/changes/TestOutgoingAction.java +++ b/plugins/git4idea/src/git4idea/changes/TestOutgoingAction.java @@ -28,9 +28,9 @@ import com.intellij.openapi.vcs.versionBrowser.CommittedChangeList; import com.intellij.openapi.vfs.VirtualFile; import git4idea.GitVcs; +import java.util.Collection; import java.util.Collections; import java.util.List; -import java.util.Collection; public class TestOutgoingAction extends AnAction { @Override @@ -41,7 +41,7 @@ public class TestOutgoingAction extends AnAction { final VcsOutgoingChangesProvider provider = vcs.getOutgoingChangesProvider(); final ProjectLevelVcsManager vcsManager = ProjectLevelVcsManager.getInstance(project); - final VirtualFile vf = (VirtualFile)e.getDataContext().getData(PlatformDataKeys.VIRTUAL_FILE.getName()); + final VirtualFile vf = PlatformDataKeys.VIRTUAL_FILE.getData(e.getDataContext()); try { if (vf != null) { final VirtualFile root = vcsManager.getVcsRootFor(vf); diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/actions/NewGroovyActionBase.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/actions/NewGroovyActionBase.java index 1db7985b3043..1b11dc71d89d 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/actions/NewGroovyActionBase.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/actions/NewGroovyActionBase.java @@ -19,7 +19,7 @@ package org.jetbrains.plugins.groovy.actions; import com.intellij.CommonBundle; import com.intellij.ide.actions.CreateElementActionBase; import com.intellij.openapi.actionSystem.DataContext; -import com.intellij.openapi.actionSystem.DataKeys; +import com.intellij.openapi.actionSystem.LangDataKeys; import com.intellij.openapi.module.Module; import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.Messages; @@ -30,7 +30,6 @@ import com.intellij.psi.PsiFile; import com.intellij.util.IncorrectOperationException; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; -import org.jetbrains.plugins.groovy.GroovyBundle; import org.jetbrains.plugins.groovy.util.GroovyUtils; import org.jetbrains.plugins.groovy.util.LibrariesUtil; @@ -63,7 +62,7 @@ public abstract class NewGroovyActionBase extends CreateElementActionBase { return false; } - Module module = (Module) dataContext.getData(DataKeys.MODULE.getName()); + Module module = LangDataKeys.MODULE.getData(dataContext); return GroovyUtils.isSuitableModule(module) && LibrariesUtil.hasGroovySdk(module); } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/intentions/dynamic/DynamicToolWindowWrapper.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/intentions/dynamic/DynamicToolWindowWrapper.java index c0dc13b661f2..14d2b34b9ed8 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/intentions/dynamic/DynamicToolWindowWrapper.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/intentions/dynamic/DynamicToolWindowWrapper.java @@ -16,7 +16,7 @@ package org.jetbrains.plugins.groovy.annotator.intentions.dynamic; import com.intellij.openapi.actionSystem.DataProvider; -import com.intellij.openapi.actionSystem.ex.DataConstantsEx; +import com.intellij.openapi.actionSystem.LangDataKeys; import com.intellij.openapi.components.ServiceManager; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.editor.Document; @@ -34,8 +34,8 @@ import com.intellij.refactoring.listeners.RefactoringElementListener; import com.intellij.refactoring.listeners.RefactoringElementListenerProvider; import com.intellij.refactoring.listeners.RefactoringListenerManager; import com.intellij.ui.*; -import com.intellij.ui.content.ContentManager; import com.intellij.ui.content.Content; +import com.intellij.ui.content.ContentManager; import com.intellij.ui.treeStructure.treetable.ListTreeTableModelOnColumns; import com.intellij.ui.treeStructure.treetable.TreeTable; import com.intellij.ui.treeStructure.treetable.TreeTableModel; @@ -738,10 +738,10 @@ public class DynamicToolWindowWrapper { @Nullable public Object getData(@NonNls String dataId) { - if (DataConstantsEx.PSI_ELEMENT.equals(dataId)) { + if (LangDataKeys.PSI_ELEMENT.is(dataId)) { return getSelectedElement(); - } else if (DataConstantsEx.PSI_FILE.equals(dataId)) { + } else if (LangDataKeys.PSI_FILE.is(dataId)) { final PsiElement element = getSelectedElement(); if (element == null) return null; diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/doc/actions/GenerateGroovyDocAction.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/doc/actions/GenerateGroovyDocAction.java index 361804c90fad..8f8dca23fc76 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/doc/actions/GenerateGroovyDocAction.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/doc/actions/GenerateGroovyDocAction.java @@ -63,8 +63,7 @@ public final class GenerateGroovyDocAction extends AnAction implements DumbAware public void update(AnActionEvent event) { super.update(event); final Presentation presentation = event.getPresentation(); - final DataContext context = event.getDataContext(); - Module module = (Module)context.getData(DataKeys.MODULE.getName()); + Module module = LangDataKeys.MODULE.getData(event.getDataContext()); if (module == null || !LibrariesUtil.hasGroovySdk(module)) { presentation.setEnabled(false); @@ -120,4 +119,4 @@ public final class GenerateGroovyDocAction extends AnAction implements DumbAware } } } -} \ No newline at end of file +} diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/move/MoveGroovyScriptHandler.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/move/MoveGroovyScriptHandler.java index 284231f9f43e..021866bfd065 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/move/MoveGroovyScriptHandler.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/move/MoveGroovyScriptHandler.java @@ -17,7 +17,7 @@ package org.jetbrains.plugins.groovy.refactoring.move; import com.intellij.openapi.actionSystem.DataContext; -import com.intellij.openapi.actionSystem.ex.DataConstantsEx; +import com.intellij.openapi.actionSystem.LangDataKeys; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.project.Project; import com.intellij.openapi.roots.ProjectRootManager; @@ -79,7 +79,7 @@ public class MoveGroovyScriptHandler extends MoveClassesOrPackagesHandlerBase { @Override public boolean tryToMove(PsiElement element, Project project, DataContext dataContext, @Nullable PsiReference reference, Editor editor) { if (canMove(element)) { - doMove(project, new PsiElement[]{element}, (PsiElement)dataContext.getData(DataConstantsEx.TARGET_PSI_ELEMENT), null); + doMove(project, new PsiElement[]{element}, LangDataKeys.TARGET_PSI_ELEMENT.getData(dataContext), null); return true; } return false; diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/rename/PropertyRenameHandler.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/rename/PropertyRenameHandler.java index 1b2e03381633..2737cdf8d74e 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/rename/PropertyRenameHandler.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/rename/PropertyRenameHandler.java @@ -15,8 +15,8 @@ */ package org.jetbrains.plugins.groovy.refactoring.rename; -import com.intellij.openapi.actionSystem.DataConstants; import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.actionSystem.LangDataKeys; import com.intellij.openapi.actionSystem.PlatformDataKeys; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.project.Project; @@ -44,7 +44,7 @@ public class PropertyRenameHandler implements RenameHandler { @Nullable private static GrField getProperty(DataContext dataContext) { - final PsiElement element = (PsiElement)dataContext.getData(DataConstants.PSI_ELEMENT); + final PsiElement element = LangDataKeys.PSI_ELEMENT.getData(dataContext); if (element instanceof GrField && ((GrField)element).isProperty()) return (GrField)element; if (element instanceof GrAccessorMethod) return ((GrAccessorMethod)element).getProperty(); return null; diff --git a/plugins/junit/src/com/intellij/execution/junit2/ui/StatisticsPanel.java b/plugins/junit/src/com/intellij/execution/junit2/ui/StatisticsPanel.java index 98ded48bd0da..f469a58762d8 100644 --- a/plugins/junit/src/com/intellij/execution/junit2/ui/StatisticsPanel.java +++ b/plugins/junit/src/com/intellij/execution/junit2/ui/StatisticsPanel.java @@ -16,8 +16,8 @@ package com.intellij.execution.junit2.ui; -import com.intellij.execution.junit2.events.TestEvent; import com.intellij.execution.junit2.TestProxy; +import com.intellij.execution.junit2.events.TestEvent; import com.intellij.execution.junit2.ui.actions.TestContext; import com.intellij.execution.junit2.ui.model.JUnitAdapter; import com.intellij.execution.junit2.ui.model.JUnitRunningModel; @@ -88,7 +88,7 @@ class StatisticsPanel extends JPanel implements DataProvider{ public Object getData(final String dataId) { if (myModel == null) return null; final TestProxy selectedTest = myChildInfo.getTestAt(myTable.getSelectedRow()); - if (TestContext.TEST_CONTEXT.equals(dataId)) { + if (TestContext.DATA_KEY.is(dataId)) { return new TestContext(myModel, selectedTest); } return TestsUIUtil.getData(selectedTest, dataId, myModel); diff --git a/plugins/junit/src/com/intellij/execution/junit2/ui/actions/TestContext.java b/plugins/junit/src/com/intellij/execution/junit2/ui/actions/TestContext.java index ec21a3feadf5..bcbfe725d668 100644 --- a/plugins/junit/src/com/intellij/execution/junit2/ui/actions/TestContext.java +++ b/plugins/junit/src/com/intellij/execution/junit2/ui/actions/TestContext.java @@ -19,10 +19,11 @@ package com.intellij.execution.junit2.ui.actions; import com.intellij.execution.junit2.TestProxy; import com.intellij.execution.junit2.ui.model.JUnitRunningModel; import com.intellij.openapi.actionSystem.AnActionEvent; -import org.jetbrains.annotations.NonNls; +import com.intellij.openapi.actionSystem.DataKey; public class TestContext { - @NonNls public static final String TEST_CONTEXT = "JUNIT_CONTEXT"; + public static final DataKey DATA_KEY = DataKey.create("JUNIT_CONTEXT"); + @Deprecated public static final String TEST_CONTEXT = DATA_KEY.getName(); private final JUnitRunningModel myModel; private final TestProxy mySelection; @@ -49,6 +50,6 @@ public class TestContext { } public static TestContext from(final AnActionEvent event) { - return (TestContext) event.getDataContext().getData(TEST_CONTEXT); + return DATA_KEY.getData(event.getDataContext()); } } diff --git a/plugins/junit/src/com/intellij/execution/junit2/ui/actions/ViewAssertEqualsDiffAction.java b/plugins/junit/src/com/intellij/execution/junit2/ui/actions/ViewAssertEqualsDiffAction.java index 21431246c65a..56180ec82ab1 100644 --- a/plugins/junit/src/com/intellij/execution/junit2/ui/actions/ViewAssertEqualsDiffAction.java +++ b/plugins/junit/src/com/intellij/execution/junit2/ui/actions/ViewAssertEqualsDiffAction.java @@ -27,24 +27,29 @@ import javax.swing.*; public class ViewAssertEqualsDiffAction extends AnAction { @NonNls public static final String ACTION_ID = "openAssertEqualsDiff"; + public void actionPerformed(final AnActionEvent e) { - final DataContext dataContext = e.getDataContext(); - final AbstractTestProxy testProxy = (AbstractTestProxy)dataContext.getData(AbstractTestProxy.DATA_CONSTANT); - final ComparisonFailureState state = (ComparisonFailureState)((TestProxy)testProxy).getState(); - state.openDiff(PlatformDataKeys.PROJECT.getData(dataContext)); + final AbstractTestProxy testProxy = AbstractTestProxy.DATA_KEY.getData(e.getDataContext()); + if (testProxy != null) { + final ComparisonFailureState state = (ComparisonFailureState)((TestProxy)testProxy).getState(); + state.openDiff(PlatformDataKeys.PROJECT.getData(e.getDataContext())); + } } public void update(final AnActionEvent e) { final Presentation presentation = e.getPresentation(); final boolean enabled; final DataContext dataContext = e.getDataContext(); - if (dataContext.getData(DataConstants.PROJECT) == null) enabled = false; + if (PlatformDataKeys.PROJECT.getData(dataContext) == null) { + enabled = false; + } else { - final AbstractTestProxy test = (AbstractTestProxy)dataContext.getData(AbstractTestProxy.DATA_CONSTANT); + final AbstractTestProxy test = AbstractTestProxy.DATA_KEY.getData(dataContext); if (test instanceof TestProxy) { final TestState state = ((TestProxy)test).getState(); enabled = state instanceof ComparisonFailureState; - } else { + } + else { enabled = false; } } diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/navigator/MavenProjectsNavigatorPanel.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/navigator/MavenProjectsNavigatorPanel.java index 72dde8a81314..533ccd919b8e 100644 --- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/navigator/MavenProjectsNavigatorPanel.java +++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/navigator/MavenProjectsNavigatorPanel.java @@ -32,8 +32,8 @@ import gnu.trove.THashMap; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.Nullable; import org.jetbrains.idea.maven.embedder.MavenEmbedderFactory; -import org.jetbrains.idea.maven.project.MavenProject; import org.jetbrains.idea.maven.execution.MavenGoalLocation; +import org.jetbrains.idea.maven.project.MavenProject; import org.jetbrains.idea.maven.utils.MavenDataKeys; import javax.swing.*; @@ -99,18 +99,18 @@ public class MavenProjectsNavigatorPanel extends SimpleToolWindowPanel implement @Nullable public Object getData(@NonNls String dataId) { - if (dataId.equals(PlatformDataKeys.HELP_ID.getName())) return "reference.toolWindows.mavenProjects"; + if (PlatformDataKeys.HELP_ID.is(dataId)) return "reference.toolWindows.mavenProjects"; - if (dataId.equals(PlatformDataKeys.PROJECT.getName())) return myProject; + if (PlatformDataKeys.PROJECT.is(dataId)) return myProject; - if (dataId.equals(PlatformDataKeys.VIRTUAL_FILE.getName())) return extractVirtualFile(); - if (dataId.equals(PlatformDataKeys.VIRTUAL_FILE_ARRAY.getName())) return extractVirtualFiles(); + if (PlatformDataKeys.VIRTUAL_FILE.is(dataId)) return extractVirtualFile(); + if (PlatformDataKeys.VIRTUAL_FILE_ARRAY.is(dataId)) return extractVirtualFiles(); - if (dataId.equals(Location.LOCATION)) return extractLocation(); - if (dataId.equals(PlatformDataKeys.NAVIGATABLE_ARRAY.getName())) return extractNavigatables(); + if (Location.DATA_KEY.is(dataId)) return extractLocation(); + if (PlatformDataKeys.NAVIGATABLE_ARRAY.is(dataId)) return extractNavigatables(); - if (dataId.equals(MavenDataKeys.MAVEN_GOALS.getName())) return extractGoals(); - if (dataId.equals(MavenDataKeys.MAVEN_PROFILES.getName())) return extractProfiles(); + if (MavenDataKeys.MAVEN_GOALS.is(dataId)) return extractGoals(); + if (MavenDataKeys.MAVEN_PROFILES.is(dataId)) return extractProfiles(); return null; } diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/tasks/MavenBeforeRunTasksProvider.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/tasks/MavenBeforeRunTasksProvider.java index 923bf6ad5070..4d3f226b84a6 100644 --- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/tasks/MavenBeforeRunTasksProvider.java +++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/tasks/MavenBeforeRunTasksProvider.java @@ -17,8 +17,8 @@ package org.jetbrains.idea.maven.tasks; import com.intellij.execution.BeforeRunTaskProvider; import com.intellij.execution.configurations.RunConfiguration; -import com.intellij.ide.DataAccessors; import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.actionSystem.PlatformDataKeys; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.application.ModalityState; import com.intellij.openapi.progress.ProgressIndicator; @@ -30,11 +30,11 @@ import com.intellij.openapi.vfs.LocalFileSystem; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.util.concurrency.Semaphore; import org.jetbrains.annotations.NotNull; +import org.jetbrains.idea.maven.execution.MavenRunner; +import org.jetbrains.idea.maven.execution.MavenRunnerParameters; import org.jetbrains.idea.maven.navigator.SelectMavenGoalDialog; import org.jetbrains.idea.maven.project.MavenProject; import org.jetbrains.idea.maven.project.MavenProjectsManager; -import org.jetbrains.idea.maven.execution.MavenRunner; -import org.jetbrains.idea.maven.execution.MavenRunnerParameters; import org.jetbrains.idea.maven.utils.MavenLog; import java.util.Collections; @@ -47,7 +47,7 @@ public class MavenBeforeRunTasksProvider extends BeforeRunTaskProvider getId() { return TASK_ID; } @@ -105,7 +105,7 @@ public class MavenBeforeRunTasksProvider extends BeforeRunTaskProvider projectAndGoal = getProjectAndGoalChecked(task); if (project == null || project.isDisposed() || projectAndGoal == null) return; diff --git a/plugins/properties/src/com/intellij/ide/favoritesTreeView/ResourcesFavoriteNodeProvider.java b/plugins/properties/src/com/intellij/ide/favoritesTreeView/ResourcesFavoriteNodeProvider.java index f5968300020f..e0c0bbf58c82 100644 --- a/plugins/properties/src/com/intellij/ide/favoritesTreeView/ResourcesFavoriteNodeProvider.java +++ b/plugins/properties/src/com/intellij/ide/favoritesTreeView/ResourcesFavoriteNodeProvider.java @@ -28,7 +28,6 @@ import com.intellij.lang.properties.projectView.ResourceBundleNode; import com.intellij.lang.properties.psi.PropertiesFile; import com.intellij.openapi.actionSystem.DataContext; import com.intellij.openapi.actionSystem.PlatformDataKeys; -import com.intellij.openapi.actionSystem.ex.DataConstantsEx; import com.intellij.openapi.project.Project; import com.intellij.openapi.vfs.VirtualFile; import org.jetbrains.annotations.NotNull; @@ -46,16 +45,18 @@ public class ResourcesFavoriteNodeProvider extends FavoriteNodeProvider { public Collection getFavoriteNodes(final DataContext context, final ViewSettings viewSettings) { final Project project = PlatformDataKeys.PROJECT.getData(context); - if (project == null) return null; - final Object object = context.getData(DataConstantsEx.RESOURCE_BUNDLE_ARRAY); + if (project == null) { + return null; + } + final ResourceBundle[] resourceBundles = ResourceBundle.ARRAY_DATA_KEY.getData(context); //on bundles nodes - if (object instanceof ResourceBundle[]) { - final Collection result = new ArrayList(); - for (ResourceBundle bundle : (ResourceBundle[])object) { - result.add(new ResourceBundleNode(project, bundle, viewSettings)); - } - return result; - } + if (resourceBundles != null) { + final Collection result = new ArrayList(); + for (ResourceBundle bundle : resourceBundles) { + result.add(new ResourceBundleNode(project, bundle, viewSettings)); + } + return result; + } return null; } @@ -100,7 +101,7 @@ public class ResourcesFavoriteNodeProvider extends FavoriteNodeProvider { } public String getElementUrl(final Object element) { - if (element instanceof ResourceBundle) { + if (element instanceof ResourceBundleImpl) { return ((ResourceBundleImpl)element).getUrl(); } return null; @@ -113,4 +114,4 @@ public class ResourcesFavoriteNodeProvider extends FavoriteNodeProvider { public Object[] createPathFromUrl(final Project project, final String url, final String moduleName) { return new Object[]{ResourceBundleImpl.createByUrl(url)}; } -} \ No newline at end of file +} diff --git a/plugins/properties/src/com/intellij/lang/properties/ResourceBundle.java b/plugins/properties/src/com/intellij/lang/properties/ResourceBundle.java index 0bb544bf23d4..dffc3a48d903 100644 --- a/plugins/properties/src/com/intellij/lang/properties/ResourceBundle.java +++ b/plugins/properties/src/com/intellij/lang/properties/ResourceBundle.java @@ -23,22 +23,30 @@ package com.intellij.lang.properties; import com.intellij.lang.properties.psi.PropertiesFile; +import com.intellij.openapi.actionSystem.DataKey; import com.intellij.openapi.project.Project; -import com.intellij.openapi.vfs.VirtualFile; import com.intellij.openapi.util.IconLoader; +import com.intellij.openapi.vfs.VirtualFile; import org.jetbrains.annotations.NotNull; import javax.swing.*; import java.util.List; public interface ResourceBundle { + DataKey ARRAY_DATA_KEY = DataKey.create("resource.bundle.array"); + Icon ICON_CLOSED = IconLoader.getIcon("/nodes/resourceBundleClosed.png"); Icon ICON_OPEN = IconLoader.getIcon("/nodes/resourceBundleOpen.png"); - @NotNull List getPropertiesFiles(final Project project); - @NotNull PropertiesFile getDefaultPropertiesFile(final Project project); + @NotNull + List getPropertiesFiles(final Project project); - @NotNull String getBaseName(); + @NotNull + PropertiesFile getDefaultPropertiesFile(final Project project); - @NotNull VirtualFile getBaseDirectory(); + @NotNull + String getBaseName(); + + @NotNull + VirtualFile getBaseDirectory(); } \ No newline at end of file diff --git a/plugins/properties/src/com/intellij/lang/properties/editor/ResourceBundleEditor.java b/plugins/properties/src/com/intellij/lang/properties/editor/ResourceBundleEditor.java index dab79655d171..177d526da508 100644 --- a/plugins/properties/src/com/intellij/lang/properties/editor/ResourceBundleEditor.java +++ b/plugins/properties/src/com/intellij/lang/properties/editor/ResourceBundleEditor.java @@ -477,7 +477,7 @@ public class ResourceBundleEditor extends UserDataHolderBase implements FileEdit } private Object getData(final String dataId) { - if (SelectInContext.DATA_CONTEXT_ID.equals(dataId)) { + if (SelectInContext.DATA_KEY.is(dataId)) { return new SelectInContext(){ @NotNull public Project getProject() { @@ -502,7 +502,12 @@ public class ResourceBundleEditor extends UserDataHolderBase implements FileEdit if (selectedPropertiesFile == null) return null; return new FileEditorProvider() { public FileEditor openFileEditor() { - return FileEditorManager.getInstance(getProject()).openFile(selectedPropertiesFile.getVirtualFile(), false)[0]; + final VirtualFile file = selectedPropertiesFile.getVirtualFile(); + if (file == null) { + return null; + } + return FileEditorManager.getInstance(getProject()).openFile(file, false)[0]; + } }; } @@ -695,4 +700,4 @@ public class ResourceBundleEditor extends UserDataHolderBase implements FileEdit } } -} \ No newline at end of file +} diff --git a/plugins/properties/src/com/intellij/lang/properties/editor/ResourceBundleStructureViewComponent.java b/plugins/properties/src/com/intellij/lang/properties/editor/ResourceBundleStructureViewComponent.java index c263df0321b9..ab734504e3ba 100644 --- a/plugins/properties/src/com/intellij/lang/properties/editor/ResourceBundleStructureViewComponent.java +++ b/plugins/properties/src/com/intellij/lang/properties/editor/ResourceBundleStructureViewComponent.java @@ -16,7 +16,7 @@ package com.intellij.lang.properties.editor; import com.intellij.lang.properties.ResourceBundle; -import com.intellij.openapi.actionSystem.DataConstants; +import com.intellij.openapi.actionSystem.PlatformDataKeys; import com.intellij.openapi.project.Project; /** @@ -31,7 +31,7 @@ class ResourceBundleStructureViewComponent extends PropertiesGroupingStructureVi } public Object getData(String dataId) { - if (dataId.equals(DataConstants.VIRTUAL_FILE)) { + if (PlatformDataKeys.VIRTUAL_FILE.is(dataId)) { return new ResourceBundleAsVirtualFile(myResourceBundle); } return super.getData(dataId); diff --git a/plugins/properties/src/com/intellij/lang/properties/projectView/ResourceBundleGrouper.java b/plugins/properties/src/com/intellij/lang/properties/projectView/ResourceBundleGrouper.java index ee8c396dab9e..306d86c97dd2 100644 --- a/plugins/properties/src/com/intellij/lang/properties/projectView/ResourceBundleGrouper.java +++ b/plugins/properties/src/com/intellij/lang/properties/projectView/ResourceBundleGrouper.java @@ -21,11 +21,10 @@ import com.intellij.ide.util.treeView.AbstractTreeNode; import com.intellij.lang.properties.ResourceBundle; import com.intellij.lang.properties.editor.ResourceBundleAsVirtualFile; import com.intellij.lang.properties.psi.PropertiesFile; -import com.intellij.openapi.actionSystem.DataConstants; -import com.intellij.openapi.actionSystem.ex.DataConstantsEx; -import com.intellij.openapi.project.Project; +import com.intellij.openapi.actionSystem.LangDataKeys; +import com.intellij.openapi.actionSystem.PlatformDataKeys; import com.intellij.openapi.project.DumbAware; -import com.intellij.psi.PsiElement; +import com.intellij.openapi.project.Project; import com.intellij.util.SmartList; import gnu.trove.THashMap; @@ -86,24 +85,24 @@ public class ResourceBundleGrouper implements TreeStructureProvider, DumbAware { if (selected == null) return null; for (AbstractTreeNode selectedElement : selected) { Object element = selectedElement.getValue(); - if (DataConstants.VIRTUAL_FILE.equals(dataName)) { + if (PlatformDataKeys.VIRTUAL_FILE.is(dataName)) { if (element instanceof ResourceBundle) { return new ResourceBundleAsVirtualFile((ResourceBundle)element); } } - if (DataConstants.PSI_ELEMENT_ARRAY.equals(dataName)) { + if (LangDataKeys.PSI_ELEMENT_ARRAY.is(dataName)) { if (element instanceof ResourceBundle) { List propertiesFiles = ((ResourceBundle)element).getPropertiesFiles(myProject); - return propertiesFiles.toArray(PsiElement.EMPTY_ARRAY); + return propertiesFiles.toArray(new PropertiesFile[propertiesFiles.size()]); } } - if (DataConstants.DELETE_ELEMENT_PROVIDER.equals(dataName)) { + if (PlatformDataKeys.DELETE_ELEMENT_PROVIDER.is(dataName)) { if (element instanceof ResourceBundle) { return new ResourceBundleDeleteProvider((ResourceBundle)element); } } } - if (DataConstantsEx.RESOURCE_BUNDLE_ARRAY.equals(dataName)) { + if (ResourceBundle.ARRAY_DATA_KEY.is(dataName)) { final List selectedElements = new ArrayList(); for (AbstractTreeNode node : selected) { final Object value = node.getValue(); diff --git a/plugins/properties/src/com/intellij/lang/properties/structureView/PropertiesFileStructureViewComponent.java b/plugins/properties/src/com/intellij/lang/properties/structureView/PropertiesFileStructureViewComponent.java index 281da13a8436..10f3d6c66e1c 100644 --- a/plugins/properties/src/com/intellij/lang/properties/structureView/PropertiesFileStructureViewComponent.java +++ b/plugins/properties/src/com/intellij/lang/properties/structureView/PropertiesFileStructureViewComponent.java @@ -17,7 +17,8 @@ package com.intellij.lang.properties.structureView; import com.intellij.lang.properties.editor.PropertiesGroupingStructureViewComponent; import com.intellij.lang.properties.psi.PropertiesFile; -import com.intellij.openapi.actionSystem.DataConstants; +import com.intellij.openapi.actionSystem.LangDataKeys; +import com.intellij.openapi.actionSystem.PlatformDataKeys; import com.intellij.openapi.fileEditor.FileEditor; import com.intellij.openapi.project.Project; @@ -33,10 +34,10 @@ public class PropertiesFileStructureViewComponent extends PropertiesGroupingStru } public Object getData(String dataId) { - if (dataId.equals(DataConstants.VIRTUAL_FILE)) { + if (PlatformDataKeys.VIRTUAL_FILE.is(dataId)) { return myPropertiesFile.getVirtualFile(); } - if (dataId.equals(DataConstants.PSI_ELEMENT)) { + if (LangDataKeys.PSI_ELEMENT.is(dataId)) { return myPropertiesFile; } return super.getData(dataId); diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/actions/AbstractIntegrateChangesAction.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/actions/AbstractIntegrateChangesAction.java index 3b0438ff6670..4d274b413405 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/actions/AbstractIntegrateChangesAction.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/actions/AbstractIntegrateChangesAction.java @@ -42,8 +42,7 @@ public abstract class AbstractIntegrateChangesAction selection, final AnActionEvent e) { - final PropertyInspectorTable inspector = (PropertyInspectorTable)e.getDataContext().getData(PropertyInspectorTable.class.getName()); + final PropertyInspectorTable inspector = PropertyInspectorTable.DATA_KEY.getData(e.getDataContext()); assert inspector != null; final Property property = inspector.getSelectedProperty(); assert property != null; @@ -66,7 +66,7 @@ public class ResetValueAction extends AbstractGuiEditorAction { } protected void update(final GuiEditor editor, final ArrayList selection, final AnActionEvent e) { - PropertyInspectorTable inspector = (PropertyInspectorTable)e.getDataContext().getData(PropertyInspectorTable.class.getName()); + PropertyInspectorTable inspector = PropertyInspectorTable.DATA_KEY.getData(e.getDataContext()); if (inspector != null) { final Property selectedProperty = inspector.getSelectedProperty(); //noinspection unchecked diff --git a/plugins/ui-designer/src/com/intellij/uiDesigner/actions/RowColumnAction.java b/plugins/ui-designer/src/com/intellij/uiDesigner/actions/RowColumnAction.java index df4795425b29..633583d149be 100644 --- a/plugins/ui-designer/src/com/intellij/uiDesigner/actions/RowColumnAction.java +++ b/plugins/ui-designer/src/com/intellij/uiDesigner/actions/RowColumnAction.java @@ -44,7 +44,7 @@ public abstract class RowColumnAction extends AnAction { public void actionPerformed(final AnActionEvent e) { GuiEditor editor = FormEditingUtil.getEditorFromContext(e.getDataContext()); - CaptionSelection selection = (CaptionSelection) e.getDataContext().getData(CaptionSelection.class.getName()); + CaptionSelection selection = CaptionSelection.DATA_KEY.getData(e.getDataContext()); if (editor == null || selection == null || !editor.ensureEditable()) { return; } @@ -57,7 +57,7 @@ public abstract class RowColumnAction extends AnAction { public void update(final AnActionEvent e) { final Presentation presentation = e.getPresentation(); - CaptionSelection selection = (CaptionSelection) e.getDataContext().getData(CaptionSelection.class.getName()); + CaptionSelection selection = CaptionSelection.DATA_KEY.getData(e.getDataContext()); if (selection == null) { presentation.setEnabled(false); } diff --git a/plugins/ui-designer/src/com/intellij/uiDesigner/actions/ShowJavadocAction.java b/plugins/ui-designer/src/com/intellij/uiDesigner/actions/ShowJavadocAction.java index fcd85525a0c2..5f7717e6efe6 100644 --- a/plugins/ui-designer/src/com/intellij/uiDesigner/actions/ShowJavadocAction.java +++ b/plugins/ui-designer/src/com/intellij/uiDesigner/actions/ShowJavadocAction.java @@ -43,7 +43,7 @@ public final class ShowJavadocAction extends AnAction { private static final Logger LOG = Logger.getInstance("#com.intellij.uiDesigner.actions.ShowJavadocAction"); public void actionPerformed(final AnActionEvent e) { - final PropertyInspectorTable inspector = (PropertyInspectorTable)e.getDataContext().getData(PropertyInspectorTable.class.getName()); + final PropertyInspectorTable inspector = PropertyInspectorTable.DATA_KEY.getData(e.getDataContext()); final IntrospectedProperty introspectedProperty = inspector.getSelectedIntrospectedProperty(); final PsiClass aClass = inspector.getComponentClass(); @@ -87,7 +87,7 @@ public final class ShowJavadocAction extends AnAction { } public void update(final AnActionEvent e) { - final PropertyInspectorTable inspector = (PropertyInspectorTable)e.getDataContext().getData(PropertyInspectorTable.class.getName()); + final PropertyInspectorTable inspector = PropertyInspectorTable.DATA_KEY.getData(e.getDataContext()); e.getPresentation().setEnabled(inspector != null && inspector.getSelectedIntrospectedProperty() != null && inspector.getComponentClass() != null); diff --git a/plugins/ui-designer/src/com/intellij/uiDesigner/actions/UngroupRowsColumnsAction.java b/plugins/ui-designer/src/com/intellij/uiDesigner/actions/UngroupRowsColumnsAction.java index eae2d2bbe2da..b0ab3ffe6209 100644 --- a/plugins/ui-designer/src/com/intellij/uiDesigner/actions/UngroupRowsColumnsAction.java +++ b/plugins/ui-designer/src/com/intellij/uiDesigner/actions/UngroupRowsColumnsAction.java @@ -16,13 +16,13 @@ package com.intellij.uiDesigner.actions; +import com.intellij.openapi.actionSystem.AnActionEvent; import com.intellij.uiDesigner.CaptionSelection; import com.intellij.uiDesigner.UIDesignerBundle; -import com.intellij.openapi.actionSystem.AnActionEvent; import com.jgoodies.forms.layout.FormLayout; -import java.util.List; import java.util.ArrayList; +import java.util.List; /** * @author yole @@ -35,7 +35,7 @@ public class UngroupRowsColumnsAction extends RowColumnAction { @Override public void update(final AnActionEvent e) { super.update(e); - CaptionSelection selection = e.getData(CaptionSelection.DATA_KEY); + CaptionSelection selection = CaptionSelection.DATA_KEY.getData(e.getDataContext()); if (selection != null) { e.getPresentation().setEnabled(selection.getContainer() != null && selection.getContainer().getLayout() instanceof FormLayout && diff --git a/plugins/ui-designer/src/com/intellij/uiDesigner/componentTree/ComponentTree.java b/plugins/ui-designer/src/com/intellij/uiDesigner/componentTree/ComponentTree.java index 950b8b8761b9..814d7a9f4dd5 100644 --- a/plugins/ui-designer/src/com/intellij/uiDesigner/componentTree/ComponentTree.java +++ b/plugins/ui-designer/src/com/intellij/uiDesigner/componentTree/ComponentTree.java @@ -37,6 +37,7 @@ import com.intellij.ui.ColoredTreeCellRenderer; import com.intellij.ui.PopupHandler; import com.intellij.ui.SimpleTextAttributes; import com.intellij.ui.TreeToolTipHandler; +import com.intellij.ui.treeStructure.Tree; import com.intellij.uiDesigner.*; import com.intellij.uiDesigner.actions.StartInplaceEditingAction; import com.intellij.uiDesigner.core.GridConstraints; @@ -47,7 +48,6 @@ import com.intellij.uiDesigner.palette.ComponentItem; import com.intellij.uiDesigner.palette.Palette; import com.intellij.uiDesigner.quickFixes.QuickFixManager; import com.intellij.uiDesigner.radComponents.*; -import com.intellij.ui.treeStructure.Tree; import com.intellij.util.ui.UIUtil; import com.intellij.util.ui.tree.TreeUtil; import org.jetbrains.annotations.NonNls; @@ -74,6 +74,9 @@ import java.util.List; public final class ComponentTree extends Tree implements DataProvider { private static final Logger LOG = Logger.getInstance("#com.intellij.uiDesigner.componentTree.ComponentTree"); + public static final DataKey LW_INSPECTION_SUPPRESSION_ARRAY_DATA_KEY = + DataKey.create(LwInspectionSuppression.class.getName()); + private SimpleTextAttributes myBindingAttributes; // exists only for performance reason private SimpleTextAttributes myClassAttributes; // exists only for performance reason private SimpleTextAttributes myPackageAttributes; // exists only for performance reason @@ -229,39 +232,38 @@ public final class ComponentTree extends Tree implements DataProvider { } /** - * Provides {@link DataConstants#NAVIGATABLE} to navigate to + * Provides {@link PlatformDataKeys#NAVIGATABLE} to navigate to * binding of currently selected component (if any) */ public Object getData(final String dataId) { - if (GuiEditor.class.getName().equals(dataId)) { + if (GuiEditor.DATA_KEY.is(dataId)) { return myEditor; } - if (DataConstants.DELETE_ELEMENT_PROVIDER.equals(dataId)) { + if (PlatformDataKeys.DELETE_ELEMENT_PROVIDER.is(dataId)) { return myDeleteProvider; } - if ( - DataConstants.COPY_PROVIDER.equals(dataId) || - DataConstants.CUT_PROVIDER.equals(dataId) || - DataConstants.PASTE_PROVIDER.equals(dataId)) { + if (PlatformDataKeys.COPY_PROVIDER.is(dataId) || + PlatformDataKeys.CUT_PROVIDER.is(dataId) || + PlatformDataKeys.PASTE_PROVIDER.is(dataId)) { return myEditor == null ? null : myEditor.getData(dataId); } - if (LwInspectionSuppression.class.getName().equals(dataId)) { + if (LW_INSPECTION_SUPPRESSION_ARRAY_DATA_KEY.is(dataId)) { Collection elements = getSelectedElements(LwInspectionSuppression.class); return elements.size() == 0 ? null : elements.toArray(new LwInspectionSuppression[elements.size()]); } - if (DataConstants.HELP_ID.equals(dataId)) { + if (PlatformDataKeys.HELP_ID.is(dataId)) { return ourHelpID; } - if (DataConstants.FILE_EDITOR.equals(dataId)) { + if (PlatformDataKeys.FILE_EDITOR.is(dataId)) { return myFormEditor; } - if (!DataConstants.NAVIGATABLE.equals(dataId)) { + if (!PlatformDataKeys.NAVIGATABLE.is(dataId)) { return null; } @@ -595,7 +597,7 @@ public final class ComponentTree extends Tree implements DataProvider { public void deleteElement(DataContext dataContext) { if (myEditor != null) { - LwInspectionSuppression[] suppressions = (LwInspectionSuppression[]) dataContext.getData(LwInspectionSuppression.class.getName()); + LwInspectionSuppression[] suppressions = LW_INSPECTION_SUPPRESSION_ARRAY_DATA_KEY.getData(dataContext); if (suppressions != null) { if (!myEditor.ensureEditable()) return; for(LwInspectionSuppression suppression: suppressions) { @@ -604,7 +606,7 @@ public final class ComponentTree extends Tree implements DataProvider { myEditor.refreshAndSave(true); } else { - DeleteProvider baseProvider = (DeleteProvider) myEditor.getData(DataConstants.DELETE_ELEMENT_PROVIDER); + DeleteProvider baseProvider = (DeleteProvider) myEditor.getData(PlatformDataKeys.DELETE_ELEMENT_PROVIDER.getName()); if (baseProvider != null) { baseProvider.deleteElement(dataContext); } @@ -614,11 +616,11 @@ public final class ComponentTree extends Tree implements DataProvider { public boolean canDeleteElement(DataContext dataContext) { if (myEditor != null) { - LwInspectionSuppression[] suppressions = (LwInspectionSuppression[]) dataContext.getData(LwInspectionSuppression.class.getName()); + LwInspectionSuppression[] suppressions = LW_INSPECTION_SUPPRESSION_ARRAY_DATA_KEY.getData(dataContext); if (suppressions != null) { return true; } - DeleteProvider baseProvider = (DeleteProvider) myEditor.getData(DataConstants.DELETE_ELEMENT_PROVIDER); + DeleteProvider baseProvider = (DeleteProvider) myEditor.getData(PlatformDataKeys.DELETE_ELEMENT_PROVIDER.getName()); if (baseProvider != null) { return baseProvider.canDeleteElement(dataContext); } diff --git a/plugins/ui-designer/src/com/intellij/uiDesigner/designSurface/GlassLayer.java b/plugins/ui-designer/src/com/intellij/uiDesigner/designSurface/GlassLayer.java index 51b6236046db..81db6370b426 100644 --- a/plugins/ui-designer/src/com/intellij/uiDesigner/designSurface/GlassLayer.java +++ b/plugins/ui-designer/src/com/intellij/uiDesigner/designSurface/GlassLayer.java @@ -17,11 +17,11 @@ package com.intellij.uiDesigner.designSurface; import com.intellij.openapi.actionSystem.*; import com.intellij.openapi.diagnostic.Logger; +import com.intellij.ui.popup.PopupOwner; +import com.intellij.uiDesigner.FormEditingUtil; import com.intellij.uiDesigner.actions.*; import com.intellij.uiDesigner.propertyInspector.UIDesignerToolWindowManager; import com.intellij.uiDesigner.radComponents.RadComponent; -import com.intellij.uiDesigner.FormEditingUtil; -import com.intellij.ui.popup.PopupOwner; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -130,11 +130,11 @@ public final class GlassLayer extends JComponent implements DataProvider, PopupO } /** - * Provides {@link DataConstants#NAVIGATABLE} to navigate to + * Provides {@link PlatformDataKeys#NAVIGATABLE} to navigate to * binding of currently selected component (if any) */ public Object getData(final String dataId) { - if(DataConstants.NAVIGATABLE.equals(dataId)) { + if(PlatformDataKeys.NAVIGATABLE.is(dataId)) { return UIDesignerToolWindowManager.getInstance(myEditor.getProject()).getComponentTree().getData(dataId); } else{ diff --git a/plugins/ui-designer/src/com/intellij/uiDesigner/designSurface/GridCaptionPanel.java b/plugins/ui-designer/src/com/intellij/uiDesigner/designSurface/GridCaptionPanel.java index f162df186972..8bf4b8ea8482 100644 --- a/plugins/ui-designer/src/com/intellij/uiDesigner/designSurface/GridCaptionPanel.java +++ b/plugins/ui-designer/src/com/intellij/uiDesigner/designSurface/GridCaptionPanel.java @@ -252,13 +252,13 @@ public class GridCaptionPanel extends JPanel implements ComponentSelectionListen } @Nullable public Object getData(String dataId) { - if (dataId.equals(GuiEditor.class.getName())) { + if (GuiEditor.DATA_KEY.is(dataId)) { return myEditor; } - if (dataId.equals(CaptionSelection.class.getName())) { + if (CaptionSelection.DATA_KEY.is(dataId)) { return new CaptionSelection(mySelectedContainer, myIsRow, getSelectedCells(null), mySelectionModel.getLeadSelectionIndex()); } - if (dataId.equals(DataConstants.DELETE_ELEMENT_PROVIDER)) { + if (PlatformDataKeys.DELETE_ELEMENT_PROVIDER.is(dataId)) { return myDeleteProvider; } return myEditor.getData(dataId); diff --git a/plugins/ui-designer/src/com/intellij/uiDesigner/designSurface/GuiEditor.java b/plugins/ui-designer/src/com/intellij/uiDesigner/designSurface/GuiEditor.java index a8b1b0b64394..79953db15c25 100644 --- a/plugins/ui-designer/src/com/intellij/uiDesigner/designSurface/GuiEditor.java +++ b/plugins/ui-designer/src/com/intellij/uiDesigner/designSurface/GuiEditor.java @@ -200,6 +200,8 @@ public final class GuiEditor extends JPanel implements DataProvider { @NonNls private static final String ourHelpID = "guiDesigner.uiTour.workspace"; + public static final DataKey DATA_KEY = DataKey.create(GuiEditor.class.getName()); + /** * @param file file to be edited * @throws java.lang.IllegalArgumentException @@ -457,7 +459,7 @@ public final class GuiEditor extends JPanel implements DataProvider { } public Object getData(final String dataId) { - if (DataConstants.HELP_ID.equals(dataId)) { + if (PlatformDataKeys.HELP_ID.is(dataId)) { return ourHelpID; } @@ -467,15 +469,13 @@ public final class GuiEditor extends JPanel implements DataProvider { return null; } - if (DataConstants.DELETE_ELEMENT_PROVIDER.equals(dataId)) { + if (PlatformDataKeys.DELETE_ELEMENT_PROVIDER.is(dataId)) { return myDeleteProvider; } - if ( - DataConstants.COPY_PROVIDER.equals(dataId) || - DataConstants.CUT_PROVIDER.equals(dataId) || - DataConstants.PASTE_PROVIDER.equals(dataId) - ) { + if (PlatformDataKeys.COPY_PROVIDER.is(dataId) || + PlatformDataKeys.CUT_PROVIDER.is(dataId) || + PlatformDataKeys.PASTE_PROVIDER.is(dataId)) { return myCutCopyPasteSupport; } diff --git a/plugins/ui-designer/src/com/intellij/uiDesigner/palette/ComponentItem.java b/plugins/ui-designer/src/com/intellij/uiDesigner/palette/ComponentItem.java index 8b5ff16c0faf..dfabb2291277 100644 --- a/plugins/ui-designer/src/com/intellij/uiDesigner/palette/ComponentItem.java +++ b/plugins/ui-designer/src/com/intellij/uiDesigner/palette/ComponentItem.java @@ -19,8 +19,8 @@ import com.intellij.ide.dnd.DnDDragStartBean; import com.intellij.ide.palette.PaletteItem; import com.intellij.openapi.actionSystem.ActionGroup; import com.intellij.openapi.actionSystem.ActionManager; -import com.intellij.openapi.actionSystem.DataConstants; import com.intellij.openapi.actionSystem.DataKey; +import com.intellij.openapi.actionSystem.LangDataKeys; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.module.ResourceFileUtil; import com.intellij.openapi.project.Project; @@ -46,7 +46,7 @@ import org.jetbrains.annotations.Nullable; import javax.swing.*; import java.awt.*; import java.io.IOException; -import java.util.*; +import java.util.HashMap; import java.util.List; /** @@ -365,13 +365,13 @@ public final class ComponentItem implements Cloneable, PaletteItem { } @Nullable public Object getData(Project project, String dataId) { - if (dataId.equals(DataConstants.PSI_ELEMENT)) { + if (LangDataKeys.PSI_ELEMENT.is(dataId)) { return JavaPsiFacade.getInstance(project).findClass(myClassName, GlobalSearchScope.allScope(project)); } - if (dataId.equals(getClass().getName())) { + if (getClass().getName().equals(dataId)) { return this; } - if (dataId.equals(GroupItem.class.getName())) { + if (GroupItem.DATA_KEY.is(dataId)) { return Palette.getInstance(project).findGroup(this); } return null; diff --git a/plugins/ui-designer/src/com/intellij/uiDesigner/palette/EditGroupAction.java b/plugins/ui-designer/src/com/intellij/uiDesigner/palette/EditGroupAction.java index 392df3666be6..b882b9cfd2d3 100644 --- a/plugins/ui-designer/src/com/intellij/uiDesigner/palette/EditGroupAction.java +++ b/plugins/ui-designer/src/com/intellij/uiDesigner/palette/EditGroupAction.java @@ -32,7 +32,7 @@ import java.util.ArrayList; public class EditGroupAction extends AnAction { public void actionPerformed(AnActionEvent e) { Project project = PlatformDataKeys.PROJECT.getData(e.getDataContext()); - GroupItem groupToBeEdited = (GroupItem)e.getDataContext().getData(GroupItem.class.getName()); + GroupItem groupToBeEdited = GroupItem.DATA_KEY.getData(e.getDataContext()); if (groupToBeEdited == null || project == null) return; // Ask group name @@ -64,7 +64,7 @@ public class EditGroupAction extends AnAction { @Override public void update(AnActionEvent e) { Project project = PlatformDataKeys.PROJECT.getData(e.getDataContext()); - GroupItem groupItem = (GroupItem) e.getDataContext().getData(GroupItem.class.getName()); + GroupItem groupItem = GroupItem.DATA_KEY.getData(e.getDataContext()); e.getPresentation().setEnabled(project != null && groupItem != null && !groupItem.isReadOnly()); } } diff --git a/plugins/ui-designer/src/com/intellij/uiDesigner/projectView/FormMergerTreeStructureProvider.java b/plugins/ui-designer/src/com/intellij/uiDesigner/projectView/FormMergerTreeStructureProvider.java index a81829539182..4fdc1140064c 100644 --- a/plugins/ui-designer/src/com/intellij/uiDesigner/projectView/FormMergerTreeStructureProvider.java +++ b/plugins/ui-designer/src/com/intellij/uiDesigner/projectView/FormMergerTreeStructureProvider.java @@ -22,7 +22,6 @@ import com.intellij.ide.projectView.ViewSettings; import com.intellij.ide.projectView.impl.nodes.BasePsiNode; import com.intellij.ide.util.DeleteHandler; import com.intellij.ide.util.treeView.AbstractTreeNode; -import com.intellij.openapi.actionSystem.DataConstants; import com.intellij.openapi.actionSystem.DataContext; import com.intellij.openapi.actionSystem.PlatformDataKeys; import com.intellij.openapi.fileTypes.StdFileTypes; @@ -103,14 +102,14 @@ public class FormMergerTreeStructureProvider implements TreeStructureProvider { return result.toArray(new Form[result.size()]); } } - else if (dataId.equals(DataConstants.DELETE_ELEMENT_PROVIDER)) { + else if (PlatformDataKeys.DELETE_ELEMENT_PROVIDER.is(dataId)) { for(AbstractTreeNode node: selected) { if (node.getValue() instanceof Form) { return new MyDeleteProvider(selected); } } } - else if (dataId.equals(MoveAction.MOVE_PROVIDER)) { + else if (MoveAction.MoveProvider.DATA_KEY.is(dataId)) { for(AbstractTreeNode node: selected) { if (node.getValue() instanceof Form) { return new FormMoveProvider(); diff --git a/plugins/ui-designer/src/com/intellij/uiDesigner/projectView/FormMoveProvider.java b/plugins/ui-designer/src/com/intellij/uiDesigner/projectView/FormMoveProvider.java index 851a7ea087af..743f334efcf7 100644 --- a/plugins/ui-designer/src/com/intellij/uiDesigner/projectView/FormMoveProvider.java +++ b/plugins/ui-designer/src/com/intellij/uiDesigner/projectView/FormMoveProvider.java @@ -14,16 +14,10 @@ * limitations under the License. */ -/* - * Created by IntelliJ IDEA. - * User: yole - * Date: 03.08.2006 - * Time: 15:31:45 - */ package com.intellij.uiDesigner.projectView; import com.intellij.openapi.actionSystem.DataContext; -import com.intellij.openapi.actionSystem.ex.DataConstantsEx; +import com.intellij.openapi.actionSystem.LangDataKeys; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.project.Project; @@ -44,6 +38,9 @@ import com.intellij.util.IncorrectOperationException; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +/** + * @author yole + */ public class FormMoveProvider implements MoveAction.MoveProvider, RefactoringActionHandler { private static final Logger LOG = Logger.getInstance("#com.intellij.uiDesigner.projectView.FormMoveProvider"); @@ -70,7 +67,7 @@ public class FormMoveProvider implements MoveAction.MoveProvider, RefactoringAct filesToMove [i] = forms [i].getFormFiles() [0]; } - final PsiElement initialTargetElement = (PsiElement)dataContext.getData(DataConstantsEx.TARGET_PSI_ELEMENT); + final PsiElement initialTargetElement = LangDataKeys.TARGET_PSI_ELEMENT.getData(dataContext); MoveClassesOrPackagesImpl.doMove(project, classesToMove, initialTargetElement, new FormMoveCallback(filesToMove, classesToMove)); } diff --git a/plugins/ui-designer/src/com/intellij/uiDesigner/propertyInspector/PropertyInspectorTable.java b/plugins/ui-designer/src/com/intellij/uiDesigner/propertyInspector/PropertyInspectorTable.java index 869ce92433f3..98d10ddddb9a 100644 --- a/plugins/ui-designer/src/com/intellij/uiDesigner/propertyInspector/PropertyInspectorTable.java +++ b/plugins/ui-designer/src/com/intellij/uiDesigner/propertyInspector/PropertyInspectorTable.java @@ -78,6 +78,8 @@ import java.util.List; public final class PropertyInspectorTable extends Table implements DataProvider{ private static final Logger LOG = Logger.getInstance("#com.intellij.uiDesigner.propertyInspector.PropertyInspectorTable"); + public static final DataKey DATA_KEY = DataKey.create(PropertyInspectorTable.class.getName()); + private static final Color SYNTETIC_PROPERTY_BACKGROUND = new Color(230,230,230); private static final Color SYNTETIC_SUBPROPERTY_BACKGROUND = new Color(240,240,240); @@ -213,7 +215,7 @@ public final class PropertyInspectorTable extends Table implements DataProvider{ if(getClass().getName().equals(dataId)){ return this; } - else if(DataConstants.PSI_ELEMENT.equals(dataId)){ + else if(LangDataKeys.PSI_ELEMENT.is(dataId)){ final IntrospectedProperty introspectedProperty = getSelectedIntrospectedProperty(); if(introspectedProperty == null){ return null; @@ -230,16 +232,16 @@ public final class PropertyInspectorTable extends Table implements DataProvider{ return PropertyUtil.findPropertySetter(aClass, introspectedProperty.getName(), false, true); } - else if (DataConstants.PSI_FILE.equals(dataId) && myEditor != null) { + else if (LangDataKeys.PSI_FILE.is(dataId) && myEditor != null) { return PsiManager.getInstance(myEditor.getProject()).findFile(myEditor.getFile()); } - else if (GuiEditor.class.getName().equals(dataId)) { + else if (GuiEditor.DATA_KEY.is(dataId)) { return myEditor; } - else if (DataConstants.FILE_EDITOR.equals(dataId)) { + else if (PlatformDataKeys.FILE_EDITOR.is(dataId)) { return UIDesignerToolWindowManager.getInstance(myProject).getActiveFormFileEditor(); } - else if (DataConstants.HELP_ID.equals(dataId)) { + else if (PlatformDataKeys.HELP_ID.is(dataId)) { return ourHelpID; } else { diff --git a/plugins/ui-designer/src/com/intellij/uiDesigner/propertyInspector/UIDesignerToolWindowManager.java b/plugins/ui-designer/src/com/intellij/uiDesigner/propertyInspector/UIDesignerToolWindowManager.java index 5b68d47f0ddc..9ab7da6dda11 100644 --- a/plugins/ui-designer/src/com/intellij/uiDesigner/propertyInspector/UIDesignerToolWindowManager.java +++ b/plugins/ui-designer/src/com/intellij/uiDesigner/propertyInspector/UIDesignerToolWindowManager.java @@ -219,7 +219,7 @@ public class UIDesignerToolWindowManager implements ProjectComponent { @Nullable public Object getData(@NonNls String dataId) { - if (dataId.equals(GuiEditor.class.getName())) { + if (GuiEditor.DATA_KEY.is(dataId)) { return getActiveFormEditor(); } return null; diff --git a/plugins/xpath/xpath-lang/src/org/intellij/lang/xpath/xslt/quickfix/AbstractFix.java b/plugins/xpath/xpath-lang/src/org/intellij/lang/xpath/xslt/quickfix/AbstractFix.java index 42f32db81986..8b570cd8205d 100644 --- a/plugins/xpath/xpath-lang/src/org/intellij/lang/xpath/xslt/quickfix/AbstractFix.java +++ b/plugins/xpath/xpath-lang/src/org/intellij/lang/xpath/xslt/quickfix/AbstractFix.java @@ -21,6 +21,7 @@ import com.intellij.codeInsight.template.TemplateBuilderImpl; import com.intellij.codeInspection.LocalQuickFix; import com.intellij.codeInspection.ProblemDescriptor; import com.intellij.ide.DataManager; +import com.intellij.openapi.actionSystem.DataContext; import com.intellij.openapi.actionSystem.LangDataKeys; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.editor.Editor; @@ -38,90 +39,98 @@ import com.intellij.util.containers.ContainerUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import java.util.List; + public abstract class AbstractFix implements IntentionAction { - @NotNull - public String getFamilyName() { - final String name = getClass().getSimpleName(); - return "XSLT " + name.replaceAll("Fix$", "").replaceAll("(\\p{Lower}+)(\\p{Upper})", "$1 $2"); - } + @NotNull + public String getFamilyName() { + final String name = getClass().getSimpleName(); + return "XSLT " + name.replaceAll("Fix$", "").replaceAll("(\\p{Lower}+)(\\p{Upper})", "$1 $2"); + } - public boolean startInWriteAction() { - return true; - } + public boolean startInWriteAction() { + return true; + } - protected static void moveTo(Editor editor, XmlTag xmlTag) { - editor.getCaretModel().moveToOffset(xmlTag.getTextRange().getStartOffset()); - } + protected static void moveTo(Editor editor, XmlTag xmlTag) { + editor.getCaretModel().moveToOffset(xmlTag.getTextRange().getStartOffset()); + } - protected static void deleteFromDocument(Editor editor, PsiElement dummy) { - editor.getDocument().deleteString(dummy.getTextRange().getStartOffset(), dummy.getTextRange().getEndOffset()); - } + protected static void deleteFromDocument(Editor editor, PsiElement dummy) { + editor.getDocument().deleteString(dummy.getTextRange().getStartOffset(), dummy.getTextRange().getEndOffset()); + } - protected static TemplateBuilderImpl createTemplateBuilder(XmlTag xmlTag) { - final PsiFile psiFile = PsiFileFactory.getInstance(xmlTag.getProject()).createFileFromText("dummy.xml", StdFileTypes.XML, xmlTag.getText(), LocalTimeCounter.currentTime(), true, false); - return new TemplateBuilderImpl(psiFile); - } + protected static TemplateBuilderImpl createTemplateBuilder(XmlTag xmlTag) { + final PsiFile psiFile = PsiFileFactory.getInstance(xmlTag.getProject()) + .createFileFromText("dummy.xml", StdFileTypes.XML, xmlTag.getText(), LocalTimeCounter.currentTime(), true, false); + return new TemplateBuilderImpl(psiFile); + } - public final boolean isAvailable(@NotNull Project project, Editor editor, PsiFile file) { - if (requiresEditor() && editor == null) return false; - - return isAvailableImpl(project, editor, file); - } + public final boolean isAvailable(@NotNull Project project, Editor editor, PsiFile file) { + if (requiresEditor() && editor == null) return false; - protected abstract boolean isAvailableImpl(@NotNull Project project, @Nullable Editor editor, PsiFile file); + return isAvailableImpl(project, editor, file); + } - protected abstract boolean requiresEditor(); + protected abstract boolean isAvailableImpl(@NotNull Project project, @Nullable Editor editor, PsiFile file); - @Nullable - public LocalQuickFix createQuickFix(boolean isOnTheFly) { - final boolean requiresEditor = requiresEditor(); - if (requiresEditor && !isOnTheFly) return null; + protected abstract boolean requiresEditor(); - return new LocalQuickFix() { - @NotNull - public String getName() { - return AbstractFix.this.getText(); + @Nullable + public LocalQuickFix createQuickFix(boolean isOnTheFly) { + final boolean requiresEditor = requiresEditor(); + if (requiresEditor && !isOnTheFly) return null; + + return new LocalQuickFix() { + @NotNull + public String getName() { + return AbstractFix.this.getText(); + } + + @NotNull + public String getFamilyName() { + return AbstractFix.this.getFamilyName(); + } + + public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) { + Editor editor; + if (requiresEditor) { + final DataContext dataContext = DataManager.getInstance().getDataContext(); + + editor = LangDataKeys.EDITOR.getData(dataContext); + if (editor == null) { + if ((editor = FileEditorManager.getInstance(project).getSelectedTextEditor()) == null) { + return; } + } + } + else { + editor = null; + } - @NotNull - public String getFamilyName() { - return AbstractFix.this.getFamilyName(); - } + final PsiFile psiFile = descriptor.getPsiElement().getContainingFile(); + if (!isAvailable(project, editor, psiFile)) { + return; + } + if (!CodeInsightUtilBase.prepareFileForWrite(psiFile)) { + return; + } + try { + invoke(project, editor, psiFile); + } + catch (IncorrectOperationException e) { + Logger.getInstance(getClass().getName()).error(e); + } + } + }; + } - public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) { - Editor editor; - if (requiresEditor) { - editor = (Editor)DataManager.getInstance().getDataContext().getData(LangDataKeys.EDITOR.getName()); - if (editor == null) { - if ((editor = FileEditorManager.getInstance(project).getSelectedTextEditor()) == null) { - return; - } - } - } else { - editor = null; - } - - final PsiFile psiFile = descriptor.getPsiElement().getContainingFile(); - if (!isAvailable(project, editor, psiFile)) { - return; - } - if(!CodeInsightUtilBase.prepareFileForWrite(psiFile)) { - return; - } - try { - invoke(project, editor, psiFile); - } catch (IncorrectOperationException e) { - Logger.getInstance(getClass().getName()).error(e); - } - } - }; - } - - public static LocalQuickFix[] createFixes(LocalQuickFix... fixes) { - return ContainerUtil.findAll(fixes, new Condition() { - public boolean value(LocalQuickFix localQuickFix) { - return localQuickFix != null; - } - }).toArray(LocalQuickFix.EMPTY_ARRAY); - } + public static LocalQuickFix[] createFixes(LocalQuickFix... fixes) { + final List result = ContainerUtil.findAll(fixes, new Condition() { + public boolean value(LocalQuickFix localQuickFix) { + return localQuickFix != null; + } + }); + return result.toArray(new LocalQuickFix[result.size()]); + } } \ No newline at end of file diff --git a/xml/dom-impl/src/com/intellij/util/xml/tree/actions/AddElementInCollectionAction.java b/xml/dom-impl/src/com/intellij/util/xml/tree/actions/AddElementInCollectionAction.java index f8d9c21d8897..1d551c15b052 100644 --- a/xml/dom-impl/src/com/intellij/util/xml/tree/actions/AddElementInCollectionAction.java +++ b/xml/dom-impl/src/com/intellij/util/xml/tree/actions/AddElementInCollectionAction.java @@ -26,9 +26,9 @@ import com.intellij.psi.xml.XmlFile; import com.intellij.ui.treeStructure.SimpleNode; import com.intellij.util.ReflectionUtil; import com.intellij.util.xml.DomElement; +import com.intellij.util.xml.DomUtil; import com.intellij.util.xml.MergedObject; import com.intellij.util.xml.TypeNameManager; -import com.intellij.util.xml.DomUtil; import com.intellij.util.xml.reflect.DomCollectionChildDescription; import com.intellij.util.xml.tree.BaseDomElementNode; import com.intellij.util.xml.tree.DomElementsGroupNode; @@ -58,7 +58,7 @@ public class AddElementInCollectionAction extends AddDomElementAction { protected DomModelTreeView getTreeView(AnActionEvent e) { if (myTreeView != null) return myTreeView; - return (DomModelTreeView)e.getDataContext().getData(DomModelTreeView.DOM_MODEL_TREE_VIEW_KEY); + return DomModelTreeView.DATA_KEY.getData(e.getDataContext()); } protected boolean isEnabled(final AnActionEvent e) { @@ -93,7 +93,7 @@ public class AddElementInCollectionAction extends AddDomElementAction { if (node instanceof BaseDomElementNode) { List consolidated = ((BaseDomElementNode)node).getConsolidatedChildrenDescriptions(); if (consolidated.size() > 0) { - return consolidated.toArray(DomCollectionChildDescription.EMPTY_ARRAY); + return consolidated.toArray(new DomCollectionChildDescription[consolidated.size()]); } } diff --git a/xml/dom-impl/src/com/intellij/util/xml/tree/actions/BaseDomTreeAction.java b/xml/dom-impl/src/com/intellij/util/xml/tree/actions/BaseDomTreeAction.java index c59a8ec1dfda..81d5ef356d11 100644 --- a/xml/dom-impl/src/com/intellij/util/xml/tree/actions/BaseDomTreeAction.java +++ b/xml/dom-impl/src/com/intellij/util/xml/tree/actions/BaseDomTreeAction.java @@ -23,8 +23,8 @@ import com.intellij.util.xml.tree.DomModelTreeView; /** * User: Sergey.Vasiliev */ -abstract public class BaseDomTreeAction extends AnAction { -private DomModelTreeView myTreeView; +abstract public class BaseDomTreeAction extends AnAction { + private DomModelTreeView myTreeView; protected BaseDomTreeAction() { } @@ -47,7 +47,7 @@ private DomModelTreeView myTreeView; protected DomModelTreeView getTreeView(AnActionEvent e) { if (myTreeView != null) return myTreeView; - return (DomModelTreeView)e.getDataContext().getData(DomModelTreeView.DOM_MODEL_TREE_VIEW_KEY); + return DomModelTreeView.DATA_KEY.getData(e.getDataContext()); } final public void actionPerformed(AnActionEvent e) { @@ -59,6 +59,6 @@ private DomModelTreeView myTreeView; public abstract void actionPerformed(AnActionEvent e, DomModelTreeView treeView); - public abstract void update(AnActionEvent e, DomModelTreeView treeView); + public abstract void update(AnActionEvent e, DomModelTreeView treeView); } diff --git a/xml/dom-openapi/src/com/intellij/util/xml/tree/DomModelTreeView.java b/xml/dom-openapi/src/com/intellij/util/xml/tree/DomModelTreeView.java index ae54e9f5407a..9f17824657ef 100644 --- a/xml/dom-openapi/src/com/intellij/util/xml/tree/DomModelTreeView.java +++ b/xml/dom-openapi/src/com/intellij/util/xml/tree/DomModelTreeView.java @@ -16,6 +16,7 @@ package com.intellij.util.xml.tree; +import com.intellij.ide.util.treeView.AbstractTreeBuilder; import com.intellij.openapi.Disposable; import com.intellij.openapi.actionSystem.*; import com.intellij.openapi.application.ApplicationManager; @@ -26,13 +27,15 @@ import com.intellij.pom.Navigatable; import com.intellij.psi.xml.XmlElement; import com.intellij.psi.xml.XmlFile; import com.intellij.ui.components.panels.Wrapper; -import com.intellij.ui.treeStructure.*; +import com.intellij.ui.treeStructure.SimpleNode; +import com.intellij.ui.treeStructure.SimpleTree; +import com.intellij.ui.treeStructure.SimpleTreeStructure; +import com.intellij.ui.treeStructure.WeightBasedComparator; import com.intellij.ui.treeStructure.actions.CollapseAllAction; import com.intellij.ui.treeStructure.actions.ExpandAllAction; import com.intellij.util.ui.tree.TreeUtil; import com.intellij.util.xml.*; import com.intellij.util.xml.highlighting.DomElementAnnotationsManager; -import com.intellij.ide.util.treeView.AbstractTreeBuilder; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -46,8 +49,8 @@ import javax.swing.tree.TreeSelectionModel; import java.awt.*; public class DomModelTreeView extends Wrapper implements DataProvider, Disposable { - - @NonNls public static String DOM_MODEL_TREE_VIEW_KEY = "DOM_MODEL_TREE_VIEW_KEY"; + public static final DataKey DATA_KEY = DataKey.create("DOM_MODEL_TREE_VIEW_KEY"); + @Deprecated @NonNls public static String DOM_MODEL_TREE_VIEW_KEY = DATA_KEY.getName(); @NonNls public static String DOM_MODEL_TREE_VIEW_POPUP = "DOM_MODEL_TREE_VIEW_POPUP"; private final SimpleTree myTree; @@ -180,14 +183,14 @@ public class DomModelTreeView extends Wrapper implements DataProvider, Disposabl @Nullable public Object getData(String dataId) { - if (DOM_MODEL_TREE_VIEW_KEY.equals(dataId)) { + if (DomModelTreeView.DATA_KEY.is(dataId)) { return this; } final SimpleNode simpleNode = getTree().getSelectedNode(); if (simpleNode instanceof AbstractDomElementNode) { final DomElement domElement = ((AbstractDomElementNode)simpleNode).getDomElement(); if (domElement != null && domElement.isValid()) { - if (DataConstants.NAVIGATABLE_ARRAY.equals(dataId)) { + if (PlatformDataKeys.NAVIGATABLE_ARRAY.is(dataId)) { final XmlElement tag = domElement.getXmlElement(); if (tag instanceof Navigatable) { return new Navigatable[] { (Navigatable)tag }; diff --git a/xml/impl/src/com/intellij/xml/actions/ValidateXmlAction.java b/xml/impl/src/com/intellij/xml/actions/ValidateXmlAction.java index 9737bfab3335..98e182c48b93 100644 --- a/xml/impl/src/com/intellij/xml/actions/ValidateXmlAction.java +++ b/xml/impl/src/com/intellij/xml/actions/ValidateXmlAction.java @@ -51,7 +51,10 @@ public class ValidateXmlAction extends AnAction { } public void actionPerformed(AnActionEvent e) { - doRunAction(LangDataKeys.PSI_FILE.getData(e.getDataContext())); + final PsiFile psiFile = LangDataKeys.PSI_FILE.getData(e.getDataContext()); + if (psiFile != null) { + doRunAction(psiFile); + } } private void doRunAction(final @NotNull PsiFile psiFile) { @@ -86,7 +89,7 @@ public class ValidateXmlAction extends AnAction { super.update(event); Presentation presentation = event.getPresentation(); - PsiElement psiElement = (PsiElement)event.getDataContext().getData(DataConstants.PSI_FILE); + PsiElement psiElement = LangDataKeys.PSI_FILE.getData(event.getDataContext()); boolean flag = psiElement instanceof XmlFile; presentation.setVisible(flag); From 3b10d5408045d407169a6b76bf9bd53248224275 Mon Sep 17 00:00:00 2001 From: Alexey Kudravtsev Date: Mon, 28 Dec 2009 18:18:54 +0300 Subject: [PATCH 33/67] additional assertion --- .../impl/source/tree/CompositeElement.java | 5 +++- .../psi/impl/source/tree/TreeElement.java | 24 +++++++++++-------- 2 files changed, 18 insertions(+), 11 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/psi/impl/source/tree/CompositeElement.java b/platform/lang-impl/src/com/intellij/psi/impl/source/tree/CompositeElement.java index 6d1ce9c16f3b..8c8e2f868ae4 100644 --- a/platform/lang-impl/src/com/intellij/psi/impl/source/tree/CompositeElement.java +++ b/platform/lang-impl/src/com/intellij/psi/impl/source/tree/CompositeElement.java @@ -350,7 +350,9 @@ public class CompositeElement extends TreeElement { // up while (cur != this) { CompositeElement parent = cur.getTreeParent(); - parent.myCachedLength -= cur.getCachedLength(); + int curLength = cur.getCachedLength(); + LOG.assertTrue(curLength != NOT_CACHED, cur); + parent.myCachedLength -= curLength; TreeElement next = cur.getTreeNext(); if (next != null) { @@ -358,6 +360,7 @@ public class CompositeElement extends TreeElement { return next; } + LOG.assertTrue(parent.lastChild == cur, parent); parent.myCachedLength = -parent.myCachedLength + NOT_CACHED; cur = parent; diff --git a/platform/lang-impl/src/com/intellij/psi/impl/source/tree/TreeElement.java b/platform/lang-impl/src/com/intellij/psi/impl/source/tree/TreeElement.java index a39e4cb2330a..6a7d807b868e 100644 --- a/platform/lang-impl/src/com/intellij/psi/impl/source/tree/TreeElement.java +++ b/platform/lang-impl/src/com/intellij/psi/impl/source/tree/TreeElement.java @@ -35,7 +35,7 @@ public abstract class TreeElement extends ElementBase implements ASTNode, Clonea private final IElementType myType; private volatile int myStartOffsetInParent = -1; - protected static final String START_OFFSET_LOCK = new String("TreeElement.START_OFFSET_LOCK"); + @NonNls protected static final String START_OFFSET_LOCK = new String("TreeElement.START_OFFSET_LOCK"); public TreeElement(IElementType type) { myType = type; @@ -99,31 +99,34 @@ public abstract class TreeElement extends ElementBase implements ASTNode, Clonea public final int getStartOffsetInParent() { if (myParent == null) return -1; - int offset = myStartOffsetInParent; - if (offset != -1) return offset; + int offsetInParent = myStartOffsetInParent; + if (offsetInParent != -1) return offsetInParent; synchronized (START_OFFSET_LOCK) { TreeElement cur = this; + offsetInParent = myStartOffsetInParent; + if (offsetInParent != -1) return offsetInParent; while (true) { - if (cur.myStartOffsetInParent != -1) break; TreeElement prev = cur.getTreePrev(); if (prev == null) break; cur = prev; + offsetInParent = cur.myStartOffsetInParent; + if (offsetInParent != -1) break; } - if (cur.myStartOffsetInParent == -1) { - cur.myStartOffsetInParent = 0; + if (offsetInParent == -1) { + cur.myStartOffsetInParent = offsetInParent = 0; } while (cur != this) { TreeElement next = cur.getTreeNext(); - next.myStartOffsetInParent = cur.myStartOffsetInParent + cur.getTextLength(); + offsetInParent += cur.getTextLength(); + next.myStartOffsetInParent = offsetInParent; cur = next; } - return myStartOffsetInParent; + return offsetInParent; } - } public int getTextOffset() { @@ -186,6 +189,7 @@ public abstract class TreeElement extends ElementBase implements ASTNode, Clonea public void clearCaches() { } + @SuppressWarnings({"EqualsWhichDoesntCheckParameterClass"}) public final boolean equals(Object obj) { return obj == this; } @@ -202,7 +206,7 @@ public abstract class TreeElement extends ElementBase implements ASTNode, Clonea if (DebugUtil.shouldTrackInvalidation()) { final Boolean trackInvalidation = getUserData(DebugUtil.TRACK_INVALIDATION_KEY); if (trackInvalidation != null && trackInvalidation) { - //noinspection HardCodedStringLiteral + //noinspection HardCodedStringLiteral,ThrowableInstanceNeverThrown,CallToPrintStackTrace new Throwable("Element invalidated:" + this).printStackTrace(); } } From bf1297bb7fd6a39b6e906f48f6d6a518a645a05b Mon Sep 17 00:00:00 2001 From: Alexey Kudravtsev Date: Tue, 29 Dec 2009 10:26:52 +0300 Subject: [PATCH 34/67] project leak --- .../intellij/find/EditorSearchComponent.java | 28 +++++++++++-------- 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/find/EditorSearchComponent.java b/platform/lang-impl/src/com/intellij/find/EditorSearchComponent.java index 2c25d1895ef1..d8c9f6a532b2 100644 --- a/platform/lang-impl/src/com/intellij/find/EditorSearchComponent.java +++ b/platform/lang-impl/src/com/intellij/find/EditorSearchComponent.java @@ -285,19 +285,11 @@ public class EditorSearchComponent extends JPanel implements DataProvider { }); new VariantsCompletionAction(); // It registers a shortcut set automatically on construction - - myDocumentListener = new com.intellij.openapi.editor.event.DocumentAdapter() { - public void documentChanged(final com.intellij.openapi.editor.event.DocumentEvent e) { - updateResults(false); - } - }; - - myEditor.getDocument().addDocumentListener(myDocumentListener); } public void setInitialText(final String initialText) { final String text = initialText != null ? initialText : ""; - if (text.indexOf("\n") >= 0) { + if (text.contains("\n")) { setRegexp(true); setTextInField(StringUtil.escapeToRegexp(text)); } @@ -374,6 +366,19 @@ public class EditorSearchComponent extends JPanel implements DataProvider { addCurrentTextToRecents(); } + @Override + public void addNotify() { + super.addNotify(); + + myDocumentListener = new com.intellij.openapi.editor.event.DocumentAdapter() { + public void documentChanged(final com.intellij.openapi.editor.event.DocumentEvent e) { + updateResults(false); + } + }; + + myEditor.getDocument().addDocumentListener(myDocumentListener); + } + public void removeNotify() { super.removeNotify(); @@ -453,7 +458,7 @@ public class EditorSearchComponent extends JPanel implements DataProvider { if (count > 0) { setRegularBackground(); if (count > 1) { - myMatchInfoLabel.setText("" + count + " matches"); + myMatchInfoLabel.setText(count + " matches"); } else { myMatchInfoLabel.setText("1 match"); @@ -529,8 +534,7 @@ public class EditorSearchComponent extends JPanel implements DataProvider { } private boolean findAndSelectFirstUsage(final FindManager findManager, final FindModel model, final int offset, VirtualFile file) { - final FindResult firstResult; - firstResult = findManager.findString(myEditor.getDocument().getCharsSequence(), offset, model, file); + final FindResult firstResult = findManager.findString(myEditor.getDocument().getCharsSequence(), offset, model, file); if (firstResult.isStringFound()) { myEditor.getSelectionModel().setSelection(firstResult.getStartOffset(), firstResult.getEndOffset()); From 0d2d3b8bfcb791acf8336f2a07a6acf916e1adaa Mon Sep 17 00:00:00 2001 From: Dmitry Avdeev Date: Tue, 29 Dec 2009 10:43:12 +0300 Subject: [PATCH 35/67] avoid direct namespace mapping for facelets --- xml/impl/src/com/intellij/xml/util/XmlUtil.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/xml/impl/src/com/intellij/xml/util/XmlUtil.java b/xml/impl/src/com/intellij/xml/util/XmlUtil.java index e7297e1ec1ba..91da28124537 100644 --- a/xml/impl/src/com/intellij/xml/util/XmlUtil.java +++ b/xml/impl/src/com/intellij/xml/util/XmlUtil.java @@ -32,7 +32,6 @@ import com.intellij.openapi.extensions.Extensions; import com.intellij.openapi.fileTypes.FileType; import com.intellij.openapi.fileTypes.StdFileTypes; import com.intellij.openapi.module.Module; -import com.intellij.openapi.module.ModuleUtil; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Key; import com.intellij.openapi.util.Pair; @@ -100,9 +99,9 @@ public class XmlUtil { @NonNls public static final String JSP_URI = "http://java.sun.com/JSP/Page"; @NonNls public static final String ANY_URI = "http://www.intellij.net/ns/any"; - @NonNls private static final String JSTL_CORE_URI = "http://java.sun.com/jsp/jstl/core"; - @NonNls private static final String JSTL_CORE_URI2 = "http://java.sun.com/jstl/core"; - @NonNls private static final String JSTL_CORE_URI3 = "http://java.sun.com/jstl/core_rt"; + @NonNls public static final String JSTL_CORE_URI = "http://java.sun.com/jsp/jstl/core"; + @NonNls public static final String JSTL_CORE_URI2 = "http://java.sun.com/jstl/core"; + @NonNls public static final String JSTL_CORE_URI3 = "http://java.sun.com/jstl/core_rt"; @NonNls public static final String[] JSTL_CORE_URIS = {JSTL_CORE_URI, JSTL_CORE_URI2, JSTL_CORE_URI3}; @NonNls public static final String JSF_HTML_URI = "http://java.sun.com/jsf/html"; @@ -137,6 +136,7 @@ public class XmlUtil { "http://java.sun.com/j2ee/dtds/web-app_2_2.dtd"}; @NonNls public static final String FACELETS_URI = "http://java.sun.com/jsf/facelets"; @NonNls public static final String JSTL_FUNCTIONS_URI = "http://java.sun.com/jsp/jstl/functions"; + @NonNls public static final String JSTL_FUNCTIONS_URI2 = "http://java.sun.com/jstl/functions"; @NonNls public static final String JSTL_FN_FACELET_URI = "com.sun.facelets.tag.jstl.fn.JstlFnLibrary"; @NonNls public static final String JSTL_CORE_FACELET_URI = "com.sun.facelets.tag.jstl.core.JstlCoreLibrary"; @NonNls public static final String TARGET_NAMESPACE_ATTR_NAME = "targetNamespace"; From 00d794dda5c26e27dd4c3a6802ed015ae8978ba3 Mon Sep 17 00:00:00 2001 From: Dmitry Avdeev Date: Tue, 29 Dec 2009 12:36:42 +0300 Subject: [PATCH 36/67] UnresolvedReferenceQuickFixProvider generalized --- .../daemon/impl/analysis/HighlightUtil.java | 16 ++-------- .../quickfix/DefaultQuickFixProvider.java | 8 ++++- .../UnresolvedReferenceQuickFixProvider.java | 31 ++++++++++++++++--- .../ResolveReferenceQuickFixProvider.java | 11 +++++-- 4 files changed, 44 insertions(+), 22 deletions(-) diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightUtil.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightUtil.java index 1884d46fd5a3..4c2731c6ca0e 100644 --- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightUtil.java +++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightUtil.java @@ -23,21 +23,18 @@ package com.intellij.codeInsight.daemon.impl.analysis; import com.intellij.codeInsight.ExceptionUtil; import com.intellij.codeInsight.daemon.JavaErrorMessages; -import com.intellij.codeInsight.daemon.QuickFixActionRegistrar; import com.intellij.codeInsight.daemon.impl.HighlightInfo; import com.intellij.codeInsight.daemon.impl.HighlightInfoType; import com.intellij.codeInsight.daemon.impl.quickfix.*; import com.intellij.codeInsight.highlighting.HighlightUsagesDescriptionLocation; import com.intellij.codeInsight.intention.IntentionAction; import com.intellij.codeInsight.intention.QuickFixFactory; -import com.intellij.codeInsight.quickfix.UnresolvedReferenceQuickFixProvider; import com.intellij.codeInsight.quickfix.ChangeVariableTypeQuickFixProvider; +import com.intellij.codeInsight.quickfix.UnresolvedReferenceQuickFixProvider; import com.intellij.lang.StdLanguages; import com.intellij.lang.findUsages.LanguageFindUsages; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.extensions.Extensions; -import com.intellij.openapi.project.DumbAware; -import com.intellij.openapi.project.DumbService; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Comparing; import com.intellij.openapi.util.Key; @@ -1873,17 +1870,8 @@ public class HighlightUtil { if (PsiUtil.isInsideJavadocComment(ref)) return null; HighlightInfo info = HighlightInfo.createHighlightInfo(type, refName, description); - QuickFixActionRegistrar registrar = new QuickFixActionRegistrarImpl(info); - - final boolean dumb = DumbService.getInstance(ref.getProject()).isDumb(); - UnresolvedReferenceQuickFixProvider[] fixProviders = Extensions.getExtensions(UnresolvedReferenceQuickFixProvider.EXTENSION_NAME); - for (UnresolvedReferenceQuickFixProvider each : fixProviders) { - if (dumb && !(each instanceof DumbAware)) { - continue; - } - each.registerFixes(ref, registrar); - } + UnresolvedReferenceQuickFixProvider.registerFixes(ref, new QuickFixActionRegistrarImpl(info), PsiJavaCodeReferenceElement.class); return info; } diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/DefaultQuickFixProvider.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/DefaultQuickFixProvider.java index f8f7ec256651..8f27e8c151a2 100644 --- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/DefaultQuickFixProvider.java +++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/DefaultQuickFixProvider.java @@ -22,8 +22,9 @@ import com.intellij.openapi.util.TextRange; import com.intellij.psi.*; import com.intellij.psi.util.PsiTreeUtil; import com.intellij.psi.util.PsiUtil; +import org.jetbrains.annotations.NotNull; -public class DefaultQuickFixProvider implements UnresolvedReferenceQuickFixProvider{ +public class DefaultQuickFixProvider extends UnresolvedReferenceQuickFixProvider { public void registerFixes(PsiJavaCodeReferenceElement ref, QuickFixActionRegistrar registrar) { registrar.register(new ImportClassFix(ref)); registrar.register(SetupJDKFix.getInstnace()); @@ -60,4 +61,9 @@ public class DefaultQuickFixProvider implements UnresolvedReferenceQuickFixProvi registrar.register(new CreateInnerClassFromUsageFix(ref, CreateClassKind.CLASS)); } } + + @NotNull + public Class getReferenceClass() { + return PsiJavaCodeReferenceElement.class; + } } \ No newline at end of file diff --git a/java/openapi/src/com/intellij/codeInsight/quickfix/UnresolvedReferenceQuickFixProvider.java b/java/openapi/src/com/intellij/codeInsight/quickfix/UnresolvedReferenceQuickFixProvider.java index 7840700b2b7c..b3463f2f6592 100644 --- a/java/openapi/src/com/intellij/codeInsight/quickfix/UnresolvedReferenceQuickFixProvider.java +++ b/java/openapi/src/com/intellij/codeInsight/quickfix/UnresolvedReferenceQuickFixProvider.java @@ -15,14 +15,35 @@ */ package com.intellij.codeInsight.quickfix; -import com.intellij.openapi.extensions.ExtensionPointName; -import com.intellij.psi.PsiJavaCodeReferenceElement; import com.intellij.codeInsight.daemon.QuickFixActionRegistrar; +import com.intellij.openapi.extensions.ExtensionPointName; +import com.intellij.openapi.extensions.Extensions; +import com.intellij.openapi.project.DumbAware; +import com.intellij.openapi.project.DumbService; +import com.intellij.psi.PsiReference; +import org.jetbrains.annotations.NotNull; -public interface UnresolvedReferenceQuickFixProvider { - ExtensionPointName EXTENSION_NAME = +public abstract class UnresolvedReferenceQuickFixProvider { + + public static void registerFixes(T ref, QuickFixActionRegistrar registrar, Class refClass) { + + final boolean dumb = DumbService.getInstance(ref.getElement().getProject()).isDumb(); + UnresolvedReferenceQuickFixProvider[] fixProviders = Extensions.getExtensions(EXTENSION_NAME); + for (UnresolvedReferenceQuickFixProvider each : fixProviders) { + if (dumb && !(each instanceof DumbAware)) { + continue; + } + if (refClass.equals(each.getReferenceClass())) { + each.registerFixes(ref, registrar); + } + } + } + + private static final ExtensionPointName EXTENSION_NAME = ExtensionPointName.create("com.intellij.codeInsight.unresolvedReferenceQuickFixProvider"); + public abstract void registerFixes(T ref, QuickFixActionRegistrar registrar); - void registerFixes(PsiJavaCodeReferenceElement ref, QuickFixActionRegistrar registrar); + @NotNull + public abstract Class getReferenceClass(); } diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/intentions/ResolveReferenceQuickFixProvider.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/intentions/ResolveReferenceQuickFixProvider.java index 04a6a795473d..15cb9f90f780 100644 --- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/intentions/ResolveReferenceQuickFixProvider.java +++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/intentions/ResolveReferenceQuickFixProvider.java @@ -15,12 +15,19 @@ */ package org.jetbrains.idea.maven.dom.intentions; -import com.intellij.codeInsight.quickfix.UnresolvedReferenceQuickFixProvider; import com.intellij.codeInsight.daemon.QuickFixActionRegistrar; +import com.intellij.codeInsight.quickfix.UnresolvedReferenceQuickFixProvider; import com.intellij.psi.PsiJavaCodeReferenceElement; +import org.jetbrains.annotations.NotNull; + +public class ResolveReferenceQuickFixProvider extends UnresolvedReferenceQuickFixProvider { -public class ResolveReferenceQuickFixProvider implements UnresolvedReferenceQuickFixProvider{ public void registerFixes(PsiJavaCodeReferenceElement ref, QuickFixActionRegistrar registrar) { registrar.register(new AddMavenDependencyQuickFix(ref)); } + + @NotNull + public Class getReferenceClass() { + return PsiJavaCodeReferenceElement.class; + } } From dea1f9ac877f150f4059f3f2d5db71385ec8c5b3 Mon Sep 17 00:00:00 2001 From: Dmitry Avdeev Date: Tue, 29 Dec 2009 15:24:11 +0300 Subject: [PATCH 37/67] UnresolvedReferenceQuickFixProvider moved to platform --- .../codeInsight/daemon/impl/analysis/HighlightUtil.java | 2 +- .../quickfix/UnresolvedReferenceQuickFixProvider.java | 5 +++-- .../platform-resources/src/META-INF/LangExtensionPoints.xml | 4 ++++ resources/src/META-INF/IdeaPlugin.xml | 3 --- 4 files changed, 8 insertions(+), 6 deletions(-) rename {java/openapi => platform/lang-impl}/src/com/intellij/codeInsight/quickfix/UnresolvedReferenceQuickFixProvider.java (87%) diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightUtil.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightUtil.java index 4c2731c6ca0e..2702e4528645 100644 --- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightUtil.java +++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightUtil.java @@ -1871,7 +1871,7 @@ public class HighlightUtil { HighlightInfo info = HighlightInfo.createHighlightInfo(type, refName, description); - UnresolvedReferenceQuickFixProvider.registerFixes(ref, new QuickFixActionRegistrarImpl(info), PsiJavaCodeReferenceElement.class); + UnresolvedReferenceQuickFixProvider.registerReferenceFixes(ref, new QuickFixActionRegistrarImpl(info)); return info; } diff --git a/java/openapi/src/com/intellij/codeInsight/quickfix/UnresolvedReferenceQuickFixProvider.java b/platform/lang-impl/src/com/intellij/codeInsight/quickfix/UnresolvedReferenceQuickFixProvider.java similarity index 87% rename from java/openapi/src/com/intellij/codeInsight/quickfix/UnresolvedReferenceQuickFixProvider.java rename to platform/lang-impl/src/com/intellij/codeInsight/quickfix/UnresolvedReferenceQuickFixProvider.java index b3463f2f6592..9bcb5d6c474c 100644 --- a/java/openapi/src/com/intellij/codeInsight/quickfix/UnresolvedReferenceQuickFixProvider.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/quickfix/UnresolvedReferenceQuickFixProvider.java @@ -25,15 +25,16 @@ import org.jetbrains.annotations.NotNull; public abstract class UnresolvedReferenceQuickFixProvider { - public static void registerFixes(T ref, QuickFixActionRegistrar registrar, Class refClass) { + public static void registerReferenceFixes(T ref, QuickFixActionRegistrar registrar) { final boolean dumb = DumbService.getInstance(ref.getElement().getProject()).isDumb(); UnresolvedReferenceQuickFixProvider[] fixProviders = Extensions.getExtensions(EXTENSION_NAME); + Class referenceClass = ref.getClass(); for (UnresolvedReferenceQuickFixProvider each : fixProviders) { if (dumb && !(each instanceof DumbAware)) { continue; } - if (refClass.equals(each.getReferenceClass())) { + if (referenceClass.isAssignableFrom(each.getReferenceClass())) { each.registerFixes(ref, registrar); } } diff --git a/platform/platform-resources/src/META-INF/LangExtensionPoints.xml b/platform/platform-resources/src/META-INF/LangExtensionPoints.xml index 944a7ce14a7a..f444606a1525 100644 --- a/platform/platform-resources/src/META-INF/LangExtensionPoints.xml +++ b/platform/platform-resources/src/META-INF/LangExtensionPoints.xml @@ -37,6 +37,10 @@ + + + diff --git a/resources/src/META-INF/IdeaPlugin.xml b/resources/src/META-INF/IdeaPlugin.xml index 3114b28d7b71..d4bd8dc21166 100644 --- a/resources/src/META-INF/IdeaPlugin.xml +++ b/resources/src/META-INF/IdeaPlugin.xml @@ -18,9 +18,6 @@ - - From 59bfa97ae36a96c12794c56f7b3b4f6b7a6bc726 Mon Sep 17 00:00:00 2001 From: Dmitry Avdeev Date: Tue, 29 Dec 2009 15:34:47 +0300 Subject: [PATCH 38/67] IDEADEV-40843: "Enable facelets support" quickfix --- .../codeInsight/daemon/impl/analysis/XmlHighlightVisitor.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/xml/impl/src/com/intellij/codeInsight/daemon/impl/analysis/XmlHighlightVisitor.java b/xml/impl/src/com/intellij/codeInsight/daemon/impl/analysis/XmlHighlightVisitor.java index f29bb3a7b5a7..99d3beb3a403 100644 --- a/xml/impl/src/com/intellij/codeInsight/daemon/impl/analysis/XmlHighlightVisitor.java +++ b/xml/impl/src/com/intellij/codeInsight/daemon/impl/analysis/XmlHighlightVisitor.java @@ -21,7 +21,9 @@ import com.intellij.codeInsight.daemon.impl.HighlightInfoType; import com.intellij.codeInsight.daemon.impl.HighlightVisitor; import com.intellij.codeInsight.daemon.impl.SeverityRegistrar; import com.intellij.codeInsight.daemon.impl.quickfix.QuickFixAction; +import com.intellij.codeInsight.daemon.impl.quickfix.QuickFixActionRegistrarImpl; import com.intellij.codeInsight.intention.IntentionAction; +import com.intellij.codeInsight.quickfix.UnresolvedReferenceQuickFixProvider; import com.intellij.codeInspection.InspectionProfile; import com.intellij.codeInspection.ex.LocalInspectionToolWrapper; import com.intellij.codeInspection.htmlInspections.RequiredAttributesInspection; @@ -534,6 +536,7 @@ public class XmlHighlightVisitor extends XmlElementVisitor implements HighlightV ); addToResults(info); if (reference instanceof QuickFixProvider) ((QuickFixProvider)reference).registerQuickfix(info, reference); + UnresolvedReferenceQuickFixProvider.registerReferenceFixes(reference, new QuickFixActionRegistrarImpl(info)); } } } From 6460bd47e99613a109faef787c9d093fc6e64db9 Mon Sep 17 00:00:00 2001 From: Dmitry Jemerov Date: Tue, 29 Dec 2009 17:32:15 +0300 Subject: [PATCH 39/67] remove incorrect null check added by maas' patch --- .../intellij/codeInsight/actions/OptimizeImportsAction.java | 3 --- 1 file changed, 3 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/codeInsight/actions/OptimizeImportsAction.java b/platform/lang-impl/src/com/intellij/codeInsight/actions/OptimizeImportsAction.java index 66a1e3b4b98b..efc13e6d1cb1 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/actions/OptimizeImportsAction.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/actions/OptimizeImportsAction.java @@ -44,9 +44,6 @@ public class OptimizeImportsAction extends AnAction { final Editor editor = BaseCodeInsightAction.getInjectedEditor(project, PlatformDataKeys.EDITOR.getData(dataContext)); final VirtualFile[] files = PlatformDataKeys.VIRTUAL_FILE_ARRAY.getData(dataContext); - if (files == null) { - return; - } PsiFile file = null; PsiDirectory dir; From abc20d4f6fa8ac0537899cd81bb35e7958ab01d4 Mon Sep 17 00:00:00 2001 From: Alexey Kudravtsev Date: Tue, 29 Dec 2009 17:35:50 +0300 Subject: [PATCH 40/67] IDEADEV-42139: new toggle button in the usage view "sort members alphabetically" --- .../usages/impl/rules/MethodGroupingRule.java | 34 ++++++++------- .../src/messages/UsageView.properties | 1 + .../intellij/usages/UsageViewSettings.java | 1 + .../impl/SortMembersAlphabeticallyAction.java | 41 +++++++++++++++++++ .../intellij/usages/impl/UsageViewImpl.java | 1 + 5 files changed, 64 insertions(+), 14 deletions(-) create mode 100644 platform/usageView/src/com/intellij/usages/impl/SortMembersAlphabeticallyAction.java diff --git a/java/java-impl/src/com/intellij/usages/impl/rules/MethodGroupingRule.java b/java/java-impl/src/com/intellij/usages/impl/rules/MethodGroupingRule.java index 6735651d7ecf..09694b709f7c 100644 --- a/java/java-impl/src/com/intellij/usages/impl/rules/MethodGroupingRule.java +++ b/java/java-impl/src/com/intellij/usages/impl/rules/MethodGroupingRule.java @@ -30,6 +30,7 @@ import com.intellij.usageView.UsageInfo; import com.intellij.usages.Usage; import com.intellij.usages.UsageGroup; import com.intellij.usages.UsageView; +import com.intellij.usages.UsageViewSettings; import com.intellij.usages.rules.PsiElementUsage; import com.intellij.usages.rules.UsageGroupingRule; import org.jetbrains.annotations.NotNull; @@ -43,26 +44,25 @@ public class MethodGroupingRule implements UsageGroupingRule { private static final Logger LOG = Logger.getInstance("#com.intellij.usages.impl.rules.MethodGroupingRule"); public UsageGroup groupUsage(Usage usage) { - if (usage instanceof PsiElementUsage) { - PsiElement psiElement = ((PsiElementUsage)usage).getElement(); - if (psiElement.getContainingFile() instanceof PsiJavaFile) { - PsiElement containingMethod = psiElement; - do { - containingMethod = PsiTreeUtil.getParentOfType(containingMethod, PsiMethod.class, true); - if (containingMethod == null || ((PsiMethod)containingMethod).getContainingClass().getQualifiedName() != null) break; - } - while (true); + if (!(usage instanceof PsiElementUsage)) return null; + PsiElement psiElement = ((PsiElementUsage)usage).getElement(); + if (psiElement.getContainingFile() instanceof PsiJavaFile) { + PsiElement containingMethod = psiElement; + do { + containingMethod = PsiTreeUtil.getParentOfType(containingMethod, PsiMethod.class, true); + if (containingMethod == null || ((PsiMethod)containingMethod).getContainingClass().getQualifiedName() != null) break; + } + while (true); - if (containingMethod != null) { - return new MethodUsageGroup((PsiMethod)containingMethod); - } + if (containingMethod != null) { + return new MethodUsageGroup((PsiMethod)containingMethod); } } return null; } private static class MethodUsageGroup implements UsageGroup, TypeSafeDataProvider { - private final SmartPsiElementPointer myMethodPointer; + private final SmartPsiElementPointer myMethodPointer; private final String myName; private Icon myIcon; @@ -142,8 +142,14 @@ public class MethodGroupingRule implements UsageGroupingRule { if (!(usageGroup instanceof MethodUsageGroup)) { LOG.error("MethodUsageGroup expected but " + usageGroup.getClass() + " found"); } + MethodUsageGroup other = (MethodUsageGroup)usageGroup; + PsiMethod myMethod = myMethodPointer.getElement(); + PsiMethod otherMethod = other.myMethodPointer.getElement(); + if (myMethod != null && otherMethod != null && myMethod != otherMethod && !UsageViewSettings.getInstance().IS_SORT_MEMBERS_ALPHABETICALLY) { + return myMethod.getTextOffset() < otherMethod.getTextOffset() ? -1 : 1; + } - return myName.compareTo(((MethodUsageGroup)usageGroup).myName); + return myName.compareTo(other.myName); } public void calcData(final DataKey key, final DataSink sink) { diff --git a/platform/platform-resources-en/src/messages/UsageView.properties b/platform/platform-resources-en/src/messages/UsageView.properties index a5a9c7ea113c..c4f18923f6ce 100644 --- a/platform/platform-resources-en/src/messages/UsageView.properties +++ b/platform/platform-resources-en/src/messages/UsageView.properties @@ -63,3 +63,4 @@ show.usages.only.usage=It''s the only usage in {0} all.usages.are.in.this.line=All {0} usages in {1} are in this line no.usages.found.in=No usages found in {0} some.usages.found=({0,choice, 1#1 usage|2#{0,number} usages} found) +sort.alphabetically.action.text=Sort Members Alphabetically diff --git a/platform/usageView/src/com/intellij/usages/UsageViewSettings.java b/platform/usageView/src/com/intellij/usages/UsageViewSettings.java index 5cdd691e149d..cdaf24566a3e 100644 --- a/platform/usageView/src/com/intellij/usages/UsageViewSettings.java +++ b/platform/usageView/src/com/intellij/usages/UsageViewSettings.java @@ -42,6 +42,7 @@ public class UsageViewSettings implements PersistentStateComponent Date: Tue, 29 Dec 2009 23:04:44 +0300 Subject: [PATCH 41/67] URQFP fixed --- .../quickfix/UnresolvedReferenceQuickFixProvider.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/platform/lang-impl/src/com/intellij/codeInsight/quickfix/UnresolvedReferenceQuickFixProvider.java b/platform/lang-impl/src/com/intellij/codeInsight/quickfix/UnresolvedReferenceQuickFixProvider.java index 9bcb5d6c474c..e177857f4077 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/quickfix/UnresolvedReferenceQuickFixProvider.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/quickfix/UnresolvedReferenceQuickFixProvider.java @@ -21,6 +21,7 @@ import com.intellij.openapi.extensions.Extensions; import com.intellij.openapi.project.DumbAware; import com.intellij.openapi.project.DumbService; import com.intellij.psi.PsiReference; +import com.intellij.util.ReflectionCache; import org.jetbrains.annotations.NotNull; public abstract class UnresolvedReferenceQuickFixProvider { @@ -34,7 +35,7 @@ public abstract class UnresolvedReferenceQuickFixProvider Date: Wed, 30 Dec 2009 13:48:09 +0300 Subject: [PATCH 42/67] plugin.xml support: dom for modules --- plugins/devkit/src/dom/Action.java | 1 + plugins/devkit/src/dom/Component.java | 1 + plugins/devkit/src/dom/ExtensionPoint.java | 1 + plugins/devkit/src/dom/IdeaPlugin.java | 3 ++ plugins/devkit/src/dom/PluginModule.java | 32 +++++++++++++++++++ .../dom/impl}/PluginPsiClassConverter.java | 6 +++- .../codeInsight/pluginWithModules.xml | 13 ++++++++ .../codeInsight/PluginXmlFunctionalTest.java | 4 +++ 8 files changed, 60 insertions(+), 1 deletion(-) create mode 100644 plugins/devkit/src/dom/PluginModule.java rename plugins/devkit/{resources/com/intellij/util/xml => src/dom/impl}/PluginPsiClassConverter.java (87%) create mode 100644 plugins/devkit/testData/codeInsight/pluginWithModules.xml diff --git a/plugins/devkit/src/dom/Action.java b/plugins/devkit/src/dom/Action.java index 18f6ab68ac2d..773d3a5ebfa5 100644 --- a/plugins/devkit/src/dom/Action.java +++ b/plugins/devkit/src/dom/Action.java @@ -22,6 +22,7 @@ package org.jetbrains.idea.devkit.dom; import com.intellij.psi.PsiClass; import com.intellij.util.xml.*; import org.jetbrains.annotations.NotNull; +import org.jetbrains.idea.devkit.dom.impl.PluginPsiClassConverter; import java.util.List; diff --git a/plugins/devkit/src/dom/Component.java b/plugins/devkit/src/dom/Component.java index 5ee37ca70c97..c21a21f1ef18 100644 --- a/plugins/devkit/src/dom/Component.java +++ b/plugins/devkit/src/dom/Component.java @@ -22,6 +22,7 @@ package org.jetbrains.idea.devkit.dom; import com.intellij.psi.PsiClass; import com.intellij.util.xml.*; import org.jetbrains.annotations.NotNull; +import org.jetbrains.idea.devkit.dom.impl.PluginPsiClassConverter; import java.util.List; diff --git a/plugins/devkit/src/dom/ExtensionPoint.java b/plugins/devkit/src/dom/ExtensionPoint.java index 47e1f59ab817..658ca26ef55b 100644 --- a/plugins/devkit/src/dom/ExtensionPoint.java +++ b/plugins/devkit/src/dom/ExtensionPoint.java @@ -18,6 +18,7 @@ package org.jetbrains.idea.devkit.dom; import com.intellij.psi.PsiClass; import com.intellij.util.xml.*; import org.jetbrains.annotations.NotNull; +import org.jetbrains.idea.devkit.dom.impl.PluginPsiClassConverter; /** * @author mike diff --git a/plugins/devkit/src/dom/IdeaPlugin.java b/plugins/devkit/src/dom/IdeaPlugin.java index 8d1d193daa8e..6afc6966bd67 100644 --- a/plugins/devkit/src/dom/IdeaPlugin.java +++ b/plugins/devkit/src/dom/IdeaPlugin.java @@ -91,6 +91,9 @@ public interface IdeaPlugin extends DomElement { @SubTagList("depends") Dependency addDependency(); + @NotNull + @SubTagList("module") + List getModules(); @NotNull @SubTagList("extensions") diff --git a/plugins/devkit/src/dom/PluginModule.java b/plugins/devkit/src/dom/PluginModule.java new file mode 100644 index 000000000000..2efc1cabdb71 --- /dev/null +++ b/plugins/devkit/src/dom/PluginModule.java @@ -0,0 +1,32 @@ +/* + * Copyright 2000-2009 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.idea.devkit.dom; + +import com.intellij.util.xml.DomElement; +import com.intellij.util.xml.GenericAttributeValue; +import com.intellij.util.xml.NameValue; +import org.jetbrains.annotations.NotNull; + +/** + * @author Dmitry Avdeev + */ +public interface PluginModule extends DomElement { + + @NotNull + @NameValue + GenericAttributeValue getValue(); + +} diff --git a/plugins/devkit/resources/com/intellij/util/xml/PluginPsiClassConverter.java b/plugins/devkit/src/dom/impl/PluginPsiClassConverter.java similarity index 87% rename from plugins/devkit/resources/com/intellij/util/xml/PluginPsiClassConverter.java rename to plugins/devkit/src/dom/impl/PluginPsiClassConverter.java index 9fabb3aeffc2..db687949a00c 100644 --- a/plugins/devkit/resources/com/intellij/util/xml/PluginPsiClassConverter.java +++ b/plugins/devkit/src/dom/impl/PluginPsiClassConverter.java @@ -13,11 +13,15 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.intellij.util.xml; +package org.jetbrains.idea.devkit.dom.impl; import com.intellij.psi.PsiClass; import com.intellij.psi.impl.source.resolve.reference.impl.providers.JavaClassReferenceProvider; import com.intellij.psi.search.GlobalSearchScope; +import com.intellij.util.xml.ConvertContext; +import com.intellij.util.xml.ExtendClass; +import com.intellij.util.xml.GenericDomValue; +import com.intellij.util.xml.PsiClassConverter; /** * @author peter diff --git a/plugins/devkit/testData/codeInsight/pluginWithModules.xml b/plugins/devkit/testData/codeInsight/pluginWithModules.xml new file mode 100644 index 000000000000..d277c5560585 --- /dev/null +++ b/plugins/devkit/testData/codeInsight/pluginWithModules.xml @@ -0,0 +1,13 @@ + + com.intellij + IDEA CORE + + + + + + + + + + \ No newline at end of file diff --git a/plugins/devkit/testSources/codeInsight/PluginXmlFunctionalTest.java b/plugins/devkit/testSources/codeInsight/PluginXmlFunctionalTest.java index 9d5d3d67388e..28eb9180393d 100644 --- a/plugins/devkit/testSources/codeInsight/PluginXmlFunctionalTest.java +++ b/plugins/devkit/testSources/codeInsight/PluginXmlFunctionalTest.java @@ -122,4 +122,8 @@ public class PluginXmlFunctionalTest extends JavaCodeInsightFixtureTestCase { myFixture.checkResultByFile(getTestName(false) + "_after.xml"); } + public void testPluginModule() throws Throwable { + myFixture.testHighlighting("pluginWithModules.xml"); + } + } From 1fc1ada8a22875ce1afa633bd5c83bb98e1e84f0 Mon Sep 17 00:00:00 2001 From: Dmitry Avdeev Date: Wed, 30 Dec 2009 15:47:23 +0300 Subject: [PATCH 43/67] plugin.xml support: using DomFileIndex --- .../src/dom/impl/ExtensionDomExtender.java | 4 +- .../src/dom/impl/IdeaPluginConverter.java | 126 +++--------------- .../testData/codeInsight/extensionPoints.xml | 3 + .../codeInsight/pluginWithXInclude.xml | 16 +++ .../codeInsight/PluginXmlFunctionalTest.java | 8 ++ 5 files changed, 49 insertions(+), 108 deletions(-) create mode 100644 plugins/devkit/testData/codeInsight/extensionPoints.xml create mode 100644 plugins/devkit/testData/codeInsight/pluginWithXInclude.xml diff --git a/plugins/devkit/src/dom/impl/ExtensionDomExtender.java b/plugins/devkit/src/dom/impl/ExtensionDomExtender.java index 926d215699dc..071e6450b422 100644 --- a/plugins/devkit/src/dom/impl/ExtensionDomExtender.java +++ b/plugins/devkit/src/dom/impl/ExtensionDomExtender.java @@ -60,9 +60,9 @@ public class ExtensionDomExtender extends DomExtender { } else { prefix = ""; } - + + registerExtensions(prefix, ideaPlugin, registrar, psiManager); final Collection dependencies = getDependencies(ideaPlugin); - ContainerUtil.addIfNotNull(ideaPlugin.getPluginId(), dependencies); for (IdeaPlugin plugin : IdeaPluginConverter.collectAllVisiblePlugins(DomUtil.getFile(extensions))) { final String value = plugin.getPluginId(); if (value != null && dependencies.contains(value)) { diff --git a/plugins/devkit/src/dom/impl/IdeaPluginConverter.java b/plugins/devkit/src/dom/impl/IdeaPluginConverter.java index b87552204075..0aead2ac5b9b 100644 --- a/plugins/devkit/src/dom/impl/IdeaPluginConverter.java +++ b/plugins/devkit/src/dom/impl/IdeaPluginConverter.java @@ -15,32 +15,27 @@ */ package org.jetbrains.idea.devkit.dom.impl; -import com.intellij.openapi.fileTypes.FileTypes; import com.intellij.openapi.module.Module; import com.intellij.openapi.module.ModuleUtil; import com.intellij.openapi.project.Project; -import com.intellij.openapi.projectRoots.Sdk; -import com.intellij.openapi.roots.ModuleRootManager; -import com.intellij.openapi.roots.PackageIndex; -import com.intellij.openapi.vfs.JarFileSystem; -import com.intellij.openapi.vfs.VirtualFile; -import com.intellij.psi.PsiManager; -import com.intellij.psi.xml.XmlDocument; +import com.intellij.psi.search.GlobalSearchScope; import com.intellij.psi.xml.XmlFile; -import com.intellij.util.xml.ConvertContext; -import com.intellij.util.xml.DomElement; -import com.intellij.util.xml.DomManager; -import com.intellij.util.xml.ResolvingConverter; +import com.intellij.util.Function; import com.intellij.util.containers.CollectionFactory; +import com.intellij.util.containers.ContainerUtil; +import com.intellij.util.xml.ConvertContext; +import com.intellij.util.xml.DomFileElement; +import com.intellij.util.xml.DomService; +import com.intellij.util.xml.ResolvingConverter; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.idea.devkit.DevKitBundle; import org.jetbrains.idea.devkit.dom.IdeaPlugin; -import org.jetbrains.idea.devkit.module.PluginModuleType; -import org.jetbrains.idea.devkit.projectRoots.IdeaJdk; -import java.util.*; +import java.util.Collection; +import java.util.List; +import java.util.Set; /** * @author mike @@ -68,100 +63,19 @@ public class IdeaPluginConverter extends ResolvingConverter { return DevKitBundle.message("error.cannot.resolve.plugin", s); } - public static Collection collectAllVisiblePlugins(final XmlFile xmlFile) { - List ideaPlugins = new ArrayList(); - final Project project = xmlFile.getProject(); - final PsiManager psiManager = PsiManager.getInstance(project); + public static Collection collectAllVisiblePlugins(@NotNull XmlFile xmlFile) { - final Iterable metaInfs = PackageIndex.getInstance(project).getDirsByPackageName("META-INF", true); + Project project = xmlFile.getProject(); + Module module = ModuleUtil.findModuleForPsiElement(xmlFile); - for (VirtualFile metaInf : metaInfs) { - final VirtualFile pluginXml = metaInf.findChild("plugin.xml"); - if (pluginXml == null) continue; - final IdeaPlugin ideaPlugin = getIdeaPlugin(project, psiManager, pluginXml); - if (ideaPlugin != null) { - ideaPlugins.add(ideaPlugin); + GlobalSearchScope scope = module == null ? GlobalSearchScope.allScope(project) : + GlobalSearchScope.moduleWithDependenciesAndLibrariesScope(module, true); + List> files = DomService.getInstance().getFileElements(IdeaPlugin.class, project, scope); + return ContainerUtil.map(files, new Function, IdeaPlugin>() { + public IdeaPlugin fun(DomFileElement ideaPluginDomFileElement) { + return ideaPluginDomFileElement.getRootElement(); } - } - - final Module module = ModuleUtil.findModuleForPsiElement(xmlFile); - if (module != null) { - // a plugin.xml doesn't need to be in a source folder. - final Module[] dependencies = ModuleRootManager.getInstance(module).getDependencies(); - for (Module dep : dependencies) { - if (PluginModuleType.isOfType(dep)) { - final XmlFile file = PluginModuleType.getPluginXml(dep); - if (file == null) continue; - final VirtualFile pluginXml = file.getVirtualFile(); - if (pluginXml != null) { - final IdeaPlugin ideaPlugin = getIdeaPlugin(project, psiManager, pluginXml); - if (ideaPlugin != null) { - if (!ideaPlugins.contains(ideaPlugin)) { - ideaPlugins.add(ideaPlugin); - } - } - } - } - } - - final Sdk jdk = ModuleRootManager.getInstance(module).getSdk(); - if (jdk != null && jdk.getSdkType() instanceof IdeaJdk) { - final VirtualFile jdkHome = jdk.getHomeDirectory(); - if (jdkHome != null) { - final VirtualFile pluginsHome = jdkHome.findChild("plugins"); - final VirtualFile[] plugins = pluginsHome != null ? pluginsHome.getChildren() : VirtualFile.EMPTY_ARRAY; - for (VirtualFile plugin : plugins) { - if (plugin.isDirectory()) { - final VirtualFile lib = plugin.findChild("lib"); - final VirtualFile[] children = lib != null ? lib.getChildren() : VirtualFile.EMPTY_ARRAY; - for (VirtualFile child : children) { - final IdeaPlugin ideaPlugin = findPluginInFile(child, project, psiManager); - if (ideaPlugin != null) { - ideaPlugins.add(ideaPlugin); - } - } - } - else { - final IdeaPlugin ideaPlugin = findPluginInFile(plugin, project, psiManager); - if (ideaPlugin != null) { - ideaPlugins.add(ideaPlugin); - } - } - } - } - } - } - - return ideaPlugins; - } - - @Nullable - private static IdeaPlugin findPluginInFile(final VirtualFile child, final Project project, final PsiManager psiManager) { - if (child.getFileType() != FileTypes.ARCHIVE) return null; - - final VirtualFile jarRoot = JarFileSystem.getInstance().getJarRootForLocalFile(child); - if (jarRoot == null) return null; - final VirtualFile metaInf = jarRoot.findChild("META-INF"); - if (metaInf == null) return null; - - final VirtualFile pluginXml = metaInf.findChild("plugin.xml"); - if (pluginXml == null) return null; - - return getIdeaPlugin(project, psiManager, pluginXml); - } - - @Nullable - private static IdeaPlugin getIdeaPlugin(final Project project, final PsiManager psiManager, final VirtualFile pluginXml) { - final XmlFile psiFile = (XmlFile)psiManager.findFile(pluginXml); - if (psiFile == null) return null; - - final XmlDocument document = psiFile.getDocument(); - if (document == null) return null; - - final DomElement domElement = DomManager.getDomManager(project).getDomElement(document.getRootTag()); - if (!(domElement instanceof IdeaPlugin)) return null; - return (IdeaPlugin)domElement; - + }); } public IdeaPlugin fromString(@Nullable @NonNls final String s, final ConvertContext context) { diff --git a/plugins/devkit/testData/codeInsight/extensionPoints.xml b/plugins/devkit/testData/codeInsight/extensionPoints.xml new file mode 100644 index 000000000000..d568f48dbebf --- /dev/null +++ b/plugins/devkit/testData/codeInsight/extensionPoints.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/plugins/devkit/testData/codeInsight/pluginWithXInclude.xml b/plugins/devkit/testData/codeInsight/pluginWithXInclude.xml new file mode 100644 index 000000000000..bea4d7ba0a72 --- /dev/null +++ b/plugins/devkit/testData/codeInsight/pluginWithXInclude.xml @@ -0,0 +1,16 @@ + + + foo + + + + + + + + + + + + + \ No newline at end of file diff --git a/plugins/devkit/testSources/codeInsight/PluginXmlFunctionalTest.java b/plugins/devkit/testSources/codeInsight/PluginXmlFunctionalTest.java index 28eb9180393d..b9a3ec0226ea 100644 --- a/plugins/devkit/testSources/codeInsight/PluginXmlFunctionalTest.java +++ b/plugins/devkit/testSources/codeInsight/PluginXmlFunctionalTest.java @@ -126,4 +126,12 @@ public class PluginXmlFunctionalTest extends JavaCodeInsightFixtureTestCase { myFixture.testHighlighting("pluginWithModules.xml"); } + public void testPluginWithModules() throws Throwable { + myFixture.testHighlighting("pluginWithModules.xml"); + } + + public void testPluginWithXInclude() throws Throwable { + myFixture.testHighlighting("pluginWithXInclude.xml", "extensionPoints.xml"); + } + } From 013421161d2b0ce1a8994ccc87f602ac5ec74a7c Mon Sep 17 00:00:00 2001 From: nik Date: Thu, 31 Dec 2009 11:23:28 +0300 Subject: [PATCH 44/67] js debugger: load source from cache and other fixes --- .../src/com/intellij/ide/XmlRpcServer.java | 6 +-- .../com/intellij/ide/XmlRpcServerImpl.java | 42 ++++++++++--------- .../ide/actions/OpenRemoteFileAction.java | 3 +- .../fileEditor/impl/http/HttpFileEditor.java | 23 +++++++++- .../xdebugger/impl/XDebugSessionImpl.java | 6 ++- .../BreadcrumbsLoaderComponent.java | 9 ++-- .../breadcrumbs/BreadcrumbsXmlWrapper.java | 2 + 7 files changed, 61 insertions(+), 30 deletions(-) diff --git a/platform/platform-api/src/com/intellij/ide/XmlRpcServer.java b/platform/platform-api/src/com/intellij/ide/XmlRpcServer.java index a1a59c482037..e3a6916e9925 100644 --- a/platform/platform-api/src/com/intellij/ide/XmlRpcServer.java +++ b/platform/platform-api/src/com/intellij/ide/XmlRpcServer.java @@ -19,7 +19,7 @@ package com.intellij.ide; * @author mike */ public interface XmlRpcServer { - void addHandler (String name, Object handler); - void removeHandler (String name); - public int getPortNumber(); + void addHandler(String name, Object handler); + void removeHandler(String name); + int getPortNumber(); } diff --git a/platform/platform-impl/src/com/intellij/ide/XmlRpcServerImpl.java b/platform/platform-impl/src/com/intellij/ide/XmlRpcServerImpl.java index 69a9586f4ad4..c3250f103fd6 100644 --- a/platform/platform-impl/src/com/intellij/ide/XmlRpcServerImpl.java +++ b/platform/platform-impl/src/com/intellij/ide/XmlRpcServerImpl.java @@ -33,7 +33,8 @@ import java.net.ServerSocket; */ public class XmlRpcServerImpl implements XmlRpcServer, ApplicationComponent { private static final Logger LOG = Logger.getInstance("#com.intellij.ide.XmlRpcServerImpl"); - public static final int PORT_NUMBER = 63342; + private static final int FIRST_PORT_NUMBER = 63342; + private static final int PORTS_COUNT = 20; public static int detectedPortNumber = -1; private WebServer myWebServer; @NonNls private static final String PROPERTY_RPC_PORT = "rpc.port"; @@ -47,7 +48,7 @@ public class XmlRpcServerImpl implements XmlRpcServer, ApplicationComponent { public void initComponent() { if (ApplicationManager.getApplication().isUnitTestMode() || !checkPort()) return; final Thread thread = Thread.currentThread(); - final int currentPrio = thread.getPriority(); + final int currentPriority = thread.getPriority(); try { thread.setPriority(Thread.NORM_PRIORITY - 2); myWebServer = new IdeaAwareWebServer(getPortNumber(), null, new IdeaAwareXmlRpcServer()); @@ -58,40 +59,44 @@ public class XmlRpcServerImpl implements XmlRpcServer, ApplicationComponent { myWebServer = null; } finally { - thread.setPriority(currentPrio); + thread.setPriority(currentPriority); } } public int getPortNumber() { - return detectedPortNumber == -1 ? getPortImpl() : detectedPortNumber; + return detectedPortNumber == -1 ? getDefaultPort() : detectedPortNumber; } - private static int getPortImpl() { + private static int getDefaultPort() { if (System.getProperty(PROPERTY_RPC_PORT) != null) return Integer.parseInt(System.getProperty(PROPERTY_RPC_PORT)); - return PORT_NUMBER; + return FIRST_PORT_NUMBER; } private static boolean checkPort() { ServerSocket socket = null; try { - try { - socket = new ServerSocket(getPortImpl()); - } - catch (BindException e) { + final int firstPort = getDefaultPort(); + for (int i = 0; i < PORTS_COUNT; i++) { + int port = firstPort + i; try { - // try any port - socket = new ServerSocket(0); - detectedPortNumber = socket.getLocalPort(); + socket = new ServerSocket(port); + detectedPortNumber = port; return true; - } catch (BindException e1) { - // fallthrow } - return false; + catch (BindException ignored) { + } + } + + try { + // try any port + socket = new ServerSocket(0); + detectedPortNumber = socket.getLocalPort(); + return true; + } catch (BindException ignored) { } } catch (IOException e) { LOG.info(e); - return false; } finally { if (socket != null) { @@ -100,11 +105,10 @@ public class XmlRpcServerImpl implements XmlRpcServer, ApplicationComponent { } catch (IOException e) { LOG.error(e); - return false; } } } - return true; + return false; } public void disposeComponent() { diff --git a/platform/platform-impl/src/com/intellij/ide/actions/OpenRemoteFileAction.java b/platform/platform-impl/src/com/intellij/ide/actions/OpenRemoteFileAction.java index 548159d1c7e6..d6f851c3a167 100644 --- a/platform/platform-impl/src/com/intellij/ide/actions/OpenRemoteFileAction.java +++ b/platform/platform-impl/src/com/intellij/ide/actions/OpenRemoteFileAction.java @@ -30,7 +30,6 @@ import com.intellij.openapi.fileEditor.FileEditorManager; * @author nik * internal action */ -@SuppressWarnings({"HardCodedStringLiteral"}) public class OpenRemoteFileAction extends AnAction implements DumbAware { @Override public void update(final AnActionEvent e) { @@ -40,7 +39,7 @@ public class OpenRemoteFileAction extends AnAction implements DumbAware { @Override public void actionPerformed(final AnActionEvent e) { Project project = e.getData(PlatformDataKeys.PROJECT); - String defaultUrl = "http://localhost:8080/index.html"; + String defaultUrl = "http://"; String url = Messages.showInputDialog(project, "URL:", "Open Remote File", null, defaultUrl, null); if (url != null) { VirtualFile file = VirtualFileManager.getInstance().findFileByUrl(url); diff --git a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/http/HttpFileEditor.java b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/http/HttpFileEditor.java index 0cb520b7d42c..ac57802c2ee0 100644 --- a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/http/HttpFileEditor.java +++ b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/http/HttpFileEditor.java @@ -17,6 +17,9 @@ package com.intellij.openapi.fileEditor.impl.http; import com.intellij.codeHighlighting.BackgroundEditorHighlighter; import com.intellij.ide.structureView.StructureViewBuilder; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.editor.EditorFactory; +import com.intellij.openapi.editor.impl.DocumentImpl; import com.intellij.openapi.fileEditor.*; import com.intellij.openapi.fileEditor.impl.text.TextEditorState; import com.intellij.openapi.project.Project; @@ -33,11 +36,14 @@ import java.beans.PropertyChangeListener; /** * @author nik */ -public class HttpFileEditor implements NavigatableFileEditor { +public class HttpFileEditor implements TextEditor { private final UserDataHolderBase myUserDataHolder = new UserDataHolderBase(); private final RemoteFilePanel myPanel; + private Editor myMockTextEditor; + private final Project myProject; public HttpFileEditor(final Project project, final HttpVirtualFile virtualFile) { + myProject = project; myPanel = new RemoteFilePanel(project, virtualFile); } @@ -59,6 +65,18 @@ public class HttpFileEditor implements NavigatableFileEditor { return "Http"; } + @NotNull + public Editor getEditor() { + final TextEditor fileEditor = myPanel.getFileEditor(); + if (fileEditor != null) { + return fileEditor.getEditor(); + } + if (myMockTextEditor == null) { + myMockTextEditor = EditorFactory.getInstance().createViewer(new DocumentImpl(""), myProject); + } + return myMockTextEditor; + } + @NotNull public FileEditorState getState(@NotNull final FileEditorStateLevel level) { final TextEditor textEditor = myPanel.getFileEditor(); @@ -157,6 +175,9 @@ public class HttpFileEditor implements NavigatableFileEditor { } public void dispose() { + if (myMockTextEditor != null) { + EditorFactory.getInstance().releaseEditor(myMockTextEditor); + } myPanel.dispose(); } } diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/XDebugSessionImpl.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/XDebugSessionImpl.java index e24074e13767..1df891c4430a 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/XDebugSessionImpl.java +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/XDebugSessionImpl.java @@ -70,7 +70,7 @@ public class XDebugSessionImpl implements XDebugSession { private XDebugSessionTab mySessionTab; private final EventDispatcher myDispatcher = EventDispatcher.create(XDebugSessionListener.class); private Project myProject; - private ExecutionEnvironment myEnvironment; + private @Nullable ExecutionEnvironment myEnvironment; private ProgramRunner myRunner; private boolean myStopped; private boolean myPauseActionSupported; @@ -174,7 +174,9 @@ public class XDebugSessionImpl implements XDebugSession { private void initSessionTab(@NotNull XDebugSessionData sessionData) { mySessionTab = new XDebugSessionTab(myProject, mySessionName); - mySessionTab.setEnvironment(myEnvironment); + if (myEnvironment != null) { + mySessionTab.setEnvironment(myEnvironment); + } Disposer.register(myProject, mySessionTab); mySessionTab.attachToSession(this, myRunner, myEnvironment, sessionData); } diff --git a/xml/impl/src/com/intellij/xml/breadcrumbs/BreadcrumbsLoaderComponent.java b/xml/impl/src/com/intellij/xml/breadcrumbs/BreadcrumbsLoaderComponent.java index 86516623b078..048387d491de 100644 --- a/xml/impl/src/com/intellij/xml/breadcrumbs/BreadcrumbsLoaderComponent.java +++ b/xml/impl/src/com/intellij/xml/breadcrumbs/BreadcrumbsLoaderComponent.java @@ -11,6 +11,7 @@ import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Disposer; import com.intellij.openapi.util.Key; import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.openapi.vfs.impl.http.HttpVirtualFile; import com.intellij.psi.FileViewProvider; import com.intellij.psi.PsiManager; import com.intellij.application.options.editor.WebEditorOptions; @@ -66,11 +67,13 @@ public class BreadcrumbsLoaderComponent extends AbstractProjectComponent { } private static boolean isSuitable(final Project project, final VirtualFile file) { + if (file instanceof HttpVirtualFile) { + return false; } + final FileViewProvider psiFile = PsiManager.getInstance(project).findViewProvider(file); - + return psiFile != null && - (BreadcrumbsXmlWrapper.findInfoProvider(psiFile) != null || - file.getUserData(BREADCRUMBS_SUITABLE_FILE) != null); + (BreadcrumbsXmlWrapper.findInfoProvider(psiFile) != null || file.getUserData(BREADCRUMBS_SUITABLE_FILE) != null); } public void fileClosed(final FileEditorManager source, final VirtualFile file) { diff --git a/xml/impl/src/com/intellij/xml/breadcrumbs/BreadcrumbsXmlWrapper.java b/xml/impl/src/com/intellij/xml/breadcrumbs/BreadcrumbsXmlWrapper.java index 1b5217a10a5f..2f4dba2791d4 100644 --- a/xml/impl/src/com/intellij/xml/breadcrumbs/BreadcrumbsXmlWrapper.java +++ b/xml/impl/src/com/intellij/xml/breadcrumbs/BreadcrumbsXmlWrapper.java @@ -229,7 +229,9 @@ public class BreadcrumbsXmlWrapper implements BreadcrumbsItemListener Date: Sat, 2 Jan 2010 00:39:52 +0300 Subject: [PATCH 45/67] Add mnemonic to PsiViewer action + rename class --- ...ViewerAction.java => PsiViewerAction.java} | 20 ++++++++----------- .../src/messages/ActionsBundle.properties | 2 +- .../src/idea/PlatformActions.xml | 2 +- 3 files changed, 10 insertions(+), 14 deletions(-) rename platform/lang-impl/src/com/intellij/internal/psiView/{ViewerAction.java => PsiViewerAction.java} (71%) diff --git a/platform/lang-impl/src/com/intellij/internal/psiView/ViewerAction.java b/platform/lang-impl/src/com/intellij/internal/psiView/PsiViewerAction.java similarity index 71% rename from platform/lang-impl/src/com/intellij/internal/psiView/ViewerAction.java rename to platform/lang-impl/src/com/intellij/internal/psiView/PsiViewerAction.java index 1c72b2160de4..e232265e7fb1 100644 --- a/platform/lang-impl/src/com/intellij/internal/psiView/ViewerAction.java +++ b/platform/lang-impl/src/com/intellij/internal/psiView/PsiViewerAction.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2010 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. @@ -13,12 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - -/** - * class ViewerAction - * created Aug 27, 2001 - * @author Jeka - */ package com.intellij.internal.psiView; import com.intellij.openapi.actionSystem.AnAction; @@ -27,16 +21,18 @@ import com.intellij.openapi.actionSystem.PlatformDataKeys; import com.intellij.openapi.project.DumbAware; import com.intellij.openapi.project.Project; -public class ViewerAction extends AnAction implements DumbAware { +/** + * @author Konstantin Bulenkov + */ +public class PsiViewerAction extends AnAction implements DumbAware { public void actionPerformed(AnActionEvent e) { - Project project = PlatformDataKeys.PROJECT.getData(e.getDataContext()); - PsiViewerDialog dialog = new PsiViewerDialog(project,false); - dialog.show(); + final Project project = PlatformDataKeys.PROJECT.getData(e.getDataContext()); + new PsiViewerDialog(project, false).show(); } @Override public void update(AnActionEvent e) { - Project project = PlatformDataKeys.PROJECT.getData(e.getDataContext()); + final Project project = PlatformDataKeys.PROJECT.getData(e.getDataContext()); e.getPresentation().setEnabled(project != null); } } diff --git a/platform/platform-resources-en/src/messages/ActionsBundle.properties b/platform/platform-resources-en/src/messages/ActionsBundle.properties index c7471702fe8a..7a54e637466d 100644 --- a/platform/platform-resources-en/src/messages/ActionsBundle.properties +++ b/platform/platform-resources-en/src/messages/ActionsBundle.properties @@ -652,7 +652,7 @@ action.ValidateXml.text=_Validate action.ValidateXml.description=Validate the current xml file action.GenerateDTD.text=Generate DTD from _XML file group.ExternalToolsGroup.text=External Tools -action.PsiViewer.text=View PSI Structure +action.PsiViewer.text=_View PSI Structure action.DebugListen.text=Throw Debug Exception action.VirtualFileInfo.text=Virtual File Info action.Merge3Files.text=Merge diff --git a/platform/platform-resources/src/idea/PlatformActions.xml b/platform/platform-resources/src/idea/PlatformActions.xml index d680785048f3..a28909f0b2d1 100644 --- a/platform/platform-resources/src/idea/PlatformActions.xml +++ b/platform/platform-resources/src/idea/PlatformActions.xml @@ -208,7 +208,7 @@ - + From 83bc825c204411f5efed24fcdee8a58da45fa801 Mon Sep 17 00:00:00 2001 From: "Kirill.Safonov" Date: Wed, 6 Jan 2010 13:18:48 +0300 Subject: [PATCH 46/67] invoke postprocess reformatting for the current file only --- .../src/com/intellij/psi/SingleRootFileViewProvider.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/lang-impl/src/com/intellij/psi/SingleRootFileViewProvider.java b/platform/lang-impl/src/com/intellij/psi/SingleRootFileViewProvider.java index 3c650e22b736..480cd0e05c05 100644 --- a/platform/lang-impl/src/com/intellij/psi/SingleRootFileViewProvider.java +++ b/platform/lang-impl/src/com/intellij/psi/SingleRootFileViewProvider.java @@ -162,7 +162,7 @@ public class SingleRootFileViewProvider extends UserDataHolderBase implements Fi if (component.isViewProviderLocked(this)) { throw new RuntimeException("Document is locked by write PSI operations. Use PsiDocumentManager.doPostponedOperationsAndUnblockDocument() to commit PSI changes to the document."); } - component.doPostponedFormatting(); + component.doPostponedFormatting(this); final PsiFileImpl psiFile = (PsiFileImpl)getCachedPsi(getBaseLanguage()); if (psiFile != null && psiFile.isContentsLoaded() && getContent()instanceof DocumentContent) { setContent(new PsiFileContent(psiFile, getModificationStamp())); From 73ced189302a81a69e850e573b795fa35745906c Mon Sep 17 00:00:00 2001 From: "Kirill.Safonov" Date: Wed, 6 Jan 2010 23:29:43 +0300 Subject: [PATCH 47/67] happy new year --- platform/testFramework/src/com/intellij/idea/Bombed.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/testFramework/src/com/intellij/idea/Bombed.java b/platform/testFramework/src/com/intellij/idea/Bombed.java index 8c4346303d76..2b7031aebfd0 100644 --- a/platform/testFramework/src/com/intellij/idea/Bombed.java +++ b/platform/testFramework/src/com/intellij/idea/Bombed.java @@ -23,7 +23,7 @@ import java.lang.annotation.Target; @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.TYPE, ElementType.METHOD}) public @interface Bombed { - int year() default 2009; + int year() default 2010; int month(); int day(); int time() default 0; From 3f62c2789fa789e4e2651a8847ddfc30a3023ac4 Mon Sep 17 00:00:00 2001 From: Dmitry Jemerov Date: Tue, 29 Dec 2009 17:59:21 +0300 Subject: [PATCH 48/67] kill the rest of DataAccessor framework, use DataKeys everywhere consistently --- .../com/intellij/ide/JavaDataAccessors.java | 36 ------ .../com/intellij/ide/macro/FileFQPackage.java | 7 +- .../intellij/ide/macro/FilePackageMacro.java | 21 ++- .../src/com/intellij/ide/DataAccessors.java | 68 ---------- .../com/intellij/ide/macro/FileDirMacro.java | 14 +- .../ide/macro/FileRelativeDirMacro.java | 14 +- .../src/com/intellij/ide/macro/Macro.java | 10 ++ .../ide/macro/ModuleFileDirMacro.java | 6 +- .../ide/macro/ModuleFilePathMacro.java | 6 +- .../ide/macro/ProjectFileDirMacro.java | 4 +- .../src/com/intellij/ide/DataAccessor.java | 121 ------------------ 11 files changed, 45 insertions(+), 262 deletions(-) delete mode 100644 java/java-impl/src/com/intellij/ide/JavaDataAccessors.java delete mode 100644 platform/lang-impl/src/com/intellij/ide/DataAccessors.java delete mode 100644 platform/platform-impl/src/com/intellij/ide/DataAccessor.java diff --git a/java/java-impl/src/com/intellij/ide/JavaDataAccessors.java b/java/java-impl/src/com/intellij/ide/JavaDataAccessors.java deleted file mode 100644 index fabee57027f7..000000000000 --- a/java/java-impl/src/com/intellij/ide/JavaDataAccessors.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright 2000-2009 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 com.intellij.ide; - -import com.intellij.openapi.actionSystem.DataContext; -import com.intellij.psi.JavaDirectoryService; -import com.intellij.psi.PsiDirectory; -import com.intellij.psi.PsiFile; -import com.intellij.psi.PsiPackage; - -public class JavaDataAccessors { - public static final DataAccessor FILE_PACKAGE = new DataAccessor() { - public PsiPackage getImpl(DataContext dataContext) throws NoDataException { - PsiFile psiFile = DataAccessors.PSI_FILE.getNotNull(dataContext); - PsiDirectory containingDirectory = psiFile.getContainingDirectory(); - if (containingDirectory == null || !containingDirectory.isValid()) return null; - return JavaDirectoryService.getInstance().getPackage(containingDirectory); - } - }; - - private JavaDataAccessors() { - } -} diff --git a/java/java-impl/src/com/intellij/ide/macro/FileFQPackage.java b/java/java-impl/src/com/intellij/ide/macro/FileFQPackage.java index ab0182ab39d7..a4e04b2f9d0b 100644 --- a/java/java-impl/src/com/intellij/ide/macro/FileFQPackage.java +++ b/java/java-impl/src/com/intellij/ide/macro/FileFQPackage.java @@ -15,14 +15,13 @@ */ package com.intellij.ide.macro; +import com.intellij.ide.IdeBundle; import com.intellij.openapi.actionSystem.DataContext; import com.intellij.psi.PsiPackage; -import com.intellij.ide.IdeBundle; -import com.intellij.ide.JavaDataAccessors; public class FileFQPackage extends Macro { - public String expand(DataContext dataContext) throws Macro.ExecutionCancelledException { - PsiPackage aPackage = JavaDataAccessors.FILE_PACKAGE.from(dataContext); + public String expand(DataContext dataContext) { + PsiPackage aPackage = FilePackageMacro.getFilePackage(dataContext); if (aPackage == null) return null; return aPackage.getQualifiedName(); } diff --git a/java/java-impl/src/com/intellij/ide/macro/FilePackageMacro.java b/java/java-impl/src/com/intellij/ide/macro/FilePackageMacro.java index 361302030d38..96343c638664 100644 --- a/java/java-impl/src/com/intellij/ide/macro/FilePackageMacro.java +++ b/java/java-impl/src/com/intellij/ide/macro/FilePackageMacro.java @@ -15,10 +15,14 @@ */ package com.intellij.ide.macro; -import com.intellij.openapi.actionSystem.DataContext; -import com.intellij.psi.PsiPackage; import com.intellij.ide.IdeBundle; -import com.intellij.ide.JavaDataAccessors; +import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.actionSystem.DataKeys; +import com.intellij.psi.JavaDirectoryService; +import com.intellij.psi.PsiDirectory; +import com.intellij.psi.PsiFile; +import com.intellij.psi.PsiPackage; +import org.jetbrains.annotations.Nullable; public final class FilePackageMacro extends Macro { public String getName() { @@ -30,8 +34,17 @@ public final class FilePackageMacro extends Macro { } public String expand(DataContext dataContext) { - PsiPackage aPackage = JavaDataAccessors.FILE_PACKAGE.from(dataContext); + PsiPackage aPackage = getFilePackage(dataContext); if (aPackage == null) return null; return aPackage.getName(); } + + @Nullable + static PsiPackage getFilePackage(DataContext dataContext) { + PsiFile psiFile = DataKeys.PSI_FILE.getData(dataContext); + if (psiFile == null) return null; + PsiDirectory containingDirectory = psiFile.getContainingDirectory(); + if (containingDirectory == null || !containingDirectory.isValid()) return null; + return JavaDirectoryService.getInstance().getPackage(containingDirectory); + } } diff --git a/platform/lang-impl/src/com/intellij/ide/DataAccessors.java b/platform/lang-impl/src/com/intellij/ide/DataAccessors.java deleted file mode 100644 index ecd2b61169e0..000000000000 --- a/platform/lang-impl/src/com/intellij/ide/DataAccessors.java +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright 2000-2009 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 com.intellij.ide; - -import com.intellij.openapi.actionSystem.DataContext; -import com.intellij.openapi.actionSystem.LangDataKeys; -import com.intellij.openapi.actionSystem.PlatformDataKeys; -import com.intellij.openapi.module.Module; -import com.intellij.openapi.project.Project; -import com.intellij.openapi.vfs.VirtualFile; -import com.intellij.psi.PsiFile; -import com.intellij.psi.PsiManager; - -/** - * @author yole - */ -public class DataAccessors { - @Deprecated - public static final DataAccessor PROJECT = new DataAccessor.SimpleDataAccessor(PlatformDataKeys.PROJECT.getName()); - @Deprecated - public static final DataAccessor MODULE = new DataAccessor.SimpleDataAccessor(LangDataKeys.MODULE.getName()); - public static final DataAccessor PSI_MANAGER = new DataAccessor() { - public PsiManager getImpl(DataContext dataContext) throws NoDataException { - return PsiManager.getInstance(PROJECT.getNotNull(dataContext)); - } - }; - public static final DataAccessor PSI_FILE = new DataAccessor() { - public PsiFile getImpl(DataContext dataContext) throws NoDataException { - return PSI_MANAGER.getNotNull(dataContext).findFile(VIRTUAL_FILE.getNotNull(dataContext)); - } - }; - public static final DataAccessor VIRTUAL_FILE = new DataAccessor.SimpleDataAccessor(PlatformDataKeys.VIRTUAL_FILE.getName()); - public static final DataAccessor VIRTUAL_DIR_OR_PARENT = new DataAccessor() { - public VirtualFile getImpl(DataContext dataContext) throws NoDataException { - VirtualFile virtualFile = VIRTUAL_FILE.getNotNull(dataContext); - return virtualFile.isDirectory() ? virtualFile : virtualFile.getParent(); - } - }; - public static final DataAccessor PROJECT_BASE_DIR = new DataAccessor() { - public VirtualFile getImpl(DataContext dataContext) throws NoDataException { - Project project = PROJECT.getNotNull(dataContext); - return project.getBaseDir(); - } - }; - public static final DataAccessor MODULE_FILE_PATH = new DataAccessor() { - public String getImpl(DataContext dataContext) throws NoDataException { - Module module = MODULE.getNotNull(dataContext); - return module.getModuleFilePath(); - } - }; - - private DataAccessors() { - } -} \ No newline at end of file diff --git a/platform/lang-impl/src/com/intellij/ide/macro/FileDirMacro.java b/platform/lang-impl/src/com/intellij/ide/macro/FileDirMacro.java index dbfffeb11024..a1f8bc0812e3 100644 --- a/platform/lang-impl/src/com/intellij/ide/macro/FileDirMacro.java +++ b/platform/lang-impl/src/com/intellij/ide/macro/FileDirMacro.java @@ -16,7 +16,6 @@ package com.intellij.ide.macro; -import com.intellij.ide.DataAccessors; import com.intellij.ide.IdeBundle; import com.intellij.openapi.actionSystem.DataContext; import com.intellij.openapi.vfs.VirtualFile; @@ -31,16 +30,7 @@ public final class FileDirMacro extends Macro { } public String expand(DataContext dataContext) { - //Project project = (Project)dataContext.getData(DataConstants.PROJECT); - //if (project == null) return null; - //VirtualFile file = (VirtualFile)dataContext.getData(DataConstantsEx.VIRTUAL_FILE); - //if (file == null) return null; - //if (!file.isDirectory()) { - // file = file.getParent(); - // if (file == null) return null; - //} - VirtualFile dir = DataAccessors.VIRTUAL_DIR_OR_PARENT.from(dataContext); - if (dir == null) return null; - return getPath(dir); + VirtualFile vFile = getVirtualDirOrParent(dataContext); + return vFile != null ? getPath(vFile) : null; } } diff --git a/platform/lang-impl/src/com/intellij/ide/macro/FileRelativeDirMacro.java b/platform/lang-impl/src/com/intellij/ide/macro/FileRelativeDirMacro.java index b73d1283d3f6..3eb55b0bf4ea 100644 --- a/platform/lang-impl/src/com/intellij/ide/macro/FileRelativeDirMacro.java +++ b/platform/lang-impl/src/com/intellij/ide/macro/FileRelativeDirMacro.java @@ -16,9 +16,9 @@ package com.intellij.ide.macro; -import com.intellij.ide.DataAccessors; import com.intellij.ide.IdeBundle; import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.actionSystem.PlatformDataKeys; import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.vfs.VfsUtil; import com.intellij.openapi.vfs.VirtualFile; @@ -33,20 +33,12 @@ public class FileRelativeDirMacro extends Macro { } public String expand(DataContext dataContext) { - //Project project = (Project)dataContext.getData(DataConstants.PROJECT); - //if (project == null) return null; - //VirtualFile file = (VirtualFile)dataContext.getData(DataConstantsEx.VIRTUAL_FILE); - //if (file == null) return null; - //if (!file.isDirectory()){ - // file = file.getParent(); - // if (file == null) return null; - //} - final VirtualFile baseDir = DataAccessors.PROJECT_BASE_DIR.from(dataContext); + final VirtualFile baseDir = PlatformDataKeys.PROJECT_FILE_DIRECTORY.getData(dataContext); if (baseDir == null) { return null; } - VirtualFile dir = DataAccessors.VIRTUAL_DIR_OR_PARENT.from(dataContext); + VirtualFile dir = getVirtualDirOrParent(dataContext); if (dir == null) return null; return FileUtil.getRelativePath(VfsUtil.virtualToIoFile(baseDir), VfsUtil.virtualToIoFile(dir)); } diff --git a/platform/lang-impl/src/com/intellij/ide/macro/Macro.java b/platform/lang-impl/src/com/intellij/ide/macro/Macro.java index eb7ad0c247d5..0f29739e5f71 100644 --- a/platform/lang-impl/src/com/intellij/ide/macro/Macro.java +++ b/platform/lang-impl/src/com/intellij/ide/macro/Macro.java @@ -17,6 +17,7 @@ package com.intellij.ide.macro; import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.actionSystem.PlatformDataKeys; import com.intellij.openapi.extensions.ExtensionPointName; import com.intellij.openapi.vfs.VirtualFile; import org.jetbrains.annotations.NonNls; @@ -61,6 +62,15 @@ public abstract class Macro { return new File(getPath(file)); } + @Nullable + protected static VirtualFile getVirtualDirOrParent(DataContext dataContext) { + VirtualFile vFile = PlatformDataKeys.VIRTUAL_FILE.getData(dataContext); + if (vFile != null && !vFile.isDirectory()) { + vFile = vFile.getParent(); + } + return vFile; + } + public static class Silent extends Macro { private final Macro myDelegate; private final String myValue; diff --git a/platform/lang-impl/src/com/intellij/ide/macro/ModuleFileDirMacro.java b/platform/lang-impl/src/com/intellij/ide/macro/ModuleFileDirMacro.java index 8362a2a4101f..7edfa1a3c619 100644 --- a/platform/lang-impl/src/com/intellij/ide/macro/ModuleFileDirMacro.java +++ b/platform/lang-impl/src/com/intellij/ide/macro/ModuleFileDirMacro.java @@ -16,9 +16,10 @@ package com.intellij.ide.macro; -import com.intellij.ide.DataAccessors; import com.intellij.ide.IdeBundle; import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.actionSystem.LangDataKeys; +import com.intellij.openapi.module.Module; import java.io.File; @@ -32,7 +33,8 @@ public final class ModuleFileDirMacro extends Macro { } public String expand(DataContext dataContext) { - final String path = DataAccessors.MODULE_FILE_PATH.from(dataContext); + final Module module = LangDataKeys.MODULE.getData(dataContext); + final String path = module != null ? module.getModuleFilePath() : null; if (path == null) { return null; } diff --git a/platform/lang-impl/src/com/intellij/ide/macro/ModuleFilePathMacro.java b/platform/lang-impl/src/com/intellij/ide/macro/ModuleFilePathMacro.java index 128550e7f79f..dc9612b295c6 100644 --- a/platform/lang-impl/src/com/intellij/ide/macro/ModuleFilePathMacro.java +++ b/platform/lang-impl/src/com/intellij/ide/macro/ModuleFilePathMacro.java @@ -16,9 +16,10 @@ package com.intellij.ide.macro; -import com.intellij.ide.DataAccessors; import com.intellij.ide.IdeBundle; import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.actionSystem.LangDataKeys; +import com.intellij.openapi.module.Module; public final class ModuleFilePathMacro extends Macro { public String getName() { @@ -30,6 +31,7 @@ public final class ModuleFilePathMacro extends Macro { } public String expand(DataContext dataContext) { - return DataAccessors.MODULE_FILE_PATH.from(dataContext); + final Module module = LangDataKeys.MODULE.getData(dataContext); + return module != null ? module.getModuleFilePath() : null; } } \ No newline at end of file diff --git a/platform/lang-impl/src/com/intellij/ide/macro/ProjectFileDirMacro.java b/platform/lang-impl/src/com/intellij/ide/macro/ProjectFileDirMacro.java index 179a4ab18497..cf86f6eb9386 100644 --- a/platform/lang-impl/src/com/intellij/ide/macro/ProjectFileDirMacro.java +++ b/platform/lang-impl/src/com/intellij/ide/macro/ProjectFileDirMacro.java @@ -16,9 +16,9 @@ package com.intellij.ide.macro; -import com.intellij.ide.DataAccessors; import com.intellij.ide.IdeBundle; import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.actionSystem.PlatformDataKeys; import com.intellij.openapi.vfs.VfsUtil; import com.intellij.openapi.vfs.VirtualFile; import org.jetbrains.annotations.Nullable; @@ -34,7 +34,7 @@ public final class ProjectFileDirMacro extends Macro { @Nullable public String expand(DataContext dataContext) { - final VirtualFile baseDir = DataAccessors.PROJECT_BASE_DIR.from(dataContext); + final VirtualFile baseDir = PlatformDataKeys.PROJECT_FILE_DIRECTORY.getData(dataContext); if (baseDir == null) { return null; } diff --git a/platform/platform-impl/src/com/intellij/ide/DataAccessor.java b/platform/platform-impl/src/com/intellij/ide/DataAccessor.java deleted file mode 100644 index a586e2d748db..000000000000 --- a/platform/platform-impl/src/com/intellij/ide/DataAccessor.java +++ /dev/null @@ -1,121 +0,0 @@ -/* - * Copyright 2000-2009 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 com.intellij.ide; - -import com.intellij.openapi.actionSystem.DataContext; -import com.intellij.openapi.util.Condition; -import com.intellij.util.Function; -import static com.intellij.util.containers.ContainerUtil.map; -import static com.intellij.util.containers.ContainerUtil.skipNulls; - -import java.lang.reflect.Array; -import java.util.List; - -public abstract class DataAccessor { - - public final T from(DataContext dataContext) { - try { - return getNotNull(dataContext); - } catch(NoDataException e) { - return null; - } - } - - protected abstract T getImpl(DataContext dataContext) throws NoDataException; - - public final T getNotNull(DataContext dataContext) throws NoDataException { - T data = getImpl(dataContext); - if (data == null) throw new NoDataException(toString()); - return data; - } - - public static DataAccessor createConvertor(final DataAccessor original, - final Function convertor) { - return new DataAccessor(){ - public T getImpl(DataContext dataContext) throws NoDataException { - return convertor.fun(original.getNotNull(dataContext)); - } - }; - } - - public static DataAccessor createArrayConvertor(final DataAccessor original, final Function convertor, final Class aClass) { - return new DataAccessor() { - public T[] getImpl(DataContext dataContext) throws NoDataException { - List converted = skipNulls(map(original.getNotNull(dataContext), convertor)); - return converted.toArray((T[])Array.newInstance(aClass, converted.size())); - } - }; - } - - public static DataAccessor createConditionalAccessor(DataAccessor accessor, Condition condition) { - return new ConditionalDataAccessor(accessor, condition); - } - - public static class SimpleDataAccessor extends DataAccessor { - private final String myDataConstant; - - public SimpleDataAccessor(String dataConstant) { - myDataConstant = dataConstant; - } - - public T getImpl(DataContext dataContext) throws NoDataException { - T data = (T)dataContext.getData(myDataConstant); - if (data == null) throw new NoDataException(myDataConstant); - return data; - } - } - - public static class SubClassDataAccessor extends DataAccessor { - private final DataAccessor myOriginal; - private final Class mySubClass; - - SubClassDataAccessor(DataAccessor original, Class subClass) { - myOriginal = original; - mySubClass = subClass; - } - - public Sub getImpl(DataContext dataContext) throws NoDataException { - Object data = myOriginal.getNotNull(dataContext); - if (!mySubClass.isInstance(data)) return null; - return (Sub)data; - } - - public static DataAccessor create(DataAccessor accessor, Class subClass) { - return new SubClassDataAccessor(accessor, subClass); - } - } - - private static class ConditionalDataAccessor extends DataAccessor { - private final DataAccessor myOriginal; - private final Condition myCondition; - - public ConditionalDataAccessor(DataAccessor original, Condition condition) { - myOriginal = original; - myCondition = condition; - } - - public T getImpl(DataContext dataContext) throws NoDataException { - T value = myOriginal.getNotNull(dataContext); - return myCondition.value(value) ? value : null; - } - } - - public static class NoDataException extends Exception { - public NoDataException(String missingData) { - super(IdeBundle.message("exception.missing.data", missingData)); - } - } -} From 9e785f14ccf21509db415df2889d88e5615f13cf Mon Sep 17 00:00:00 2001 From: Dmitry Jemerov Date: Tue, 29 Dec 2009 19:30:37 +0300 Subject: [PATCH 49/67] remember size of file chooser dialogs (IDEADEV-42144) --- .../openapi/fileChooser/ex/FileChooserDialogImpl.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/platform/platform-impl/src/com/intellij/openapi/fileChooser/ex/FileChooserDialogImpl.java b/platform/platform-impl/src/com/intellij/openapi/fileChooser/ex/FileChooserDialogImpl.java index f46d15598a28..e5bfa7ca3a55 100644 --- a/platform/platform-impl/src/com/intellij/openapi/fileChooser/ex/FileChooserDialogImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/fileChooser/ex/FileChooserDialogImpl.java @@ -513,4 +513,8 @@ public class FileChooserDialogImpl extends DialogWrapper implements FileChooserD setErrorText(null); } + @Override + protected String getDimensionServiceKey() { + return "FileChooserDialogImpl"; + } } From 759b293a2b3a3baf2eba8431765fe0755212a22e Mon Sep 17 00:00:00 2001 From: Maas van den Berg Date: Thu, 7 Jan 2010 16:05:18 +0300 Subject: [PATCH 50/67] clear inspection icon correctly (IDEADEV-42158) --- .../intellij/openapi/wm/impl/status/TogglePopupHintsPanel.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/platform/lang-impl/src/com/intellij/openapi/wm/impl/status/TogglePopupHintsPanel.java b/platform/lang-impl/src/com/intellij/openapi/wm/impl/status/TogglePopupHintsPanel.java index e88872a4061e..98b893f1c6d9 100644 --- a/platform/lang-impl/src/com/intellij/openapi/wm/impl/status/TogglePopupHintsPanel.java +++ b/platform/lang-impl/src/com/intellij/openapi/wm/impl/status/TogglePopupHintsPanel.java @@ -84,7 +84,8 @@ public class TogglePopupHintsPanel extends JPanel implements StatusBarPatch{ } public void clear() { - + myHectorLabel.setIcon(EMPTY_ICON); + myHectorLabel.setToolTipText(null); } public void updateStatus() { From a2d58c893c0d9f55c69623701fbc8c24dbee74ef Mon Sep 17 00:00:00 2001 From: anna Date: Thu, 7 Jan 2010 18:19:33 +0300 Subject: [PATCH 51/67] rename/move package as everything inside directory --- ...ClassesOrPackagesToNewDirectoryDialog.java | 11 + .../MoveDirectoryWithClassesProcessor.java | 277 ++++++++++++++++++ .../MovePackagesHandler.java | 81 +++-- .../DirectoryAsPackageRenameHandler.java | 104 +++++-- .../after/src1/pack2/UsagesFromBoth.java | 9 + .../movePackage/after/src1/target/empty.txt | 0 .../after/src1/target/pack1/S1.java | 3 + .../movePackage/after/src2/pack1/S2.java | 3 + .../after/src2/pack2/UsagesFromBoth2.java | 9 + .../movePackage/before/src1/pack1/S1.java | 3 + .../before/src1/pack2/UsagesFromBoth.java | 8 + .../movePackage/before/src1/target/empty.txt | 0 .../movePackage/before/src2/pack1/S2.java | 3 + .../before/src2/pack2/UsagesFromBoth2.java | 8 + .../after/src1/pack2/UsagesFromBoth.java | 11 + .../after/src1/target/empty.txt | 0 .../after/src1/target/pack1/S1.java | 3 + .../after/src1/target/pack1/subpack/SS.java | 3 + .../after/src2/pack1/S2.java | 3 + .../after/src2/pack2/UsagesFromBoth2.java | 9 + .../before/src1/pack1/S1.java | 3 + .../before/src1/pack1/subpack/SS.java | 3 + .../before/src1/pack2/UsagesFromBoth.java | 10 + .../before/src1/target/empty.txt | 0 .../before/src2/pack1/S2.java | 3 + .../before/src2/pack2/UsagesFromBoth2.java | 8 + .../MovePackageAsDirectoryTest.java | 82 ++++++ .../src/messages/RefactoringBundle.properties | 2 + 28 files changed, 598 insertions(+), 61 deletions(-) create mode 100644 java/java-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/MoveDirectoryWithClassesProcessor.java create mode 100644 java/java-tests/testData/refactoring/movePackageAsDir/movePackage/after/src1/pack2/UsagesFromBoth.java create mode 100644 java/java-tests/testData/refactoring/movePackageAsDir/movePackage/after/src1/target/empty.txt create mode 100644 java/java-tests/testData/refactoring/movePackageAsDir/movePackage/after/src1/target/pack1/S1.java create mode 100644 java/java-tests/testData/refactoring/movePackageAsDir/movePackage/after/src2/pack1/S2.java create mode 100644 java/java-tests/testData/refactoring/movePackageAsDir/movePackage/after/src2/pack2/UsagesFromBoth2.java create mode 100644 java/java-tests/testData/refactoring/movePackageAsDir/movePackage/before/src1/pack1/S1.java create mode 100644 java/java-tests/testData/refactoring/movePackageAsDir/movePackage/before/src1/pack2/UsagesFromBoth.java create mode 100644 java/java-tests/testData/refactoring/movePackageAsDir/movePackage/before/src1/target/empty.txt create mode 100644 java/java-tests/testData/refactoring/movePackageAsDir/movePackage/before/src2/pack1/S2.java create mode 100644 java/java-tests/testData/refactoring/movePackageAsDir/movePackage/before/src2/pack2/UsagesFromBoth2.java create mode 100644 java/java-tests/testData/refactoring/movePackageAsDir/removeUnresolvedImports/after/src1/pack2/UsagesFromBoth.java create mode 100644 java/java-tests/testData/refactoring/movePackageAsDir/removeUnresolvedImports/after/src1/target/empty.txt create mode 100644 java/java-tests/testData/refactoring/movePackageAsDir/removeUnresolvedImports/after/src1/target/pack1/S1.java create mode 100644 java/java-tests/testData/refactoring/movePackageAsDir/removeUnresolvedImports/after/src1/target/pack1/subpack/SS.java create mode 100644 java/java-tests/testData/refactoring/movePackageAsDir/removeUnresolvedImports/after/src2/pack1/S2.java create mode 100644 java/java-tests/testData/refactoring/movePackageAsDir/removeUnresolvedImports/after/src2/pack2/UsagesFromBoth2.java create mode 100644 java/java-tests/testData/refactoring/movePackageAsDir/removeUnresolvedImports/before/src1/pack1/S1.java create mode 100644 java/java-tests/testData/refactoring/movePackageAsDir/removeUnresolvedImports/before/src1/pack1/subpack/SS.java create mode 100644 java/java-tests/testData/refactoring/movePackageAsDir/removeUnresolvedImports/before/src1/pack2/UsagesFromBoth.java create mode 100644 java/java-tests/testData/refactoring/movePackageAsDir/removeUnresolvedImports/before/src1/target/empty.txt create mode 100644 java/java-tests/testData/refactoring/movePackageAsDir/removeUnresolvedImports/before/src2/pack1/S2.java create mode 100644 java/java-tests/testData/refactoring/movePackageAsDir/removeUnresolvedImports/before/src2/pack2/UsagesFromBoth2.java create mode 100644 java/java-tests/testSrc/com/intellij/refactoring/MovePackageAsDirectoryTest.java diff --git a/java/java-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/MoveClassesOrPackagesToNewDirectoryDialog.java b/java/java-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/MoveClassesOrPackagesToNewDirectoryDialog.java index 32c7f0a48a20..a9e8bab3bfc1 100644 --- a/java/java-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/MoveClassesOrPackagesToNewDirectoryDialog.java +++ b/java/java-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/MoveClassesOrPackagesToNewDirectoryDialog.java @@ -150,6 +150,17 @@ public class MoveClassesOrPackagesToNewDirectoryDialog extends DialogWrapper { refactoringSettings.MOVE_SEARCH_IN_COMMENTS = searchInComments; refactoringSettings.MOVE_SEARCH_FOR_TEXT = searchForTextOccurences; + performRefactoring(project, directory, aPackage, searchInComments, searchForTextOccurences); + } + + @Override + public JComponent getPreferredFocusedComponent() { + return myDestDirectoryField.getTextField(); + } + + protected void performRefactoring(Project project, PsiDirectory directory, PsiPackage aPackage, + boolean searchInComments, + boolean searchForTextOccurences) { final VirtualFile sourceRoot = ProjectRootManager.getInstance(project).getFileIndex().getSourceRootForFile(directory.getVirtualFile()); if (sourceRoot == null) { Messages.showErrorDialog(project, RefactoringBundle.message("destination.directory.does.not.correspond.to.any.package"), diff --git a/java/java-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/MoveDirectoryWithClassesProcessor.java b/java/java-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/MoveDirectoryWithClassesProcessor.java new file mode 100644 index 000000000000..b2cf0d2b546d --- /dev/null +++ b/java/java-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/MoveDirectoryWithClassesProcessor.java @@ -0,0 +1,277 @@ +/* + * Copyright 2000-2009 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. + */ + +/* + * User: anna + * Date: 28-Dec-2009 + */ +package com.intellij.refactoring.move.moveClassesOrPackages; + +import com.intellij.codeInsight.ChangeContextUtil; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.Ref; +import com.intellij.openapi.util.text.StringUtil; +import com.intellij.openapi.vfs.VfsUtil; +import com.intellij.psi.*; +import com.intellij.psi.search.searches.ReferencesSearch; +import com.intellij.psi.util.PsiTreeUtil; +import com.intellij.refactoring.BaseRefactoringProcessor; +import com.intellij.refactoring.RefactoringBundle; +import com.intellij.refactoring.listeners.RefactoringElementListener; +import com.intellij.refactoring.move.MoveCallback; +import com.intellij.refactoring.rename.RenameUtil; +import com.intellij.refactoring.util.NonCodeUsageInfo; +import com.intellij.refactoring.util.RefactoringUIUtil; +import com.intellij.usageView.UsageInfo; +import com.intellij.usageView.UsageViewDescriptor; +import com.intellij.usageView.UsageViewUtil; +import com.intellij.util.IncorrectOperationException; +import com.intellij.util.containers.MultiMap; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.*; + +public class MoveDirectoryWithClassesProcessor extends BaseRefactoringProcessor { + private final PsiDirectory[] myDirectories; + private PsiDirectory myTargetDirectory; + private boolean mySearchInComments; + private boolean mySearchInNonJavaFiles; + private Map myClassesToMove; + private NonCodeUsageInfo[] myNonCodeUsages; + private MoveCallback myMoveCallback; + + public MoveDirectoryWithClassesProcessor(Project project, + PsiDirectory[] directories, + PsiDirectory targetDirectory, + boolean searchInComments, + boolean searchInNonJavaFiles, + boolean includeSelf, + MoveCallback moveCallback) { + super(project); + myDirectories = directories; + myTargetDirectory = targetDirectory; + mySearchInComments = searchInComments; + mySearchInNonJavaFiles = searchInNonJavaFiles; + myMoveCallback = moveCallback; + myClassesToMove = new HashMap(); + for (PsiDirectory dir : directories) { + collectClasses(myClassesToMove, dir, includeSelf ? dir.getParentDirectory() : dir, getTargetDirectory(dir)); + } + } + + @Override + protected UsageViewDescriptor createUsageViewDescriptor(UsageInfo[] usages) { + PsiElement[] elements = new PsiElement[myClassesToMove.size()]; + final PsiClass[] classes = myClassesToMove.keySet().toArray(new PsiClass[myClassesToMove.keySet().size()]); + System.arraycopy(classes, 0, elements, 0, classes.length); + return new MoveClassesOrPackagesViewDescriptor(elements, false, false, getTargetName()); + } + + protected String getTargetName() { + return RefactoringUIUtil.getDescription(getTargetDirectory(null).getTargetDirectory(), false); + } + + @NotNull + @Override + public UsageInfo[] findUsages() { + final List usages = new ArrayList(); + final Set packageNames = new HashSet(); + for (PsiClass psiClass : myClassesToMove.keySet()) { + Collections.addAll(usages, MoveClassesOrPackagesUtil.findUsages(psiClass, mySearchInComments, mySearchInNonJavaFiles, psiClass.getName())); + final String fqName = psiClass.getQualifiedName(); + assert fqName != null; + packageNames.add(StringUtil.getPackageName(fqName)); + } + final JavaPsiFacade psiFacade = JavaPsiFacade.getInstance(myProject); + for (String packageName : packageNames) { + final PsiPackage aPackage = psiFacade.findPackage(packageName); + if (aPackage != null) { + boolean remainsNothing = true; + for (PsiDirectory packageDirectory : aPackage.getDirectories()) { + if (!isUnderRefactoring(packageDirectory)) { + remainsNothing = false; + break; + } + } + if (remainsNothing) { + for (PsiReference reference : ReferencesSearch.search(aPackage)) { + final PsiElement element = reference.getElement(); + final PsiImportStatementBase statementBase = PsiTreeUtil.getParentOfType(element, PsiImportStatementBase.class); + if (statementBase != null && statementBase.isOnDemand()) { + usages.add(new RemoveOnDemandImportStatementsUsageInfo(statementBase)); + } + } + } + } + } + return UsageViewUtil.removeDuplicatedUsages(usages.toArray(new UsageInfo[usages.size()])); + } + + private boolean isUnderRefactoring(PsiDirectory packageDirectory) { + for (PsiDirectory directory : myDirectories) { + if (PsiTreeUtil.isAncestor(directory, packageDirectory, true)) { + return true; + } + } + return false; + } + + + @Override + protected boolean preprocessUsages(Ref refUsages) { + final MultiMap conflicts = new MultiMap(); + for (PsiClass psiClass : myClassesToMove.keySet()) { + try { + myClassesToMove.get(psiClass).checkMove(psiClass); + } + catch (IncorrectOperationException e) { + conflicts.putValue(psiClass, e.getMessage()); + } + } + return showConflicts(conflicts); + } + + @Override + protected void refreshElements(PsiElement[] elements) {} + + @Override + public void performRefactoring(UsageInfo[] usages) { + final Map oldToNewElementsMapping = new HashMap(); + for (PsiClass psiClass : myClassesToMove.keySet()) { + ChangeContextUtil.encodeContextInfo(psiClass, true); + final RefactoringElementListener listener = getTransaction().getElementListener(psiClass); + final PsiClass newClass = MoveClassesOrPackagesUtil.doMoveClass(psiClass, myClassesToMove.get(psiClass).findOrCreateTargetDirectory()); + oldToNewElementsMapping.put(psiClass, newClass); + listener.elementMoved(newClass); + } + for (PsiClass psiClass : myClassesToMove.keySet()) { + ChangeContextUtil.decodeContextInfo(psiClass, null, null); + } + myNonCodeUsages = MoveClassesOrPackagesProcessor.retargetUsages(usages, oldToNewElementsMapping); + for (UsageInfo usage : usages) { + if (usage instanceof RemoveOnDemandImportStatementsUsageInfo) { + final PsiElement element = usage.getElement(); + if (element != null) { + element.delete(); + } + } + } + for (PsiDirectory directory : myDirectories) { + directory.delete(); + } + } + + @Override + protected void performPsiSpoilingRefactoring() { + RenameUtil.renameNonCodeUsages(myProject, myNonCodeUsages); + if (myMoveCallback != null) { + myMoveCallback.refactoringCompleted(); + } + } + + private static void collectClasses(Map classesToMove, + PsiDirectory directory, + PsiDirectory rootDirectory, + @NotNull TargetDirectoryWrapper targetDirectory) { + final PsiElement[] children = directory.getChildren(); + final String relativePath = VfsUtil.getRelativePath(directory.getVirtualFile(), rootDirectory.getVirtualFile(), '/'); + + final TargetDirectoryWrapper newTargetDirectory = relativePath.length() == 0 + ? targetDirectory + : targetDirectory.findOrCreateChild(relativePath); + for (PsiElement child : children) { + if (child instanceof PsiJavaFile) { + for (PsiClass aClass : ((PsiJavaFile)child).getClasses()) { + classesToMove.put(aClass, newTargetDirectory); + } + } + else if (child instanceof PsiDirectory){ + collectClasses(classesToMove, (PsiDirectory)child, directory, newTargetDirectory); + } + } + } + + @Override + protected String getCommandName() { + return RefactoringBundle.message("moving.directories.command"); + } + + public TargetDirectoryWrapper getTargetDirectory(PsiDirectory dir) { + return new TargetDirectoryWrapper(myTargetDirectory); + } + + private static class RemoveOnDemandImportStatementsUsageInfo extends UsageInfo { + public RemoveOnDemandImportStatementsUsageInfo(PsiImportStatementBase statementBase) { + super(statementBase); + } + } + + public static class TargetDirectoryWrapper { + private TargetDirectoryWrapper myParentDirectory; + private PsiDirectory myTargetDirectory; + private String myRelativePath; + + public TargetDirectoryWrapper(PsiDirectory targetDirectory) { + myTargetDirectory = targetDirectory; + } + + public TargetDirectoryWrapper(TargetDirectoryWrapper parentDirectory, String relativePath) { + myParentDirectory = parentDirectory; + myRelativePath = relativePath; + } + + public TargetDirectoryWrapper(PsiDirectory parentDirectory, String relativePath) { + myTargetDirectory = parentDirectory.findSubdirectory(relativePath); + //in case it was null + myParentDirectory = new TargetDirectoryWrapper(parentDirectory); + myRelativePath = relativePath; + } + + public PsiDirectory findOrCreateTargetDirectory() { + if (myTargetDirectory == null) { + final PsiDirectory root = myParentDirectory.findOrCreateTargetDirectory(); + + myTargetDirectory = root.findSubdirectory(myRelativePath); + if (myTargetDirectory == null) { + myTargetDirectory = root.createSubdirectory(myRelativePath); + } + } + return myTargetDirectory; + } + + @Nullable + public PsiDirectory getTargetDirectory() { + return myTargetDirectory; + } + + public TargetDirectoryWrapper findOrCreateChild(String relativePath) { + if (myTargetDirectory != null) { + final PsiDirectory psiDirectory = myTargetDirectory.findSubdirectory(relativePath); + if (psiDirectory != null) { + return new TargetDirectoryWrapper(psiDirectory); + } + } + return new TargetDirectoryWrapper(this, relativePath); + } + + public void checkMove(PsiClass psiClass) throws IncorrectOperationException { + if (myTargetDirectory != null) { + psiClass.getManager().checkMove(psiClass, myTargetDirectory); + } + } + } +} diff --git a/java/java-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/MovePackagesHandler.java b/java/java-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/MovePackagesHandler.java index c07c8ca6dfde..136d2f94b3f0 100644 --- a/java/java-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/MovePackagesHandler.java +++ b/java/java-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/MovePackagesHandler.java @@ -19,21 +19,20 @@ import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.project.Project; import com.intellij.openapi.roots.ProjectRootManager; import com.intellij.openapi.ui.DialogWrapper; -import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.vfs.VirtualFile; -import com.intellij.psi.*; -import com.intellij.psi.search.searches.ReferencesSearch; +import com.intellij.psi.JavaDirectoryService; +import com.intellij.psi.PsiDirectory; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiPackage; +import com.intellij.refactoring.JavaRefactoringSettings; import com.intellij.refactoring.RefactoringBundle; import com.intellij.refactoring.move.MoveCallback; -import com.intellij.refactoring.move.moveFilesOrDirectories.MoveFilesOrDirectoriesUtil; -import com.intellij.refactoring.util.MoveRenameUsageInfo; import com.intellij.refactoring.util.RadioUpDownListener; import com.intellij.refactoring.util.RefactoringUtil; import com.intellij.util.containers.HashSet; import javax.swing.*; import java.awt.*; -import java.util.ArrayList; public class MovePackagesHandler extends MoveClassesOrPackagesHandlerBase { private static final Logger LOG = Logger.getInstance("#com.intellij.refactoring.move.moveClassesOrPackages.MovePackagesHandler"); @@ -50,10 +49,10 @@ public class MovePackagesHandler extends MoveClassesOrPackagesHandlerBase { } public void doMove(final Project project, final PsiElement[] elements, final PsiElement targetContainer, final MoveCallback callback) { - if (targetContainer == null && canMoveOrRearrangePackages(elements) ) { - PsiDirectory[] directories = new PsiDirectory[elements.length]; + if (canMoveOrRearrangePackages(elements) ) { + final PsiDirectory[] directories = new PsiDirectory[elements.length]; System.arraycopy(elements, 0, directories, 0, directories.length); - SelectMoveOrRearrangePackageDialog dialog = new SelectMoveOrRearrangePackageDialog(project, directories); + SelectMoveOrRearrangePackageDialog dialog = new SelectMoveOrRearrangePackageDialog(project, directories, targetContainer == null); dialog.show(); if (!dialog.isOK()) return; @@ -63,40 +62,29 @@ public class MovePackagesHandler extends MoveClassesOrPackagesHandlerBase { } if (dialog.isMoveDirectory()) { - final ArrayList usages = new ArrayList(); - for (PsiDirectory directory : directories) { - final PsiPackage aPackage = JavaDirectoryService.getInstance().getPackage(directory); - if (aPackage != null) { - for (PsiReference reference : ReferencesSearch.search(aPackage, directory.getUseScope())) { - usages.add(new MoveRenameUsageInfo(reference, aPackage)); - } - } + if (targetContainer instanceof PsiDirectory) { + final JavaRefactoringSettings refactoringSettings = JavaRefactoringSettings.getInstance(); + final MoveDirectoryWithClassesProcessor processor = + new MoveDirectoryWithClassesProcessor(project, directories, (PsiDirectory)targetContainer, + refactoringSettings.RENAME_SEARCH_IN_COMMENTS_FOR_PACKAGE, + refactoringSettings.RENAME_SEARCH_IN_COMMENTS_FOR_PACKAGE, true, callback); + processor.run(); } - - final PsiElement[] targetDirectory = new PsiElement[]{targetContainer}; - - MoveFilesOrDirectoriesUtil.doMove(project, elements, targetDirectory, new MoveCallback() { - public void refactoringCompleted() { - if (callback != null) callback.refactoringCompleted(); - if (targetDirectory[0] instanceof PsiDirectory) { - final PsiPackage destPackage = JavaDirectoryService.getInstance().getPackage((PsiDirectory)targetDirectory[0]); - if (destPackage != null) { - for (MoveRenameUsageInfo usage : usages) { - final PsiPackage aPackage = (PsiPackage)usage.getReferencedElement(); - if (aPackage != null) { - final PsiReference reference = usage.getReference(); - if (reference != null) { - final PsiPackage pack = JavaPsiFacade.getInstance(project).findPackage(StringUtil.getQualifiedName(destPackage.getQualifiedName(), aPackage.getName())); - if (pack != null) { - reference.bindToElement(pack); - } - } - } - } - } + else { + new MoveClassesOrPackagesToNewDirectoryDialog(directories[0], new PsiElement[2], callback) { + @Override + protected void performRefactoring(Project project, + final PsiDirectory targetDirectory, + PsiPackage aPackage, + boolean searchInComments, + boolean searchForTextOccurences) { + final MoveDirectoryWithClassesProcessor processor = + new MoveDirectoryWithClassesProcessor(project, directories, targetDirectory, searchInComments, searchForTextOccurences, + true, callback); + processor.run(); } - } - }); + }.show(); + } return; } } @@ -131,10 +119,16 @@ public class MovePackagesHandler extends MoveClassesOrPackagesHandlerBase { private JRadioButton myRbMoveDirectory; private final PsiDirectory[] myDirectories; + private final boolean myRearrangePackagesEnabled; public SelectMoveOrRearrangePackageDialog(Project project, PsiDirectory[] directories) { + this(project, directories, true); + } + + public SelectMoveOrRearrangePackageDialog(Project project, PsiDirectory[] directories, boolean rearrangePackagesEnabled) { super(project, true); myDirectories = directories; + myRearrangePackagesEnabled = rearrangePackagesEnabled; setTitle(RefactoringBundle.message("select.refactoring.title")); init(); } @@ -184,13 +178,14 @@ public class MovePackagesHandler extends MoveClassesOrPackagesHandlerBase { } myRbRearrangePackage = new JRadioButton(); myRbRearrangePackage.setText(rearrangeDescription); + myRbRearrangePackage.setVisible(myRearrangePackagesEnabled); final String moveDirectoryDescription; if (myDirectories.length > 1) { - moveDirectoryDescription = "Move " + myDirectories.length + " directories to another directory"; + moveDirectoryDescription = "Move everything from " + myDirectories.length + " directories to another directory"; } else { - moveDirectoryDescription = "Move directory " + myDirectories[0].getVirtualFile().getPresentableUrl() + " to another directory"; + moveDirectoryDescription = "Move everything from " + myDirectories[0].getVirtualFile().getPresentableUrl() + " to another directory"; } myRbMoveDirectory = new JRadioButton(); myRbMoveDirectory.setMnemonic('d'); diff --git a/java/java-impl/src/com/intellij/refactoring/rename/DirectoryAsPackageRenameHandler.java b/java/java-impl/src/com/intellij/refactoring/rename/DirectoryAsPackageRenameHandler.java index ac3aa984c0b3..d8c69e078e04 100644 --- a/java/java-impl/src/com/intellij/refactoring/rename/DirectoryAsPackageRenameHandler.java +++ b/java/java-impl/src/com/intellij/refactoring/rename/DirectoryAsPackageRenameHandler.java @@ -22,11 +22,17 @@ import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.editor.ScrollType; import com.intellij.openapi.project.Project; +import com.intellij.openapi.roots.ProjectFileIndex; +import com.intellij.openapi.roots.ProjectRootManager; +import com.intellij.openapi.ui.DialogWrapper; import com.intellij.openapi.ui.Messages; +import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.*; +import com.intellij.psi.search.GlobalSearchScope; import com.intellij.refactoring.RefactoringBundle; import com.intellij.refactoring.lang.TitledHandler; +import com.intellij.refactoring.move.moveClassesOrPackages.MoveDirectoryWithClassesProcessor; import org.jetbrains.annotations.NotNull; /** @@ -37,7 +43,7 @@ public class DirectoryAsPackageRenameHandler implements RenameHandler, TitledHan public boolean isAvailableOnDataContext(final DataContext dataContext) { final PsiElement element = PsiElementRenameHandler.getElement(dataContext); - return element instanceof PsiDirectory; + return element instanceof PsiDirectory && ProjectRootManager.getInstance(element.getProject()).getFileIndex().isInContent(((PsiDirectory)element).getVirtualFile()); } public boolean isRenaming(final DataContext dataContext) { @@ -59,9 +65,9 @@ public class DirectoryAsPackageRenameHandler implements RenameHandler, TitledHan doRename(element, project, element, editor); } - public static void doRename(PsiElement element, Project project, PsiElement nameSuggestionContext, Editor editor) { - PsiDirectory psiDirectory = (PsiDirectory)element; - PsiPackage aPackage = JavaDirectoryService.getInstance().getPackage(psiDirectory); + public static void doRename(PsiElement element, final Project project, PsiElement nameSuggestionContext, Editor editor) { + final PsiDirectory psiDirectory = (PsiDirectory)element; + final PsiPackage aPackage = JavaDirectoryService.getInstance().getPackage(psiDirectory); final String qualifiedName = aPackage != null ? aPackage.getQualifiedName() : ""; if (aPackage == null || qualifiedName.length() == 0/*default package*/ || !JavaPsiFacade.getInstance(project).getNameHelper().isIdentifier(psiDirectory.getName())) { @@ -74,25 +80,87 @@ public class DirectoryAsPackageRenameHandler implements RenameHandler, TitledHan PsiElementRenameHandler.rename(aPackage, project, nameSuggestionContext, editor); } else { // the directory corresponds to a package that has multiple associated directories - StringBuffer message = new StringBuffer(); - RenameUtil.buildPackagePrefixChangedMessage(virtualFiles, message, qualifiedName); - buildMultipleDirectoriesInPackageMessage(message, aPackage, directories); - message.append(RefactoringBundle.message("directories.and.all.references.to.package.will.be.renamed", psiDirectory.getVirtualFile().getPresentableUrl())); - int ret = - Messages.showDialog(project, message.toString(), RefactoringBundle.message("warning.title"), - new String[]{ - RefactoringBundle.message("rename.package.button.text"), - RefactoringBundle.message("rename.directory.button.text"), - CommonBundle.getCancelButtonText()}, 0, Messages.getWarningIcon()); - if (ret == 0) { - PsiElementRenameHandler.rename(aPackage, project, nameSuggestionContext, editor); - } else if (ret == 1){ - PsiElementRenameHandler.rename(psiDirectory, project, nameSuggestionContext, editor); + final ProjectFileIndex projectFileIndex = ProjectRootManager.getInstance(project).getFileIndex(); + boolean inLib = false; + for (PsiDirectory directory : directories) { + inLib |= !projectFileIndex.isInContent(directory.getVirtualFile()); + } + + final PsiDirectory[] projectDirectories = aPackage.getDirectories(GlobalSearchScope.projectScope(project)); + if (inLib) { + final String promptMessage = "Package \'" + + aPackage.getName() + + "\' contains directories in libraries which cannot be renamed. Do you want to rename current directory"; + if (projectDirectories.length > 0) { + int ret = Messages + .showDialog(project, promptMessage + " or all directories in project?", RefactoringBundle.message("warning.title"), + new String[]{RefactoringBundle.message("rename.current.directory"), + RefactoringBundle.message("rename.directories"), CommonBundle.getCancelButtonText()}, 0, + Messages.getWarningIcon()); + renameDirs(project, nameSuggestionContext, editor, psiDirectory, aPackage, ret == 0 ? new PsiDirectory[] {psiDirectory} : projectDirectories); + } + else { + if (Messages.showDialog(project, promptMessage + "?", RefactoringBundle.message("warning.title"), + new String[]{CommonBundle.getOkButtonText(), CommonBundle.getCancelButtonText()}, 0, + Messages.getWarningIcon()) == DialogWrapper.OK_EXIT_CODE) { + renameDirs(project, nameSuggestionContext, editor, psiDirectory, aPackage, psiDirectory); + } + } + } + else { + final StringBuffer message = new StringBuffer(); + RenameUtil.buildPackagePrefixChangedMessage(virtualFiles, message, qualifiedName); + buildMultipleDirectoriesInPackageMessage(message, aPackage, directories); + message.append(RefactoringBundle.message("directories.and.all.references.to.package.will.be.renamed", + psiDirectory.getVirtualFile().getPresentableUrl())); + int ret = Messages.showDialog(project, message.toString(), RefactoringBundle.message("warning.title"), + new String[]{RefactoringBundle.message("rename.package.button.text"), + RefactoringBundle.message("rename.directory.button.text"), CommonBundle.getCancelButtonText()}, 0, + Messages.getWarningIcon()); + if (ret == 0) { + PsiElementRenameHandler.rename(aPackage, project, nameSuggestionContext, editor); + } + else if (ret == 1) { + renameDirs(project, nameSuggestionContext, editor, psiDirectory, aPackage, psiDirectory); + } } } } } + private static void renameDirs(final Project project, + final PsiElement nameSuggestionContext, + final Editor editor, + final PsiDirectory contextDirectory, + final PsiPackage aPackage, + final PsiDirectory... dirsToRename) { + final RenameDialog dialog = new RenameDialog(project, contextDirectory, nameSuggestionContext, editor) { + @Override + protected void doAction() { + final String newName = StringUtil.getQualifiedName(StringUtil.getPackageName(aPackage.getQualifiedName()), getNewName()); + final MoveDirectoryWithClassesProcessor moveProcessor = + new MoveDirectoryWithClassesProcessor(project, dirsToRename, null, isSearchInComments(), isSearchInNonJavaFiles(), false, null) { + @Override + public TargetDirectoryWrapper getTargetDirectory(final PsiDirectory dir) { + return new TargetDirectoryWrapper(dir.getParentDirectory(), getNewName()); + } + + @Override + protected String getTargetName() { + return newName; + } + + @Override + protected String getCommandName() { + return dirsToRename.length == 1 ? "Rename directory" : "Rename directories"; + } + }; + invokeRefactoring(moveProcessor); + } + }; + dialog.show(); + } + public static void buildMultipleDirectoriesInPackageMessage(StringBuffer message, PsiPackage aPackage, PsiDirectory[] directories) { diff --git a/java/java-tests/testData/refactoring/movePackageAsDir/movePackage/after/src1/pack2/UsagesFromBoth.java b/java/java-tests/testData/refactoring/movePackageAsDir/movePackage/after/src1/pack2/UsagesFromBoth.java new file mode 100644 index 000000000000..6d4410fd6ae6 --- /dev/null +++ b/java/java-tests/testData/refactoring/movePackageAsDir/movePackage/after/src1/pack2/UsagesFromBoth.java @@ -0,0 +1,9 @@ +package pack2; + +import pack1.*; +import target.pack1.S1; + +public class UsagesFromBoth { + S1 s1; + S2 s2; +} diff --git a/java/java-tests/testData/refactoring/movePackageAsDir/movePackage/after/src1/target/empty.txt b/java/java-tests/testData/refactoring/movePackageAsDir/movePackage/after/src1/target/empty.txt new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/java/java-tests/testData/refactoring/movePackageAsDir/movePackage/after/src1/target/pack1/S1.java b/java/java-tests/testData/refactoring/movePackageAsDir/movePackage/after/src1/target/pack1/S1.java new file mode 100644 index 000000000000..bafd60dc4fa1 --- /dev/null +++ b/java/java-tests/testData/refactoring/movePackageAsDir/movePackage/after/src1/target/pack1/S1.java @@ -0,0 +1,3 @@ +package target.pack1; + +public class S1{} diff --git a/java/java-tests/testData/refactoring/movePackageAsDir/movePackage/after/src2/pack1/S2.java b/java/java-tests/testData/refactoring/movePackageAsDir/movePackage/after/src2/pack1/S2.java new file mode 100644 index 000000000000..0bd2d2024dc6 --- /dev/null +++ b/java/java-tests/testData/refactoring/movePackageAsDir/movePackage/after/src2/pack1/S2.java @@ -0,0 +1,3 @@ +package pack1; + +public class S2{} diff --git a/java/java-tests/testData/refactoring/movePackageAsDir/movePackage/after/src2/pack2/UsagesFromBoth2.java b/java/java-tests/testData/refactoring/movePackageAsDir/movePackage/after/src2/pack2/UsagesFromBoth2.java new file mode 100644 index 000000000000..9b53f3854379 --- /dev/null +++ b/java/java-tests/testData/refactoring/movePackageAsDir/movePackage/after/src2/pack2/UsagesFromBoth2.java @@ -0,0 +1,9 @@ +package pack2; + +import pack1.*; +import target.pack1.S1; + +public class UsagesFromBoth2 { + S1 s1; + S2 s2; +} diff --git a/java/java-tests/testData/refactoring/movePackageAsDir/movePackage/before/src1/pack1/S1.java b/java/java-tests/testData/refactoring/movePackageAsDir/movePackage/before/src1/pack1/S1.java new file mode 100644 index 000000000000..c0a5f31dbfba --- /dev/null +++ b/java/java-tests/testData/refactoring/movePackageAsDir/movePackage/before/src1/pack1/S1.java @@ -0,0 +1,3 @@ +package pack1; + +public class S1{} diff --git a/java/java-tests/testData/refactoring/movePackageAsDir/movePackage/before/src1/pack2/UsagesFromBoth.java b/java/java-tests/testData/refactoring/movePackageAsDir/movePackage/before/src1/pack2/UsagesFromBoth.java new file mode 100644 index 000000000000..906b1fe953d6 --- /dev/null +++ b/java/java-tests/testData/refactoring/movePackageAsDir/movePackage/before/src1/pack2/UsagesFromBoth.java @@ -0,0 +1,8 @@ +package pack2; + +import pack1.*; + +public class UsagesFromBoth { + S1 s1; + S2 s2; +} diff --git a/java/java-tests/testData/refactoring/movePackageAsDir/movePackage/before/src1/target/empty.txt b/java/java-tests/testData/refactoring/movePackageAsDir/movePackage/before/src1/target/empty.txt new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/java/java-tests/testData/refactoring/movePackageAsDir/movePackage/before/src2/pack1/S2.java b/java/java-tests/testData/refactoring/movePackageAsDir/movePackage/before/src2/pack1/S2.java new file mode 100644 index 000000000000..0bd2d2024dc6 --- /dev/null +++ b/java/java-tests/testData/refactoring/movePackageAsDir/movePackage/before/src2/pack1/S2.java @@ -0,0 +1,3 @@ +package pack1; + +public class S2{} diff --git a/java/java-tests/testData/refactoring/movePackageAsDir/movePackage/before/src2/pack2/UsagesFromBoth2.java b/java/java-tests/testData/refactoring/movePackageAsDir/movePackage/before/src2/pack2/UsagesFromBoth2.java new file mode 100644 index 000000000000..d8ece1cab742 --- /dev/null +++ b/java/java-tests/testData/refactoring/movePackageAsDir/movePackage/before/src2/pack2/UsagesFromBoth2.java @@ -0,0 +1,8 @@ +package pack2; + +import pack1.*; + +public class UsagesFromBoth2 { + S1 s1; + S2 s2; +} diff --git a/java/java-tests/testData/refactoring/movePackageAsDir/removeUnresolvedImports/after/src1/pack2/UsagesFromBoth.java b/java/java-tests/testData/refactoring/movePackageAsDir/removeUnresolvedImports/after/src1/pack2/UsagesFromBoth.java new file mode 100644 index 000000000000..e21505a4f182 --- /dev/null +++ b/java/java-tests/testData/refactoring/movePackageAsDir/removeUnresolvedImports/after/src1/pack2/UsagesFromBoth.java @@ -0,0 +1,11 @@ +package pack2; + +import pack1.*; +import target.pack1.S1; +import target.pack1.subpack.SS; + +public class UsagesFromBoth { + S1 s1; + S2 s2; + SS ss; +} diff --git a/java/java-tests/testData/refactoring/movePackageAsDir/removeUnresolvedImports/after/src1/target/empty.txt b/java/java-tests/testData/refactoring/movePackageAsDir/removeUnresolvedImports/after/src1/target/empty.txt new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/java/java-tests/testData/refactoring/movePackageAsDir/removeUnresolvedImports/after/src1/target/pack1/S1.java b/java/java-tests/testData/refactoring/movePackageAsDir/removeUnresolvedImports/after/src1/target/pack1/S1.java new file mode 100644 index 000000000000..bafd60dc4fa1 --- /dev/null +++ b/java/java-tests/testData/refactoring/movePackageAsDir/removeUnresolvedImports/after/src1/target/pack1/S1.java @@ -0,0 +1,3 @@ +package target.pack1; + +public class S1{} diff --git a/java/java-tests/testData/refactoring/movePackageAsDir/removeUnresolvedImports/after/src1/target/pack1/subpack/SS.java b/java/java-tests/testData/refactoring/movePackageAsDir/removeUnresolvedImports/after/src1/target/pack1/subpack/SS.java new file mode 100644 index 000000000000..39cf0b625314 --- /dev/null +++ b/java/java-tests/testData/refactoring/movePackageAsDir/removeUnresolvedImports/after/src1/target/pack1/subpack/SS.java @@ -0,0 +1,3 @@ +package target.pack1.subpack; + +public class SS {} diff --git a/java/java-tests/testData/refactoring/movePackageAsDir/removeUnresolvedImports/after/src2/pack1/S2.java b/java/java-tests/testData/refactoring/movePackageAsDir/removeUnresolvedImports/after/src2/pack1/S2.java new file mode 100644 index 000000000000..0bd2d2024dc6 --- /dev/null +++ b/java/java-tests/testData/refactoring/movePackageAsDir/removeUnresolvedImports/after/src2/pack1/S2.java @@ -0,0 +1,3 @@ +package pack1; + +public class S2{} diff --git a/java/java-tests/testData/refactoring/movePackageAsDir/removeUnresolvedImports/after/src2/pack2/UsagesFromBoth2.java b/java/java-tests/testData/refactoring/movePackageAsDir/removeUnresolvedImports/after/src2/pack2/UsagesFromBoth2.java new file mode 100644 index 000000000000..9b53f3854379 --- /dev/null +++ b/java/java-tests/testData/refactoring/movePackageAsDir/removeUnresolvedImports/after/src2/pack2/UsagesFromBoth2.java @@ -0,0 +1,9 @@ +package pack2; + +import pack1.*; +import target.pack1.S1; + +public class UsagesFromBoth2 { + S1 s1; + S2 s2; +} diff --git a/java/java-tests/testData/refactoring/movePackageAsDir/removeUnresolvedImports/before/src1/pack1/S1.java b/java/java-tests/testData/refactoring/movePackageAsDir/removeUnresolvedImports/before/src1/pack1/S1.java new file mode 100644 index 000000000000..c0a5f31dbfba --- /dev/null +++ b/java/java-tests/testData/refactoring/movePackageAsDir/removeUnresolvedImports/before/src1/pack1/S1.java @@ -0,0 +1,3 @@ +package pack1; + +public class S1{} diff --git a/java/java-tests/testData/refactoring/movePackageAsDir/removeUnresolvedImports/before/src1/pack1/subpack/SS.java b/java/java-tests/testData/refactoring/movePackageAsDir/removeUnresolvedImports/before/src1/pack1/subpack/SS.java new file mode 100644 index 000000000000..869423cf5146 --- /dev/null +++ b/java/java-tests/testData/refactoring/movePackageAsDir/removeUnresolvedImports/before/src1/pack1/subpack/SS.java @@ -0,0 +1,3 @@ +package pack1.subpack; + +public class SS {} diff --git a/java/java-tests/testData/refactoring/movePackageAsDir/removeUnresolvedImports/before/src1/pack2/UsagesFromBoth.java b/java/java-tests/testData/refactoring/movePackageAsDir/removeUnresolvedImports/before/src1/pack2/UsagesFromBoth.java new file mode 100644 index 000000000000..b0f9a94641d2 --- /dev/null +++ b/java/java-tests/testData/refactoring/movePackageAsDir/removeUnresolvedImports/before/src1/pack2/UsagesFromBoth.java @@ -0,0 +1,10 @@ +package pack2; + +import pack1.*; +import pack1.subpack.*; + +public class UsagesFromBoth { + S1 s1; + S2 s2; + SS ss; +} diff --git a/java/java-tests/testData/refactoring/movePackageAsDir/removeUnresolvedImports/before/src1/target/empty.txt b/java/java-tests/testData/refactoring/movePackageAsDir/removeUnresolvedImports/before/src1/target/empty.txt new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/java/java-tests/testData/refactoring/movePackageAsDir/removeUnresolvedImports/before/src2/pack1/S2.java b/java/java-tests/testData/refactoring/movePackageAsDir/removeUnresolvedImports/before/src2/pack1/S2.java new file mode 100644 index 000000000000..0bd2d2024dc6 --- /dev/null +++ b/java/java-tests/testData/refactoring/movePackageAsDir/removeUnresolvedImports/before/src2/pack1/S2.java @@ -0,0 +1,3 @@ +package pack1; + +public class S2{} diff --git a/java/java-tests/testData/refactoring/movePackageAsDir/removeUnresolvedImports/before/src2/pack2/UsagesFromBoth2.java b/java/java-tests/testData/refactoring/movePackageAsDir/removeUnresolvedImports/before/src2/pack2/UsagesFromBoth2.java new file mode 100644 index 000000000000..d8ece1cab742 --- /dev/null +++ b/java/java-tests/testData/refactoring/movePackageAsDir/removeUnresolvedImports/before/src2/pack2/UsagesFromBoth2.java @@ -0,0 +1,8 @@ +package pack2; + +import pack1.*; + +public class UsagesFromBoth2 { + S1 s1; + S2 s2; +} diff --git a/java/java-tests/testSrc/com/intellij/refactoring/MovePackageAsDirectoryTest.java b/java/java-tests/testSrc/com/intellij/refactoring/MovePackageAsDirectoryTest.java new file mode 100644 index 000000000000..fdd9074160d6 --- /dev/null +++ b/java/java-tests/testSrc/com/intellij/refactoring/MovePackageAsDirectoryTest.java @@ -0,0 +1,82 @@ + +package com.intellij.refactoring; + +import com.intellij.JavaTestUtil; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.fileEditor.FileDocumentManager; +import com.intellij.openapi.roots.ContentEntry; +import com.intellij.openapi.roots.ModifiableRootModel; +import com.intellij.openapi.roots.ModuleRootManager; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.psi.JavaPsiFacade; +import com.intellij.psi.PsiDirectory; +import com.intellij.psi.PsiPackage; +import com.intellij.refactoring.move.moveClassesOrPackages.MoveDirectoryWithClassesProcessor; + +import java.util.Arrays; +import java.util.Comparator; + +public class MovePackageAsDirectoryTest extends MultiFileTestCase { + + @Override + protected String getTestDataPath() { + return JavaTestUtil.getJavaTestDataPath(); + } + + protected String getTestRoot() { + return "/refactoring/movePackageAsDir/"; + } + + public void testMovePackage() throws Exception { + doTest(createAction("pack1", "target")); + } + + public void testRemoveUnresolvedImports() throws Exception { + doTest(createAction("pack1", "target")); + } + + private PerformAction createAction(final String packageName, final String targetPackageName) { + return new PerformAction() { + public void performAction(VirtualFile rootDir, VirtualFile rootAfter) throws Exception { + final JavaPsiFacade psiFacade = JavaPsiFacade.getInstance(myProject); + final Comparator directoryComparator = new Comparator() { + public int compare(PsiDirectory o1, PsiDirectory o2) { + return o1.getVirtualFile().getPresentableUrl().compareTo(o2.getVirtualFile().getPresentableUrl()); + } + }; + + final PsiPackage sourcePackage = psiFacade.findPackage(packageName); + assertNotNull(sourcePackage); + final PsiDirectory[] srcDirectories = sourcePackage.getDirectories(); + assertEquals(srcDirectories.length, 2); + Arrays.sort(srcDirectories, directoryComparator); + + final PsiPackage targetPackage = psiFacade.findPackage(targetPackageName); + assertNotNull(targetPackage); + final PsiDirectory[] targetDirectories = targetPackage.getDirectories(); + Arrays.sort(targetDirectories, directoryComparator); + assertTrue(targetDirectories.length > 0); + + new MoveDirectoryWithClassesProcessor(getProject(), new PsiDirectory[]{srcDirectories[0]}, targetDirectories[0], false, false, true, null).run(); + FileDocumentManager.getInstance().saveAllDocuments(); + } + }; + } + + protected void setupProject(VirtualFile rootDir) { + final ModifiableRootModel rootModel = ModuleRootManager.getInstance(myModule).getModifiableModel(); + final ContentEntry contentEntry = rootModel.addContentEntry(rootDir); + final VirtualFile[] children = rootDir.getChildren(); + for (VirtualFile child : children) { + if (child.getName().startsWith("src")) { + contentEntry.addSourceFolder(child, false); + } + } + + ApplicationManager.getApplication().runWriteAction(new Runnable() { + public void run() { + rootModel.commit(); + } + }); + } +} diff --git a/platform/platform-resources-en/src/messages/RefactoringBundle.properties b/platform/platform-resources-en/src/messages/RefactoringBundle.properties index 25abb7ea4dca..64254c508fa9 100644 --- a/platform/platform-resources-en/src/messages/RefactoringBundle.properties +++ b/platform/platform-resources-en/src/messages/RefactoringBundle.properties @@ -219,6 +219,8 @@ multiple.directories.correspond.to.package=Multiple directories correspond to pa directories.and.all.references.to.package.will.be.renamed=\n\nDo you want to rename the whole package or directory \n{0} only? rename.package.button.text=Rename &package rename.directory.button.text=Rename &directory +rename.directories= Rename &all +rename.current.directory= Rename ¤t warning.title=Warning replace.constructor.with.factory.method.title=Replace Constructor With Factory Method class.does.not.have.implicit.default.consructor=Class {0} does not have implicit default consructor. From 09e56b98c65dc8fd227471af0af1b1c4db4d9715 Mon Sep 17 00:00:00 2001 From: anna Date: Thu, 7 Jan 2010 21:21:57 +0300 Subject: [PATCH 52/67] move packages/classes to the 'drop' directory prserving src folders --- ...ClassesOrPackagesToNewDirectoryDialog.java | 32 ++++++++++++++++++- ...veClassesOrPackagesToNewDirectoryForm.form | 31 +++++++++++------- .../MovePackagesHandler.java | 28 ++++++++-------- 3 files changed, 66 insertions(+), 25 deletions(-) diff --git a/java/java-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/MoveClassesOrPackagesToNewDirectoryDialog.java b/java/java-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/MoveClassesOrPackagesToNewDirectoryDialog.java index a9e8bab3bfc1..542201bbb395 100644 --- a/java/java-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/MoveClassesOrPackagesToNewDirectoryDialog.java +++ b/java/java-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/MoveClassesOrPackagesToNewDirectoryDialog.java @@ -21,6 +21,7 @@ import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.fileChooser.FileChooser; import com.intellij.openapi.fileChooser.FileChooserDescriptor; import com.intellij.openapi.project.Project; +import com.intellij.openapi.roots.ProjectFileIndex; import com.intellij.openapi.roots.ProjectRootManager; import com.intellij.openapi.ui.DialogWrapper; import com.intellij.openapi.ui.Messages; @@ -45,6 +46,8 @@ import javax.swing.*; import javax.swing.event.DocumentEvent; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; +import java.util.HashSet; +import java.util.Set; /** * @author ven @@ -58,6 +61,12 @@ public class MoveClassesOrPackagesToNewDirectoryDialog extends DialogWrapper { public MoveClassesOrPackagesToNewDirectoryDialog(@NotNull final PsiDirectory directory, PsiElement[] elementsToMove, final MoveCallback moveCallback) { + this(directory, elementsToMove, true, moveCallback); + } + + public MoveClassesOrPackagesToNewDirectoryDialog(@NotNull final PsiDirectory directory, PsiElement[] elementsToMove, + boolean canShowPreserveSourceRoots, + final MoveCallback moveCallback) { super(false); setTitle(MoveHandler.REFACTORING_NAME); myDirectory = directory; @@ -93,6 +102,24 @@ public class MoveClassesOrPackagesToNewDirectoryDialog extends DialogWrapper { } }); + if (canShowPreserveSourceRoots) { + final Set sourceRoots = new HashSet(); + final ProjectFileIndex fileIndex = ProjectRootManager.getInstance(directory.getProject()).getFileIndex(); + for (PsiElement element : elementsToMove) { + if (element instanceof PsiPackage) { + for (PsiDirectory psiDirectory : ((PsiPackage)element).getDirectories()) { + sourceRoots.add(fileIndex.getSourceRootForFile(psiDirectory.getVirtualFile())); + } + } else if (element instanceof PsiClass) { + final PsiDirectory psiDirectory = element.getContainingFile().getContainingDirectory(); + LOG.assertTrue(psiDirectory != null); + if (psiDirectory != null) { + sourceRoots.add(psiDirectory.getVirtualFile()); + } + } + } + myPreserveSourceRoot.setVisible(sourceRoots.size() > 1); + } init(); } @@ -101,6 +128,7 @@ public class MoveClassesOrPackagesToNewDirectoryDialog extends DialogWrapper { private JCheckBox mySearchInCommentsAndStringsCheckBox; private JPanel myRootPanel; private JLabel myNameLabel; + private JCheckBox myPreserveSourceRoot; private boolean isSearchInNonJavaFiles() { return mySearchForTextOccurrencesCheckBox.isSelected(); @@ -168,7 +196,9 @@ public class MoveClassesOrPackagesToNewDirectoryDialog extends DialogWrapper { return; } final JavaRefactoringFactory factory = JavaRefactoringFactory.getInstance(project); - final MoveDestination destination = factory.createSourceRootMoveDestination(aPackage.getQualifiedName(), sourceRoot); + final MoveDestination destination = myPreserveSourceRoot.isSelected() && myPreserveSourceRoot.isVisible() + ? factory.createSourceFolderPreservingMoveDestination(aPackage.getQualifiedName()) + : factory.createSourceRootMoveDestination(aPackage.getQualifiedName(), sourceRoot); MoveClassesOrPackagesProcessor processor = new MoveClassesOrPackagesProcessor(myDirectory.getProject(), myElementsToMove, destination, searchInComments, searchForTextOccurences, diff --git a/java/java-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/MoveClassesOrPackagesToNewDirectoryForm.form b/java/java-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/MoveClassesOrPackagesToNewDirectoryForm.form index 3f5fec5d3902..77610b90cba1 100644 --- a/java/java-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/MoveClassesOrPackagesToNewDirectoryForm.form +++ b/java/java-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/MoveClassesOrPackagesToNewDirectoryForm.form @@ -1,9 +1,9 @@ - + - + @@ -16,14 +16,6 @@ - - - - - - - - @@ -35,7 +27,7 @@ - + @@ -58,6 +50,23 @@ + + + + + + + + + + + + + + + + + diff --git a/java/java-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/MovePackagesHandler.java b/java/java-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/MovePackagesHandler.java index 136d2f94b3f0..388ba520fda2 100644 --- a/java/java-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/MovePackagesHandler.java +++ b/java/java-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/MovePackagesHandler.java @@ -71,19 +71,21 @@ public class MovePackagesHandler extends MoveClassesOrPackagesHandlerBase { processor.run(); } else { - new MoveClassesOrPackagesToNewDirectoryDialog(directories[0], new PsiElement[2], callback) { - @Override - protected void performRefactoring(Project project, - final PsiDirectory targetDirectory, - PsiPackage aPackage, - boolean searchInComments, - boolean searchForTextOccurences) { - final MoveDirectoryWithClassesProcessor processor = - new MoveDirectoryWithClassesProcessor(project, directories, targetDirectory, searchInComments, searchForTextOccurences, - true, callback); - processor.run(); - } - }.show(); + final MoveClassesOrPackagesToNewDirectoryDialog dlg = + new MoveClassesOrPackagesToNewDirectoryDialog(directories[0], new PsiElement[2], false, callback) { + @Override + protected void performRefactoring(Project project, + final PsiDirectory targetDirectory, + PsiPackage aPackage, + boolean searchInComments, + boolean searchForTextOccurences) { + final MoveDirectoryWithClassesProcessor processor = + new MoveDirectoryWithClassesProcessor(project, directories, targetDirectory, searchInComments, searchForTextOccurences, + true, callback); + processor.run(); + } + }; + dlg.show(); } return; } From acd41ec13cb7dc289e22dae0a01104c1f3d03b17 Mon Sep 17 00:00:00 2001 From: Dmitry Avdeev Date: Mon, 11 Jan 2010 15:20:47 +0300 Subject: [PATCH 53/67] plugin.xml support: project scope for dependencies --- plugins/devkit/src/dom/impl/IdeaPluginConverter.java | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/plugins/devkit/src/dom/impl/IdeaPluginConverter.java b/plugins/devkit/src/dom/impl/IdeaPluginConverter.java index 0aead2ac5b9b..3e5e18deeb30 100644 --- a/plugins/devkit/src/dom/impl/IdeaPluginConverter.java +++ b/plugins/devkit/src/dom/impl/IdeaPluginConverter.java @@ -15,8 +15,6 @@ */ package org.jetbrains.idea.devkit.dom.impl; -import com.intellij.openapi.module.Module; -import com.intellij.openapi.module.ModuleUtil; import com.intellij.openapi.project.Project; import com.intellij.psi.search.GlobalSearchScope; import com.intellij.psi.xml.XmlFile; @@ -66,10 +64,7 @@ public class IdeaPluginConverter extends ResolvingConverter { public static Collection collectAllVisiblePlugins(@NotNull XmlFile xmlFile) { Project project = xmlFile.getProject(); - Module module = ModuleUtil.findModuleForPsiElement(xmlFile); - - GlobalSearchScope scope = module == null ? GlobalSearchScope.allScope(project) : - GlobalSearchScope.moduleWithDependenciesAndLibrariesScope(module, true); + GlobalSearchScope scope = GlobalSearchScope.allScope(project); List> files = DomService.getInstance().getFileElements(IdeaPlugin.class, project, scope); return ContainerUtil.map(files, new Function, IdeaPlugin>() { public IdeaPlugin fun(DomFileElement ideaPluginDomFileElement) { From b28cc0b46d928436369230cafbe2328512780c50 Mon Sep 17 00:00:00 2001 From: "Kirill.Safonov" Date: Mon, 11 Jan 2010 19:02:09 +0300 Subject: [PATCH 54/67] postponed formatting: fix performance regress --- .../source/PostprocessReformattingAspect.java | 23 +++++++++++-------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/psi/impl/source/PostprocessReformattingAspect.java b/platform/lang-impl/src/com/intellij/psi/impl/source/PostprocessReformattingAspect.java index 5003994f2c83..a462f520b1e7 100644 --- a/platform/lang-impl/src/com/intellij/psi/impl/source/PostprocessReformattingAspect.java +++ b/platform/lang-impl/src/com/intellij/psi/impl/source/PostprocessReformattingAspect.java @@ -215,14 +215,13 @@ public class PostprocessReformattingAspect implements PomModelAspect, Disposable public void run() { if (isDisabled()) return; try { - for (final FileViewProvider viewProvider : myUpdatedProviders) { + FileViewProvider[] viewProviders = myUpdatedProviders.toArray(new FileViewProvider[myUpdatedProviders.size()]); + for (final FileViewProvider viewProvider : viewProviders) { doPostponedFormatting(viewProvider); } } finally { LOG.assertTrue(myReformatElements.isEmpty()); - myUpdatedProviders.clear(); - myReformatElements.clear(); } } }); @@ -231,13 +230,19 @@ public class PostprocessReformattingAspect implements PomModelAspect, Disposable public void doPostponedFormatting(final FileViewProvider viewProvider) { atomic(new Runnable() { public void run() { - if (isDisabled()) return; + if (isDisabled() || !myUpdatedProviders.contains(viewProvider)) return; - disablePostprocessFormattingInside(new Runnable() { - public void run() { - doPostponedFormattingInner(viewProvider); - } - }); + try { + disablePostprocessFormattingInside(new Runnable() { + public void run() { + doPostponedFormattingInner(viewProvider); + } + }); + } + finally { + myUpdatedProviders.remove(viewProvider); + myReformatElements.remove(viewProvider); + } } }); } From 0d4f8d0346bd61c391e0f2c1c1d7a6262314af68 Mon Sep 17 00:00:00 2001 From: "Kirill.Safonov" Date: Mon, 11 Jan 2010 21:08:21 +0300 Subject: [PATCH 55/67] better 'index not ready' message when trying to fetch documentation in dumb mode --- .../codeInsight/documentation/DocumentationManager.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/platform/lang-impl/src/com/intellij/codeInsight/documentation/DocumentationManager.java b/platform/lang-impl/src/com/intellij/codeInsight/documentation/DocumentationManager.java index 7b8f741286c4..3b1b009e3d80 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/documentation/DocumentationManager.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/documentation/DocumentationManager.java @@ -39,6 +39,7 @@ import com.intellij.openapi.actionSystem.ex.AnActionListener; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.components.ServiceManager; import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.project.IndexNotReadyException; import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.popup.JBPopup; import com.intellij.openapi.ui.popup.JBPopupFactory; @@ -437,7 +438,10 @@ public class DocumentationManager { //noinspection SSBasedInspection SwingUtilities.invokeLater(new Runnable() { public void run() { - component.setText(CodeInsightBundle.message("javadoc.external.fetch.error.message", ex[0].getLocalizedMessage()), true); + String message = ex[0] instanceof IndexNotReadyException + ? "Documentation is not available until indices are built." + : CodeInsightBundle.message("javadoc.external.fetch.error.message", ex[0].getLocalizedMessage()); + component.setText(message, true); callback.setDone(); } }); From 45df06fb37e0a16bf6b93c45d5d6623cec9213fa Mon Sep 17 00:00:00 2001 From: Kirill Kalishev Date: Tue, 12 Jan 2010 11:26:36 +0300 Subject: [PATCH 56/67] NPE: RunnerContentUi.getTabFor --- .../execution/ui/actions/BaseViewAction.java | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/platform/lang-api/src/com/intellij/execution/ui/actions/BaseViewAction.java b/platform/lang-api/src/com/intellij/execution/ui/actions/BaseViewAction.java index e86338fc2182..07feeb2b6c61 100644 --- a/platform/lang-api/src/com/intellij/execution/ui/actions/BaseViewAction.java +++ b/platform/lang-api/src/com/intellij/execution/ui/actions/BaseViewAction.java @@ -32,12 +32,26 @@ public abstract class BaseViewAction extends DumbAwareAction { Content[] content = getContent(e); if (context != null && content != null) { - update(e, context, content); + if (containsInvalidContent(content)) { + e.getPresentation().setEnabled(false); + } else { + update(e, context, content); + } } else { e.getPresentation().setEnabled(false); } } + private boolean containsInvalidContent(Content[] content) { + for (Content each : content) { + if (!each.isValid()) { + return true; + } + } + + return false; + } + protected void update(AnActionEvent e, ViewContext context, Content[] content) { } From 7cb294ae5777d60618e5f6e69ace80bfba53adc1 Mon Sep 17 00:00:00 2001 From: Kirill Kalishev Date: Tue, 12 Jan 2010 12:20:01 +0300 Subject: [PATCH 57/67] TreeUi: scroll rect to visible is deferred when tree ui is ready --- .../src/com/intellij/util/ui/tree/TreeUtil.java | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/platform/platform-api/src/com/intellij/util/ui/tree/TreeUtil.java b/platform/platform-api/src/com/intellij/util/ui/tree/TreeUtil.java index f9cf2411bc38..bdc75a33d713 100644 --- a/platform/platform-api/src/com/intellij/util/ui/tree/TreeUtil.java +++ b/platform/platform-api/src/com/intellij/util/ui/tree/TreeUtil.java @@ -15,6 +15,7 @@ */ package com.intellij.util.ui.tree; +import com.intellij.ide.util.treeView.AbstractTreeBuilder; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.project.Project; @@ -504,7 +505,16 @@ public final class TreeUtil { final Runnable runnable = new Runnable() { public void run() { if (scroll) { - tree.scrollRectToVisible(b1); + AbstractTreeBuilder builder = AbstractTreeBuilder.getBuilderFor(tree); + if (builder != null) { + builder.getReady(TreeUtil.class).doWhenDone(new Runnable() { + public void run() { + tree.scrollRectToVisible(b1); + } + }); + } else { + tree.scrollRectToVisible(b1); + } } callback.setDone(); } From c043f359404aa0ea80a7e1cd2145a60f5d72f9fd Mon Sep 17 00:00:00 2001 From: Kirill Kalishev Date: Tue, 12 Jan 2010 12:28:26 +0300 Subject: [PATCH 58/67] Balloons: isInsideBalloon should check for isShowing() --- platform/platform-impl/src/com/intellij/ui/BalloonImpl.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/platform/platform-impl/src/com/intellij/ui/BalloonImpl.java b/platform/platform-impl/src/com/intellij/ui/BalloonImpl.java index 9c002ce5114d..c31b269a6c03 100644 --- a/platform/platform-impl/src/com/intellij/ui/BalloonImpl.java +++ b/platform/platform-impl/src/com/intellij/ui/BalloonImpl.java @@ -119,6 +119,8 @@ public class BalloonImpl implements Disposable, Balloon, LightweightWindow { final Point mouseEventPoint = me.getPoint(); SwingUtilities.convertPointToScreen(mouseEventPoint, me.getComponent()); + if (!myComp.isShowing()) return false; + final Rectangle compRect = new Rectangle(myComp.getLocationOnScreen(), myComp.getSize()); if (compRect.contains(mouseEventPoint)) return true; return false; From 3f0343e24c422ee6580ab7917b4da1ac9fcd867a Mon Sep 17 00:00:00 2001 From: Kirill Kalishev Date: Tue, 12 Jan 2010 12:35:39 +0300 Subject: [PATCH 59/67] TreeUi: NPE when trying to set indexing timestamp for presumably parent node for rootm which is null --- .../src/com/intellij/ide/util/treeView/AbstractTreeUi.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/platform/platform-api/src/com/intellij/ide/util/treeView/AbstractTreeUi.java b/platform/platform-api/src/com/intellij/ide/util/treeView/AbstractTreeUi.java index dfa88363b2b1..a7d119152e2d 100644 --- a/platform/platform-api/src/com/intellij/ide/util/treeView/AbstractTreeUi.java +++ b/platform/platform-api/src/com/intellij/ide/util/treeView/AbstractTreeUi.java @@ -2218,7 +2218,10 @@ public class AbstractTreeUi { if (newElement.get() != null) { createMapping(newElement.get(), childNode); } - getDescriptorFrom(parentNode).setChildrenSortingStamp(-1); + NodeDescriptor parentDescriptor = getDescriptorFrom(parentNode); + if (parentDescriptor != null) { + parentDescriptor.setChildrenSortingStamp(-1); + } } if (index == null) { From f90a38164284a0698f9fbf4c2af2cb3fb27edad6 Mon Sep 17 00:00:00 2001 From: Kirill Kalishev Date: Tue, 12 Jan 2010 12:58:20 +0300 Subject: [PATCH 60/67] When checking for canPaint() && isDispatchThread there should be check if we're printing, not painting --- .../src/com/intellij/ui/SimpleColoredComponent.java | 6 ++++-- platform/util/src/com/intellij/util/ui/UIUtil.java | 4 ++++ 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/platform/platform-api/src/com/intellij/ui/SimpleColoredComponent.java b/platform/platform-api/src/com/intellij/ui/SimpleColoredComponent.java index 203faa8d5f8f..3c30a2c3e74a 100644 --- a/platform/platform-api/src/com/intellij/ui/SimpleColoredComponent.java +++ b/platform/platform-api/src/com/intellij/ui/SimpleColoredComponent.java @@ -344,7 +344,7 @@ public class SimpleColoredComponent extends JComponent { } protected synchronized void doPaint(final Graphics g) { - checkCanPaint(); + checkCanPaint(g); int xOffset = 0; // Paint icon and its background @@ -456,7 +456,9 @@ public class SimpleColoredComponent extends JComponent { } } - private static void checkCanPaint() { + private static void checkCanPaint(Graphics g) { + if (UIUtil.isPrinting(g)) return; + /* wtf?? if (!isDisplayable()) { LOG.assertTrue(false, logSwingPath()); diff --git a/platform/util/src/com/intellij/util/ui/UIUtil.java b/platform/util/src/com/intellij/util/ui/UIUtil.java index 4123abb5dd83..a70d4b8ab392 100644 --- a/platform/util/src/com/intellij/util/ui/UIUtil.java +++ b/platform/util/src/com/intellij/util/ui/UIUtil.java @@ -1060,5 +1060,9 @@ public class UIUtil { } } + public static boolean isPrinting(Graphics g) { + return g instanceof PrintGraphics; + } + } From af1c79a8b71e49fa0ec5a2e7a94d0b163d6d8d74 Mon Sep 17 00:00:00 2001 From: Kirill Kalishev Date: Tue, 12 Jan 2010 13:02:07 +0300 Subject: [PATCH 61/67] TreeUi: removeNodeFromParent has assertions in swing, so we need to check if parent != null first --- .../src/com/intellij/ide/util/treeView/AbstractTreeUi.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/platform/platform-api/src/com/intellij/ide/util/treeView/AbstractTreeUi.java b/platform/platform-api/src/com/intellij/ide/util/treeView/AbstractTreeUi.java index a7d119152e2d..021a7df3933c 100644 --- a/platform/platform-api/src/com/intellij/ide/util/treeView/AbstractTreeUi.java +++ b/platform/platform-api/src/com/intellij/ide/util/treeView/AbstractTreeUi.java @@ -2379,7 +2379,9 @@ public class AbstractTreeUi { } } - myTreeModel.removeNodeFromParent(node); + if (node.getParent() != null) { + myTreeModel.removeNodeFromParent(node); + } } }); } From 3bd66724e1a303a8b4b5fb93604595478928c092 Mon Sep 17 00:00:00 2001 From: Alexey Kudravtsev Date: Tue, 12 Jan 2010 14:28:45 +0300 Subject: [PATCH 62/67] cleanup --- .../codeInsight/daemon/impl/quickfix/ModifierFix.java | 1 + .../src/com/intellij/codeInspection/dataFlow/ControlFlow.java | 4 ---- .../src/com/intellij/psi/codeStyle/CodeStyleSettings.java | 2 +- .../com/intellij/openapi/command/impl/UndoManagerImpl.java | 2 +- .../intellij/openapi/command/impl/UndoRedoStacksHolder.java | 4 ++-- 5 files changed, 5 insertions(+), 8 deletions(-) diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/ModifierFix.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/ModifierFix.java index a5d1ea164e74..3b9f9633b698 100644 --- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/ModifierFix.java +++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/ModifierFix.java @@ -99,6 +99,7 @@ public class ModifierFix extends IntentionAndQuickFixAction { return myModifierList != null && myModifierList.isValid() && myModifierList.getManager().isInProject(myModifierList) && + myModifierList.hasModifierProperty(myModifier) != myShouldHave && (myVariable == null || myVariable.isValid()); } diff --git a/java/java-impl/src/com/intellij/codeInspection/dataFlow/ControlFlow.java b/java/java-impl/src/com/intellij/codeInspection/dataFlow/ControlFlow.java index 38f199306aaa..cfd4d0816797 100644 --- a/java/java-impl/src/com/intellij/codeInspection/dataFlow/ControlFlow.java +++ b/java/java-impl/src/com/intellij/codeInspection/dataFlow/ControlFlow.java @@ -92,10 +92,6 @@ public class ControlFlow { myFields = fields; } - public void dump(PrintStream p) { - p.println(toString()); - } - public String toString() { StringBuilder result = new StringBuilder(); diff --git a/platform/lang-api/src/com/intellij/psi/codeStyle/CodeStyleSettings.java b/platform/lang-api/src/com/intellij/psi/codeStyle/CodeStyleSettings.java index 5a3376679f27..7a838c6165a2 100644 --- a/platform/lang-api/src/com/intellij/psi/codeStyle/CodeStyleSettings.java +++ b/platform/lang-api/src/com/intellij/psi/codeStyle/CodeStyleSettings.java @@ -164,7 +164,7 @@ public class CodeStyleSettings implements Cloneable, JDOMExternalizable { field.set(to, field.get(from)); } else { - System.out.println("Field not copied " + field.getName()); + throw new RuntimeException("Field not copied " + field.getName()); } } diff --git a/platform/platform-impl/src/com/intellij/openapi/command/impl/UndoManagerImpl.java b/platform/platform-impl/src/com/intellij/openapi/command/impl/UndoManagerImpl.java index 77bfe1d0eab1..1385a344ec29 100644 --- a/platform/platform-impl/src/com/intellij/openapi/command/impl/UndoManagerImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/command/impl/UndoManagerImpl.java @@ -403,7 +403,7 @@ public class UndoManagerImpl extends UndoManager implements ProjectComponent, Ap return isUndoOrRedoAvailable(refs, false); } - private Collection getDocRefs(FileEditor editor) { + private static Collection getDocRefs(FileEditor editor) { if (editor instanceof TextEditor && ((TextEditor)editor).getEditor().isViewer()) return null; return getDocumentReferences(editor); } diff --git a/platform/platform-impl/src/com/intellij/openapi/command/impl/UndoRedoStacksHolder.java b/platform/platform-impl/src/com/intellij/openapi/command/impl/UndoRedoStacksHolder.java index 8e98c1f57ec4..5f5e169a6271 100644 --- a/platform/platform-impl/src/com/intellij/openapi/command/impl/UndoRedoStacksHolder.java +++ b/platform/platform-impl/src/com/intellij/openapi/command/impl/UndoRedoStacksHolder.java @@ -136,7 +136,7 @@ class UndoRedoStacksHolder { } } - private void doAddToStack(LinkedList stack, UndoableGroup group, int limit) { + private static void doAddToStack(LinkedList stack, UndoableGroup group, int limit) { if (!group.isUndoable() && stack.isEmpty()) return; stack.addLast(group); @@ -187,7 +187,7 @@ class UndoRedoStacksHolder { } } - private void doInvalidateAllGlobalActions(LinkedList stack) { + private static void doInvalidateAllGlobalActions(LinkedList stack) { for (UndoableGroup g : stack) { g.invalidateIfGlobal(); } From 1ddc49bc040dd128a5756b6d9eb05ba6e56f02b2 Mon Sep 17 00:00:00 2001 From: "Kirill.Safonov" Date: Tue, 12 Jan 2010 14:33:07 +0300 Subject: [PATCH 63/67] fix postponed formatting --- .../com/intellij/psi/SingleRootFileViewProvider.java | 2 +- .../psi/impl/source/PostprocessReformattingAspect.java | 10 +++++++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/psi/SingleRootFileViewProvider.java b/platform/lang-impl/src/com/intellij/psi/SingleRootFileViewProvider.java index 480cd0e05c05..438eff30e62b 100644 --- a/platform/lang-impl/src/com/intellij/psi/SingleRootFileViewProvider.java +++ b/platform/lang-impl/src/com/intellij/psi/SingleRootFileViewProvider.java @@ -162,7 +162,7 @@ public class SingleRootFileViewProvider extends UserDataHolderBase implements Fi if (component.isViewProviderLocked(this)) { throw new RuntimeException("Document is locked by write PSI operations. Use PsiDocumentManager.doPostponedOperationsAndUnblockDocument() to commit PSI changes to the document."); } - component.doPostponedFormatting(this); + component.postponedFormatting(this); final PsiFileImpl psiFile = (PsiFileImpl)getCachedPsi(getBaseLanguage()); if (psiFile != null && psiFile.isContentsLoaded() && getContent()instanceof DocumentContent) { setContent(new PsiFileContent(psiFile, getModificationStamp())); diff --git a/platform/lang-impl/src/com/intellij/psi/impl/source/PostprocessReformattingAspect.java b/platform/lang-impl/src/com/intellij/psi/impl/source/PostprocessReformattingAspect.java index a462f520b1e7..cb2dd5d39464 100644 --- a/platform/lang-impl/src/com/intellij/psi/impl/source/PostprocessReformattingAspect.java +++ b/platform/lang-impl/src/com/intellij/psi/impl/source/PostprocessReformattingAspect.java @@ -227,10 +227,18 @@ public class PostprocessReformattingAspect implements PomModelAspect, Disposable }); } + public void postponedFormatting(final FileViewProvider viewProvider) { + postponedFormattingImpl(viewProvider, true); + } + public void doPostponedFormatting(final FileViewProvider viewProvider) { + postponedFormattingImpl(viewProvider, false); + } + + private void postponedFormattingImpl(final FileViewProvider viewProvider, final boolean check) { atomic(new Runnable() { public void run() { - if (isDisabled() || !myUpdatedProviders.contains(viewProvider)) return; + if (isDisabled() || check && !myUpdatedProviders.contains(viewProvider)) return; try { disablePostprocessFormattingInside(new Runnable() { From b9589ec47e3740c70a9506a1c1a7992ff04fc24a Mon Sep 17 00:00:00 2001 From: Dmitry Avdeev Date: Tue, 12 Jan 2010 15:41:00 +0300 Subject: [PATCH 64/67] PreferredAction marker interface --- .../intention/PreferredAction.java | 27 ++++++++++++++++ .../intention/impl/IntentionListStep.java | 32 +++++++++++++------ 2 files changed, 49 insertions(+), 10 deletions(-) create mode 100644 platform/lang-api/src/com/intellij/codeInsight/intention/PreferredAction.java diff --git a/platform/lang-api/src/com/intellij/codeInsight/intention/PreferredAction.java b/platform/lang-api/src/com/intellij/codeInsight/intention/PreferredAction.java new file mode 100644 index 000000000000..0dda5015847b --- /dev/null +++ b/platform/lang-api/src/com/intellij/codeInsight/intention/PreferredAction.java @@ -0,0 +1,27 @@ +/* + * Copyright 2000-2010 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 com.intellij.codeInsight.intention; + +/** + * Marker interface for intentions and quick fixes. + * Marked actions are shown on the top of the list and are separated from the others. + * + * @author Dmitry Avdeev + * @see com.intellij.codeInsight.intention.IntentionAction + * @see com.intellij.codeInspection.LocalQuickFix + */ +public interface PreferredAction { +} diff --git a/platform/lang-impl/src/com/intellij/codeInsight/intention/impl/IntentionListStep.java b/platform/lang-impl/src/com/intellij/codeInsight/intention/impl/IntentionListStep.java index a17dad573c69..9db9a3fca2b7 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/intention/impl/IntentionListStep.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/intention/impl/IntentionListStep.java @@ -21,6 +21,7 @@ import com.intellij.codeInsight.daemon.impl.ShowIntentionsPass; import com.intellij.codeInsight.hint.HintManager; import com.intellij.codeInsight.intention.EmptyIntentionAction; import com.intellij.codeInsight.intention.IntentionAction; +import com.intellij.codeInsight.intention.PreferredAction; import com.intellij.codeInsight.intention.impl.config.IntentionManagerSettings; import com.intellij.codeInspection.ex.QuickFixWrapper; import com.intellij.openapi.application.ApplicationManager; @@ -213,12 +214,8 @@ class IntentionListStep implements ListPopupStep result.addAll(myCachedGutters); Collections.sort(result, new Comparator() { public int compare(final IntentionActionWithTextCaching o1, final IntentionActionWithTextCaching o2) { - final IntentionAction action1 = o1.getAction(); - final IntentionAction action2 = o2.getAction(); - if (action1 instanceof EmptyIntentionAction && !(action2 instanceof EmptyIntentionAction)) return 1; - if (action2 instanceof EmptyIntentionAction && !(action1 instanceof EmptyIntentionAction)) return -1; - int weight1 = myCachedErrorFixes.contains(o1) ? 2 : myCachedInspectionFixes.contains(o1) ? 1 : 0; - int weight2 = myCachedErrorFixes.contains(o2) ? 2 : myCachedInspectionFixes.contains(o2) ? 1 : 0; + int weight1 = getWeight(o1); + int weight2 = getWeight(o2); if (weight1 != weight2) { return weight2 - weight1; } @@ -228,6 +225,24 @@ class IntentionListStep implements ListPopupStep return result; } + private int getWeight(IntentionActionWithTextCaching action) { + if (action.getAction() instanceof PreferredAction) { + return 3; + } + else if (myCachedErrorFixes.contains(action)) { + return 2; + } + else if (myCachedInspectionFixes.contains(action)) { + return 1; + } + else if (action.getAction() instanceof EmptyIntentionAction) { + return -1; + } + else { + return 0; + } + } + @NotNull public String getTextFor(final IntentionActionWithTextCaching action) { return action.getAction().getText(); @@ -272,10 +287,7 @@ class IntentionListStep implements ListPopupStep if (index == 0) return null; IntentionActionWithTextCaching prev = values.get(index - 1); - if (myCachedErrorFixes.contains(value) != myCachedErrorFixes.contains(prev) - || myCachedInspectionFixes.contains(value) != myCachedInspectionFixes.contains(prev) - || myCachedIntentions.contains(value) != myCachedIntentions.contains(prev) - || value.getAction() instanceof EmptyIntentionAction != prev.getAction() instanceof EmptyIntentionAction) { + if (getWeight(value) != getWeight(prev)) { return new ListSeparator(); } return null; From a946f5b03c21362f22a5730692cc51821e2e4029 Mon Sep 17 00:00:00 2001 From: Kirill Kalishev Date: Tue, 12 Jan 2010 16:09:11 +0300 Subject: [PATCH 65/67] DataProvider returns null context component if focus is being tranferred, registry value for diagnostics added --- .../src/com/intellij/ide/impl/DataManagerImpl.java | 10 ++++++++++ .../platform-resources-en/src/misc/registry.properties | 1 + 2 files changed, 11 insertions(+) diff --git a/platform/platform-impl/src/com/intellij/ide/impl/DataManagerImpl.java b/platform/platform-impl/src/com/intellij/ide/impl/DataManagerImpl.java index 3ecc9ae676cc..775f44ab6b83 100644 --- a/platform/platform-impl/src/com/intellij/ide/impl/DataManagerImpl.java +++ b/platform/platform-impl/src/com/intellij/ide/impl/DataManagerImpl.java @@ -26,6 +26,8 @@ import com.intellij.openapi.editor.Editor; import com.intellij.openapi.extensions.Extensions; import com.intellij.openapi.keymap.impl.IdeKeyEventDispatcher; import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.registry.Registry; +import com.intellij.openapi.wm.IdeFocusManager; import com.intellij.openapi.wm.ex.WindowManagerEx; import com.intellij.util.KeyedLazyInstanceEP; import com.intellij.util.StringSetSpinAllocator; @@ -223,6 +225,14 @@ public class DataManagerImpl extends DataManager implements ApplicationComponent if (activeWindow == null) return null; } } + + if (Registry.is("actionSystem.noContextComponentWhileFocusTransfer")) { + IdeFocusManager fm = IdeFocusManager.findInstanceByComponent(activeWindow); + if (fm.isFocusBeingTransferred()) { + return null; + } + } + // try to find first parent window that has focus Window window = activeWindow; Component focusedComponent = null; diff --git a/platform/platform-resources-en/src/misc/registry.properties b/platform/platform-resources-en/src/misc/registry.properties index 625b0f97e468..aafce86fc9d9 100644 --- a/platform/platform-resources-en/src/misc/registry.properties +++ b/platform/platform-resources-en/src/misc/registry.properties @@ -18,6 +18,7 @@ actionSystem.focusIdleTimeout=20 actionSystem.mac.screenMenuNotUpdatedFix=false actionSystem.keyGestures.enabled=false actionSystem.suspendFocusTransferIfApplicationInactive=false +actionSystem.noContextComponentWhileFocusTransfer=true ide.debugMode=true ide.debugMode.description=Record additonal information to make bug reports more informative From 1c426671b0bd7d09434c6aef926adbae456b7017 Mon Sep 17 00:00:00 2001 From: Kirill Kalishev Date: Tue, 12 Jan 2010 16:24:16 +0300 Subject: [PATCH 66/67] Ignore NPE for sun's bug under Linux, http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6322854 --- .../intellij/ide/util/gotoByName/ChooseByNameBase.java | 10 +++++++++- platform/util/src/com/intellij/Patches.java | 5 +++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/platform/lang-impl/src/com/intellij/ide/util/gotoByName/ChooseByNameBase.java b/platform/lang-impl/src/com/intellij/ide/util/gotoByName/ChooseByNameBase.java index 9d3099bd757d..68a673718b5c 100644 --- a/platform/lang-impl/src/com/intellij/ide/util/gotoByName/ChooseByNameBase.java +++ b/platform/lang-impl/src/com/intellij/ide/util/gotoByName/ChooseByNameBase.java @@ -16,6 +16,7 @@ package com.intellij.ide.util.gotoByName; +import com.intellij.Patches; import com.intellij.ide.IdeBundle; import com.intellij.ide.actions.CopyReferenceAction; import com.intellij.ide.ui.UISettings; @@ -965,7 +966,14 @@ public abstract class ChooseByNameBase{ } return; } - super.processKeyEvent(e); + try { + super.processKeyEvent(e); + } + catch (NullPointerException e1) { + if (!Patches.SUN_BUG_6322854) { + throw e1; + } + } } private void fillInCommonPrefix(final String pattern) { diff --git a/platform/util/src/com/intellij/Patches.java b/platform/util/src/com/intellij/Patches.java index b31a3154b1cf..af6571b56953 100644 --- a/platform/util/src/com/intellij/Patches.java +++ b/platform/util/src/com/intellij/Patches.java @@ -41,6 +41,11 @@ public class Patches { */ public static final boolean SUN_BUG_338675 = SystemInfo.JAVA_VERSION.indexOf("1.4.") != -1; + /** + * java.lang.NullPointerException: Failed to retrieve atom name. + */ + public static final boolean SUN_BUG_6322854 = SystemInfo.isLinux; + /** * See sun bug parade. * If you invoke popup menu, then click on a different window (JFrame, JDialog. It doesn't matter), From 0ce2ecd8e58dbd0f5a4fc52f2ca41ef2e960cf94 Mon Sep 17 00:00:00 2001 From: Maxim Shafirov Date: Tue, 12 Jan 2010 17:56:28 +0300 Subject: [PATCH 67/67] IDEADEV-42191: The file may belong to a library AND the source root of the module at the same time. --- .../src/com/intellij/psi/search/ProjectScope.java | 8 +++++--- .../module/impl/scopes/ModuleWithDependentsScope.java | 2 +- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/platform/lang-api/src/com/intellij/psi/search/ProjectScope.java b/platform/lang-api/src/com/intellij/psi/search/ProjectScope.java index 83cc6be033de..56d750efce0a 100644 --- a/platform/lang-api/src/com/intellij/psi/search/ProjectScope.java +++ b/platform/lang-api/src/com/intellij/psi/search/ProjectScope.java @@ -63,9 +63,11 @@ public class ProjectScope { private final ProjectFileIndex myFileIndex = projectRootManager.getFileIndex(); public boolean contains(VirtualFile file) { - if (myFileIndex.isInLibraryClasses(file)) return false; + if (file instanceof VirtualFileWindow) return true; - return file instanceof VirtualFileWindow || myFileIndex.isInContent(file); + if (myFileIndex.isInLibraryClasses(file) && !myFileIndex.isInSourceContent(file)) return false; + + return myFileIndex.isInContent(file); } public int compare(VirtualFile file1, VirtualFile file2) { @@ -107,4 +109,4 @@ public class ProjectScope { } return projectScope; } -} \ No newline at end of file +} diff --git a/platform/lang-impl/src/com/intellij/openapi/module/impl/scopes/ModuleWithDependentsScope.java b/platform/lang-impl/src/com/intellij/openapi/module/impl/scopes/ModuleWithDependentsScope.java index 042e67a688fd..4523bb6f9e8a 100644 --- a/platform/lang-impl/src/com/intellij/openapi/module/impl/scopes/ModuleWithDependentsScope.java +++ b/platform/lang-impl/src/com/intellij/openapi/module/impl/scopes/ModuleWithDependentsScope.java @@ -80,7 +80,7 @@ public class ModuleWithDependentsScope extends GlobalSearchScope { if (moduleOfFile == null) return false; if (!myModules.contains(moduleOfFile)) return false; if (myOnlyTests && !myProjectFileIndex.isInTestSourceContent(file)) return false; - if (myProjectFileIndex.isInLibraryClasses(file)) return false; + if (myProjectFileIndex.isInLibraryClasses(file) && !myProjectFileIndex.isInSourceContent(file)) return false; return true; }

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 literal 0 HcmV?d00001 diff --git a/tools/lexer/jflex-1.4/examples/binary/Makefile b/tools/lexer/jflex-1.4/examples/binary/Makefile new file mode 100644 index 000000000000..52607f7f210e --- /dev/null +++ b/tools/lexer/jflex-1.4/examples/binary/Makefile @@ -0,0 +1,22 @@ + +JAVA = java +JAVAC = javac +JFLEX = jflex + +# ------------------------------------------------- + +all: run + +run: compile + $(JAVA) BinaryLexer * + +compile: BinaryLexer.class StraightStreamReader.class + +clean: + rm -f *~ *.class BinaryLexer.java + +%.class: %.java + $(JAVAC) $^ + +BinaryLexer.java: binary.flex + $(JFLEX) $^ diff --git a/tools/lexer/jflex-1.4/examples/binary/README b/tools/lexer/jflex-1.4/examples/binary/README new file mode 100644 index 000000000000..8fceab48c4b8 --- /dev/null +++ b/tools/lexer/jflex-1.4/examples/binary/README @@ -0,0 +1,18 @@ +This directory contains a small example of a scanner for binary files. + +The example tries to detect if an input file is a java class file by +checking if the first 4 bytes contain the magic number 0xCAFEBABE. +It uses a custom Reader class that copies bytes to characters one to +one. The characters the scanner gets to read are the bytes from the +input stream without any conversion. Many thanks to Stephen Ostermiller +for providing the custom Reader class, the original version of that +class is available from http://www.smo.f2s.com/utils/ + +See the JFlex manual for details on how to scan binaries and how +this is different from scanning text files. + +Files: +binary.flex the scanner spec +StraightStreamReader.java the custom reader class (by Stephen Ostermiller) +Makefile rules for make to compile and run the example +README this file diff --git a/tools/lexer/jflex-1.4/examples/binary/StraightStreamReader.java b/tools/lexer/jflex-1.4/examples/binary/StraightStreamReader.java new file mode 100644 index 000000000000..7f418b5823cf --- /dev/null +++ b/tools/lexer/jflex-1.4/examples/binary/StraightStreamReader.java @@ -0,0 +1,287 @@ +/* + * An InputStreamReader that does no character encoding translations. + * Copyright (C) 2001 Stephen Ostermiller + * + * Changes: (2001 by Gerwin Klein ) + * - commented out package declaration for the example + * - original version at http://www.smo.f2s.com/utils/ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * See COPYING.TXT for details. + */ + +// package com.Ostermiller.util; + +import java.io.*; + +/** + * A StraightStreamReader is a bridge from byte streams to character streams: It reads bytes + * and translates them into characters without using a character encoding. The characters + * that a StraightStreamReader returns may not be valid unicode characters but they are + * guaranteed to be in the 0x00 to 0xFF range. + *