forked from phoedos/pmd
Added support for Objective-C to CPD.
This commit is contained in:
1407
pmd-objectivec/etc/grammar/ObjC2.0.jj
Normal file
1407
pmd-objectivec/etc/grammar/ObjC2.0.jj
Normal file
File diff suppressed because it is too large
Load Diff
96
pmd-objectivec/pom.xml
Normal file
96
pmd-objectivec/pom.xml
Normal file
@ -0,0 +1,96 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
<artifactId>pmd-objectivec</artifactId>
|
||||||
|
<name>PMD Objective-C</name>
|
||||||
|
|
||||||
|
<parent>
|
||||||
|
<groupId>net.sourceforge.pmd</groupId>
|
||||||
|
<artifactId>pmd</artifactId>
|
||||||
|
<version>5.2.4-SNAPSHOT</version>
|
||||||
|
</parent>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<config.basedir>${basedir}/../pmd-core</config.basedir>
|
||||||
|
</properties>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<artifactId>maven-resources-plugin</artifactId>
|
||||||
|
<configuration>
|
||||||
|
<useDefaultDelimiters>false</useDefaultDelimiters>
|
||||||
|
<delimiters>
|
||||||
|
<delimiter>${*}</delimiter>
|
||||||
|
</delimiters>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-antrun-plugin</artifactId>
|
||||||
|
<inherited>true</inherited>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<id>generate-sources</id>
|
||||||
|
<phase>generate-sources</phase>
|
||||||
|
<configuration>
|
||||||
|
<target>
|
||||||
|
<ant antfile="src/main/ant/alljavacc.xml">
|
||||||
|
<property name="target" value="${project.build.directory}/generated-sources/javacc" />
|
||||||
|
<property name="javacc.jar" value="${settings.localRepository}/net/java/dev/javacc/javacc/${javacc.version}/javacc-${javacc.version}.jar" />
|
||||||
|
</ant>
|
||||||
|
</target>
|
||||||
|
</configuration>
|
||||||
|
<goals>
|
||||||
|
<goal>run</goal>
|
||||||
|
</goals>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.codehaus.mojo</groupId>
|
||||||
|
<artifactId>build-helper-maven-plugin</artifactId>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<id>add-javacc-generated-sources</id>
|
||||||
|
<goals>
|
||||||
|
<goal>add-source</goal>
|
||||||
|
</goals>
|
||||||
|
<configuration>
|
||||||
|
<sources>
|
||||||
|
<source>${project.build.directory}/generated-sources/javacc</source>
|
||||||
|
</sources>
|
||||||
|
</configuration>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-site-plugin</artifactId>
|
||||||
|
<configuration>
|
||||||
|
<xdocDirectory>${project.build.directory}/generated-xdocs</xdocDirectory>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>net.sourceforge.pmd</groupId>
|
||||||
|
<artifactId>pmd-core</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>junit</groupId>
|
||||||
|
<artifactId>junit</artifactId>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>net.sourceforge.pmd</groupId>
|
||||||
|
<artifactId>pmd-test</artifactId>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
</project>
|
45
pmd-objectivec/src/main/ant/alljavacc.xml
Normal file
45
pmd-objectivec/src/main/ant/alljavacc.xml
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
<project name="pmd" default="alljavacc" basedir="../../">
|
||||||
|
|
||||||
|
<property name="javacc-home.path" value="target/lib" />
|
||||||
|
|
||||||
|
<target name="alljavacc"
|
||||||
|
description="Generates all JavaCC aspects within PMD"
|
||||||
|
depends="checkUpToDate,init,objectivecjavacc,cleanup" />
|
||||||
|
|
||||||
|
<target name="checkUpToDate">
|
||||||
|
<uptodate property="javaccBuildNotRequired" targetfile="${target}/last-generated-timestamp">
|
||||||
|
<srcfiles dir="etc/grammar" includes="*.jj*"/>
|
||||||
|
</uptodate>
|
||||||
|
<echo message="up to date check: javaccBuildNotRequired=${javaccBuildNotRequired}"/>
|
||||||
|
</target>
|
||||||
|
|
||||||
|
<target name="init" unless="javaccBuildNotRequired">
|
||||||
|
<mkdir dir="${javacc-home.path}" />
|
||||||
|
<copy file="${javacc.jar}" tofile="${javacc-home.path}/javacc.jar" />
|
||||||
|
|
||||||
|
<mkdir dir="${target}"/>
|
||||||
|
<touch file="${target}/last-generated-timestamp"/>
|
||||||
|
</target>
|
||||||
|
|
||||||
|
<target name="cleanup">
|
||||||
|
<delete dir="${javacc-home.path}" />
|
||||||
|
</target>
|
||||||
|
|
||||||
|
<target name="objectivecjavacc" description="Generates the Objective-C grammar" unless="javaccBuildNotRequired">
|
||||||
|
<delete dir="${target}/net/sourceforge/pmd/lang/objectivec/ast" />
|
||||||
|
<mkdir dir="${target}/net/sourceforge/pmd/lang/objectivec/ast" />
|
||||||
|
<!-- Ensure generated using CharStream interface -->
|
||||||
|
<javacc static="false"
|
||||||
|
usercharstream="true"
|
||||||
|
target="etc/grammar/ObjC2.0.jj"
|
||||||
|
outputdirectory="${target}/net/sourceforge/pmd/lang/objectivec/ast"
|
||||||
|
javacchome="${javacc-home.path}" />
|
||||||
|
<replace file="${target}/net/sourceforge/pmd/lang/objectivec/ast/ObjectiveCParserTokenManager.java"
|
||||||
|
token="class ObjectiveCParserTokenManager"
|
||||||
|
value="class ObjectiveCParserTokenManager extends net.sourceforge.pmd.lang.ast.AbstractTokenManager" />
|
||||||
|
<delete file="${target}/net/sourceforge/pmd/lang/objectivec/ast/CharStream.java" />
|
||||||
|
<delete file="${target}/net/sourceforge/pmd/lang/objectivec/ast/ParseException.java" />
|
||||||
|
<delete file="${target}/net/sourceforge/pmd/lang/objectivec/ast/TokenMgrError.java" />
|
||||||
|
</target>
|
||||||
|
|
||||||
|
</project>
|
@ -0,0 +1,18 @@
|
|||||||
|
/**
|
||||||
|
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
|
||||||
|
*/
|
||||||
|
package net.sourceforge.pmd.cpd;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Defines the Language module for Objective-C
|
||||||
|
*/
|
||||||
|
public class ObjectiveCLanguage extends AbstractLanguage {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new instance of {@link ObjectiveCLanguage} with the default extensions for Objective-C files.
|
||||||
|
*/
|
||||||
|
public ObjectiveCLanguage() {
|
||||||
|
super("Objective-C", "objectivec", new ObjectiveCTokenizer(), ".h", ".m");
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,44 @@
|
|||||||
|
/**
|
||||||
|
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
|
||||||
|
*/
|
||||||
|
package net.sourceforge.pmd.cpd;
|
||||||
|
|
||||||
|
import java.io.Reader;
|
||||||
|
import java.io.StringReader;
|
||||||
|
|
||||||
|
import net.sourceforge.pmd.lang.LanguageRegistry;
|
||||||
|
import net.sourceforge.pmd.lang.LanguageVersionHandler;
|
||||||
|
import net.sourceforge.pmd.lang.TokenManager;
|
||||||
|
import net.sourceforge.pmd.lang.ast.TokenMgrError;
|
||||||
|
import net.sourceforge.pmd.lang.objectivec.ObjectiveCLanguageModule;
|
||||||
|
import net.sourceforge.pmd.lang.objectivec.ast.Token;
|
||||||
|
|
||||||
|
import org.apache.commons.io.IOUtils;
|
||||||
|
|
||||||
|
public class ObjectiveCTokenizer implements Tokenizer {
|
||||||
|
|
||||||
|
public void tokenize(SourceCode sourceCode, Tokens tokenEntries) {
|
||||||
|
StringBuilder buffer = sourceCode.getCodeBuffer();
|
||||||
|
Reader reader = null;
|
||||||
|
try {
|
||||||
|
LanguageVersionHandler languageVersionHandler = LanguageRegistry.getLanguage(ObjectiveCLanguageModule.NAME)
|
||||||
|
.getDefaultVersion().getLanguageVersionHandler();
|
||||||
|
reader = new StringReader(buffer.toString());
|
||||||
|
TokenManager tokenManager = languageVersionHandler.getParser(
|
||||||
|
languageVersionHandler.getDefaultParserOptions()).getTokenManager(sourceCode.getFileName(), reader);
|
||||||
|
Token currentToken = (Token) tokenManager.getNextToken();
|
||||||
|
while (currentToken.image.length() > 0) {
|
||||||
|
tokenEntries.add(new TokenEntry(currentToken.image, sourceCode.getFileName(), currentToken.beginLine));
|
||||||
|
currentToken = (Token) tokenManager.getNextToken();
|
||||||
|
}
|
||||||
|
tokenEntries.add(TokenEntry.getEOF());
|
||||||
|
System.err.println("Added " + sourceCode.getFileName());
|
||||||
|
} catch (TokenMgrError err) {
|
||||||
|
err.printStackTrace();
|
||||||
|
System.err.println("Skipping " + sourceCode.getFileName() + " due to parse error");
|
||||||
|
tokenEntries.add(TokenEntry.getEOF());
|
||||||
|
} finally {
|
||||||
|
IOUtils.closeQuietly(reader);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,25 @@
|
|||||||
|
/**
|
||||||
|
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
|
||||||
|
*/
|
||||||
|
package net.sourceforge.pmd.lang.objectivec;
|
||||||
|
|
||||||
|
import net.sourceforge.pmd.lang.AbstractLanguageVersionHandler;
|
||||||
|
import net.sourceforge.pmd.lang.Parser;
|
||||||
|
import net.sourceforge.pmd.lang.ParserOptions;
|
||||||
|
import net.sourceforge.pmd.lang.rule.RuleViolationFactory;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Implementation of LanguageVersionHandler for the Objective-C Language.
|
||||||
|
*/
|
||||||
|
public class ObjectiveCHandler extends AbstractLanguageVersionHandler {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public RuleViolationFactory getRuleViolationFactory() {
|
||||||
|
throw new UnsupportedOperationException("getRuleViolationFactory() is not supported for Objective-C");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Parser getParser(ParserOptions parserOptions) {
|
||||||
|
return new ObjectiveCParser(parserOptions);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,25 @@
|
|||||||
|
/**
|
||||||
|
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
|
||||||
|
*/
|
||||||
|
package net.sourceforge.pmd.lang.objectivec;
|
||||||
|
|
||||||
|
import net.sourceforge.pmd.lang.BaseLanguageModule;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Implementation of the Objective-C Language Module.
|
||||||
|
*/
|
||||||
|
public class ObjectiveCLanguageModule extends BaseLanguageModule {
|
||||||
|
|
||||||
|
/** The name, that can be used to display the language in UI. */
|
||||||
|
public static final String NAME = "Objective-C";
|
||||||
|
/** The internal name. */
|
||||||
|
public static final String TERSE_NAME = "objectivec";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new instance of {@link ObjectiveCLanguageModule} with the default file extensions for Objective-C.
|
||||||
|
*/
|
||||||
|
public ObjectiveCLanguageModule() {
|
||||||
|
super(NAME, null, TERSE_NAME, null, "h", "m");
|
||||||
|
addVersion("", new ObjectiveCHandler(), true);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,49 @@
|
|||||||
|
/**
|
||||||
|
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
|
||||||
|
*/
|
||||||
|
package net.sourceforge.pmd.lang.objectivec;
|
||||||
|
|
||||||
|
import java.io.Reader;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import net.sourceforge.pmd.lang.AbstractParser;
|
||||||
|
import net.sourceforge.pmd.lang.ParserOptions;
|
||||||
|
import net.sourceforge.pmd.lang.TokenManager;
|
||||||
|
import net.sourceforge.pmd.lang.ast.AbstractTokenManager;
|
||||||
|
import net.sourceforge.pmd.lang.ast.Node;
|
||||||
|
import net.sourceforge.pmd.lang.ast.ParseException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adapter for the Objective-C Parser.
|
||||||
|
*/
|
||||||
|
public class ObjectiveCParser extends AbstractParser {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new Objective-C Parser.
|
||||||
|
* @param parserOptions the options
|
||||||
|
*/
|
||||||
|
public ObjectiveCParser(ParserOptions parserOptions) {
|
||||||
|
super(parserOptions);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TokenManager createTokenManager(Reader source) {
|
||||||
|
return new ObjectiveCTokenManager(source);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean canParse() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Node parse(String fileName, Reader source) throws ParseException {
|
||||||
|
AbstractTokenManager.setFileName(fileName);
|
||||||
|
throw new UnsupportedOperationException("parse(Reader) is not supported for Objective-C");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Map<Integer, String> getSuppressMap() {
|
||||||
|
throw new UnsupportedOperationException("getSuppressMap() is not supported for Objective-C");
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,34 @@
|
|||||||
|
/**
|
||||||
|
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
|
||||||
|
*/
|
||||||
|
package net.sourceforge.pmd.lang.objectivec;
|
||||||
|
|
||||||
|
import java.io.Reader;
|
||||||
|
|
||||||
|
import net.sourceforge.pmd.lang.TokenManager;
|
||||||
|
import net.sourceforge.pmd.lang.ast.SimpleCharStream;
|
||||||
|
import net.sourceforge.pmd.lang.objectivec.ast.ObjectiveCParserTokenManager;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Objective-C Token Manager implementation.
|
||||||
|
*/
|
||||||
|
public class ObjectiveCTokenManager implements TokenManager {
|
||||||
|
private final ObjectiveCParserTokenManager tokenManager;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new Objective-C Token Manager from the given source code.
|
||||||
|
* @param source the source code
|
||||||
|
*/
|
||||||
|
public ObjectiveCTokenManager(Reader source) {
|
||||||
|
tokenManager = new ObjectiveCParserTokenManager(new SimpleCharStream(source));
|
||||||
|
}
|
||||||
|
|
||||||
|
public Object getNextToken() {
|
||||||
|
return tokenManager.getNextToken();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setFileName(String fileName) {
|
||||||
|
ObjectiveCParserTokenManager.setFileName(fileName);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1 @@
|
|||||||
|
net.sourceforge.pmd.cpd.ObjectiveCLanguage
|
@ -0,0 +1 @@
|
|||||||
|
net.sourceforge.pmd.lang.objectivec.ObjectiveCLanguageModule
|
3
pmd-objectivec/src/site/markdown/index.md
Normal file
3
pmd-objectivec/src/site/markdown/index.md
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
# PMD Objective-C
|
||||||
|
|
||||||
|
Only CPD is supported. There are no PMD rules for Objective-C.
|
12
pmd-objectivec/src/site/site.xml
Normal file
12
pmd-objectivec/src/site/site.xml
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project
|
||||||
|
xmlns="http://maven.apache.org/DECORATION/1.1.0"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/DECORATION/1.1.0 http://maven.apache.org/xsd/decoration-1.1.0.xsd"
|
||||||
|
name="PMD Objective-C">
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<menu ref="parent"/>
|
||||||
|
<menu ref="reports"/>
|
||||||
|
</body>
|
||||||
|
</project>
|
@ -0,0 +1,27 @@
|
|||||||
|
/**
|
||||||
|
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
|
||||||
|
*/
|
||||||
|
package net.sourceforge.pmd;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Collection;
|
||||||
|
|
||||||
|
import net.sourceforge.pmd.lang.LanguageRegistry;
|
||||||
|
import net.sourceforge.pmd.lang.LanguageVersion;
|
||||||
|
import net.sourceforge.pmd.lang.objectivec.ObjectiveCLanguageModule;
|
||||||
|
|
||||||
|
import org.junit.runners.Parameterized.Parameters;
|
||||||
|
|
||||||
|
public class LanguageVersionTest extends AbstractLanguageVersionTest {
|
||||||
|
|
||||||
|
public LanguageVersionTest(String name, String terseName, String version, LanguageVersion expected) {
|
||||||
|
super(name, terseName, version, expected);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Parameters
|
||||||
|
public static Collection<Object[]> data() {
|
||||||
|
return Arrays.asList(new Object[][] {
|
||||||
|
{ ObjectiveCLanguageModule.NAME, ObjectiveCLanguageModule.TERSE_NAME, "", LanguageRegistry.getLanguage(ObjectiveCLanguageModule.NAME).getDefaultVersion() }
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,40 @@
|
|||||||
|
/**
|
||||||
|
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
|
||||||
|
*/
|
||||||
|
package net.sourceforge.pmd.cpd;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import net.sourceforge.pmd.testframework.AbstractTokenizerTest;
|
||||||
|
import net.sourceforge.pmd.testframework.StreamUtil;
|
||||||
|
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
|
||||||
|
public class ObjectiveCTokenizerTest extends AbstractTokenizerTest {
|
||||||
|
|
||||||
|
private static final String FILENAME = "AFHTTPRequestOperation.m";
|
||||||
|
|
||||||
|
@Before
|
||||||
|
@Override
|
||||||
|
public void buildTokenizer() {
|
||||||
|
this.tokenizer = new ObjectiveCTokenizer();
|
||||||
|
this.sourceCode = new SourceCode(new SourceCode.StringCodeLoader(this.getSampleCode(), FILENAME));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getSampleCode() {
|
||||||
|
return StreamUtil.toString(ObjectiveCTokenizer.class.getResourceAsStream(FILENAME));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void tokenizeTest() throws IOException {
|
||||||
|
this.expectedTokenCount = 884;
|
||||||
|
super.tokenizeTest();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static junit.framework.Test suite() {
|
||||||
|
return new junit.framework.JUnit4TestAdapter(ObjectiveCTokenizerTest.class);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,209 @@
|
|||||||
|
// This sample file was copied from the AFNetworking GitHub project. (https://github.com/AFNetworking/AFNetworking)
|
||||||
|
// Original source file: https://github.com/AFNetworking/AFNetworking/blob/master/AFNetworking/AFHTTPRequestOperation.m
|
||||||
|
//
|
||||||
|
// AFHTTPRequestOperation.m
|
||||||
|
//
|
||||||
|
// Copyright (c) 2013-2014 AFNetworking (http://afnetworking.com)
|
||||||
|
//
|
||||||
|
// 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:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be included in
|
||||||
|
// all copies or substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// 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.
|
||||||
|
|
||||||
|
#import "AFHTTPRequestOperation.h"
|
||||||
|
|
||||||
|
static dispatch_queue_t http_request_operation_processing_queue() {
|
||||||
|
static dispatch_queue_t af_http_request_operation_processing_queue;
|
||||||
|
static dispatch_once_t onceToken;
|
||||||
|
dispatch_once(&onceToken, ^{
|
||||||
|
af_http_request_operation_processing_queue = dispatch_queue_create("com.alamofire.networking.http-request.processing", DISPATCH_QUEUE_CONCURRENT);
|
||||||
|
});
|
||||||
|
|
||||||
|
return af_http_request_operation_processing_queue;
|
||||||
|
}
|
||||||
|
|
||||||
|
static dispatch_group_t http_request_operation_completion_group() {
|
||||||
|
static dispatch_group_t af_http_request_operation_completion_group;
|
||||||
|
static dispatch_once_t onceToken;
|
||||||
|
dispatch_once(&onceToken, ^{
|
||||||
|
af_http_request_operation_completion_group = dispatch_group_create();
|
||||||
|
});
|
||||||
|
|
||||||
|
return af_http_request_operation_completion_group;
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma mark -
|
||||||
|
|
||||||
|
@interface AFURLConnectionOperation ()
|
||||||
|
@property (readwrite, nonatomic, strong) NSURLRequest *request;
|
||||||
|
@property (readwrite, nonatomic, strong) NSURLResponse *response;
|
||||||
|
@end
|
||||||
|
|
||||||
|
@interface AFHTTPRequestOperation ()
|
||||||
|
@property (readwrite, nonatomic, strong) NSHTTPURLResponse *response;
|
||||||
|
@property (readwrite, nonatomic, strong) id responseObject;
|
||||||
|
@property (readwrite, nonatomic, strong) NSError *responseSerializationError;
|
||||||
|
@property (readwrite, nonatomic, strong) NSRecursiveLock *lock;
|
||||||
|
@end
|
||||||
|
|
||||||
|
@implementation AFHTTPRequestOperation
|
||||||
|
@dynamic lock;
|
||||||
|
|
||||||
|
- (instancetype)initWithRequest:(NSURLRequest *)urlRequest {
|
||||||
|
self = [super initWithRequest:urlRequest];
|
||||||
|
if (!self) {
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
|
||||||
|
self.responseSerializer = [AFHTTPResponseSerializer serializer];
|
||||||
|
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)setResponseSerializer:(AFHTTPResponseSerializer <AFURLResponseSerialization> *)responseSerializer {
|
||||||
|
NSParameterAssert(responseSerializer);
|
||||||
|
|
||||||
|
[self.lock lock];
|
||||||
|
_responseSerializer = responseSerializer;
|
||||||
|
self.responseObject = nil;
|
||||||
|
self.responseSerializationError = nil;
|
||||||
|
[self.lock unlock];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (id)responseObject {
|
||||||
|
[self.lock lock];
|
||||||
|
if (!_responseObject && [self isFinished] && !self.error) {
|
||||||
|
NSError *error = nil;
|
||||||
|
self.responseObject = [self.responseSerializer responseObjectForResponse:self.response data:self.responseData error:&error];
|
||||||
|
if (error) {
|
||||||
|
self.responseSerializationError = error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
[self.lock unlock];
|
||||||
|
|
||||||
|
return _responseObject;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (NSError *)error {
|
||||||
|
if (_responseSerializationError) {
|
||||||
|
return _responseSerializationError;
|
||||||
|
} else {
|
||||||
|
return [super error];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma mark - AFHTTPRequestOperation
|
||||||
|
|
||||||
|
- (void)setCompletionBlockWithSuccess:(void (^)(AFHTTPRequestOperation *operation, id responseObject))success
|
||||||
|
failure:(void (^)(AFHTTPRequestOperation *operation, NSError *error))failure
|
||||||
|
{
|
||||||
|
// completionBlock is manually nilled out in AFURLConnectionOperation to break the retain cycle.
|
||||||
|
#pragma clang diagnostic push
|
||||||
|
#pragma clang diagnostic ignored "-Warc-retain-cycles"
|
||||||
|
#pragma clang diagnostic ignored "-Wgnu"
|
||||||
|
self.completionBlock = ^{
|
||||||
|
if (self.completionGroup) {
|
||||||
|
dispatch_group_enter(self.completionGroup);
|
||||||
|
}
|
||||||
|
|
||||||
|
dispatch_async(http_request_operation_processing_queue(), ^{
|
||||||
|
if (self.error) {
|
||||||
|
if (failure) {
|
||||||
|
dispatch_group_async(self.completionGroup ?: http_request_operation_completion_group(), self.completionQueue ?: dispatch_get_main_queue(), ^{
|
||||||
|
failure(self, self.error);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
id responseObject = self.responseObject;
|
||||||
|
if (self.error) {
|
||||||
|
if (failure) {
|
||||||
|
dispatch_group_async(self.completionGroup ?: http_request_operation_completion_group(), self.completionQueue ?: dispatch_get_main_queue(), ^{
|
||||||
|
failure(self, self.error);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (success) {
|
||||||
|
dispatch_group_async(self.completionGroup ?: http_request_operation_completion_group(), self.completionQueue ?: dispatch_get_main_queue(), ^{
|
||||||
|
success(self, responseObject);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (self.completionGroup) {
|
||||||
|
dispatch_group_leave(self.completionGroup);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
#pragma clang diagnostic pop
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma mark - AFURLRequestOperation
|
||||||
|
|
||||||
|
- (void)pause {
|
||||||
|
[super pause];
|
||||||
|
|
||||||
|
u_int64_t offset = 0;
|
||||||
|
if ([self.outputStream propertyForKey:NSStreamFileCurrentOffsetKey]) {
|
||||||
|
offset = [(NSNumber *)[self.outputStream propertyForKey:NSStreamFileCurrentOffsetKey] unsignedLongLongValue];
|
||||||
|
} else {
|
||||||
|
offset = [(NSData *)[self.outputStream propertyForKey:NSStreamDataWrittenToMemoryStreamKey] length];
|
||||||
|
}
|
||||||
|
|
||||||
|
NSMutableURLRequest *mutableURLRequest = [self.request mutableCopy];
|
||||||
|
if ([self.response respondsToSelector:@selector(allHeaderFields)] && [[self.response allHeaderFields] valueForKey:@"ETag"]) {
|
||||||
|
[mutableURLRequest setValue:[[self.response allHeaderFields] valueForKey:@"ETag"] forHTTPHeaderField:@"If-Range"];
|
||||||
|
}
|
||||||
|
[mutableURLRequest setValue:[NSString stringWithFormat:@"bytes=%llu-", offset] forHTTPHeaderField:@"Range"];
|
||||||
|
self.request = mutableURLRequest;
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma mark - NSSecureCoding
|
||||||
|
|
||||||
|
+ (BOOL)supportsSecureCoding {
|
||||||
|
return YES;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (id)initWithCoder:(NSCoder *)decoder {
|
||||||
|
self = [super initWithCoder:decoder];
|
||||||
|
if (!self) {
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
|
||||||
|
self.responseSerializer = [decoder decodeObjectOfClass:[AFHTTPResponseSerializer class] forKey:NSStringFromSelector(@selector(responseSerializer))];
|
||||||
|
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)encodeWithCoder:(NSCoder *)coder {
|
||||||
|
[super encodeWithCoder:coder];
|
||||||
|
|
||||||
|
[coder encodeObject:self.responseSerializer forKey:NSStringFromSelector(@selector(responseSerializer))];
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma mark - NSCopying
|
||||||
|
|
||||||
|
- (id)copyWithZone:(NSZone *)zone {
|
||||||
|
AFHTTPRequestOperation *operation = [super copyWithZone:zone];
|
||||||
|
|
||||||
|
operation.responseSerializer = [self.responseSerializer copyWithZone:zone];
|
||||||
|
operation.completionQueue = self.completionQueue;
|
||||||
|
operation.completionGroup = self.completionGroup;
|
||||||
|
|
||||||
|
return operation;
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
1
pom.xml
1
pom.xml
@ -864,6 +864,7 @@
|
|||||||
<module>pmd-java</module>
|
<module>pmd-java</module>
|
||||||
<module>pmd-javascript</module>
|
<module>pmd-javascript</module>
|
||||||
<module>pmd-jsp</module>
|
<module>pmd-jsp</module>
|
||||||
|
<module>pmd-objectivec</module>
|
||||||
<module>pmd-php</module>
|
<module>pmd-php</module>
|
||||||
<module>pmd-plsql</module>
|
<module>pmd-plsql</module>
|
||||||
<module>pmd-ruby</module>
|
<module>pmd-ruby</module>
|
||||||
|
Reference in New Issue
Block a user