mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
Merge branch 'master' of git.labs.intellij.net:idea/community
This commit is contained in:
Generated
+1
@@ -11,6 +11,7 @@
|
||||
<module fileurl="file://$PROJECT_DIR$/RegExpSupport/RegExpSupport.iml" filepath="$PROJECT_DIR$/RegExpSupport/RegExpSupport.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/platform/annotations/annotations.iml" filepath="$PROJECT_DIR$/platform/annotations/annotations.iml" group="platform" />
|
||||
<module fileurl="file://$PROJECT_DIR$/plugins/ant/ant.iml" filepath="$PROJECT_DIR$/plugins/ant/ant.iml" group="plugins" />
|
||||
<module fileurl="file://$PROJECT_DIR$/plugins/relaxng/relaxng.iml" filepath="$PROJECT_DIR$/plugins/relaxng/relaxng.iml" group="plugins" />
|
||||
<module fileurl="file://$PROJECT_DIR$/platform/boot/boot.iml" filepath="$PROJECT_DIR$/platform/boot/boot.iml" group="platform" />
|
||||
<module fileurl="file://$PROJECT_DIR$/platform/bootstrap/bootstrap.iml" filepath="$PROJECT_DIR$/platform/bootstrap/bootstrap.iml" group="platform" />
|
||||
<module fileurl="file://$PROJECT_DIR$/build/build.iml" filepath="$PROJECT_DIR$/build/build.iml" />
|
||||
|
||||
@@ -172,6 +172,9 @@ def layoutFull(String home, String targetDirectory) {
|
||||
|
||||
layoutPlugin("SpellChecker", "spellchecker", "spellchecker-core")
|
||||
|
||||
layoutPlugin("RelaxNG-Support", "relaxng") {
|
||||
fileset(dir: "${home}/community/plugins/relaxng/lib", includes: "**/*.jar")
|
||||
}
|
||||
|
||||
layoutPlugin("maven") {
|
||||
jar("maven-facade-api.jar") {
|
||||
|
||||
@@ -97,6 +97,8 @@ import java.util.concurrent.TimeUnit;
|
||||
|
||||
public class CompileDriver {
|
||||
private static final Logger LOG = Logger.getInstance("#com.intellij.compiler.impl.CompileDriver");
|
||||
// to be used in tests only for debug output
|
||||
public static boolean ourDebugMode = false;
|
||||
|
||||
private final Project myProject;
|
||||
private final Map<Pair<IntermediateOutputCompiler, Module>, Pair<VirtualFile, VirtualFile>> myGenerationCompilerModuleToOutputDirMap; // [IntermediateOutputCompiler, Module] -> [ProductionSources, TestSources]
|
||||
@@ -1558,12 +1560,20 @@ public class CompileDriver {
|
||||
if (toDelete.isEmpty() && toCompile.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
if (LOG.isDebugEnabled()) {
|
||||
if (LOG.isDebugEnabled() || ourDebugMode) {
|
||||
if (!toDelete.isEmpty()) {
|
||||
LOG.debug("Found items to delete, compiler " + compiler.getDescription());
|
||||
final String message = "Found items to delete, compiler " + compiler.getDescription();
|
||||
LOG.debug(message);
|
||||
if (ourDebugMode) {
|
||||
System.out.println(message);
|
||||
}
|
||||
}
|
||||
if (!toCompile.isEmpty()) {
|
||||
LOG.debug("Found items to compile, compiler " + compiler.getDescription());
|
||||
final String message = "Found items to compile, compiler " + compiler.getDescription();
|
||||
LOG.debug(message);
|
||||
if (ourDebugMode) {
|
||||
System.out.println(message);
|
||||
}
|
||||
}
|
||||
}
|
||||
throw new ExitException(ExitStatus.CANCELLED);
|
||||
|
||||
+62
-18
@@ -78,6 +78,7 @@ import java.util.*;
|
||||
|
||||
public class TranslatingCompilerFilesMonitor implements ApplicationComponent {
|
||||
private static final Logger LOG = Logger.getInstance("#com.intellij.compiler.impl.TranslatingCompilerFilesMonitor");
|
||||
public static boolean ourDebugMode = false;
|
||||
@NonNls
|
||||
private static final String PATHS_TO_DELETE_FILENAME = "paths_to_delete.dat";
|
||||
private static final String OUTPUT_ROOTS_FILENAME = "output_roots.dat";
|
||||
@@ -163,8 +164,12 @@ public class TranslatingCompilerFilesMonitor implements ApplicationComponent {
|
||||
while (scopeSrcIterator.hasNext()) {
|
||||
final VirtualFile file = scopeSrcIterator.next();
|
||||
if (!file.isValid()) {
|
||||
if (LOG.isDebugEnabled()) {
|
||||
LOG.debug("Skipping invalid file " + file.getPresentableUrl());
|
||||
if (LOG.isDebugEnabled() || ourDebugMode) {
|
||||
final String message = "Skipping invalid file " + file.getPresentableUrl();
|
||||
LOG.debug(message);
|
||||
if (ourDebugMode) {
|
||||
System.out.println(message);
|
||||
}
|
||||
}
|
||||
continue;
|
||||
}
|
||||
@@ -212,11 +217,22 @@ public class TranslatingCompilerFilesMonitor implements ApplicationComponent {
|
||||
//noinspection UnnecessaryBoxing
|
||||
final File file = new File(outputPath);
|
||||
toDelete.add(new Trinity<File, String, Boolean>(file, classNamePair.getClassName(), Boolean.valueOf(sourcePresent)));
|
||||
if (LOG.isDebugEnabled()) {
|
||||
LOG.debug("Found file to delete: " + file);
|
||||
if (LOG.isDebugEnabled() || ourDebugMode) {
|
||||
final String message = "Found file to delete: " + file;
|
||||
LOG.debug(message);
|
||||
if (ourDebugMode) {
|
||||
System.out.println(message);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (LOG.isDebugEnabled() || ourDebugMode) {
|
||||
final String message = "Found zombie entry marked for deletion: " + outputPath;
|
||||
LOG.debug(message);
|
||||
if (ourDebugMode) {
|
||||
System.out.println(message);
|
||||
}
|
||||
}
|
||||
// must be gagbage entry, should cleanup
|
||||
zombieEntries.add(outputPath);
|
||||
}
|
||||
@@ -301,8 +317,12 @@ public class TranslatingCompilerFilesMonitor implements ApplicationComponent {
|
||||
final long fileStamp = file.getTimeStamp();
|
||||
info.updateTimestamp(projectId, fileStamp);
|
||||
saveSourceInfo(file, info);
|
||||
if (LOG.isDebugEnabled()) {
|
||||
LOG.debug("Unschedule recompilation (successfully compiled) " + file.getPresentableUrl());
|
||||
if (LOG.isDebugEnabled() || ourDebugMode) {
|
||||
final String message = "Unschedule recompilation (successfully compiled) " + file.getPresentableUrl();
|
||||
LOG.debug(message);
|
||||
if (ourDebugMode) {
|
||||
System.out.println(message);
|
||||
}
|
||||
}
|
||||
removeSourceForRecompilation(projectId, Math.abs(getFileId(file)));
|
||||
if ((fileStamp > compilationStartStamp && !((CompileContextEx)context).isGenerated(file)) || forceRecompile.contains(file)) {
|
||||
@@ -365,8 +385,12 @@ public class TranslatingCompilerFilesMonitor implements ApplicationComponent {
|
||||
final String outputPath = FileUtil.toSystemIndependentName(CompilerIOUtil.readString(is));
|
||||
final String srcUrl = CompilerIOUtil.readString(is);
|
||||
final String className = CompilerIOUtil.readString(is);
|
||||
if (LOG.isDebugEnabled()) {
|
||||
LOG.debug("INIT path to delete: " + outputPath);
|
||||
if (LOG.isDebugEnabled() || ourDebugMode) {
|
||||
final String message = "INIT path to delete: " + outputPath;
|
||||
LOG.debug(message);
|
||||
if (ourDebugMode) {
|
||||
System.out.println(message);
|
||||
}
|
||||
}
|
||||
map.put(outputPath, new SourceUrlClassNamePair(srcUrl, className));
|
||||
}
|
||||
@@ -1136,8 +1160,12 @@ public class TranslatingCompilerFilesMonitor implements ApplicationComponent {
|
||||
|
||||
public void beforeFileDeletion(final VirtualFileEvent event) {
|
||||
final VirtualFile eventFile = event.getFile();
|
||||
if (LOG.isDebugEnabled() && eventFile.isDirectory()) {
|
||||
LOG.debug("Processing file deletion: " + eventFile.getPresentableUrl());
|
||||
if ((LOG.isDebugEnabled() && eventFile.isDirectory()) || ourDebugMode) {
|
||||
final String message = "Processing file deletion: " + eventFile.getPresentableUrl();
|
||||
LOG.debug(message);
|
||||
if (ourDebugMode) {
|
||||
System.out.println(message);
|
||||
}
|
||||
}
|
||||
processRecursively(eventFile, true, new FileProcessor() {
|
||||
public void execute(final VirtualFile file) {
|
||||
@@ -1167,8 +1195,12 @@ public class TranslatingCompilerFilesMonitor implements ApplicationComponent {
|
||||
for (int projectId : projects.toArray()) {
|
||||
// mark associated outputs for deletion
|
||||
srcInfo.processOutputPaths(projectId, deletionProc);
|
||||
if (LOG.isDebugEnabled()) {
|
||||
LOG.debug("Unschedule recompilation because of deletion " + file.getPresentableUrl());
|
||||
if (LOG.isDebugEnabled() || ourDebugMode) {
|
||||
final String message = "Unschedule recompilation because of deletion " + file.getPresentableUrl();
|
||||
LOG.debug(message);
|
||||
if (ourDebugMode) {
|
||||
System.out.println(message);
|
||||
}
|
||||
}
|
||||
removeSourceForRecompilation(projectId, Math.abs(getFileId(file)));
|
||||
}
|
||||
@@ -1269,8 +1301,12 @@ public class TranslatingCompilerFilesMonitor implements ApplicationComponent {
|
||||
mySourcesToRecompile.put(projectId, set);
|
||||
}
|
||||
alreadyMarked = !set.add(Math.abs(getFileId(srcFile)));
|
||||
if (!alreadyMarked && LOG.isDebugEnabled()) {
|
||||
LOG.debug("Scheduled recompilation " + srcFile.getPresentableUrl());
|
||||
if (!alreadyMarked && (LOG.isDebugEnabled() || ourDebugMode)) {
|
||||
final String message = "Scheduled recompilation " + srcFile.getPresentableUrl();
|
||||
LOG.debug(message);
|
||||
if (ourDebugMode) {
|
||||
System.out.println(message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1336,8 +1372,12 @@ public class TranslatingCompilerFilesMonitor implements ApplicationComponent {
|
||||
myOutputsToDelete.put(projectId, map);
|
||||
}
|
||||
map.put(outputPath, new SourceUrlClassNamePair(srcUrl, classname));
|
||||
if (LOG.isDebugEnabled()) {
|
||||
LOG.debug("ADD path to delete: " + outputPath + "; source: " + srcUrl);
|
||||
if (LOG.isDebugEnabled() || ourDebugMode) {
|
||||
final String message = "ADD path to delete: " + outputPath + "; source: " + srcUrl;
|
||||
LOG.debug(message);
|
||||
if (ourDebugMode) {
|
||||
System.out.println(message);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1349,8 +1389,12 @@ public class TranslatingCompilerFilesMonitor implements ApplicationComponent {
|
||||
if (map != null) {
|
||||
final SourceUrlClassNamePair val = map.remove(outputPath);
|
||||
if (val != null) {
|
||||
if (LOG.isDebugEnabled()) {
|
||||
LOG.debug("REMOVE path to delete: " + outputPath);
|
||||
if (LOG.isDebugEnabled() || ourDebugMode) {
|
||||
final String message = "REMOVE path to delete: " + outputPath;
|
||||
LOG.debug(message);
|
||||
if (ourDebugMode) {
|
||||
System.out.println(message);
|
||||
}
|
||||
}
|
||||
if (map.isEmpty()) {
|
||||
myOutputsToDelete.remove(projectId);
|
||||
|
||||
+5
-1
@@ -1081,7 +1081,11 @@ public class ExtractMethodProcessor implements MatchProvider {
|
||||
}
|
||||
if (success) {
|
||||
myTargetClass = newTargetClass;
|
||||
inputVariables.addAll(array);
|
||||
for (PsiVariable variable : array) {
|
||||
if (!inputVariables.contains(variable)) {
|
||||
inputVariables.addAll(array);
|
||||
}
|
||||
}
|
||||
myNeedChangeContext = true;
|
||||
}
|
||||
}
|
||||
|
||||
+26
-6
@@ -18,6 +18,7 @@ package com.intellij.refactoring.inline;
|
||||
import com.intellij.codeInsight.TargetElementUtilBase;
|
||||
import com.intellij.lang.StdLanguages;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.progress.ProgressManager;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.Ref;
|
||||
import com.intellij.patterns.ElementPattern;
|
||||
@@ -34,6 +35,7 @@ import com.intellij.util.ArrayUtil;
|
||||
import com.intellij.util.Processor;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
|
||||
/**
|
||||
@@ -50,17 +52,29 @@ public class InlineToAnonymousClassHandler extends JavaInlineActionHandler {
|
||||
return element instanceof PsiMethod || element instanceof PsiClass;
|
||||
}
|
||||
|
||||
public boolean canInlineElement(PsiElement element) {
|
||||
public boolean canInlineElement(final PsiElement element) {
|
||||
if (element.getLanguage() != StdLanguages.JAVA) return false;
|
||||
if (element instanceof PsiMethod) {
|
||||
PsiMethod method = (PsiMethod)element;
|
||||
if (method.isConstructor() && !InlineMethodHandler.isChainingConstructor(method)) {
|
||||
final PsiClass containingClass = method.getContainingClass();
|
||||
return containingClass != null && ClassInheritorsSearch.search(containingClass).findAll().size() == 0;
|
||||
if (containingClass == null) return false;
|
||||
return findClassInheritors(containingClass);
|
||||
}
|
||||
}
|
||||
if (!(element instanceof PsiClass)) return false;
|
||||
Collection<PsiClass> inheritors = ClassInheritorsSearch.search((PsiClass)element).findAll();
|
||||
if (element instanceof PsiAnonymousClass) return false;
|
||||
return findClassInheritors((PsiClass)element);
|
||||
}
|
||||
|
||||
private static boolean findClassInheritors(final PsiClass element) {
|
||||
final Collection<PsiClass> inheritors = new ArrayList<PsiClass>();
|
||||
if (!ProgressManager.getInstance().runProcessWithProgressSynchronously(new Runnable(){
|
||||
@Override
|
||||
public void run() {
|
||||
inheritors.addAll(ClassInheritorsSearch.search(element).findAll());
|
||||
}
|
||||
}, "Searching for class \"" + element.getQualifiedName() + "\" inheritors ...", true, element.getProject())) return false;
|
||||
return inheritors.size() == 0;
|
||||
}
|
||||
|
||||
@@ -78,9 +92,15 @@ public class InlineToAnonymousClassHandler extends JavaInlineActionHandler {
|
||||
return;
|
||||
}
|
||||
|
||||
String errorMessage = getCannotInlineMessage(psiClass);
|
||||
if (errorMessage != null) {
|
||||
CommonRefactoringUtil.showErrorHint(project, editor, errorMessage, RefactoringBundle.message("inline.to.anonymous.refactoring"), null);
|
||||
final Ref<String> errorMessage = new Ref<String>();
|
||||
if (!ProgressManager.getInstance().runProcessWithProgressSynchronously(new Runnable(){
|
||||
@Override
|
||||
public void run() {
|
||||
errorMessage.set(getCannotInlineMessage(psiClass));
|
||||
}
|
||||
}, "Check if inline is possible...", true, project)) return;
|
||||
if (errorMessage.get() != null) {
|
||||
CommonRefactoringUtil.showErrorHint(project, editor, errorMessage.get(), RefactoringBundle.message("inline.to.anonymous.refactoring"), null);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -29,6 +29,7 @@ import com.intellij.openapi.actionSystem.PlatformDataKeys;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.editor.ScrollType;
|
||||
import com.intellij.openapi.progress.ProgressManager;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.ui.DialogWrapper;
|
||||
import com.intellij.psi.*;
|
||||
@@ -142,11 +143,17 @@ public class JavaPullUpHandler implements RefactoringActionHandler, PullUpDialog
|
||||
|
||||
|
||||
|
||||
public boolean checkConflicts(PullUpDialog dialog) {
|
||||
public boolean checkConflicts(final PullUpDialog dialog) {
|
||||
final MemberInfo[] infos = dialog.getSelectedMemberInfos();
|
||||
PsiClass superClass = dialog.getSuperClass();
|
||||
final PsiClass superClass = dialog.getSuperClass();
|
||||
if (!checkWritable(superClass, infos)) return false;
|
||||
MultiMap<PsiElement,String> conflicts = PullUpConflictsUtil.checkConflicts(infos, mySubclass, superClass, null, null, dialog.getContainmentVerifier());
|
||||
final MultiMap<PsiElement, String> conflicts = new MultiMap<PsiElement, String>();
|
||||
if (!ProgressManager.getInstance().runProcessWithProgressSynchronously(new Runnable() {
|
||||
public void run() {
|
||||
conflicts
|
||||
.putAllValues(PullUpConflictsUtil.checkConflicts(infos, mySubclass, superClass, null, null, dialog.getContainmentVerifier()));
|
||||
}
|
||||
}, "Detecting possible conflicts...", true, myProject)) return false;
|
||||
if (!conflicts.isEmpty()) {
|
||||
ConflictsDialog conflictsDialog = new ConflictsDialog(myProject, conflicts);
|
||||
conflictsDialog.show();
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
class Test {
|
||||
void f() {
|
||||
new Runnable() {
|
||||
public void run() {
|
||||
int j = 0;
|
||||
if (j == 0 && <selection>j < 0 && j > 0</selection>) {
|
||||
assert false;
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
class Test {
|
||||
void f() {
|
||||
new Runnable() {
|
||||
public void run() {
|
||||
int j = 0;
|
||||
if (j == 0 && newMethod(j)) {
|
||||
assert false;
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private boolean newMethod(int j) {
|
||||
return j < 0 && j > 0;
|
||||
}
|
||||
}
|
||||
@@ -9,10 +9,13 @@ import com.intellij.openapi.projectRoots.impl.JavaSdkImpl;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiExpression;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.psi.PsiType;
|
||||
import com.intellij.psi.codeStyle.CodeStyleSettings;
|
||||
import com.intellij.psi.codeStyle.CodeStyleSettingsManager;
|
||||
import com.intellij.refactoring.extractMethod.ExtractMethodProcessor;
|
||||
import com.intellij.refactoring.extractMethod.PrepareFailedException;
|
||||
import com.intellij.refactoring.introduceVariable.IntroduceVariableBase;
|
||||
import com.intellij.refactoring.util.RefactoringUtil;
|
||||
import com.intellij.refactoring.util.duplicates.Match;
|
||||
import com.intellij.testFramework.LightCodeInsightTestCase;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
@@ -448,6 +451,10 @@ public class ExtractMethodTest extends LightCodeInsightTestCase {
|
||||
doDuplicatesTest();
|
||||
}
|
||||
|
||||
public void testParametersFromAnonymous() throws Exception {
|
||||
doTest();
|
||||
}
|
||||
|
||||
private void doPrepareErrorTest(final String expectedMessage) throws Exception {
|
||||
String expectedError = null;
|
||||
try {
|
||||
@@ -503,6 +510,12 @@ public class ExtractMethodTest extends LightCodeInsightTestCase {
|
||||
else {
|
||||
elements = CodeInsightUtil.findStatementsInRange(file, startOffset, endOffset);
|
||||
}
|
||||
if (elements.length == 0) {
|
||||
final PsiExpression expression = IntroduceVariableBase.getSelectedExpression(project, file, startOffset, endOffset);
|
||||
if (expression != null) {
|
||||
elements = new PsiElement[]{expression};
|
||||
}
|
||||
}
|
||||
assertTrue(elements.length > 0);
|
||||
|
||||
final ExtractMethodProcessor processor =
|
||||
|
||||
@@ -30,6 +30,7 @@ import java.util.Collection;
|
||||
* @author spleaner
|
||||
*/
|
||||
public abstract class FileColorManager {
|
||||
public static final String OUT_OF_PROJECT_SCOPE_COLOR = "OUT_OF_PROJECT_SCOPE";
|
||||
|
||||
public static FileColorManager getInstance(@NotNull final Project project) {
|
||||
return ServiceManager.getService(project, FileColorManager.class);
|
||||
@@ -41,6 +42,8 @@ public abstract class FileColorManager {
|
||||
|
||||
public abstract boolean isEnabledForTabs();
|
||||
|
||||
public abstract boolean isHighlightNonProjectFiles();
|
||||
|
||||
@SuppressWarnings({"MethodMayBeStatic"})
|
||||
@Nullable
|
||||
public abstract Color getColor(@NotNull String name);
|
||||
|
||||
+20
-10
@@ -23,14 +23,17 @@ import com.intellij.openapi.application.ModalityState;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.editor.EditorFactory;
|
||||
import com.intellij.openapi.editor.ex.EditorSettingsExternalizable;
|
||||
import com.intellij.openapi.editor.impl.FoldingModelImpl;
|
||||
import com.intellij.openapi.extensions.Extensions;
|
||||
import com.intellij.openapi.options.CompositeConfigurable;
|
||||
import com.intellij.openapi.options.ConfigurationException;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import org.jetbrains.annotations.Nls;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
@@ -57,8 +60,9 @@ public class CodeFoldingConfigurable extends CompositeConfigurable<CodeFoldingOp
|
||||
|
||||
public JComponent createComponent() {
|
||||
for (CodeFoldingOptionsProvider provider : getConfigurables()) {
|
||||
myFoldingPanel.add(provider.createComponent(), new GridBagConstraints(0, GridBagConstraints.RELATIVE, 1, 1, 0, 0, GridBagConstraints.NORTHWEST,
|
||||
GridBagConstraints.NONE, new Insets(0,0,0,0), 0,0));
|
||||
myFoldingPanel
|
||||
.add(provider.createComponent(), new GridBagConstraints(0, GridBagConstraints.RELATIVE, 1, 1, 0, 0, GridBagConstraints.NORTHWEST,
|
||||
GridBagConstraints.NONE, new Insets(0, 0, 0, 0), 0, 0));
|
||||
}
|
||||
return myRootPanel;
|
||||
}
|
||||
@@ -72,19 +76,25 @@ public class CodeFoldingConfigurable extends CompositeConfigurable<CodeFoldingOp
|
||||
EditorSettingsExternalizable.getInstance().setFoldingOutlineShown(myCbFolding.isSelected());
|
||||
super.apply();
|
||||
|
||||
final List<Pair<Editor, Project>> toUpdate = new ArrayList<Pair<Editor, Project>>();
|
||||
for (final Editor editor : EditorFactory.getInstance().getAllEditors()) {
|
||||
final Project project = editor.getProject();
|
||||
if (project != null && !project.isDefault()) {
|
||||
final CodeFoldingManager foldingManager = CodeFoldingManager.getInstance(project);
|
||||
if (foldingManager != null) {
|
||||
ApplicationManager.getApplication().invokeLater(new Runnable() {
|
||||
public void run() {
|
||||
foldingManager.forceDefaultState(editor);
|
||||
}
|
||||
}, ModalityState.NON_MODAL);
|
||||
}
|
||||
toUpdate.add(Pair.create(editor, project));
|
||||
}
|
||||
}
|
||||
|
||||
ApplicationManager.getApplication().invokeLater(new Runnable() {
|
||||
public void run() {
|
||||
for (Pair<Editor, Project> each : toUpdate) {
|
||||
final CodeFoldingManager foldingManager = CodeFoldingManager.getInstance(each.second);
|
||||
if (foldingManager != null) {
|
||||
foldingManager.buildInitialFoldings(each.first);
|
||||
}
|
||||
}
|
||||
EditorOptionsPanel.reinitAllEditors();
|
||||
}
|
||||
}, ModalityState.NON_MODAL);
|
||||
}
|
||||
|
||||
public void reset() {
|
||||
|
||||
+2
-2
@@ -87,7 +87,7 @@ public class UpdateHighlightersUtil {
|
||||
List<HighlightInfo> infosToRemove = new ArrayList<HighlightInfo>();
|
||||
for (HighlightInfo info : infos) {
|
||||
if (info.group == group) {
|
||||
manager.removeEditorAnnotation(fileEditor, info.fileLevelComponent);
|
||||
manager.removeTopComponent(fileEditor, info.fileLevelComponent);
|
||||
infosToRemove.add(info);
|
||||
}
|
||||
}
|
||||
@@ -340,7 +340,7 @@ public class UpdateHighlightersUtil {
|
||||
if (fileEditor instanceof TextEditor) {
|
||||
FileLevelIntentionComponent component = new FileLevelIntentionComponent(info.description, info.severity, info.quickFixActionRanges,
|
||||
project, psiFile, ((TextEditor)fileEditor).getEditor());
|
||||
manager.showEditorAnnotation(fileEditor, component);
|
||||
manager.addTopComponent(fileEditor, component);
|
||||
List<HighlightInfo> fileLevelInfos = fileEditor.getUserData(FILE_LEVEL_HIGHLIGHTS);
|
||||
if (fileLevelInfos == null) {
|
||||
fileLevelInfos = new ArrayList<HighlightInfo>();
|
||||
|
||||
-1
@@ -49,7 +49,6 @@ public class FileLevelIntentionComponent extends EditorNotificationPanel {
|
||||
final HighlightSeverity severity,
|
||||
final List<Pair<HighlightInfo.IntentionActionDescriptor, TextRange>> intentions,
|
||||
final Project project, final PsiFile psiFile, final Editor editor) {
|
||||
super();
|
||||
myProject = project;
|
||||
|
||||
final ShowIntentionsPass.IntentionsInfo info = new ShowIntentionsPass.IntentionsInfo();
|
||||
|
||||
@@ -155,4 +155,8 @@ public class CustomTemplateCallback {
|
||||
}
|
||||
return element;
|
||||
}
|
||||
|
||||
public boolean isInInjectedFragment() {
|
||||
return myInInjectedFragment;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -150,7 +150,7 @@ public class ExecutionHelper {
|
||||
|
||||
public static class RailsErrorViewPanel extends NewErrorTreeViewPanel {
|
||||
public RailsErrorViewPanel(final Project project) {
|
||||
super(project, null);
|
||||
super(project, "reference.toolWindows.messages");
|
||||
}
|
||||
|
||||
protected boolean canHideWarnings() {
|
||||
@@ -270,54 +270,27 @@ public class ExecutionHelper {
|
||||
final int timeout) {
|
||||
return new Runnable() {
|
||||
private final Semaphore mySemaphore = new Semaphore();
|
||||
private final Object LOCK = new Object();
|
||||
private Boolean processedFinished = Boolean.FALSE;
|
||||
|
||||
private final Runnable myProcessThread = new Runnable() {
|
||||
public void run() {
|
||||
try {
|
||||
processHandler.waitFor();
|
||||
synchronized (LOCK) {
|
||||
processedFinished = Boolean.TRUE;
|
||||
final boolean finished = processHandler.waitFor(1000 * timeout);
|
||||
if (!finished) {
|
||||
LOG.error("Timeout (" + timeout + " sec) on executing: " + processHandler.getCommandLine());
|
||||
processHandler.destroyProcess();
|
||||
}
|
||||
}
|
||||
finally {
|
||||
} finally {
|
||||
mySemaphore.up();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
private final Runnable myTimeoutListener = new Runnable() {
|
||||
public void run() {
|
||||
try {
|
||||
synchronized (this) {
|
||||
try {
|
||||
wait(1000 * timeout);
|
||||
synchronized (LOCK) {
|
||||
if (!processedFinished) {
|
||||
LOG.error("Timeout (" + timeout + " sec) on executing: " + processHandler.getCommandLine());
|
||||
processHandler.destroyProcess();
|
||||
}
|
||||
}
|
||||
}
|
||||
finally {
|
||||
mySemaphore.up();
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (InterruptedException e) {
|
||||
//Do nothing
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
public void run() {
|
||||
mySemaphore.down();
|
||||
ApplicationManager.getApplication().executeOnPooledThread(myProcessThread);
|
||||
ApplicationManager.getApplication().executeOnPooledThread(myTimeoutListener);
|
||||
|
||||
mySemaphore.waitFor();
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+4
-3
@@ -100,7 +100,8 @@ public class GeneralColorsPage implements ColorSettingsPage, InspectionColorSett
|
||||
private static final ColorDescriptor[] COLOR_DESCRIPTORS = {
|
||||
new ColorDescriptor(OptionsBundle.message("options.general.color.descriptor.background.in.readonly.files"), EditorColors.READONLY_BACKGROUND_COLOR, ColorDescriptor.Kind.BACKGROUND),
|
||||
new ColorDescriptor(OptionsBundle.message("options.deneral.color.descriptor.readonly.fragment.background"), EditorColors.READONLY_FRAGMENT_BACKGROUND_COLOR, ColorDescriptor.Kind.BACKGROUND),
|
||||
new ColorDescriptor(OptionsBundle.message("options.general.color.descriptor.gutter.background"), EditorColors.LEFT_GUTTER_BACKGROUND, ColorDescriptor.Kind.BACKGROUND),
|
||||
new ColorDescriptor(OptionsBundle.message("options.general.color.descriptor.gutter.background"), EditorColors.GUTTER_BACKGROUND, ColorDescriptor.Kind.BACKGROUND),
|
||||
new ColorDescriptor(OptionsBundle.message("options.general.color.descriptor.notification.background"), EditorColors.NOTIFICATION_BACKGROUND, ColorDescriptor.Kind.BACKGROUND),
|
||||
|
||||
new ColorDescriptor(OptionsBundle.message("options.general.color.descriptor.selection.background"), EditorColors.SELECTION_BACKGROUND_COLOR, ColorDescriptor.Kind.BACKGROUND),
|
||||
new ColorDescriptor(OptionsBundle.message("options.general.color.descriptor.selection.foreground"), EditorColors.SELECTION_FOREGROUND_COLOR, ColorDescriptor.Kind.FOREGROUND),
|
||||
@@ -113,8 +114,8 @@ public class GeneralColorsPage implements ColorSettingsPage, InspectionColorSett
|
||||
new ColorDescriptor(OptionsBundle.message("options.general.color.descriptor.line.number"), EditorColors.LINE_NUMBERS_COLOR, ColorDescriptor.Kind.FOREGROUND),
|
||||
new ColorDescriptor(OptionsBundle.message("options.general.color.descriptor.vcs.annotations"), EditorColors.ANNOTATIONS_COLOR, ColorDescriptor.Kind.FOREGROUND),
|
||||
new ColorDescriptor(OptionsBundle.message("options.general.color.descriptor.vcs.annotations.merged"), EditorColors.ANNOTATIONS_MERGED_COLOR, ColorDescriptor.Kind.FOREGROUND),
|
||||
new ColorDescriptor(OptionsBundle.message("options.general.color.descriptor.folding.outline"), EditorColors.FOLDING_TREE_COLOR, ColorDescriptor.Kind.FOREGROUND),
|
||||
new ColorDescriptor(OptionsBundle.message("options.general.color.descriptor.selected.folding.outline"), EditorColors.SELECTED_FOLDING_TREE_COLOR, ColorDescriptor.Kind.FOREGROUND),
|
||||
new ColorDescriptor(OptionsBundle.message("options.general.color.descriptor.tearline"), EditorColors.TEARLINE_COLOR, ColorDescriptor.Kind.FOREGROUND),
|
||||
new ColorDescriptor(OptionsBundle.message("options.general.color.descriptor.tearline.selected"), EditorColors.SELECTED_TEARLINE_COLOR, ColorDescriptor.Kind.FOREGROUND),
|
||||
new ColorDescriptor(OptionsBundle.message("options.general.color.descriptor.added.lines"), EditorColors.ADDED_LINES_COLOR, ColorDescriptor.Kind.BACKGROUND),
|
||||
new ColorDescriptor(OptionsBundle.message("options.general.color.descriptor.modified.lines"), EditorColors.MODIFIED_LINES_COLOR, ColorDescriptor.Kind.BACKGROUND),
|
||||
new ColorDescriptor(OptionsBundle.message("options.java.color.descriptor.method.separator.color"), CodeInsightColors.METHOD_SEPARATORS_COLOR, ColorDescriptor.Kind.FOREGROUND),
|
||||
|
||||
+17
-5
@@ -32,12 +32,13 @@ import com.intellij.refactoring.rename.PsiElementRenameHandler;
|
||||
import com.intellij.refactoring.rename.RenameHandler;
|
||||
import com.intellij.refactoring.rename.RenameHandlerRegistry;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public final class VariableInplaceRenameHandler implements RenameHandler {
|
||||
public class VariableInplaceRenameHandler implements RenameHandler {
|
||||
private static final ThreadLocal<Boolean> ourPreventInlineRenameFlag = new ThreadLocal<Boolean>();
|
||||
private static final Logger LOG = Logger.getInstance("#com.intellij.refactoring.rename.inplace.VariableInplaceRenameHandler");
|
||||
|
||||
public boolean isAvailableOnDataContext(final DataContext dataContext) {
|
||||
public final boolean isAvailableOnDataContext(final DataContext dataContext) {
|
||||
final PsiElement element = PsiElementRenameHandler.getElement(dataContext);
|
||||
final Editor editor = PlatformDataKeys.EDITOR.getData(dataContext);
|
||||
final PsiFile file = LangDataKeys.PSI_FILE.getData(dataContext);
|
||||
@@ -46,15 +47,20 @@ public final class VariableInplaceRenameHandler implements RenameHandler {
|
||||
if (ourPreventInlineRenameFlag.get() != null) {
|
||||
return false;
|
||||
}
|
||||
return isAvailable(element, editor, file);
|
||||
}
|
||||
|
||||
protected boolean isAvailable(PsiElement element, Editor editor, PsiFile file) {
|
||||
final PsiElement nameSuggestionContext = file.findElementAt(editor.getCaretModel().getOffset());
|
||||
|
||||
final RefactoringSupportProvider supportProvider = element != null ? LanguageRefactoringSupport.INSTANCE.forLanguage(element.getLanguage()):null;
|
||||
final RefactoringSupportProvider
|
||||
supportProvider = element != null ? LanguageRefactoringSupport.INSTANCE.forLanguage(element.getLanguage()):null;
|
||||
return supportProvider != null &&
|
||||
editor.getSettings().isVariableInplaceRenameEnabled() &&
|
||||
supportProvider.doInplaceRenameFor(element, nameSuggestionContext);
|
||||
}
|
||||
|
||||
public boolean isRenaming(final DataContext dataContext) {
|
||||
public final boolean isRenaming(final DataContext dataContext) {
|
||||
return isAvailableOnDataContext(dataContext);
|
||||
}
|
||||
|
||||
@@ -83,7 +89,8 @@ public final class VariableInplaceRenameHandler implements RenameHandler {
|
||||
return;
|
||||
}
|
||||
|
||||
final boolean startedRename = new VariableInplaceRenamer((PsiNameIdentifierOwner)elementToRename, editor).performInplaceRename();
|
||||
VariableInplaceRenamer renamer = createRenamer(elementToRename, editor);
|
||||
boolean startedRename = renamer == null ? false : renamer.performInplaceRename();
|
||||
|
||||
if (!startedRename) {
|
||||
try {
|
||||
@@ -101,4 +108,9 @@ public final class VariableInplaceRenameHandler implements RenameHandler {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
protected VariableInplaceRenamer createRenamer(PsiElement elementToRename, Editor editor) {
|
||||
return new VariableInplaceRenamer((PsiNameIdentifierOwner)elementToRename, editor);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
|
||||
package com.intellij.ui.tabs;
|
||||
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.psi.search.scope.packageSet.NamedScopeManager;
|
||||
import org.jdom.Element;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
@@ -54,7 +56,7 @@ class FileColorConfiguration implements Cloneable {
|
||||
myColorName = colorName;
|
||||
}
|
||||
|
||||
public boolean isValid() {
|
||||
public boolean isValid(Project project) {
|
||||
if (myScopeName == null || myScopeName.length() == 0) {
|
||||
return false;
|
||||
}
|
||||
@@ -63,11 +65,15 @@ class FileColorConfiguration implements Cloneable {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
if (project != null) {
|
||||
return NamedScopeManager.getScope(project, myScopeName) != null;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public void save(@NotNull final Element e) {
|
||||
if (!isValid()) {
|
||||
if (!isValid(null)) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -53,11 +53,14 @@ public class FileColorManagerImpl extends FileColorManager implements Persistent
|
||||
|
||||
private final Project myProject;
|
||||
private boolean myEnabledForTabs = true;
|
||||
private boolean myHighlightNonProjectFiles = true;
|
||||
|
||||
private static final Map<String, Color> ourDefaultColors;
|
||||
private static final Map<String, Color> ourHiddenColors;
|
||||
|
||||
static {
|
||||
ourDefaultColors = new LinkedHashMap<String, Color>();
|
||||
ourHiddenColors = new LinkedHashMap<String, Color>();
|
||||
ourDefaultColors.put("Blue", new Color(215, 237, 243));
|
||||
//ourDefaultColors.put("Blue 2", new Color(218, 224, 244));
|
||||
ourDefaultColors.put("Green", new Color(228, 241, 209));
|
||||
@@ -66,6 +69,8 @@ public class FileColorManagerImpl extends FileColorManager implements Persistent
|
||||
ourDefaultColors.put("Rose", new Color(242, 206, 202));
|
||||
ourDefaultColors.put("Violet", new Color(222, 213, 241));
|
||||
ourDefaultColors.put("Yellow", new Color(247, 241, 203));
|
||||
|
||||
ourHiddenColors.put(OUT_OF_PROJECT_SCOPE_COLOR, new Color(255, 255, 228));
|
||||
}
|
||||
|
||||
public FileColorManagerImpl(@NotNull final Project project) {
|
||||
@@ -95,11 +100,20 @@ public class FileColorManagerImpl extends FileColorManager implements Persistent
|
||||
return myEnabledForTabs;
|
||||
}
|
||||
|
||||
public boolean isHighlightNonProjectFiles() {
|
||||
return myHighlightNonProjectFiles;
|
||||
}
|
||||
|
||||
public void setHighlightNonProjectFiles(boolean highlight) {
|
||||
myHighlightNonProjectFiles = highlight;
|
||||
}
|
||||
|
||||
public Element getState(final boolean shared) {
|
||||
Element element = new Element("state");
|
||||
if (!shared) {
|
||||
element.setAttribute("enabled", Boolean.toString(myEnabled));
|
||||
element.setAttribute("enabledForTabs", Boolean.toString(myEnabledForTabs));
|
||||
element.setAttribute("highlightNonProjectFiles", Boolean.toString(myHighlightNonProjectFiles));
|
||||
}
|
||||
|
||||
myModel.save(element, shared);
|
||||
@@ -110,7 +124,8 @@ public class FileColorManagerImpl extends FileColorManager implements Persistent
|
||||
@SuppressWarnings({"MethodMayBeStatic"})
|
||||
@Nullable
|
||||
public Color getColor(@NotNull final String name) {
|
||||
return ourDefaultColors.get(name);
|
||||
final Color color = ourDefaultColors.get(name);
|
||||
return color == null ? ourHiddenColors.get(name) : color;
|
||||
}
|
||||
|
||||
public static String toString(final Color color) {
|
||||
@@ -133,7 +148,10 @@ public class FileColorManagerImpl extends FileColorManager implements Persistent
|
||||
myEnabled = enabled == null ? true : Boolean.valueOf(enabled);
|
||||
|
||||
final String enabledForTabs = state.getAttributeValue("enabledForTabs");
|
||||
myEnabledForTabs = enabledForTabs == null ? false : Boolean.valueOf(enabledForTabs);
|
||||
myEnabledForTabs = enabledForTabs == null ? true : Boolean.valueOf(enabledForTabs);
|
||||
|
||||
final String highlightNonProjectFiles = state.getAttributeValue("highlightNonProjectFiles");
|
||||
myHighlightNonProjectFiles = highlightNonProjectFiles == null ? true : Boolean.valueOf(highlightNonProjectFiles);
|
||||
}
|
||||
|
||||
myModel.load(state, shared);
|
||||
@@ -183,7 +201,7 @@ public class FileColorManagerImpl extends FileColorManager implements Persistent
|
||||
@Nullable
|
||||
public Color getFileColor(@NotNull final PsiFile file) {
|
||||
final String colorName = myModel.getColor(file);
|
||||
return colorName == null ? null : ourDefaultColors.get(colorName);
|
||||
return colorName == null ? null : getColor(colorName);
|
||||
}
|
||||
|
||||
public boolean isShared(@NotNull final String scopeName) {
|
||||
|
||||
@@ -37,6 +37,7 @@ public class FileColorsConfigurablePanel extends JPanel implements Disposable {
|
||||
private FileColorManagerImpl myManager;
|
||||
private final JCheckBox myEnabledCheckBox;
|
||||
private final JCheckBox myTabsEnabledCheckBox;
|
||||
private final JCheckBox myHighlightNonProjectFilesCheckBox;
|
||||
private final FileColorSettingsTable myLocalTable;
|
||||
private final FileColorSettingsTable mySharedTable;
|
||||
|
||||
@@ -56,6 +57,10 @@ public class FileColorsConfigurablePanel extends JPanel implements Disposable {
|
||||
myTabsEnabledCheckBox = new JCheckBox("Use colors in Editor Tabs");
|
||||
myTabsEnabledCheckBox.setMnemonic('T');
|
||||
topPanel.add(myTabsEnabledCheckBox);
|
||||
|
||||
myHighlightNonProjectFilesCheckBox = new JCheckBox("Highlight Non-Project Files");
|
||||
myHighlightNonProjectFilesCheckBox.setMnemonic('N');
|
||||
topPanel.add(myHighlightNonProjectFilesCheckBox);
|
||||
topPanel.add(Box.createHorizontalGlue());
|
||||
|
||||
add(topPanel, BorderLayout.NORTH);
|
||||
@@ -229,6 +234,7 @@ public class FileColorsConfigurablePanel extends JPanel implements Disposable {
|
||||
|
||||
modified = myEnabledCheckBox.isSelected() != myManager.isEnabled();
|
||||
modified |= myTabsEnabledCheckBox.isSelected() != myManager.isEnabledForTabs();
|
||||
modified |= myHighlightNonProjectFilesCheckBox.isSelected() != myManager.isHighlightNonProjectFiles();
|
||||
modified |= myLocalTable.isModified() || mySharedTable.isModified();
|
||||
|
||||
return modified;
|
||||
@@ -237,6 +243,7 @@ public class FileColorsConfigurablePanel extends JPanel implements Disposable {
|
||||
public void apply() {
|
||||
myManager.setEnabled(myEnabledCheckBox.isSelected());
|
||||
myManager.setEnabledForTabs(myTabsEnabledCheckBox.isSelected());
|
||||
myManager.setHighlightNonProjectFiles(myHighlightNonProjectFilesCheckBox.isSelected());
|
||||
|
||||
myLocalTable.apply();
|
||||
mySharedTable.apply();
|
||||
@@ -247,6 +254,7 @@ public class FileColorsConfigurablePanel extends JPanel implements Disposable {
|
||||
public void reset() {
|
||||
myEnabledCheckBox.setSelected(myManager.isEnabled());
|
||||
myTabsEnabledCheckBox.setSelected(myManager.isEnabledForTabs());
|
||||
myHighlightNonProjectFilesCheckBox.setSelected(myManager.isHighlightNonProjectFiles());
|
||||
|
||||
if(myLocalTable.isModified()) myLocalTable.reset();
|
||||
if(mySharedTable.isModified()) mySharedTable.reset();
|
||||
|
||||
@@ -17,10 +17,14 @@
|
||||
package com.intellij.ui.tabs;
|
||||
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.roots.ProjectFileIndex;
|
||||
import com.intellij.openapi.roots.ProjectRootManager;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.psi.search.scope.packageSet.NamedScope;
|
||||
import com.intellij.psi.search.scope.packageSet.NamedScopeManager;
|
||||
import com.intellij.psi.search.scope.packageSet.NamedScopesHolder;
|
||||
import com.intellij.ui.FileColorManager;
|
||||
import org.jdom.Element;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
@@ -136,13 +140,23 @@ public class FileColorsModel implements Cloneable {
|
||||
}
|
||||
|
||||
final FileColorConfiguration configuration = findConfiguration(psiFile);
|
||||
if (configuration != null && configuration.isValid()) {
|
||||
if (configuration != null && configuration.isValid(psiFile.getProject())) {
|
||||
return configuration.getColorName();
|
||||
}
|
||||
|
||||
if (FileColorManager.getInstance(myProject).isHighlightNonProjectFiles()
|
||||
&& !isFileUnderProject(psiFile.getVirtualFile())) {
|
||||
return FileColorManager.OUT_OF_PROJECT_SCOPE_COLOR;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private boolean isFileUnderProject(@Nullable VirtualFile file) {
|
||||
if (file == null) return false;
|
||||
final ProjectFileIndex fileIndex = ProjectRootManager.getInstance(myProject).getFileIndex();
|
||||
return myProject.isInitialized() && !fileIndex.isIgnored(file) && fileIndex.getContentRootForFile(file) != null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private FileColorConfiguration findConfiguration(@NotNull final PsiFile colored) {
|
||||
for (final FileColorConfiguration configuration : myConfigurations) {
|
||||
|
||||
@@ -33,15 +33,22 @@ public interface EditorColors {
|
||||
TextAttributesKey SEARCH_RESULT_ATTRIBUTES = TextAttributesKey.createTextAttributesKey("SEARCH_RESULT_ATTRIBUTES");
|
||||
TextAttributesKey WRITE_SEARCH_RESULT_ATTRIBUTES = TextAttributesKey.createTextAttributesKey("WRITE_SEARCH_RESULT_ATTRIBUTES");
|
||||
TextAttributesKey IDENTIFIER_UNDER_CARET_ATTRIBUTES = TextAttributesKey.createTextAttributesKey("IDENTIFIER_UNDER_CARET_ATTRIBUTES");
|
||||
TextAttributesKey WRITE_IDENTIFIER_UNDER_CARET_ATTRIBUTES = TextAttributesKey.createTextAttributesKey("WRITE_IDENTIFIER_UNDER_CARET_ATTRIBUTES");
|
||||
TextAttributesKey WRITE_IDENTIFIER_UNDER_CARET_ATTRIBUTES =
|
||||
TextAttributesKey.createTextAttributesKey("WRITE_IDENTIFIER_UNDER_CARET_ATTRIBUTES");
|
||||
TextAttributesKey TEXT_SEARCH_RESULT_ATTRIBUTES = TextAttributesKey.createTextAttributesKey("TEXT_SEARCH_RESULT_ATTRIBUTES");
|
||||
|
||||
TextAttributesKey FOLDED_TEXT_ATTRIBUTES = TextAttributesKey.createTextAttributesKey("FOLDED_TEXT_ATTRIBUTES");
|
||||
ColorKey FOLDING_TREE_COLOR = ColorKey.createColorKey("FOLDING_TREE_COLOR");
|
||||
ColorKey SELECTED_FOLDING_TREE_COLOR = ColorKey.createColorKey("SELECTED_FOLDING_TREE_COLOR");
|
||||
|
||||
ColorKey GUTTER_BACKGROUND = ColorKey.createColorKey("GUTTER_BACKGROUND");
|
||||
@Deprecated ColorKey LEFT_GUTTER_BACKGROUND = GUTTER_BACKGROUND;
|
||||
ColorKey NOTIFICATION_BACKGROUND = ColorKey.createColorKey("NOTIFICATION_BACKGROUND");
|
||||
|
||||
ColorKey TEARLINE_COLOR = ColorKey.createColorKey("TEARLINE_COLOR");
|
||||
ColorKey SELECTED_TEARLINE_COLOR = ColorKey.createColorKey("SELECTED_TEARLINE_COLOR");
|
||||
@Deprecated ColorKey FOLDING_TREE_COLOR = TEARLINE_COLOR;
|
||||
@Deprecated ColorKey SELECTED_FOLDING_TREE_COLOR = SELECTED_TEARLINE_COLOR;
|
||||
|
||||
ColorKey ADDED_LINES_COLOR = ColorKey.createColorKey("ADDED_LINES_COLOR");
|
||||
ColorKey MODIFIED_LINES_COLOR = ColorKey.createColorKey("MODIFIED_LINES_COLOR");
|
||||
ColorKey LEFT_GUTTER_BACKGROUND = ColorKey.createColorKey("LEFT_GUTTER_BACKGROUND");
|
||||
TextAttributesKey INJECTED_LANGUAGE_FRAGMENT = TextAttributesKey.createTextAttributesKey("INJECTED_LANGUAGE_FRAGMENT");
|
||||
}
|
||||
|
||||
@@ -108,7 +108,13 @@ public abstract class FileEditorManager {
|
||||
*/
|
||||
@NotNull public abstract FileEditor[] getAllEditors();
|
||||
|
||||
/**
|
||||
* @deprecated use addTopComponent
|
||||
*/
|
||||
public abstract void showEditorAnnotation(@NotNull FileEditor editor, @NotNull JComponent annotationComoponent);
|
||||
/**
|
||||
* @deprecated use removeTopComponent
|
||||
*/
|
||||
public abstract void removeEditorAnnotation(@NotNull FileEditor editor, @NotNull JComponent annotationComoponent);
|
||||
|
||||
public abstract void addTopComponent(@NotNull final FileEditor editor, @NotNull final JComponent component);
|
||||
|
||||
@@ -20,6 +20,9 @@ import com.intellij.openapi.actionSystem.ActionManager;
|
||||
import com.intellij.openapi.actionSystem.ActionPlaces;
|
||||
import com.intellij.openapi.actionSystem.AnAction;
|
||||
import com.intellij.openapi.actionSystem.AnActionEvent;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.editor.colors.EditorColors;
|
||||
import com.intellij.openapi.editor.colors.EditorColorsManager;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
|
||||
import javax.swing.*;
|
||||
@@ -31,19 +34,16 @@ import java.awt.*;
|
||||
* @author Dmitry Avdeev
|
||||
*/
|
||||
public class EditorNotificationPanel extends JPanel {
|
||||
|
||||
protected final JLabel myLabel = new JLabel();
|
||||
protected final JPanel myLinksPanel;
|
||||
|
||||
public EditorNotificationPanel() {
|
||||
super(new BorderLayout());
|
||||
|
||||
setBackground(LightColors.YELLOW);
|
||||
setBorder(new SideBorder(Color.gray, SideBorder.BOTTOM, true));
|
||||
setBorder(BorderFactory.createEmptyBorder(1, 15, 1, 15));
|
||||
|
||||
setPreferredSize(new Dimension(-1, 24));
|
||||
|
||||
add(myLabel, BorderLayout.CENTER);
|
||||
myLabel.setBorder(BorderFactory.createEmptyBorder(0, 10, 0, 0));
|
||||
|
||||
myLinksPanel = new JPanel(new FlowLayout());
|
||||
myLinksPanel.setBackground(LightColors.YELLOW);
|
||||
@@ -54,6 +54,12 @@ public class EditorNotificationPanel extends JPanel {
|
||||
myLabel.setText(text);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Color getBackground() {
|
||||
Color color = EditorColorsManager.getInstance().getGlobalScheme().getColor(EditorColors.NOTIFICATION_BACKGROUND);
|
||||
return color == null ? new Color(0xffffcc) : color;
|
||||
}
|
||||
|
||||
public HyperlinkLabel createActionLabel(final String text, @NonNls final String actionId) {
|
||||
return createActionLabel(text, new Runnable() {
|
||||
public void run() {
|
||||
@@ -63,7 +69,7 @@ public class EditorNotificationPanel extends JPanel {
|
||||
}
|
||||
|
||||
public HyperlinkLabel createActionLabel(final String text, final Runnable action) {
|
||||
HyperlinkLabel label = new HyperlinkLabel(text, Color.BLUE, LightColors.YELLOW, Color.BLUE);
|
||||
HyperlinkLabel label = new HyperlinkLabel(text, Color.BLUE, getBackground(), Color.BLUE);
|
||||
label.addHyperlinkListener(new HyperlinkListener() {
|
||||
public void hyperlinkUpdate(final HyperlinkEvent e) {
|
||||
if (e.getEventType() == HyperlinkEvent.EventType.ACTIVATED) {
|
||||
|
||||
@@ -85,6 +85,6 @@ public class ExcludingTraversalPolicy extends FocusTraversalPolicy {
|
||||
|
||||
@Override
|
||||
public Component getDefaultComponent(Container aContainer) {
|
||||
return myWrappee.getDefaultComponent(aContainer);
|
||||
return getFirstComponent(aContainer);
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -114,7 +114,7 @@ public class EditorFragmentComponent extends JPanel {
|
||||
setLayout(new BorderLayout());
|
||||
add(component);
|
||||
|
||||
final Color borderColor = editor.getColorsScheme().getColor(EditorColors.SELECTED_FOLDING_TREE_COLOR);
|
||||
final Color borderColor = editor.getColorsScheme().getColor(EditorColors.SELECTED_TEARLINE_COLOR);
|
||||
|
||||
Border outsideBorder = BorderFactory.createLineBorder(borderColor, 1);
|
||||
Border insideBorder = BorderFactory.createEmptyBorder(2, 2, 2, 2);
|
||||
|
||||
+8
-1
@@ -31,7 +31,14 @@ public abstract class EditorGutterComponentEx extends JComponent implements Edit
|
||||
|
||||
public abstract int getWhitespaceSeparatorOffset();
|
||||
|
||||
public abstract Color getFoldingColor(boolean isActive);
|
||||
public abstract Color getOutlineColor(boolean isActive);
|
||||
|
||||
/**
|
||||
* @deprecated use getOutlineColor
|
||||
*/
|
||||
public Color getFoldingColor(boolean isActive) {
|
||||
return getOutlineColor(isActive);
|
||||
}
|
||||
|
||||
public abstract void revalidateMarkup();
|
||||
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* 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.openapi.editor.ex;
|
||||
|
||||
/**
|
||||
* Defines a contract for the callbacks for soft wraps management notifications (addition/removal).
|
||||
*
|
||||
* @author Denis Zhdanov
|
||||
* @since Jul 8, 2010 6:50:17 PM
|
||||
*/
|
||||
public interface SoftWrapChangeListener {
|
||||
|
||||
/**
|
||||
* This method is assumed to be called every time number of soft wraps registered for the target logical line(s)
|
||||
* is changed (soft wraps are added or remove).
|
||||
*
|
||||
* @param changedLogicalLine logical line for which number of registered soft wraps is changed
|
||||
*/
|
||||
void softWrapsStateChanged(int changedLogicalLine);
|
||||
}
|
||||
@@ -23,6 +23,7 @@ import com.intellij.openapi.editor.impl.softwrap.SoftWrapDrawingType;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.awt.*;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
@@ -72,6 +73,18 @@ public interface SoftWrapModelEx extends SoftWrapModel {
|
||||
*/
|
||||
List<? extends TextChange> getRegisteredSoftWraps();
|
||||
|
||||
/**
|
||||
* Tries to find index of the target soft wrap at {@link #getRegisteredSoftWraps() soft wraps collection}.
|
||||
* <code>'Target'</code> soft wrap is the one that starts at the given offset.
|
||||
*
|
||||
* @param offset target offset
|
||||
* @return index that conforms to {@link Collections#binarySearch(List, Object)} contract, i.e. non-negative returned
|
||||
* index points to soft wrap that starts at the given offset; <code>'-(negative value) - 1'</code> points
|
||||
* to position at {@link #getRegisteredSoftWraps() soft wraps collection} where soft wrap for the given index
|
||||
* should be inserted
|
||||
*/
|
||||
int getSoftWrapIndex(int offset);
|
||||
|
||||
/**
|
||||
* Asks to paint drawing of target type at the given graphics buffer at the given position.
|
||||
*
|
||||
@@ -91,4 +104,12 @@ public interface SoftWrapModelEx extends SoftWrapModel {
|
||||
* @return width in pixels required for the painting of the given type
|
||||
*/
|
||||
int getMinDrawingWidth(@NotNull SoftWrapDrawingType drawingType);
|
||||
|
||||
/**
|
||||
* Registers given listener within the current model
|
||||
*
|
||||
* @param listener listener to register
|
||||
* @return <code>true</code> if given listener was not registered before; <code>false</code> otherwise
|
||||
*/
|
||||
boolean addSoftWrapChangeListener(@NotNull SoftWrapChangeListener listener);
|
||||
}
|
||||
|
||||
+22
-30
@@ -27,7 +27,6 @@ package com.intellij.openapi.editor.impl;
|
||||
import com.intellij.codeInsight.hint.TooltipController;
|
||||
import com.intellij.codeInsight.hint.TooltipGroup;
|
||||
import com.intellij.ide.IdeEventQueue;
|
||||
import com.intellij.ide.ui.LafManager;
|
||||
import com.intellij.ide.ui.UISettings;
|
||||
import com.intellij.openapi.actionSystem.*;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
@@ -119,6 +118,7 @@ class EditorGutterComponentImpl extends EditorGutterComponentEx implements Mouse
|
||||
|
||||
public void reinitSettings() {
|
||||
myBackgroundColor = null;
|
||||
revalidateMarkup();
|
||||
repaint();
|
||||
}
|
||||
|
||||
@@ -191,9 +191,12 @@ class EditorGutterComponentImpl extends EditorGutterComponentEx implements Mouse
|
||||
|
||||
|
||||
private void paintAnnotations(Graphics g, Rectangle clip) {
|
||||
paintBackground(g, clip, getAnnotationsAreaOffset(), getAnnotationsAreaWidth());
|
||||
|
||||
int x = getAnnotationsAreaOffset();
|
||||
int w = getAnnotationsAreaWidth();
|
||||
|
||||
if (w == 0) return;
|
||||
|
||||
paintBackground(g, clip, getAnnotationsAreaOffset(), w);
|
||||
|
||||
Color color = myEditor.getColorsScheme().getColor(EditorColors.ANNOTATIONS_COLOR);
|
||||
g.setColor(color != null ? color : Color.blue);
|
||||
@@ -201,6 +204,7 @@ class EditorGutterComponentImpl extends EditorGutterComponentEx implements Mouse
|
||||
|
||||
for (int i = 0; i < myTextAnnotationGutters.size(); i++) {
|
||||
TextAnnotationGutterProvider gutterProvider = myTextAnnotationGutters.get(i);
|
||||
|
||||
int lineHeight = myEditor.getLineHeight();
|
||||
int startLineNumber = clip.y / lineHeight;
|
||||
int endLineNumber = (clip.y + clip.height) / lineHeight + 1;
|
||||
@@ -209,7 +213,7 @@ class EditorGutterComponentImpl extends EditorGutterComponentEx implements Mouse
|
||||
.line;
|
||||
endLineNumber = Math.min(endLineNumber, lastLine + 1);
|
||||
if (startLineNumber >= endLineNumber) {
|
||||
return;
|
||||
break;
|
||||
}
|
||||
|
||||
for (int j = startLineNumber; j < endLineNumber; j++) {
|
||||
@@ -219,7 +223,7 @@ class EditorGutterComponentImpl extends EditorGutterComponentEx implements Mouse
|
||||
final Color bg = gutterProvider.getBgColor(logLine, myEditor);
|
||||
if (bg != null) {
|
||||
g.setColor(bg);
|
||||
g.fillRect(x, j * lineHeight, getAnnotationsAreaWidth(), lineHeight);
|
||||
g.fillRect(x, j * lineHeight, w, lineHeight);
|
||||
}
|
||||
g.setColor(myEditor.getColorsScheme().getColor(gutterProvider.getColor(logLine, myEditor)));
|
||||
g.setFont(myEditor.getColorsScheme().getFont(style));
|
||||
@@ -230,6 +234,8 @@ class EditorGutterComponentImpl extends EditorGutterComponentEx implements Mouse
|
||||
|
||||
x += myTextAnnotationGutterSizes.get(i);
|
||||
}
|
||||
|
||||
UIUtil.drawVDottedLine((Graphics2D)g, getAnnotationsAreaOffset() + w - 1, clip.y, clip.y + clip.height, null, getOutlineColor(false));
|
||||
}
|
||||
|
||||
private void paintFoldingTree(Graphics g, Rectangle clip) {
|
||||
@@ -237,9 +243,7 @@ class EditorGutterComponentImpl extends EditorGutterComponentEx implements Mouse
|
||||
paintFoldingTree((Graphics2D)g);
|
||||
}
|
||||
else {
|
||||
g.setColor(Color.white);
|
||||
int x = getWhitespaceSeparatorOffset() - 1;
|
||||
UIUtil.drawVDottedLine((Graphics2D)g, x, clip.y, clip.y + clip.height, myEditor.getBackgroundColor(), getFoldingColor(false));
|
||||
UIUtil.drawVDottedLine((Graphics2D)g, clip.x + clip.width -1, clip.y, clip.y + clip.height, null, getOutlineColor(false));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -270,28 +274,16 @@ class EditorGutterComponentImpl extends EditorGutterComponentEx implements Mouse
|
||||
private void paintLineNumbers(Graphics g, Rectangle clip) {
|
||||
if (isLineNumbersShown()) {
|
||||
paintBackground(g, clip, getLineNumberAreaOffset(), getLineNumberAreaWidth());
|
||||
g.setColor(Color.white);
|
||||
int x = getLineNumberAreaOffset() + getLineNumberAreaWidth() - 2;
|
||||
UIUtil.drawLine(g, x, clip.y, x, clip.y + clip.height);
|
||||
UIUtil.drawVDottedLine((Graphics2D)g, x, clip.y, clip.y + clip.height, null, getOutlineColor(false));
|
||||
paintLineNumbers(g);
|
||||
}
|
||||
}
|
||||
|
||||
public Color getBackground() {
|
||||
if (myBackgroundColor == null) {
|
||||
final Color userDefinedColor = myEditor.getColorsScheme().getColor(EditorColors.LEFT_GUTTER_BACKGROUND);
|
||||
if (userDefinedColor != null) {
|
||||
myBackgroundColor = userDefinedColor;
|
||||
}
|
||||
else {
|
||||
LafManager lafManager = LafManager.getInstance();
|
||||
if (lafManager != null && lafManager.isUnderAquaLookAndFeel()) {
|
||||
myBackgroundColor = new Color(0xF0F0F0);
|
||||
}
|
||||
else {
|
||||
myBackgroundColor = super.getBackground();
|
||||
}
|
||||
}
|
||||
Color color = myEditor.getColorsScheme().getColor(EditorColors.GUTTER_BACKGROUND);
|
||||
myBackgroundColor = color == null ? new Color(0xF0F0F0) : color;
|
||||
}
|
||||
return myBackgroundColor;
|
||||
}
|
||||
@@ -639,8 +631,8 @@ class EditorGutterComponentImpl extends EditorGutterComponentEx implements Mouse
|
||||
return (myEditor.getLineHeight() - icon.getIconHeight()) /2;
|
||||
}
|
||||
|
||||
public Color getFoldingColor(boolean isActive) {
|
||||
ColorKey key = isActive ? EditorColors.SELECTED_FOLDING_TREE_COLOR : EditorColors.FOLDING_TREE_COLOR;
|
||||
public Color getOutlineColor(boolean isActive) {
|
||||
ColorKey key = isActive ? EditorColors.SELECTED_TEARLINE_COLOR : EditorColors.TEARLINE_COLOR;
|
||||
Color color = myEditor.getColorsScheme().getColor(key);
|
||||
return color != null ? color : Color.black;
|
||||
}
|
||||
@@ -706,7 +698,7 @@ class EditorGutterComponentImpl extends EditorGutterComponentEx implements Mouse
|
||||
if (!isFoldingOutlineShown()) return;
|
||||
Rectangle clip = g.getClipBounds();
|
||||
|
||||
UIUtil.drawVDottedLine(g, getWhitespaceSeparatorOffset(), clip.y, clip.y + clip.height, myEditor.getBackgroundColor(), getFoldingColor(false));
|
||||
UIUtil.drawVDottedLine(g, getWhitespaceSeparatorOffset(), clip.y, clip.y + clip.height, null, getOutlineColor(false));
|
||||
|
||||
int anchorX = getFoldingAreaOffset();
|
||||
int width = getFoldingAnchorWidth();
|
||||
@@ -820,7 +812,7 @@ class EditorGutterComponentImpl extends EditorGutterComponentEx implements Mouse
|
||||
g.fillPolygon(xPoints, yPoints, 5);
|
||||
}
|
||||
else {
|
||||
g.setColor(getFoldingColor(active));
|
||||
g.setColor(getOutlineColor(active));
|
||||
g.drawPolygon(xPoints, yPoints, 5);
|
||||
|
||||
//Minus
|
||||
@@ -855,11 +847,11 @@ class EditorGutterComponentImpl extends EditorGutterComponentEx implements Mouse
|
||||
g.fillRect(anchorX, y, width, width);
|
||||
}
|
||||
else {
|
||||
g.setColor(getFoldingColor(active));
|
||||
g.setColor(getOutlineColor(active));
|
||||
g.drawRect(anchorX, y, width, width);
|
||||
|
||||
// Draw plus
|
||||
if (!active) g.setColor(getFoldingColor(true));
|
||||
if (!active) g.setColor(getOutlineColor(true));
|
||||
UIUtil.drawLine(g, anchorX + 2, y + width / 2, anchorX + width - 2, y + width / 2);
|
||||
}
|
||||
}
|
||||
@@ -876,7 +868,7 @@ class EditorGutterComponentImpl extends EditorGutterComponentEx implements Mouse
|
||||
|
||||
int lineX = anchorX + width / 2;
|
||||
|
||||
g.setColor(getFoldingColor(true));
|
||||
g.setColor(getOutlineColor(true));
|
||||
UIUtil.drawLine(g, lineX, startY, lineX, endY);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -176,7 +176,6 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
|
||||
private static final int MOUSE_SELECTION_STATE_LINE_SELECTED = 2;
|
||||
|
||||
private final MarkupModelListener myMarkupModelListener;
|
||||
private final List<TextChange> mySoftWrapsOnLastRepaint = new ArrayList<TextChange>();
|
||||
|
||||
private EditorHighlighter myHighlighter;
|
||||
private final TextDrawingCallback myTextDrawingCallback = new MyTextDrawingCallback();
|
||||
@@ -216,6 +215,7 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
|
||||
private boolean myEmbeddedIntoDialogWrapper;
|
||||
private CachedFontContent myLastCache;
|
||||
private boolean mySpacesHaveSameWidth;
|
||||
private boolean mySoftWrapsChanged;
|
||||
|
||||
private Point myLastBackgroundPosition = null;
|
||||
private Color myLastBackgroundColor = null;
|
||||
@@ -327,6 +327,14 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
|
||||
myFoldingModel.flushCaretShift();
|
||||
myScrollBarOrientation = VERTICAL_SCROLLBAR_RIGHT;
|
||||
|
||||
mySoftWrapModel.addSoftWrapChangeListener(new SoftWrapChangeListener() {
|
||||
@Override
|
||||
public void softWrapsStateChanged(int changedLogicalLine) {
|
||||
mySoftWrapsChanged = true;
|
||||
mySizeContainer.update(changedLogicalLine, changedLogicalLine, changedLogicalLine);
|
||||
}
|
||||
});
|
||||
|
||||
EditorHighlighter highlighter = new EmptyEditorHighlighter(myScheme.getAttributes(HighlighterColors.TEXT));
|
||||
setHighlighter(highlighter);
|
||||
|
||||
@@ -1692,8 +1700,10 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
|
||||
// Perform additional activity if soft wrap is added or removed during repainting.
|
||||
// Note: this code lives in this method in assumption that background repainting is the very first activity performed
|
||||
// during whole editor component repaint.
|
||||
List<? extends TextChange> softWrapsAfterRepaint = mySoftWrapModel.getRegisteredSoftWraps();
|
||||
if (!mySoftWrapsOnLastRepaint.equals(softWrapsAfterRepaint)) {
|
||||
if (mySoftWrapsChanged) {
|
||||
mySoftWrapsChanged = false;
|
||||
validateSize();
|
||||
|
||||
// Repaint editor to the bottom in order to ensure that its content is shown correctly after new soft wrap introduction.
|
||||
repaintToScreenBottom(xyToLogicalPosition(position).line);
|
||||
|
||||
@@ -1704,8 +1714,6 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
|
||||
// Ask caret model to update visual caret position.
|
||||
getCaretModel().moveToOffset(getCaretModel().getOffset());
|
||||
}
|
||||
mySoftWrapsOnLastRepaint.clear();
|
||||
mySoftWrapsOnLastRepaint.addAll(softWrapsAfterRepaint);
|
||||
}
|
||||
|
||||
private void paintRectangularSelection(Graphics g) {
|
||||
@@ -2482,11 +2490,7 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
|
||||
|
||||
public Dimension getContentSize() {
|
||||
Dimension size = mySizeContainer.getContentSize();
|
||||
//TODO den move soft wrap-related logic to editor size container
|
||||
return new Dimension(
|
||||
size.width,
|
||||
size.height + (mySettings.getAdditionalLinesCount() + mySoftWrapModel.getSoftWrapsIntroducedLinesNumber()) * getLineHeight()
|
||||
);
|
||||
return new Dimension(size.width, size.height + mySettings.getAdditionalLinesCount() * getLineHeight());
|
||||
}
|
||||
|
||||
public JScrollPane getScrollPane() {
|
||||
@@ -2524,10 +2528,20 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
|
||||
return myLastColumnNumber;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return information about total number of lines that can be viewed by user. I.e. this is a number of all document
|
||||
* lines (considering that single logical document line may be represented on multiple visual lines because of
|
||||
* soft wraps appliance) minus number of folded lines
|
||||
*/
|
||||
int getVisibleLineCount() {
|
||||
int line = getDocument().getLineCount() + getSoftWrapModel().getSoftWrapsIntroducedLinesNumber();
|
||||
line -= myFoldingModel.getFoldedLinesCountBefore(getDocument().getTextLength() + 1);
|
||||
return line;
|
||||
return getVisibleLogicalLinesCount() + getSoftWrapModel().getSoftWrapsIntroducedLinesNumber();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return number of visible logical lines. Generally, that is a total logical lines number minus number of folded lines
|
||||
*/
|
||||
private int getVisibleLogicalLinesCount() {
|
||||
return getDocument().getLineCount() - myFoldingModel.getFoldedLinesCountBefore(getDocument().getTextLength() + 1);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -4595,15 +4609,25 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings({"FieldAccessedSynchronizedAndUnsynchronized"})
|
||||
private class EditorSizeContainer {
|
||||
|
||||
/** Holds logical line widths in pixels. */
|
||||
private TIntArrayList myLineWidths;
|
||||
|
||||
/** Holds value that indicates if line widths recalculation should be performed. */
|
||||
private volatile boolean myIsDirty;
|
||||
|
||||
/** Holds number of the last logical line affected by the last document change. */
|
||||
private int myOldEndLine;
|
||||
|
||||
private Dimension mySize;
|
||||
private int myMaxWidth = -1;
|
||||
|
||||
private final Object lock = new Object();
|
||||
private int myMaxWidth = -1;
|
||||
|
||||
public synchronized void reset() {
|
||||
int visLinesCount = getVisibleLineCount();
|
||||
int visLinesCount = getDocument().getLineCount();
|
||||
myLineWidths = new TIntArrayList(visLinesCount + 300);
|
||||
int[] values = new int[visLinesCount];
|
||||
Arrays.fill(values, -1);
|
||||
@@ -4611,6 +4635,7 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
|
||||
myIsDirty = true;
|
||||
}
|
||||
|
||||
@SuppressWarnings({"NonPrivateFieldAccessedInSynchronizedContext"})
|
||||
public synchronized void beforeChange(DocumentEvent e) {
|
||||
if (myDocument.isInBulkUpdate()) {
|
||||
myMaxWidth = mySize != null ? mySize.width : -1;
|
||||
@@ -4626,11 +4651,7 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
|
||||
return offsetToVisualPosition(startLineOffset).line;
|
||||
}
|
||||
|
||||
public synchronized void changedUpdate(DocumentEvent e) {
|
||||
int startLine = e.getOldLength() == 0 ? myOldEndLine : getVisualPositionLine(e.getOffset());
|
||||
int newEndLine = e.getNewLength() == 0 ? startLine : getVisualPositionLine(e.getOffset() + e.getNewLength());
|
||||
int oldEndLine = myOldEndLine;
|
||||
|
||||
public synchronized void update(int startLine, int newEndLine, int oldEndLine) {
|
||||
final int lineWidthSize = myLineWidths.size();
|
||||
if (lineWidthSize == 0) {
|
||||
reset();
|
||||
@@ -4657,12 +4678,21 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized void changedUpdate(DocumentEvent e) {
|
||||
int startLine = e.getOldLength() == 0 ? myOldEndLine : getVisualPositionLine(e.getOffset());
|
||||
int newEndLine = e.getNewLength() == 0 ? startLine : getVisualPositionLine(e.getOffset() + e.getNewLength());
|
||||
int oldEndLine = myOldEndLine;
|
||||
|
||||
update(startLine, newEndLine, oldEndLine);
|
||||
}
|
||||
|
||||
@SuppressWarnings({"NonPrivateFieldAccessedInSynchronizedContext", "AssignmentToForLoopParameter"})
|
||||
private void validateSizes() {
|
||||
if (!myIsDirty) return;
|
||||
|
||||
synchronized (this) {
|
||||
synchronized (lock) {
|
||||
if (!myIsDirty) return;
|
||||
int lineCount = myLineWidths.size();
|
||||
int lineCount = Math.min(myLineWidths.size(), myDocument.getLineCount());
|
||||
|
||||
if (myMaxWidth != -1 && myDocument.isInBulkUpdate()) {
|
||||
mySize = new Dimension(myMaxWidth, getLineHeight() * lineCount);
|
||||
@@ -4676,19 +4706,31 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
|
||||
final int fontSize = myScheme.getEditorFontSize();
|
||||
final String fontName = myScheme.getEditorFontName();
|
||||
|
||||
List<? extends TextChange> softWraps = getSoftWrapModel().getRegisteredSoftWraps();
|
||||
int softWrapsIndex = -1;
|
||||
|
||||
for (int line = 0; line < lineCount; line++) {
|
||||
if (myLineWidths.getQuick(line) != -1) continue;
|
||||
x = 0;
|
||||
int offset = logicalPositionToOffset(visualToLogicalPosition(new VisualPosition(line, 0)));
|
||||
int offset = myDocument.getLineStartOffset(line);
|
||||
|
||||
if (offset >= myDocument.getTextLength()) {
|
||||
myLineWidths.set(line, 0);
|
||||
break;
|
||||
}
|
||||
|
||||
if (softWrapsIndex < 0) {
|
||||
softWrapsIndex = getSoftWrapModel().getSoftWrapIndex(offset);
|
||||
if (softWrapsIndex < 0) {
|
||||
softWrapsIndex = -softWrapsIndex - 1;
|
||||
}
|
||||
}
|
||||
|
||||
IterationState state = new IterationState(EditorImpl.this, offset, false);
|
||||
int fontType = state.getMergedAttributes().getFontType();
|
||||
|
||||
int maxPreviousSoftWrappedWidth = -1;
|
||||
|
||||
while (offset < end && line < lineCount) {
|
||||
char c = text.charAt(offset);
|
||||
if (offset >= state.getEndOffset()) {
|
||||
@@ -4696,6 +4738,22 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
|
||||
fontType = state.getMergedAttributes().getFontType();
|
||||
}
|
||||
|
||||
while (softWrapsIndex < softWraps.size()) {
|
||||
TextChange softWrap = softWraps.get(softWrapsIndex);
|
||||
if (softWrap.getStart() > offset) {
|
||||
break;
|
||||
}
|
||||
softWrapsIndex++;
|
||||
if (softWrap.getStart() == offset) {
|
||||
maxPreviousSoftWrappedWidth = Math.max(maxPreviousSoftWrappedWidth, x);
|
||||
x = getSoftWrapModel().getSoftWrapIndentWidthInPixels(softWrap);
|
||||
}
|
||||
}
|
||||
if (line + 1 >= lineCount) {
|
||||
myLineWidths.set(line, Math.max(x, maxPreviousSoftWrappedWidth));
|
||||
break;
|
||||
}
|
||||
|
||||
FoldRegion collapsed = state.getCurrentFold();
|
||||
if (collapsed != null) {
|
||||
String placeholder = collapsed.getPlaceholderText();
|
||||
@@ -4703,6 +4761,7 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
|
||||
x += EditorUtil.charWidth(placeholder.charAt(i), fontType, EditorImpl.this);
|
||||
}
|
||||
offset = collapsed.getEndOffset();
|
||||
line = myDocument.getLineNumber(offset);
|
||||
}
|
||||
else {
|
||||
if (c == '\t') {
|
||||
@@ -4711,7 +4770,7 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
|
||||
}
|
||||
else {
|
||||
if (c == '\n') {
|
||||
myLineWidths.set(line, x);
|
||||
myLineWidths.set(line, Math.max(x, maxPreviousSoftWrappedWidth));
|
||||
if (line + 1 >= lineCount || myLineWidths.getQuick(line + 1) != -1) break;
|
||||
offset++;
|
||||
x = 0;
|
||||
@@ -4732,12 +4791,28 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
|
||||
x); // Last line can be non-zero length and won't be caught by in-loop procedure since latter only react on \n's
|
||||
}
|
||||
|
||||
// There is a following possible situation:
|
||||
// 1. Big document is opened at editor;
|
||||
// 2. Soft wraps are calculated for the current visible area;
|
||||
// 2. The user scrolled down;
|
||||
// 3. The user significantly reduced visible area width (say, reduced it twice);
|
||||
// 4. Soft wraps are calculated for the current visible area;
|
||||
// We need to consider only the widths for the logical lines that are completely shown at the current visible area then.
|
||||
// I.e. we shouldn't use widths of the lines that are not shown for max width calculation because previous widths are calculated
|
||||
// for another visible area width.
|
||||
int startToUse = 0;
|
||||
int endToUse = lineCount;
|
||||
if (getSoftWrapModel().isSoftWrappingEnabled()) {
|
||||
Rectangle visibleArea = getScrollingModel().getVisibleArea();
|
||||
startToUse = xyToLogicalPosition(visibleArea.getLocation()).line + 1;
|
||||
endToUse = xyToLogicalPosition(new Point(0, visibleArea.y + visibleArea.height)).line;
|
||||
}
|
||||
int maxWidth = 0;
|
||||
for (int i = 0; i < lineCount; i++) {
|
||||
for (int i = startToUse; i < endToUse; i++) {
|
||||
maxWidth = Math.max(maxWidth, myLineWidths.getQuick(i));
|
||||
}
|
||||
|
||||
mySize = new Dimension(maxWidth, getLineHeight() * lineCount);
|
||||
mySize = new Dimension(maxWidth, getLineHeight() * getVisibleLineCount());
|
||||
|
||||
myIsDirty = false;
|
||||
}
|
||||
|
||||
@@ -15,11 +15,9 @@
|
||||
*/
|
||||
package com.intellij.openapi.editor.impl;
|
||||
|
||||
import com.intellij.openapi.editor.Document;
|
||||
import com.intellij.openapi.editor.LogicalPosition;
|
||||
import com.intellij.openapi.editor.TextChange;
|
||||
import com.intellij.openapi.editor.VisualPosition;
|
||||
import com.intellij.openapi.editor.*;
|
||||
import com.intellij.openapi.editor.ex.EditorEx;
|
||||
import com.intellij.openapi.editor.ex.SoftWrapChangeListener;
|
||||
import com.intellij.openapi.editor.ex.SoftWrapModelEx;
|
||||
import com.intellij.openapi.editor.ex.util.EditorUtil;
|
||||
import com.intellij.openapi.editor.impl.softwrap.*;
|
||||
@@ -56,7 +54,7 @@ public class SoftWrapModelImpl implements SoftWrapModelEx {
|
||||
private int myActive;
|
||||
|
||||
public SoftWrapModelImpl(@NotNull EditorEx editor) {
|
||||
this(editor, new SoftWrapsStorage(), new CompositeSoftWrapPainter(editor));
|
||||
this(editor, new SoftWrapsStorage(editor.getDocument()), new CompositeSoftWrapPainter(editor));
|
||||
}
|
||||
|
||||
public SoftWrapModelImpl(@NotNull final EditorEx editor, @NotNull SoftWrapsStorage storage, @NotNull SoftWrapPainter painter) {
|
||||
@@ -77,7 +75,7 @@ public class SoftWrapModelImpl implements SoftWrapModelEx {
|
||||
}
|
||||
|
||||
public boolean isSoftWrappingEnabled() {
|
||||
return myEditor.getSettings().isUseSoftWraps();
|
||||
return myEditor.getSettings().isUseSoftWraps() && !myEditor.isOneLineMode();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@@ -88,6 +86,11 @@ public class SoftWrapModelImpl implements SoftWrapModelEx {
|
||||
return myStorage.getSoftWrap(offset);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSoftWrapIndex(int offset) {
|
||||
return myStorage.getSoftWrapIndex(offset);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public List<? extends TextChange> getSoftWrapsForRange(int start, int end) {
|
||||
@@ -138,8 +141,11 @@ public class SoftWrapModelImpl implements SoftWrapModelEx {
|
||||
return 0;
|
||||
}
|
||||
int result = 0;
|
||||
for (TextChange myWrap : myStorage.getSoftWraps()) {
|
||||
result += StringUtil.countNewLines(myWrap.getText());
|
||||
FoldingModel foldingModel = myEditor.getFoldingModel();
|
||||
for (TextChange softWrap : myStorage.getSoftWraps()) {
|
||||
if (!foldingModel.isOffsetCollapsed(softWrap.getStart())) {
|
||||
result += StringUtil.countNewLines(softWrap.getText());
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@@ -309,4 +315,9 @@ public class SoftWrapModelImpl implements SoftWrapModelEx {
|
||||
// Restore caret position.
|
||||
myEditor.getCaretModel().moveToVisualPosition(visualCaretPosition);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean addSoftWrapChangeListener(@NotNull SoftWrapChangeListener listener) {
|
||||
return myStorage.addSoftWrapChangeListener(listener);
|
||||
}
|
||||
}
|
||||
|
||||
+27
-2
@@ -15,12 +15,16 @@
|
||||
*/
|
||||
package com.intellij.openapi.editor.impl.softwrap;
|
||||
|
||||
import com.intellij.openapi.editor.Document;
|
||||
import com.intellij.openapi.editor.ex.SoftWrapChangeListener;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.CopyOnWriteArraySet;
|
||||
|
||||
/**
|
||||
* Holds registered soft wraps and provides monitoring and management facilities for them.
|
||||
@@ -32,8 +36,15 @@ import java.util.List;
|
||||
*/
|
||||
public class SoftWrapsStorage {
|
||||
|
||||
private final List<TextChangeImpl> myWraps = new ArrayList<TextChangeImpl>();
|
||||
private final List<TextChangeImpl> myWrapsView = Collections.unmodifiableList(myWraps);
|
||||
private final List<TextChangeImpl> myWraps = new ArrayList<TextChangeImpl>();
|
||||
private final List<TextChangeImpl> myWrapsView = Collections.unmodifiableList(myWraps);
|
||||
private final Set<SoftWrapChangeListener> myListeners = new CopyOnWriteArraySet<SoftWrapChangeListener>();
|
||||
|
||||
private final Document myDocument;
|
||||
|
||||
public SoftWrapsStorage(Document document) {
|
||||
myDocument = document;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return <code>true</code> if there is at least one soft wrap registered at the current storage; <code>false</code> otherwise
|
||||
@@ -103,6 +114,10 @@ public class SoftWrapsStorage {
|
||||
|
||||
i = -i - 1;
|
||||
myWraps.add(i, softWrap);
|
||||
int changedLogicalLine = myDocument.getLineNumber(softWrap.getStart());
|
||||
for (SoftWrapChangeListener listener : myListeners) {
|
||||
listener.softWrapsStateChanged(changedLogicalLine);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -127,4 +142,14 @@ public class SoftWrapsStorage {
|
||||
public void removeAll() {
|
||||
myWraps.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers given listener within the current model
|
||||
*
|
||||
* @param listener listener to register
|
||||
* @return <code>true</code> if given listener was not registered before; <code>false</code> otherwise
|
||||
*/
|
||||
public boolean addSoftWrapChangeListener(@NotNull SoftWrapChangeListener listener) {
|
||||
return myListeners.add(listener);
|
||||
}
|
||||
}
|
||||
|
||||
+36
-15
@@ -20,6 +20,8 @@ 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.editor.colors.EditorColors;
|
||||
import com.intellij.openapi.editor.colors.EditorColorsManager;
|
||||
import com.intellij.openapi.fileEditor.*;
|
||||
import com.intellij.openapi.fileEditor.ex.FileEditorManagerEx;
|
||||
import com.intellij.openapi.project.DumbService;
|
||||
@@ -29,6 +31,7 @@ import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.openapi.wm.FocusWatcher;
|
||||
import com.intellij.ui.PrevNextActionsDescriptor;
|
||||
import com.intellij.ui.SideBorder;
|
||||
import com.intellij.ui.TabbedPaneWrapper;
|
||||
import com.intellij.ui.tabs.UiDecorator;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -77,7 +80,6 @@ public abstract class EditorComposite implements Disposable {
|
||||
private FileEditor mySelectedEditor;
|
||||
private final FileEditorManagerEx myFileEditorManager;
|
||||
private final long myInitialFileModificationStamp;
|
||||
private final Map<FileEditor, FileEditorInfoPane> myInfoPanes = new HashMap<FileEditor, FileEditorInfoPane>();
|
||||
private final Map<FileEditor, JComponent> myTopComponents = new HashMap<FileEditor, JComponent>();
|
||||
private final Map<FileEditor, JComponent> myBottomComponents = new HashMap<FileEditor, JComponent>();
|
||||
|
||||
@@ -198,20 +200,14 @@ public abstract class EditorComposite implements Disposable {
|
||||
|
||||
component.add(comp, BorderLayout.CENTER);
|
||||
|
||||
final JPanel topPanel = new JPanel();
|
||||
topPanel.setLayout(new BoxLayout(topPanel, BoxLayout.Y_AXIS));
|
||||
JPanel topPanel = new TopBottomPanel();
|
||||
myTopComponents.put(editor, topPanel);
|
||||
component.add(topPanel, BorderLayout.NORTH);
|
||||
|
||||
final JPanel bottomPanel = new JPanel();
|
||||
bottomPanel.setLayout(new BoxLayout(bottomPanel, BoxLayout.Y_AXIS));
|
||||
final JPanel bottomPanel = new TopBottomPanel();
|
||||
myBottomComponents.put(editor, bottomPanel);
|
||||
component.add(bottomPanel, BorderLayout.SOUTH);
|
||||
|
||||
FileEditorInfoPane infoPane = new FileEditorInfoPane();
|
||||
myInfoPanes.put(editor, infoPane);
|
||||
addTopComponent(editor, infoPane);
|
||||
|
||||
return component;
|
||||
}
|
||||
|
||||
@@ -307,17 +303,13 @@ public abstract class EditorComposite implements Disposable {
|
||||
assert container != null;
|
||||
|
||||
if (remove) {
|
||||
container.remove(component);
|
||||
container.remove(component.getParent());
|
||||
} else {
|
||||
container.add(component);
|
||||
container.add(new TopBottomComponentWrapper(component, top));
|
||||
}
|
||||
container.revalidate();
|
||||
}
|
||||
|
||||
public FileEditorInfoPane getPane(FileEditor editor) {
|
||||
return myInfoPanes.get(editor);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return currently selected myEditor. The method never returns <code>null</code>.
|
||||
*/
|
||||
@@ -409,4 +401,33 @@ public abstract class EditorComposite implements Disposable {
|
||||
|
||||
public void dispose() {
|
||||
}
|
||||
|
||||
private class TopBottomPanel extends JPanel {
|
||||
private TopBottomPanel() {
|
||||
setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Color getBackground() {
|
||||
Color color = EditorColorsManager.getInstance().getGlobalScheme().getColor(EditorColors.GUTTER_BACKGROUND);
|
||||
return color == null ? Color.gray : color;
|
||||
}
|
||||
}
|
||||
|
||||
private class TopBottomComponentWrapper extends JPanel {
|
||||
public TopBottomComponentWrapper(JComponent component, boolean top) {
|
||||
super(new BorderLayout());
|
||||
setOpaque(false);
|
||||
|
||||
setBorder(new SideBorder(null, top ? SideBorder.BOTTOM : SideBorder.TOP, true) {
|
||||
@Override
|
||||
public Color getLineColor() {
|
||||
Color result = EditorColorsManager.getInstance().getGlobalScheme().getColor(EditorColors.TEARLINE_COLOR);
|
||||
return result == null ? Color.black : result;
|
||||
}
|
||||
});
|
||||
|
||||
add(component);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
-107
@@ -1,107 +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.openapi.fileEditor.impl;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.util.ArrayList;
|
||||
|
||||
/**
|
||||
* @author max
|
||||
*/
|
||||
public class FileEditorInfoPane extends JPanel {
|
||||
private int myCounter = 0;
|
||||
private final JPanel myCards;
|
||||
private final JButton myPrevButton;
|
||||
private final JButton myNextButton;
|
||||
private final java.util.List<JComponent> myComponents;
|
||||
private final JPanel myButtonsPanel;
|
||||
|
||||
public FileEditorInfoPane() {
|
||||
super(new BorderLayout());
|
||||
final CardLayout layout = new CardLayout();
|
||||
myCards = new JPanel(layout);
|
||||
myComponents = new ArrayList<JComponent>();
|
||||
add(myCards, BorderLayout.CENTER);
|
||||
myPrevButton = new JButton("<");
|
||||
myNextButton = new JButton(">");
|
||||
|
||||
myButtonsPanel = new JPanel(new GridLayout(1, 2));
|
||||
myButtonsPanel.add(myPrevButton);
|
||||
myButtonsPanel.add(myNextButton);
|
||||
|
||||
myPrevButton.addActionListener(new ActionListener() {
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
layout.previous(myCards);
|
||||
updateButtons();
|
||||
}
|
||||
});
|
||||
|
||||
myNextButton.addActionListener(new ActionListener() {
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
layout.next(myCards);
|
||||
updateButtons();
|
||||
}
|
||||
});
|
||||
|
||||
add(myButtonsPanel, BorderLayout.EAST);
|
||||
myButtonsPanel.setVisible(false);
|
||||
setVisible(false);
|
||||
}
|
||||
|
||||
public void addInfo(JComponent component) {
|
||||
myComponents.add(component);
|
||||
myCards.add(component, String.valueOf(myCounter++));
|
||||
updateButtons();
|
||||
validate();
|
||||
}
|
||||
|
||||
public void removeInfo(JComponent component) {
|
||||
myComponents.remove(component);
|
||||
myCards.remove(component);
|
||||
updateButtons();
|
||||
validate();
|
||||
}
|
||||
|
||||
private int getCurrentCard() {
|
||||
for (int i = 0; i < myComponents.size(); i++) {
|
||||
if (myComponents.get(i).isVisible()) return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
private void updateButtons() {
|
||||
int count = myComponents.size();
|
||||
if (count > 0) {
|
||||
setVisible(true);
|
||||
if (count == 1) {
|
||||
myButtonsPanel.setVisible(false);
|
||||
}
|
||||
else {
|
||||
myButtonsPanel.setVisible(true);
|
||||
int currentCard = getCurrentCard();
|
||||
myNextButton.setEnabled(currentCard + 1 < count);
|
||||
myPrevButton.setEnabled(currentCard - 1 >= 0);
|
||||
}
|
||||
}
|
||||
else {
|
||||
setVisible(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
+2
-8
@@ -915,17 +915,11 @@ public class FileEditorManagerImpl extends FileEditorManagerEx implements Projec
|
||||
}
|
||||
|
||||
public void showEditorAnnotation(@NotNull FileEditor editor, @NotNull JComponent annotationComponent) {
|
||||
final EditorComposite composite = getEditorComposite(editor);
|
||||
if (composite != null) {
|
||||
composite.getPane(editor).addInfo(annotationComponent);
|
||||
}
|
||||
addTopComponent(editor, annotationComponent);
|
||||
}
|
||||
|
||||
public void removeEditorAnnotation(@NotNull FileEditor editor, @NotNull JComponent annotationComponent) {
|
||||
final EditorComposite composite = getEditorComposite(editor);
|
||||
if (composite != null) {
|
||||
composite.getPane(editor).removeInfo(annotationComponent);
|
||||
}
|
||||
removeTopComponent(editor, annotationComponent);
|
||||
}
|
||||
|
||||
public void addTopComponent(@NotNull final FileEditor editor, @NotNull final JComponent component) {
|
||||
|
||||
+7
-5
@@ -1,5 +1,6 @@
|
||||
package com.intellij.openapi.editor.impl.softwrap;
|
||||
|
||||
import com.intellij.idea.Bombed;
|
||||
import com.intellij.mock.MockFoldRegion;
|
||||
import com.intellij.openapi.editor.*;
|
||||
import com.intellij.openapi.editor.ex.EditorEx;
|
||||
@@ -17,10 +18,7 @@ import org.jmock.integration.junit4.JUnit4Mockery;
|
||||
import org.jmock.Mockery;
|
||||
import org.jmock.lib.legacy.ClassImposteriser;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* @author Denis Zhdanov
|
||||
@@ -85,9 +83,10 @@ public class SoftWrapDataMapperTest {
|
||||
myMockery = new JUnit4Mockery() {{
|
||||
setImposteriser(ClassImposteriser.INSTANCE);
|
||||
}};
|
||||
myStorage = new SoftWrapsStorage();
|
||||
|
||||
myEditor = myMockery.mock(EditorEx.class);
|
||||
myDocument = myMockery.mock(Document.class);
|
||||
myStorage = new SoftWrapsStorage(myDocument);
|
||||
myFoldingModel = myMockery.mock(FoldingModel.class);
|
||||
final EditorSettings settings = myMockery.mock(EditorSettings.class);
|
||||
final Project project = myMockery.mock(Project.class);
|
||||
@@ -177,6 +176,7 @@ public class SoftWrapDataMapperTest {
|
||||
myMockery.assertIsSatisfied();
|
||||
}
|
||||
|
||||
@Bombed(day = 12, month = Calendar.JULY)
|
||||
@Test
|
||||
public void softWrapHasSymbolBeforeFirstLineFeed() {
|
||||
String document =
|
||||
@@ -192,6 +192,7 @@ public class SoftWrapDataMapperTest {
|
||||
test(document);
|
||||
}
|
||||
|
||||
@Bombed(day = 12, month = Calendar.JULY)
|
||||
@Test
|
||||
public void multipleSoftWrappedLogicalLines() {
|
||||
String document =
|
||||
@@ -211,6 +212,7 @@ public class SoftWrapDataMapperTest {
|
||||
test(document);
|
||||
}
|
||||
|
||||
@Bombed(day = 12, month = Calendar.JULY)
|
||||
@Test
|
||||
public void softWrapAndFoldedLines() {
|
||||
String document =
|
||||
|
||||
@@ -107,8 +107,9 @@ options.xml.attribute.descriptor.descriptor.entity,reference=Entity reference
|
||||
options.general.color.descriptor.background.in.readonly.files=Background in readonly files
|
||||
options.deneral.color.descriptor.readonly.fragment.background=Readonly fragment background
|
||||
options.general.color.descriptor.gutter.background=Gutter background
|
||||
options.general.color.descriptor.selection.background=Selection Background
|
||||
options.general.color.descriptor.selection.foreground=Selection Foreground
|
||||
options.general.color.descriptor.notification.background=Notification background
|
||||
options.general.color.descriptor.selection.background=Selection background
|
||||
options.general.color.descriptor.selection.foreground=Selection foreground
|
||||
options.general.color.descriptor.caret=Caret
|
||||
options.general.color.descriptor.caret.row=Caret row
|
||||
options.general.color.descriptor.right.margin=Right margin
|
||||
@@ -118,8 +119,8 @@ options.general.color.descriptor.indent.guide.selected=Selected vertical indent
|
||||
options.general.color.descriptor.line.number=Line number
|
||||
options.general.color.descriptor.vcs.annotations=VCS annotations
|
||||
options.general.color.descriptor.vcs.annotations.merged=VCS annotations (merged from)
|
||||
options.general.color.descriptor.folding.outline=Folding outline
|
||||
options.general.color.descriptor.selected.folding.outline=Selected folding outline
|
||||
options.general.color.descriptor.tearline=Tear line
|
||||
options.general.color.descriptor.tearline.selected=Selected tear line
|
||||
options.general.color.descriptor.added.lines=Added lines
|
||||
options.general.color.descriptor.modified.lines=Modified lines
|
||||
options.general.color.descriptor.console.background=Console background
|
||||
|
||||
@@ -11,6 +11,8 @@
|
||||
<option name="METHOD_SEPARATORS_COLOR" value="c0c0c0"/>
|
||||
<option name="WHITESPACES" value="c5c5c5"/>
|
||||
<option name="INDENT_GUIDE" value="e6e6e6"/>
|
||||
<option name="GUTTER_BACKGROUND" value="f0f0f0" />
|
||||
<option name="NOTIFICATION_BACKGROUND" value="ffffcc" />
|
||||
<option name="SELECTED_INDENT_GUIDE" value="c8c8c8"/>
|
||||
<option name="SELECTION_FOREGROUND" value="ffffff"/>
|
||||
<option name="LINE_NUMBERS_COLOR" value="800000"/>
|
||||
@@ -18,8 +20,8 @@
|
||||
<option name="ANNOTATIONS_MERGED_COLOR" value="008080" />
|
||||
<option name="CARET_COLOR" value="0"/>
|
||||
<option name="RIGHT_MARGIN_COLOR" value="c0c0c0"/>
|
||||
<option name="FOLDING_TREE_COLOR" value="808080"/>
|
||||
<option name="SELECTED_FOLDING_TREE_COLOR" value="000000"/>
|
||||
<option name="TEARLINE_COLOR" value="808080"/>
|
||||
<option name="SELECTED_TEARLINE_COLOR" value="000000"/>
|
||||
<option name="READONLY_FRAGMENT_BACKGROUND" value="cfe7ff"/>
|
||||
|
||||
<option name="ADDED_LINES_COLOR" value="edfced"/>
|
||||
|
||||
@@ -41,6 +41,7 @@
|
||||
interface="com.intellij.javaee.ImplicitNamespaceDescriptorProvider"/>
|
||||
|
||||
<extensionPoint name="xml.zenCodingGenerator" interface="com.intellij.codeInsight.template.zencoding.filters.ZenCodingGenerator"/>
|
||||
<extensionPoint name="xml.zenCodingFilter" interface="com.intellij.codeInsight.template.zencoding.filters.ZenCodingFilter"/>
|
||||
</extensionPoints>
|
||||
|
||||
<extensions defaultExtensionNs="com.intellij">
|
||||
|
||||
@@ -17,8 +17,13 @@ package com.intellij.openapi.util;
|
||||
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@SuppressWarnings({"AssignmentToStaticFieldFromInstanceMethod", "UnusedDeclaration"})
|
||||
/**
|
||||
* @author max
|
||||
* @author Konstantin Bulenkov
|
||||
*/
|
||||
@SuppressWarnings({"AssignmentToStaticFieldFromInstanceMethod", "UnusedDeclaration", "EqualsWhichDoesntCheckParameterClass"})
|
||||
public class Key<T> {
|
||||
private static int ourKeysCounter = 0;
|
||||
private final int myIndex = ourKeysCounter++;
|
||||
@@ -45,4 +50,32 @@ public class Key<T> {
|
||||
public static <T> Key<T> create(@NotNull @NonNls String name) {
|
||||
return new Key<T>(name);
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public T get(@Nullable UserDataHolder holder) {
|
||||
return holder == null ? null : holder.getUserData(this);
|
||||
}
|
||||
|
||||
public T get(@Nullable UserDataHolder holder, T defaultValue) {
|
||||
final T t = get(holder);
|
||||
return t == null ? defaultValue : t;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns <code>true</code> if and only if the <code>holder</code> has
|
||||
* not null value by the key.
|
||||
*
|
||||
* @param holder user data holder object
|
||||
* @return <code>true</code> if holder.getUserData(this) != null
|
||||
* <code>false</code> otherwise.
|
||||
*/
|
||||
public boolean isIn(@Nullable UserDataHolder holder) {
|
||||
return get(holder) != null;
|
||||
}
|
||||
|
||||
public void set(@Nullable UserDataHolder holder, T value) {
|
||||
if (holder != null) {
|
||||
holder.putUserData(this, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -66,24 +66,24 @@ public class SideBorder extends LineBorder {
|
||||
g.setColor(getLineColor());
|
||||
for(i = 0; i < getThickness(); i++){
|
||||
if ((mySideMask & LEFT) != 0){
|
||||
drawLine(g, x + i, y + i, x + i, height - i - i - 1);
|
||||
drawLine(c, g, x + i, y + i, x + i, height - i - i - 1);
|
||||
}
|
||||
if ((mySideMask & TOP) != 0){
|
||||
drawLine(g, x + i, y + i, width - i - i - 1, y + i);
|
||||
drawLine(c, g, x + i, y + i, width - i - i - 1, y + i);
|
||||
}
|
||||
if ((mySideMask & RIGHT) != 0){
|
||||
drawLine(g, width - i - i - 1, y + i, width - i - i - 1, height - i - i - 1);
|
||||
drawLine(c, g, width - i - i - 1, y + i, width - i - i - 1, height - i - i - 1);
|
||||
}
|
||||
if ((mySideMask & BOTTOM) != 0){
|
||||
drawLine(g, x + i, height - i - i - 1, width - i - i - 1, height - i - i - 1);
|
||||
drawLine(c, g, x + i, height - i - i - 1, width - i - i - 1, height - i - i - 1);
|
||||
}
|
||||
}
|
||||
g.setColor(oldColor);
|
||||
}
|
||||
|
||||
private void drawLine(Graphics g, int x1, int y1, int x2, int y2) {
|
||||
private void drawLine(Component c, Graphics g, int x1, int y1, int x2, int y2) {
|
||||
if (myDotted) {
|
||||
UIUtil.drawDottedLine((Graphics2D)g, x1, y1, x2, y2, ((Graphics2D)g).getBackground(), getLineColor());
|
||||
UIUtil.drawDottedLine((Graphics2D)g, x1, y1, x2, y2, null, getLineColor());
|
||||
}
|
||||
else {
|
||||
UIUtil.drawLine(g, x1, y1, x2, y2);
|
||||
|
||||
@@ -889,20 +889,23 @@ public class UIUtil {
|
||||
});
|
||||
}
|
||||
|
||||
public static void drawVDottedLine(Graphics2D g, int lineX, int startY, int endY, final Color bgColor, final Color fgColor) {
|
||||
g.setColor(bgColor);
|
||||
drawLine(g, lineX, startY, lineX, endY);
|
||||
public static void drawVDottedLine(Graphics2D g, int lineX, int startY, int endY, @Nullable final Color bgColor, final Color fgColor) {
|
||||
if (bgColor != null) {
|
||||
g.setColor(bgColor);
|
||||
drawLine(g, lineX, startY, lineX, endY);
|
||||
}
|
||||
|
||||
g.setColor(fgColor);
|
||||
|
||||
for (int i = (startY / 2) * 2; i < endY; i += 2) {
|
||||
g.drawRect(lineX, i, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
public static void drawHDottedLine(Graphics2D g, int startX, int endX, int lineY, final Color bgColor, final Color fgColor) {
|
||||
g.setColor(bgColor);
|
||||
drawLine(g, startX, lineY, endX, lineY);
|
||||
public static void drawHDottedLine(Graphics2D g, int startX, int endX, int lineY, @Nullable final Color bgColor, final Color fgColor) {
|
||||
if (bgColor != null) {
|
||||
g.setColor(bgColor);
|
||||
drawLine(g, startX, lineY, endX, lineY);
|
||||
}
|
||||
|
||||
g.setColor(fgColor);
|
||||
|
||||
@@ -911,7 +914,7 @@ public class UIUtil {
|
||||
}
|
||||
}
|
||||
|
||||
public static void drawDottedLine(Graphics2D g, int x1, int y1, int x2, int y2, final Color bgColor, final Color fgColor) {
|
||||
public static void drawDottedLine(Graphics2D g, int x1, int y1, int x2, int y2, @Nullable final Color bgColor, final Color fgColor) {
|
||||
if (x1 == x2) {
|
||||
drawVDottedLine(g, x1, y1, y2, bgColor, fgColor);
|
||||
}
|
||||
|
||||
+16
-1
@@ -15,8 +15,23 @@
|
||||
*/
|
||||
package com.intellij.openapi.vcs.annotate;
|
||||
|
||||
public abstract class LineAnnotationAspectAdapter implements LineAnnotationAspect {
|
||||
import com.intellij.openapi.editor.EditorGutterAction;
|
||||
|
||||
import java.awt.*;
|
||||
|
||||
public abstract class LineAnnotationAspectAdapter implements LineAnnotationAspect, EditorGutterAction {
|
||||
public String getTooltipText(int lineNumber) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public Cursor getCursor(final int lineNum) {
|
||||
return Cursor.getPredefinedCursor(Cursor.HAND_CURSOR);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doAction(int lineNum) {
|
||||
showAffectedPaths(lineNum);
|
||||
}
|
||||
|
||||
protected abstract void showAffectedPaths(int lineNum);
|
||||
}
|
||||
|
||||
+1
@@ -18,6 +18,7 @@ package com.intellij.openapi.vcs.changes.committed;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.components.ProjectComponent;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.fileEditor.FileEditor;
|
||||
import com.intellij.openapi.fileEditor.FileEditorManager;
|
||||
import com.intellij.openapi.fileEditor.FileEditorManagerEvent;
|
||||
|
||||
@@ -216,7 +216,7 @@ public class LineStatusTracker {
|
||||
int width = endX - x;
|
||||
if (r.height > 0) {
|
||||
g.fillRect(x, r.y + 2, width, r.height - 4);
|
||||
g.setColor(gutter.getFoldingColor(false));
|
||||
g.setColor(gutter.getOutlineColor(false));
|
||||
UIUtil.drawLine(g, x, r.y + 2, x + width, r.y + 2);
|
||||
UIUtil.drawLine(g, x, r.y + 2, x, r.y + r.height - 3);
|
||||
UIUtil.drawLine(g, x, r.y + r.height - 3, x + width, r.y + r.height - 3);
|
||||
@@ -230,7 +230,7 @@ public class LineStatusTracker {
|
||||
r.y};
|
||||
g.fillPolygon(xPoints, yPoints, 3);
|
||||
|
||||
g.setColor(gutter.getFoldingColor(false));
|
||||
g.setColor(gutter.getOutlineColor(false));
|
||||
g.drawPolygon(xPoints, yPoints, 3);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -37,7 +37,7 @@ public class CvsFileAnnotation implements FileAnnotation{
|
||||
private final VirtualFile myFile;
|
||||
private final List<AnnotationListener> myListeners = new ArrayList<AnnotationListener>();
|
||||
|
||||
private final LineAnnotationAspect USER = new LineAnnotationAspectAdapter() {
|
||||
private final LineAnnotationAspect USER = new CvsAnnotationAspect() {
|
||||
public String getValue(int lineNumber) {
|
||||
if (lineNumber < 0 || lineNumber >= myAnnotations.length) {
|
||||
return "";
|
||||
@@ -48,7 +48,7 @@ public class CvsFileAnnotation implements FileAnnotation{
|
||||
}
|
||||
};
|
||||
|
||||
private final LineAnnotationAspect DATE = new LineAnnotationAspectAdapter() {
|
||||
private final LineAnnotationAspect DATE = new CvsAnnotationAspect() {
|
||||
public String getValue(int lineNumber) {
|
||||
if (lineNumber < 0 || lineNumber >= myAnnotations.length) {
|
||||
return "";
|
||||
@@ -59,7 +59,7 @@ public class CvsFileAnnotation implements FileAnnotation{
|
||||
}
|
||||
};
|
||||
|
||||
private final LineAnnotationAspect REVISION = new LineAnnotationAspectAdapter() {
|
||||
private final LineAnnotationAspect REVISION = new CvsAnnotationAspect() {
|
||||
public String getValue(int lineNumber) {
|
||||
if (lineNumber < 0 || lineNumber >= myAnnotations.length) {
|
||||
return "";
|
||||
@@ -172,4 +172,10 @@ public class CvsFileAnnotation implements FileAnnotation{
|
||||
return null;
|
||||
}
|
||||
|
||||
private abstract class CvsAnnotationAspect extends LineAnnotationAspectAdapter {
|
||||
@Override
|
||||
protected void showAffectedPaths(int lineNum) {
|
||||
//todo
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,13 +20,11 @@ import com.intellij.openapi.components.*;
|
||||
import com.intellij.openapi.module.Module;
|
||||
import com.intellij.openapi.module.ModuleServiceManager;
|
||||
import com.intellij.openapi.roots.impl.storage.ClasspathStorage;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import org.jdom.Element;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.*;
|
||||
|
||||
@State(
|
||||
name = "EclipseModuleManager",
|
||||
@@ -44,12 +42,13 @@ public class EclipseModuleManager implements PersistentStateComponent<Element>{
|
||||
@NonNls private static final String CONELEMENT = "conelement";
|
||||
@NonNls private static final String FORCED_JDK = "forced_jdk";
|
||||
private CachedXmlDocumentSet myDocumentSet;
|
||||
private final Map<String, String> myEclipseVariablePaths = new HashMap<String, String>();
|
||||
private final Set<String> myEclipseUrls = new HashSet<String>();
|
||||
private final Set<String> myUnknownCons = new HashSet<String>();
|
||||
private final Map<String, String> myEclipseVariablePaths = new LinkedHashMap<String, String>();
|
||||
private final Set<String> myEclipseUrls = new LinkedHashSet<String>();
|
||||
private final Set<String> myUnknownCons = new LinkedHashSet<String>();
|
||||
private boolean myForceConfigureJDK = false;
|
||||
private static final String SRC_PREFIX = "src:";
|
||||
private static final String SRC_LINK_PREFIX = "linksrc:";
|
||||
@NonNls private static final String SRC_PREFIX = "src:";
|
||||
@NonNls private static final String SRC_LINK_PREFIX = "linksrc:";
|
||||
@NonNls private static final String PREFIX_ATTR = "kind";
|
||||
private final Module myModule;
|
||||
@NonNls private static final String LIBELEMENT = "libelement";
|
||||
|
||||
@@ -118,7 +117,7 @@ public class EclipseModuleManager implements PersistentStateComponent<Element>{
|
||||
}
|
||||
|
||||
public Element getState() {
|
||||
if (ClasspathStorage.getStorageType(myModule) != EclipseClasspathStorageProvider.ID) {
|
||||
if (!ClasspathStorage.getStorageType(myModule).equals(EclipseClasspathStorageProvider.ID)) {
|
||||
if (!myEclipseUrls.isEmpty() || !myEclipseVariablePaths.isEmpty() || myForceConfigureJDK || !myUnknownCons.isEmpty()) {
|
||||
Element root = new Element("EclipseModuleSettings");
|
||||
for (String eclipseUrl : myEclipseUrls) {
|
||||
@@ -128,7 +127,15 @@ public class EclipseModuleManager implements PersistentStateComponent<Element>{
|
||||
}
|
||||
for (String var : myEclipseVariablePaths.keySet()) {
|
||||
Element varElement = new Element(VARELEMENT);
|
||||
varElement.setAttribute(VAR_ATTRIBUTE, var);
|
||||
if (var.startsWith(SRC_PREFIX)) {
|
||||
varElement.setAttribute(VAR_ATTRIBUTE, StringUtil.trimStart(var, SRC_PREFIX));
|
||||
varElement.setAttribute(PREFIX_ATTR, SRC_PREFIX);
|
||||
} else if (var.startsWith(SRC_LINK_PREFIX)) {
|
||||
varElement.setAttribute(VAR_ATTRIBUTE, StringUtil.trimStart(var, SRC_LINK_PREFIX));
|
||||
varElement.setAttribute(PREFIX_ATTR, SRC_LINK_PREFIX);
|
||||
} else {
|
||||
varElement.setAttribute(VAR_ATTRIBUTE, var);
|
||||
}
|
||||
varElement.setAttribute(VALUE_ATTR, myEclipseVariablePaths.get(var));
|
||||
root.addContent(varElement);
|
||||
}
|
||||
@@ -153,7 +160,8 @@ public class EclipseModuleManager implements PersistentStateComponent<Element>{
|
||||
}
|
||||
|
||||
for (Object o : state.getChildren(VARELEMENT)) {
|
||||
myEclipseVariablePaths.put(((Element)o).getAttributeValue(VAR_ATTRIBUTE), ((Element)o).getAttributeValue(VALUE_ATTR));
|
||||
final String prefix = ((Element)o).getAttributeValue(PREFIX_ATTR);
|
||||
myEclipseVariablePaths.put(((Element)o).getAttributeValue(VAR_ATTRIBUTE), (prefix != null ? prefix : "") + ((Element)o).getAttributeValue(VALUE_ATTR));
|
||||
}
|
||||
|
||||
for (Object o : state.getChildren(CONELEMENT)) {
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
package git4idea.annotate;
|
||||
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.editor.EditorGutterAction;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.vcs.FileStatus;
|
||||
import com.intellij.openapi.vcs.FileStatusListener;
|
||||
@@ -89,14 +88,14 @@ public class GitFileAnnotation implements FileAnnotation {
|
||||
*/
|
||||
private final boolean myMonitorFlag;
|
||||
|
||||
private final LineAnnotationAspect DATE_ASPECT = new MyAnnotationAspect() {
|
||||
private final LineAnnotationAspect DATE_ASPECT = new GitAnnotationAspect() {
|
||||
public String doGetValue(LineInfo info) {
|
||||
final Date date = info.getDate();
|
||||
return date == null ? "" : DATE_FORMAT.format(date);
|
||||
}
|
||||
};
|
||||
|
||||
private final LineAnnotationAspect REVISION_ASPECT = new MyAnnotationAspect() {
|
||||
private final LineAnnotationAspect REVISION_ASPECT = new GitAnnotationAspect() {
|
||||
@Override
|
||||
protected String doGetValue(LineInfo lineInfo) {
|
||||
final GitRevisionNumber revision = lineInfo.getRevision();
|
||||
@@ -104,7 +103,7 @@ public class GitFileAnnotation implements FileAnnotation {
|
||||
}
|
||||
};
|
||||
|
||||
private final LineAnnotationAspect AUTHOR_ASPECT = new MyAnnotationAspect() {
|
||||
private final LineAnnotationAspect AUTHOR_ASPECT = new GitAnnotationAspect() {
|
||||
@Override
|
||||
protected String doGetValue(LineInfo lineInfo) {
|
||||
final String author = lineInfo.getAuthor();
|
||||
@@ -285,7 +284,7 @@ public class GitFileAnnotation implements FileAnnotation {
|
||||
/**
|
||||
* Revision annotation aspect implementation
|
||||
*/
|
||||
private abstract class MyAnnotationAspect extends LineAnnotationAspectAdapter implements EditorGutterAction {
|
||||
private abstract class GitAnnotationAspect extends LineAnnotationAspectAdapter {
|
||||
public String getValue(int lineNumber) {
|
||||
if (myLines.size() <= lineNumber || lineNumber < 0 || myLines.get(lineNumber) == null) {
|
||||
return "";
|
||||
@@ -297,17 +296,8 @@ public class GitFileAnnotation implements FileAnnotation {
|
||||
|
||||
protected abstract String doGetValue(LineInfo lineInfo);
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public Cursor getCursor(final int lineNum) {
|
||||
return Cursor.getPredefinedCursor(Cursor.HAND_CURSOR);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public void doAction(int lineNum) {
|
||||
@Override
|
||||
protected void showAffectedPaths(int lineNum) {
|
||||
if (lineNum >= 0 && lineNum < myLines.size()) {
|
||||
final LineInfo info = myLines.get(lineNum);
|
||||
VcsFileRevision revision = myRevisionMap.get(info.getRevision());
|
||||
|
||||
+1
-1
@@ -79,7 +79,7 @@ public class GroovyShortNamesCache extends PsiShortNamesCache {
|
||||
|
||||
@NotNull
|
||||
public PsiClass[] getClassesByFQName(@NotNull @NonNls String name, @NotNull GlobalSearchScope scope) {
|
||||
final Collection<PsiClass> result = getScriptClassesByFQName(name, scope);
|
||||
final Collection<PsiClass> result = new ArrayList<PsiClass>(getScriptClassesByFQName(name, scope));
|
||||
|
||||
final Collection<? extends PsiElement> classes = StubIndex.getInstance().get(GrFullClassNameIndex.KEY, name.hashCode(), myProject, new GrSourceFilterScope(scope));
|
||||
if (!classes.isEmpty()) {
|
||||
|
||||
@@ -14,10 +14,7 @@ package org.zmlx.hg4idea.provider.annotate;
|
||||
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.vcs.VcsException;
|
||||
import com.intellij.openapi.vcs.annotate.AnnotationListener;
|
||||
import com.intellij.openapi.vcs.annotate.AnnotationSourceSwitcher;
|
||||
import com.intellij.openapi.vcs.annotate.FileAnnotation;
|
||||
import com.intellij.openapi.vcs.annotate.LineAnnotationAspect;
|
||||
import com.intellij.openapi.vcs.annotate.*;
|
||||
import com.intellij.openapi.vcs.changes.CurrentContentRevision;
|
||||
import com.intellij.openapi.vcs.history.VcsFileRevision;
|
||||
import com.intellij.openapi.vcs.history.VcsRevisionNumber;
|
||||
@@ -108,7 +105,7 @@ public class HgAnnotation implements FileAnnotation {
|
||||
return result;
|
||||
}
|
||||
|
||||
class HgLineAnnotationAspect implements LineAnnotationAspect {
|
||||
class HgLineAnnotationAspect extends LineAnnotationAspectAdapter {
|
||||
private final FIELD aspectType;
|
||||
|
||||
public HgLineAnnotationAspect(FIELD aspectType) {
|
||||
@@ -125,8 +122,9 @@ public class HgAnnotation implements FileAnnotation {
|
||||
: annotationLine.get(aspectType).toString();
|
||||
}
|
||||
|
||||
public String getTooltipText(int lineNumber) {
|
||||
return null;
|
||||
@Override
|
||||
protected void showAffectedPaths(int lineNum) {
|
||||
// todo
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
*/
|
||||
package org.jetbrains.idea.maven.utils;
|
||||
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.fileEditor.FileEditor;
|
||||
import com.intellij.openapi.fileEditor.FileEditorManager;
|
||||
import com.intellij.openapi.fileEditor.FileEditorManagerAdapter;
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,31 @@
|
||||
Copyright (c) 2002, 2003 Thai Open Source Software Center Ltd
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in
|
||||
the documentation and/or other materials provided with the
|
||||
distribution.
|
||||
|
||||
Neither the name of the Thai Open Source Software Center Ltd nor
|
||||
the names of its contributors may be used to endorse or promote
|
||||
products derived from this software without specific prior written
|
||||
permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR
|
||||
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
Binary file not shown.
@@ -0,0 +1,56 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module relativePaths="true" type="JAVA_MODULE" version="4">
|
||||
<component name="NewModuleRootManager" inherit-compiler-output="true">
|
||||
<exclude-output />
|
||||
<content url="file://$MODULE_DIR$">
|
||||
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/test" isTestSource="true" />
|
||||
</content>
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
<orderEntry type="module" module-name="lang-api" />
|
||||
<orderEntry type="module" module-name="xml" />
|
||||
<orderEntry type="module" module-name="dom-openapi" />
|
||||
<orderEntry type="module" module-name="lang-impl" />
|
||||
<orderEntry type="module" module-name="testFramework" scope="TEST" />
|
||||
<orderEntry type="module-library">
|
||||
<library>
|
||||
<CLASSES>
|
||||
<root url="jar://$MODULE_DIR$/lib/rngom-20051226-patched.jar!/" />
|
||||
</CLASSES>
|
||||
<JAVADOC />
|
||||
<SOURCES>
|
||||
<root url="jar://$MODULE_DIR$/lib/rngom-src.zip!/src" />
|
||||
</SOURCES>
|
||||
</library>
|
||||
</orderEntry>
|
||||
<orderEntry type="module-library">
|
||||
<library>
|
||||
<CLASSES>
|
||||
<root url="jar://$MODULE_DIR$/lib/isorelax.jar!/" />
|
||||
</CLASSES>
|
||||
<JAVADOC />
|
||||
<SOURCES />
|
||||
</library>
|
||||
</orderEntry>
|
||||
<orderEntry type="module-library">
|
||||
<library>
|
||||
<CLASSES>
|
||||
<root url="jar://$MODULE_DIR$/lib/trang-core.jar!/" />
|
||||
</CLASSES>
|
||||
<JAVADOC />
|
||||
<SOURCES />
|
||||
</library>
|
||||
</orderEntry>
|
||||
<orderEntry type="module-library">
|
||||
<library>
|
||||
<CLASSES>
|
||||
<root url="jar://$MODULE_DIR$/lib/jing.jar!/" />
|
||||
</CLASSES>
|
||||
<JAVADOC />
|
||||
<SOURCES />
|
||||
</library>
|
||||
</orderEntry>
|
||||
</component>
|
||||
</module>
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
Copyright 2007 Sascha Weinreuter
|
||||
|
||||
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.
|
||||
@@ -0,0 +1,73 @@
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<title>Jing Copying Conditions</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<h1>Jing Copying Conditions</h1>
|
||||
|
||||
<p>Copyright (c) 2001-2003 Thai Open Source Software Center Ltd<br />
|
||||
All rights reserved.</p>
|
||||
|
||||
<p>Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:</p>
|
||||
|
||||
<ul>
|
||||
<li>Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.</li>
|
||||
|
||||
<li>Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in
|
||||
the documentation and/or other materials provided with the
|
||||
distribution.</li>
|
||||
|
||||
<li>Neither the name of the Thai Open Source Software Center Ltd nor
|
||||
the names of its contributors may be used to endorse or promote
|
||||
products derived from this software without specific prior written
|
||||
permission.</li>
|
||||
</ul>
|
||||
|
||||
<p>THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR
|
||||
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.</p>
|
||||
|
||||
<h2>Third-party JARs</h2>
|
||||
|
||||
<p>This distribution includes some additional JAR files, which have
|
||||
their own copying conditions:</p>
|
||||
|
||||
<dl>
|
||||
|
||||
<dt><code>isorelax.jar</code></dt>
|
||||
<dd>Comes from <a href="http://sourceforge.net/projects/iso-relax/">ISO RELAX</a>
|
||||
2003/01/08 distribution and is covered by the following license:
|
||||
|
||||
<p>Copyright (c) 2001-2002, SourceForge ISO-RELAX Project (ASAMI Tomoharu, Daisuke
|
||||
Okajima, Kohsuke Kawaguchi, and MURATA Makoto)</p>
|
||||
|
||||
<p>Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use,
|
||||
copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
|
||||
Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:</p>
|
||||
|
||||
<p>The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.</p>
|
||||
|
||||
<p>THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR
|
||||
A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||
ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.</p>
|
||||
</dd>
|
||||
|
||||
</dl>
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
||||
@@ -0,0 +1,93 @@
|
||||
<idea-plugin version="2" url="http://www.jetbrains.net/confluence/display/CONTEST/RELAX-NG+Support">
|
||||
<id>RelaxNG-Support</id>
|
||||
<name>RELAX-NG Support</name>
|
||||
<depends>com.intellij.modules.xml</depends>
|
||||
|
||||
<description><![CDATA[
|
||||
Support for RELAX-NG XML schemas. See <a href="http://relaxng.org/">relaxng.org</a> and the corresponding
|
||||
IntelliJ IDEA feature request: <a href="http://www.jetbrains.net/jira/browse/IDEA-13734">IDEA-13734</a>.
|
||||
<p>
|
||||
The plugin provides the following features:
|
||||
</p>
|
||||
<ul>
|
||||
<li> Completion and validation of XML documents associated with RELAX-NG schemas</li>
|
||||
<li> Editing RELAX-NG files in XML and compact syntax, including on-the-fly error checking, completion,
|
||||
documentation lookup and more.</li>
|
||||
<li> Conversion between different schema formats (including W3C XML Schema/XML 1.0 DTDs) using
|
||||
<a href="http://www.thaiopensource.com/relaxng/trang.html">Trang</a></li>
|
||||
</ul>
|
||||
]]></description>
|
||||
<version>1.5.5</version>
|
||||
|
||||
<change-notes><![CDATA[
|
||||
<ul>
|
||||
<li>extreme index optimization</li>
|
||||
<li>renameable xml prefixes</li>
|
||||
<li>IDEA 9.x compatibility bugfixes</li>
|
||||
</ul>
|
||||
<p>
|
||||
The complete list of changes in earlier versions is available
|
||||
<a href="http://www.jetbrains.net/confluence/display/CONTEST/RELAX-NG+Support#RELAX-NGSupport-VersionHistory">here</a>
|
||||
</p>
|
||||
]]></change-notes>
|
||||
|
||||
<vendor email="sascha.weinreuter@cit.de">Sascha Weinreuter</vendor>
|
||||
<idea-version since-build="95.4" /><!-- 9.x -->
|
||||
|
||||
<extensions defaultExtensionNs="com.intellij">
|
||||
<errorHandler implementation="org.intellij.plugins.relaxNG.SimpleErrorReportSubmitter" />
|
||||
<gotoSymbolContributor implementation="org.intellij.plugins.relaxNG.GotoSymbolContributor" />
|
||||
<xml.schemaProvider implementation="org.intellij.plugins.relaxNG.config.NoNamespaceSchemaProvider" />
|
||||
<hectorComponentProvider implementation="org.intellij.plugins.relaxNG.config.NoNamespaceConfigImpl$HectorProvider" />
|
||||
|
||||
<fileTypeFactory implementation="org.intellij.plugins.relaxNG.compact.RncFileType$Factory" />
|
||||
<completionData fileType="RNG Compact" className="org.intellij.plugins.relaxNG.compact.RncCompletionData" />
|
||||
<standardResourceProvider implementation="org.intellij.plugins.relaxNG.ApplicationLoader$ResourceProvider" />
|
||||
|
||||
<annotator language="RELAX-NG" implementationClass="org.intellij.plugins.relaxNG.compact.ReferenceAnnotator" />
|
||||
<annotator language="RELAX-NG" implementationClass="org.intellij.plugins.relaxNG.model.annotation.ModelAnnotator" />
|
||||
<externalAnnotator language="RELAX-NG" implementationClass="org.intellij.plugins.relaxNG.validation.RngSchemaValidator" />
|
||||
|
||||
<lang.parserDefinition language="RELAX-NG" implementationClass="org.intellij.plugins.relaxNG.compact.RncParserDefinition" />
|
||||
<lang.braceMatcher language="RELAX-NG" implementationClass="org.intellij.plugins.relaxNG.compact.RngCompactLanguage$MyPairedBraceMatcher" />
|
||||
<lang.commenter language="RELAX-NG" implementationClass="org.intellij.plugins.relaxNG.compact.RngCompactLanguage$MyCommenter" />
|
||||
<lang.foldingBuilder language="RELAX-NG" implementationClass="org.intellij.plugins.relaxNG.compact.folding.RncFoldingBuilder" />
|
||||
<lang.formatter language="RELAX-NG" implementationClass="org.intellij.plugins.relaxNG.compact.formatting.RncFormattingModelBuilder" />
|
||||
<lang.namesValidator language="RELAX-NG" implementationClass="org.intellij.plugins.relaxNG.compact.RngCompactLanguage$MyNamesValidator" />
|
||||
<lang.syntaxHighlighterFactory key="RELAX-NG" implementationClass="org.intellij.plugins.relaxNG.compact.RngCompactLanguage$MySyntaxHighlighterFactory" />
|
||||
|
||||
<lang.elementManipulator forClass="org.intellij.plugins.relaxNG.compact.psi.RncFileReference" implementationClass="org.intellij.plugins.relaxNG.ProjectLoader$RncFileReferenceManipulator" />
|
||||
|
||||
<lang.documentationProvider language="RELAX-NG" implementationClass="org.intellij.plugins.relaxNG.compact.RngCompactLanguage$MyDocumentationProvider" />
|
||||
|
||||
<fileBasedIndex implementation="org.intellij.plugins.relaxNG.model.resolve.RelaxSymbolIndex" />
|
||||
<include.provider implementation="org.intellij.plugins.relaxNG.model.resolve.RelaxIncludeProvider"/>
|
||||
|
||||
<externalAnnotator language="XML" implementationClass="org.intellij.plugins.relaxNG.validation.RngSchemaValidator" />
|
||||
<lang.documentationProvider language="XML" implementationClass="org.intellij.plugins.relaxNG.RngDocumentationProvider" />
|
||||
</extensions>
|
||||
|
||||
<project-components>
|
||||
<component>
|
||||
<implementation-class>org.intellij.plugins.relaxNG.ProjectLoader</implementation-class>
|
||||
</component>
|
||||
<component>
|
||||
<interface-class>org.intellij.plugins.relaxNG.config.NoNamespaceConfig</interface-class>
|
||||
<implementation-class>org.intellij.plugins.relaxNG.config.NoNamespaceConfigImpl</implementation-class>
|
||||
</component>
|
||||
</project-components>
|
||||
|
||||
<application-components>
|
||||
<component>
|
||||
<implementation-class>org.intellij.plugins.relaxNG.ApplicationLoader</implementation-class>
|
||||
</component>
|
||||
</application-components>
|
||||
|
||||
<actions>
|
||||
<action id="ConvertSchemaAction" class="org.intellij.plugins.relaxNG.convert.ConvertSchemaAction"
|
||||
text="Convert Schema..."
|
||||
description="Converts the selected Schema document (RNG, RNC, XSD, DTD) into another format">
|
||||
<add-to-group group-id="ToolsXmlGroup" anchor="after" relative-to-action="GenerateDTD" />
|
||||
</action>
|
||||
</actions>
|
||||
</idea-plugin>
|
||||
@@ -0,0 +1,25 @@
|
||||
<html>
|
||||
<head>
|
||||
<style type="text/css">
|
||||
body, table {
|
||||
font-family: Verdana, sans-serif;
|
||||
font-size: 100%;
|
||||
padding-left: 2mm;
|
||||
}
|
||||
|
||||
#footer {
|
||||
font-size: 95%;
|
||||
padding-top: 10px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<p>
|
||||
This inspections checks for any unresolved references to named patterns ("define") in a RELAX-NG file in XML Syntax.
|
||||
For unresolved references, a QuickFix is offered to create a corresponding define-element.
|
||||
</p>
|
||||
|
||||
<p id="footer">Powered by RELAX-NG Support</p>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,26 @@
|
||||
<html>
|
||||
<head>
|
||||
<style type="text/css">
|
||||
body, table {
|
||||
font-family: Verdana, sans-serif;
|
||||
font-size: 100%;
|
||||
padding-left: 2mm;
|
||||
}
|
||||
|
||||
#footer {
|
||||
font-size: 95%;
|
||||
padding-top: 10px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<p>
|
||||
This inspections checks for any unused named patterns ("define") in a RELAX-NG file (XML or Compact Syntax) and
|
||||
highlights them as unused symbols. This is done with respect to includes from other files, i.e. a define is not
|
||||
marked as unused if is is used through an include in another file.
|
||||
</p>
|
||||
|
||||
<p id="footer">Powered by RELAX-NG Support</p>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,124 @@
|
||||
/*
|
||||
* Copyright 2007 Sascha Weinreuter
|
||||
*
|
||||
* 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.intellij.plugins.relaxNG;
|
||||
|
||||
import org.intellij.plugins.relaxNG.compact.psi.impl.RncDocument;
|
||||
import org.intellij.plugins.relaxNG.inspections.RngDomInspection;
|
||||
import org.intellij.plugins.relaxNG.inspections.UnusedDefineInspection;
|
||||
import org.intellij.plugins.relaxNG.model.descriptors.RngNsDescriptor;
|
||||
import org.intellij.plugins.relaxNG.validation.ValidateAction;
|
||||
import org.intellij.plugins.relaxNG.xml.dom.RngDefine;
|
||||
import org.intellij.plugins.relaxNG.xml.dom.impl.RngDefineMetaData;
|
||||
|
||||
import com.intellij.codeInspection.InspectionToolProvider;
|
||||
import com.intellij.javaee.ResourceRegistrar;
|
||||
import com.intellij.javaee.StandardResourceProvider;
|
||||
import com.intellij.openapi.actionSystem.ActionManager;
|
||||
import com.intellij.openapi.actionSystem.AnAction;
|
||||
import com.intellij.openapi.components.ApplicationComponent;
|
||||
import com.intellij.openapi.fileTypes.FileTypeManager;
|
||||
import com.intellij.openapi.fileTypes.StdFileTypes;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.filters.AndFilter;
|
||||
import com.intellij.psi.filters.ClassFilter;
|
||||
import com.intellij.psi.filters.ElementFilter;
|
||||
import com.intellij.psi.filters.position.NamespaceFilter;
|
||||
import com.intellij.psi.meta.MetaDataRegistrar;
|
||||
import com.intellij.psi.xml.XmlDocument;
|
||||
import com.intellij.psi.xml.XmlTag;
|
||||
import com.intellij.util.xml.DomElement;
|
||||
import com.intellij.util.xml.DomManager;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* Created by IntelliJ IDEA.
|
||||
* User: sweinreuter
|
||||
* Date: 18.07.2007
|
||||
*/
|
||||
public class ApplicationLoader implements ApplicationComponent, InspectionToolProvider {
|
||||
private static final String RNG_EXT = "rng";
|
||||
private static final String VALIDATE_XML = "ValidateXml";
|
||||
|
||||
@NonNls
|
||||
@NotNull
|
||||
public String getComponentName() {
|
||||
return "Relax-NG";
|
||||
}
|
||||
|
||||
public void initComponent() {
|
||||
registerMetaData();
|
||||
|
||||
final FileTypeManager ftm = FileTypeManager.getInstance();
|
||||
ftm.registerFileType(StdFileTypes.XML, RNG_EXT);
|
||||
|
||||
installValidateXmlAction();
|
||||
}
|
||||
|
||||
private static void installValidateXmlAction() {
|
||||
final ActionManager mgr = ActionManager.getInstance();
|
||||
final AnAction validateAction = mgr.getAction(VALIDATE_XML);
|
||||
mgr.unregisterAction(VALIDATE_XML);
|
||||
mgr.registerAction(VALIDATE_XML, new ValidateAction(validateAction));
|
||||
}
|
||||
|
||||
private static void registerMetaData() {
|
||||
final MetaDataRegistrar registrar = MetaDataRegistrar.getInstance();
|
||||
registrar.registerMetaData(
|
||||
new AndFilter(
|
||||
new NamespaceFilter(ProjectLoader.RNG_NAMESPACE),
|
||||
new ClassFilter(XmlDocument.class)
|
||||
),
|
||||
RngNsDescriptor.class);
|
||||
|
||||
registrar.registerMetaData(
|
||||
new ClassFilter(RncDocument.class),
|
||||
RngNsDescriptor.class);
|
||||
|
||||
registrar.registerMetaData(new ElementFilter() {
|
||||
public boolean isAcceptable(Object element, PsiElement context) {
|
||||
if (element instanceof XmlTag) {
|
||||
final XmlTag tag = (XmlTag)element;
|
||||
final DomElement domElement = DomManager.getDomManager(tag.getProject()).getDomElement(tag);
|
||||
return domElement instanceof RngDefine;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean isClassAcceptable(Class hintClass) {
|
||||
return XmlTag.class.isAssignableFrom(hintClass);
|
||||
}
|
||||
}, RngDefineMetaData.class);
|
||||
}
|
||||
|
||||
public void disposeComponent() {
|
||||
}
|
||||
|
||||
public Class[] getInspectionClasses() {
|
||||
return new Class[]{
|
||||
RngDomInspection.class,
|
||||
UnusedDefineInspection.class
|
||||
};
|
||||
}
|
||||
|
||||
public class ResourceProvider implements StandardResourceProvider {
|
||||
public void registerResources(ResourceRegistrar registrar) {
|
||||
registrar.addStdResource(ProjectLoader.RNG_NAMESPACE, "resources/relaxng.rng", getClass());
|
||||
registrar.addIgnoredResource("http://relaxng.org/ns/compatibility/annotations/1.0");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Copyright 2007 Sascha Weinreuter
|
||||
*
|
||||
* 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.intellij.plugins.relaxNG;
|
||||
|
||||
import org.intellij.plugins.relaxNG.model.resolve.RelaxSymbolIndex;
|
||||
|
||||
import com.intellij.navigation.ChooseByNameContributor;
|
||||
import com.intellij.navigation.NavigationItem;
|
||||
import com.intellij.openapi.project.Project;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
/*
|
||||
* Created by IntelliJ IDEA.
|
||||
* User: sweinreuter
|
||||
* Date: 24.10.2007
|
||||
*/
|
||||
public class GotoSymbolContributor implements ChooseByNameContributor {
|
||||
|
||||
public NavigationItem[] getItemsByName(String name, String pattern, Project project, boolean includeNonProjectItems) {
|
||||
return RelaxSymbolIndex.getSymbolsByName(name, project, includeNonProjectItems);
|
||||
}
|
||||
|
||||
public String[] getNames(Project project, boolean includeNonProjectItems) {
|
||||
final Collection<String> names = RelaxSymbolIndex.getSymbolNames(project);
|
||||
return names.toArray(new String[names.size()]);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,152 @@
|
||||
/*
|
||||
* Copyright 2007 Sascha Weinreuter
|
||||
*
|
||||
* 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.intellij.plugins.relaxNG;
|
||||
|
||||
import com.intellij.lang.ASTNode;
|
||||
import com.intellij.openapi.components.ProjectComponent;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
import com.intellij.patterns.StringPattern;
|
||||
import com.intellij.patterns.XmlNamedElementPattern;
|
||||
import com.intellij.psi.AbstractElementManipulator;
|
||||
import com.intellij.psi.PsiManager;
|
||||
import com.intellij.psi.filters.position.PatternFilter;
|
||||
import com.intellij.psi.impl.source.resolve.reference.ReferenceProvidersRegistry;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import com.intellij.util.xml.DomFileDescription;
|
||||
import com.intellij.util.xml.DomManager;
|
||||
import com.intellij.util.xml.highlighting.DomElementsAnnotator;
|
||||
import com.intellij.xml.util.XmlUtil;
|
||||
import org.intellij.plugins.relaxNG.compact.RncTokenTypes;
|
||||
import org.intellij.plugins.relaxNG.compact.psi.RncFileReference;
|
||||
import org.intellij.plugins.relaxNG.compact.psi.util.RenameUtil;
|
||||
import org.intellij.plugins.relaxNG.model.annotation.ModelAnnotator;
|
||||
import org.intellij.plugins.relaxNG.references.PrefixReferenceProvider;
|
||||
import org.intellij.plugins.relaxNG.xml.dom.*;
|
||||
import org.intellij.plugins.relaxNG.xml.dom.impl.RngDefineImpl;
|
||||
import org.intellij.plugins.relaxNG.xml.dom.impl.RngGrammarImpl;
|
||||
import org.intellij.plugins.relaxNG.xml.dom.impl.RngIncludeImpl;
|
||||
import org.intellij.plugins.relaxNG.xml.dom.impl.RngRefImpl;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import static com.intellij.patterns.StandardPatterns.string;
|
||||
import static com.intellij.patterns.XmlPatterns.*;
|
||||
|
||||
/**
|
||||
* Created by IntelliJ IDEA.
|
||||
* User: sweinreuter
|
||||
* Date: 16.07.2007
|
||||
*/
|
||||
public class ProjectLoader implements ProjectComponent {
|
||||
public static final String RNG_NAMESPACE = "http://relaxng.org/ns/structure/1.0";
|
||||
|
||||
private static final XmlNamedElementPattern RNG_TAG_PATTERN = xmlTag().withNamespace(string().equalTo(RNG_NAMESPACE));
|
||||
|
||||
private static final XmlNamedElementPattern.XmlAttributePattern NAME_ATTR_PATTERN = xmlAttribute("name");
|
||||
private static final StringPattern ELEMENT_OR_ATTRIBUTE_PATTERN = string().oneOf("element", "attribute");
|
||||
private static final XmlNamedElementPattern.XmlAttributePattern NAME_PATTERN = NAME_ATTR_PATTERN.withParent(
|
||||
RNG_TAG_PATTERN.withLocalName(ELEMENT_OR_ATTRIBUTE_PATTERN));
|
||||
|
||||
private final Project myProject;
|
||||
|
||||
public ProjectLoader(Project project) {
|
||||
myProject = project;
|
||||
}
|
||||
|
||||
@NonNls
|
||||
@NotNull
|
||||
public String getComponentName() {
|
||||
return "RELAX-NG";
|
||||
}
|
||||
|
||||
public void initComponent() {
|
||||
registerFileDescriptions();
|
||||
|
||||
registerReferences();
|
||||
}
|
||||
|
||||
private void registerReferences() {
|
||||
final ReferenceProvidersRegistry registry = ReferenceProvidersRegistry.getInstance(myProject);
|
||||
XmlUtil.registerXmlAttributeValueReferenceProvider(registry, new String[]{
|
||||
"name"
|
||||
}, new PatternFilter(xmlAttributeValue().withParent(NAME_PATTERN)), true, new PrefixReferenceProvider());
|
||||
|
||||
// final XmlAttributeValuePattern id = xmlAttributeValue().withParent(xmlAttribute()).with(IdRefProvider.HAS_ID_REF_TYPE);
|
||||
// final XmlAttributeValuePattern idref = xmlAttributeValue().withParent(xmlAttribute()).with(IdRefProvider.HAS_ID_TYPE);
|
||||
// registry.registerXmlAttributeValueReferenceProvider(null, new PatternFilter(or(id, idref)), false, new IdRefProvider());
|
||||
}
|
||||
|
||||
@SuppressWarnings({ "deprecation" })
|
||||
private void registerFileDescriptions() {
|
||||
final DomManager mgr = DomManager.getDomManager(myProject);
|
||||
mgr.registerFileDescription(new MyFileDescription<RngGrammar>(RngGrammar.class, "grammar"));
|
||||
mgr.registerFileDescription(new MyFileDescription<RngElement>(RngElement.class, "element"));
|
||||
mgr.registerFileDescription(new MyFileDescription<RngChoice>(RngChoice.class, "choice"));
|
||||
mgr.registerFileDescription(new MyFileDescription<RngGroup>(RngGroup.class, "group"));
|
||||
mgr.registerFileDescription(new MyFileDescription<RngInterleave>(RngInterleave.class, "interleave"));
|
||||
}
|
||||
|
||||
public void disposeComponent() {
|
||||
}
|
||||
|
||||
public void projectOpened() {
|
||||
}
|
||||
|
||||
public void projectClosed() {
|
||||
}
|
||||
|
||||
private static class MyFileDescription<T> extends DomFileDescription<T> {
|
||||
public MyFileDescription(Class<T> elementClass, String rootTagName) {
|
||||
super(elementClass, rootTagName);
|
||||
registerNamespacePolicy("RELAX-NG", RNG_NAMESPACE);
|
||||
registerImplementation(RngDefine.class, RngDefineImpl.class);
|
||||
registerImplementation(RngGrammar.class, RngGrammarImpl.class);
|
||||
registerImplementation(RngInclude.class, RngIncludeImpl.class);
|
||||
registerImplementation(RngRef.class, RngRefImpl.class);
|
||||
}
|
||||
|
||||
public boolean isAutomaticHighlightingEnabled() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public DomElementsAnnotator createAnnotator() {
|
||||
return new ModelAnnotator();
|
||||
}
|
||||
}
|
||||
|
||||
public static class RncFileReferenceManipulator extends AbstractElementManipulator<RncFileReference> {
|
||||
public RncFileReference handleContentChange(RncFileReference element, TextRange range, String newContent) throws IncorrectOperationException {
|
||||
final ASTNode node = element.getNode();
|
||||
assert node != null;
|
||||
|
||||
final ASTNode literal = node.findChildByType(RncTokenTypes.LITERAL);
|
||||
if (literal != null) {
|
||||
assert range.equals(element.getReferenceRange());
|
||||
final PsiManager manager = PsiManager.getInstance(element.getProject());
|
||||
final ASTNode newChild = RenameUtil.createLiteralNode(manager, newContent);
|
||||
literal.getTreeParent().replaceChild(literal, newChild);
|
||||
}
|
||||
return element;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TextRange getRangeInElement(RncFileReference element) {
|
||||
return element.getReferenceRange();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,148 @@
|
||||
/*
|
||||
* Copyright 2007 Sascha Weinreuter
|
||||
*
|
||||
* 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.intellij.plugins.relaxNG;
|
||||
|
||||
import org.intellij.plugins.relaxNG.model.descriptors.CompositeDescriptor;
|
||||
import org.intellij.plugins.relaxNG.model.descriptors.RngElementDescriptor;
|
||||
import org.intellij.plugins.relaxNG.model.descriptors.RngXmlAttributeDescriptor;
|
||||
|
||||
import com.intellij.lang.documentation.DocumentationProvider;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiManager;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.psi.xml.XmlAttribute;
|
||||
import com.intellij.psi.xml.XmlElement;
|
||||
import com.intellij.psi.xml.XmlTag;
|
||||
import com.intellij.xml.XmlAttributeDescriptor;
|
||||
import com.intellij.xml.XmlElementDescriptor;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import org.kohsuke.rngom.digested.DElementPattern;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
/*
|
||||
* Created by IntelliJ IDEA.
|
||||
* User: sweinreuter
|
||||
* Date: 19.11.2007
|
||||
*/
|
||||
public class RngDocumentationProvider implements DocumentationProvider {
|
||||
@NonNls
|
||||
private static final String COMPATIBILITY_ANNOTATIONS_1_0 = "http://relaxng.org/ns/compatibility/annotations/1.0";
|
||||
|
||||
@Nullable
|
||||
public String generateDoc(PsiElement element, PsiElement originalElement) {
|
||||
final XmlElement c = PsiTreeUtil.getParentOfType(originalElement, XmlTag.class, XmlAttribute.class);
|
||||
if (c instanceof XmlTag) {
|
||||
final XmlTag xmlElement = (XmlTag)c;
|
||||
final XmlElementDescriptor descriptor = xmlElement.getDescriptor();
|
||||
if (descriptor instanceof CompositeDescriptor) {
|
||||
final StringBuilder sb = new StringBuilder();
|
||||
final CompositeDescriptor d = (CompositeDescriptor)descriptor;
|
||||
final DElementPattern[] patterns = d.getElementPatterns();
|
||||
for (DElementPattern pattern : patterns) {
|
||||
final PsiElement psiElement = d.getDeclaration(pattern.getLocation());
|
||||
if (psiElement instanceof XmlTag) {
|
||||
if (sb.length() > 0) {
|
||||
sb.append("<hr>");
|
||||
}
|
||||
sb.append(getDocumentationFromTag((XmlTag)psiElement, xmlElement.getLocalName(), "Element"));
|
||||
}
|
||||
}
|
||||
return makeDocumentation(sb);
|
||||
} else if (descriptor instanceof RngElementDescriptor) {
|
||||
final RngElementDescriptor d = (RngElementDescriptor)descriptor;
|
||||
final PsiElement declaration = d.getDeclaration();
|
||||
if (declaration instanceof XmlTag) {
|
||||
return makeDocumentation(getDocumentationFromTag((XmlTag)declaration, xmlElement.getLocalName(), "Element"));
|
||||
}
|
||||
}
|
||||
} else if (c instanceof XmlAttribute) {
|
||||
final XmlAttribute attribute = (XmlAttribute)c;
|
||||
final XmlAttributeDescriptor descriptor = attribute.getDescriptor();
|
||||
if (descriptor instanceof RngXmlAttributeDescriptor) {
|
||||
final RngXmlAttributeDescriptor d = (RngXmlAttributeDescriptor)descriptor;
|
||||
final StringBuilder sb = new StringBuilder();
|
||||
final Collection<PsiElement> declaration = d.getDeclarations();
|
||||
for (PsiElement psiElement : declaration) {
|
||||
if (psiElement instanceof XmlTag) {
|
||||
if (sb.length() > 0) {
|
||||
sb.append("<hr>");
|
||||
}
|
||||
sb.append(getDocumentationFromTag((XmlTag)element, d.getName(), "Attribute"));
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (element instanceof XmlTag) {
|
||||
return makeDocumentation(getDocumentationFromTag((XmlTag)element, ((XmlTag)element).getLocalName(), "Element"));
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static String makeDocumentation(StringBuilder sb) {
|
||||
if (!sb.toString().startsWith("<html>")) {
|
||||
sb.insert(0, "<html>");
|
||||
sb.append("</html>");
|
||||
}
|
||||
return sb.toString().replaceAll("\n", "<br>");
|
||||
}
|
||||
|
||||
private static StringBuilder getDocumentationFromTag(XmlTag tag, String localName, String kind) {
|
||||
if (tag.getNamespace().equals(ProjectLoader.RNG_NAMESPACE)) {
|
||||
final StringBuilder sb = new StringBuilder();
|
||||
sb.append(kind).append(": <b>").append(localName).append("</b><br>");
|
||||
final XmlTag[] docTags = tag.findSubTags("documentation", COMPATIBILITY_ANNOTATIONS_1_0);
|
||||
for (XmlTag docTag : docTags) {
|
||||
sb.append(docTag.getValue().getTrimmedText());
|
||||
sb.append("\n");
|
||||
}
|
||||
final XmlTag nextTag = PsiTreeUtil.getNextSiblingOfType(tag, XmlTag.class);
|
||||
if (nextTag != null) {
|
||||
if ("documentation".equals(nextTag.getLocalName()) && COMPATIBILITY_ANNOTATIONS_1_0.equals(nextTag.getNamespace())) {
|
||||
sb.append(nextTag.getValue().getTrimmedText());
|
||||
}
|
||||
}
|
||||
return sb;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public PsiElement getDocumentationElementForLink(PsiManager psiManager, String link, PsiElement context) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public PsiElement getDocumentationElementForLookupItem(PsiManager psiManager, Object object, PsiElement element) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public String getQuickNavigateInfo(PsiElement element) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public List<String> getUrlFor(PsiElement element, PsiElement originalElement) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
return 0; // CompositeDocumentationProvider uses a HashSet that doesn't preserve order. We want to be the first one.
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,135 @@
|
||||
/*
|
||||
* Copyright 2006 Sascha Weinreuter
|
||||
*
|
||||
* 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.intellij.plugins.relaxNG;
|
||||
|
||||
import com.intellij.ide.BrowserUtil;
|
||||
import com.intellij.ide.plugins.IdeaPluginDescriptor;
|
||||
import com.intellij.ide.plugins.PluginManager;
|
||||
import com.intellij.openapi.diagnostic.ErrorReportSubmitter;
|
||||
import com.intellij.openapi.diagnostic.IdeaLoggingEvent;
|
||||
import com.intellij.openapi.diagnostic.SubmittedReportInfo;
|
||||
import com.intellij.openapi.ui.DialogWrapper;
|
||||
import com.intellij.openapi.ui.Messages;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.event.HyperlinkEvent;
|
||||
import javax.swing.event.HyperlinkListener;
|
||||
import java.awt.*;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.net.URLEncoder;
|
||||
|
||||
public class SimpleErrorReportSubmitter extends ErrorReportSubmitter {
|
||||
public String getReportActionText() {
|
||||
return "Error Report Information";
|
||||
}
|
||||
|
||||
public SubmittedReportInfo submit(IdeaLoggingEvent[] events, Component parentComponent) {
|
||||
final IdeaPluginDescriptor plugin = PluginManager.getPlugin(getPluginDescriptor().getPluginId());
|
||||
|
||||
assert plugin != null;
|
||||
final String title = plugin.getName() + " - " + plugin.getVersion();
|
||||
|
||||
final String vendorEmail = plugin.getVendorEmail();
|
||||
final String subject = title + " Exception";
|
||||
final String mailto = "mailto:" + encode(vendorEmail) + "?Subject=" + encode(subject) /*+
|
||||
"&body=" + encode("Stacktrace:\n" + events[0].getThrowableText())*/;
|
||||
|
||||
final String weblink = "http://www.intellij.net/forums/forum.jsp?forum=18";
|
||||
final String website = plugin.getUrl();
|
||||
|
||||
final String font = new JLabel().getFont().getName();
|
||||
|
||||
String message = "<html><span style='font: " + font + "; font-size:smaller'>" +
|
||||
"To report an exception, please post the exception stacktrace and a short description " +
|
||||
"of how it can be reproduced to the IntelliJ " +
|
||||
"<a href='" + weblink + "'>plugin web forum</a> or the corresponding newsgroup, " +
|
||||
"and/or send an email containing that information to " +
|
||||
"<a href='" + mailto + "'>" + vendorEmail + "</a>." +
|
||||
(website != null ? "<br><br>Please also check the plugin's <a href='" + website + "'>website</a> for more information." : "") +
|
||||
"</span></html>";
|
||||
|
||||
final JEditorPane pane = new JEditorPane("text/html", message);
|
||||
pane.setEditable(false);
|
||||
pane.setPreferredSize(new Dimension(410, website != null ? 110 : 80));
|
||||
pane.addHyperlinkListener(new HyperlinkListener() {
|
||||
public void hyperlinkUpdate(HyperlinkEvent e) {
|
||||
if (e.getEventType() == HyperlinkEvent.EventType.ACTIVATED) {
|
||||
BrowserUtil.launchBrowser(e.getURL().toExternalForm());
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
new MyMessageDialog(parentComponent, title, Messages.getErrorIcon(), pane).show();
|
||||
|
||||
return new SubmittedReportInfo(null, null, SubmittedReportInfo.SubmissionStatus.FAILED);
|
||||
}
|
||||
|
||||
private String encode(String link) {
|
||||
final String enc = System.getProperty("file.encoding");
|
||||
try {
|
||||
return URLEncoder.encode(link, enc).replaceAll("\\+", "%20");
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
throw new Error(e);
|
||||
}
|
||||
}
|
||||
|
||||
private static class MyMessageDialog extends DialogWrapper {
|
||||
protected JComponent myMessage;
|
||||
protected Icon myIcon;
|
||||
|
||||
public MyMessageDialog(Component parent, String title, Icon icon, JComponent message) {
|
||||
super(parent, false);
|
||||
_init(title, message, icon);
|
||||
}
|
||||
|
||||
private void _init(String title, JComponent message, Icon icon) {
|
||||
setTitle(title);
|
||||
myMessage = message;
|
||||
myIcon = icon;
|
||||
setButtonsAlignment(SwingUtilities.CENTER);
|
||||
init();
|
||||
|
||||
myMessage.setBackground(getContentPane().getBackground());
|
||||
}
|
||||
|
||||
protected Action[] createActions() {
|
||||
return new Action[]{ getOKAction() };
|
||||
}
|
||||
|
||||
protected JComponent createNorthPanel() {
|
||||
JPanel panel = new JPanel(new BorderLayout(15, 0));
|
||||
if (myIcon != null) {
|
||||
JLabel iconLabel = new JLabel(myIcon);
|
||||
Container container = new Container();
|
||||
container.setLayout(new BorderLayout());
|
||||
container.add(iconLabel, BorderLayout.NORTH);
|
||||
panel.add(container, BorderLayout.WEST);
|
||||
}
|
||||
|
||||
if (myMessage != null) {
|
||||
panel.add(myMessage, BorderLayout.CENTER);
|
||||
}
|
||||
return panel;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
protected JComponent createCenterPanel() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,126 @@
|
||||
/*
|
||||
* Copyright 2007 Sascha Weinreuter
|
||||
*
|
||||
* 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.intellij.plugins.relaxNG.compact;
|
||||
|
||||
import org.intellij.plugins.relaxNG.compact.psi.*;
|
||||
|
||||
import com.intellij.codeInsight.daemon.EmptyResolveMessageProvider;
|
||||
import com.intellij.codeInsight.daemon.QuickFixProvider;
|
||||
import com.intellij.codeInsight.daemon.impl.HighlightInfo;
|
||||
import com.intellij.codeInsight.daemon.impl.HighlightInfoType;
|
||||
import com.intellij.codeInspection.ProblemHighlightType;
|
||||
import com.intellij.lang.annotation.Annotation;
|
||||
import com.intellij.lang.annotation.AnnotationHolder;
|
||||
import com.intellij.lang.annotation.Annotator;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiPolyVariantReference;
|
||||
import com.intellij.psi.PsiReference;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.text.MessageFormat;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Created by IntelliJ IDEA.
|
||||
* User: sweinreuter
|
||||
* Date: 10.08.2007
|
||||
*/
|
||||
public class ReferenceAnnotator extends RncElementVisitor implements Annotator {
|
||||
private AnnotationHolder myHolder;
|
||||
|
||||
public synchronized void annotate(@NotNull PsiElement psiElement, @NotNull AnnotationHolder holder) {
|
||||
myHolder = holder;
|
||||
try {
|
||||
psiElement.accept(this);
|
||||
} finally {
|
||||
myHolder = null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitInclude(RncInclude include) {
|
||||
checkReferences(include.getReferences());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitExternalRef(RncExternalRef ref) {
|
||||
checkReferences(ref.getReferences());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitRef(RncRef pattern) {
|
||||
checkReferences(pattern.getReferences());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitParentRef(RncParentRef pattern) {
|
||||
checkReferences(pattern.getReferences());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitName(RncName name) {
|
||||
checkReferences(name.getReferences());
|
||||
}
|
||||
|
||||
private void checkReferences(PsiReference[] references) {
|
||||
for (PsiReference reference : references) {
|
||||
if (!reference.isSoft()) {
|
||||
if (reference.resolve() == null) {
|
||||
if (reference instanceof PsiPolyVariantReference) {
|
||||
final PsiPolyVariantReference pvr = (PsiPolyVariantReference)reference;
|
||||
if (pvr.multiResolve(false).length == 0) {
|
||||
addError(reference);
|
||||
}
|
||||
} else {
|
||||
addError(reference);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void addError(PsiReference reference) {
|
||||
final TextRange rangeInElement = reference.getRangeInElement();
|
||||
final TextRange range = TextRange.from(reference.getElement().getTextRange().getStartOffset()
|
||||
+ rangeInElement.getStartOffset(), rangeInElement.getLength());
|
||||
|
||||
final Annotation annotation;
|
||||
if (reference instanceof EmptyResolveMessageProvider) {
|
||||
final String s = ((EmptyResolveMessageProvider)reference).getUnresolvedMessagePattern();
|
||||
annotation = myHolder.createErrorAnnotation(range, s != null ?
|
||||
MessageFormat.format(s, reference.getCanonicalText())
|
||||
: "Cannot resolve symbol");
|
||||
} else {
|
||||
annotation = myHolder.createErrorAnnotation(range, "Cannot resolve symbol");
|
||||
}
|
||||
annotation.setHighlightType(ProblemHighlightType.LIKE_UNKNOWN_SYMBOL);
|
||||
|
||||
if (reference instanceof QuickFixProvider) {
|
||||
final HighlightInfo info = new HighlightInfo(HighlightInfoType.WRONG_REF, annotation.getStartOffset(), annotation.getEndOffset(), "", null);
|
||||
((QuickFixProvider)reference).registerQuickfix(info, reference);
|
||||
|
||||
final List<Pair<HighlightInfo.IntentionActionDescriptor,TextRange>> ranges = info.quickFixActionRanges;
|
||||
if (ranges != null) {
|
||||
for (Pair<HighlightInfo.IntentionActionDescriptor, TextRange> pair : ranges) {
|
||||
annotation.registerFix(pair.first.getAction(), pair.second);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,137 @@
|
||||
/*
|
||||
* Copyright 2007 Sascha Weinreuter
|
||||
*
|
||||
* 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.intellij.plugins.relaxNG.compact;
|
||||
|
||||
import com.intellij.codeInsight.TailType;
|
||||
import com.intellij.codeInsight.completion.CompletionContext;
|
||||
import com.intellij.codeInsight.completion.CompletionData;
|
||||
import com.intellij.codeInsight.completion.CompletionVariant;
|
||||
import com.intellij.codeInsight.lookup.LookupElement;
|
||||
import com.intellij.codeInsight.lookup.LookupElementFactory;
|
||||
import com.intellij.patterns.ElementPattern;
|
||||
import com.intellij.patterns.PsiElementPattern;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiWhiteSpace;
|
||||
import com.intellij.psi.filters.AndFilter;
|
||||
import com.intellij.psi.filters.ContextGetter;
|
||||
import com.intellij.psi.filters.ElementFilter;
|
||||
import com.intellij.psi.filters.position.PatternFilter;
|
||||
import com.intellij.psi.impl.source.tree.LeafPsiElement;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.util.ArrayUtil;
|
||||
import com.intellij.util.Function;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import org.intellij.plugins.relaxNG.compact.psi.RncDecl;
|
||||
import org.intellij.plugins.relaxNG.compact.psi.RncDefine;
|
||||
import org.intellij.plugins.relaxNG.compact.psi.RncElement;
|
||||
import org.intellij.plugins.relaxNG.compact.psi.RncGrammar;
|
||||
import org.intellij.plugins.relaxNG.compact.psi.util.EscapeUtil;
|
||||
|
||||
import static com.intellij.patterns.PlatformPatterns.psiElement;
|
||||
import static com.intellij.patterns.StandardPatterns.*;
|
||||
|
||||
public class RncCompletionData extends CompletionData {
|
||||
|
||||
public RncCompletionData() {
|
||||
declareFinalScope(RncElement.class);
|
||||
|
||||
final CompletionVariant variant = new CompletionVariant(new AndFilter(
|
||||
new ElementFilter() {
|
||||
public boolean isAcceptable(Object element, PsiElement context) {
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean isClassAcceptable(Class hintClass) {
|
||||
return PsiElement.class.isAssignableFrom(hintClass);
|
||||
}
|
||||
},
|
||||
new PatternFilter(or(
|
||||
psiElement().afterLeaf(psiElement(RncTokenTypes.KEYWORD_DEFAULT)),
|
||||
not(
|
||||
or(
|
||||
psiElement().inside(psiElement(RncTokenTypes.LITERAL)),
|
||||
psiElement().afterLeaf(psiElement().withElementType(RncTokenTypes.KEYWORDS))
|
||||
)
|
||||
)
|
||||
))
|
||||
));
|
||||
|
||||
variant.includeScopeClass(LeafPsiElement.class, true);
|
||||
|
||||
variant.addCompletion(new KeywordGetter());
|
||||
|
||||
registerVariant(variant);
|
||||
}
|
||||
|
||||
private static class KeywordGetter implements ContextGetter {
|
||||
private static final ElementPattern TOP_LEVEL =
|
||||
not(psiElement().inside(psiElement(RncGrammar.class)
|
||||
.inside(true, psiElement(RncGrammar.class))));
|
||||
|
||||
private static final PsiElementPattern DECL_PATTERN =
|
||||
psiElement().inside(psiElement(RncDecl.class));
|
||||
|
||||
private static final PsiElementPattern DEFAULT_PATTERN =
|
||||
DECL_PATTERN.afterLeaf(psiElement().withText("default"));
|
||||
|
||||
private static final ElementPattern DEFINE_PATTERN =
|
||||
and(psiElement().withParent(RncDefine.class), psiElement().afterLeafSkipping(psiElement(PsiWhiteSpace.class), psiElement().withText("=")));
|
||||
|
||||
private static final String[] DECL_KEYWORDS = new String[]{ "default", "namespace", "datatypes" };
|
||||
private static final String[] GRAMMAR_CONTENT_KEYWORDS = new String[]{ "include", "div", "start" };
|
||||
private static final String[] PATTERN_KEYWORDS = new String[]{ "attribute", "element", "grammar",
|
||||
"notAllowed", "text", "empty", "external", "parent", "list", "mixed" };
|
||||
|
||||
public Object[] get(PsiElement context, CompletionContext completionContext) {
|
||||
return ContainerUtil.map2Array(doGetKeywords(context), LookupElement.class, new Function<String, LookupElement>() {
|
||||
public LookupElement fun(String s) {
|
||||
return LookupElementFactory.getInstance().createLookupElement(s).setTailType(TailType.SPACE).setBold();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private String[] doGetKeywords(PsiElement context) {
|
||||
final PsiElement next = PsiTreeUtil.skipSiblingsForward(context, PsiWhiteSpace.class);
|
||||
if (next != null && EscapeUtil.unescapeText(next).equals("=")) {
|
||||
return new String[]{ "start" };
|
||||
}
|
||||
|
||||
if (DEFAULT_PATTERN.accepts(context)) {
|
||||
return new String[]{ "namespace" };
|
||||
} else if (DECL_PATTERN.accepts(context)) {
|
||||
return ArrayUtil.EMPTY_STRING_ARRAY;
|
||||
} else if (context.getParent() instanceof RncDefine && context.getParent().getFirstChild() == context) {
|
||||
if (DEFINE_PATTERN.accepts(context)) {
|
||||
return ArrayUtil.EMPTY_STRING_ARRAY;
|
||||
}
|
||||
if (TOP_LEVEL.accepts(context)) {
|
||||
if (!afterPattern(context)) {
|
||||
return ArrayUtil.mergeArrays(DECL_KEYWORDS,
|
||||
ArrayUtil.mergeArrays(GRAMMAR_CONTENT_KEYWORDS, PATTERN_KEYWORDS, String.class), String.class);
|
||||
}
|
||||
}
|
||||
return GRAMMAR_CONTENT_KEYWORDS;
|
||||
}
|
||||
return PATTERN_KEYWORDS;
|
||||
}
|
||||
|
||||
private boolean afterPattern(PsiElement context) {
|
||||
// TODO: recognize all patterns
|
||||
return PsiTreeUtil.getPrevSiblingOfType(context.getParent(), RncDefine.class) != null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Copyright 2007 Sascha Weinreuter
|
||||
*
|
||||
* 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.intellij.plugins.relaxNG.compact;
|
||||
|
||||
import org.intellij.plugins.relaxNG.compact.psi.RncElement;
|
||||
|
||||
import com.intellij.lang.ASTNode;
|
||||
import com.intellij.psi.tree.IElementType;
|
||||
import com.intellij.util.NotNullFunction;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.Modifier;
|
||||
|
||||
public class RncElementType extends IElementType {
|
||||
public RncElementType(String name) {
|
||||
super(name, RngCompactLanguage.INSTANCE);
|
||||
}
|
||||
}
|
||||
|
||||
class RncElementTypeEx<C extends RncElement> extends RncElementType implements NotNullFunction<ASTNode, C> {
|
||||
private final Constructor<? extends C> myConstructor;
|
||||
|
||||
RncElementTypeEx(String name, Class<? extends C> clazz) {
|
||||
super(name);
|
||||
assert !clazz.isInterface() && !Modifier.isAbstract(clazz.getModifiers());
|
||||
try {
|
||||
myConstructor = clazz.getConstructor(ASTNode.class);
|
||||
} catch (NoSuchMethodException e) {
|
||||
throw new Error(e);
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public final C fun(ASTNode node) {
|
||||
try {
|
||||
return myConstructor.newInstance(node);
|
||||
} catch (Exception e) {
|
||||
throw new Error(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
/*
|
||||
* Copyright 2007 Sascha Weinreuter
|
||||
*
|
||||
* 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.intellij.plugins.relaxNG.compact;
|
||||
|
||||
import org.intellij.plugins.relaxNG.compact.psi.*;
|
||||
import org.intellij.plugins.relaxNG.compact.psi.impl.*;
|
||||
|
||||
import com.intellij.psi.tree.IElementType;
|
||||
import com.intellij.psi.tree.IFileElementType;
|
||||
|
||||
/*
|
||||
* Created by IntelliJ IDEA.
|
||||
* User: sweinreuter
|
||||
* Date: 01.08.2007
|
||||
*/
|
||||
public class RncElementTypes {
|
||||
public static final IFileElementType FILE_ELEMENT_TYPE = new IFileElementType(RngCompactLanguage.INSTANCE);
|
||||
|
||||
public static final IElementType DOCUMENT = new RncElementTypeEx<RncDocument>("DOCUMENT", RncDocument.class);
|
||||
|
||||
public static final IElementType NS_DECL = new RncElementTypeEx<RncNsDecl>("NS_DECL", RncNsDeclImpl.class);
|
||||
public static final IElementType DATATYPES_DECL = new RncElementTypeEx<RncDecl>("DATATYPES_DECL", RncDeclImpl.class);
|
||||
|
||||
public static final IElementType START = new RncElementType("START");
|
||||
public static final IElementType DIV = new RncElementTypeEx<RncDiv>("DIV", RncDivImpl.class);
|
||||
public static final IElementType INCLUDE = new RncElementTypeEx<RncInclude>("INCLUDE", RncIncludeImpl.class);
|
||||
|
||||
public static final IElementType NAME_CLASS = new RncElementType("NAME_CLASS");
|
||||
public static final IElementType NAME_CLASS_CHOICE = new RncElementType("NAME_CLASS_CHOICE");
|
||||
public static final IElementType EXCEPT_NAME_CLASS = new RncElementType("EXCEPT_NAME_CLASS");
|
||||
|
||||
public static final IElementType DEFINE = new RncElementTypeEx<RncDefine>("DEFINE", RncDefineImpl.class);
|
||||
public static final IElementType PATTERN = new RncElementType("PATTERN");
|
||||
public static final IElementType GROUP_PATTERN = new RncElementType("GROUP_PATTERN");
|
||||
public static final IElementType GRAMMAR_PATTERN = new RncElementTypeEx<RncGrammar>("GRAMMAR_PATTERN", RncGrammarImpl.class);
|
||||
public static final IElementType EMPTY_PATTERN = new RncElementType("EMPTY_PATTERN");
|
||||
public static final IElementType TEXT_PATTERN = new RncElementType("TEXT_PATTERN");
|
||||
public static final IElementType NOT_ALLOWED_PATTERN = new RncElementType("NOT_ALLOWED_PATTERN");
|
||||
public static final IElementType EXTERNAL_REF = new RncElementTypeEx<RncExternalRef>("EXTERNAL_REF", RncExternalRefImpl.class);
|
||||
public static final IElementType PARENT_REF = new RncElementTypeEx<RncParentRef>("PARENT_REF", RncParentRefImpl.class);
|
||||
public static final IElementType REF_PATTERN = new RncElementTypeEx<RncRef>("REF_PATTERN", RncRefImpl.class);
|
||||
public static final IElementType LIST_PATTERN = new RncElementType("LIST_PATTERN");
|
||||
public static final IElementType MIXED_PATTERN = new RncElementType("MIXED_PATTERN");
|
||||
|
||||
public static final IElementType DATATYPE_PATTERN = new RncElementType("DATATYPE_PATTERN");
|
||||
public static final IElementType PARAM = new RncElementType("PARAM");
|
||||
|
||||
public static final IElementType SEQUENCE = new RncElementType("SEQUENCE");
|
||||
public static final IElementType INTERLEAVE = new RncElementType("INTERLEAVE");
|
||||
public static final IElementType CHOICE = new RncElementType("CHOICE");
|
||||
public static final IElementType OPTIONAL = new RncElementType("OPTIONAL");
|
||||
public static final IElementType ZERO_OR_MORE = new RncElementType("ZERO_OR_MORE");
|
||||
public static final IElementType ONE_OR_MORE = new RncElementType("ONE_OR_MORE");
|
||||
|
||||
public static final IElementType NAME = new RncElementTypeEx<RncName>("NAME", RncNameImpl.class);
|
||||
|
||||
public static final IElementType ANNOTATION = new RncElementTypeEx<RncAnnotation>("ANNOTATION", RncAnnotationImpl.class);
|
||||
public static final IElementType ANNOTATION_ELEMENT = new RncElementTypeEx<RncAnnotation>("ANNOTATION_ELEMENT", RncAnnotationImpl.class);
|
||||
public static final IElementType FORWARD_ANNOTATION = new RncElementTypeEx<RncAnnotation>("FORWARD_ANNOTATION", RncAnnotationImpl.class);
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
/*
|
||||
* Copyright 2007 Sascha Weinreuter
|
||||
*
|
||||
* 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.intellij.plugins.relaxNG.compact;
|
||||
|
||||
import com.intellij.openapi.fileTypes.FileType;
|
||||
import com.intellij.openapi.fileTypes.FileTypeConsumer;
|
||||
import com.intellij.openapi.fileTypes.FileTypeFactory;
|
||||
import com.intellij.openapi.fileTypes.LanguageFileType;
|
||||
import com.intellij.openapi.util.IconLoader;
|
||||
import com.intellij.util.PairConsumer;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import javax.swing.*;
|
||||
|
||||
/*
|
||||
* Created by IntelliJ IDEA.
|
||||
* User: sweinreuter
|
||||
* Date: 01.08.2007
|
||||
*/
|
||||
public class RncFileType extends LanguageFileType {
|
||||
public static final String RNC_EXT = "rnc";
|
||||
|
||||
private static FileType INSTANCE;
|
||||
|
||||
private RncFileType() {
|
||||
super(RngCompactLanguage.INSTANCE);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@NonNls
|
||||
public String getName() {
|
||||
return "RNG Compact";
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public String getDescription() {
|
||||
return "RELAX NG Compact Syntax";
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@NonNls
|
||||
public String getDefaultExtension() {
|
||||
return "rnc";
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Icon getIcon() {
|
||||
return IconLoader.findIcon("/fileTypes/text.png");
|
||||
}
|
||||
|
||||
public static synchronized FileType getInstance() {
|
||||
if (INSTANCE == null) {
|
||||
INSTANCE = new RncFileType();
|
||||
}
|
||||
return INSTANCE;
|
||||
}
|
||||
|
||||
public static class Factory extends FileTypeFactory {
|
||||
public void createFileTypes(@NotNull FileTypeConsumer fileTypeConsumer) {
|
||||
fileTypeConsumer.consume(getInstance(), RNC_EXT);
|
||||
}
|
||||
|
||||
public void createFileTypes(@NotNull PairConsumer<FileType, String> consumer) {
|
||||
consumer.consume(getInstance(), RNC_EXT);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
/*
|
||||
* Copyright 2007 Sascha Weinreuter
|
||||
*
|
||||
* 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.intellij.plugins.relaxNG.compact;
|
||||
|
||||
import org.intellij.plugins.relaxNG.compact.lexer.CompactSyntaxLexerAdapter;
|
||||
|
||||
import com.intellij.lexer.Lexer;
|
||||
import com.intellij.openapi.editor.HighlighterColors;
|
||||
import com.intellij.openapi.editor.SyntaxHighlighterColors;
|
||||
import com.intellij.openapi.editor.colors.CodeInsightColors;
|
||||
import com.intellij.openapi.editor.colors.TextAttributesKey;
|
||||
import com.intellij.openapi.fileTypes.SyntaxHighlighterBase;
|
||||
import com.intellij.psi.tree.IElementType;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Created by IntelliJ IDEA.
|
||||
* User: sweinreuter
|
||||
* Date: 04.08.2007
|
||||
*/
|
||||
public class RncHighlighter extends SyntaxHighlighterBase {
|
||||
@NotNull
|
||||
public Lexer getHighlightingLexer() {
|
||||
return new CompactSyntaxLexerAdapter();
|
||||
}
|
||||
|
||||
private static final Map<IElementType, TextAttributesKey> ourMap1;
|
||||
|
||||
static {
|
||||
ourMap1 = new HashMap<IElementType, TextAttributesKey>();
|
||||
|
||||
fillMap(ourMap1, RncTokenTypes.KEYWORDS, SyntaxHighlighterColors.KEYWORD);
|
||||
fillMap(ourMap1, RncTokenTypes.OPERATORS, SyntaxHighlighterColors.OPERATION_SIGN);
|
||||
|
||||
fillMap(ourMap1, RncTokenTypes.STRINGS, SyntaxHighlighterColors.STRING);
|
||||
|
||||
ourMap1.put(RncTokenTypes.LBRACE, SyntaxHighlighterColors.BRACES);
|
||||
ourMap1.put(RncTokenTypes.RBRACE, SyntaxHighlighterColors.BRACES);
|
||||
|
||||
ourMap1.put(RncTokenTypes.LBRACKET, SyntaxHighlighterColors.BRACKETS);
|
||||
ourMap1.put(RncTokenTypes.RBRACKET, SyntaxHighlighterColors.BRACKETS);
|
||||
|
||||
ourMap1.put(RncTokenTypes.LPAREN, SyntaxHighlighterColors.PARENTHS);
|
||||
ourMap1.put(RncTokenTypes.RPAREN, SyntaxHighlighterColors.PARENTHS);
|
||||
|
||||
ourMap1.put(RncTokenTypes.COMMA, SyntaxHighlighterColors.COMMA);
|
||||
|
||||
fillMap(ourMap1, RncTokenTypes.DOC_TOKENS, SyntaxHighlighterColors.DOC_COMMENT);
|
||||
fillMap(ourMap1, RncTokenTypes.COMMENTS, SyntaxHighlighterColors.LINE_COMMENT);
|
||||
|
||||
fillMap(ourMap1, RncTokenTypes.IDENTIFIERS, CodeInsightColors.LOCAL_VARIABLE_ATTRIBUTES);
|
||||
|
||||
ourMap1.put(RncTokenTypes.ILLEGAL_CHAR, HighlighterColors.BAD_CHARACTER);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public TextAttributesKey[] getTokenHighlights(IElementType tokenType) {
|
||||
return pack(ourMap1.get(tokenType));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,103 @@
|
||||
/*
|
||||
* Copyright 2007 Sascha Weinreuter
|
||||
*
|
||||
* 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.intellij.plugins.relaxNG.compact;
|
||||
|
||||
import org.intellij.plugins.relaxNG.compact.lexer.CompactSyntaxLexerAdapter;
|
||||
import org.intellij.plugins.relaxNG.compact.parser.RncParser;
|
||||
import org.intellij.plugins.relaxNG.compact.psi.RncElementVisitor;
|
||||
import org.intellij.plugins.relaxNG.compact.psi.impl.RncElementImpl;
|
||||
import org.intellij.plugins.relaxNG.compact.psi.impl.RncFileImpl;
|
||||
|
||||
import com.intellij.lang.ASTNode;
|
||||
import com.intellij.lang.ParserDefinition;
|
||||
import com.intellij.lang.PsiParser;
|
||||
import com.intellij.lexer.Lexer;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.psi.FileViewProvider;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.psi.TokenType;
|
||||
import com.intellij.psi.tree.IElementType;
|
||||
import com.intellij.psi.tree.IFileElementType;
|
||||
import com.intellij.psi.tree.TokenSet;
|
||||
import com.intellij.util.NotNullFunction;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* Created by IntelliJ IDEA.
|
||||
* User: sweinreuter
|
||||
* Date: 10.08.2007
|
||||
*/
|
||||
public class RncParserDefinition implements ParserDefinition {
|
||||
@NotNull
|
||||
public Lexer createLexer(Project project) {
|
||||
return new CompactSyntaxLexerAdapter();
|
||||
}
|
||||
|
||||
public PsiParser createParser(Project project) {
|
||||
return new RncParser();
|
||||
}
|
||||
|
||||
public IFileElementType getFileNodeType() {
|
||||
return RncElementTypes.FILE_ELEMENT_TYPE;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public TokenSet getWhitespaceTokens() {
|
||||
return TokenSet.create(TokenType.WHITE_SPACE);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public TokenSet getCommentTokens() {
|
||||
return TokenSet.orSet(RncTokenTypes.COMMENTS, RncTokenTypes.DOC_TOKENS);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public TokenSet getStringLiteralElements() {
|
||||
return TokenSet.create(RncTokenTypes.LITERAL);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@SuppressWarnings({ "unchecked" })
|
||||
public PsiElement createElement(ASTNode node) {
|
||||
final IElementType type = node.getElementType();
|
||||
|
||||
if (type instanceof NotNullFunction) {
|
||||
return ((NotNullFunction<ASTNode, PsiElement>)type).fun(node);
|
||||
}
|
||||
|
||||
return new MyRncElement(node);
|
||||
}
|
||||
|
||||
public PsiFile createFile(FileViewProvider viewProvider) {
|
||||
return new RncFileImpl(viewProvider);
|
||||
}
|
||||
|
||||
public SpaceRequirements spaceExistanceTypeBetweenTokens(ASTNode left, ASTNode right) {
|
||||
return SpaceRequirements.MAY;
|
||||
}
|
||||
|
||||
private static class MyRncElement extends RncElementImpl {
|
||||
public MyRncElement(ASTNode node) {
|
||||
super(node);
|
||||
}
|
||||
|
||||
public void accept(@NotNull RncElementVisitor visitor) {
|
||||
visitor.visitElement(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,205 @@
|
||||
/*
|
||||
* Copyright 2007 Sascha Weinreuter
|
||||
*
|
||||
* 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.intellij.plugins.relaxNG.compact;
|
||||
|
||||
import com.intellij.openapi.util.Ref;
|
||||
import com.intellij.psi.tree.IElementType;
|
||||
import com.intellij.psi.tree.TokenSet;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import gnu.trove.TIntObjectHashMap;
|
||||
import gnu.trove.TObjectProcedure;
|
||||
import org.kohsuke.rngom.parse.compact.CompactSyntaxConstants;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
/**
|
||||
* Created by IntelliJ IDEA.
|
||||
* User: sweinreuter
|
||||
* Date: 04.08.2007
|
||||
*/
|
||||
public class RncTokenTypes {
|
||||
private static final TIntObjectHashMap<IElementType> ourTokenTypes = new TIntObjectHashMap<IElementType>();
|
||||
|
||||
static {
|
||||
assert RngCompactLanguage.INSTANCE != null;
|
||||
try {
|
||||
final Field[] fields = CompactSyntaxConstants.class.getFields();
|
||||
for (Field field : fields) {
|
||||
final String name = field.getName();
|
||||
if (name.equals("DEFAULT")) break;
|
||||
|
||||
if (int.class.isAssignableFrom(field.getType())) {
|
||||
Integer i = (Integer)field.get(null);
|
||||
ourTokenTypes.put(i, new RncElementType(name));
|
||||
}
|
||||
}
|
||||
|
||||
final String[] tokens = CompactSyntaxConstants.tokenImage;
|
||||
for (int i = 0; i < tokens.length; i++) {
|
||||
String token = tokens[i];
|
||||
if (token.matches("\"\\w*\"")) {
|
||||
token = "KEYWORD_" + token.substring(1, token.length() - 1).toUpperCase();
|
||||
} else if (token.matches("\".*\"")) {
|
||||
token = token.substring(1, token.length() - 1);
|
||||
}
|
||||
if (ourTokenTypes.get(i) == null) {
|
||||
ourTokenTypes.put(i, new RncElementType(token));
|
||||
}
|
||||
}
|
||||
} catch (IllegalAccessException e) {
|
||||
throw new Error(e);
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static IElementType get(int i) {
|
||||
assert !ourTokenTypes.isEmpty();
|
||||
final IElementType type = ourTokenTypes.get(i);
|
||||
assert type != null : "Unknown token kind: " + i;
|
||||
return type;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static IElementType get(final String name) {
|
||||
assert !ourTokenTypes.isEmpty();
|
||||
final Ref<IElementType> ref = new Ref<IElementType>();
|
||||
ourTokenTypes.forEachValue(new TObjectProcedure<IElementType>() {
|
||||
public boolean execute(IElementType iElementType) {
|
||||
if (iElementType.toString().equals(name)) {
|
||||
ref.set(iElementType);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
});
|
||||
return ref.get();
|
||||
}
|
||||
|
||||
private static final IElementType WS = get(CompactSyntaxConstants.WS);
|
||||
public static final TokenSet WHITESPACE = TokenSet.create(WS);
|
||||
|
||||
public static final IElementType ILLEGAL_CHAR = get(CompactSyntaxConstants.ILLEGAL_CHAR);
|
||||
|
||||
public static final IElementType LBRACE = get("{");
|
||||
public static final IElementType RBRACE = get("}");
|
||||
public static final IElementType LBRACKET = get("[");
|
||||
public static final IElementType RBRACKET = get("]");
|
||||
public static final IElementType LPAREN = get("(");
|
||||
public static final IElementType RPAREN = get(")");
|
||||
|
||||
public static final IElementType GTGT = get(CompactSyntaxConstants.FANNOTATE);
|
||||
|
||||
public static final TokenSet BRACES = TokenSet.create(LBRACE, RBRACE);
|
||||
|
||||
public static final IElementType EQ = get("=");
|
||||
public static final IElementType PLUS = get("+");
|
||||
public static final IElementType MINUS = get("-");
|
||||
public static final IElementType STAR = get("*");
|
||||
public static final IElementType AND = get("&");
|
||||
public static final IElementType PIPE = get("|");
|
||||
public static final IElementType QUEST = get("?");
|
||||
|
||||
public static final IElementType PREFIXED_NAME = get(CompactSyntaxConstants.PREFIXED_NAME);
|
||||
public static final IElementType PREFIXED_STAR = get(CompactSyntaxConstants.PREFIX_STAR);
|
||||
|
||||
public static final IElementType CHOICE_EQ = get("|=");
|
||||
public static final IElementType INTERLEAVE_EQ = get("&=");
|
||||
|
||||
public static final IElementType COMMA = get(",");
|
||||
|
||||
public static final TokenSet BINARY_OPS = TokenSet.create(
|
||||
COMMA, PIPE, AND
|
||||
);
|
||||
|
||||
public static final TokenSet QUANTIFIER_OPS = TokenSet.create(
|
||||
PLUS, STAR, QUEST
|
||||
);
|
||||
|
||||
public static final IElementType DOC = get(CompactSyntaxConstants.DOCUMENTATION);
|
||||
public static final TokenSet DOC_TOKENS = TokenSet.create(
|
||||
DOC,
|
||||
get(CompactSyntaxConstants.DOCUMENTATION_AFTER_SINGLE_LINE_COMMENT),
|
||||
get(CompactSyntaxConstants.DOCUMENTATION_CONTINUE)
|
||||
);
|
||||
|
||||
public static final IElementType COMMENT = get(CompactSyntaxConstants.SINGLE_LINE_COMMENT);
|
||||
public static final TokenSet COMMENTS = TokenSet.create(
|
||||
COMMENT,
|
||||
get(CompactSyntaxConstants.SINGLE_LINE_COMMENT_CONTINUE)
|
||||
);
|
||||
|
||||
public static final IElementType ESCAPED_IDENTIFIER = get(CompactSyntaxConstants.ESCAPED_IDENTIFIER);
|
||||
public static final TokenSet IDENTIFIERS = TokenSet.create(
|
||||
get(CompactSyntaxConstants.IDENTIFIER),
|
||||
ESCAPED_IDENTIFIER
|
||||
);
|
||||
|
||||
public static final TokenSet OPERATORS = TokenSet.orSet(TokenSet.create(
|
||||
CHOICE_EQ, INTERLEAVE_EQ), BINARY_OPS, QUANTIFIER_OPS);
|
||||
|
||||
public static final IElementType LITERAL = get(CompactSyntaxConstants.LITERAL);
|
||||
public static final TokenSet STRINGS = TokenSet.create(LITERAL);
|
||||
|
||||
static final TokenSet READABLE_TEXT = TokenSet.orSet(
|
||||
DOC_TOKENS, COMMENTS,
|
||||
TokenSet.create(LITERAL));
|
||||
|
||||
public static final IElementType KEYWORD_ElEMENT = get("KEYWORD_ELEMENT");
|
||||
public static final IElementType KEYWORD_ATTRIBUTE = get("KEYWORD_ATTRIBUTE");
|
||||
public static final IElementType KEYWORD_NAMESPACE = get("KEYWORD_NAMESPACE");
|
||||
public static final IElementType KEYWORD_LIST = get("KEYWORD_LIST");
|
||||
public static final IElementType KEYWORD_MIXED = get("KEYWORD_MIXED");
|
||||
public static final IElementType KEYWORD_EMPTY = get("KEYWORD_EMPTY");
|
||||
public static final IElementType KEYWORD_GRAMMAR = get("KEYWORD_GRAMMAR");
|
||||
public static final IElementType KEYWORD_TEXT = get("KEYWORD_TEXT");
|
||||
public static final IElementType KEYWORD_PARENT = get("KEYWORD_PARENT");
|
||||
public static final IElementType KEYWORD_EXTERNAL = get("KEYWORD_LIST");
|
||||
public static final IElementType KEYWORD_NOT_ALLOWED = get("KEYWORD_NOTALLOWED");
|
||||
public static final IElementType KEYWORD_START = get("KEYWORD_START");
|
||||
public static final IElementType KEYWORD_INCLUDE = get("KEYWORD_INCLUDE");
|
||||
public static final IElementType KEYWORD_DEFAULT = get("KEYWORD_DEFAULT");
|
||||
public static final IElementType KEYWORD_INHERIT = get("KEYWORD_INHERIT");
|
||||
public static final IElementType KEYWORD_STRING = get("KEYWORD_STRING");
|
||||
public static final IElementType KEYWORD_TOKEN = get("KEYWORD_TOKEN");
|
||||
public static final IElementType KEYWORD_DATATYPES = get("KEYWORD_DATATYPES");
|
||||
public static final IElementType KEYWORD_DIV = get("KEYWORD_DIV");
|
||||
|
||||
public static final TokenSet KEYWORDS = TokenSet.create(
|
||||
KEYWORD_ATTRIBUTE,
|
||||
KEYWORD_DATATYPES,
|
||||
KEYWORD_DEFAULT,
|
||||
KEYWORD_DIV,
|
||||
KEYWORD_ElEMENT,
|
||||
KEYWORD_EMPTY,
|
||||
KEYWORD_EXTERNAL,
|
||||
KEYWORD_GRAMMAR,
|
||||
KEYWORD_INCLUDE,
|
||||
KEYWORD_INHERIT,
|
||||
KEYWORD_LIST,
|
||||
KEYWORD_MIXED,
|
||||
KEYWORD_NAMESPACE,
|
||||
KEYWORD_NOT_ALLOWED,
|
||||
KEYWORD_PARENT,
|
||||
KEYWORD_START,
|
||||
KEYWORD_STRING,
|
||||
KEYWORD_TEXT,
|
||||
KEYWORD_TOKEN
|
||||
);
|
||||
|
||||
public static final TokenSet IDENTIFIER_OR_KEYWORD = TokenSet.orSet(KEYWORDS, IDENTIFIERS);
|
||||
}
|
||||
@@ -0,0 +1,164 @@
|
||||
/*
|
||||
* Copyright 2007 Sascha Weinreuter
|
||||
*
|
||||
* 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.intellij.plugins.relaxNG.compact;
|
||||
|
||||
import org.intellij.plugins.relaxNG.compact.psi.RncDefine;
|
||||
import org.intellij.plugins.relaxNG.compact.psi.RncElement;
|
||||
import org.intellij.plugins.relaxNG.compact.psi.util.EscapeUtil;
|
||||
import org.intellij.plugins.relaxNG.compact.psi.util.RenameUtil;
|
||||
|
||||
import com.intellij.lang.BracePair;
|
||||
import com.intellij.lang.Commenter;
|
||||
import com.intellij.lang.Language;
|
||||
import com.intellij.lang.PairedBraceMatcher;
|
||||
import com.intellij.lang.documentation.DocumentationProvider;
|
||||
import com.intellij.lang.refactoring.NamesValidator;
|
||||
import com.intellij.openapi.fileTypes.SingleLazyInstanceSyntaxHighlighterFactory;
|
||||
import com.intellij.openapi.fileTypes.SyntaxHighlighter;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.tree.IElementType;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/*
|
||||
* Created by IntelliJ IDEA.
|
||||
* User: sweinreuter
|
||||
* Date: 01.08.2007
|
||||
*/
|
||||
public class RngCompactLanguage extends Language {
|
||||
public static final String ID = "RELAX-NG";
|
||||
|
||||
public static final RngCompactLanguage INSTANCE = new RngCompactLanguage();
|
||||
|
||||
private RngCompactLanguage() {
|
||||
super(ID);
|
||||
}
|
||||
|
||||
public static class MyCommenter implements Commenter {
|
||||
@Nullable
|
||||
public String getLineCommentPrefix() {
|
||||
return "#";
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public String getBlockCommentPrefix() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public String getBlockCommentSuffix() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public String getCommentedBlockCommentPrefix() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public String getCommentedBlockCommentSuffix() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static class MyPairedBraceMatcher implements PairedBraceMatcher {
|
||||
private BracePair[] myBracePairs;
|
||||
|
||||
public BracePair[] getPairs() {
|
||||
if (myBracePairs == null) {
|
||||
myBracePairs = new BracePair[]{
|
||||
new BracePair(RncTokenTypes.LBRACE, RncTokenTypes.RBRACE, true),
|
||||
new BracePair(RncTokenTypes.LPAREN, RncTokenTypes.RPAREN, false),
|
||||
new BracePair(RncTokenTypes.LBRACKET, RncTokenTypes.RBRACKET, false),
|
||||
};
|
||||
}
|
||||
return myBracePairs;
|
||||
}
|
||||
|
||||
public boolean isPairedBracesAllowedBeforeType(@NotNull IElementType lbraceType, @Nullable IElementType contextType) {
|
||||
return false;
|
||||
}
|
||||
|
||||
public int getCodeConstructStart(PsiFile file, int openingBraceOffset) {
|
||||
// TODO
|
||||
return openingBraceOffset;
|
||||
}
|
||||
}
|
||||
|
||||
public static class MyNamesValidator implements NamesValidator {
|
||||
public boolean isKeyword(String name, Project project) {
|
||||
return RenameUtil.isKeyword(PsiManager.getInstance(project), name);
|
||||
}
|
||||
|
||||
public boolean isIdentifier(String name, Project project) {
|
||||
return RenameUtil.isIdentifier(PsiManager.getInstance(project), name);
|
||||
}
|
||||
}
|
||||
|
||||
public static class MyDocumentationProvider implements DocumentationProvider {
|
||||
@Nullable
|
||||
public String getQuickNavigateInfo(PsiElement element) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public List<String> getUrlFor(PsiElement element, PsiElement originalElement) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public String generateDoc(PsiElement element, PsiElement originalElement) {
|
||||
if (element instanceof RncElement) {
|
||||
PsiElement comment = element.getPrevSibling();
|
||||
while (comment instanceof PsiWhiteSpace) {
|
||||
comment = comment.getPrevSibling();
|
||||
}
|
||||
if (comment instanceof PsiComment) {
|
||||
final StringBuilder sb = new StringBuilder();
|
||||
do {
|
||||
sb.insert(0, EscapeUtil.unescapeText(comment).replaceAll("\n?##?", "") + "<br>");
|
||||
comment = comment.getPrevSibling();
|
||||
} while (comment instanceof PsiComment);
|
||||
|
||||
if (element instanceof RncDefine) {
|
||||
sb.insert(0, "Define: <b>" + ((RncDefine)element).getName() + "</b><br>");
|
||||
}
|
||||
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public PsiElement getDocumentationElementForLookupItem(PsiManager psiManager, Object object, PsiElement element) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public PsiElement getDocumentationElementForLink(PsiManager psiManager, String link, PsiElement context) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static class MySyntaxHighlighterFactory extends SingleLazyInstanceSyntaxHighlighterFactory {
|
||||
@NotNull
|
||||
protected SyntaxHighlighter createHighlighter() {
|
||||
return new RncHighlighter();
|
||||
}
|
||||
}
|
||||
}
|
||||
+158
@@ -0,0 +1,158 @@
|
||||
/*
|
||||
* Copyright 2007 Sascha Weinreuter
|
||||
*
|
||||
* 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.intellij.plugins.relaxNG.compact.folding;
|
||||
|
||||
import org.intellij.plugins.relaxNG.compact.RncElementTypes;
|
||||
import org.intellij.plugins.relaxNG.compact.RncTokenTypes;
|
||||
import org.intellij.plugins.relaxNG.compact.psi.RncAnnotation;
|
||||
import org.intellij.plugins.relaxNG.compact.psi.RncName;
|
||||
import org.intellij.plugins.relaxNG.compact.psi.util.EscapeUtil;
|
||||
|
||||
import com.intellij.codeInsight.folding.CodeFoldingSettings;
|
||||
import com.intellij.lang.ASTNode;
|
||||
import com.intellij.lang.folding.FoldingBuilder;
|
||||
import com.intellij.lang.folding.FoldingDescriptor;
|
||||
import com.intellij.openapi.editor.Document;
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
import com.intellij.psi.PsiWhiteSpace;
|
||||
import com.intellij.psi.tree.IElementType;
|
||||
import com.intellij.psi.tree.TokenSet;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
/**
|
||||
* Created by IntelliJ IDEA.
|
||||
* User: sweinreuter
|
||||
* Date: 10.08.2007
|
||||
*/
|
||||
public class RncFoldingBuilder implements FoldingBuilder {
|
||||
@NotNull
|
||||
public FoldingDescriptor[] buildFoldRegions(@NotNull ASTNode node, @NotNull Document document) {
|
||||
|
||||
final ArrayList<FoldingDescriptor> regions = new ArrayList<FoldingDescriptor>();
|
||||
process(node, document, regions);
|
||||
|
||||
return regions.size() > 0
|
||||
? regions.toArray(new FoldingDescriptor[regions.size()])
|
||||
: FoldingDescriptor.EMPTY;
|
||||
}
|
||||
|
||||
public String getPlaceholderText(@NotNull ASTNode node) {
|
||||
final IElementType type = node.getElementType();
|
||||
if (type == RncTokenTypes.LBRACE) {
|
||||
return "{ ... }";
|
||||
} else if (isCommentLike(type)) {
|
||||
return "# ...";
|
||||
} else if (isAnnotation(type)) {
|
||||
final RncName element = ((RncAnnotation)node.getPsi()).getNameElement();
|
||||
if (element != null) {
|
||||
final ASTNode n = element.getNode();
|
||||
assert n != null;
|
||||
return EscapeUtil.unescapeText(n) + " [ ... ]";
|
||||
}
|
||||
return "[ ... ]";
|
||||
} else {
|
||||
return "...";
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean isAnnotation(IElementType type) {
|
||||
return RncElementTypes.ANNOTATION == type || RncElementTypes.ANNOTATION_ELEMENT == type || RncElementTypes.FORWARD_ANNOTATION == type;
|
||||
}
|
||||
|
||||
private static boolean isCommentLike(IElementType type) {
|
||||
return RncTokenTypes.COMMENTS.contains(type) || RncTokenTypes.DOC_TOKENS.contains(type);
|
||||
}
|
||||
|
||||
public boolean isCollapsedByDefault(@NotNull ASTNode node) {
|
||||
return isCommentLike(node.getElementType()) && CodeFoldingSettings.getInstance().COLLAPSE_DOC_COMMENTS;
|
||||
}
|
||||
|
||||
private static void process(@Nullable ASTNode node, Document document, ArrayList<FoldingDescriptor> regions) {
|
||||
if (node == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
final ASTNode[] braces = node.getChildren(RncTokenTypes.BRACES);
|
||||
if (braces.length == 2) {
|
||||
final ASTNode lbrace = braces[0];
|
||||
final ASTNode rbrace = braces[1];
|
||||
if (shouldFold(lbrace, rbrace, document)) {
|
||||
final TextRange range = new TextRange(lbrace.getStartOffset(), rbrace.getTextRange().getEndOffset());
|
||||
regions.add(new FoldingDescriptor(lbrace, range));
|
||||
}
|
||||
} else if (isAnnotation(node.getElementType())) {
|
||||
if (isOnDifferentLine(node.getFirstChildNode(), node.getLastChildNode(), document)) {
|
||||
regions.add(new FoldingDescriptor(node, node.getTextRange()));
|
||||
}
|
||||
}
|
||||
|
||||
node = node.getFirstChildNode();
|
||||
while (node != null) {
|
||||
node = checkNodeAndSiblings(node, RncTokenTypes.DOC_TOKENS, regions, document);
|
||||
|
||||
node = checkNodeAndSiblings(node, RncTokenTypes.COMMENTS, regions, document);
|
||||
|
||||
process(node, document, regions);
|
||||
|
||||
if (node != null) {
|
||||
node = node.getTreeNext();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static ASTNode checkNodeAndSiblings(@Nullable ASTNode node, TokenSet tokens, ArrayList<FoldingDescriptor> regions, Document document) {
|
||||
if (node != null && tokens.contains(node.getElementType())) {
|
||||
final ASTNode start = node;
|
||||
ASTNode end = start;
|
||||
|
||||
node = node.getTreeNext();
|
||||
if (node != null) {
|
||||
do {
|
||||
end = node;
|
||||
node = node.getTreeNext();
|
||||
} while (node != null && tokens.contains(node.getElementType()));
|
||||
}
|
||||
if (end != start) {
|
||||
while (end.getPsi() instanceof PsiWhiteSpace) {
|
||||
end = end.getTreePrev();
|
||||
}
|
||||
if (isOnDifferentLine(start, end, document)) {
|
||||
regions.add(new FoldingDescriptor(start, new TextRange(start.getStartOffset(), end.getTextRange().getEndOffset())));
|
||||
}
|
||||
}
|
||||
}
|
||||
return node;
|
||||
}
|
||||
|
||||
private static boolean shouldFold(ASTNode first, ASTNode second, Document document) {
|
||||
if (first.getElementType() != RncTokenTypes.LBRACE) {
|
||||
return false;
|
||||
} else if (second.getElementType() != RncTokenTypes.RBRACE) {
|
||||
return false;
|
||||
} else {
|
||||
return isOnDifferentLine(first, second, document);
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean isOnDifferentLine(ASTNode first, ASTNode second, Document document) {
|
||||
return document.getLineNumber(first.getStartOffset()) != document.getLineNumber(second.getStartOffset());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,127 @@
|
||||
/*
|
||||
* Copyright 2007 Sascha Weinreuter
|
||||
*
|
||||
* 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.intellij.plugins.relaxNG.compact.formatting;
|
||||
|
||||
import org.intellij.plugins.relaxNG.compact.RncElementTypes;
|
||||
import org.intellij.plugins.relaxNG.compact.RncTokenTypes;
|
||||
import org.intellij.plugins.relaxNG.compact.psi.RncDecl;
|
||||
import org.intellij.plugins.relaxNG.compact.psi.RncDefine;
|
||||
import org.intellij.plugins.relaxNG.compact.psi.RncFile;
|
||||
import org.intellij.plugins.relaxNG.compact.psi.RncGrammar;
|
||||
import org.intellij.plugins.relaxNG.compact.psi.impl.RncDocument;
|
||||
|
||||
import com.intellij.formatting.*;
|
||||
import com.intellij.lang.ASTNode;
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
class RncBlock implements Block {
|
||||
private final ASTNode myNode;
|
||||
|
||||
public RncBlock(ASTNode element) {
|
||||
myNode = element;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public TextRange getTextRange() {
|
||||
return myNode.getTextRange();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public List<Block> getSubBlocks() {
|
||||
final List<Block> list = new ArrayList<Block>();
|
||||
ASTNode node = myNode.getFirstChildNode();
|
||||
while (node != null) {
|
||||
if (!RncTokenTypes.WHITESPACE.contains(node.getElementType()) && node.getTextLength() > 0) {
|
||||
list.add(new RncBlock(node));
|
||||
}
|
||||
node = node.getTreeNext();
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Wrap getWrap() {
|
||||
// TODO
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Indent getIndent() {
|
||||
if (isTopLevel()) {
|
||||
return Indent.getAbsoluteNoneIndent();
|
||||
} else if (myNode.getTreeParent().getPsi() instanceof RncGrammar && !RncTokenTypes.BRACES.contains(myNode.getElementType())) {
|
||||
// TODO: fix block psi
|
||||
return Indent.getNormalIndent();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private boolean isTopLevel() {
|
||||
final PsiElement parent = myNode.getTreeParent().getPsi();
|
||||
return parent instanceof RncDocument ||
|
||||
parent instanceof RncFile ||
|
||||
parent instanceof RncGrammar && parent.getParent() instanceof RncDocument;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Alignment getAlignment() {
|
||||
// TODO
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Spacing getSpacing(Block child1, Block child2) {
|
||||
final ASTNode lnode = ((RncBlock)child1).myNode;
|
||||
final PsiElement lpsi = lnode.getPsi();
|
||||
final PsiElement rpsi = ((RncBlock)child2).myNode.getPsi();
|
||||
|
||||
if (lpsi instanceof RncDecl && rpsi instanceof RncDecl) {
|
||||
return makeNewline();
|
||||
}
|
||||
if ((lpsi instanceof RncDecl || lpsi instanceof RncDefine ||
|
||||
lnode.getElementType() == RncElementTypes.START) &&
|
||||
(rpsi instanceof RncDefine || rpsi instanceof RncGrammar)) {
|
||||
return makeNewline();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static Spacing makeNewline() {
|
||||
return Spacing.createSpacing(0, Integer.MAX_VALUE, 1, true, 100);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public ChildAttributes getChildAttributes(int newChildIndex) {
|
||||
return new ChildAttributes(null, null);
|
||||
}
|
||||
|
||||
public boolean isIncomplete() {
|
||||
// TODO
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean isLeaf() {
|
||||
// TODO
|
||||
return false;
|
||||
}
|
||||
}
|
||||
+39
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* Copyright 2007 Sascha Weinreuter
|
||||
*
|
||||
* 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.intellij.plugins.relaxNG.compact.formatting;
|
||||
|
||||
import com.intellij.formatting.FormattingModel;
|
||||
import com.intellij.formatting.FormattingModelBuilder;
|
||||
import com.intellij.formatting.FormattingModelProvider;
|
||||
import com.intellij.lang.ASTNode;
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.psi.codeStyle.CodeStyleSettings;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class RncFormattingModelBuilder implements FormattingModelBuilder {
|
||||
@NotNull
|
||||
public FormattingModel createModel(PsiElement element, CodeStyleSettings settings) {
|
||||
return FormattingModelProvider.createFormattingModelForPsiFile(element.getContainingFile(), new RncBlock(element.getNode()), settings);
|
||||
}
|
||||
|
||||
public TextRange getRangeAffectingIndent(PsiFile file, int offset, ASTNode elementAtOffset) {
|
||||
// TODO
|
||||
return null;
|
||||
}
|
||||
}
|
||||
+258
@@ -0,0 +1,258 @@
|
||||
/*
|
||||
* Copyright 2007 Sascha Weinreuter
|
||||
*
|
||||
* 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.intellij.plugins.relaxNG.compact.lexer;
|
||||
|
||||
import org.intellij.plugins.relaxNG.compact.RncTokenTypes;
|
||||
|
||||
import com.intellij.lexer.LexerBase;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.util.io.FileUtil;
|
||||
import com.intellij.psi.TokenType;
|
||||
import com.intellij.psi.tree.IElementType;
|
||||
import com.intellij.util.text.CharArrayCharSequence;
|
||||
import com.intellij.util.text.CharArrayUtil;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import gnu.trove.TIntIntHashMap;
|
||||
import org.kohsuke.rngom.parse.compact.CompactSyntaxConstants;
|
||||
import org.kohsuke.rngom.parse.compact.CompactSyntaxTokenManager;
|
||||
import org.kohsuke.rngom.parse.compact.Token;
|
||||
import org.kohsuke.rngom.parse.compact.TokenMgrError;
|
||||
|
||||
import java.io.CharArrayReader;
|
||||
import java.io.FileReader;
|
||||
import java.io.IOException;
|
||||
import java.io.Reader;
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.LinkedList;
|
||||
|
||||
/**
|
||||
* An adapter to use the lexer ("TokenManager") generated from a javacc grammar.
|
||||
*
|
||||
* Not sure if it was easier to write this than hacking my own lexer...
|
||||
*/
|
||||
public class CompactSyntaxLexerAdapter extends LexerBase {
|
||||
private static final Logger LOG = Logger.getInstance(CompactSyntaxLexerAdapter.class.getName());
|
||||
|
||||
private static final Field myStateField;
|
||||
|
||||
static {
|
||||
try {
|
||||
myStateField = CompactSyntaxTokenManager.class.getDeclaredField("curLexState");
|
||||
myStateField.setAccessible(true);
|
||||
} catch (NoSuchFieldException e) {
|
||||
throw new Error(e);
|
||||
}
|
||||
}
|
||||
|
||||
private static final Token START = new Token();
|
||||
|
||||
private CompactSyntaxTokenManager myLexer;
|
||||
private final LinkedList<Token> myTokenQueue = new LinkedList<Token>();
|
||||
private Token myCurrentToken;
|
||||
private int myCurrentOffset;
|
||||
private int myCurrentEnd;
|
||||
|
||||
private IElementType myCurrentTokenType;
|
||||
private CharSequence myBuffer;
|
||||
private int myEndOffset;
|
||||
private TIntIntHashMap myLengthMap;
|
||||
|
||||
public void advance() {
|
||||
try {
|
||||
myCurrentToken = nextToken();
|
||||
myCurrentOffset = myCurrentEnd;
|
||||
|
||||
if (myCurrentToken != null) {
|
||||
|
||||
myCurrentEnd = myCurrentOffset + myCurrentToken.image.length();
|
||||
for (int i = myCurrentOffset; i < myCurrentEnd; i++) {
|
||||
myCurrentEnd += myLengthMap.get(i);
|
||||
}
|
||||
|
||||
if (myCurrentToken.kind == CompactSyntaxConstants.EOF) {
|
||||
assert myCurrentOffset == myEndOffset : "actual: " + myCurrentOffset + ", expected: " + myEndOffset;
|
||||
myCurrentToken = null;
|
||||
}
|
||||
}
|
||||
|
||||
// if (myCurrentToken != null) {
|
||||
// System.out.println("token = <" + RncTokenTypes.get(myCurrentToken.kind).toString() + "> [" + myCurrentToken.image + "]");
|
||||
// }
|
||||
} catch (TokenMgrError e) {
|
||||
LOG.error(e);
|
||||
myCurrentToken = null;
|
||||
}
|
||||
|
||||
if (myCurrentToken == null) {
|
||||
myCurrentTokenType = null;
|
||||
} else {
|
||||
myCurrentTokenType = RncTokenTypes.get(myCurrentToken.kind);
|
||||
|
||||
// collapse whitespace tokens into TokenType.WHITE_SPACE [IDEA-12106]
|
||||
if (RncTokenTypes.WHITESPACE.contains(myCurrentTokenType)) {
|
||||
myCurrentTokenType = TokenType.WHITE_SPACE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private Token nextToken() {
|
||||
if (myTokenQueue.size() > 0) {
|
||||
return myTokenQueue.removeFirst();
|
||||
}
|
||||
|
||||
final Token t = myLexer.getNextToken();
|
||||
if (t.specialToken != null) {
|
||||
myTokenQueue.addFirst(t);
|
||||
for (Token s = t.specialToken; s != null; s = s.specialToken) {
|
||||
myTokenQueue.addFirst(s);
|
||||
}
|
||||
return myTokenQueue.removeFirst();
|
||||
} else {
|
||||
return t;
|
||||
}
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public char[] getBuffer() {
|
||||
return CharArrayUtil.fromSequence(myBuffer);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CharSequence getBufferSequence() {
|
||||
return myBuffer;
|
||||
}
|
||||
|
||||
public int getBufferEnd() {
|
||||
return myEndOffset;
|
||||
}
|
||||
|
||||
public int getState() {
|
||||
try {
|
||||
return (Integer)myStateField.get(myLexer);
|
||||
} catch (Exception e) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
public int getTokenEnd() {
|
||||
return myCurrentEnd;
|
||||
}
|
||||
|
||||
public int getTokenStart() {
|
||||
return myCurrentToken == null ? 0 : myCurrentOffset;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public IElementType getTokenType() {
|
||||
if (myCurrentToken == null) {
|
||||
return null;
|
||||
} else {
|
||||
return myCurrentTokenType;
|
||||
}
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public void start(char[] buffer, int startOffset, int endOffset, int initialState) {
|
||||
myBuffer = new CharArrayCharSequence(buffer, startOffset, endOffset);
|
||||
|
||||
final CharArrayReader reader = new CharArrayReader(buffer, startOffset, endOffset - startOffset);
|
||||
init(startOffset, endOffset, reader, initialState);
|
||||
}
|
||||
|
||||
public void start(CharSequence buffer, int startOffset, int endOffset, int initialState) {
|
||||
myBuffer = buffer;
|
||||
|
||||
final Reader reader = new CharSequenceReader(buffer, startOffset, endOffset);
|
||||
init(startOffset, endOffset, reader, initialState);
|
||||
}
|
||||
|
||||
private void init(int startOffset, int endOffset, Reader reader, int initialState) {
|
||||
myEndOffset = endOffset;
|
||||
myLengthMap = new TIntIntHashMap();
|
||||
|
||||
final EscapePreprocessor preprocessor = new EscapePreprocessor(reader, startOffset, myLengthMap);
|
||||
myLexer = new CompactSyntaxTokenManager(new SimpleCharStream(preprocessor, 1, 1), initialState);
|
||||
|
||||
myCurrentToken = START;
|
||||
myCurrentOffset = startOffset;
|
||||
myCurrentEnd = startOffset;
|
||||
myTokenQueue.clear();
|
||||
advance();
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws IOException {
|
||||
final CompactSyntaxLexerAdapter lexer = new CompactSyntaxLexerAdapter();
|
||||
lexer.start(new CharArrayCharSequence(FileUtil.adaptiveLoadText(new FileReader(args[0]))));
|
||||
while (lexer.getTokenType() != null) {
|
||||
System.out.println("token = " + lexer.getTokenType());
|
||||
final int start = lexer.getTokenStart();
|
||||
System.out.println("start = " + start);
|
||||
final int end = lexer.getTokenEnd();
|
||||
System.out.println("end = " + end);
|
||||
final CharSequence t = lexer.getBufferSequence().subSequence(start, end);
|
||||
System.out.println("t = " + t);
|
||||
lexer.advance();
|
||||
}
|
||||
}
|
||||
|
||||
// adapted from com.intellij.util.text.CharSequenceReader with start- and endOffset support
|
||||
static class CharSequenceReader extends Reader {
|
||||
private final CharSequence myText;
|
||||
private final int myEndOffset;
|
||||
private int myCurPos;
|
||||
|
||||
public CharSequenceReader(final CharSequence text, int startOffset, int endOffset) {
|
||||
myText = text;
|
||||
myEndOffset = endOffset;
|
||||
myCurPos = startOffset;
|
||||
}
|
||||
|
||||
public void close() {
|
||||
}
|
||||
|
||||
public int read(char[] cbuf, int off, int len) {
|
||||
if ((off < 0) || (off > cbuf.length) || (len < 0) || ((off + len) > cbuf.length) || ((off + len) < 0)) {
|
||||
throw new IndexOutOfBoundsException();
|
||||
} else if (len == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (myText instanceof CharArrayCharSequence) { // Optimization
|
||||
final int readChars = ((CharArrayCharSequence)myText).readCharsTo(myCurPos, cbuf, off, len);
|
||||
if (readChars < 0) return -1;
|
||||
myCurPos += readChars;
|
||||
return readChars;
|
||||
}
|
||||
|
||||
int charsToCopy = Math.min(len, myEndOffset - myCurPos);
|
||||
if (charsToCopy <= 0) return -1;
|
||||
|
||||
for (int n = 0; n < charsToCopy; n++) {
|
||||
cbuf[n + off] = myText.charAt(n + myCurPos);
|
||||
}
|
||||
|
||||
myCurPos += charsToCopy;
|
||||
return charsToCopy;
|
||||
}
|
||||
|
||||
public int read() {
|
||||
if (myCurPos >= myEndOffset) return -1;
|
||||
return myText.charAt(myCurPos++);
|
||||
}
|
||||
}
|
||||
}
|
||||
+140
@@ -0,0 +1,140 @@
|
||||
/*
|
||||
* Copyright 2007 Sascha Weinreuter
|
||||
*
|
||||
* 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.intellij.plugins.relaxNG.compact.lexer;
|
||||
|
||||
import gnu.trove.TIntArrayList;
|
||||
import gnu.trove.TIntIntHashMap;
|
||||
import org.kohsuke.rngom.util.Utf16;
|
||||
|
||||
import java.io.FilterReader;
|
||||
import java.io.IOException;
|
||||
import java.io.Reader;
|
||||
|
||||
/**
|
||||
* A reader that deals with escape sequences in RNC files (\x{xx}) and keeps track of their positions to build correct
|
||||
* token ranges in the lexer.
|
||||
* <p/>
|
||||
* Created by IntelliJ IDEA.
|
||||
* User: sweinreuter
|
||||
* Date: 05.08.2007
|
||||
*/
|
||||
class EscapePreprocessor extends FilterReader {
|
||||
private final TIntArrayList myQueuedChars;
|
||||
private final TIntIntHashMap myLengthMap;
|
||||
|
||||
private int myOffset;
|
||||
|
||||
public EscapePreprocessor(Reader reader, int startOffset, TIntIntHashMap map) {
|
||||
super(reader);
|
||||
myOffset = startOffset;
|
||||
myQueuedChars = new TIntArrayList();
|
||||
myLengthMap = map;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int read(char cbuf[], int off, int len) throws IOException {
|
||||
final int i = read();
|
||||
if (i == -1) {
|
||||
return -1;
|
||||
}
|
||||
cbuf[off] = (char)i; // not really efficient, but acceptable since we're usually not having to deal with megabytes of RNC files...
|
||||
return 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int read() throws IOException {
|
||||
if (myQueuedChars.size() > 0) {
|
||||
return consume();
|
||||
}
|
||||
final int i = super.read();
|
||||
if (i == -1) {
|
||||
return -1;
|
||||
}
|
||||
myOffset++;
|
||||
|
||||
switch (i) {
|
||||
case '\r':
|
||||
assert false : "Unexpected newline character"; // IDEA document's are supposed to newlines normalized to \n
|
||||
if (peek() == '\n') {
|
||||
consume();
|
||||
myLengthMap.put(myOffset - 1, 2);
|
||||
}
|
||||
case '\n':
|
||||
return '\u0000';
|
||||
|
||||
case '\\':
|
||||
int n = 0;
|
||||
int x;
|
||||
while ((x = peek()) == 'x') {
|
||||
n++;
|
||||
}
|
||||
if (n > 0 && x == '{') {
|
||||
n++;
|
||||
} else {
|
||||
return i;
|
||||
}
|
||||
int value = 0;
|
||||
while (isHexChar((char)(x = peek()))) {
|
||||
n++;
|
||||
value <<= 4;
|
||||
value |= Character.digit(x, 16);
|
||||
}
|
||||
if (x == '}') {
|
||||
n++;
|
||||
}
|
||||
consume(n);
|
||||
|
||||
myLengthMap.put(myOffset - 1, n);
|
||||
myOffset += n;
|
||||
|
||||
if (value <= 0xFFFF) {
|
||||
return value;
|
||||
}
|
||||
|
||||
myQueuedChars.add(Utf16.surrogate2(value));
|
||||
return Utf16.surrogate1(value);
|
||||
}
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
private static boolean isHexChar(char i) {
|
||||
if (Character.isDigit(i)) return true;
|
||||
final char c = Character.toLowerCase(i);
|
||||
return c >= 'a' && c <= 'f';
|
||||
}
|
||||
|
||||
private int consume() {
|
||||
if (myQueuedChars.size() > 0) {
|
||||
return myQueuedChars.remove(0);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
private void consume(int n) {
|
||||
myQueuedChars.remove(0, n);
|
||||
}
|
||||
|
||||
private int peek() throws IOException {
|
||||
final int i = super.read();
|
||||
if (i == -1) {
|
||||
return -1;
|
||||
}
|
||||
myQueuedChars.add(i);
|
||||
return i;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,420 @@
|
||||
/*
|
||||
* Copyright 2007 Sascha Weinreuter
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/* Generated By:JavaCC: Do not edit this line. SimpleCharStream.java Version 3.0 */
|
||||
package org.intellij.plugins.relaxNG.compact.lexer;
|
||||
|
||||
import org.kohsuke.rngom.parse.compact.CharStream;
|
||||
import org.kohsuke.rngom.parse.compact.EOFException;
|
||||
|
||||
/**
|
||||
* An implementation of interface CharStream, where the stream is assumed to
|
||||
* contain only ASCII characters (without unicode processing).
|
||||
*/
|
||||
|
||||
@SuppressWarnings({ "ALL" })
|
||||
public class SimpleCharStream implements CharStream
|
||||
{
|
||||
int bufsize;
|
||||
int available;
|
||||
int tokenBegin;
|
||||
public int bufpos = -1;
|
||||
protected int bufline[];
|
||||
protected int bufcolumn[];
|
||||
|
||||
protected int column = 0;
|
||||
protected int line = 1;
|
||||
|
||||
protected boolean prevCharIsCR = false;
|
||||
protected boolean prevCharIsLF = false;
|
||||
|
||||
protected java.io.Reader inputStream;
|
||||
|
||||
protected char[] buffer;
|
||||
protected int maxNextCharInd = 0;
|
||||
protected int inBuf = 0;
|
||||
|
||||
protected void ExpandBuff(boolean wrapAround)
|
||||
{
|
||||
char[] newbuffer = new char[bufsize + 2048];
|
||||
int newbufline[] = new int[bufsize + 2048];
|
||||
int newbufcolumn[] = new int[bufsize + 2048];
|
||||
|
||||
try
|
||||
{
|
||||
if (wrapAround)
|
||||
{
|
||||
System.arraycopy(buffer, tokenBegin, newbuffer, 0, bufsize - tokenBegin);
|
||||
System.arraycopy(buffer, 0, newbuffer,
|
||||
bufsize - tokenBegin, bufpos);
|
||||
buffer = newbuffer;
|
||||
|
||||
System.arraycopy(bufline, tokenBegin, newbufline, 0, bufsize - tokenBegin);
|
||||
System.arraycopy(bufline, 0, newbufline, bufsize - tokenBegin, bufpos);
|
||||
bufline = newbufline;
|
||||
|
||||
System.arraycopy(bufcolumn, tokenBegin, newbufcolumn, 0, bufsize - tokenBegin);
|
||||
System.arraycopy(bufcolumn, 0, newbufcolumn, bufsize - tokenBegin, bufpos);
|
||||
bufcolumn = newbufcolumn;
|
||||
|
||||
maxNextCharInd = (bufpos += (bufsize - tokenBegin));
|
||||
}
|
||||
else
|
||||
{
|
||||
System.arraycopy(buffer, tokenBegin, newbuffer, 0, bufsize - tokenBegin);
|
||||
buffer = newbuffer;
|
||||
|
||||
System.arraycopy(bufline, tokenBegin, newbufline, 0, bufsize - tokenBegin);
|
||||
bufline = newbufline;
|
||||
|
||||
System.arraycopy(bufcolumn, tokenBegin, newbufcolumn, 0, bufsize - tokenBegin);
|
||||
bufcolumn = newbufcolumn;
|
||||
|
||||
maxNextCharInd = (bufpos -= tokenBegin);
|
||||
}
|
||||
}
|
||||
catch (Throwable t)
|
||||
{
|
||||
throw new Error(t.getMessage());
|
||||
}
|
||||
|
||||
|
||||
bufsize += 2048;
|
||||
available = bufsize;
|
||||
tokenBegin = 0;
|
||||
}
|
||||
|
||||
protected void FillBuff() throws EOFException
|
||||
{
|
||||
if (maxNextCharInd == available)
|
||||
{
|
||||
if (available == bufsize)
|
||||
{
|
||||
if (tokenBegin > 2048)
|
||||
{
|
||||
bufpos = maxNextCharInd = 0;
|
||||
available = tokenBegin;
|
||||
}
|
||||
else if (tokenBegin < 0)
|
||||
bufpos = maxNextCharInd = 0;
|
||||
else
|
||||
ExpandBuff(false);
|
||||
}
|
||||
else if (available > tokenBegin)
|
||||
available = bufsize;
|
||||
else if ((tokenBegin - available) < 2048)
|
||||
ExpandBuff(true);
|
||||
else
|
||||
available = tokenBegin;
|
||||
}
|
||||
|
||||
int i;
|
||||
try {
|
||||
if ((i = inputStream.read(buffer, maxNextCharInd,
|
||||
available - maxNextCharInd)) == -1)
|
||||
{
|
||||
inputStream.close();
|
||||
throw new java.io.IOException();
|
||||
}
|
||||
else
|
||||
maxNextCharInd += i;
|
||||
return;
|
||||
}
|
||||
catch(java.io.IOException e) {
|
||||
--bufpos;
|
||||
backup(0);
|
||||
if (tokenBegin == -1)
|
||||
tokenBegin = bufpos;
|
||||
throw new EOFException();
|
||||
}
|
||||
}
|
||||
|
||||
public char BeginToken() throws EOFException
|
||||
{
|
||||
tokenBegin = -1;
|
||||
char c = readChar();
|
||||
tokenBegin = bufpos;
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
protected void UpdateLineColumn(char c)
|
||||
{
|
||||
column++;
|
||||
|
||||
if (prevCharIsLF)
|
||||
{
|
||||
prevCharIsLF = false;
|
||||
line += (column = 1);
|
||||
}
|
||||
else if (prevCharIsCR)
|
||||
{
|
||||
prevCharIsCR = false;
|
||||
if (c == '\n')
|
||||
{
|
||||
prevCharIsLF = true;
|
||||
}
|
||||
else
|
||||
line += (column = 1);
|
||||
}
|
||||
|
||||
switch (c)
|
||||
{
|
||||
case '\r' :
|
||||
prevCharIsCR = true;
|
||||
break;
|
||||
case '\n' :
|
||||
prevCharIsLF = true;
|
||||
break;
|
||||
case '\t' :
|
||||
column--;
|
||||
column += (8 - (column & 07));
|
||||
break;
|
||||
default :
|
||||
break;
|
||||
}
|
||||
|
||||
bufline[bufpos] = line;
|
||||
bufcolumn[bufpos] = column;
|
||||
}
|
||||
|
||||
public char readChar() throws EOFException
|
||||
{
|
||||
if (inBuf > 0)
|
||||
{
|
||||
--inBuf;
|
||||
|
||||
if (++bufpos == bufsize)
|
||||
bufpos = 0;
|
||||
|
||||
return buffer[bufpos];
|
||||
}
|
||||
|
||||
if (++bufpos >= maxNextCharInd)
|
||||
FillBuff();
|
||||
|
||||
char c = buffer[bufpos];
|
||||
|
||||
UpdateLineColumn(c);
|
||||
return (c);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
* @see #getEndColumn
|
||||
*/
|
||||
|
||||
public int getColumn() {
|
||||
return bufcolumn[bufpos];
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
* @see #getEndLine
|
||||
*/
|
||||
|
||||
public int getLine() {
|
||||
return bufline[bufpos];
|
||||
}
|
||||
|
||||
public int getEndColumn() {
|
||||
return bufcolumn[bufpos];
|
||||
}
|
||||
|
||||
public int getEndLine() {
|
||||
return bufline[bufpos];
|
||||
}
|
||||
|
||||
public int getBeginColumn() {
|
||||
return bufcolumn[tokenBegin];
|
||||
}
|
||||
|
||||
public int getBeginLine() {
|
||||
return bufline[tokenBegin];
|
||||
}
|
||||
|
||||
public void backup(int amount) {
|
||||
|
||||
inBuf += amount;
|
||||
if ((bufpos -= amount) < 0)
|
||||
bufpos += bufsize;
|
||||
}
|
||||
|
||||
public SimpleCharStream(java.io.Reader dstream, int startline,
|
||||
int startcolumn, int buffersize)
|
||||
{
|
||||
inputStream = dstream;
|
||||
line = startline;
|
||||
column = startcolumn - 1;
|
||||
|
||||
available = bufsize = buffersize;
|
||||
buffer = new char[buffersize];
|
||||
bufline = new int[buffersize];
|
||||
bufcolumn = new int[buffersize];
|
||||
}
|
||||
|
||||
public SimpleCharStream(java.io.Reader dstream, int startline,
|
||||
int startcolumn)
|
||||
{
|
||||
this(dstream, startline, startcolumn, 4096);
|
||||
}
|
||||
|
||||
public SimpleCharStream(java.io.Reader dstream)
|
||||
{
|
||||
this(dstream, 1, 1, 4096);
|
||||
}
|
||||
public void ReInit(java.io.Reader dstream, int startline,
|
||||
int startcolumn, int buffersize)
|
||||
{
|
||||
inputStream = dstream;
|
||||
line = startline;
|
||||
column = startcolumn - 1;
|
||||
|
||||
if (buffer == null || buffersize != buffer.length)
|
||||
{
|
||||
available = bufsize = buffersize;
|
||||
buffer = new char[buffersize];
|
||||
bufline = new int[buffersize];
|
||||
bufcolumn = new int[buffersize];
|
||||
}
|
||||
prevCharIsLF = prevCharIsCR = false;
|
||||
tokenBegin = inBuf = maxNextCharInd = 0;
|
||||
bufpos = -1;
|
||||
}
|
||||
|
||||
public void ReInit(java.io.Reader dstream, int startline,
|
||||
int startcolumn)
|
||||
{
|
||||
ReInit(dstream, startline, startcolumn, 4096);
|
||||
}
|
||||
|
||||
public void ReInit(java.io.Reader dstream)
|
||||
{
|
||||
ReInit(dstream, 1, 1, 4096);
|
||||
}
|
||||
public SimpleCharStream(java.io.InputStream dstream, int startline,
|
||||
int startcolumn, int buffersize)
|
||||
{
|
||||
this(new java.io.InputStreamReader(dstream), startline, startcolumn, 4096);
|
||||
}
|
||||
|
||||
public SimpleCharStream(java.io.InputStream dstream, int startline,
|
||||
int startcolumn)
|
||||
{
|
||||
this(dstream, startline, startcolumn, 4096);
|
||||
}
|
||||
|
||||
public SimpleCharStream(java.io.InputStream dstream)
|
||||
{
|
||||
this(dstream, 1, 1, 4096);
|
||||
}
|
||||
|
||||
public void ReInit(java.io.InputStream dstream, int startline,
|
||||
int startcolumn, int buffersize)
|
||||
{
|
||||
ReInit(new java.io.InputStreamReader(dstream), startline, startcolumn, 4096);
|
||||
}
|
||||
|
||||
public void ReInit(java.io.InputStream dstream)
|
||||
{
|
||||
ReInit(dstream, 1, 1, 4096);
|
||||
}
|
||||
public void ReInit(java.io.InputStream dstream, int startline,
|
||||
int startcolumn)
|
||||
{
|
||||
ReInit(dstream, startline, startcolumn, 4096);
|
||||
}
|
||||
public String GetImage()
|
||||
{
|
||||
if (bufpos >= tokenBegin)
|
||||
return new String(buffer, tokenBegin, bufpos - tokenBegin + 1);
|
||||
else
|
||||
return new String(buffer, tokenBegin, bufsize - tokenBegin) +
|
||||
new String(buffer, 0, bufpos + 1);
|
||||
}
|
||||
|
||||
public char[] GetSuffix(int len)
|
||||
{
|
||||
char[] ret = new char[len];
|
||||
|
||||
if ((bufpos + 1) >= len)
|
||||
System.arraycopy(buffer, bufpos - len + 1, ret, 0, len);
|
||||
else
|
||||
{
|
||||
System.arraycopy(buffer, bufsize - (len - bufpos - 1), ret, 0,
|
||||
len - bufpos - 1);
|
||||
System.arraycopy(buffer, 0, ret, len - bufpos - 1, bufpos + 1);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
public void Done()
|
||||
{
|
||||
buffer = null;
|
||||
bufline = null;
|
||||
bufcolumn = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to adjust line and column numbers for the start of a token.
|
||||
*/
|
||||
public void adjustBeginLineColumn(int newLine, int newCol)
|
||||
{
|
||||
int start = tokenBegin;
|
||||
int len;
|
||||
|
||||
if (bufpos >= tokenBegin)
|
||||
{
|
||||
len = bufpos - tokenBegin + inBuf + 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
len = bufsize - tokenBegin + bufpos + 1 + inBuf;
|
||||
}
|
||||
|
||||
int i = 0, j = 0, k = 0;
|
||||
int nextColDiff = 0, columnDiff = 0;
|
||||
|
||||
while (i < len &&
|
||||
bufline[j = start % bufsize] == bufline[k = ++start % bufsize])
|
||||
{
|
||||
bufline[j] = newLine;
|
||||
nextColDiff = columnDiff + bufcolumn[k] - bufcolumn[j];
|
||||
bufcolumn[j] = newCol + columnDiff;
|
||||
columnDiff = nextColDiff;
|
||||
i++;
|
||||
}
|
||||
|
||||
if (i < len)
|
||||
{
|
||||
bufline[j] = newLine++;
|
||||
bufcolumn[j] = newCol + columnDiff;
|
||||
|
||||
while (i++ < len)
|
||||
{
|
||||
if (bufline[j = start % bufsize] != bufline[++start % bufsize])
|
||||
bufline[j] = newLine++;
|
||||
else
|
||||
bufline[j] = newLine;
|
||||
}
|
||||
}
|
||||
|
||||
line = bufline[j];
|
||||
column = bufcolumn[j];
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,156 @@
|
||||
/*
|
||||
* Copyright 2007 Sascha Weinreuter
|
||||
*
|
||||
* 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.intellij.plugins.relaxNG.compact.parser;
|
||||
|
||||
import org.intellij.plugins.relaxNG.compact.RncElementTypes;
|
||||
import static org.intellij.plugins.relaxNG.compact.RncTokenTypes.*;
|
||||
|
||||
import com.intellij.lang.PsiBuilder;
|
||||
import com.intellij.psi.tree.IElementType;
|
||||
import com.intellij.psi.tree.TokenSet;
|
||||
|
||||
/**
|
||||
* Created by IntelliJ IDEA.
|
||||
* User: sweinreuter
|
||||
* Date: 09.08.2007
|
||||
*/
|
||||
public abstract class AbstractParsing {
|
||||
protected static final TokenSet LA_INCLUDE_CONTENT = TokenSet.orSet(TokenSet.create(
|
||||
KEYWORD_DIV, KEYWORD_START), IDENTIFIERS);
|
||||
|
||||
protected static final TokenSet LA_GRAMMAR_CONTENT = TokenSet.orSet(TokenSet.create(
|
||||
KEYWORD_INCLUDE), LA_INCLUDE_CONTENT);
|
||||
|
||||
protected static final TokenSet ATTR_OR_ELEMENT = TokenSet.create(
|
||||
KEYWORD_ATTRIBUTE, KEYWORD_ElEMENT);
|
||||
|
||||
protected static final TokenSet CONTENT = TokenSet.create(
|
||||
KEYWORD_LIST, KEYWORD_MIXED);
|
||||
|
||||
protected static final TokenSet LA_DATATYPE = TokenSet.create(
|
||||
KEYWORD_STRING, KEYWORD_TOKEN);
|
||||
|
||||
protected static final TokenSet LA_DECL = TokenSet.create(
|
||||
KEYWORD_DATATYPES, KEYWORD_NAMESPACE, KEYWORD_DEFAULT);
|
||||
|
||||
protected static final TokenSet NS_URI_LITERAL = TokenSet.create(KEYWORD_INHERIT, LITERAL);
|
||||
protected static final TokenSet ASSIGN_METHOD = TokenSet.create(EQ, CHOICE_EQ, INTERLEAVE_EQ);
|
||||
protected final PsiBuilder myBuilder;
|
||||
|
||||
public AbstractParsing(PsiBuilder builder) {
|
||||
myBuilder = builder;
|
||||
}
|
||||
|
||||
protected final PsiBuilder.Marker begin() {
|
||||
final PsiBuilder.Marker marker = myBuilder.mark();
|
||||
advance();
|
||||
return marker;
|
||||
}
|
||||
|
||||
protected final boolean matches(TokenSet set) {
|
||||
if (set.contains(currentToken())) {
|
||||
advance();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
protected final boolean matches(IElementType t) {
|
||||
if (t == currentToken()) {
|
||||
advance();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
protected final void match(IElementType token, String msg) {
|
||||
if (!matches(token)) {
|
||||
error(msg);
|
||||
advance();
|
||||
}
|
||||
}
|
||||
|
||||
protected final void match(TokenSet set, String msg) {
|
||||
if (!matches(set)) {
|
||||
error(msg);
|
||||
advance();
|
||||
}
|
||||
}
|
||||
|
||||
protected final void error(String s) {
|
||||
myBuilder.error(s);
|
||||
}
|
||||
|
||||
protected final void advance() {
|
||||
myBuilder.advanceLexer();
|
||||
}
|
||||
|
||||
protected final IElementType currentToken() {
|
||||
final IElementType token = myBuilder.getTokenType();
|
||||
if (isName(token)) {
|
||||
final PsiBuilder.Marker marker = myBuilder.mark();
|
||||
makeName();
|
||||
if (myBuilder.getTokenType() == LBRACKET) {
|
||||
skipAnnotation(marker, RncElementTypes.ANNOTATION_ELEMENT);
|
||||
return currentToken();
|
||||
} else {
|
||||
marker.rollbackTo();
|
||||
}
|
||||
} else if (token == LBRACKET) {
|
||||
final PsiBuilder.Marker marker = myBuilder.mark();
|
||||
skipAnnotation(marker, RncElementTypes.ANNOTATION);
|
||||
return currentToken();
|
||||
} else if (token == GTGT) {
|
||||
final PsiBuilder.Marker marker = myBuilder.mark();
|
||||
advance();
|
||||
if (isName(myBuilder.getTokenType())) {
|
||||
makeName();
|
||||
if (myBuilder.getTokenType() == LBRACKET) {
|
||||
skipAnnotation(marker, RncElementTypes.FORWARD_ANNOTATION);
|
||||
return currentToken();
|
||||
}
|
||||
}
|
||||
marker.done(RncElementTypes.FORWARD_ANNOTATION);
|
||||
return currentToken();
|
||||
}
|
||||
return token;
|
||||
}
|
||||
|
||||
protected static boolean isName(IElementType token) {
|
||||
return IDENTIFIER_OR_KEYWORD.contains(token) || token == PREFIXED_NAME;
|
||||
}
|
||||
|
||||
private void skipAnnotation(PsiBuilder.Marker marker, IElementType annotationType) {
|
||||
final boolean b = myBuilder.getTokenType() == LBRACKET;
|
||||
advance();
|
||||
assert b;
|
||||
|
||||
while (!myBuilder.eof() && currentToken() != RBRACKET) {
|
||||
advance();
|
||||
}
|
||||
if (myBuilder.getTokenType() == RBRACKET) {
|
||||
advance();
|
||||
}
|
||||
marker.done(annotationType);
|
||||
}
|
||||
|
||||
protected final void makeName() {
|
||||
final PsiBuilder.Marker name = myBuilder.mark();
|
||||
advance();
|
||||
name.done(RncElementTypes.NAME);
|
||||
}
|
||||
}
|
||||
+178
@@ -0,0 +1,178 @@
|
||||
/*
|
||||
* Copyright 2007 Sascha Weinreuter
|
||||
*
|
||||
* 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.intellij.plugins.relaxNG.compact.parser;
|
||||
|
||||
import org.intellij.plugins.relaxNG.compact.RncElementTypes;
|
||||
import static org.intellij.plugins.relaxNG.compact.RncTokenTypes.*;
|
||||
|
||||
import com.intellij.lang.PsiBuilder;
|
||||
import com.intellij.psi.tree.IElementType;
|
||||
|
||||
/**
|
||||
* Created by IntelliJ IDEA.
|
||||
* User: sweinreuter
|
||||
* Date: 09.08.2007
|
||||
*/
|
||||
public abstract class DeclarationParsing extends AbstractParsing {
|
||||
|
||||
public DeclarationParsing(PsiBuilder builder) {
|
||||
super(builder);
|
||||
}
|
||||
|
||||
protected void parseTopLevel() {
|
||||
while (!myBuilder.eof() && LA_DECL.contains(currentToken())) {
|
||||
parseDecl(myBuilder);
|
||||
}
|
||||
|
||||
if (LA_GRAMMAR_CONTENT.contains(currentToken())) {
|
||||
final PsiBuilder.Marker marker = myBuilder.mark();
|
||||
parseGrammarContents();
|
||||
marker.done(RncElementTypes.GRAMMAR_PATTERN);
|
||||
} else if (currentToken() == KEYWORD_GRAMMAR) {
|
||||
parsePattern();
|
||||
} else {
|
||||
final PsiBuilder.Marker marker = myBuilder.mark();
|
||||
while (!myBuilder.eof()) {
|
||||
if (!parsePattern()) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
marker.done(RncElementTypes.GRAMMAR_PATTERN);
|
||||
}
|
||||
}
|
||||
|
||||
protected abstract boolean parsePattern();
|
||||
|
||||
protected void parseGrammarContents() {
|
||||
while (LA_GRAMMAR_CONTENT.contains(currentToken())) {
|
||||
parseGrammarContent(true);
|
||||
}
|
||||
}
|
||||
|
||||
private void parseIncludeContents() {
|
||||
while (LA_INCLUDE_CONTENT.contains(currentToken())) {
|
||||
parseGrammarContent(false);
|
||||
}
|
||||
}
|
||||
|
||||
private void parseGrammarContent(boolean allowInclude) {
|
||||
final IElementType t = currentToken();
|
||||
if (t == KEYWORD_START) {
|
||||
parseStart();
|
||||
} else if (t == KEYWORD_DIV) {
|
||||
parseDiv();
|
||||
} else if (allowInclude && t == KEYWORD_INCLUDE) {
|
||||
parseInclude();
|
||||
} else if (IDENTIFIERS.contains(t)) {
|
||||
parseDefine();
|
||||
} else {
|
||||
error("Unexpected token");
|
||||
advance();
|
||||
}
|
||||
}
|
||||
|
||||
private void parseDefine() {
|
||||
final PsiBuilder.Marker marker = begin();
|
||||
match(ASSIGN_METHOD, "'=', '|=' or '&=' expected");
|
||||
if (!parsePattern()) {
|
||||
error("Pattern expected");
|
||||
}
|
||||
marker.done(RncElementTypes.DEFINE);
|
||||
}
|
||||
|
||||
private void parseInclude() {
|
||||
final PsiBuilder.Marker marker = begin();
|
||||
|
||||
parseAnyUriLiteral();
|
||||
|
||||
parseInherit();
|
||||
|
||||
if (matches(LBRACE)) {
|
||||
parseIncludeContents();
|
||||
match(RBRACE, "'}' expected");
|
||||
}
|
||||
marker.done(RncElementTypes.INCLUDE);
|
||||
}
|
||||
|
||||
protected final void parseAnyUriLiteral() {
|
||||
match(LITERAL, "URI literal expected");
|
||||
}
|
||||
|
||||
protected final void parseInherit() {
|
||||
if (matches(KEYWORD_INHERIT)) {
|
||||
match(EQ, "'=' expected");
|
||||
match(IDENTIFIER_OR_KEYWORD, "Identifier expected");
|
||||
}
|
||||
}
|
||||
|
||||
private void parseDiv() {
|
||||
final PsiBuilder.Marker marker = begin();
|
||||
parseBracedGrammarContents();
|
||||
marker.done(RncElementTypes.DIV);
|
||||
}
|
||||
|
||||
private void parseStart() {
|
||||
final PsiBuilder.Marker marker = begin();
|
||||
match(ASSIGN_METHOD, "'=', '|=' or '&=' expected");
|
||||
if (!parsePattern()) {
|
||||
error("Pattern expected");
|
||||
}
|
||||
marker.done(RncElementTypes.START);
|
||||
}
|
||||
|
||||
protected void parseBracedGrammarContents() {
|
||||
match(LBRACE, "'{' expected");
|
||||
parseGrammarContents();
|
||||
match(RBRACE, "'}' expected");
|
||||
}
|
||||
|
||||
protected void parseDecl(PsiBuilder builder) {
|
||||
final IElementType t = builder.getTokenType();
|
||||
if (t == KEYWORD_NAMESPACE) {
|
||||
parseNamespaceDecl(false);
|
||||
} else if (t == KEYWORD_DEFAULT) {
|
||||
parseNamespaceDecl(true);
|
||||
} else if (t == KEYWORD_DATATYPES) {
|
||||
parseDataTypesDecl();
|
||||
}
|
||||
}
|
||||
|
||||
private void parseDataTypesDecl() {
|
||||
final PsiBuilder.Marker marker = begin();
|
||||
match(IDENTIFIER_OR_KEYWORD, "Identifier expected");
|
||||
match(EQ, "'=' expected");
|
||||
parseNsUriLiteral();
|
||||
marker.done(RncElementTypes.DATATYPES_DECL);
|
||||
}
|
||||
|
||||
private void parseNamespaceDecl(boolean isDefault) {
|
||||
final PsiBuilder.Marker marker = begin();
|
||||
if (isDefault) {
|
||||
match(KEYWORD_NAMESPACE, "'namespace' expected");
|
||||
matches(IDENTIFIER_OR_KEYWORD);
|
||||
} else {
|
||||
match(IDENTIFIER_OR_KEYWORD, "Identifier expected");
|
||||
}
|
||||
match(EQ, "'=' expected");
|
||||
parseNsUriLiteral();
|
||||
marker.done(RncElementTypes.NS_DECL);
|
||||
}
|
||||
|
||||
private void parseNsUriLiteral() {
|
||||
match(NS_URI_LITERAL, "Namespace URI or 'inherit' expected");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
/*
|
||||
* Copyright 2007 Sascha Weinreuter
|
||||
*
|
||||
* 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.intellij.plugins.relaxNG.compact.parser;
|
||||
|
||||
import org.intellij.plugins.relaxNG.compact.RncElementTypes;
|
||||
import static org.intellij.plugins.relaxNG.compact.RncTokenTypes.*;
|
||||
|
||||
import com.intellij.lang.PsiBuilder;
|
||||
import com.intellij.psi.tree.IElementType;
|
||||
|
||||
public class NameClassParsing extends AbstractParsing {
|
||||
|
||||
public NameClassParsing(PsiBuilder builder) {
|
||||
super(builder);
|
||||
}
|
||||
|
||||
public boolean parseNameClass() {
|
||||
PsiBuilder.Marker marker = myBuilder.mark();
|
||||
|
||||
if (!parseNameClassPart()) {
|
||||
marker.drop();
|
||||
return false;
|
||||
}
|
||||
|
||||
if (currentToken() == PIPE) {
|
||||
do {
|
||||
advance();
|
||||
if (!parseNameClassPart()) {
|
||||
error("NameClass expected");
|
||||
}
|
||||
} while (currentToken() == PIPE);
|
||||
marker.done(RncElementTypes.NAME_CLASS_CHOICE);
|
||||
} else {
|
||||
marker.drop();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean parseNameClassPart() {
|
||||
final IElementType t = currentToken();
|
||||
PsiBuilder.Marker marker = myBuilder.mark();
|
||||
if (IDENTIFIER_OR_KEYWORD.contains(t)) {
|
||||
advance();
|
||||
} else if (PREFIXED_NAME == t) { // CName
|
||||
makeName();
|
||||
} else if (STAR == t) { // anyName
|
||||
advance();
|
||||
parseExceptNameClass();
|
||||
} else if (PREFIXED_STAR == t) { // nsName
|
||||
makeName();
|
||||
parseExceptNameClass();
|
||||
} else if (LPAREN == t) {
|
||||
advance();
|
||||
if (parseNameClass()) {
|
||||
match(RPAREN, "')' expected");
|
||||
}
|
||||
} else {
|
||||
marker.drop();
|
||||
return false;
|
||||
}
|
||||
marker.done(RncElementTypes.NAME_CLASS);
|
||||
return true;
|
||||
}
|
||||
|
||||
private void parseExceptNameClass() {
|
||||
if (MINUS == currentToken()) {
|
||||
final PsiBuilder.Marker marker = begin();
|
||||
if (!parseNameClass()) {
|
||||
error("NameClass expected");
|
||||
}
|
||||
marker.done(RncElementTypes.EXCEPT_NAME_CLASS);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,191 @@
|
||||
/*
|
||||
* Copyright 2007 Sascha Weinreuter
|
||||
*
|
||||
* 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.intellij.plugins.relaxNG.compact.parser;
|
||||
|
||||
import org.intellij.plugins.relaxNG.compact.RncElementTypes;
|
||||
import static org.intellij.plugins.relaxNG.compact.RncTokenTypes.*;
|
||||
|
||||
import com.intellij.lang.PsiBuilder;
|
||||
import com.intellij.psi.tree.IElementType;
|
||||
|
||||
import gnu.trove.THashMap;
|
||||
import gnu.trove.TObjectHashingStrategy;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Created by IntelliJ IDEA.
|
||||
* User: sweinreuter
|
||||
* Date: 09.08.2007
|
||||
*/
|
||||
public class PatternParsing extends DeclarationParsing {
|
||||
|
||||
@SuppressWarnings({ "unchecked" })
|
||||
protected static final Map<IElementType, IElementType> TOKEN_MAP =
|
||||
new THashMap<IElementType, IElementType>(TObjectHashingStrategy.IDENTITY);
|
||||
|
||||
static {
|
||||
TOKEN_MAP.put(COMMA, RncElementTypes.SEQUENCE);
|
||||
TOKEN_MAP.put(PIPE, RncElementTypes.CHOICE);
|
||||
TOKEN_MAP.put(AND, RncElementTypes.INTERLEAVE);
|
||||
TOKEN_MAP.put(STAR, RncElementTypes.ZERO_OR_MORE);
|
||||
TOKEN_MAP.put(PLUS, RncElementTypes.ONE_OR_MORE);
|
||||
TOKEN_MAP.put(QUEST, RncElementTypes.OPTIONAL);
|
||||
}
|
||||
|
||||
private final NameClassParsing myNameClassParsing;
|
||||
|
||||
public PatternParsing(PsiBuilder builder) {
|
||||
super(builder);
|
||||
myNameClassParsing = new NameClassParsing(builder);
|
||||
}
|
||||
|
||||
public void parse() {
|
||||
parseTopLevel();
|
||||
}
|
||||
|
||||
protected boolean parsePattern() {
|
||||
PsiBuilder.Marker marker = myBuilder.mark();
|
||||
if (!parseQuantifiedPattern()) {
|
||||
marker.drop();
|
||||
return false;
|
||||
}
|
||||
|
||||
while (BINARY_OPS.contains(currentToken())) {
|
||||
IElementType t;
|
||||
if (BINARY_OPS.contains(t = currentToken())) {
|
||||
do {
|
||||
advance();
|
||||
if (!parseQuantifiedPattern()) {
|
||||
error("Pattern expected");
|
||||
}
|
||||
} while (currentToken() == t);
|
||||
marker.done(TOKEN_MAP.get(t));
|
||||
marker = marker.precede();
|
||||
}
|
||||
}
|
||||
marker.drop();
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean parseQuantifiedPattern() {
|
||||
final PsiBuilder.Marker marker = myBuilder.mark();
|
||||
if (!parseSinglePattern()) {
|
||||
marker.drop();
|
||||
return false;
|
||||
}
|
||||
|
||||
final IElementType t = currentToken();
|
||||
if (matches(QUANTIFIER_OPS)) {
|
||||
marker.done(TOKEN_MAP.get(t));
|
||||
} else {
|
||||
marker.drop();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean parseSinglePattern() {
|
||||
final PsiBuilder.Marker marker = myBuilder.mark();
|
||||
if (matches(ATTR_OR_ELEMENT)) {
|
||||
if (!myNameClassParsing.parseNameClass()) {
|
||||
error("Name class expected");
|
||||
marker.drop();
|
||||
return false;
|
||||
}
|
||||
parseBracedPattern();
|
||||
marker.done(RncElementTypes.PATTERN);
|
||||
} else if (matches(KEYWORD_LIST)) {
|
||||
parseBracedPattern();
|
||||
marker.done(RncElementTypes.LIST_PATTERN);
|
||||
} else if (matches(KEYWORD_MIXED)) {
|
||||
parseBracedPattern();
|
||||
marker.done(RncElementTypes.MIXED_PATTERN);
|
||||
} else if (matches(KEYWORD_EXTERNAL)) {
|
||||
parseAnyUriLiteral();
|
||||
parseInherit();
|
||||
marker.done(RncElementTypes.EXTERNAL_REF);
|
||||
} else if (matches(KEYWORD_NOT_ALLOWED)) {
|
||||
marker.done(RncElementTypes.NOT_ALLOWED_PATTERN);
|
||||
} else if (matches(KEYWORD_TEXT)) {
|
||||
marker.done(RncElementTypes.TEXT_PATTERN);
|
||||
} else if (matches(KEYWORD_EMPTY)) {
|
||||
marker.done(RncElementTypes.EMPTY_PATTERN);
|
||||
} else if (matches(KEYWORD_PARENT)) {
|
||||
match(IDENTIFIERS, "Identifier expected");
|
||||
marker.done(RncElementTypes.PARENT_REF);
|
||||
} else if (matches(KEYWORD_GRAMMAR)) {
|
||||
parseBracedGrammarContents();
|
||||
marker.done(RncElementTypes.GRAMMAR_PATTERN);
|
||||
} else if (matches(LPAREN)) {
|
||||
if (!parsePattern()) {
|
||||
error("Pattern expected");
|
||||
}
|
||||
match(RPAREN, "')' expected");
|
||||
marker.done(RncElementTypes.GROUP_PATTERN);
|
||||
} else if (matches(IDENTIFIERS)) {
|
||||
marker.done(RncElementTypes.REF_PATTERN);
|
||||
} else if (matches(LA_DATATYPE)) {
|
||||
parseDatatype();
|
||||
marker.done(RncElementTypes.DATATYPE_PATTERN);
|
||||
} else if (currentToken() == PREFIXED_NAME) {
|
||||
makeName();
|
||||
parseDatatype();
|
||||
marker.done(RncElementTypes.DATATYPE_PATTERN);
|
||||
} else if (matches(LITERAL)) {
|
||||
marker.done(RncElementTypes.DATATYPE_PATTERN);
|
||||
} else {
|
||||
marker.drop();
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private void parseDatatype() {
|
||||
if (currentToken() == LITERAL) {
|
||||
advance();
|
||||
} else if (matches(LBRACE)) {
|
||||
parseParams();
|
||||
if (matches(MINUS)) {
|
||||
if (!parsePattern()) {
|
||||
error("Pattern expected");
|
||||
}
|
||||
}
|
||||
match(RBRACE, "'}' expected");
|
||||
}
|
||||
}
|
||||
|
||||
private void parseBracedPattern() {
|
||||
match(LBRACE, "'{' expected");
|
||||
if (!parsePattern()) {
|
||||
error("Pattern expected");
|
||||
}
|
||||
match(RBRACE, "'}' expected");
|
||||
}
|
||||
|
||||
private void parseParams() {
|
||||
final IElementType t = currentToken();
|
||||
if (t != RBRACE) {
|
||||
do {
|
||||
final PsiBuilder.Marker marker = myBuilder.mark();
|
||||
match(IDENTIFIER_OR_KEYWORD, "Identifier expected");
|
||||
match(EQ, "'=' expected");
|
||||
match(LITERAL, "Literal expected");
|
||||
marker.done(RncElementTypes.PARAM);
|
||||
} while (IDENTIFIER_OR_KEYWORD.contains(currentToken()));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Copyright 2007 Sascha Weinreuter
|
||||
*
|
||||
* 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.intellij.plugins.relaxNG.compact.parser;
|
||||
|
||||
import org.intellij.plugins.relaxNG.compact.RncElementTypes;
|
||||
|
||||
import com.intellij.lang.ASTNode;
|
||||
import com.intellij.lang.PsiBuilder;
|
||||
import com.intellij.lang.PsiParser;
|
||||
import com.intellij.psi.tree.IElementType;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* Created by IntelliJ IDEA.
|
||||
* User: sweinreuter
|
||||
* Date: 07.08.2007
|
||||
*/
|
||||
public class RncParser implements PsiParser {
|
||||
|
||||
@NotNull
|
||||
public ASTNode parse(IElementType root, PsiBuilder builder) {
|
||||
final PsiBuilder.Marker fileMarker = builder.mark();
|
||||
final PsiBuilder.Marker docMarker = builder.mark();
|
||||
|
||||
new PatternParsing(builder).parse();
|
||||
|
||||
while (!builder.eof()) {
|
||||
builder.error("Unexpected token");
|
||||
builder.advanceLexer();
|
||||
}
|
||||
|
||||
docMarker.done(RncElementTypes.DOCUMENT);
|
||||
fileMarker.done(root);
|
||||
return builder.getTreeBuilt();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* Copyright 2007 Sascha Weinreuter
|
||||
*
|
||||
* 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.intellij.plugins.relaxNG.compact.psi;
|
||||
|
||||
import com.intellij.psi.PsiComment;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/*
|
||||
* Created by IntelliJ IDEA.
|
||||
* User: sweinreuter
|
||||
* Date: 24.08.2007
|
||||
*/
|
||||
public interface RncAnnotation extends RncElement, PsiComment {
|
||||
@Nullable
|
||||
RncName getNameElement();
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* Copyright 2007 Sascha Weinreuter
|
||||
*
|
||||
* 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.intellij.plugins.relaxNG.compact.psi;
|
||||
|
||||
import com.intellij.psi.PsiNamedElement;
|
||||
|
||||
/**
|
||||
* Created by IntelliJ IDEA.
|
||||
* User: sweinreuter
|
||||
* Date: 16.08.2007
|
||||
*/
|
||||
public interface RncDecl extends RncElement, PsiNamedElement {
|
||||
String getPrefix();
|
||||
|
||||
String getDeclaredNamespace();
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* Copyright 2007 Sascha Weinreuter
|
||||
*
|
||||
* 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.intellij.plugins.relaxNG.compact.psi;
|
||||
|
||||
import org.intellij.plugins.relaxNG.model.Define;
|
||||
|
||||
import com.intellij.psi.PsiNamedElement;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* Created by IntelliJ IDEA.
|
||||
* User: sweinreuter
|
||||
* Date: 13.08.2007
|
||||
*/
|
||||
public interface RncDefine extends RncPattern, PsiNamedElement, Define<RncPattern, RncElement> {
|
||||
@Nullable
|
||||
RncPattern getPattern();
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
/*
|
||||
* Copyright 2007 Sascha Weinreuter
|
||||
*
|
||||
* 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.intellij.plugins.relaxNG.compact.psi;
|
||||
|
||||
import org.intellij.plugins.relaxNG.model.Div;
|
||||
|
||||
/*
|
||||
* Created by IntelliJ IDEA.
|
||||
* User: sweinreuter
|
||||
* Date: 24.08.2007
|
||||
*/
|
||||
public interface RncDiv extends RncElement, Div<RncElement> {
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
/*
|
||||
* Copyright 2007 Sascha Weinreuter
|
||||
*
|
||||
* 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.intellij.plugins.relaxNG.compact.psi;
|
||||
|
||||
import com.intellij.psi.PsiElement;
|
||||
|
||||
/**
|
||||
* Created by IntelliJ IDEA.
|
||||
* User: sweinreuter
|
||||
* Date: 10.08.2007
|
||||
*/
|
||||
public interface RncElement extends PsiElement {
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
/*
|
||||
* Copyright 2007 Sascha Weinreuter
|
||||
*
|
||||
* 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.intellij.plugins.relaxNG.compact.psi;
|
||||
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiElementVisitor;
|
||||
|
||||
public class RncElementVisitor extends PsiElementVisitor {
|
||||
|
||||
@Override
|
||||
public final void visitElement(PsiElement element) {
|
||||
if (element instanceof RncElement) {
|
||||
visitElement((RncElement)element);
|
||||
} else {
|
||||
superVisitElement(element);
|
||||
}
|
||||
}
|
||||
|
||||
protected void superVisitElement(PsiElement element) {
|
||||
super.visitElement(element);
|
||||
}
|
||||
|
||||
public void visitElement(RncElement element) {
|
||||
super.visitElement(element);
|
||||
}
|
||||
|
||||
public void visitInclude(RncInclude include) {
|
||||
visitElement(include);
|
||||
}
|
||||
|
||||
public void visitDiv(RncDiv div) {
|
||||
visitElement(div);
|
||||
}
|
||||
|
||||
public void visitRef(RncRef pattern) {
|
||||
visitElement(pattern);
|
||||
}
|
||||
|
||||
public void visitParentRef(RncParentRef pattern) {
|
||||
visitElement(pattern);
|
||||
}
|
||||
|
||||
public void visitDefine(RncDefine pattern) {
|
||||
visitElement(pattern);
|
||||
}
|
||||
|
||||
public void visitGrammar(RncGrammar pattern) {
|
||||
visitElement(pattern);
|
||||
}
|
||||
|
||||
public void visitName(RncName name) {
|
||||
visitElement(name);
|
||||
}
|
||||
|
||||
public void visitAnnotation(RncAnnotation annotation) {
|
||||
visitElement(annotation);
|
||||
}
|
||||
|
||||
public void visitExternalRef(RncExternalRef ref) {
|
||||
visitElement(ref);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
* Copyright 2007 Sascha Weinreuter
|
||||
*
|
||||
* 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.intellij.plugins.relaxNG.compact.psi;
|
||||
|
||||
/**
|
||||
* Created by IntelliJ IDEA.
|
||||
* User: sweinreuter
|
||||
* Date: 11.08.2007
|
||||
*/
|
||||
public interface RncExternalRef extends RncFileReference {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* Copyright 2007 Sascha Weinreuter
|
||||
*
|
||||
* 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.intellij.plugins.relaxNG.compact.psi;
|
||||
|
||||
import com.intellij.psi.PsiFile;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* Created by IntelliJ IDEA.
|
||||
* User: sweinreuter
|
||||
* Date: 11.08.2007
|
||||
*/
|
||||
public interface RncFile extends PsiFile {
|
||||
RncDecl[] getDeclarations();
|
||||
|
||||
@Nullable
|
||||
RncGrammar getGrammar();
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* Copyright 2007 Sascha Weinreuter
|
||||
*
|
||||
* 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.intellij.plugins.relaxNG.compact.psi;
|
||||
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* Created by IntelliJ IDEA.
|
||||
* User: sweinreuter
|
||||
* Date: 29.08.2007
|
||||
*/
|
||||
public interface RncFileReference extends RncElement {
|
||||
@Nullable
|
||||
RncFile getReferencedFile();
|
||||
|
||||
@Nullable
|
||||
String getFileReference();
|
||||
|
||||
TextRange getReferenceRange();
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* Copyright 2007 Sascha Weinreuter
|
||||
*
|
||||
* 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.intellij.plugins.relaxNG.compact.psi;
|
||||
|
||||
import org.intellij.plugins.relaxNG.model.Grammar;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* Created by IntelliJ IDEA.
|
||||
* User: sweinreuter
|
||||
* Date: 13.08.2007
|
||||
*/
|
||||
public interface RncGrammar extends RncElement, Grammar<RncPattern, RncElement> {
|
||||
@Nullable
|
||||
RncPattern getStart();
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user