Skip to content

Commit

Permalink
Fixed bug in the computation of method names for CA
Browse files Browse the repository at this point in the history
  • Loading branch information
Sebastian Zarnekow authored and Sebastian Zarnekow committed Jul 11, 2017
1 parent be7a786 commit 8485c5b
Show file tree
Hide file tree
Showing 2 changed files with 166 additions and 41 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -19,47 +19,6 @@
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.jface.text.rules.IPartitionTokenScanner;
import org.eclipse.jface.text.rules.ITokenScanner;
import org.eclipse.ui.plugin.AbstractUIPlugin;
import org.eclipse.xtext.builder.EclipseResourceFileSystemAccess2;
import org.eclipse.xtext.builder.IXtextBuilderParticipant;
import org.eclipse.xtext.builder.preferences.BuilderPreferenceAccess;
import org.eclipse.xtext.generator.IFileSystemAccess;
import org.eclipse.xtext.generator.IGenerator;
import org.eclipse.xtext.generator.IOutputConfigurationProvider;
import org.eclipse.xtext.ide.editor.contentassist.antlr.FollowElementComputer;
import org.eclipse.xtext.ide.editor.contentassist.antlr.IContentAssistParser;
import org.eclipse.xtext.resource.ILocationInFileProvider;
import org.eclipse.xtext.resource.SynchronizedXtextResourceSet;
import org.eclipse.xtext.resource.XtextResourceSet;
import org.eclipse.xtext.resource.containers.IAllContainersState;
import org.eclipse.xtext.ui.editor.DirtyStateEditorSupport;
import org.eclipse.xtext.ui.editor.IXtextEditorCallback;
import org.eclipse.xtext.ui.editor.XtextEditor;
import org.eclipse.xtext.ui.editor.autoedit.AbstractEditStrategyProvider;
import org.eclipse.xtext.ui.editor.contentassist.FQNPrefixMatcher;
import org.eclipse.xtext.ui.editor.contentassist.FQNPrefixMatcher.LastSegmentFinder;
import org.eclipse.xtext.ui.editor.contentassist.IContentAssistantFactory;
import org.eclipse.xtext.ui.editor.contentassist.PrefixMatcher;
import org.eclipse.xtext.ui.editor.doubleClicking.DoubleClickStrategyProvider;
import org.eclipse.xtext.ui.editor.formatting2.ContentFormatter;
import org.eclipse.xtext.ui.editor.hover.IEObjectHoverProvider;
import org.eclipse.xtext.ui.editor.model.DocumentTokenSource;
import org.eclipse.xtext.ui.editor.model.IResourceForEditorInputFactory;
import org.eclipse.xtext.ui.editor.model.TerminalsTokenTypeToPartitionMapper;
import org.eclipse.xtext.ui.editor.quickfix.MarkerResolutionGenerator;
import org.eclipse.xtext.ui.editor.syntaxcoloring.AbstractAntlrTokenToAttributeIdMapper;
import org.eclipse.xtext.ui.editor.syntaxcoloring.IHighlightingConfiguration;
import org.eclipse.xtext.ui.editor.syntaxcoloring.IHighlightingHelper;
import org.eclipse.xtext.ui.resource.DefaultResourceUIServiceProvider;
import org.eclipse.xtext.ui.shared.Access;
import org.eclipse.xtext.ui.util.IssueUtil;
import org.eclipse.xtext.validation.IResourceValidator;

import com.google.inject.Binder;
import com.google.inject.Provider;
import com.google.inject.Singleton;

import org.eclipse.n4js.ui.logging.N4jsUiLoggingInitializer;
import org.eclipse.n4js.CancelIndicatorBaseExtractor;
import org.eclipse.n4js.N4JSRuntimeModule;
import org.eclipse.n4js.binaries.BinariesPreferenceStore;
Expand Down Expand Up @@ -87,6 +46,7 @@
import org.eclipse.n4js.ui.contentassist.CustomN4JSParser;
import org.eclipse.n4js.ui.contentassist.N4JSFollowElementCalculator;
import org.eclipse.n4js.ui.contentassist.PatchedFollowElementComputer;
import org.eclipse.n4js.ui.contentassist.PatchedRequiredRuleNameComputer;
import org.eclipse.n4js.ui.contentassist.SimpleLastSegmentFinder;
import org.eclipse.n4js.ui.editor.AlwaysAddNatureCallback;
import org.eclipse.n4js.ui.editor.N4JSDirtyStateEditorSupport;
Expand All @@ -107,6 +67,7 @@
import org.eclipse.n4js.ui.labeling.N4JSContentAssistLabelProvider;
import org.eclipse.n4js.ui.labeling.N4JSHoverProvider;
import org.eclipse.n4js.ui.labeling.N4JSHyperlinkLabelProvider;
import org.eclipse.n4js.ui.logging.N4jsUiLoggingInitializer;
import org.eclipse.n4js.ui.organize.imports.IReferenceFilter;
import org.eclipse.n4js.ui.organize.imports.N4JSReferencesFilter;
import org.eclipse.n4js.ui.preferences.N4JSBuilderPreferenceAccess;
Expand All @@ -120,6 +81,46 @@
import org.eclipse.n4js.ui.workingsets.WorkingSetManagerBroker;
import org.eclipse.n4js.ui.workingsets.WorkingSetManagerBrokerImpl;
import org.eclipse.n4js.utils.process.OutputStreamProvider;
import org.eclipse.ui.plugin.AbstractUIPlugin;
import org.eclipse.xtext.builder.EclipseResourceFileSystemAccess2;
import org.eclipse.xtext.builder.IXtextBuilderParticipant;
import org.eclipse.xtext.builder.preferences.BuilderPreferenceAccess;
import org.eclipse.xtext.generator.IFileSystemAccess;
import org.eclipse.xtext.generator.IGenerator;
import org.eclipse.xtext.generator.IOutputConfigurationProvider;
import org.eclipse.xtext.ide.editor.contentassist.antlr.FollowElementComputer;
import org.eclipse.xtext.ide.editor.contentassist.antlr.IContentAssistParser;
import org.eclipse.xtext.ide.editor.contentassist.antlr.RequiredRuleNameComputer;
import org.eclipse.xtext.resource.ILocationInFileProvider;
import org.eclipse.xtext.resource.SynchronizedXtextResourceSet;
import org.eclipse.xtext.resource.XtextResourceSet;
import org.eclipse.xtext.resource.containers.IAllContainersState;
import org.eclipse.xtext.ui.editor.DirtyStateEditorSupport;
import org.eclipse.xtext.ui.editor.IXtextEditorCallback;
import org.eclipse.xtext.ui.editor.XtextEditor;
import org.eclipse.xtext.ui.editor.autoedit.AbstractEditStrategyProvider;
import org.eclipse.xtext.ui.editor.contentassist.FQNPrefixMatcher;
import org.eclipse.xtext.ui.editor.contentassist.FQNPrefixMatcher.LastSegmentFinder;
import org.eclipse.xtext.ui.editor.contentassist.IContentAssistantFactory;
import org.eclipse.xtext.ui.editor.contentassist.PrefixMatcher;
import org.eclipse.xtext.ui.editor.doubleClicking.DoubleClickStrategyProvider;
import org.eclipse.xtext.ui.editor.formatting2.ContentFormatter;
import org.eclipse.xtext.ui.editor.hover.IEObjectHoverProvider;
import org.eclipse.xtext.ui.editor.model.DocumentTokenSource;
import org.eclipse.xtext.ui.editor.model.IResourceForEditorInputFactory;
import org.eclipse.xtext.ui.editor.model.TerminalsTokenTypeToPartitionMapper;
import org.eclipse.xtext.ui.editor.quickfix.MarkerResolutionGenerator;
import org.eclipse.xtext.ui.editor.syntaxcoloring.AbstractAntlrTokenToAttributeIdMapper;
import org.eclipse.xtext.ui.editor.syntaxcoloring.IHighlightingConfiguration;
import org.eclipse.xtext.ui.editor.syntaxcoloring.IHighlightingHelper;
import org.eclipse.xtext.ui.resource.DefaultResourceUIServiceProvider;
import org.eclipse.xtext.ui.shared.Access;
import org.eclipse.xtext.ui.util.IssueUtil;
import org.eclipse.xtext.validation.IResourceValidator;

import com.google.inject.Binder;
import com.google.inject.Provider;
import com.google.inject.Singleton;

/**
* Use this class to register components to be used within the IDE.
Expand Down Expand Up @@ -355,6 +356,13 @@ public Class<? extends FollowElementComputer> bindFollowElementComputer() {
return PatchedFollowElementComputer.class;
}

/**
* Remove this binding with Xtext 2.13
*/
public Class<? extends RequiredRuleNameComputer> bindRequiredRuleNameComputer() {
return PatchedRequiredRuleNameComputer.class;
}

@Override
public Class<? extends IContentAssistParser> bindIContentAssistParser() {
return CustomN4JSParser.class;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
/**
* Copyright (c) 2017 NumberFour AG.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* NumberFour AG - Initial API and implementation
*/
package org.eclipse.n4js.ui.contentassist;

import static org.eclipse.xtext.xtext.ParameterConfigHelper.getAssignedArguments;
import static org.eclipse.xtext.xtext.ParameterConfigHelper.getParameterConfig;

import java.util.List;
import java.util.Set;

import org.eclipse.emf.ecore.EObject;
import org.eclipse.xtext.AbstractElement;
import org.eclipse.xtext.GrammarUtil;
import org.eclipse.xtext.Group;
import org.eclipse.xtext.Parameter;
import org.eclipse.xtext.ParserRule;
import org.eclipse.xtext.RuleCall;
import org.eclipse.xtext.ide.editor.contentassist.antlr.RequiredRuleNameComputer;

import com.google.inject.Singleton;

// TODO remove with Xtext 2.13
/**
* Fixes two issues with the computation of the methods that are supposed to be called on the parser.
*
* <ol>
* <li>The parser attempts to call methods for groups that contain only one element. These grammar constructs are
* normalized in the parser generator. See {@link #getEnclosingSingleElementGroup(AbstractElement)}.</li>
* <li>The super impl has a bug in {@link #getRequiredRuleNames(Param)} which would return the original method name
* instead of the adjusted name.</li>
* </ol>
*
*/
@Singleton
public class PatchedRequiredRuleNameComputer extends RequiredRuleNameComputer {

private static final String[][] EMPTY_ARRAY = new String[0][];

@Override
protected boolean isFiltered(Param param) {
AbstractElement elementToParse = param.elementToParse;
while (elementToParse != null) {
if (isFiltered(elementToParse, param)) {
return true;
}
elementToParse = getEnclosingSingleElementGroup(elementToParse);
}
return false;
}

/**
* Return the containing group if it contains exactly one element.
*/
protected AbstractElement getEnclosingSingleElementGroup(AbstractElement elementToParse) {
EObject container = elementToParse.eContainer();
if (container instanceof Group) {
if (((Group) container).getElements().size() == 1) {
return (AbstractElement) container;
}
}
return null;
}

@SuppressWarnings("restriction")
@Override
public String[][] getRequiredRuleNames(Param param) {
if (isFiltered(param)) {
return EMPTY_ARRAY;
}
AbstractElement elementToParse = param.elementToParse;
String ruleName = param.ruleName;
if (ruleName == null) {
if (elementToParse instanceof RuleCall) {
RuleCall call = (RuleCall) elementToParse;
if (call.getRule() instanceof ParserRule) {
String antlrRuleName = getRuleNames().getAntlrRuleName(call.getRule());
if (!call.getArguments().isEmpty()) {
Set<Parameter> context = param.getAssignedParametes();
Set<Parameter> arguments = getAssignedArguments(call, context);
int config = getParameterConfig(arguments);
antlrRuleName = getRuleNames().getAntlrRuleName(call.getRule(), config);
}
return new String[][] { { antlrRuleName } };
}
}
return EMPTY_ARRAY;
}
String adjustedRuleName = adjustRuleName(ruleName, param);
if (!(GrammarUtil.isOptionalCardinality(elementToParse)
|| GrammarUtil.isOneOrMoreCardinality(elementToParse))) {
return new String[][] { { adjustedRuleName } };
}
if ((elementToParse.eContainer() instanceof Group)) {
List<AbstractElement> tokens = getFilteredElements(((Group) elementToParse.eContainer()).getElements(),
param);
int idx = tokens.indexOf(elementToParse) + 1;
if (idx != tokens.size()) {
String secondRule = param.getBaseRuleName((AbstractElement) elementToParse.eContainer());
secondRule = secondRule.substring(0, secondRule.lastIndexOf('_') + 1) + idx;
String adjustedSecondRule = adjustRuleName(secondRule, param);
if (GrammarUtil.isMultipleCardinality(elementToParse))
return new String[][] { { adjustedRuleName }, { adjustedRuleName, adjustedSecondRule } };
return new String[][] { { adjustedRuleName, adjustedSecondRule } };
}
}
// Fix is here. Original method returns the original ruleName instead of the adjusted rule name.
return new String[][] { { adjustedRuleName } };
}
}

0 comments on commit 8485c5b

Please sign in to comment.